Commit Graph

596 Commits

Author SHA1 Message Date
herman ten brugge
8f8abcc756 more bsd updates
This implements support for FreeBSD on aarch64
This partial implements support on FreeBSD(32). This still needs fixing
i386_gen.c because small structures on this target are passed in registers.

Add aligned 16 to __int128_t for FreeBSD
Support __i386__ on FreeBSD/NetBSD
Fix testcase 115 on FreeBSD/NetBSD
Disable testcase 116 on *BSD* because TLS_FUNC/TLS_VAR not set in bcheck.c
Remove FreeBSD/FreeBSD_kernel code from tccelf.c
2020-12-22 07:02:47 +01:00
grischka
8ff705554d tcc_enter/exit_state(): do not use!
tcc_enter/exit_state() are meant exclusively to protect
the tcc_compile() and its sub-functions in tccpp.c,
tccgen.c, tccasm.c and xxx-gen.c.

Other files that are part of libtcc simply must not use global
variables.

- riscv64/last_hi: move to TCCState
  from 72250bece2

- tccrun.c: Using a fixed address would not work anyway
  ("tcc -run tcc.c -run ..." for example)
  from baacb0f52a

- tests/Makefile: support for a platform doesn't make sense if
  it doesn't pass our basic tests.
  from 591feda103
Also:
- tccgen: cleanup "duplicate member" (only 2 passes,
  avoids additional TokenSym field)
  from 170be79a42
2020-12-08 19:57:57 +01:00
herman ten brugge
170be79a42 duplicate member
Check duplicate struct/union member names

tcc.h: Add cnt field in TokenSym

tccgen.c: New function check_fields to find duplicate member names.

This avoids quadratic behavior and can be used for large structs.
2020-12-03 07:53:44 +01:00
grischka
cf8d9cf072 win64: fix pe_isafunc()
- tccpe.c: commit "tidy support for helper function" created
  STT_NOTYPE symbols and hence relied on ad-hoc detection which
  didn't work for x86_64 (as reported by Christian Jullien)

- tccgen.c: However to be more safe the helper symbols are
  now made STT_FUNC anyway (via new VT_ASM_FUNC).

Also:
- tcc.h: minor reorder
- riscv64-*, arm64-*, tccmacho.c: avoid some gcc format-warnings
  (mingw-gcc complains about "%llx" being "unknown conversion",
  although it does work since Vista or so)
2020-11-26 16:11:17 +01:00
grischka
4a42b0d95e tidy support for helper function such as memmove
tcc.h, tccgen.c: Introduce Sym *external_helper_sym(int v);
  to create an external reference with no specific type. This
  avoids type conflicts if the symbol is used from C too.
the other files: use it.
2020-11-24 11:47:02 +01:00
Arthur Williams
3709f8de14 Treat func pointers with different return types as not compatible
Tcc considered function ptrs with different return types to be
compatible which disallowed some otherwise valid operations like:
`_Generic(foo, int(*)():0, void(*)(void):1)`
which would fail to compile with a error message of "type match twice"

This changed also required longjump's return type to be void and
munmap's to be int to be compatible with standard headers.
2020-11-22 16:30:34 -06:00
grischka
8b69059f66 three small fixes & three reverts
- tcc.h: msvc doesn't grok __func__ (reverts previous commit)

- tccgen.c: fortify tcc against bogus code:
  - n[sizeof({3;})]; // statement expression outside of function
  - f(){"123"4}; // tokens with values following each other
  (also, add "type defaults to int" warning for variables)

- tccpe.c: removed a check that caused BSS symbols not to be
  exported.  Whatever that check was meant to prevent.

- win32/build-tcc.bat: cmd.exe sometimes doesn't grok '-' in labels

- Revert "libtcc: no need to undef"
  This reverts commit 2b7aa2a1e1.
- Revert "tcc.h libtcc.c: remove unused defines"
  This reverts commit 985d963745.

The point of these "unused defines" is to be unused,  that is
to remind people not to use malloc but please to "use_tcc_malloc",
instead.
2020-11-02 18:08:56 +01:00
grischka
72b520e709 tccgen: flex arrays etc.
Fixes potential writes past the allocated space with mostly
illegal flex array initializers. (60_errors_and_warnings.c
:test_var_array)

