Checked on:
- i386/x86_64 (linux/windows)
- arm/arm64 (rapberry pi)
- riscv64 (simulator)
Not tested for arm softfloat because raspberry pi does not support it.
Modifications:
Makefile:
add arm-asm.c to arm64_FILES
add riscv64-asm.c (new file) to riscv64_FILES
lib/Makefile:
add fetch_and_add_arm.o(new file) to ARM_O
add fetch_and_add_arm64.o(new file) to ARM64_O
add fetch_and_add_riscv64.o(new file) to RISCV64_O
add $(BCHECK_O) to OBJ-arm/OBJ-arm64/OBJ-riscv64
tcc.h:
Enable CONFIG_TCC_BCHECK for arm32/arm64/riscv64
Add arm-asm.c, riscv64-asm.c
tcctok.h:
for arm use memmove4 instead of memcpy4
for arm use memmove8 instead of memcpy8
tccgen.c:
put_extern_sym2: for arm check memcpy/memmove/memset/memmove4/memmove8
only use alloca for i386/x86_64
for arm use memmove4 instead of memcpy4
for arm use memmove8 instead of memcpy8
fix builtin_frame_address/builtin_return_address for arm/riscv64
tccrun.c:
Add riscv64 support
fix rt_getcontext/rt_get_caller_pc for arm
tccelf.c:
tcc_load_dll: Print filename for bad architecture
libtcc.c:
add arm-asm.c/riscv64-asm.c
tcc-doc.texi:
Add arm, arm64, riscv64 support for bound checking
lib/bcheck.c:
add __bound___aeabi_memcpy/__bound___aeabi_memmove
__bound___aeabi_memmove4/__bound___aeabi_memmove8
__bound___aeabi_memset for arm
call fetch_and_add_arm/fetch_and_add_arm64/fetch_and_add_riscv64
__bound_init: Fix type for start/end/ad
__bound_malloc/__bound_memalign/__bound_realloc/__bound_calloc: Use size + 1
arm-gen.c:
add bound checking code like i386/x86_64
assign_regs: only malloc if nb_args != 0
gen_opi/gen_opf: Fix reload problems
arm-link.c:
relocate_plt: Fix address calculating
arm64-gen.c:
add bound checking code like i386/x86_64
load/store: remove VT_BOUNDED from sv->r
arm64_hfa_aux/arm64_hfa_aux: Fix array code
gfunc_prolog: only malloc if n != 0
arm64-link.c:
code_reloc/gotplt_entry_type/relocate: add R_AARCH64_LDST64_ABS_LO12_NC
relocate: Use addXXle instead of writeXXle
riscv64-gen.c:
add bound checking code like i386/x86_64
add NB_ASM_REGS/CONFIG_TCC_ASM
riscv64-link.c:
relocate: Use addXXle instead of writeXXle
i386-gen.c/x86_64-gen.c
gen_bounds_epilog: Fix code (unrelated)
tests/Makefile:
add $(BTESTS) for arm/arm64/riscv64
tests/tests2/Makefile:
Use 85 only on i386/x86_64 because of asm code
Use 113 only on i386/x86_64 because of DLL code
Add 112/114/115/116 for arm/arm64/riscv64
Fix FILTER (failed on riscv64)
tests/boundtest.c:
Only use alloca for i386/x86_64
an enum must be compatible with one or more integer type,
so adjust the test accordingly. That means the following
redeclarations should work:
enum e6 { E1 = -1, E0 };
void f3(enum e6);
void f3(int); // should work as int and e6 are compatible
while the following should not:
void f4(enum e6 e);
void f4(unsigned e); // should error as unsigned and e6 are incompatible
they were emitted too early, in particular also in macro
substitution which might turn out to not be stray in case it's
further stringified. Check in next() instead. Add two testcases
that an error is still emitted for obvious top-level baskslashes,
and that stringifying such a thing works.
i386-gen.c:
- load/gen_opf: set v1.sym to NULL
lib/Makefile:
- Add -gstabs -fno-omit-frame-pointer -Wno-unused-function -Wno-unused-variable
lib/bt-log.c:
- tcc_backtrace: Prevent __builtin_frame_address warning
tccgen.c:
- struct_layout: Set t.t to VT_BYTE
- default_debug: Use octal instead of -1 to make size_t work
tccpp.c:
- tal_realloc_impl: Only memcpy when p set
x86_64-gen.c:
- gen_bounds_epilog: Do not save/restore rcx (not caller/callee saved)
This also made stack not aligned to 16 bytes.
tcctok.h:
- Add __bound_setjmp/setjmp/_setjmp/longjmp
tccgen.c:
- redirect setjmp/longjmp to bcheck.c code
i386-gen.c/x86_64-gen.c
- Change func_bound_alloca_used into func_bound_add_epilog
- Set func_bound_add_epilog also when setjmp is called
bcheck.c:
- Add __bound_setjmp/__bound_longjmp
- __bound_local_delete: remove setjmp if used in function
- __bound_exit: clear setjmp list and print statistic
- make malloc_redir more readable (unrelated)
New testcases:
- 115_bound_setjmp
- 116_bound_setjmp2
Merge function attributes with those given given for the
prototype, also handle post-decl appearance such as
void func() __attribute__((noreturn))
{
}
Also, some test fixes (unrelated).
from 3e731e3a78
tccgen.c:
- make 'struct default_debug' const
- pass TCCState* as parameter to tcc_debug_xxx functions
- always check tcc_state->do_debug before calling functions
- factor out tcc_debug_extern_sym()
- remove formats "%lld"/"%llu" (not reliable on windows)
xxx-gen files:
- set func_vt/var from caller
for simplicity handles like -v (verbose), but enables the usual idiom
of configure scripts to use '$CC --version' to find out the compiler
variant and version.
This allows debugging with variables/structs/unions/enums/bitfields.
Add new functions:
- tcc_debug_stabs: store stabs debug info
- tcc_debug_stabn: store stabn debug info
- tcc_get_debug_info: generate stabs debug info
- tcc_debug_finish: store debug info in debug section
- tcc_add_debug_info: Add function debug info
Update functions:
- tcc_debug_end: free debug hash
- tcc_debug_funcstart: Generate correct function debug info
- tcc_debug_funcend: Finish debug info
- put_extern_sym2: Generate debug info for symbols
- pop_local_syms: Add debug info
- prev_scope: Add local symbols
it doesn't round so the RM field can be zero. According to some
sourcs it should be set to zero by software in these cases, and
the binutils disassembler doesn't like us setting it to 7.
This shouldn't matter in practice, but who knows.
This makes available the __builtin_va_list type and __builtin variants
of va_start, va_arg, va_copy and va_end. We do this via a header file
that's prepended to all compilations always (except if merely
preprocessing): tcc_predefs.h. That header could also be used
for predefining other builtins in the future.
We don't need the define hacks for musl anymore with this.
Also fix x86_64 gfunc_prologue to reserve enoug space for the
full va_list structure, not just 16 bytes.
this partly reverts 1803762e3 to fix stdarg on x86-64 again. I've tried
to retain the apple specific changes from that commit.
Also include stdarg.h first in tcc.h, maybe that helps as well.
When compiling on macOS (at least in version 10.12) the TCC compiler failed
to compile libtcc1.a. Three problems were solved:
- The predefined macro "__APPLE__" is now available, as it is tested in the
libc darwin header files
- the libtcc1 Makefile defined _ANSI_SOURCE, although it used signals
- stdargs.h defined va_list differently from the darwin libc.
If the darwin standard library was included BEFORE stdargs this caused
problems.
- the darwin libc generated a warning if GCC < 4 was used
- additional defines are predefined now to make darwin libc headers compile.
as there's overlap between handling types for binary and ternay
operations. Factor this into a single routine (combine_types).
This uses the structure that gen_op was following, and expr_cond
was using as well in the past, which I find easier to reconvene
with the standard language. But it reuses the new functions for
diagnostics to improve (a little) on what GCC or clang produce :)
the support for the macro GCC_MAJOR is gone since 2017, and it's
fairly doubtful that anyone serious is using gcc 2.95.
Also adds a test for the ternary ops typing rules: 'x?bool:bool' has
to promote to int.
as per testcase. We must not reset token.sym_label twice with
kept symbols. This is no problem for non-label symbols because those
aren't generated on demand when mentioning them.
On windows. there is no long double really IOW it is the
same as double. However setting the VT_LONG flag in
combination with VT_DOUBLE allows to keep track of the
original type for the purpose of '_Generic() or more
accurate type warnings.
... in order to avoid fp stack overflow (see test below).
#include <math.h>
#include <stdio.h>
int main()
{
printf("%f %f %f %f\n", trunc(1.2), rint(1.2), trunc(1.2), rint(1.2));
printf("%f %f %f %f\n", trunc(1.2), rint(1.2), trunc(1.2), rint(1.2));
printf("%f %f %f %f\n", trunc(1.2), rint(1.2), trunc(1.2), rintl(1.2));
}
Also in rintl:
- 'long double' is not a ten-byte float on windows.
- Updated msvcrt.def with symbols from 64bit version of dll - it contains the float math functions missing in the 32bit dll.
- Made sure this patch only apply to to WIN32 and WIN64. For WIN32 float functions calls the double variants, on 64bit they are called natively.
by calling the double functions and removing unsupported __asm implementations using "=t".
This patch also enables the double version of logb(double).
Note: None of the 'long double' variants works though - could easily be fixed
by aliasing the double equvalents for completeness/compability.
Fix static assert to support literal string instead of just printing
the sring of the current token as it use to be
so we can now use _Static_assert(0, "0" "1") which will print
__FILE__ __LINE__ error: 01
commit ef42295fe8 intrduced 4 .o files to
win32/lib. But they (bcheck.o, bt-dll.o, bt-exe.o and bt-log.o) are not
removed by "win32/build-tcc.bat -clean". This commit should fix it.
- revert const-folding in gvtst() and put it back into
expr_landor(). Although it did make sense, one reason
not to do it is __builtin_constant_p() which may return
true when it shouldn't because of nocode_wanted, see test.
- tccgen_init() can do init_prec(), also for tcc -E.
- for nostalgic reasons, keep the original expression parser
functions in the source.
- Makefile: remove stale stuff
so that it also is called from the precedence parser. This
is complicated by the fact that something needs to be done before
the second operand is parsed in a single pass compiler, so it
doesn't quite fit into expr_infix itself. It turns out the smallest
code changes result when expr_landor remains separate. But it can
be tidied a bit.
This is smaller and uses less stack depth per expression (eight function
calls from expr_or to get down to a unary). It's a tiny bit faster
depending on how good the branch predictor is, on my machine a wash.
ELF files that refer to shared libs containing sym-versions, but
don't refer to any dynamic symbols with symbol versions (should happen
only with very simple shared libs) would generate an empty .gnu.version_r
section. Some dynamic linker contain bugs in that they don't check
the section size or DT_VERNEEDNUM (which are both zero for such files
we generate) before accessing the first entry, and then bail out with
a message like
./a.exe: error while loading shared libraries: ./a1.so: unsupported
version 25960 of Verneed record
(where the "version number" actually comes from neighboring bytes
from different sections).
So, there's not much choice, we simply must not generate such section.