mirror of
https://github.com/mirror/tinycc.git
synced 2025-01-13 05:10:07 +08:00
tccrun: PAGEALIGN'ed mprotect
the un-mprotect() after run was severly off the limits. Also in tcc.c:main: do not confuse errors with non-zero results from tcc_run()
This commit is contained in:
parent
7bc0cb5ba0
commit
42395a1912
1
configure
vendored
1
configure
vendored
@ -518,6 +518,7 @@ fcho "Doc directory " "$docdir"
|
|||||||
fcho "Target root prefix " "$sysroot"
|
fcho "Target root prefix " "$sysroot"
|
||||||
fcho "/usr/include dir " "$tcc_usrinclude"
|
fcho "/usr/include dir " "$tcc_usrinclude"
|
||||||
echo "Source path $source_path"
|
echo "Source path $source_path"
|
||||||
|
echo "Build OS $(uname -m -s)"
|
||||||
echo "C compiler $cc ($gcc_major.$gcc_minor)"
|
echo "C compiler $cc ($gcc_major.$gcc_minor)"
|
||||||
echo "Target OS $targetos"
|
echo "Target OS $targetos"
|
||||||
echo "CPU $cpu"
|
echo "CPU $cpu"
|
||||||
|
27
tcc.c
27
tcc.c
@ -359,20 +359,18 @@ redo:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* compile or add each files or library */
|
/* compile or add each files or library */
|
||||||
first_file = NULL, ret = 0;
|
first_file = NULL;
|
||||||
do {
|
do {
|
||||||
struct filespec *f = s->files[n];
|
struct filespec *f = s->files[n];
|
||||||
s->filetype = f->type;
|
s->filetype = f->type;
|
||||||
if (f->type & AFF_TYPE_LIB) {
|
if (f->type & AFF_TYPE_LIB) {
|
||||||
if (tcc_add_library_err(s, f->name) < 0)
|
ret = tcc_add_library_err(s, f->name);
|
||||||
ret = 1;
|
|
||||||
} else {
|
} else {
|
||||||
if (1 == s->verbose)
|
if (1 == s->verbose)
|
||||||
printf("-> %s\n", f->name);
|
printf("-> %s\n", f->name);
|
||||||
if (!first_file)
|
if (!first_file)
|
||||||
first_file = f->name;
|
first_file = f->name;
|
||||||
if (tcc_add_file(s, f->name) < 0)
|
ret = tcc_add_file(s, f->name);
|
||||||
ret = 1;
|
|
||||||
}
|
}
|
||||||
done = ret || ++n >= s->nb_files;
|
done = ret || ++n >= s->nb_files;
|
||||||
} while (!done && (s->output_type != TCC_OUTPUT_OBJ || s->option_r));
|
} while (!done && (s->output_type != TCC_OUTPUT_OBJ || s->option_r));
|
||||||
@ -393,21 +391,24 @@ redo:
|
|||||||
if (!s->outfile)
|
if (!s->outfile)
|
||||||
s->outfile = default_outputfile(s, first_file);
|
s->outfile = default_outputfile(s, first_file);
|
||||||
if (!s->just_deps && tcc_output_file(s, s->outfile))
|
if (!s->just_deps && tcc_output_file(s, s->outfile))
|
||||||
ret = 1;
|
;
|
||||||
else if (s->gen_deps)
|
else if (s->gen_deps)
|
||||||
ret = gen_makedeps(s, s->outfile, s->deps_outfile);
|
gen_makedeps(s, s->outfile, s->deps_outfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (done && 0 == t && 0 == ret && s->do_bench)
|
done = 1;
|
||||||
|
if (t)
|
||||||
|
done = 0; /* run more tests with -dt -run */
|
||||||
|
else if (s->nb_errors)
|
||||||
|
ret = 1;
|
||||||
|
else if (n < s->nb_files)
|
||||||
|
done = 0; /* compile more files with -c */
|
||||||
|
else if (s->do_bench)
|
||||||
tcc_print_stats(s, end_time - start_time);
|
tcc_print_stats(s, end_time - start_time);
|
||||||
|
|
||||||
tcc_delete(s);
|
tcc_delete(s);
|
||||||
if (!done)
|
if (!done)
|
||||||
goto redo; /* compile more files with -c */
|
goto redo;
|
||||||
if (t)
|
|
||||||
goto redo; /* run more tests with -dt -run */
|
|
||||||
|
|
||||||
if (ppfp && ppfp != stdout)
|
if (ppfp && ppfp != stdout)
|
||||||
fclose(ppfp);
|
fclose(ppfp);
|
||||||
return ret;
|
return ret;
|
||||||
|
11
tcc.h
11
tcc.h
@ -92,14 +92,6 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
|||||||
# undef CONFIG_TCC_STATIC
|
# undef CONFIG_TCC_STATIC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PAGESIZE
|
|
||||||
# ifdef _SC_PAGESIZE
|
|
||||||
# define PAGESIZE sysconf(_SC_PAGESIZE)
|
|
||||||
# else
|
|
||||||
# define PAGESIZE 4096
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef O_BINARY
|
#ifndef O_BINARY
|
||||||
# define O_BINARY 0
|
# define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
@ -995,7 +987,8 @@ struct TCCState {
|
|||||||
|
|
||||||
#ifdef TCC_IS_NATIVE
|
#ifdef TCC_IS_NATIVE
|
||||||
const char *run_main; /* entry for tcc_run() */
|
const char *run_main; /* entry for tcc_run() */
|
||||||
void *run_ptr; /* ptr to runtime_memory */
|
void *run_mem; /* runtime_memory */
|
||||||
|
void *run_ptr; /* ptr to runtime_memory (aligned) */
|
||||||
unsigned run_size; /* size of runtime_memory */
|
unsigned run_size; /* size of runtime_memory */
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
void *run_function_table; /* unwind data */
|
void *run_function_table; /* unwind data */
|
||||||
|
74
tccrun.c
74
tccrun.c
@ -91,6 +91,19 @@ static void *win64_add_function_table(TCCState *s1);
|
|||||||
static void win64_del_function_table(void *);
|
static void win64_del_function_table(void *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined PAGESIZE
|
||||||
|
# if defined _SC_PAGESIZE
|
||||||
|
# define PAGESIZE sysconf(_SC_PAGESIZE)
|
||||||
|
# elif defined __APPLE__
|
||||||
|
# include <libkern/OSCacheControl.h>
|
||||||
|
# define PAGESIZE getpagesize()
|
||||||
|
# else
|
||||||
|
# define PAGESIZE 4096
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PAGEALIGN(n) ((addr_t)n + (-(addr_t)n & (PAGESIZE-1)))
|
||||||
|
|
||||||
#if !_WIN32 && !__APPLE__
|
#if !_WIN32 && !__APPLE__
|
||||||
//#define HAVE_SELINUX 1
|
//#define HAVE_SELINUX 1
|
||||||
#endif
|
#endif
|
||||||
@ -116,7 +129,8 @@ static int rt_mem(TCCState *s1, int size)
|
|||||||
ptr_diff = (char*)prw - (char*)ptr; /* = size; */
|
ptr_diff = (char*)prw - (char*)ptr; /* = size; */
|
||||||
//printf("map %p %p %p\n", ptr, prw, (void*)ptr_diff);
|
//printf("map %p %p %p\n", ptr, prw, (void*)ptr_diff);
|
||||||
#else
|
#else
|
||||||
ptr = tcc_malloc(size += PAGESIZE); /* one extra page to align malloc memory */
|
s1->run_mem = tcc_malloc(size + PAGESIZE); /* one extra page to align malloc memory */
|
||||||
|
ptr = (void*)PAGEALIGN(s1->run_mem);
|
||||||
#endif
|
#endif
|
||||||
s1->run_ptr = ptr;
|
s1->run_ptr = ptr;
|
||||||
s1->run_size = size;
|
s1->run_size = size;
|
||||||
@ -181,7 +195,7 @@ ST_FUNC void tcc_run_free(TCCState *s1)
|
|||||||
# ifdef _WIN64
|
# ifdef _WIN64
|
||||||
win64_del_function_table(s1->run_function_table);
|
win64_del_function_table(s1->run_function_table);
|
||||||
# endif
|
# endif
|
||||||
tcc_free(ptr);
|
tcc_free(s1->run_mem);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,11 +228,11 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
|||||||
top_sym = "main";
|
top_sym = "main";
|
||||||
}
|
}
|
||||||
if (tcc_relocate(s1) < 0)
|
if (tcc_relocate(s1) < 0)
|
||||||
return 1;
|
return -1;
|
||||||
|
|
||||||
prog_main = (void*)get_sym_addr(s1, s1->run_main, 1, 1);
|
prog_main = (void*)get_sym_addr(s1, s1->run_main, 1, 1);
|
||||||
if ((addr_t)-1 == (addr_t)prog_main)
|
if ((addr_t)-1 == (addr_t)prog_main)
|
||||||
return 1;
|
return -1;
|
||||||
errno = 0; /* clean errno value */
|
errno = 0; /* clean errno value */
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
@ -274,12 +288,9 @@ static void cleanup_sections(TCCState *s1)
|
|||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* 0 = .text rwx other rw */
|
/* 0 = .text rwx other rw */
|
||||||
/* 1 = .text rx .rdata r .data/.bss rw */
|
/* 1 = .text rx .rdata r .data/.bss rw */
|
||||||
|
|
||||||
#ifndef CONFIG_RUNMEM_RO
|
#ifndef CONFIG_RUNMEM_RO
|
||||||
# ifdef _WIN32
|
# define CONFIG_RUNMEM_RO 0
|
||||||
# define CONFIG_RUNMEM_RO 0
|
|
||||||
# else
|
|
||||||
# define CONFIG_RUNMEM_RO 1
|
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* relocate code. Return -1 on error, required size if ptr is NULL,
|
/* relocate code. Return -1 on error, required size if ptr is NULL,
|
||||||
@ -304,14 +315,11 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, unsigned ptr_diff)
|
|||||||
offset = copy = 0;
|
offset = copy = 0;
|
||||||
mem = (addr_t)ptr;
|
mem = (addr_t)ptr;
|
||||||
redo:
|
redo:
|
||||||
if (s1->verbose == 2 && copy) {
|
if (s1->verbose == 2 && copy)
|
||||||
printf(&"-----------------------------------------------------\n"[PTR_SIZE*2 - 8]);
|
printf(&"-----------------------------------------------------\n"[PTR_SIZE*2 - 8]);
|
||||||
if (1 == copy)
|
|
||||||
printf("memory %p len %05x\n", ptr, s1->run_size);
|
|
||||||
}
|
|
||||||
if (s1->nb_errors)
|
if (s1->nb_errors)
|
||||||
return -1;
|
return -1;
|
||||||
if (copy == 2)
|
if (copy == 3)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (k = 0; k < 3; ++k) { /* 0:rx, 1:ro, 2:rw sections */
|
for (k = 0; k < 3; ++k) { /* 0:rx, 1:ro, 2:rw sections */
|
||||||
@ -324,14 +332,16 @@ redo:
|
|||||||
if (shf[k] != (s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR)))
|
if (shf[k] != (s->sh_flags & (SHF_ALLOC|SHF_WRITE|SHF_EXECINSTR)))
|
||||||
continue;
|
continue;
|
||||||
length = s->data_offset;
|
length = s->data_offset;
|
||||||
|
if (copy == 2) {
|
||||||
|
if (addr == 0)
|
||||||
|
addr = s->sh_addr;
|
||||||
|
n = (s->sh_addr - addr) + length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (copy) { /* final step: copy section data to memory */
|
if (copy) { /* final step: copy section data to memory */
|
||||||
if (s1->verbose == 2)
|
if (s1->verbose == 2)
|
||||||
printf("%d: %-16s %p len %05x align %04x\n",
|
printf("%d: %-16s %p len %05x align %04x\n",
|
||||||
k, s->name, (void*)s->sh_addr, length, s->sh_addralign);
|
k, s->name, (void*)s->sh_addr, length, s->sh_addralign);
|
||||||
if (addr == 0)
|
|
||||||
addr = s->sh_addr;
|
|
||||||
n = (s->sh_addr - addr) + length;
|
|
||||||
ptr = (void*)s->sh_addr;
|
ptr = (void*)s->sh_addr;
|
||||||
if (k == 0)
|
if (k == 0)
|
||||||
ptr = (void*)(s->sh_addr + ptr_diff);
|
ptr = (void*)(s->sh_addr + ptr_diff);
|
||||||
@ -339,10 +349,6 @@ redo:
|
|||||||
memset(ptr, 0, length);
|
memset(ptr, 0, length);
|
||||||
else
|
else
|
||||||
memcpy(ptr, s->data, length);
|
memcpy(ptr, s->data, length);
|
||||||
#ifdef _WIN64
|
|
||||||
if (s == s1->uw_pdata)
|
|
||||||
s1->run_function_table = win64_add_function_table(s1);
|
|
||||||
#endif
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,13 +366,12 @@ redo:
|
|||||||
align = PAGESIZE;
|
align = PAGESIZE;
|
||||||
}
|
}
|
||||||
s->sh_addralign = align;
|
s->sh_addralign = align;
|
||||||
|
|
||||||
addr = k ? mem + ptr_diff : mem;
|
addr = k ? mem + ptr_diff : mem;
|
||||||
offset += -(addr + offset) & (align - 1);
|
offset += -(addr + offset) & (align - 1);
|
||||||
s->sh_addr = mem ? addr + offset : 0;
|
s->sh_addr = mem ? addr + offset : 0;
|
||||||
offset += length;
|
offset += length;
|
||||||
}
|
}
|
||||||
if (copy) { /* set permissions */
|
if (copy == 2) { /* set permissions */
|
||||||
if (n == 0) /* no data */
|
if (n == 0) /* no data */
|
||||||
continue;
|
continue;
|
||||||
#ifdef HAVE_SELINUX
|
#ifdef HAVE_SELINUX
|
||||||
@ -379,10 +384,10 @@ redo:
|
|||||||
continue;
|
continue;
|
||||||
f = 3; /* change only SHF_EXECINSTR to rwx */
|
f = 3; /* change only SHF_EXECINSTR to rwx */
|
||||||
}
|
}
|
||||||
n = (n + PAGESIZE-1) & ~(PAGESIZE-1);
|
n = PAGEALIGN(n);
|
||||||
if (s1->verbose == 2) {
|
if (s1->verbose == 2) {
|
||||||
printf("protect %3s %p len %05x\n",
|
printf("protect %3s %p len %05x\n",
|
||||||
&"rx\0r \0rw\0rwx"[f*3], (void*)addr, (unsigned)n);
|
&"rx\0ro\0rw\0rwx"[f*3], (void*)addr, (unsigned)n);
|
||||||
}
|
}
|
||||||
if (protect_pages((void*)addr, n, f) < 0)
|
if (protect_pages((void*)addr, n, f) < 0)
|
||||||
return tcc_error_noabort(
|
return tcc_error_noabort(
|
||||||
@ -391,9 +396,15 @@ redo:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (0 == mem)
|
if (0 == mem)
|
||||||
return (offset + (PAGESIZE-1)) & ~(PAGESIZE-1);
|
return PAGEALIGN(offset);
|
||||||
|
|
||||||
if (++copy == 2) {
|
if (++copy == 2) {
|
||||||
|
goto redo;
|
||||||
|
}
|
||||||
|
if (copy == 3) {
|
||||||
|
#ifdef _WIN64
|
||||||
|
s1->run_function_table = win64_add_function_table(s1);
|
||||||
|
#endif
|
||||||
/* remove local symbols and free sections except symtab */
|
/* remove local symbols and free sections except symtab */
|
||||||
cleanup_symbols(s1);
|
cleanup_symbols(s1);
|
||||||
cleanup_sections(s1);
|
cleanup_sections(s1);
|
||||||
@ -427,7 +438,6 @@ static int protect_pages(void *ptr, unsigned long length, int mode)
|
|||||||
DWORD old;
|
DWORD old;
|
||||||
if (!VirtualProtect(ptr, length, protect[mode], &old))
|
if (!VirtualProtect(ptr, length, protect[mode], &old))
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
|
||||||
#else
|
#else
|
||||||
static const unsigned char protect[] = {
|
static const unsigned char protect[] = {
|
||||||
PROT_READ | PROT_EXEC,
|
PROT_READ | PROT_EXEC,
|
||||||
@ -435,11 +445,7 @@ static int protect_pages(void *ptr, unsigned long length, int mode)
|
|||||||
PROT_READ | PROT_WRITE,
|
PROT_READ | PROT_WRITE,
|
||||||
PROT_READ | PROT_WRITE | PROT_EXEC
|
PROT_READ | PROT_WRITE | PROT_EXEC
|
||||||
};
|
};
|
||||||
addr_t start, end;
|
if (mprotect(ptr, length, protect[mode]))
|
||||||
start = (addr_t)ptr & ~(PAGESIZE - 1);
|
|
||||||
end = (addr_t)ptr + length;
|
|
||||||
end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
|
|
||||||
if (mprotect((void *)start, end - start, protect[mode]))
|
|
||||||
return -1;
|
return -1;
|
||||||
/* XXX: BSD sometimes dump core with bad system call */
|
/* XXX: BSD sometimes dump core with bad system call */
|
||||||
# if (defined TCC_TARGET_ARM && !TARGETOS_BSD) || defined TCC_TARGET_ARM64
|
# if (defined TCC_TARGET_ARM && !TARGETOS_BSD) || defined TCC_TARGET_ARM64
|
||||||
@ -448,8 +454,8 @@ static int protect_pages(void *ptr, unsigned long length, int mode)
|
|||||||
__clear_cache(ptr, (char *)ptr + length);
|
__clear_cache(ptr, (char *)ptr + length);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
return 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
@ -207,7 +207,7 @@ tccb:
|
|||||||
$(TCC) -b $(TOPSRC)/tcc.c $(TCCFLAGS) $(NATIVE_DEFINES) -o tccb1.exe
|
$(TCC) -b $(TOPSRC)/tcc.c $(TCCFLAGS) $(NATIVE_DEFINES) -o tccb1.exe
|
||||||
mv tccb1.exe tccb2.exe
|
mv tccb1.exe tccb2.exe
|
||||||
./tccb2.exe -b $(TOPSRC)/tcc.c $(TCCFLAGS) $(NATIVE_DEFINES) -o tccb1.exe
|
./tccb2.exe -b $(TOPSRC)/tcc.c $(TCCFLAGS) $(NATIVE_DEFINES) -o tccb1.exe
|
||||||
cmp -s tccb1.exe tccb2.exe && echo "Exe Bound-Rest OK"
|
cmp -s tccb1.exe tccb2.exe && echo "Exe Bound-Test OK"
|
||||||
|
|
||||||
|
|
||||||
# speed test
|
# speed test
|
||||||
|
Loading…
Reference in New Issue
Block a user