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 --- tcctok.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tcctok.h') diff --git a/tcctok.h b/tcctok.h index fde13dd..9b47a60 100644 --- a/tcctok.h +++ b/tcctok.h @@ -194,8 +194,8 @@ DEF(TOK__remu, "_remu") #endif #ifdef TCC_TARGET_I386 - DEF(TOK___tcc_int_fpu_control, "__tcc_int_fpu_control") - DEF(TOK___tcc_fpu_control, "__tcc_fpu_control") + DEF(TOK___tcc_fpinit, "__tcc_fpinit") + DEF(TOK___tcc_cvt_ftol, "__tcc_cvt_ftol") #endif #ifdef TCC_ARM_EABI DEF(TOK___ashrdi3, "__aeabi_lasr") -- cgit v1.3.1 From 1c4afd13501f07a673aed5f130166f2ee0f30927 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 29 Oct 2013 22:10:02 +0800 Subject: Add support for thread-local storage variables --- elf.h | 4 +++- libtcc.c | 5 ++++- tccelf.c | 29 +++++++++++++++++++++-------- tccgen.c | 29 +++++++++++++++++++++++++---- tcctok.h | 1 + 5 files changed, 54 insertions(+), 14 deletions(-) (limited to 'tcctok.h') diff --git a/elf.h b/elf.h index 2983c75..039a697 100644 --- a/elf.h +++ b/elf.h @@ -447,6 +447,7 @@ typedef struct #define STT_SECTION 3 /* Symbol associated with a section */ #define STT_FILE 4 /* Symbol's name is file name */ #define STT_NUM 5 /* Number of defined types. */ +#define STT_TLS 6 /* Symbol is a thread-local data object */ #define STT_GNU_IFUNC 10 /* Symbol is a indirect code object */ #define STT_LOOS 11 /* Start of OS-specific */ #define STT_HIOS 12 /* End of OS-specific */ @@ -555,7 +556,8 @@ typedef struct #define PT_NOTE 4 /* Auxiliary information */ #define PT_SHLIB 5 /* Reserved */ #define PT_PHDR 6 /* Entry for header table itself */ -#define PT_NUM 7 /* Number of defined types. */ +#define PT_TLS 7 /* Thread-local program segment */ +#define PT_NUM 8 /* Number of defined types. */ #define PT_LOOS 0x60000000 /* Start of OS-specific */ #define PT_HIOS 0x6fffffff /* End of OS-specific */ #define PT_LOPROC 0x70000000 /* Start of processor-specific */ diff --git a/libtcc.c b/libtcc.c index f841eb0..fbea50b 100644 --- a/libtcc.c +++ b/libtcc.c @@ -444,7 +444,10 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, } else if ((sym->type.t & VT_BTYPE) == VT_VOID) { sym_type = STT_NOTYPE; } else { - sym_type = STT_OBJECT; + if (section && section->sh_flags & SHF_TLS) + sym_type = STT_TLS; + else + sym_type = STT_OBJECT; } if (sym->type.t & VT_STATIC) diff --git a/tccelf.c b/tccelf.c index 8af4bb6..4602ce8 100644 --- a/tccelf.c +++ b/tccelf.c @@ -1543,6 +1543,7 @@ static int elf_output_file(TCCState *s1, const char *filename) int fd, mode, ret; int *section_order; int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k; + int have_tls_section = 0; long long tmp; addr_t addr; Section *strsec, *s; @@ -1861,6 +1862,11 @@ static int elf_output_file(TCCState *s1, const char *filename) /* we output all sections if debug or object file */ s->sh_size = s->data_offset; } + /* if tls section we'll need to add one segment */ + if (s->sh_flags & SHF_TLS) { + have_tls_section = 1; + phnum++; + } } /* allocate program segment headers */ @@ -1904,12 +1910,16 @@ static int elf_output_file(TCCState *s1, const char *filename) if (interp) ph += 1 + HAVE_PHDR; - for(j = 0; j < 2; j++) { - ph->p_type = PT_LOAD; - if (j == 0) - ph->p_flags = PF_R | PF_X; + for(j = 0; j < 2 + have_tls_section; j++) { + if (j != 2) + ph->p_type = PT_LOAD; else - ph->p_flags = PF_R | PF_W; + ph->p_type = PT_TLS; + ph->p_flags = PF_R; + if (j == 0) + ph->p_flags |= PF_X; + else if (j == 1) + ph->p_flags |= PF_W; ph->p_align = s1->section_align; /* we do the following ordering: interp, symbol tables, @@ -1920,13 +1930,16 @@ static int elf_output_file(TCCState *s1, const char *filename) s = s1->sections[i]; /* compute if section should be included */ if (j == 0) { - if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != + if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) != SHF_ALLOC) continue; - } else { - if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != + } else if (j == 1) { + if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) != (SHF_ALLOC | SHF_WRITE)) continue; + } else { + if ((s->sh_flags & SHF_TLS) != SHF_TLS) + continue; } if (s == interp) { if (k != 0) diff --git a/tccgen.c b/tccgen.c index bab4f7c..bfe461f 100644 --- a/tccgen.c +++ b/tccgen.c @@ -31,6 +31,7 @@ ST_DATA int rsym, anon_sym, ind, loc; ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ +ST_DATA Section *tdata_section, *tbss_section; /* thread-local storage sections */ ST_DATA Section *cur_text_section; /* current section where function code is generated */ #ifdef CONFIG_TCC_ASM ST_DATA Section *last_text_section; /* to handle .previous asm directive */ @@ -3092,6 +3093,10 @@ static int parse_btype(CType *type, AttributeDef *ad) t |= VT_INLINE; next(); break; + case TOK_THREAD: + t |= VT_TLS; + next(); + break; /* GNUC attribute */ case TOK_ATTRIBUTE1: @@ -5495,10 +5500,26 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, /* allocate symbol in corresponding section */ sec = ad->section; if (!sec) { - if (has_init) - sec = data_section; - else if (tcc_state->nocommon) - sec = bss_section; + if (has_init) { + if (type->t & VT_TLS) { + if (!tdata_section) + tdata_section = new_section(tcc_state, ".tdata", + SHT_PROGBITS, + SHF_ALLOC | SHF_WRITE | SHF_TLS); + sec = tdata_section; + } else + sec = data_section; + } + else if (tcc_state->nocommon) { + if (type->t & VT_TLS) { + if (!tbss_section) + tbss_section = new_section(tcc_state, ".tbss", + SHT_NOBITS, + SHF_ALLOC | SHF_WRITE | SHF_TLS); + sec = tbss_section; + } else + sec = bss_section; + } } if (sec) { data_offset = sec->data_offset; diff --git a/tcctok.h b/tcctok.h index 9b47a60..d55c9d7 100644 --- a/tcctok.h +++ b/tcctok.h @@ -10,6 +10,7 @@ DEF(TOK_FOR, "for") DEF(TOK_EXTERN, "extern") DEF(TOK_STATIC, "static") + DEF(TOK_THREAD, "__thread") DEF(TOK_UNSIGNED, "unsigned") DEF(TOK_GOTO, "goto") DEF(TOK_DO, "do") -- cgit v1.3.1 From cf02f920c148a77794b05ba09d73586e5f0b3601 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Sun, 3 Nov 2013 18:55:54 +0800 Subject: Revert "Add support for thread-local storage variables" TLS support in tinyCC is absolutely not ready: - segment register not select in load and store - no relocation added for computing offset of per-thread symbol - no support for TLS-specific relocations - no program header added as per Drepper document about TLS This reverts commit 1c4afd13501f07a673aed5f130166f2ee0f30927. --- elf.h | 4 +--- libtcc.c | 5 +---- tccelf.c | 29 ++++++++--------------------- tccgen.c | 29 ++++------------------------- tcctok.h | 1 - 5 files changed, 14 insertions(+), 54 deletions(-) (limited to 'tcctok.h') diff --git a/elf.h b/elf.h index 039a697..2983c75 100644 --- a/elf.h +++ b/elf.h @@ -447,7 +447,6 @@ typedef struct #define STT_SECTION 3 /* Symbol associated with a section */ #define STT_FILE 4 /* Symbol's name is file name */ #define STT_NUM 5 /* Number of defined types. */ -#define STT_TLS 6 /* Symbol is a thread-local data object */ #define STT_GNU_IFUNC 10 /* Symbol is a indirect code object */ #define STT_LOOS 11 /* Start of OS-specific */ #define STT_HIOS 12 /* End of OS-specific */ @@ -556,8 +555,7 @@ typedef struct #define PT_NOTE 4 /* Auxiliary information */ #define PT_SHLIB 5 /* Reserved */ #define PT_PHDR 6 /* Entry for header table itself */ -#define PT_TLS 7 /* Thread-local program segment */ -#define PT_NUM 8 /* Number of defined types. */ +#define PT_NUM 7 /* Number of defined types. */ #define PT_LOOS 0x60000000 /* Start of OS-specific */ #define PT_HIOS 0x6fffffff /* End of OS-specific */ #define PT_LOPROC 0x70000000 /* Start of processor-specific */ diff --git a/libtcc.c b/libtcc.c index fbea50b..f841eb0 100644 --- a/libtcc.c +++ b/libtcc.c @@ -444,10 +444,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, } else if ((sym->type.t & VT_BTYPE) == VT_VOID) { sym_type = STT_NOTYPE; } else { - if (section && section->sh_flags & SHF_TLS) - sym_type = STT_TLS; - else - sym_type = STT_OBJECT; + sym_type = STT_OBJECT; } if (sym->type.t & VT_STATIC) diff --git a/tccelf.c b/tccelf.c index 4602ce8..8af4bb6 100644 --- a/tccelf.c +++ b/tccelf.c @@ -1543,7 +1543,6 @@ static int elf_output_file(TCCState *s1, const char *filename) int fd, mode, ret; int *section_order; int shnum, i, phnum, file_offset, offset, size, j, sh_order_index, k; - int have_tls_section = 0; long long tmp; addr_t addr; Section *strsec, *s; @@ -1862,11 +1861,6 @@ static int elf_output_file(TCCState *s1, const char *filename) /* we output all sections if debug or object file */ s->sh_size = s->data_offset; } - /* if tls section we'll need to add one segment */ - if (s->sh_flags & SHF_TLS) { - have_tls_section = 1; - phnum++; - } } /* allocate program segment headers */ @@ -1910,16 +1904,12 @@ static int elf_output_file(TCCState *s1, const char *filename) if (interp) ph += 1 + HAVE_PHDR; - for(j = 0; j < 2 + have_tls_section; j++) { - if (j != 2) - ph->p_type = PT_LOAD; - else - ph->p_type = PT_TLS; - ph->p_flags = PF_R; + for(j = 0; j < 2; j++) { + ph->p_type = PT_LOAD; if (j == 0) - ph->p_flags |= PF_X; - else if (j == 1) - ph->p_flags |= PF_W; + ph->p_flags = PF_R | PF_X; + else + ph->p_flags = PF_R | PF_W; ph->p_align = s1->section_align; /* we do the following ordering: interp, symbol tables, @@ -1930,15 +1920,12 @@ static int elf_output_file(TCCState *s1, const char *filename) s = s1->sections[i]; /* compute if section should be included */ if (j == 0) { - if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) != + if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != SHF_ALLOC) continue; - } else if (j == 1) { - if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_TLS)) != - (SHF_ALLOC | SHF_WRITE)) - continue; } else { - if ((s->sh_flags & SHF_TLS) != SHF_TLS) + if ((s->sh_flags & (SHF_ALLOC | SHF_WRITE)) != + (SHF_ALLOC | SHF_WRITE)) continue; } if (s == interp) { diff --git a/tccgen.c b/tccgen.c index bfe461f..bab4f7c 100644 --- a/tccgen.c +++ b/tccgen.c @@ -31,7 +31,6 @@ ST_DATA int rsym, anon_sym, ind, loc; ST_DATA Section *text_section, *data_section, *bss_section; /* predefined sections */ -ST_DATA Section *tdata_section, *tbss_section; /* thread-local storage sections */ ST_DATA Section *cur_text_section; /* current section where function code is generated */ #ifdef CONFIG_TCC_ASM ST_DATA Section *last_text_section; /* to handle .previous asm directive */ @@ -3093,10 +3092,6 @@ static int parse_btype(CType *type, AttributeDef *ad) t |= VT_INLINE; next(); break; - case TOK_THREAD: - t |= VT_TLS; - next(); - break; /* GNUC attribute */ case TOK_ATTRIBUTE1: @@ -5500,26 +5495,10 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, /* allocate symbol in corresponding section */ sec = ad->section; if (!sec) { - if (has_init) { - if (type->t & VT_TLS) { - if (!tdata_section) - tdata_section = new_section(tcc_state, ".tdata", - SHT_PROGBITS, - SHF_ALLOC | SHF_WRITE | SHF_TLS); - sec = tdata_section; - } else - sec = data_section; - } - else if (tcc_state->nocommon) { - if (type->t & VT_TLS) { - if (!tbss_section) - tbss_section = new_section(tcc_state, ".tbss", - SHT_NOBITS, - SHF_ALLOC | SHF_WRITE | SHF_TLS); - sec = tbss_section; - } else - sec = bss_section; - } + if (has_init) + sec = data_section; + else if (tcc_state->nocommon) + sec = bss_section; } if (sec) { data_offset = sec->data_offset; diff --git a/tcctok.h b/tcctok.h index d55c9d7..9b47a60 100644 --- a/tcctok.h +++ b/tcctok.h @@ -10,7 +10,6 @@ DEF(TOK_FOR, "for") DEF(TOK_EXTERN, "extern") DEF(TOK_STATIC, "static") - DEF(TOK_THREAD, "__thread") DEF(TOK_UNSIGNED, "unsigned") DEF(TOK_GOTO, "goto") DEF(TOK_DO, "do") -- cgit v1.3.1 From 4ad186c5ef61477030ca37372f9d6c6d03681015 Mon Sep 17 00:00:00 2001 From: grischka Date: Mon, 6 Jan 2014 19:07:08 +0100 Subject: i386: use __fixdfdi instead of __tcc_cvt_ftol Variants __fixsfdi/__fixxfdi are not needed for now because the value is converted to double always. Also: - remove __tcc_fpinit for unix as it seems redundant by the __setfpucw call in the startup code - avoid reference to s->runtime_main in cross compilers - configure: fix --with-libgcc help - tcctok.h: cleanup --- configure | 2 +- i386-gen.c | 28 ++++++++----------- lib/libtcc1.c | 39 ++++++++++++++------------ tccelf.c | 4 +-- tccpe.c | 2 ++ tcctok.h | 89 ++++++++++++++++++++++++++++++----------------------------- 6 files changed, 84 insertions(+), 80 deletions(-) mode change 100755 => 100644 configure (limited to 'tcctok.h') diff --git a/configure b/configure old mode 100755 new mode 100644 index cc8ca5a..8c44e5c --- a/configure +++ b/configure @@ -273,7 +273,7 @@ Advanced options (experts only): --strip-binaries strip symbol tables from resulting binaries --disable-static make libtcc.so instead of libtcc.a --disable-rpath disable use of -rpath with the above - --with-libgcc use libgcc_s.so.1 instead of libtcc.a in dynamic link + --with-libgcc use libgcc_s.so.1 instead of libtcc1.a in dynamic link --enable-mingw32 build windows version on linux with mingw32 --enable-cygwin build windows version on windows with cygwin --enable-cross build cross compilers diff --git a/i386-gen.c b/i386-gen.c index 2eb6922..4c4a54b 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -581,14 +581,6 @@ ST_FUNC void gfunc_prolog(CType *func_type) func_bound_offset = lbounds_section->data_offset; } #endif - -#ifndef CONFIG_USE_LIBGCC -#ifndef TCC_TARGET_PE - if (0 == strcmp(funcname, "main")) - gen_static_call(TOK___tcc_fpinit); -#endif -#endif - } /* generate function epilog */ @@ -988,16 +980,20 @@ ST_FUNC void gen_cvt_itof(int t) } /* convert fp to int 't' type */ -/* XXX: handle long long case */ ST_FUNC void gen_cvt_ftoi(int t) { - gv(RC_FLOAT); - save_reg(TREG_EAX); - save_reg(TREG_EDX); - gen_static_call(TOK___tcc_cvt_ftol); - vtop->r = TREG_EAX; /* mark reg as used */ - if (t == VT_LLONG) - vtop->r2 = TREG_EDX; + int bt = vtop->type.t & VT_BTYPE; + if (bt == VT_FLOAT) + vpush_global_sym(&func_old_type, TOK___fixsfdi); + else if (bt == VT_LDOUBLE) + vpush_global_sym(&func_old_type, TOK___fixxfdi); + else + vpush_global_sym(&func_old_type, TOK___fixdfdi); + vswap(); + gfunc_call(1); + vpushi(0); + vtop->r = REG_IRET; + vtop->r2 = REG_LRET; } /* convert from one floating point type to another */ diff --git a/lib/libtcc1.c b/lib/libtcc1.c index 3103691..44208cd 100644 --- a/lib/libtcc1.c +++ b/lib/libtcc1.c @@ -478,24 +478,6 @@ long long __ashldi3(long long a, int b) #endif } -#ifndef _WIN32 -void __tcc_fpinit(void) -{ - unsigned c = 0x137F; - __asm__ __volatile__ ("fldcw %0" : : "m" (c)); -} -#endif -long long __tcc_cvt_ftol(long double x) -{ - unsigned c0, c1; - long long ret; - __asm__ __volatile__ ("fnstcw %0" : "=m" (c0)); - c1 = c0 | 0x0C00; - __asm__ __volatile__ ("fldcw %0" : : "m" (c1)); - __asm__ __volatile__ ("fistpll %0" : "=m" (ret)); - __asm__ __volatile__ ("fldcw %0" : : "m" (c0)); - return ret; -} #endif /* !__x86_64__ */ /* XXX: fix tcc's code generator to do this instead */ @@ -616,6 +598,27 @@ unsigned long long __fixunsxfdi (long double a1) return 0; } +long long __fixsfdi (float a1) +{ + long long ret; int s; + ret = __fixunssfdi((s = a1 >= 0) ? a1 : -a1); + return s ? ret : -ret; +} + +long long __fixdfdi (double a1) +{ + long long ret; int s; + ret = __fixunsdfdi((s = a1 >= 0) ? a1 : -a1); + return s ? ret : -ret; +} + +long long __fixxfdi (long double a1) +{ + long long ret; int s; + ret = __fixunsxfdi((s = a1 >= 0) ? a1 : -a1); + return s ? ret : -ret; +} + #if defined(__x86_64__) && !defined(_WIN64) #ifndef __TINYC__ diff --git a/tccelf.c b/tccelf.c index caa8281..aa3daac 100644 --- a/tccelf.c +++ b/tccelf.c @@ -178,11 +178,11 @@ LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name) return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0); } -#ifdef TCC_IS_NATIVE +#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE /* return elf symbol value or error */ ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name) { - return (void*)get_elf_sym_addr(s, name, 1); + return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1); } #endif diff --git a/tccpe.c b/tccpe.c index bc1545e..62df865 100644 --- a/tccpe.c +++ b/tccpe.c @@ -1800,7 +1800,9 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) if (TCC_OUTPUT_MEMORY == s1->output_type) { pe_type = PE_RUN; +#ifdef TCC_IS_NATIVE s1->runtime_main = start_symbol; +#endif } else { pe->start_addr = (DWORD)tcc_get_symbol_err(s1, start_symbol); } diff --git a/tcctok.h b/tcctok.h index 9b47a60..73b0cf9 100644 --- a/tcctok.h +++ b/tcctok.h @@ -143,23 +143,34 @@ #endif /* builtin functions or variables */ -#ifdef TCC_ARM_EABI - DEF(TOK_memcpy, "__aeabi_memcpy") - DEF(TOK_memcpy4, "__aeabi_memcpy4") - DEF(TOK_memcpy8, "__aeabi_memcpy8") - DEF(TOK_memset, "__aeabi_memset") - DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod") - DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod") -#else +#ifndef TCC_ARM_EABI DEF(TOK_memcpy, "memcpy") DEF(TOK_memset, "memset") DEF(TOK___divdi3, "__divdi3") DEF(TOK___moddi3, "__moddi3") DEF(TOK___udivdi3, "__udivdi3") DEF(TOK___umoddi3, "__umoddi3") + DEF(TOK___ashrdi3, "__ashrdi3") + DEF(TOK___lshrdi3, "__lshrdi3") + DEF(TOK___ashldi3, "__ashldi3") + DEF(TOK___floatundisf, "__floatundisf") + DEF(TOK___floatundidf, "__floatundidf") +# ifndef TCC_ARM_VFP + DEF(TOK___floatundixf, "__floatundixf") + DEF(TOK___fixunsxfdi, "__fixunsxfdi") +# endif + DEF(TOK___fixunssfdi, "__fixunssfdi") + DEF(TOK___fixunsdfdi, "__fixunsdfdi") #endif -#if defined(TCC_TARGET_ARM) -#ifdef TCC_ARM_EABI + +#if defined TCC_TARGET_ARM +# ifdef TCC_ARM_EABI + DEF(TOK_memcpy, "__aeabi_memcpy") + DEF(TOK_memcpy4, "__aeabi_memcpy4") + DEF(TOK_memcpy8, "__aeabi_memcpy8") + DEF(TOK_memset, "__aeabi_memset") + DEF(TOK___aeabi_ldivmod, "__aeabi_ldivmod") + DEF(TOK___aeabi_uldivmod, "__aeabi_uldivmod") DEF(TOK___aeabi_idivmod, "__aeabi_idivmod") DEF(TOK___aeabi_uidivmod, "__aeabi_uidivmod") DEF(TOK___divsi3, "__aeabi_idiv") @@ -168,24 +179,33 @@ DEF(TOK___floatdidf, "__aeabi_l2d") DEF(TOK___fixsfdi, "__aeabi_f2lz") DEF(TOK___fixdfdi, "__aeabi_d2lz") -#else + DEF(TOK___ashrdi3, "__aeabi_lasr") + DEF(TOK___lshrdi3, "__aeabi_llsr") + DEF(TOK___ashldi3, "__aeabi_llsl") + DEF(TOK___floatundisf, "__aeabi_ul2f") + DEF(TOK___floatundidf, "__aeabi_ul2d") + DEF(TOK___fixunssfdi, "__aeabi_f2ulz") + DEF(TOK___fixunsdfdi, "__aeabi_d2ulz") +# else DEF(TOK___modsi3, "__modsi3") DEF(TOK___umodsi3, "__umodsi3") DEF(TOK___divsi3, "__divsi3") DEF(TOK___udivsi3, "__udivsi3") DEF(TOK___floatdisf, "__floatdisf") DEF(TOK___floatdidf, "__floatdidf") -#ifndef TCC_ARM_VFP +# ifndef TCC_ARM_VFP DEF(TOK___floatdixf, "__floatdixf") DEF(TOK___fixunssfsi, "__fixunssfsi") DEF(TOK___fixunsdfsi, "__fixunsdfsi") DEF(TOK___fixunsxfsi, "__fixunsxfsi") DEF(TOK___fixxfdi, "__fixxfdi") -#endif +# endif DEF(TOK___fixsfdi, "__fixsfdi") DEF(TOK___fixdfdi, "__fixdfdi") +# endif #endif -#elif defined(TCC_TARGET_C67) + +#if defined TCC_TARGET_C67 DEF(TOK__divi, "_divi") DEF(TOK__divu, "_divu") DEF(TOK__divf, "_divf") @@ -193,32 +213,18 @@ DEF(TOK__remi, "_remi") DEF(TOK__remu, "_remu") #endif -#ifdef TCC_TARGET_I386 - DEF(TOK___tcc_fpinit, "__tcc_fpinit") - DEF(TOK___tcc_cvt_ftol, "__tcc_cvt_ftol") -#endif -#ifdef TCC_ARM_EABI - DEF(TOK___ashrdi3, "__aeabi_lasr") - DEF(TOK___lshrdi3, "__aeabi_llsr") - DEF(TOK___ashldi3, "__aeabi_llsl") - DEF(TOK___floatundisf, "__aeabi_ul2f") - DEF(TOK___floatundidf, "__aeabi_ul2d") - DEF(TOK___fixunssfdi, "__aeabi_f2ulz") - DEF(TOK___fixunsdfdi, "__aeabi_d2ulz") -#else - DEF(TOK___ashrdi3, "__ashrdi3") - DEF(TOK___lshrdi3, "__lshrdi3") - DEF(TOK___ashldi3, "__ashldi3") - DEF(TOK___floatundisf, "__floatundisf") - DEF(TOK___floatundidf, "__floatundidf") -#ifndef TCC_ARM_VFP - DEF(TOK___floatundixf, "__floatundixf") - DEF(TOK___fixunsxfdi, "__fixunsxfdi") + +#if defined TCC_TARGET_I386 + DEF(TOK___fixsfdi, "__fixsfdi") + DEF(TOK___fixdfdi, "__fixdfdi") + DEF(TOK___fixxfdi, "__fixxfdi") #endif - DEF(TOK___fixunssfdi, "__fixunssfdi") - DEF(TOK___fixunsdfdi, "__fixunsdfdi") + +#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 + DEF(TOK_alloca, "alloca") #endif -#ifdef TCC_TARGET_PE + +#if defined TCC_TARGET_PE DEF(TOK___chkstk, "__chkstk") #endif @@ -233,20 +239,17 @@ DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16") DEF(TOK___bound_local_new, "__bound_local_new") DEF(TOK___bound_local_delete, "__bound_local_delete") -#ifdef TCC_TARGET_PE +# ifdef TCC_TARGET_PE DEF(TOK_malloc, "malloc") DEF(TOK_free, "free") DEF(TOK_realloc, "realloc") DEF(TOK_memalign, "memalign") DEF(TOK_calloc, "calloc") -#endif +# endif DEF(TOK_memmove, "memmove") DEF(TOK_strlen, "strlen") DEF(TOK_strcpy, "strcpy") #endif -#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64 - DEF(TOK_alloca, "alloca") -#endif /* Tiny Assembler */ DEF_ASM(byte) -- cgit v1.3.1 From b125743323f92b3492634cd875be820c890d5f29 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Sat, 29 Mar 2014 14:28:02 +0800 Subject: Create bcheck region for argv and arge argument For program manipulating argv or arge as pointer with construct such as: (while *argv++) { do_something_with_argv; } it is necessary to have argv and arge inside a region. This patch create regions argv and arge) if main is declared with those parameters. --- lib/bcheck.c | 7 +++++++ tccgen.c | 15 +++++++++++++++ tcctok.h | 1 + 3 files changed, 23 insertions(+) (limited to 'tcctok.h') diff --git a/lib/bcheck.c b/lib/bcheck.c index 064fb5d..968cdf4 100644 --- a/lib/bcheck.c +++ b/lib/bcheck.c @@ -418,6 +418,13 @@ void __bound_init(void) } } +void __bound_main_arg(void **p) +{ + void *start = p; + while (*p++); + __bound_new_region(start, (void *) p - start); +} + void __bound_exit(void) { restore_malloc_hooks(); diff --git a/tccgen.c b/tccgen.c index b4f97f4..fa03daf 100644 --- a/tccgen.c +++ b/tccgen.c @@ -5770,6 +5770,21 @@ static void gen_function(Sym *sym) /* push a dummy symbol to enable local sym storage */ sym_push2(&local_stack, SYM_FIELD, 0, 0); gfunc_prolog(&sym->type); +#ifdef CONFIG_TCC_BCHECK + if (tcc_state->do_bound_check + && !strcmp(get_tok_str(sym->v, NULL), "main")) { + int i; + + sym = local_stack; + for (i = 0, sym = local_stack; i < 2; i++, sym = sym->prev) { + if (sym->v & SYM_FIELD || sym->prev->v & SYM_FIELD) + break; + vpush_global_sym(&func_old_type, TOK___bound_main_arg); + vset(&sym->type, sym->r, sym->c); + gfunc_call(1); + } + } +#endif rsym = 0; block(NULL, NULL, NULL, NULL, 0, 0); gsym(rsym); diff --git a/tcctok.h b/tcctok.h index 73b0cf9..c17711f 100644 --- a/tcctok.h +++ b/tcctok.h @@ -237,6 +237,7 @@ DEF(TOK___bound_ptr_indir8, "__bound_ptr_indir8") DEF(TOK___bound_ptr_indir12, "__bound_ptr_indir12") DEF(TOK___bound_ptr_indir16, "__bound_ptr_indir16") + DEF(TOK___bound_main_arg, "__bound_main_arg") DEF(TOK___bound_local_new, "__bound_local_new") DEF(TOK___bound_local_delete, "__bound_local_delete") # ifdef TCC_TARGET_PE -- cgit v1.3.1 From fbda78aefeaaa97182658bb81b5a6f215cc24b17 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Mon, 14 Apr 2014 02:53:11 +0200 Subject: Parse and emit hidden visibility This adds parsing of (GCC compatible) visibility attribute in order to mark selected global symbols as hidden. The generated .o files contain hidden symbols already, the TCC linker doesn't yet do the right thing. --- tcc.h | 12 ++++++++++-- tccgen.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- tcctok.h | 2 ++ 3 files changed, 69 insertions(+), 5 deletions(-) (limited to 'tcctok.h') diff --git a/tcc.h b/tcc.h index dda2fc1..ab14b38 100644 --- a/tcc.h +++ b/tcc.h @@ -375,7 +375,8 @@ struct Attribute { func_proto : 1, mode : 4, weak : 1, - fill : 10; // 10 bits left to fit well in union below + visibility : 2, + fill : 8; // 8 bits left to fit well in union below }; /* GNUC attribute definition */ @@ -787,11 +788,18 @@ struct TCCState { #define VT_EXPORT 0x00008000 /* win32: data exported from dll */ #define VT_WEAK 0x00010000 /* weak symbol */ #define VT_TLS 0x00040000 /* thread-local storage */ +#define VT_VIS_SHIFT 19 /* shift for symbol visibility, overlapping + bitfield values, because bitfields never + have linkage and hence never have + visibility. */ +#define VT_VIS_SIZE 2 /* We have four visibilities. */ +#define VT_VIS_MASK (((1 << VT_VIS_SIZE)-1) << VT_VIS_SHIFT) #define VT_STRUCT_SHIFT 19 /* shift for bitfield shift values (max: 32 - 2*6) */ + /* type mask (except storage) */ -#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT | VT_WEAK) +#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT | VT_WEAK | VT_VIS_MASK) #define VT_TYPE (~(VT_STORAGE)) /* token values */ diff --git a/tccgen.c b/tccgen.c index 78f24aa..9b00824 100644 --- a/tccgen.c +++ b/tccgen.c @@ -300,6 +300,29 @@ static void weaken_symbol(Sym *sym) } } +static void apply_visibility(Sym *sym, CType *type) +{ + int vis = sym->type.t & VT_VIS_MASK; + int vis2 = type->t & VT_VIS_MASK; + if (vis == (STV_DEFAULT << VT_VIS_SHIFT)) + vis = vis2; + else if (vis2 == (STV_DEFAULT << VT_VIS_SHIFT)) + ; + else + vis = (vis < vis2) ? vis : vis2; + sym->type.t &= ~VT_VIS_MASK; + sym->type.t |= vis; + + if (sym->c > 0) { + int esym_type; + ElfW(Sym) *esym; + + esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; + vis >>= VT_VIS_SHIFT; + esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis; + } +} + /* ------------------------------------------------------------------------- */ ST_FUNC void swap(int *p, int *q) @@ -436,6 +459,13 @@ static Sym *external_sym(int v, CType *type, int r, char *asm_label) tcc_error("incompatible types for redefinition of '%s'", get_tok_str(v, NULL)); } + /* Merge some storage attributes. */ + if (type->t & VT_WEAK) + weaken_symbol(s); + + if (type->t & VT_VIS_MASK) + apply_visibility(s, type); + return s; } @@ -2662,6 +2692,24 @@ static void parse_attribute(AttributeDef *ad) next(); skip(')'); break; + case TOK_VISIBILITY1: + case TOK_VISIBILITY2: + skip('('); + if (tok != TOK_STR) + expect("visibility(\"default|hidden|internal|protected\")"); + if (!strcmp (tokc.cstr->data, "default")) + ad->a.visibility = STV_DEFAULT; + else if (!strcmp (tokc.cstr->data, "hidden")) + ad->a.visibility = STV_HIDDEN; + else if (!strcmp (tokc.cstr->data, "internal")) + ad->a.visibility = STV_INTERNAL; + else if (!strcmp (tokc.cstr->data, "protected")) + ad->a.visibility = STV_PROTECTED; + else + expect("visibility(\"default|hidden|internal|protected\")"); + next(); + skip(')'); + break; case TOK_ALIGNED1: case TOK_ALIGNED2: if (tok == '(') { @@ -5656,6 +5704,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, /* patch symbol weakness */ if (type->t & VT_WEAK) weaken_symbol(sym); + apply_visibility(sym, type); #ifdef CONFIG_TCC_BCHECK /* handles bounds now because the symbol must be defined before for the relocation */ @@ -5801,6 +5850,7 @@ static void gen_function(Sym *sym) /* patch symbol weakness (this definition overrules any prototype) */ if (sym->type.t & VT_WEAK) weaken_symbol(sym); + apply_visibility(sym, &sym->type); if (tcc_state->do_debug) { put_stabn(N_FUN, 0, 0, ind - func_ind); } @@ -5934,6 +5984,8 @@ static int decl0(int l, int is_for_loop_init) if (ad.a.func_export) type.t |= VT_EXPORT; #endif + type.t |= ad.a.visibility << VT_VIS_SHIFT; + if (tok == '{') { if (l == VT_LOCAL) tcc_error("cannot use local functions"); @@ -5973,6 +6025,11 @@ static int decl0(int l, int is_for_loop_init) if (sym->type.t & VT_STATIC) type.t = (type.t & ~VT_EXTERN) | VT_STATIC; + /* If the definition has no visibility use the + one from prototype. */ + if (! (type.t & VT_VIS_MASK)) + type.t |= sym->type.t & VT_VIS_MASK; + if (!is_compatible_types(&sym->type, &type)) { func_error1: tcc_error("incompatible types for redefinition of '%s'", @@ -6063,9 +6120,6 @@ static int decl0(int l, int is_for_loop_init) extern */ sym = external_sym(v, &type, r, asm_label); - if (type.t & VT_WEAK) - weaken_symbol(sym); - if (ad.alias_target) { Section tsec; Elf32_Sym *esym; diff --git a/tcctok.h b/tcctok.h index c17711f..d8c0344 100644 --- a/tcctok.h +++ b/tcctok.h @@ -121,6 +121,8 @@ DEF(TOK_DLLIMPORT, "dllimport") DEF(TOK_NORETURN1, "noreturn") DEF(TOK_NORETURN2, "__noreturn__") + DEF(TOK_VISIBILITY1, "visibility") + DEF(TOK_VISIBILITY2, "__visibility__") DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p") DEF(TOK_builtin_constant_p, "__builtin_constant_p") DEF(TOK_builtin_frame_address, "__builtin_frame_address") -- cgit v1.3.1 From a9fda392a0d03d62f0bef0acd42ec82b29216ab3 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Mon, 14 Apr 2014 03:33:50 +0200 Subject: Parse assembler .hidden directive This makes TCCs assembler understand the '.hidden symbol' directive (and emits a STV_HIDDEN ELF symbol then). --- libtcc.c | 3 +++ tccasm.c | 12 ++++++++---- tcctok.h | 1 + 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'tcctok.h') diff --git a/libtcc.c b/libtcc.c index a24ef2d..05abaef 100644 --- a/libtcc.c +++ b/libtcc.c @@ -508,6 +508,9 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, if (sym->type.t & VT_IMPORT) other |= 4; } +#else + if (! (sym->type.t & VT_STATIC)) + other = (sym->type.t & VT_VIS_MASK) >> VT_VIS_SHIFT; #endif if (tcc_state->leading_underscore && can_add_underscore) { buf1[0] = '_'; diff --git a/tccasm.c b/tccasm.c index 1c6a65d..38efe1c 100644 --- a/tccasm.c +++ b/tccasm.c @@ -483,6 +483,7 @@ static void asm_parse_directive(TCCState *s1) case TOK_ASM_globl: case TOK_ASM_global: case TOK_ASM_weak: + case TOK_ASM_hidden: tok1 = tok; do { Sym *sym; @@ -493,9 +494,12 @@ static void asm_parse_directive(TCCState *s1) sym = label_push(&s1->asm_labels, tok, 0); sym->type.t = VT_VOID; } - sym->type.t &= ~VT_STATIC; + if (tok1 != TOK_ASM_hidden) + sym->type.t &= ~VT_STATIC; if (tok1 == TOK_ASM_weak) sym->type.t |= VT_WEAK; + else if (tok1 == TOK_ASM_hidden) + sym->type.t |= STV_HIDDEN << VT_VIS_SHIFT; next(); } while (tok == ','); break; @@ -588,12 +592,12 @@ static void asm_parse_directive(TCCState *s1) tcc_error("label not found: %s", get_tok_str(tok, NULL)); } - next(); - skip(','); /* XXX .size name,label2-label1 */ if (s1->warn_unsupported) tcc_warning("ignoring .size %s,*", get_tok_str(tok, NULL)); + next(); + skip(','); while (tok != '\n' && tok != CH_EOF) { next(); } @@ -622,7 +626,7 @@ static void asm_parse_directive(TCCState *s1) } if (!strcmp(newtype, "function") || !strcmp(newtype, "STT_FUNC")) { - sym->type.t = VT_FUNC; + sym->type.t = (sym->type.t & ~VT_BTYPE) | VT_FUNC; } else if (s1->warn_unsupported) tcc_warning("change type of '%s' from 0x%x to '%s' ignored", diff --git a/tcctok.h b/tcctok.h index d8c0344..735ccdd 100644 --- a/tcctok.h +++ b/tcctok.h @@ -266,6 +266,7 @@ DEF_ASM(file) DEF_ASM(globl) DEF_ASM(global) + DEF_ASM(hidden) DEF_ASM(ident) DEF_ASM(size) DEF_ASM(type) -- cgit v1.3.1