See test. We need to use 'ind' from later when the address
field of the instruction is put.
Also: fix crash when the substracted symbol is undefined
Also: assume asm-symbols to be lvalues (except func/array)
- LIBTCCAPI int tcc_set_backtrace_func(void *ud, ...)
accept opaque user data pointer,
- tcc -vv -run... : show section info
- use memalign() to allocate runtime memory
- printline_/dwarf : pass output to parent function
- tccpe.c : fix -nostdlib -run
- --config-backtrace=no : make it work again
- new LIBTCC API tcc_setjmp() to allow longjmps & signals
from compiled code back to libtcc per TCCState
- new LIBTCC API tcc_set_backtrace_func() to handle backtrace output
- move c/dtor/atexit stuff to runtime (lib/runmain.c)
- move bt-log.o into libtcc1.a
- add timeouts to github action (beware, it did happen to hang
infinitely in the signal handler at some point)
tcc failed to run with bounds checking enabled because the functions
rt_wait_sem, rt_post_sem and _rt_error where defined twice.
This is solved by making them weak in tccrun.c
Also a nested lock was present when setting TCC_BOUNDS_PRINT_CALLS=1
This is solved in lib/bt-exe.c by moving lock/unlock code.
Also added a testcase in tests/Makefile to test tcc with bounds
checking enabled.
- abort with notice when tcc_relocate() is called with the
former two-step method
- support backtrace & bcheck not only with tcc_run() but also
for directly called functions from tcc_get_symbol(); enable
witn 'tcc_set_options("-bt/-b");'
- move struct rt_context and debug sections into compiled code
for TCC_OUTPUT_MEMORY also
- protect access (g_rc) with semaphore
Also:
- add armv7/aarch4/riscv64 github tests (qemu emulated)
- win32/build-tcc.bat: build cross compiler only with -x
- remove TOK_NOSUBST, mark the token itself instead
- get_tok_str(); mask out SYM_FIELD & update uses
- next(): optimize (~5% faster with tcc -E)
- tok_flags: remove some redundancy
- parse_define(): do not remove spaces around '##' and after '#'
and mark macros with '##' as MACRO_JOIN to avoid unnecessary
call to macro_twosharps(mstr):
- next_nomacro(): removed, next_nomacro1(): renamed to next_nomacro()
- next_argstream(): cleanup & new function peek_file()
- macro_subst_tok(): handle special macros (__DATE__ etc.)
like normal macros if they are #defined
- -DPP_DEBUG : more structured output
- pp_error(): better preprocessor expression error message
- tcctok.h: sort basic keywords (somehow)
- testspp/Makefile: generate .expect with 'make testspp.##+'
- tcc.c: tcc -E -o file : put unixy LFs also on windows
removed second argument for tcc_relocate(s). previous
'TCC_RELOCATE_AUTO' is now default and only behavior.
Rationale:
In the past, the option to compile into memory provided by the
user was introduced because only one TCCState could exist at a time.
This is no longer a limitation. As such it is also possible now to
keep any number of compiled code snippets around together with their
state in order to run them as needed.
- Also
- LIBTCCAPI tcc_get_error_func/opaque() removed
- tccrun/SELINUX: switch rx/rw mappings such that rx comes first
(risc64-link.c:relocate_plt() does not like got < plt)
- tcc_relocate_ex(): free local symbols and obsolete sections
to reduce memory after tcc_relocate()
When using libtcc it's reasonable to be able to use the application's
memory allocator for all allocations, including tcc_new(), and including
#define MEM_DEBUG
Ideally the allocator would be stored in the TCCState, like TCCErrorFunc.
That would imply a new API tcc_new_with_allocator(), but more importantly
would require all uses of tcc_malloc(x) to be changed to s->tcc_malloc(x).
That's a non-starter in my book.
Instead I refactored the memory management code so that all allocations
flow through tcc_realloc(). Which simply calls a function pointer, the
default value of which is the previous tcc_realloc().
It then becomess trivial to install a new allocator with the new function:
LIBTCCAPI void tcc_set_realloc(TCCReallocFunc realloc);
The resulting code adds the trivial cost of an additional function call
per allocation/free. It also doesn't distinguish between malloc failure
and realloc failure, but since both just fprintf then exit() that seems
unimportant to me.
On the plus side the preprocessor magic is much more clear. The diffs
don't hightlight that, but take a look at the result to see if you agree.
All tests passed on my x86 linux box.
tccpp.c:
- revert "Preprocessor fix + new testcase"
Fix was not a fix and nobody could understand the test.
This reverts 6379f2ee76
- better fix and add new test (pp/18.c)
tccgen.c:
- remove global variables 'in_sizeof', 'constant_p'
- rework comma expression (gexpr())
- merge func/data 'alias_target' codes
(See 08c777053c)
- move call to do_Static_assert()
- better error: "expression expected before '%s'"
- fix "statement after label"
- remove unnecessary second parameter to block()
- remove unnecessary call to decl()
- revert changes to old C89 test file
See 7f0a28f6ca
tccelf.c:
- rework "...make undefined global symbol STT_NOTYPE"
(See f44060f8fc)
- move tccelf_add_crtbegin() from libtcc.c
tcctest:
- unfix K&R fix (keep old look of K&R functions)
tccrun.c:
- exit(0) returns 0
libtcc.c:
- move #defines for -dumpmachine
- more explicit error "file not found"
(as opposed to error while loading file)
tccpe.c, x86_64-gen.c, i386-asm.c, tccasm.c:
- use R_X86_64_PLT32 for functions on x86_64-win32
tccdefs.h
- empty #defines for _Nonnull, __has_builtin(), etc.
configure:
- Simpler "macOS .dylib ... VERSION letters."
(See 6b967b1285)
Makefile:
- macOS version also
- add cross searchpaths for packages
build.yml:
- disable codesign on macos-11 (doesn't seem to work)
This reverts commit ece74ceaaf.
codesigning is already supported via --config-codesign.
This patch actually broke testing for tcc builds with
that set.
Allows running the tests out-of-the-box on macOS.
Also delete *.dylib in tests2 dir on "make clean".
One remaining issue on macOS 14.1 is that the
-undefined warning option no longer works,
thus breaking test3 and test1b.
The testcases 22_floating_point and 24_math_library did not work with
make tcov-test
Add -lm for these in tests/tests2/Makefile
gcc -fanalyzer complains about tcc_malloc and tcc_realloc because
malloc(0) and realloc(ptr, 0) is not tested correctly.
configure:
- option --targetos=... for cross build
- cleanup
win32/build-tcc.bat:
- option -b <bindir>
- make 'libtcc1.a' and cross-prefix-libtcc1.a
(same convention as with makefile)
Makefile:
- streamline tcov-tests, help, etc.
workflow/build.xml: simplify
- using "windows-2019" runner (instead of windows-latest)
because its msys seems more complete and has no problems
with the 96_nodata_wanted.test either.
Changelog,TODO,USES,tcc-doc.texi: update
libtcc.c:
- revert "Small patch to allow..." (someone's personal easteregg)
(see da3a763e97)
- check return value from macho_load_tbd/dylib
tcc.c:
- remove help for "not yet implemented" option
tccelf.c:
- check PIE's for "unresolved symbols"
tccgen.c:
- avoid int->double->int cast
(see a46372e910)
- fix constant propagation with pseudo long doubles
(must mask out VT_LONG from type)
- cleanup find_field() (again)
tccpp.c:
- disallow strings and double constants in #if expressions
win32/include/uchar.h:
- change file mode
The following targets are added:
testc / testc2.all / testc2.37 / testc2.37+ / testc2.37-
testcpp.all / make testcpp.17
This allows to check that the testcase(s) test the code modified.
See Makefile tests/pp/Makefile tests/tests2/Makefile
lib/tcov.c: Fix while loops with fgets.
tcc.h: Fix tcc_p compilation with latest gcc
tests/tests2/22_floating_point.*: Better test floating point
The incr_offset offset code was not working with bounds checking.
So I reverted part of tccgen.c.
See new test code 132.
Also added some debugging code that prints location of
bounds checking calls. Needed this to find the problem.
See lib/bcheck.c, lib/bt-dll.c, lib/bt-exe.c, lib/bt-log.c, tccrun.c
tccgen.c:
- new function incr_offset(int) to increment a lvalue
- use it in gv/vstore to load/store from/to two-word types
- use it to advance the pointer to struct fields
- use it to load/store structs passed in registers
- structs: always assume that reg-classes of registers are 2^n
- adjust stack space when regsize > sizeof the_struct
x86_64-gen.c:
- return regsize=16 for VT_QLONG/QFLOAT
i386-gen.c:
- pass structs of size(8) as two VT_INT rather than one VT_LLONG
(both should work now)
fixes a82aff3337
fixes fd6d2180c5 (slightly)
The stack was not aligned when a returned structure was stored on stack.
This resulted in destoying of previous values stored on stack.
See testcase 119 (tst_struct_return_align) where value d is overwritten.
On backends that rely on gfunc_return() to handle structures
returned in registers (like RISC-V), gfunc_return() may generate
invalid loads for structures without VT_LOCAL and VT_LVAL. This
commit fixes it and adds a regression test
(131_return_struct_in_reg)
pragma once can now be used with
test.h
./test.h
and other references to the same file just like gcc/clang.
On linux we can use stat and st_ino to check for the same file.
On windows the st_ino does not work so we calculate a file hash
if the size of the file differs and then compare the hash.
if we include standard headers on glibc-based systems then
we can't use '__attribute__' (those are defined away for unknown
compilers) but must use '__attribute' (or #undef that token).
tccgen.c:
- just track local_stack for small scopes (can't declare variables)
- fix a vla problem with nested scopes
- move debug N_L/RBRAC into curly braced block
Also:
- tccpp.c: move 'label_...' functions to tccgen.c
- tccpp.c: let get_tok_str() say "<no name>" for anonymous symbols
- tcctest.c: let __pa_symbol() work for memory > 2GB
- 119_random_stuff.c: revert strtoll test (no reason to test libc)
- tccdefs.h/tcctest.c: enable bit fncs for _WIN32
- Makefile:
- use i686-linux-gnu instead of i386-linux-gnu for cross-i386
- update 'make help'
- revert umplicit 'make all' with 'make install' (but print warning)
instead in vcheck_cmp(), pass the CODE_OFF_BIT to generators
unless other nocode purposes are set.
This reverts commit cad8739594.
Also in 128_run_atexit.c:
avoid line output disorder which may happen on windows when
tcc itself and runned code are using two different printf
implementations and tcc would print the "[Returns 1]" above
any output from the runned test.
The generated code by yarpgen failed. I traced the problem to
expr_landor. The problem was that nocode_wanted was removing
too much code.
See also testcase 33.
the casted type was lost when a delayed bool was finally converted
to a value. See testcase, in the wrong case the '(unsigned int)' cast
was ignored, and hence the division was signed reulting in -1 instead of
the proper 0x7fffffff.
the code in expr_cond save nocode_wanted around some parts of
expression evaluation, but at the wrong spots. If the evaluation
of the condition itself (e.g. in the testcase the first whole ternary
expression) resulted in CODE_OFF, then that was saved, and restored
before return, even if in-between codegen would have CODE_ON'ed already.
Thus the whole CODE_OFF state bled out to outside the expression
evaluation and also disabled the whole if-block. Found by yarpgen v1
(seed 64).
we activate code (CODE_ON) only when the target labels are used,
which doesn't happen during nocode_wanted regions. So, we cannot
just switch off code either during nocode_wanted regions, nothing
would switch it on again (except in the happy coincidences when we
outright save/restore nocode_wanted). See the testcase for one
example, reduced from code generated by yarpgen: in
ext = (xxx || 1) // #1
|| ((xxx && 1) || 1) // #2
code is first suppressed in #1 normally, then (before this commit)
was suppressed via CODE_OFF during #2 (via indirect gjmp),
then the suppression from #1 was undone, but nothing undoes the
suppression from #2 anymore as everything therein was generated
while nocode_wanted was active.
So, we would either need to save/restore nocode_wanted around
some more expressions, activate CODE_ON also with unused labels (breaks
some optimizations we want), or deactivate CODE_OFF only when not
already in nocode_wanted state. This does the latter.
Sym.sym_scope and Sym.f (FuncAttr) share space, so blindly setting
one clobbers the other. Right now this only leads to missing errors
on incompatible typedefs (see testcase), which this commit fixes.
But it points to a larger problem:
Generally we can only manipulate Sym.f for anonymous and field symbols,
not for anything that has a top-level name (basically any proper decl),
because the latter use sym_scope. Luckily the functions type always
contains an anonymous symbol (in sym->type.ref), so we can use that.
But some of the functions attributes actually _do_ apply to the decl,
not the type (e.g. always_inline), so we still have a problem possibly,
when we update an pre-existing type that may already be shared with
another decl.
Would need untangling and perhaps using accessor functions that check
that Sym.f and Sym.sym_scope aren't used for the same symbol.