From 73faaea227a53e365dd75f1dba7a5071c7b5e541 Mon Sep 17 00:00:00 2001 From: grischka Date: Wed, 28 Aug 2013 22:55:05 +0200 Subject: i386-gen: preserve fp control word in gen_cvt_ftoi - 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 8a81f9e1036637e21a47e14fb56bf64133546890 winapi: add missing WINAPI decl. for some functions --- tccrun.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tccrun.c') diff --git a/tccrun.c b/tccrun.c index d858ae6..b07ab0f 100644 --- a/tccrun.c +++ b/tccrun.c @@ -97,7 +97,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) return -1; - prog_main = tcc_get_symbol_err(s1, "main"); + prog_main = tcc_get_symbol_err(s1, s1->runtime_main); #ifdef CONFIG_TCC_BACKTRACE if (s1->do_debug) { -- cgit v1.3.1 From 935d8169b8e3570f1a5e726c5295be2f460c1540 Mon Sep 17 00:00:00 2001 From: keren Date: Thu, 9 Jan 2014 14:00:19 -0800 Subject: Use anonymous file instead of regular file to back mmap Signed-off-by: Keren Tan --- tccrun.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'tccrun.c') diff --git a/tccrun.c b/tccrun.c index b07ab0f..a53330f 100644 --- a/tccrun.c +++ b/tccrun.c @@ -59,25 +59,16 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) return ret; #ifdef HAVE_SELINUX - { /* Use mmap instead of malloc for Selinux. Ref: - http://www.gnu.org/s/libc/manual/html_node/File-Size.html */ - - char tmpfname[] = "/tmp/.tccrunXXXXXX"; - int fd = mkstemp (tmpfname); - - s1->mem_size = ret; - unlink (tmpfname); - ftruncate (fd, s1->mem_size); - + { /* Use mmap instead of malloc for Selinux. */ s1->write_mem = mmap (NULL, ret, PROT_READ|PROT_WRITE, - MAP_SHARED, fd, 0); + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (s1->write_mem == MAP_FAILED) - tcc_error("/tmp not writeable"); + tcc_error("mmap not writeable"); s1->runtime_mem = mmap (NULL, ret, PROT_READ|PROT_EXEC, - MAP_SHARED, fd, 0); + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (s1->runtime_mem == MAP_FAILED) - tcc_error("/tmp not executable"); + tcc_error("mmap not executable"); ret = tcc_relocate_ex(s1, s1->write_mem); } -- cgit v1.3.1 From 80b36ab628ecb04d94e2593a61adf321e1325cd4 Mon Sep 17 00:00:00 2001 From: keren Date: Fri, 10 Jan 2014 10:23:11 -0800 Subject: Fix missing mem_size assignment when using mmap() --- tccrun.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tccrun.c') diff --git a/tccrun.c b/tccrun.c index a53330f..97f4761 100644 --- a/tccrun.c +++ b/tccrun.c @@ -60,6 +60,8 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) #ifdef HAVE_SELINUX { /* Use mmap instead of malloc for Selinux. */ + s1->mem_size = ret; + s1->write_mem = mmap (NULL, ret, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (s1->write_mem == MAP_FAILED) -- cgit v1.3.1 From 8e724128e8233c1e0addef8f0860e33194bd9ab9 Mon Sep 17 00:00:00 2001 From: Iavael Date: Sun, 12 Jan 2014 09:26:41 +0400 Subject: Revert "Use anonymous file instead of regular file to back mmap" This reverts commit 935d8169b8e3570f1a5e726c5295be2f460c1540, because two anonymous mappings would have different content, while they must have the same one. --- tccrun.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'tccrun.c') diff --git a/tccrun.c b/tccrun.c index 97f4761..b07ab0f 100644 --- a/tccrun.c +++ b/tccrun.c @@ -59,18 +59,25 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr) return ret; #ifdef HAVE_SELINUX - { /* Use mmap instead of malloc for Selinux. */ + { /* Use mmap instead of malloc for Selinux. Ref: + http://www.gnu.org/s/libc/manual/html_node/File-Size.html */ + + char tmpfname[] = "/tmp/.tccrunXXXXXX"; + int fd = mkstemp (tmpfname); + s1->mem_size = ret; + unlink (tmpfname); + ftruncate (fd, s1->mem_size); s1->write_mem = mmap (NULL, ret, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + MAP_SHARED, fd, 0); if (s1->write_mem == MAP_FAILED) - tcc_error("mmap not writeable"); + tcc_error("/tmp not writeable"); s1->runtime_mem = mmap (NULL, ret, PROT_READ|PROT_EXEC, - MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); + MAP_SHARED, fd, 0); if (s1->runtime_mem == MAP_FAILED) - tcc_error("mmap not executable"); + tcc_error("/tmp not executable"); ret = tcc_relocate_ex(s1, s1->write_mem); } -- cgit v1.3.1 From 75118780da3f30bc9061973546e510dd10173447 Mon Sep 17 00:00:00 2001 From: Kirill Smelkov Date: Sun, 19 Jan 2014 16:35:20 +0400 Subject: tccrun: Mark argv area as valid for bcheck 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... --- tccrun.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'tccrun.c') diff --git a/tccrun.c b/tccrun.c index b07ab0f..55fb3d8 100644 --- a/tccrun.c +++ b/tccrun.c @@ -110,13 +110,30 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) if (s1->do_bounds_check) { void (*bound_init)(void); void (*bound_exit)(void); + void (*bound_new_region)(void *p, unsigned long size); + int (*bound_delete_region)(void *p); + int i; + /* set error function */ rt_bound_error_msg = tcc_get_symbol_err(s1, "__bound_error_msg"); /* XXX: use .init section so that it also work in binary ? */ bound_init = tcc_get_symbol_err(s1, "__bound_init"); bound_exit = tcc_get_symbol_err(s1, "__bound_exit"); + bound_new_region = tcc_get_symbol_err(s1, "__bound_new_region"); + bound_delete_region = tcc_get_symbol_err(s1, "__bound_delete_region"); bound_init(); + /* mark argv area as valid */ + bound_new_region(argv, argc*sizeof(argv[0])); + for (i=0; i Date: Sat, 8 Feb 2014 08:31:32 +0100 Subject: Fix warning about undeclared __clear_cache function call. --- tccrun.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tccrun.c') diff --git a/tccrun.c b/tccrun.c index 55fb3d8..620be0d 100644 --- a/tccrun.c +++ b/tccrun.c @@ -234,6 +234,7 @@ static void set_pages_executable(void *ptr, unsigned long length) unsigned long old_protect; VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect); #else + extern void __clear_cache(char *beginning, char *end); #ifndef PAGESIZE # define PAGESIZE 4096 #endif -- cgit v1.3.1 From 62d1da1b3eb91b405a633aa4e4d841d8a7a0da3a Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Sun, 9 Mar 2014 22:52:31 +0800 Subject: Fix warning of clang --- tccelf.c | 40 ++++++++++++++++++++-------------------- tccpp.c | 4 ++-- tccrun.c | 4 ++-- 3 files changed, 24 insertions(+), 24 deletions(-) (limited to 'tccrun.c') diff --git a/tccelf.c b/tccelf.c index 321ec2e..424db69 100644 --- a/tccelf.c +++ b/tccelf.c @@ -56,7 +56,7 @@ static void rebuild_hash(Section *s, unsigned int nb_buckets) { ElfW(Sym) *sym; int *ptr, *hash, nb_syms, sym_index, h; - char *strtab; + unsigned char *strtab; strtab = s->link->data; nb_syms = s->data_offset / sizeof(ElfW(Sym)); @@ -115,7 +115,7 @@ ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, if (ELFW(ST_BIND)(info) != STB_LOCAL) { /* add another hashing entry */ nbuckets = base[0]; - h = elf_hash(name) % nbuckets; + h = elf_hash((unsigned char *) name) % nbuckets; *ptr = base[2 + h]; base[2 + h] = sym_index; base[1]++; @@ -145,11 +145,11 @@ ST_FUNC int find_elf_sym(Section *s, const char *name) if (!hs) return 0; nbuckets = ((int *)hs->data)[0]; - h = elf_hash(name) % nbuckets; + h = elf_hash((unsigned char *) name) % nbuckets; sym_index = ((int *)hs->data)[2 + h]; while (sym_index != 0) { sym = &((ElfW(Sym) *)s->data)[sym_index]; - name1 = s->link->data + sym->st_name; + name1 = (char *) s->link->data + sym->st_name; if (!strcmp(name, name1)) return sym_index; sym_index = ((int *)hs->data)[2 + nbuckets + sym_index]; @@ -429,12 +429,12 @@ ST_FUNC void relocate_syms(TCCState *s1, int do_resolve) for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { sh_num = sym->st_shndx; if (sh_num == SHN_UNDEF) { - name = strtab_section->data + sym->st_name; + name = (char *) strtab_section->data + sym->st_name; /* Use ld.so to resolve symbol for us (for tcc -run) */ if (do_resolve) { #if defined TCC_IS_NATIVE && !defined _WIN32 void *addr; - name = symtab_section->link->data + sym->st_name; + name = (char *) symtab_section->link->data + sym->st_name; addr = resolve_sym(s1, name); if (addr) { sym->st_value = (addr_t)addr; @@ -1026,7 +1026,7 @@ static void put_got_entry(TCCState *s1, if (s1->dynsym) { sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - name = symtab_section->link->data + sym->st_name; + name = (char *) symtab_section->link->data + sym->st_name; offset = sym->st_value; #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) if (reloc_type == @@ -1198,7 +1198,7 @@ ST_FUNC void build_got_entries(TCCState *s1) char *name, buf[1024]; Section *text_section; - name = symtab_section->link->data + sym->st_name; + name = (char *) symtab_section->link->data + sym->st_name; text_section = s1->sections[sym->st_shndx]; /* Modify reloc to target a thumb stub to switch to ARM */ snprintf(buf, sizeof(buf), "%s_from_thumb", name); @@ -1566,7 +1566,7 @@ static void bind_exe_dynsyms(TCCState *s1) - if STT_OBJECT symbol -> add it in .bss section with suitable reloc */ for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { if (sym->st_shndx == SHN_UNDEF) { - name = symtab_section->link->data + sym->st_name; + name = (char *) symtab_section->link->data + sym->st_name; sym_index = find_elf_sym(s1->dynsymtab_section, name); if (sym_index) { esym = &((ElfW(Sym) *)s1->dynsymtab_section->data)[sym_index]; @@ -1596,7 +1596,7 @@ static void bind_exe_dynsyms(TCCState *s1) for_each_elem(s1->dynsymtab_section, 1, dynsym, ElfW(Sym)) { if ((dynsym->st_value == esym->st_value) && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) { - char *dynname = s1->dynsymtab_section->link->data + char *dynname = (char *) s1->dynsymtab_section->link->data + dynsym->st_name; put_elf_sym(s1->dynsym, offset, dynsym->st_size, dynsym->st_info, 0, @@ -1621,7 +1621,7 @@ static void bind_exe_dynsyms(TCCState *s1) } } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { /* if -rdynamic option, then export all non local symbols */ - name = symtab_section->link->data + sym->st_name; + name = (char *) symtab_section->link->data + sym->st_name; put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info, 0, sym->st_shndx, name); } @@ -1640,7 +1640,7 @@ static void bind_libs_dynsyms(TCCState *s1) corresponding symbol */ for_each_elem(s1->dynsymtab_section, 1, esym, ElfW(Sym)) { if (esym->st_shndx == SHN_UNDEF) { - name = s1->dynsymtab_section->link->data + esym->st_name; + name = (char *) s1->dynsymtab_section->link->data + esym->st_name; sym_index = find_elf_sym(symtab_section, name); if (sym_index) { /* XXX: avoid adding a symbol if already present because of @@ -1682,7 +1682,7 @@ static void export_global_syms(TCCState *s1) } else #endif { - name = symtab_section->link->data + sym->st_name; + name = (char *) symtab_section->link->data + sym->st_name; dynindex = put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info, 0, sym->st_shndx, name); index = sym - (ElfW(Sym) *) symtab_section->data; @@ -2527,7 +2527,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, if (i == ehdr.e_shstrndx) continue; sh = &shdr[i]; - sh_name = strsec + sh->sh_name; + sh_name = (char *) strsec + sh->sh_name; /* ignore sections types we do not handle */ if (sh->sh_type != SHT_PROGBITS && sh->sh_type != SHT_RELX && @@ -2648,7 +2648,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, already defined symbol. It is very important to get correct relocations */ if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { - name = strtab + sym->st_name; + name = (char *) strtab + sym->st_name; sym_index = find_elf_sym(symtab_section, name); if (sym_index) old_to_new_syms[i] = sym_index; @@ -2664,7 +2664,7 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, sym->st_value += sm->offset; } /* add symbol */ - name = strtab + sym->st_name; + name = (char *) strtab + sym->st_name; sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size, sym->st_info, sym->st_other, sym->st_shndx, name); @@ -2765,7 +2765,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size) goto fail; nsyms = get_be32(data); ar_index = data + 4; - ar_names = ar_index + nsyms * 4; + ar_names = (char *) ar_index + nsyms * 4; do { bound = 0; @@ -2898,7 +2898,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) { if (dt->d_tag == DT_SONAME) { - soname = dynstr + dt->d_un.d_val; + soname = (char *) dynstr + dt->d_un.d_val; } } @@ -2925,7 +2925,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) sym_bind = ELFW(ST_BIND)(sym->st_info); if (sym_bind == STB_LOCAL) continue; - name = dynstr + sym->st_name; + name = (char *) dynstr + sym->st_name; add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size, sym->st_info, sym->st_other, sym->st_shndx, name); } @@ -2934,7 +2934,7 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) { switch(dt->d_tag) { case DT_NEEDED: - name = dynstr + dt->d_un.d_val; + name = (char *) dynstr + dt->d_un.d_val; for(j = 0; j < s1->nb_loaded_dlls; j++) { dllref = s1->loaded_dlls[j]; if (!strcmp(name, dllref->name)) diff --git a/tccpp.c b/tccpp.c index b12b120..cf1fc65 100644 --- a/tccpp.c +++ b/tccpp.c @@ -1247,7 +1247,7 @@ static inline int hash_cached_include(const char *filename) unsigned int h; h = TOK_HASH_INIT; - s = filename; + s = (unsigned char *) filename; while (*s) { h = TOK_HASH_FUNC(h, *s); s++; @@ -2222,7 +2222,7 @@ maybe_newline: goto token_found; pts = &(ts->hash_next); } - ts = tok_alloc_new(pts, p1, len); + ts = tok_alloc_new(pts, (char *) p1, len); token_found: ; } else { /* slower case */ diff --git a/tccrun.c b/tccrun.c index 620be0d..bd8c33f 100644 --- a/tccrun.c +++ b/tccrun.c @@ -272,7 +272,7 @@ static addr_t rt_printline(addr_t wanted_pc, const char *msg) if (stab_section) { stab_len = stab_section->data_offset; stab_sym = (Stab_Sym *)stab_section->data; - stab_str = stabstr_section->data; + stab_str = (char *) stabstr_section->data; } func_name[0] = '\0'; @@ -365,7 +365,7 @@ no_stabs: if (wanted_pc >= sym->st_value && wanted_pc < sym->st_value + sym->st_size) { pstrcpy(last_func_name, sizeof(last_func_name), - strtab_section->data + sym->st_name); + (char *) strtab_section->data + sym->st_name); func_addr = sym->st_value; goto found; } -- cgit v1.3.1 From 9750d0b725d65296364c08451a985c717bf1890d Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Sun, 6 Apr 2014 00:30:22 +0200 Subject: x86_64: Create proper PLT and GOT also for -run 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. --- tcc.h | 3 ++- tccelf.c | 37 +++++++++++++++++++++---------------- tccrun.c | 1 + 3 files changed, 24 insertions(+), 17 deletions(-) (limited to 'tccrun.c') diff --git a/tcc.h b/tcc.h index 093e758..76f25bd 100644 --- a/tcc.h +++ b/tcc.h @@ -712,7 +712,7 @@ struct TCCState { void *write_mem; unsigned long mem_size; # endif -# if !defined TCC_TARGET_PE && (defined TCC_TARGET_X86_64 || defined TCC_TARGET_ARM) +# if !defined TCC_TARGET_PE && (defined TCC_TARGET_ARM) /* write PLT and GOT here */ char *runtime_plt_and_got; unsigned runtime_plt_and_got_offset; @@ -1265,6 +1265,7 @@ ST_FUNC void put_stabd(int type, int other, int desc); ST_FUNC void relocate_common_syms(void); ST_FUNC void relocate_syms(TCCState *s1, int do_resolve); ST_FUNC void relocate_section(TCCState *s1, Section *s); +ST_FUNC void relocate_plt(TCCState *s1); ST_FUNC void tcc_add_linker_symbols(TCCState *s1); ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset); diff --git a/tccelf.c b/tccelf.c index b55dbc9..4ed845b 100644 --- a/tccelf.c +++ b/tccelf.c @@ -851,8 +851,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) /* We've put the PLT slot offset into r_addend when generating it, and that's what we must use as relocation value (adjusted by section offset of course). */ - if (s1->output_type != TCC_OUTPUT_MEMORY) - val = s1->plt->sh_addr + rel->r_addend; + val = s1->plt->sh_addr + rel->r_addend; /* fallthrough. */ plt32pc32: @@ -878,7 +877,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) case R_X86_64_GLOB_DAT: case R_X86_64_JUMP_SLOT: /* They don't need addend */ - *(int *)ptr = val - rel->r_addend; + *(addr_t *)ptr = val - rel->r_addend; break; case R_X86_64_GOTPCREL: #ifdef TCC_HAS_RUNTIME_PLTGOT @@ -1042,7 +1041,7 @@ static unsigned long put_got_entry(TCCState *s1, if (!s1->got) build_got(s1); - need_plt_entry = s1->dynsym && + need_plt_entry = #ifdef TCC_TARGET_X86_64 (reloc_type == R_X86_64_JUMP_SLOT); #elif defined(TCC_TARGET_I386) @@ -1053,6 +1052,13 @@ static unsigned long put_got_entry(TCCState *s1, 0; #endif + if (need_plt_entry && !s1->plt) { + /* add PLT */ + s1->plt = new_section(s1, ".plt", SHT_PROGBITS, + SHF_ALLOC | SHF_EXECINSTR); + s1->plt->sh_entsize = 4; + } + /* If a got/plt entry already exists for that symbol, no need to add one */ if (sym_index < s1->nb_sym_attrs) { if (need_plt_entry && s1->sym_attrs[sym_index].plt_offset) @@ -1067,10 +1073,9 @@ static unsigned long put_got_entry(TCCState *s1, if (!need_plt_entry) symattr->got_offset = s1->got->data_offset; - if (s1->dynsym) { - sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; - name = (char *) symtab_section->link->data + sym->st_name; - offset = sym->st_value; + sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; + name = (char *) symtab_section->link->data + sym->st_name; + offset = sym->st_value; #if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) if (need_plt_entry) { Section *plt; @@ -1165,10 +1170,13 @@ static unsigned long put_got_entry(TCCState *s1, offset = plt->data_offset - 16; } #elif defined(TCC_TARGET_C67) + if (s1->dynsym) { tcc_error("C67 got not implemented"); + } #else #error unsupported CPU #endif + if (s1->dynsym) { /* XXX This might generate multiple syms for name. */ index = put_elf_sym(s1->dynsym, offset, size, info, 0, sym->st_shndx, name); @@ -1316,8 +1324,7 @@ ST_FUNC void build_got_entries(TCCState *s1) reloc_type = R_X86_64_JUMP_SLOT; ofs = put_got_entry(s1, reloc_type, sym->st_size, sym->st_info, sym_index); - if (type == R_X86_64_PLT32 - && s1->output_type != TCC_OUTPUT_MEMORY) + if (type == R_X86_64_PLT32) /* We store the place of the generated PLT slot in our addend. */ rel->r_addend += ofs; @@ -1754,10 +1761,13 @@ static void export_global_syms(TCCState *s1) /* relocate the PLT: compute addresses and offsets in the PLT now that final address for PLT and GOT are known (see fill_program_header) */ -static void relocate_plt(TCCState *s1) +ST_FUNC void relocate_plt(TCCState *s1) { uint8_t *p, *p_end; + if (!s1->plt) + return; + p = s1->plt->data; p_end = p + s1->plt->data_offset; if (p < p_end) { @@ -2346,11 +2356,6 @@ static int elf_output_file(TCCState *s1, const char *filename) dynamic->link = dynstr; dynamic->sh_entsize = sizeof(ElfW(Dyn)); - /* add PLT */ - s1->plt = new_section(s1, ".plt", SHT_PROGBITS, - SHF_ALLOC | SHF_EXECINSTR); - s1->plt->sh_entsize = 4; - build_got(s1); if (file_type == TCC_OUTPUT_EXE) { diff --git a/tccrun.c b/tccrun.c index bd8c33f..2876ab7 100644 --- a/tccrun.c +++ b/tccrun.c @@ -197,6 +197,7 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr) if (s->reloc) relocate_section(s1, s); } + relocate_plt(s1); for(i = 1; i < s1->nb_sections; i++) { s = s1->sections[i]; -- cgit v1.3.1 From 6a947d9d2610723db3f46bcae4f35d5d5c572f89 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Sun, 6 Apr 2014 01:59:35 +0200 Subject: ELF: Remove traces of old RUNTIME_PLTGOT code The last users of it went away, no use in keeping this code. --- tcc.h | 6 ------ tccelf.c | 64 +--------------------------------------------------------------- tccrun.c | 13 ------------- 3 files changed, 1 insertion(+), 82 deletions(-) (limited to 'tccrun.c') diff --git a/tcc.h b/tcc.h index 5033b19..1688a0c 100644 --- a/tcc.h +++ b/tcc.h @@ -712,12 +712,6 @@ struct TCCState { void *write_mem; unsigned long mem_size; # endif -# if !defined TCC_TARGET_PE && (0) - /* write PLT and GOT here */ - char *runtime_plt_and_got; - unsigned runtime_plt_and_got_offset; -# define TCC_HAS_RUNTIME_PLTGOT -# endif #endif /* used by main and tcc_parse_args only */ diff --git a/tccelf.c b/tccelf.c index 6f63f83..6955847 100644 --- a/tccelf.c +++ b/tccelf.c @@ -476,42 +476,6 @@ ST_FUNC void relocate_syms(TCCState *s1, int do_resolve) } } -#ifdef TCC_HAS_RUNTIME_PLTGOT -#ifdef TCC_TARGET_X86_64 -#define JMP_TABLE_ENTRY_SIZE 14 -static addr_t add_jmp_table(TCCState *s1, addr_t val) -{ - char *p = s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset; - s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE; - /* jmp *0x0(%rip) */ - p[0] = 0xff; - p[1] = 0x25; - *(int *)(p + 2) = 0; - *(addr_t *)(p + 6) = val; - return (addr_t)p; -} - -static addr_t add_got_table(TCCState *s1, addr_t val) -{ - addr_t *p = (addr_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset); - s1->runtime_plt_and_got_offset += sizeof(addr_t); - *p = val; - return (addr_t)p; -} -#elif defined TCC_TARGET_ARM -#define JMP_TABLE_ENTRY_SIZE 8 -static addr_t add_jmp_table(TCCState *s1, int val) -{ - uint32_t *p = (uint32_t *)(s1->runtime_plt_and_got + s1->runtime_plt_and_got_offset); - s1->runtime_plt_and_got_offset += JMP_TABLE_ENTRY_SIZE; - /* ldr pc, [pc, #-4] */ - p[0] = 0xE51FF004; - p[1] = val; - return (addr_t)p; -} -#endif -#endif /* def TCC_HAS_RUNTIME_PLTGOT */ - /* relocate a given section (CPU dependent) by applying the relocations in the associated relocation section */ ST_FUNC void relocate_section(TCCState *s1, Section *s) @@ -627,15 +591,6 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) #endif h = x & 2; th_ko = (x & 3) && (!blx_avail || !is_call); -#ifdef TCC_HAS_RUNTIME_PLTGOT - if (s1->output_type == TCC_OUTPUT_MEMORY) { - if (th_ko || x >= 0x2000000 || x < -0x2000000) { - x += add_jmp_table(s1, val) - val; /* add veneer */ - th_ko = (x & 3) && (!blx_avail || !is_call); - is_thumb = 0; /* Veneer uses ARM instructions */ - } - } -#endif if (th_ko || x >= 0x2000000 || x < -0x2000000) tcc_error("can't relocate value at %x,%d",addr, type); x >>= 2; @@ -878,17 +833,7 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) long long diff; diff = (long long)val - addr; if (diff <= -2147483647 || diff > 2147483647) { -#ifdef TCC_HAS_RUNTIME_PLTGOT - /* XXX: naive support for over 32bit jump */ - if (s1->output_type == TCC_OUTPUT_MEMORY) { - val = (add_jmp_table(s1, val - rel->r_addend) + - rel->r_addend); - diff = val - addr; - } -#endif - if (diff <= -2147483647 || diff > 2147483647) { - tcc_error("internal error: relocation failed"); - } + tcc_error("internal error: relocation failed"); } *(int *)ptr += diff; } @@ -899,13 +844,6 @@ ST_FUNC void relocate_section(TCCState *s1, Section *s) *(addr_t *)ptr = val - rel->r_addend; break; case R_X86_64_GOTPCREL: -#ifdef TCC_HAS_RUNTIME_PLTGOT - if (s1->output_type == TCC_OUTPUT_MEMORY) { - val = add_got_table(s1, val - rel->r_addend) + rel->r_addend; - *(int *)ptr += val - addr; - break; - } -#endif *(int *)ptr += (s1->got->sh_addr - addr + s1->sym_attrs[sym_index].got_offset - 4); break; diff --git a/tccrun.c b/tccrun.c index 2876ab7..52a74b3 100644 --- a/tccrun.c +++ b/tccrun.c @@ -180,14 +180,6 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr) if (s1->nb_errors) return -1; -#ifdef TCC_HAS_RUNTIME_PLTGOT - s1->runtime_plt_and_got_offset = 0; - s1->runtime_plt_and_got = (char *)(mem + offset); - /* double the size of the buffer for got and plt entries - XXX: calculate exact size for them? */ - offset *= 2; -#endif - if (0 == mem) return offset; @@ -215,11 +207,6 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr) set_pages_executable(ptr, length); } -#ifdef TCC_HAS_RUNTIME_PLTGOT - set_pages_executable(s1->runtime_plt_and_got, - s1->runtime_plt_and_got_offset); -#endif - #ifdef _WIN64 win64_add_function_table(s1); #endif -- cgit v1.3.1 From 8d3e0b3080dfed90e5675d103b4acaffaaa0f703 Mon Sep 17 00:00:00 2001 From: minux Date: Sat, 12 Apr 2014 00:52:20 -0400 Subject: tccrun: fix build on DragonFly BSD. --- tccrun.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tccrun.c') diff --git a/tccrun.c b/tccrun.c index 52a74b3..a3e496e 100644 --- a/tccrun.c +++ b/tccrun.c @@ -528,7 +528,7 @@ static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) /* XXX: only support linux */ #if defined(__APPLE__) *paddr = uc->uc_mcontext->__ss.__rip; -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) *paddr = uc->uc_mcontext.mc_rip; #else *paddr = uc->uc_mcontext.gregs[REG_RIP]; @@ -537,7 +537,7 @@ static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) } else { #if defined(__APPLE__) fp = uc->uc_mcontext->__ss.__rbp; -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) fp = uc->uc_mcontext.mc_rbp; #else fp = uc->uc_mcontext.gregs[REG_RBP]; -- cgit v1.3.1 From 9714d2e75f70f8fcca9fd7b596440a346e504742 Mon Sep 17 00:00:00 2001 From: minux Date: Sat, 12 Apr 2014 01:42:46 -0400 Subject: build: add initial NetBSD support. 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") --- configure | 1 + lib/bcheck.c | 4 ++-- tccrun.c | 12 ++++++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'tccrun.c') diff --git a/configure b/configure index 8c44e5c..c309de6 100755 --- a/configure +++ b/configure @@ -56,6 +56,7 @@ case $targetos in DragonFly) noldl=yes;; OpenBSD) noldl=yes;; FreeBSD) noldl=yes;; + NetBSD) noldl=yes;; *) ;; esac diff --git a/lib/bcheck.c b/lib/bcheck.c index 76413ad..8ac7d4e 100644 --- a/lib/bcheck.c +++ b/lib/bcheck.c @@ -22,7 +22,7 @@ #include #include #if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) \ - && !defined(__DragonFly__) && !defined(__OpenBSD__) + && !defined(__DragonFly__) && !defined(__OpenBSD__) && !defined(__NetBSD__) #include #endif #if !defined(_WIN32) @@ -41,7 +41,7 @@ #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) \ || defined(__DragonFly__) || defined(__dietlibc__) \ - || defined(__UCLIBC__) || defined(__OpenBSD__) \ + || defined(__UCLIBC__) || defined(__OpenBSD__) || defined(__NetBSD__) \ || defined(_WIN32) || defined(TCC_UCLIBC) #warning Bound checking does not support malloc (etc.) in this environment. #undef CONFIG_TCC_MALLOC_HOOKS diff --git a/tccrun.c b/tccrun.c index a3e496e..13c2012 100644 --- a/tccrun.c +++ b/tccrun.c @@ -486,10 +486,12 @@ static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) if (level == 0) { #if defined(__APPLE__) *paddr = uc->uc_mcontext->__ss.__eip; -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) *paddr = uc->uc_mcontext.mc_eip; #elif defined(__dietlibc__) *paddr = uc->uc_mcontext.eip; +#elif defined(__NetBSD__) + *paddr = uc->uc_mcontext.__gregs[_REG_EIP]; #else *paddr = uc->uc_mcontext.gregs[REG_EIP]; #endif @@ -497,10 +499,12 @@ static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) } else { #if defined(__APPLE__) fp = uc->uc_mcontext->__ss.__ebp; -#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) fp = uc->uc_mcontext.mc_ebp; #elif defined(__dietlibc__) fp = uc->uc_mcontext.ebp; +#elif defined(__NetBSD__) + fp = uc->uc_mcontext.__gregs[_REG_EBP]; #else fp = uc->uc_mcontext.gregs[REG_EBP]; #endif @@ -530,6 +534,8 @@ static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) *paddr = uc->uc_mcontext->__ss.__rip; #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) *paddr = uc->uc_mcontext.mc_rip; +#elif defined(__NetBSD__) + *paddr = uc->uc_mcontext.__gregs[_REG_RIP]; #else *paddr = uc->uc_mcontext.gregs[REG_RIP]; #endif @@ -539,6 +545,8 @@ static int rt_get_caller_pc(addr_t *paddr, ucontext_t *uc, int level) fp = uc->uc_mcontext->__ss.__rbp; #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) fp = uc->uc_mcontext.mc_rbp; +#elif defined(__NetBSD__) + fp = uc->uc_mcontext.__gregs[_REG_RBP]; #else fp = uc->uc_mcontext.gregs[REG_RBP]; #endif -- cgit v1.3.1