When bound check is enabled, tcc tries to relocate a call to
__bound_init in _init. This means that relocation (in tcc_add_bcheck)
must be done after libtcc1.a (which countains __bound_init) is loaded
but before crtn.o is loaded as this finalize _init.
Prior to this commit runtime library was compiled according to the host
because of the macro used to detec what architecture to choose. This
commit fixes this by using the TARGET_* macro instead.
Call fill_got_entry unconditionally from fill_got so as to avoid
warnings on !x86-64 architectures. This can be done since this code path
is only followed by x86-64 architecture anyway.
When checking for exact compatibility between types (such as in
__builtin_types_compatible_p) consider the case of default signedness to
be incompatible with both of the explicit signedness for char. That is,
char is incompatible with signed char *and* unsigned char, no matter
what the default signedness for char is.
Result of float to unsigned integer conversion is undefined if float is
negative. This commit take the absolute value of the float before doing
the conversion to unsigned integer and add more float to integer
conversion test.
This improves commit 5cbe03b9c4 by
avoiding a double transfer when the default float ABI is already softfp.
It's also more clean by expliciting that the ABI is simply changed for
runtime ABI functions.
EABI functions to convert an int to a double register take the integer
value in core registers and also give the result in core registers.
It is thus necessary to move the result back to VFP register after the
function call. This only affected integer to double conversion because
integer to float conversion used a VFP instruction to do the conversion
and this obviously left the result in VFP register. Note that the
behavior is left untouched for !EABI as the correct behavior in this
case is unknown to the author of this patch.
- Thanks to Kirill "tcc -b itself" should work now
(was removed in d5f4df09ff)
Also:
- tests/Makefile:
- fix spurious --I from 767410b875
- lookup boundtest.c via VPATH (for out-of-tree build)
- test[123]b?: fail on diff error
- Windows: test3 now works (from e31579b076)
- abitest: a libtcc.a made by gcc is not usable for tcc
on WIndows - using source instead (libtcc.c)
- tccpe:
- avoid gcc warning (x86_64)
On my x86_64 box in i386 mode with address space randomization turned off,
I've observed the following:
tests$ ../tcc -B.. -b -run boundtest.c 1
Runtime error: dereferencing invalid pointer
boundtest.c:222: at 0x808da73 main()
With diagnostic patch (like in efd9d92b "lib/bcheck: Don't assume heap
goes right after bss") and bcheck traces for __bound_new_region,
__bound_ptr_indir, etc... here is how the program run looks like:
>>> TCC
etext: 0x8067ed8
edata: 0x807321d
end: 0x807d95c
brk: 0x807e000
stack: 0xffffd0b4
&errno: 0xf7dbd688
mark_invalid 0xfff80000 - (nil)
mark_invalid 0x80fa000 - 0x100fa000
new 808fdb0 808ff40 101 101 fd0 ff0
new 808ff44 808ff48 101 101 ff0 ff0
new 808ff49 8090049 101 101 ff0 1000
new 808fd20 808fd29 101 101 fd0 fd0
new 808fd2c 808fd6c 101 101 fd0 fd0
new 808fd6d 808fda0 101 101 fd0 fd0
E: __bound_ptr_indir4(0xffffd184, 0x4)
Runtime error: dereferencing invalid pointer
boundtest.c:222: at 0x808ea83 main()
So we are accessing something on stack, above stack entry for compiled
main. Investigating with gdb shows that this is argv:
tests$ gdb ../tcc
Reading symbols from /home/kirr/src/tools/tinycc/tcc...done.
(gdb) set args -B.. -b -run boundtest.c 1
(gdb) r
Starting program: /home/kirr/src/tools/tinycc/tests/../tcc -B.. -b -run boundtest.c 1
warning: Could not load shared library symbols for linux-gate.so.1.
Do you need "set solib-search-path" or "set sysroot"?
>>> TCC
etext: 0x8067ed8
edata: 0x807321d
end: 0x807d95c
brk: 0x807e000
stack: 0xffffd074
&errno: 0xf7dbd688
mark_invalid 0xfff80000 - (nil)
mark_invalid 0x80fa000 - 0x100fa000
new 808fdb0 808ff40 101 101 fd0 ff0
new 808ff44 808ff48 101 101 ff0 ff0
new 808ff49 8090049 101 101 ff0 1000
new 808fd20 808fd29 101 101 fd0 fd0
new 808fd2c 808fd6c 101 101 fd0 fd0
new 808fd6d 808fda0 101 101 fd0 fd0
E: __bound_ptr_indir4(0xffffd144, 0x4)
Program received signal SIGSEGV, Segmentation fault.
0x0808ea83 in ?? ()
(gdb) bt
#0 0x0808ea83 in ?? ()
#1 0x080639b3 in tcc_run (s1=s1@entry=0x807e008, argc=argc@entry=2, argv=argv@entry=0xffffd144) at tccrun.c:132
#2 0x080492b0 in main (argc=6, argv=0xffffd134) at tcc.c:346
(gdb) f 1
#1 0x080639b3 in tcc_run (s1=s1@entry=0x807e008, argc=argc@entry=2, argv=argv@entry=0xffffd144) at tccrun.c:132
132 ret = (*prog_main)(argc, argv);
132 ret = (*prog_main)(argc, argv);
(gdb) p argv
$1 = (char **) 0xffffd144
So before running compiled program, mark argv as valid region and we are
done - now the test passes.
P.S. maybe it would be better to just mark the whole vector kernel passes to
program (argv, env, auxv, etc...) as valid all at once...
when x86-64 support was added, "for long double, we use x87 FPU".
And indeed, tests show that Intel's extended precision is used,
not double precision.
negate(x) is subtract(-0,x), not subtract(+0,x), which makes
a difference with signed zeros. Also +x was expressed as x+0,
in order for the integer promotions to happen, but also mangles signed
zeros, so just don't do that with floating types.