In exchange suspicious precautions such as section_reserve
or checks with sec->data_allocated were removed.  (There is
an hard check 'init_assert()' for now but it's meant to be
just temporary)

Also, instead of filling holes, always memset(0) structures
& arrays on stack.  Sometimes more efficient, sometimes isn't.
At least we can omit putting null initializers.

About array range inititializers:  Reparsing tokens has a
small problem with sideeffects, for example

   int c = 0, dd[] = { [0 ... 1] = ++c, [2 ... 3] = ++c };

Also, instead of 'squeeze_multi_relocs()', delete pre-existing
relocations in advance. This works even if secondary initializers
don't even have relocations, as with
    [0 ... 7] = &stuff,
    [4] = NULL

Also, in tcc.h: new macro "tcc_internal_error()"
2020-10-03 18:12:46 +02:00
Michael Matz
78da4586a0 Fix tests2/120_alias.c on macos
While MacOS doesn't natively support the alias attribute, let's support
it with TCC anyway.  This means we need to make a decision if the
string in the alias attribute is decorated or not due to the implicit
underscore on MacOS.  To make life easier we decide that it's the C name,
i.e. without underscore, and so TCC needs to emit alias names with
underscore handling.

Irrespective of that the test case needs to deal with the underscore
itself for __asm__ renaming which is always requiring the assembler name.
2020-10-01 18:03:56 +02:00
herman ten brugge
0da93838c1 Init range wth symbols
The init range with symbols did only init the first value.
The relocation for all other symbols was missing.
Also see testcase.

tccgen.c:
- New function get_init_string
- Use macro processing in decl_designator for each init string
- Use get_init_string in decl_initializer_alloc

tccelf.c:
- Fix insertion sort in squeeze_multi_relocs

tests/tests2/90_struct-init.c:
- Add test case test_init_ranges
2020-10-01 17:50:20 +02:00
herman ten brugge
afc0917f88 Bound checking fixes
tccgen.c:
- Fix 'tcc -b conftest.s'
- Add offset during bound checking for struct return

lib/bcheck.c:
- Check overlap when reusing vla/alloca

arm-gen.c:
arm64-gen.c:
riscv64-gen.c:
lib/alloca86-bt.S:
- add space for vla/alloca during bound checking

tests/tests2/Makefile:
tests/tests2/121_struct_return:
tests/tests2/122_vla_reuse:
- New test cases with bound checking enabled to test vla and struct return
2020-10-01 17:09:09 +02:00
Michael Matz
352e1d0fc4 Reinstate attribute alias handling
commit 2a0167a merged alias and asm symbol renaming, but broke
semantics of aliases, see testcase.  Basically the difference between
the two is that an asm rename doesn't generate a new symbol, i.e. with

  int foo __asm__("bar");

all source reference to 'foo' will be to 'bar', nothing of the name
'foo' will remain in the object file, and for instance reference to
'foo' from other compilation units won't be resolved to this one.

Aliases OTOH create an additional symbol.  With:

  void target (void) { return; }
  void afunc (void) __attribute__((alias("target")));

reference to 'afunc' will remain 'afunc' in the object file.  It will
generate two symbols, 'afunc' and 'target' referring to the same entity.
This difference matters if other compilation units make references to
'afunc'.

A side requirement of this is that for alias to work that the target
symbol needs to be defined in the same unit.  For TCC we even require a
stricter variant: it must be defined before the alias is created.

Now, with this I merely re-instated the old flow of events before above
commit.  It didn't seem useful anymore to place both names in the
asm_label member of attributes, and the asm_label member of Sym now
again only needs the hold the __asm__ rename.

