There are install shell scripts around, often derived from X11 like
contained in glibc or Gash sources, which require to separate -m from
its value. Therefore add a space behind 'install -m' in the Makefile.
GAS selects default attributes for a section based on its name and makes
the sections .text, .init, .fini executable. The crti.s and crtn.s files
of musl rely on these defaults and don't set the "x" flag for the .init
and .fini sections. Unfortunately TCC does not care for .init and .fini
section defaults in assembler or C code. Fix this for assembler code.
Handle 'register long r10 __asm__("%r10")' without %, too. Using GCC
the % is optional. The musl source code does not use the % prefix.
The GCC source code uses both variants.
despite being defined in tcc's own stddef.h, intended to be included by
libtcc.h, libtcc.h actually included the libc's standard include
tested on musl
* case 1: local scope of 'ff'
int main() {
int ff = 123;
{
int ff(int):
ff(456)
}}
* case 2: linkage of a static extern symbol
(older gcc did allow that)
static int ff(int);
int main() {
int ff(int):
ff(456)
}
Also:
- cleanup enum, let sym_push() handle redefinition
- just mark incomplete array base types, unshare only
when needed (in decl_initializer_alloc())
- fix sizeof empty array (= 0) : int ii[] = {};
- rename 'Sym' members used by __attribute__((cleanup(f)))
wanted by gdb to have global variables info on windows
Also:
tcc.h:
- move dwarf inline fns
- use dwarf as default for 64-bit platforms. GDB can't handle
locals info from stabs on 64-bit correctly (also not from gcc).
tccpe.c:
- use 's1' instead of 'pe->s1'
tccdbg.c:
- fix locals info problem on Windows where (unsigned long) s->value
is uint32_t and would not cast to long long correctly.
- tweak dwarf to have line info at begin of functions, otherwise
"gdb b main, r, n" would say "no line number info, single step..."
(see also objdump --dwarf=decodedline ...)
Fix 'void func2(char *(*md)(char *md))' declaration.
Fix global array and local extern array problems.
Fix scope problem with old function declaration.
Fix 'typedef int t[]' declaration. Empty size should remain.
... see tests
Also:
- tccgen.c: cleanup _Generic a little
- libtcc.c: cleanup mem-debug a little
- arm-link.c: read/write only once
- tcc.h: another fix for clang offsetof
- tccdbg.c:
* stabs: handle forward struct/enum decls
* stabs: fix anonymous struct members (must not have a .L123 name)
* avoid strncpy()
Currently debug size is big because some types are output multiple times.
Function scope was not treated correctly.
Rename anon(ymous) into forw(ard).
Compact string table by reusing names.
int foo(struct xxx {int x[3];} *p) { ...
We want 'xxx' be visible only inside the function. To get that,
the patch removes the 'sym_push(param)' in xxx-gen.c, and instead
(in tccgen.c:gen_function()) pushes all symbols that were newly
defined during parsing of the parameter list in post_type().
Also,
- decl_initializer_alloc():
patch existing globals earlier, which updates flex arrays too
- let patch_type() do the 'redefinition' check and FUNC_OLD update
tcc.c:
- be nice to leak checkers
tcctools.c:
- remove unused TCCState params
tccrun.c:
- call bound_exit() after signals to let it free mem
tccelf.c:
- use section_add() instead of section_ptr_add() when
more appropriate
tccpp.c:
- use size_t to align tal_header naturally
- 'POINTER_SIZE' and 'PTR_SIZE' in the same source is confusing
- "char file_name[TAL_DEBUG_FILE_LEN + 1];" looks silly.
- next_nomacro(): skip UTF8 BOM at BOF
tccgen.c:
- get rid of STMT_EXPR clause on top of block
- warn with useless type like 'int;'
- move skip()'s in block() for better error line-info
- BIT_SIZE bits are meaningful only with VT_BITFIELD
(not with enums for example)
workflow/test-win32:
- build with MSVC using build-tcc.bat also
alloca.S:
- fix 'off by one' problem on win32 (must touch current page
too because the 'push %edx' at the end could touch the next page)
- must not align greater than 4 when used for struct args
(i386-gen.c:gfunc_call())
libtcc.c:
- accept -g1dwarf (dwarf output, only line info)
The code:
void mul(double *p)
{
*p *= 2.0;
}
failed on x86_64 because register was not loaded after
bound checking call.
Also printed size when pointer indir failes.
I updated the tests/gcctestsuite.sh a bit.
before:
3329 test(s) ok.
210 test(s) skipped.
168 test(s) failed.
28 test(s) exe failed.
after:
3331 test(s) ok.
299 test(s) skipped.
79 test(s) failed.
26 test(s) exe failed.
I found some small problems:
include/tccdefs.h: Add alloca definition for i386 and x86_64
lib/alloca.S/lib/alloca-bt.S: align i386 alloca to 16 bytes.
i386_gen.c vla code and gcc do the same.
x86_64-gen.c: fix typo in comment
arm-link.c: remove some casts
tccelf.c: code style and remove code
tccpp.c: use correct pointer size so cross compiling works
riscv64-gen.c: make code more readable
I tried to fix all remaining warnings/errors reported by -fsanitize.
The riscv64-gen.c is a bit large because it contained a lot of warnings.
I forgot some arm-link.c changes in last commit.
The other changes are all small fixes to avoid warnings/errors.
Tested code with:
clang -fsanitize=address,undefined,nullability -pie -fPIE -Iinclude -I. -g tcc.c -o tcc.tcc -lm -ldl -lpthread
./tcc.tcc -Iinclude -I. -b -g tcc.c -o tcc.tcc1 -lm -ldl -lpthread
Also checked on i386/x86_64 with -fsanitize=memory (others not supported).
arm-link.c: use read32le/write32le/add32le to avoid unaligned access
tcc.h i386-asm.c: fix signed left shift
lib/bcheck.c: Add _Atomic
libtcc.c: Correct MEM_DEBUG_CHECK3 to avoid unaligned access
riscv64-link.c: Fix R_RISCV_SET16
tccpp.c: Align tal_header_t to avoid unaligned access
tccgen.c x86_64-gen.c: avoid use of uninitialized value
There are still warnings reported:
tccgen.c:4031:13: runtime error: member access within null pointer of type 'TCCState' (aka 'struct TCCState')
tccelf.c:321:22: runtime error: applying zero offset to null pointer
tccelf.c:1132:23: runtime error: applying non-zero offset 169184 to null pointer
A lot of left shift of negative value warnings.
I ignored these for the moment.
Also the -run option does no work well with -fsanitize. It gets confused
because it does not detect that the generated code in memory is used
without -fsanitize option.
There are a lot more -fsanitize options. I did not find serious problems
with them.
While adding some testcases for attribute cleanup I found a
bug in the riscv code. It modifies the sv->c.i in load_symofs.
If a structure contains more then one element only the
first is stored correctly. This only happens on a large
stack frame.
Fixed by saving/restoring sv->c.i.
workflows/build.yml:
- win32/64: install mingw32/64 gcc on msys (because the default
gcc installed elsewhere seems to use ucrt, producing incompatible
fp printf formats.)
tccgen.c:
- cleanup funcs: save any lvalues from return expressions. Also use
get_temp_local_var() which however was causing a problem on i386
because its gfunc_call() removes the arguments from vstack and by
that defeats the 'in-use' tracking of get_temp_local_var(). Fixed by:
i386/arm/arm64/x86_64-gen.c:
- in gfunc_call(): save_regs before anything else, fixes
problems seen in arm64/i386
tccpp.c:
- allow arm asm specific use of '#' in macros
libtcc.c:
- organize -M options, and:
tccpe.c:
- move the subsystem option parsing from libtcc.c
tccelf.c:
- improved error handling in tcc_load_ldscript()
lib/atomic.S:
- TCC_TARGET_... not defined when building the lib
- endbrNN security feature not supported by TCC
tests/tests2/136_atomic_gcc_style.c:
- never use standard assert() in tests