aboutsummaryrefslogtreecommitdiff
path: root/tccrun.c
diff options
context:
space:
mode:
authorgrischka <grischka>2017-10-11 18:13:43 +0200
committergrischka <grischka>2017-10-11 18:13:43 +0200
commitda8c62f75d893449e232944fc62566c020b4d010 (patch)
tree977fec8d53d90ceb8c718f07f47c2bc9cbd6edfc /tccrun.c
parentfaa9744f5d13c94c7298bf08e8d1eedca5db88a9 (diff)
downloadtinycc-da8c62f75d893449e232944fc62566c020b4d010.tar.gz
tinycc-da8c62f75d893449e232944fc62566c020b4d010.tar.bz2
various stuff
win32/Makefile ("for cygwin") removed - On cygwin, the normal ./configure && make can be used with either cygwin's "GCC for Win32 Toolchain" ./configure --cross-prefix=i686-w64-mingw32- or with an existing tcc: ./configure --cc=<old-tccdir>/tcc.exe tcctest.c: - exclude test_high_clobbers() on _WIN64 (does not work) tests2/95_bitfield.c: - use 'signed char' for ARM (where default 'char' is unsigned) tests: - remove -I "expr" diff option to allow tests with busybox-diff. libtcc.c, tcc.c: - removed -iwithprefix option. It is supposed to be combined with -iprefix which we don't have either. tccgen.c: - fix assignments and return of 'void', as in void f() { void *p, *q; *p = *q: return *p; } This appears to be allowed but should do nothing. tcc.h, libtcc.c, tccpp.c: - Revert "Introduce VIP sysinclude paths which are always searched first" This reverts commit 1d5e386b0a78393ac6b670c209a185849ec798a1. The patch was giving tcc's system includes priority over -I which is not how it should be. tccelf.c: - add DT_TEXTREL tag only if text relocations are actually used (which is likely not the case on x86_64) - prepare_dynamic_rel(): avoid relocation of unresolved (weak) symbols tccrun.c: - for HAVE_SELINUX, use two mappings to the same (real) file. (it was so once except the RX mapping wasn't used at all). tccpe.c: - fix relocation constant used for x86_64 (by Andrei E. Warentin) - #ifndef _WIN32 do "chmod 755 ..." to get runnable exes on cygwin. tccasm.c: - keep forward asm labels static, otherwise they will endup in dynsym eventually. configure, Makefile: - mingw32: respect ./configure options --bindir --docdir --libdir - allow overriding tcc when building libtcc1.a and libtcc.def with make XTCC=<tcc program to use> - use $(wildcard ...) for install to allow installing just a cross compiler for example make cross-arm make install - use name <target>-libtcc1.a build-tcc.bat: - add options: -clean, -b bindir
Diffstat (limited to 'tccrun.c')
-rw-r--r--tccrun.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/tccrun.c b/tccrun.c
index 85957b8..b9a052b 100644
--- a/tccrun.c
+++ b/tccrun.c
@@ -45,15 +45,13 @@ static void set_exception_handler(void);
#endif
static void set_pages_executable(void *ptr, unsigned long length);
-static int tcc_relocate_ex(TCCState *s1, void *ptr);
+static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff);
#ifdef _WIN64
static void *win64_add_function_table(TCCState *s1);
static void win64_del_function_table(void *);
#endif
-// #define HAVE_SELINUX
-
/* ------------------------------------------------------------- */
/* Do all relocations (needed before using tcc_get_symbol())
Returns -1 on error. */
@@ -61,25 +59,36 @@ static void win64_del_function_table(void *);
LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr)
{
int size;
+ addr_t ptr_diff = 0;
if (TCC_RELOCATE_AUTO != ptr)
- return tcc_relocate_ex(s1, ptr);
+ return tcc_relocate_ex(s1, ptr, 0);
- size = tcc_relocate_ex(s1, NULL);
+ size = tcc_relocate_ex(s1, NULL, 0);
if (size < 0)
return -1;
#ifdef HAVE_SELINUX
- /* Use mmap instead of malloc for Selinux. */
- ptr = mmap (NULL, size, PROT_READ|PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (ptr == MAP_FAILED)
- tcc_error("tccrun: could not map memory");
+{
+ /* Using mmap instead of malloc */
+ void *prx;
+ char tmpfname[] = "/tmp/.tccrunXXXXXX";
+ int fd = mkstemp(tmpfname);
+ unlink(tmpfname);
+ ftruncate(fd, size);
+
+ ptr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ prx = mmap (NULL, size, PROT_READ|PROT_EXEC, MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED || prx == MAP_FAILED)
+ tcc_error("tccrun: could not map memory");
dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, (void*)(addr_t)size);
+ dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, prx);
+ ptr_diff = (char*)prx - (char*)ptr;
+}
#else
ptr = tcc_malloc(size);
#endif
- tcc_relocate_ex(s1, ptr); /* no more errors expected */
+ tcc_relocate_ex(s1, ptr, ptr_diff); /* no more errors expected */
dynarray_add(&s1->runtime_mem, &s1->nb_runtime_mem, ptr);
return 0;
}
@@ -91,6 +100,7 @@ ST_FUNC void tcc_run_free(TCCState *s1)
for (i = 0; i < s1->nb_runtime_mem; ++i) {
#ifdef HAVE_SELINUX
unsigned size = (unsigned)(addr_t)s1->runtime_mem[i++];
+ munmap(s1->runtime_mem[i++], size);
munmap(s1->runtime_mem[i], size);
#else
#ifdef _WIN64
@@ -166,7 +176,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
/* relocate code. Return -1 on error, required size if ptr is NULL,
otherwise copy code into buffer passed by the caller */
-static int tcc_relocate_ex(TCCState *s1, void *ptr)
+static int tcc_relocate_ex(TCCState *s1, void *ptr, addr_t ptr_diff)
{
Section *s;
unsigned offset, length, fill, i, k;
@@ -199,7 +209,12 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr)
if (k != !(s->sh_flags & SHF_EXECINSTR))
continue;
offset += fill;
- s->sh_addr = mem ? mem + offset : 0;
+ if (!mem)
+ s->sh_addr = 0;
+ else if (s->sh_flags & SHF_EXECINSTR)
+ s->sh_addr = mem + offset + ptr_diff;
+ else
+ s->sh_addr = mem + offset;
#if 0
if (mem)
printf("%-16s +%02lx %p %04x\n",
@@ -242,13 +257,15 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr)
continue;
length = s->data_offset;
ptr = (void*)s->sh_addr;
+ if (s->sh_flags & SHF_EXECINSTR)
+ ptr = (char*)ptr - ptr_diff;
if (NULL == s->data || s->sh_type == SHT_NOBITS)
memset(ptr, 0, length);
else
memcpy(ptr, s->data, length);
/* mark executable sections as executable in memory */
if (s->sh_flags & SHF_EXECINSTR)
- set_pages_executable(ptr, length);
+ set_pages_executable((char*)ptr + ptr_diff, length);
}
return 0;
}
@@ -263,15 +280,17 @@ static void set_pages_executable(void *ptr, unsigned long length)
VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
#else
void __clear_cache(void *beginning, void *end);
+# ifndef HAVE_SELINUX
addr_t start, end;
-#ifndef PAGESIZE
-# define PAGESIZE 4096
-#endif
+# ifndef PAGESIZE
+# define PAGESIZE 4096
+# endif
start = (addr_t)ptr & ~(PAGESIZE - 1);
end = (addr_t)ptr + length;
end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
if (mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC))
tcc_error("mprotect failed: did you mean to configure --with-selinux?");
+# endif
# if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64
__clear_cache(ptr, (char *)ptr + length);
# endif