The problem was with tcctest.c:
unsigned set;
__asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc");
when with tcc compiled with the HAVE_SELINUX option, run with
tcc -run, it would use large addresses far beyond the 32bits
range when tcc did not use the pc-relative mode for accessing
'set' in global data memory. In fact the assembler did not
know about %rip at all.
Changes:
- memory operands use (%rax) not (%eax)
- conversion from VT_LLOCAL: use type VT_PTR
- support 'k' modifier
- support %rip register
- support X(%rip) pc-relative addresses
The test in tcctest.c is from Michael Matz.
- call RtlDeleteFunctionTable
(important for multiple compilations)
- the RUNTIME_FUNCTION* is now at the beginning of the
runtime memory. Therefor when tcc_relocate is called
with user memory, this should be done manually before
it is free'd:
RtlDeleteFunctionTable(*(void**)user_mem);
[ free(user_mem); ]
- x86_64-gen.c: expand char/short return values to int
Makefile :
- do not 'uninstall' peoples /usr/local/doc entirely
libtcc.c :
- MEM_DEBUG : IDE-friendly output "file:line: ..."
- always ELF for objects
tccgen.c :
- fix memory leak in new switch code
- move static 'in_sizeof' out of function
profiling :
- define 'static' to empty
resolve_sym() :
- replace by dlsym()
win32/64: fix R_XXX_RELATIVE fixme
- was fixed for i386 already in
8e4d64be2f
- do not -Lsystemdir if compiling to .o
* Documentation is now in "docs".
* Source code is now in "src".
* Misc. fixes here and there so that everything still works.
I think I got everything in this commit, but I only tested this
on Linux (Make) and Windows (CMake), so I might've messed
something up on other platforms...
On Linux 32: sizeof(long)=32 == sizeof(void *)=32
on Linux 64: sizeof(long)=64 == sizeof(void *)=64
on Windows 64: sizeof(long)=32 != sizeof(void *)=64
The following program (errno.c) reports errno=2 when run
using "tcc -run errno.c"
#include <errno.h>
#include <stdio.h>
int main(void) { printf("errno=%d\n", errno); return 0; }
This adds some more support for properly transfering some
offsets over the different stages of a relocations life.
Still not at all psABI compliant and DSOs can't yet be generated.
But it runs the testsuite in qemu-arm64.
Not able to generate ELF files on NetBSD yet (lacks the note and crt1.o
is actually named crt0.o on NetBSD), but -run works with these extra
defines:
-D__lint__ -D"__symbolrename(x)=asm(#x)" -D__NetBSD__
The -D__lint__ is an ugly hack, TCC should be able to emulate GCC just
fine, but it seems TCC doesn't support __builtin_va_list yet?
typedef __builtin_va_list __va_list;
/usr/include/sys/ansi.h:72: error: ';' expected (got "__va_list")
This makes us use the normal PLT/GOT codepaths also for -run,
which formerly used an on-the-side blob for the jump tables.
For x86_64 only for now, arm coming up.
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...
- Use runtime function for conversion
- Also initialize fp with tcc -run on windows
This fixes a bug where
double x = 1.0;
double y = 1.0000000000000001;
double z = x < y ? 0 : sqrt (x*x - y*y);
caused a bad sqrt because rounding precision for the x < y comparison
was different to the one used within the sqrt function.
This also fixes a bug where
printf("%d, %d", (int)pow(10, 2), (int)pow(10, 2));
would print
100, 99
Unrelated:
win32: document relative include & lib lookup
win32: normalize_slashes: do not mirror silly gcc behavior
This reverts part of commit 8a81f9e103
winapi: add missing WINAPI decl. for some functions
On some architectures, ARM for instance, the data and instruction caches
are not coherent with each other. This is a problem for the -run feature
since instructions are written in memory, and are thus written in the
data cache first and then later flushed to the main memory. If the
instructions are executed before they are pushed out of the cache, then
the processor will fetch the old content from the memory and not the
newly generated code. The solution is to flush from the data cache all
the data in the memory region containing the instructions and to
invalidate the same region in the instruction cache.
This replaces -> use instead:
-----------------------------------
- tcc_set_linker -> tcc_set_options(s, "-Wl,...");
- tcc_set_warning -> tcc_set_options(s, "-W...");
- tcc_enable_debug -> tcc_set_options(s, "-g");
parse_args is moved to libtcc.c (now tcc_parse_args).
Also some cleanups:
- reorder TCCState members
- add some comments here and there
- do not use argv's directly, make string copies
- use const char* in tcc_set_linker
- tccpe: use fd instead of fp
tested with -D MEM_DEBUG: 0 bytes left
tests:
- add "hello" to test first basic compilation to file/memory
- add "more" test (tests2 suite)
- remove some tests
tests2:
- move into tests dir
- Convert some files from DOS to unix LF
- remove 2>&1 redirection
win32:
- tccrun.c: modify exception filter to exit correctly (needed for btest)
- tcctest.c: exclude weak_test() (feature does not exist on win32)
We are now compatible with the 0.9,25 version though. A special
value for the second (ptr) argument is used to get the simple
behavior as with the 0.9.24 version.
This changeset attempts to fix a few problems when giving using
the high 32bits of a 64bit section offset. There are likely more
issues (or perhaps regressions) lurking in the muck here. In general,
this moves a few data type declarations to use uplong. Also, add
support for 64bit mingw32 building under cygwin. Because native
types are used for 64 bit offsets, this won't fix challenges with
cross compiling from 32bit -> 64bit.
Tested under cygwin, against binary compiled with
-Wl,-Ttext=0xffffff8000000000
Signed-off-by: Andrew Mulbrook <andrew262@gmail.com>
Applied patch found on stackoverflow (link below). I also found some
related changes that looked like logically needed. The stackoverflow
changes addressed only two registers which were breaking a compile.
However reading the code in the same file shows two other register
accesses that, while not breaking the build, should have the same fix.
http://stackoverflow.com/questions/3712902/problems-compiling-tcc-on-os-x/3713144#3713144
The test driver was changed by changing 'cp -u' into 'cp' as '-u' is not
supported on mac osx.
I found that osx build required the WITHOUT_LIBTCC define. I suspect the
reason for this is tcc unability to handle mach-o files. In order to
properly address this I had to change 'configure' to propagate target os
name to Makefile.
Current state is that simple tests work, but not the whole 'make test'
suite runs.
To the best of my knowledge, these changes should not impact other
platforms.
- use {B} to substitute tcc_lih_path (instead of \b)
- expand CONFIG_TCC_CRTPREFIX in CONFIG_TCC_LIBPATHS
which fixes duplicate CONFIG_SYSROOT.
- put default CONFIG_SYSROOT ("") into tcc.h
- remove hack from commit db6fcce78f
because $(tccdir)/include is already in sysincludes
- configure: error out for unrecognized options.
- win32/build-tcc.bat: put libtcc into base dir where it will
find lib/include automatically, and build libtcc_test example.