It also follows that tcc_predefs.h can't make use of attribute alias to
e.g. map __builtin_memcpy to __bound_memcpy (simply because the latter
isn't defined in all units), but rather must use __asm__ renaming, which
in turn means that the underscore handling needs to be done by hand.
2020-09-30 17:46:01 +02:00
herman ten brugge
727e24cb0a Add typedef debug info
tccgen.c:
- In tcc_get_debug_info mask VT_STORAGE instead of VT_EXTERN | VT_STATIC
- New function tcc_debug_typedef
- Call tcc_debug_typedef in decl0
2020-09-27 11:13:37 +02:00
herman ten brugge
8fd7a384e2 Fix bitfields init : tiny solution
tccgen.c: Check struct/union size for bitfield.
tests/tcctest.c: Add test code.
2020-09-25 12:23:48 +02:00
grischka
8cb3e5368f bitfields init : tiny solution
This replaces commit 5c6356ff8e,
except the tests.
2020-09-18 23:31:34 +02:00
herman ten brugge
5c6356ff8e default-initialization of bitfields
The code:

struct bf_SS {unsigned int bit:1,bits31:31; };
void func(void) {
  struct bf_SS bf_finit = { .bit = 1 };
}

will not init bits31 to 0.

tccgen.c:
- check_bf: New function to check if bitfield is present in struct/union
- decl_initializer: Call check_bf and set value to 0 is bitfield found

tests/tcctest.c:
- Add struct bitfield test code
2020-09-18 19:20:57 +02:00
herman ten brugge
c9bbd4e707 Allow strings in __builtin_constant_p
tccgen.c:
- Fix handling __builtin_constant_p

tests/bug.c:
- Remove tst3

tests/tcctest.c:
- Add new tests for __builtin_constant_p
2020-09-17 09:11:10 +02:00
Kyryl Melekhin
618ba55a81 fix float to u64 intrinsics
reverts commit
310e3b428c
(more info there)

now functions check for
sign bit in float.

now hopefully this patch will
cover entirety of areas it might affect
2020-09-10 17:35:36 +00:00
Kyryl Melekhin
310e3b428c (bug caused by tcc intristics)
reproduce bug:
$ ./configure --cc=gcc
$ make
$ make install
(OK)
run a test:

extern int printf(const char *str, ...);
int main()
{
        int t2 = (int)(-1.847759065f * 4096);
        printf("%d\n", t2);
}

$ tcc test.c
$ ./a.out
$ -7568
(OK)

(self compiled now)
$ ./configure --cc=tcc
$ make
$ make install
(OK)

$ tcc test.c
$ ./a.out
$ 7568
(WRONG!!!)

why:
gcc does not have intristics for
uint to long double conversion
therefore it does cast implicitly, so
the sign bit is preserved, but this does
not happen when __fixunsxfdi is called
because tcc was bootstrapped.

solution:
force cast to int64 and preserve the
sign bit.

side effects:
not found.
2020-09-08 22:12:01 +00:00
grischka
53d815b8a0 win32/tccpe: use full dll-path with -run
This allows for example this scenario:

- A dll to be linked with is specified in file.c, where file.c
  and the dll exist in the same directory:
    #pragma comment(lib, "txml")
    #pragma comment(option, "-L{f}")

- tcc is called to run file.c from other, varying directories:
    $ tcc -run some/dir/file.c <args...>

Note that tcc replaces {f} by the currently compiled file's
directory ('some/dir' in this example).

Also:
- tccgen.c: fix last commit for gen_cast.
2020-08-21 22:47:56 +02:00
grischka
d746e32349 tests2: rework 117..119 to follow our conventions
Please respect some conventions:

- tests2 filenames don't end with '..._test'

- tests2 tests are meant to produce some output

- the output should be somehow informative, not just
  "error" or "dummy". Because other people would want to
  know where it fails if it does.

- tests2 tests should work with both GCC and TCC, except
  if there are specifc reasons (like testing tcc-only
  feature such as bounds checking)

- tests2 tests should never crash or abort.  Because that
  would cause gui dialogs to pop up on windows, and because
  other people would not know where it fails if it does.

- tests2 tests should be somehow specific, in general.
  (rather than just collections of random stuff)

- in general, do not use 'long' if you mean 'larger than int'
  Because it isn't on many platforms.

- use four (4) spaces for block indention.  Do not insert
  tab characters in files if possible.

Also:
- tccgen.c:gen_cast() simplify last fix.
2020-08-21 21:44:11 +02:00
grischka
f9870f7860 bcheck: remove static (compile-time) control
Providing both run-time and compile-time control for bounds
checking as an user interface appears unnecessary and confusing.

Also:
- replace 'bound_...' by 'bounds_...' for consistency
- tcc-doc: put related info into one place and cleanup

The __bounds_checking(x) function is still missing explanation.
(I.e. what happens if the accumulated value drops below zero.)
2020-08-21 20:26:36 +02:00
herman ten brugge
a34a9775ba Fix char to ushort cast
tccgen.c:
- gen_cast: add check for char to ushort cast

tests/bug.c:
- remove tst1

tests/tests2/117_gcc_test.c:
- add tst_cast
2020-08-21 19:35:30 +02:00
herman ten brugge
696b765437 Fix switch/case
Fix switch for signed/unsigned switch
Also add new testcase 118
2020-08-18 20:05:53 +02:00
Willy Tarreau
b107f7bdd9 Fix switch/case on uint64_t
The switch/case operation was entirely performed on int64_t, resulting
in a warning and bad code to be emitted on 64 bit machines when used on
an unsigned long with a case range whose signed representation starts
positive and ends negative like in the example below:

  #include <limits.h>
  #include <stdio.h>
  #include <stdlib.h>

  int nbdg(unsigned long n)
  {
  	switch (n) {
  	case                    1UL ...                   9UL: return 1;
  	case                   10UL ...                  99UL: return 2;
  	case                  100UL ...                 999UL: return 3;
  	case                 1000UL ...                9999UL: return 4;
  	case                10000UL ...               99999UL: return 5;
  	case               100000UL ...              999999UL: return 6;
  	case              1000000UL ...             9999999UL: return 7;
  	case             10000000UL ...            99999999UL: return 8;
  	case            100000000UL ...           999999999UL: return 9;
  	case           1000000000UL ...          9999999999UL: return 10;
  	case          10000000000UL ...         99999999999UL: return 11;
  	case         100000000000UL ...        999999999999UL: return 12;
  	case        1000000000000UL ...       9999999999999UL: return 13;
  	case       10000000000000UL ...      99999999999999UL: return 14;
  	case      100000000000000UL ...     999999999999999UL: return 15;
  	case     1000000000000000UL ...    9999999999999999UL: return 16;
  	case    10000000000000000UL ...   99999999999999999UL: return 17;
  	case   100000000000000000UL ...  999999999999999999UL: return 18;
  	case  1000000000000000000UL ... 9999999999999999999UL: return 19; // this one
  	case 10000000000000000000UL ...             ULONG_MAX: return 20;
  	}
  	return 0;
  }

  int main(int argc, char **argv)
  {
  	unsigned long v = strtoul(argc > 1 ? argv[1] : "1111", NULL, 0);
  	printf("%lu : %d\n", v, nbdg(v));
  	return 0;
  }

  $ tcc dg.c
  dg.c:26: warning: empty case range
  $ x="";for i in 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0; do x=$x$i; ./a.out $x;done
  1 : 1
  12 : 2
  123 : 3
  1234 : 4
  12345 : 5
  123456 : 6
  1234567 : 7
  12345678 : 8
  123456789 : 9
  1234567890 : 10
  12345678901 : 11
  123456789012 : 12
  1234567890123 : 13
  12345678901234 : 14
  123456789012345 : 15
  1234567890123456 : 16
  12345678901234567 : 17
  123456789012345678 : 18
  1234567890123456789 : 0
  12345678901234567890 : 20

What this patch does is to use a separate set of signed and unsigned
case_cmp functions depending on whether the expression is signed or
unsigned, and also does this to decide when to emit the warning.

The bad code on output was caused by the removal of the unsigned bit
resulting from the signed sort, which causes only signed comparisons
to be emitted in the asm code. As such some sets could not match.

Note that there is no way to rely on the values only to sort properly
nor to emit the warning because we're effectively dealing with 65-bit
arithmetic here and any two values will have a different behavior
depending on the signed or unsigned expectation.

For unsigned expressions now the warning only happens when bounds are
switched, For signed expressions (e.g. if the input is signed long
above), the warning remains and the abnormal output as well. In both
cases this remains consistent with what gcc produces.
2020-08-18 11:27:27 +02:00
herman ten brugge
4c9e3a5988 Update attribute bound_no_checking
tcctok.h:
- Add CONFIG_TCC_BCHECK  arround TOK_NO_BOUND_CHECK1/TOK_NO_BOUND_CHECK2

tccgen.c:
- Add CONFIG_TCC_BCHECK  arround TOK_NO_BOUND_CHECK1/TOK_NO_BOUND_CHECK2
- Undo alias definition in tccpp.c when function bound checking if off

tests/tests2/114_bound_signal.c:
- Test alias undo
- fix sleep problem
2020-08-14 06:35:47 +02:00
herman ten brugge
c740fa2795 Fix attribute patch for windows 2020-08-13 11:26:59 +02:00
herman ten brugge
50fe33f880 Add attribute bound_no_checking
tcc-doc.texi:
- Document attribute bound_no_checking

tcctok.h:
- Add bound_no_checking attribute

tcc.h:
- Add no_bcheck function attribute

tccgen.c:
- Use function attribute no_bcheck in merge_funcattr/parse_attribute/gen_function

bcheck.c:
- Fix no_checking in __bound_new_region/__bound_free/__bound_check

tests/tests2/114_bound_signal.c:
- Fix code with new attribute bound_no_checking

tests/tests2/103_implicit_memmove.c:
- Fix memmove prototype
2020-08-13 11:19:11 +02:00
herman ten brugge
8b8e714517 Fix bound checking for packed struct 2020-08-11 07:33:11 +02:00
herman ten brugge
09ed7e9557 Add bool debug type 2020-08-11 07:23:01 +02:00
herman ten brugge
dcb87d36fe Fix long bitfield
The fix is avoiding a core dump for radare2 project.
2020-08-09 07:50:34 +02:00
herman ten brugge
d55a3f3362 Fix riscv64 compare problem.
Fix 64->32 bits sign/zero extention for riscv64.
2020-07-30 09:40:35 +02:00
herman ten brugge
c1e1c17c0a Move bound functions to tccgen.c
Move gen_bounded_ptr_add() and gen_bounded_ptr_deref() code to tccgen.c
No functional changes.
2020-07-12 10:55:40 +02:00
herman ten brugge
fc05da3c0b Fix alloca and arm problems
alloca is only defined for i386 and x86_64
arm has __aeabi_ prefixes for mem... calls
2020-07-06 20:10:56 +02:00
grischka
2a0167adfe __builtin_/__bound_: A 'stay tiny' approach to the matter
tccgen.c:
- cleanup __builtin_... stuff
- merge __attribute((alias("sym"))) with __asm__("sym")
    Now one cannot have both, however for alias underscores are
    added if enabled.  For __asm__ they aren't.
tccpp.c:
- extend tcc_predefs accordingly.  Was generated with
  'cd tests/misc && tcc -run c2str.c tcc_predef.h tcc_predefs'
xxx-gen.c:
- move bcheck setjmp test to tccgen.c:gbound_args()
i386-gen.c:
- create win32 compatible stack space for big structures
tcctest.c:
- some cleanup + nicer output
2020-07-06 13:42:02 +02:00
grischka
72277967ff some cleanups related to recent commits
- configure/Makefile : cleanup, really use CC_NAME
- tccasm.c : remove C99 construct that MSVC doesn't compile
- arm-gen.c, x86_64-gen.c, riscv64-gen.c, tccmacho.c : ditto
- arm64-gen.c: commit 383acf8eff wrote:
  "Instead of a cast, it would be better to pass the exact type."
  It is true that there are better solutions but it is not
  passing the exact type (I think).
- tcctest.c: revert "fix cast test for clang" 03646ad46f
  this obviously wants to test non-portable conversions
- 114_bound_signal.test: clock_nanosleep is too new for older
  linuxes, just use sleep() instead
2020-07-06 13:00:47 +02:00
herman ten brugge
9712aff9c0 Fix gcc testsuite problems
arm-gen.c:
- is_hgen_float_aggr/gfunc_sret: Fix for zero sized structs

arm64-gen.c:
- arm64_ldrs: Fix for zero sized structs
- arm64_sym: Use R_AARCH64_ABS64 instead of R_AARCH64_MOVW_UABS_G*
             This has same speed. See 117_gcc_test.c(tst_adr)
- load: Fix for zero sized structs and add VT_CONST | VT_LVAL support
- store: add VT_CONST | VT_LVAL support
- arm64_gen_bl_or_b: Allow branch. See 117_gcc_test.c(tst_branch)
- gen_bounds_prolog: Use R_AARCH64_ABS64 for bound checking
- gen_bounds_epilog: Use R_AARCH64_ABS64 for bound checking
- gfunc_call: Allow large stack
- arm64_gen_opic: Do not crash on large shift

riscv64-gen.c:
- load: Move type_size call. (move_reg set sv.type.ref NULL for VT_STRUCT)
- gfunc_call: Allow large stack
- gen_opil: Fix word mode calls

x86_64-gen.c:
- load: Fix for zero sized structs

libtcc.c:
- Add some defines for gcc testsuite (only most common)

tccgen.c:
- parse_builtin_params: Add types for builtins
- unary: Add builtins: __builtin_abort __builtin_memcpy __builtin_memcmp
                       __builtin_memmove __builtin_memset __builtin_strlen
                       __builtin_strcpy __builtin_strncpy __builtin_strcmp
                       __builtin_strncmp __builtin_strcat __builtin_strchr
                       __builtin_strdup __builtin_malloc __builtin_realloc
                       __builtin_calloc __builtin_free __builtin_alloca
- decl_initializer: Fix crash. See 60_errors_and_warnings(test_var_array)

tccmacho.c:
- Remove 'ret = 0'

tcctok.h:
- Add builtin/bound checking tokens

tests/gcctestsuite.sh:
- Add more counters and run execute tests

tests/bug.c
- Some remaining bugs in tcc (not complete)

tests/tests2/60_errors_and_warnings:
- Add test_var_array test

tests/tests2/117_gcc_test:
- New test

Results of gcctestsuite.sh for all targets:

linux:
x86_64: 3036 test(s) ok.  328 test(s) failed.  24 test(s) exe failed.
i386:   3037 test(s) ok.  327 test(s) failed.  24 test(s) exe failed.
arm:    2986 test(s) ok.  362 test(s) failed.  40 test(s) exe failed.
arm64:  2996 test(s) ok.  367 test(s) failed.  25 test(s) exe failed.
macos:  3031 test(s) ok.  332 test(s) failed.  25 test(s) exe failed.
riscv:  2948 test(s) ok.  401 test(s) failed.  39 test(s) exe failed.

windows:
x86_64: 3027 test(s) ok.  333 test(s) failed.  28 test(s) exe failed.
i386:   3029 test(s) ok.  331 test(s) failed.  28 test(s) exe failed.

linux with bounds checking:
x86_64: 3030 test(s) ok.  328 test(s) failed.  30 test(s) exe failed.
i386:   3028 test(s) ok.  327 test(s) failed.  33 test(s) exe failed.
arm:    2997 test(s) ok.  362 test(s) failed.  29 test(s) exe failed.
arm64:  2986 test(s) ok.  367 test(s) failed.  35 test(s) exe failed.
macos:  3026 test(s) ok.  332 test(s) failed.  30 test(s) exe failed.
riscv:  2936 test(s) ok.  409 test(s) failed.  43 test(s) exe failed.

windows with bounds checking:
x86_64: 3029 test(s) ok.  332 test(s) failed.  27 test(s) exe failed.
i386:   3027 test(s) ok.  331 test(s) failed.  30 test(s) exe failed.

all: fail for complex and vector types, nested functions
     and a lot of gcc defines/buitins.
arm/arm64/riscv: fail for asm and alloca.
riscv: fail with 'error: unimp: store(struct)'
2020-07-05 14:01:50 +02:00
Michael Matz
ba8980f492 limit gnu_inline hack to macos
some linux programs (kernel) really want to have 'extern inline'
functions be visible from other units, i.e. not be static, but also
mark them as always_inline.  That's -fgnu89-inline semantics, so it's
fine, but we don't (yet) implement this, so we can't make them static
just so.  But we do need this hack on MacOS due to some uses in
system headers (see commit f18f8651).

So, for now conditionalize the hack on Mach-O.
2020-06-21 02:03:46 +02:00
Michael Matz
f18f865159 Handle always_inline as GNU inline
this is needed for multi-file testcases using stdio.h, as
the __sputc function is implemented as a extern inline
function (with gnu_inline attribute, but we don't support that for now).

Without this change that leads to multiply defined symbols when using
multiple units including stdio.h.

It also has an always_inline attribute, which we can use to guide our
behaviour, as in ISO-C an always_inline can't be defined with ISO
'extern inline' semantics.  This is the minimal change and not a full
implementation of GNU inline semantics, which would require thorough
testcases.

If __clang__ would be defined the header would make use of C99 semantics,
which would work for us.  It would also do that if _GNUC_ wouldn't be
defined.  But we can't do the latter (as the whole MacOSX SDK refuses
to be compiled with anything not defining that).  I haven't tested
defining __clang__, but suspect that's going to be problematic.
2020-06-20 22:14:56 +02:00
Michael Matz
94066765ed macos: First cut at generating Mach-O executables
this does generate a working executable for a very simple
example input, e.g. this:

% cat simple.c
int main(void)
{
  return 0;
}
% ./tcc -B. -c simple.c
% ./tcc -nostdlib -B. simple.o -lc
% ./a.out && echo okay
okay

(the -lc is actually not necessary right now, see below).  This
has many limitations:

* no symbol table, hence no calls to external functions from
  e.g. libc, aka libSystemB
* no proper entry point (should be main, but is hardcoded to first
  real .text address)
* libSystemB is hardcoded, no other libs are supported (but again
  no external calls anyway)
* generated Mach-O executable is in old format: neither LC_DYLD_INFO
  no export tries for symbols are created (no symbol table at all!)
* the __LINKEDIT segment is faked and empty, as dyld doesn't like
  it empty even if no symbols point into it
* same with __DATA, dyld wants a non-empty writable segment which
  we enforce with useless data
* no relocations, hence no function call stubs (lazy or not) are
  generated
* hardcodes some other constants as well
2020-06-20 22:09:21 +02:00
Michael Matz
7b6931ed1f Fix some string literal expressions in initializers
Things like 'char x[] = { "foo"[1], 0 }' (which should initialize
a two-character array 'x' with "o\0").  See added testcase.
2020-06-20 22:00:18 +02:00
grischka
b5faa45d90 tccpp: faster next()
- call TOK_GET() as a function only for tokens with values
- get rid of 'next_nomacro_spc()'
- be sligtly more efficient in next()

This made about 4-5%+ speed in my tests.

Also: tcc.h: reorder tokens
2020-06-17 18:44:11 +02:00
herman ten brugge
44019e874f Fix debug info for functions
Add code for VT_FUNC.
Use octal number for unsigned int/unsigned long for 32 bits targets.
Add VT_BYTE | VT_UNSIGNED for targets with default unsigned signed char.
Remove extra ',' in default_debug struct.
2020-06-17 07:58:18 +02:00
herman ten brugge
0b8ee7364a Add bound checking to arm, arm64 and riscv64
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
2020-06-16 07:39:48 +02:00
Michael Matz
9eef33993a Fix type compatiblity of enums and ints
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
2020-06-05 16:02:08 +02:00
herman ten brugge
3b617fdc53 Add sigsetjmp/siglongjmp bound checking support
tcctok.h:
- Add sigsetjmp/__sigsetjmp/siglongjmp

tccgen.c:
- redirect sigsetjmp/siglongjmp to bcheck.c code

i386-gen.c/x86_64-gen.c
- gcall_or_jmp: Set func_bound_add_epilog also when sigsetjmp is called
- gen_bounds_epilog: Only call __bound_local_new when needed (unrelated)

bcheck.c:
- Add __bound_siglongjmp
- __bound_setjmp/__bound_long_jump: Check no_checking
- Optimize __bound_local_delete (unrelated)

Modify testcase:
- 114_bound_signal
2020-05-25 12:26:55 +02:00
herman ten brugge
045632defb Fix gcc10 warnings
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.
2020-05-23 20:27:43 +02:00
herman ten brugge
b5b92c7d6d Add setjmp/longjmp bound checking support
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
2020-05-23 20:02:41 +02:00
grischka
4429cef9f6 tccgen.c: merge more function attributes
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).
2020-05-13 11:39:39 +02:00
grischka
9c28349757 tccgen.c: cleanup debug support
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
2020-05-11 11:41:56 +02:00