From 6a4f3cf127e6d70a7699c6f0094dab6fd299a3e8 Mon Sep 17 00:00:00 2001 From: grischka Date: Sat, 27 Jun 2020 17:15:06 +0200 Subject: [PATCH] rework leading underscores tested on win32/64 to pass the tests when enabled - libtcc.c : let tcc define __leading_underscore if enabled tcc_add_symbol() : add _ automatically - tccelf.c : remove tcc_get_symbol_err(), find_c_sym() currently symbol length is limited to 256 in several places, so we can use a fixed local buffer for now as well. - win32/lib/crtinit.c : new file for init/fini - lib/*.S, tests7* : use __leading_underscore - bt-log.c: this file wont work relibaly if compiled with gcc --- lib/alloca86-bt.S | 13 ++++-- lib/alloca86.S | 9 +++- lib/alloca86_64-bt.S | 23 +++++----- lib/alloca86_64.S | 10 +++-- lib/bt-dll.c | 8 +++- lib/bt-log.c | 13 ------ libtcc.c | 17 +++++-- tcc.h | 29 ++++++------ tccelf.c | 62 ++++++++++---------------- tccmacho.c | 6 +-- tccpe.c | 5 +-- tccrun.c | 6 +-- tests/asm-c-connect-1.c | 4 +- tests/asm-c-connect-2.c | 4 +- tests/tests2/85_asm-outside-function.c | 7 +-- tests/tests2/98_al_ax_extend.c | 2 +- tests/tests2/99_fastcall.c | 2 +- win32/lib/chkstk.S | 20 +++++---- win32/lib/crt1.c | 22 ++------- win32/lib/crtinit.c | 26 +++++++++++ win32/lib/dllcrt1.c | 26 +++-------- win32/lib/wincrt1.c | 22 ++------- x86_64-link.c | 2 + 23 files changed, 160 insertions(+), 178 deletions(-) create mode 100644 win32/lib/crtinit.c diff --git a/lib/alloca86-bt.S b/lib/alloca86-bt.S index 4f95cf1..177838a 100644 --- a/lib/alloca86-bt.S +++ b/lib/alloca86-bt.S @@ -1,9 +1,14 @@ /* ---------------------------------------------- */ /* alloca86-bt.S */ -.globl __bound_alloca +#ifdef __leading_underscore +# define _(s) _##s +#else +# define _(s) s +#endif -__bound_alloca: +.globl _(__bound_alloca) +_(__bound_alloca): pop %edx pop %eax mov %eax, %ecx @@ -30,8 +35,8 @@ p5: push %eax push %ecx push %eax - call __bound_new_region - add $8, %esp + call _(__bound_new_region) + add $8, %esp pop %eax pop %edx diff --git a/lib/alloca86.S b/lib/alloca86.S index bb7a2c2..bdc7391 100644 --- a/lib/alloca86.S +++ b/lib/alloca86.S @@ -1,9 +1,14 @@ /* ---------------------------------------------- */ /* alloca86.S */ -.globl alloca +#ifdef __leading_underscore +# define _(s) _##s +#else +# define _(s) s +#endif -alloca: +.globl _(alloca) +_(alloca): pop %edx pop %eax add $3,%eax diff --git a/lib/alloca86_64-bt.S b/lib/alloca86_64-bt.S index c3f4e54..d1df3a9 100644 --- a/lib/alloca86_64-bt.S +++ b/lib/alloca86_64-bt.S @@ -1,26 +1,25 @@ /* ---------------------------------------------- */ /* alloca86_64.S */ -#ifdef __APPLE__ -#define __bound_alloca ___bound_alloca -#define __bound_alloca_nr ___bound_alloca_nr -#define __bound_new_region ___bound_new_region +#ifdef __leading_underscore +# define _(s) _##s +#else +# define _(s) s #endif -.globl __bound_alloca -__bound_alloca: - +.globl _(__bound_alloca) +_(__bound_alloca): #ifdef _WIN32 inc %rcx # add one extra to separate regions - jmp alloca -.globl __bound_alloca_nr -__bound_alloca_nr: + jmp _(alloca) +.globl _(__bound_alloca_nr) +_(__bound_alloca_nr): dec %rcx push %rax mov %rcx,%rdx mov %rax,%rcx sub $32,%rsp - call __bound_new_region + call _(__bound_new_region) add $32,%rsp pop %rax ret @@ -40,7 +39,7 @@ __bound_alloca_nr: push %rdx push %rax - call __bound_new_region + call _(__bound_new_region) pop %rax pop %rdx diff --git a/lib/alloca86_64.S b/lib/alloca86_64.S index bb03233..5195eca 100644 --- a/lib/alloca86_64.S +++ b/lib/alloca86_64.S @@ -1,12 +1,14 @@ /* ---------------------------------------------- */ /* alloca86_64.S */ -#ifdef __APPLE__ -#define alloca _alloca +#ifdef __leading_underscore +# define _(s) _##s +#else +# define _(s) s #endif -.globl alloca -alloca: +.globl _(alloca) +_(alloca): pop %rdx #ifdef _WIN32 mov %rcx,%rax diff --git a/lib/bt-dll.c b/lib/bt-dll.c index fab08e8..3389bd7 100644 --- a/lib/bt-dll.c +++ b/lib/bt-dll.c @@ -35,13 +35,19 @@ REDIR(__bound_strchr) \ REDIR(__bound_strdup) +#ifdef __leading_underscore +#define _(s) "_"#s +#else +#define _(s) #s +#endif + #define REDIR(s) void *s; static struct { REDIR_ALL } all_ptrs; #undef REDIR #define REDIR(s) #s"\0" static const char all_names[] = REDIR_ALL; #undef REDIR -#define REDIR(s) __asm__(".global "#s";"#s": jmp *%0" : : "m" (all_ptrs.s) ); +#define REDIR(s) __asm__(".global " _(s) ";" _(s) ": jmp *%0" : : "m" (all_ptrs.s) ); static void all_jmps() { REDIR_ALL } #undef REDIR diff --git a/lib/bt-log.c b/lib/bt-log.c index 23a78ef..d767f08 100644 --- a/lib/bt-log.c +++ b/lib/bt-log.c @@ -13,15 +13,6 @@ int (*__rt_error)(void*, void*, const char *, va_list); # define DLL_EXPORT #endif -#if defined(__GNUC__) && (__GNUC__ >= 6) -/* - * At least gcc 6.2 complains when __builtin_frame_address is used with - * nonzero argument. - */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wframe-address" -#endif - DLL_EXPORT int tcc_backtrace(const char *fmt, ...) { va_list ap; @@ -44,7 +35,3 @@ DLL_EXPORT int tcc_backtrace(const char *fmt, ...) } return ret; } - -#if defined(__GNUC__) && (__GNUC__ >= 6) -#pragma GCC diagnostic pop -#endif diff --git a/libtcc.c b/libtcc.c index 143dfe9..9cbdc12 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1058,6 +1058,9 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type) if (s->option_pthread) tcc_define_symbol(s, "_REENTRANT", NULL); + if (s->leading_underscore) + tcc_define_symbol(s, "__leading_underscore", NULL); + if (!s->nostdinc) { /* default include paths */ /* -isystem paths have already been handled */ @@ -1236,6 +1239,7 @@ static int tcc_add_library_internal(TCCState *s, const char *fmt, return -1; } +#ifndef TCC_TARGET_MACHO /* find and load a dll. Return non zero if not found */ /* XXX: add '-rpath' option support ? */ ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags) @@ -1243,8 +1247,9 @@ ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags) return tcc_add_library_internal(s, "%s/%s", filename, flags, s->library_paths, s->nb_library_paths); } +#endif -#ifndef TCC_TARGET_PE +#if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename) { if (-1 == tcc_add_library_internal(s1, "%s/%s", @@ -1300,9 +1305,13 @@ LIBTCCAPI int tcc_add_symbol(TCCState *s1, const char *name, const void *val) So it is handled here as if it were in a DLL. */ pe_putimport(s1, 0, name, (uintptr_t)val); #else - set_elf_sym(symtab_section, (uintptr_t)val, 0, - ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, - SHN_ABS, name); + char buf[256]; + if (s1->leading_underscore) { + buf[0] = '_'; + pstrcpy(buf + 1, sizeof(buf) - 1, name); + name = buf; + } + set_global_sym(s1, name, NULL, (addr_t)(uintptr_t)val); /* NULL: SHN_ABS */ #endif return 0; } diff --git a/tcc.h b/tcc.h index d28e02b..8dde096 100644 --- a/tcc.h +++ b/tcc.h @@ -194,6 +194,10 @@ extern long double strtold (const char *__nptr, char **__endptr); # endif #endif +#if defined TCC_TARGET_PE || defined TCC_TARGET_MACHO +# define ELF_OBJ_ONLY /* create elf .o but native executables */ +#endif + /* ------------ path configuration ------------ */ #ifndef CONFIG_SYSROOT @@ -886,11 +890,6 @@ struct TCCState { int uw_sym; unsigned uw_offs; # endif -# define ELF_OBJ_ONLY -#endif - -#ifdef TCC_TARGET_MACHO -# define ELF_OBJ_ONLY #endif #ifndef ELF_OBJ_ONLY @@ -1281,11 +1280,12 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) #define AFF_BINTYPE_AR 3 #define AFF_BINTYPE_C67 4 - -#ifndef TCC_TARGET_PE +#ifndef ELF_OBJ_ONLY ST_FUNC int tcc_add_crt(TCCState *s, const char *filename); #endif +#ifndef TCC_TARGET_MACHO ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags); +#endif #ifdef CONFIG_TCC_BCHECK ST_FUNC void tcc_add_bcheck(TCCState *s1); #endif @@ -1538,21 +1538,16 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, int fd, unsigned long file_offset ST_FUNC int tcc_load_archive(TCCState *s1, int fd, int alacarte); ST_FUNC void add_array(TCCState *s1, const char *sec, int c); -#if !defined(ELF_OBJ_ONLY) || defined(TCC_TARGET_MACHO) +#if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE) ST_FUNC void build_got_entries(TCCState *s1); #endif ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc); ST_FUNC void squeeze_multi_relocs(Section *sec, size_t oldrelocoffset); -ST_FUNC int find_c_sym(TCCState *, const char *name); ST_FUNC addr_t get_sym_addr(TCCState *s, const char *name, int err, int forc); ST_FUNC void list_elf_symbols(TCCState *s, void *ctx, void (*symbol_cb)(void *ctx, const char *name, const void *val)); -#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE -ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name); -#endif - -ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, long offs); +ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs); /* Browse each elem of type in section starting at elem using variable */ @@ -1560,9 +1555,11 @@ ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, long of for (elem = (type *) sec->data + startoff; \ elem < (type *) (sec->data + sec->data_offset); elem++) -#ifndef TCC_TARGET_PE +#ifndef ELF_OBJ_ONLY ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level); ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd); +#endif +#ifndef TCC_TARGET_PE ST_FUNC void tcc_add_runtime(TCCState *s1); #endif @@ -1580,9 +1577,11 @@ enum gotplt_entry { #if !defined(ELF_OBJ_ONLY) || defined(TCC_TARGET_MACHO) ST_FUNC int code_reloc (int reloc_type); ST_FUNC int gotplt_entry_type (int reloc_type); +#if !defined(TCC_TARGET_MACHO) || defined TCC_IS_NATIVE ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr); ST_FUNC void relocate_plt(TCCState *s1); #endif +#endif ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val); /* ------------ xxx-gen.c ------------ */ diff --git a/tccelf.c b/tccelf.c index a370633..ebbd15f 100644 --- a/tccelf.c +++ b/tccelf.c @@ -481,42 +481,40 @@ ST_FUNC int find_elf_sym(Section *s, const char *name) return 0; } -ST_FUNC int find_c_sym(TCCState *s1, const char *name) -{ - int ret; - CString cstr; - if (s1->leading_underscore) { - cstr_new(&cstr); - cstr_ccat(&cstr, '_'); - cstr_cat(&cstr, name, 0); - name = cstr.data; - } - ret = find_elf_sym(s1->symtab, name); - if (s1->leading_underscore) - cstr_free(&cstr); - return ret; -} - /* return elf symbol value, signal error if 'err' is nonzero, decorate name if FORC */ ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc) { int sym_index; ElfW(Sym) *sym; - - if (forc) - sym_index = find_c_sym(s1, name); - else - sym_index = find_elf_sym(s1->symtab, name); + char buf[256]; + if (forc && s1->leading_underscore +#ifdef TCC_TARGET_PE + /* win32-32bit stdcall symbols always have _ already */ + && !strchr(name, '@') +#endif + ) { + buf[0] = '_'; + pstrcpy(buf + 1, sizeof(buf) - 1, name); + name = buf; + } + sym_index = find_elf_sym(s1->symtab, name); sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index]; if (!sym_index || sym->st_shndx == SHN_UNDEF) { if (err) tcc_error("%s not defined", name); - return 0; + return (addr_t)-1; } return sym->st_value; } +/* return elf symbol value */ +LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name) +{ + addr_t addr = get_sym_addr(s, name, 0, 1); + return addr == -1 ? NULL : (void*)(uintptr_t)addr; +} + /* list elf symbol names and values */ ST_FUNC void list_elf_symbols(TCCState *s, void *ctx, void (*symbol_cb)(void *ctx, const char *name, const void *val)) @@ -541,12 +539,6 @@ ST_FUNC void list_elf_symbols(TCCState *s, void *ctx, } } -/* return elf symbol value */ -LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name) -{ - return (void*)(uintptr_t)get_sym_addr(s, name, 0, 1); -} - /* list elf symbol names and values */ LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx, void (*symbol_cb)(void *ctx, const char *name, const void *val)) @@ -554,14 +546,6 @@ LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx, list_elf_symbols(s, ctx, symbol_cb); } -#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*)(uintptr_t)get_sym_addr(s, name, 1, 1); -} -#endif - #ifndef ELF_OBJ_ONLY static void version_add (TCCState *s1) @@ -1087,7 +1071,7 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr) } #endif -#if !defined(ELF_OBJ_ONLY) || defined(TCC_TARGET_MACHO) +#if !defined(ELF_OBJ_ONLY) || (defined(TCC_TARGET_MACHO) && defined TCC_IS_NATIVE) static void build_got(TCCState *s1) { /* if no got, then create it */ @@ -1294,7 +1278,7 @@ ST_FUNC void build_got_entries(TCCState *s1) } #endif -ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, long offs) +ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs) { int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF; if (sec && offs == -1) @@ -1306,7 +1290,7 @@ ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, long of static void add_init_array_defines(TCCState *s1, const char *section_name) { Section *s; - long end_offset; + addr_t end_offset; char buf[1024]; s = find_section(s1, section_name); if (!s) { diff --git a/tccmacho.c b/tccmacho.c index fc8d598..6ad127d 100644 --- a/tccmacho.c +++ b/tccmacho.c @@ -762,10 +762,10 @@ static void macho_write(TCCState *s1, struct macho *mo, FILE *fp) } for (sk = sk_unknown; sk < sk_last; sk++) { - struct segment_command_64 *seg; + //struct segment_command_64 *seg; if (!skinfo[sk].seg || !mo->sk_to_sect[sk].s) continue; - seg = get_segment(mo, skinfo[sk].seg); + /*seg =*/ get_segment(mo, skinfo[sk].seg); for (s = mo->sk_to_sect[sk].s; s; s = s->prev) { if (s->sh_type != SHT_NOBITS) { while (fileofs < s->sh_offset) @@ -811,7 +811,7 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename) Section *s; collect_sections(s1, &mo); relocate_syms(s1, s1->symtab, 0); - mo.ep->entryoff = get_sym_addr(s1, "_main", 1, 0) + mo.ep->entryoff = get_sym_addr(s1, "main", 1, 1) - get_segment(&mo, 1)->vmaddr; if (s1->nb_errors) goto do_ret; diff --git a/tccpe.c b/tccpe.c index d524294..9b59d92 100644 --- a/tccpe.c +++ b/tccpe.c @@ -1891,6 +1891,7 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) : (unicode_entry ? "__wstart" : "__start") ; + pe->start_symbol = start_symbol + 1; if (!s1->leading_underscore || strchr(start_symbol, '@')) ++start_symbol; @@ -1937,7 +1938,6 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) if (TCC_OUTPUT_MEMORY == s1->output_type) pe_type = PE_RUN; pe->type = pe_type; - pe->start_symbol = start_symbol; } static void pe_set_options(TCCState * s1, struct pe_info *pe) @@ -2020,8 +2020,7 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) } } pe.start_addr = (DWORD) - ((uintptr_t)tcc_get_symbol_err(s1, pe.start_symbol) - - pe.imagebase); + (get_sym_addr(s1, pe.start_symbol, 1, 1) - pe.imagebase); if (s1->nb_errors) ret = -1; else diff --git a/tccrun.c b/tccrun.c index d83eb52..0609cb4 100644 --- a/tccrun.c +++ b/tccrun.c @@ -147,15 +147,15 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) #endif s1->runtime_main = s1->nostdlib ? "_start" : "main"; - if ((s1->dflag & 16) && !find_c_sym(s1, s1->runtime_main)) + if ((s1->dflag & 16) && (addr_t)-1 == get_sym_addr(s1, s1->runtime_main, 0, 1)) return 0; #ifdef CONFIG_TCC_BACKTRACE if (s1->do_debug) - tcc_add_symbol(s1, &"_exit"[!s1->leading_underscore], rt_exit); + tcc_add_symbol(s1, "exit", rt_exit); #endif if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) return -1; - prog_main = tcc_get_symbol_err(s1, s1->runtime_main); + prog_main = (void*)get_sym_addr(s1, s1->runtime_main, 1, 1); #ifdef CONFIG_TCC_BACKTRACE memset(rc, 0, sizeof *rc); diff --git a/tests/asm-c-connect-1.c b/tests/asm-c-connect-1.c index c515c8d..d79270d 100644 --- a/tests/asm-c-connect-1.c +++ b/tests/asm-c-connect-1.c @@ -1,8 +1,6 @@ #include -#if defined _WIN32 && !defined __TINYC__ -# define _ "_" -#elif defined __APPLE__ +#if (defined _WIN32 || defined __APPLE__) && (!defined __TINYC__ || defined __leading_underscore) # define _ "_" #else # define _ diff --git a/tests/asm-c-connect-2.c b/tests/asm-c-connect-2.c index 4c00c71..e2b4b59 100644 --- a/tests/asm-c-connect-2.c +++ b/tests/asm-c-connect-2.c @@ -1,8 +1,6 @@ #include -#if defined _WIN32 && !defined __TINYC__ -# define _ "_" -#elif defined __APPLE__ +#if (defined _WIN32 || defined __APPLE__) && (!defined __TINYC__ || defined __leading_underscore) # define _ "_" #else # define _ diff --git a/tests/tests2/85_asm-outside-function.c b/tests/tests2/85_asm-outside-function.c index a7bd5b9..3d7434d 100644 --- a/tests/tests2/85_asm-outside-function.c +++ b/tests/tests2/85_asm-outside-function.c @@ -1,8 +1,9 @@ -#ifdef __APPLE__ -#define _ "_" +#ifdef __leading_underscore +# define _ "_" #else -#define _ +# define _ #endif + extern int printf (const char *, ...); extern void vide(void); __asm__(_"vide: ret"); diff --git a/tests/tests2/98_al_ax_extend.c b/tests/tests2/98_al_ax_extend.c index 9b4e02f..1cd6585 100644 --- a/tests/tests2/98_al_ax_extend.c +++ b/tests/tests2/98_al_ax_extend.c @@ -8,7 +8,7 @@ asm ( "ret;" ); -#if 1 +#ifndef __leading_underscore #define us _us #define ss _ss #define uc _uc diff --git a/tests/tests2/99_fastcall.c b/tests/tests2/99_fastcall.c index ee4b67d..8fbc904 100644 --- a/tests/tests2/99_fastcall.c +++ b/tests/tests2/99_fastcall.c @@ -5,7 +5,7 @@ #define __fastcall __attribute((fastcall)) #endif -#if 1 +#ifndef __leading_underscore #define SYMBOL(x) _##x #else #define SYMBOL(x) x diff --git a/win32/lib/chkstk.S b/win32/lib/chkstk.S index e360611..6f583a5 100644 --- a/win32/lib/chkstk.S +++ b/win32/lib/chkstk.S @@ -1,13 +1,18 @@ /* ---------------------------------------------- */ /* chkstk86.s */ +#ifdef __leading_underscore +# define _(s) _##s +#else +# define _(s) s +#endif + /* ---------------------------------------------- */ #ifndef __x86_64__ /* ---------------------------------------------- */ -.globl __chkstk - -__chkstk: +.globl _(__chkstk) +_(__chkstk): xchg (%esp),%ebp /* store ebp, get ret.addr */ push %ebp /* push ret.addr */ lea 4(%esp),%ebp /* setup frame ptr */ @@ -31,9 +36,8 @@ P0: #else /* ---------------------------------------------- */ -.globl __chkstk - -__chkstk: +.globl _(__chkstk) +_(__chkstk): xchg (%rsp),%rbp /* store ebp, get ret.addr */ push %rbp /* push ret.addr */ lea 8(%rsp),%rbp /* setup frame ptr */ @@ -57,8 +61,8 @@ P0: /* ---------------------------------------------- */ /* setjmp/longjmp support */ -.globl tinyc_getbp -tinyc_getbp: +.globl _(tinyc_getbp) +_(tinyc_getbp): mov %rbp,%rax ret diff --git a/win32/lib/crt1.c b/win32/lib/crt1.c index 96dcb0e..0686302 100644 --- a/win32/lib/crt1.c +++ b/win32/lib/crt1.c @@ -34,29 +34,15 @@ int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int glob void __cdecl __set_app_type(int apptype); unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask); extern int _tmain(int argc, _TCHAR * argv[], _TCHAR * env[]); -extern void (*__init_array_start[]) (int argc, char **argv, char **envp); -extern void (*__init_array_end[]) (int argc, char **argv, char **envp); -extern void (*__fini_array_start[]) (void); -extern void (*__fini_array_end[]) (void); + +#include "crtinit.c" static int do_main (int argc, _TCHAR * argv[], _TCHAR * env[]) { int retval; - long i; - - i = 0; - while (&__init_array_start[i] != __init_array_end) { -#ifdef UNICODE - (*__init_array_start[i++])(0, NULL, NULL); -#else - (*__init_array_start[i++])(argc, argv, env); -#endif - } + run_ctors(argc, argv, env); retval = _tmain(__argc, __targv, _tenviron); - i = 0; - while (&__fini_array_end[i] != __fini_array_start) { - (*__fini_array_end[--i])(); - } + run_dtors(); return retval; } diff --git a/win32/lib/crtinit.c b/win32/lib/crtinit.c new file mode 100644 index 0000000..31f087b --- /dev/null +++ b/win32/lib/crtinit.c @@ -0,0 +1,26 @@ +//+--------------------------------------------------------------------------- + +#ifdef __leading_underscore +# define _(s) s +#else +# define _(s) _##s +#endif + +extern void (*_(_init_array_start)[]) (int argc, _TCHAR **argv, _TCHAR **envp); +extern void (*_(_init_array_end)[]) (int argc, _TCHAR **argv, _TCHAR **envp); +extern void (*_(_fini_array_start)[]) (void); +extern void (*_(_fini_array_end)[]) (void); + +static void run_ctors(int argc, _TCHAR **argv, _TCHAR **env) +{ + int i = 0; + while (&_(_init_array_start)[i] != _(_init_array_end)) + (*_(_init_array_start)[i++])(argc, argv, env); +} + +static void run_dtors(void) +{ + int i = 0; + while (&_(_fini_array_end)[i] != _(_fini_array_start)) + (*_(_fini_array_end)[--i])(); +} diff --git a/win32/lib/dllcrt1.c b/win32/lib/dllcrt1.c index c92cf0f..5a9be82 100644 --- a/win32/lib/dllcrt1.c +++ b/win32/lib/dllcrt1.c @@ -1,32 +1,18 @@ //+--------------------------------------------------------------------------- +#include #include - -extern void (*__init_array_start[]) (int argc, char **argv, char **envp); -extern void (*__init_array_end[]) (int argc, char **argv, char **envp); -extern void (*__fini_array_start[]) (void); -extern void (*__fini_array_end[]) (void); +#include "crtinit.c" BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved); BOOL WINAPI _dllstart(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) { BOOL bRet; - int i; - - if (dwReason == DLL_PROCESS_ATTACH) { /* ignore DLL_THREAD_ATTACH */ - i = 0; - while (&__init_array_start[i] != __init_array_end) { - (*__init_array_start[i++])(0, NULL, NULL); - } - } - if (dwReason == DLL_PROCESS_DETACH) { /* ignore DLL_THREAD_DETACH */ - i = 0; - while (&__fini_array_end[i] != __fini_array_start) { - (*__fini_array_end[--i])(); - } - } + if (dwReason == DLL_PROCESS_ATTACH) /* ignore DLL_THREAD_ATTACH */ + run_ctors(0, 0, 0); bRet = DllMain (hDll, dwReason, lpReserved); + if (dwReason == DLL_PROCESS_DETACH) /* ignore DLL_THREAD_DETACH */ + run_dtors(); return bRet; } - diff --git a/win32/lib/wincrt1.c b/win32/lib/wincrt1.c index b294d9b..d74a0cf 100644 --- a/win32/lib/wincrt1.c +++ b/win32/lib/wincrt1.c @@ -23,21 +23,17 @@ int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int); #define _runtwinmain _runwinmain #endif -extern void (*__init_array_start[]) (int argc, char **argv, char **envp); -extern void (*__init_array_end[]) (int argc, char **argv, char **envp); -extern void (*__fini_array_start[]) (void); -extern void (*__fini_array_end[]) (void); - typedef struct { int newmode; } _startupinfo; int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*); +#include "crtinit.c" + static int go_winmain(TCHAR *arg1) { STARTUPINFO si; _TCHAR *szCmd, *p; int fShow; int retval; - int i; GetStartupInfo(&si); if (si.dwFlags & STARTF_USESHOWWINDOW) @@ -55,19 +51,9 @@ static int go_winmain(TCHAR *arg1) #if defined __i386__ || defined __x86_64__ _controlfp(0x10000, 0x30000); #endif - i = 0; - while (&__init_array_start[i] != __init_array_end) { -#ifdef UNICODE - (*__init_array_start[i++])(0, NULL, NULL); -#else - (*__init_array_start[i++])(__argc, __targv, _tenviron); -#endif - } + run_ctors(__argc, __targv, _tenviron); retval = _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow); - i = 0; - while (&__fini_array_end[i] != __fini_array_start) { - (*__fini_array_end[--i])(); - } + run_dtors(); return retval; } diff --git a/x86_64-link.c b/x86_64-link.c index ceec8d0..ec67d74 100644 --- a/x86_64-link.c +++ b/x86_64-link.c @@ -96,6 +96,7 @@ int gotplt_entry_type (int reloc_type) return -1; } +#if !defined(TCC_TARGET_MACHO) || defined TCC_IS_NATIVE ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr) { Section *plt = s1->plt; @@ -161,6 +162,7 @@ ST_FUNC void relocate_plt(TCCState *s1) } } #endif +#endif void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) {