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
This commit is contained in:
grischka 2020-06-27 17:15:06 +02:00
parent 72277967ff
commit 6a4f3cf127
23 changed files with 160 additions and 178 deletions

View File

@ -1,9 +1,14 @@
/* ---------------------------------------------- */ /* ---------------------------------------------- */
/* alloca86-bt.S */ /* 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 %edx
pop %eax pop %eax
mov %eax, %ecx mov %eax, %ecx
@ -30,8 +35,8 @@ p5:
push %eax push %eax
push %ecx push %ecx
push %eax push %eax
call __bound_new_region call _(__bound_new_region)
add $8, %esp add $8, %esp
pop %eax pop %eax
pop %edx pop %edx

View File

@ -1,9 +1,14 @@
/* ---------------------------------------------- */ /* ---------------------------------------------- */
/* alloca86.S */ /* alloca86.S */
.globl alloca #ifdef __leading_underscore
# define _(s) _##s
#else
# define _(s) s
#endif
alloca: .globl _(alloca)
_(alloca):
pop %edx pop %edx
pop %eax pop %eax
add $3,%eax add $3,%eax

View File

@ -1,26 +1,25 @@
/* ---------------------------------------------- */ /* ---------------------------------------------- */
/* alloca86_64.S */ /* alloca86_64.S */
#ifdef __APPLE__ #ifdef __leading_underscore
#define __bound_alloca ___bound_alloca # define _(s) _##s
#define __bound_alloca_nr ___bound_alloca_nr #else
#define __bound_new_region ___bound_new_region # define _(s) s
#endif #endif
.globl __bound_alloca .globl _(__bound_alloca)
__bound_alloca: _(__bound_alloca):
#ifdef _WIN32 #ifdef _WIN32
inc %rcx # add one extra to separate regions inc %rcx # add one extra to separate regions
jmp alloca jmp _(alloca)
.globl __bound_alloca_nr .globl _(__bound_alloca_nr)
__bound_alloca_nr: _(__bound_alloca_nr):
dec %rcx dec %rcx
push %rax push %rax
mov %rcx,%rdx mov %rcx,%rdx
mov %rax,%rcx mov %rax,%rcx
sub $32,%rsp sub $32,%rsp
call __bound_new_region call _(__bound_new_region)
add $32,%rsp add $32,%rsp
pop %rax pop %rax
ret ret
@ -40,7 +39,7 @@ __bound_alloca_nr:
push %rdx push %rdx
push %rax push %rax
call __bound_new_region call _(__bound_new_region)
pop %rax pop %rax
pop %rdx pop %rdx

View File

@ -1,12 +1,14 @@
/* ---------------------------------------------- */ /* ---------------------------------------------- */
/* alloca86_64.S */ /* alloca86_64.S */
#ifdef __APPLE__ #ifdef __leading_underscore
#define alloca _alloca # define _(s) _##s
#else
# define _(s) s
#endif #endif
.globl alloca
alloca: .globl _(alloca)
_(alloca):
pop %rdx pop %rdx
#ifdef _WIN32 #ifdef _WIN32
mov %rcx,%rax mov %rcx,%rax

View File

@ -35,13 +35,19 @@
REDIR(__bound_strchr) \ REDIR(__bound_strchr) \
REDIR(__bound_strdup) REDIR(__bound_strdup)
#ifdef __leading_underscore
#define _(s) "_"#s
#else
#define _(s) #s
#endif
#define REDIR(s) void *s; #define REDIR(s) void *s;
static struct { REDIR_ALL } all_ptrs; static struct { REDIR_ALL } all_ptrs;
#undef REDIR #undef REDIR
#define REDIR(s) #s"\0" #define REDIR(s) #s"\0"
static const char all_names[] = REDIR_ALL; static const char all_names[] = REDIR_ALL;
#undef REDIR #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 } static void all_jmps() { REDIR_ALL }
#undef REDIR #undef REDIR

View File

@ -13,15 +13,6 @@ int (*__rt_error)(void*, void*, const char *, va_list);
# define DLL_EXPORT # define DLL_EXPORT
#endif #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, ...) DLL_EXPORT int tcc_backtrace(const char *fmt, ...)
{ {
va_list ap; va_list ap;
@ -44,7 +35,3 @@ DLL_EXPORT int tcc_backtrace(const char *fmt, ...)
} }
return ret; return ret;
} }
#if defined(__GNUC__) && (__GNUC__ >= 6)
#pragma GCC diagnostic pop
#endif

View File

@ -1058,6 +1058,9 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
if (s->option_pthread) if (s->option_pthread)
tcc_define_symbol(s, "_REENTRANT", NULL); tcc_define_symbol(s, "_REENTRANT", NULL);
if (s->leading_underscore)
tcc_define_symbol(s, "__leading_underscore", NULL);
if (!s->nostdinc) { if (!s->nostdinc) {
/* default include paths */ /* default include paths */
/* -isystem paths have already been handled */ /* -isystem paths have already been handled */
@ -1236,6 +1239,7 @@ static int tcc_add_library_internal(TCCState *s, const char *fmt,
return -1; return -1;
} }
#ifndef TCC_TARGET_MACHO
/* find and load a dll. Return non zero if not found */ /* find and load a dll. Return non zero if not found */
/* XXX: add '-rpath' option support ? */ /* XXX: add '-rpath' option support ? */
ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags) 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, return tcc_add_library_internal(s, "%s/%s", filename, flags,
s->library_paths, s->nb_library_paths); 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) ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename)
{ {
if (-1 == tcc_add_library_internal(s1, "%s/%s", 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. */ So it is handled here as if it were in a DLL. */
pe_putimport(s1, 0, name, (uintptr_t)val); pe_putimport(s1, 0, name, (uintptr_t)val);
#else #else
set_elf_sym(symtab_section, (uintptr_t)val, 0, char buf[256];
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, if (s1->leading_underscore) {
SHN_ABS, name); 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 #endif
return 0; return 0;
} }

29
tcc.h
View File

@ -194,6 +194,10 @@ extern long double strtold (const char *__nptr, char **__endptr);
# endif # endif
#endif #endif
#if defined TCC_TARGET_PE || defined TCC_TARGET_MACHO
# define ELF_OBJ_ONLY /* create elf .o but native executables */
#endif
/* ------------ path configuration ------------ */ /* ------------ path configuration ------------ */
#ifndef CONFIG_SYSROOT #ifndef CONFIG_SYSROOT
@ -886,11 +890,6 @@ struct TCCState {
int uw_sym; int uw_sym;
unsigned uw_offs; unsigned uw_offs;
# endif # endif
# define ELF_OBJ_ONLY
#endif
#ifdef TCC_TARGET_MACHO
# define ELF_OBJ_ONLY
#endif #endif
#ifndef ELF_OBJ_ONLY #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_AR 3
#define AFF_BINTYPE_C67 4 #define AFF_BINTYPE_C67 4
#ifndef ELF_OBJ_ONLY
#ifndef TCC_TARGET_PE
ST_FUNC int tcc_add_crt(TCCState *s, const char *filename); ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);
#endif #endif
#ifndef TCC_TARGET_MACHO
ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags); ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags);
#endif
#ifdef CONFIG_TCC_BCHECK #ifdef CONFIG_TCC_BCHECK
ST_FUNC void tcc_add_bcheck(TCCState *s1); ST_FUNC void tcc_add_bcheck(TCCState *s1);
#endif #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 int tcc_load_archive(TCCState *s1, int fd, int alacarte);
ST_FUNC void add_array(TCCState *s1, const char *sec, int c); 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); ST_FUNC void build_got_entries(TCCState *s1);
#endif #endif
ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc); 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 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 addr_t get_sym_addr(TCCState *s, const char *name, int err, int forc);
ST_FUNC void list_elf_symbols(TCCState *s, void *ctx, ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
void (*symbol_cb)(void *ctx, const char *name, const void *val)); void (*symbol_cb)(void *ctx, const char *name, const void *val));
#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE ST_FUNC int set_global_sym(TCCState *s1, const char *name, Section *sec, addr_t offs);
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);
/* Browse each elem of type <type> in section <sec> starting at elem <startoff> /* Browse each elem of type <type> in section <sec> starting at elem <startoff>
using variable <elem> */ using variable <elem> */
@ -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; \ for (elem = (type *) sec->data + startoff; \
elem < (type *) (sec->data + sec->data_offset); elem++) 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_dll(TCCState *s1, int fd, const char *filename, int level);
ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd); ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd);
#endif
#ifndef TCC_TARGET_PE
ST_FUNC void tcc_add_runtime(TCCState *s1); ST_FUNC void tcc_add_runtime(TCCState *s1);
#endif #endif
@ -1580,9 +1577,11 @@ enum gotplt_entry {
#if !defined(ELF_OBJ_ONLY) || defined(TCC_TARGET_MACHO) #if !defined(ELF_OBJ_ONLY) || defined(TCC_TARGET_MACHO)
ST_FUNC int code_reloc (int reloc_type); ST_FUNC int code_reloc (int reloc_type);
ST_FUNC int gotplt_entry_type (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 unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr);
ST_FUNC void relocate_plt(TCCState *s1); ST_FUNC void relocate_plt(TCCState *s1);
#endif #endif
#endif
ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val); ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val);
/* ------------ xxx-gen.c ------------ */ /* ------------ xxx-gen.c ------------ */

View File

@ -481,42 +481,40 @@ ST_FUNC int find_elf_sym(Section *s, const char *name)
return 0; 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 /* return elf symbol value, signal error if 'err' is nonzero, decorate
name if FORC */ name if FORC */
ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc) ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
{ {
int sym_index; int sym_index;
ElfW(Sym) *sym; ElfW(Sym) *sym;
char buf[256];
if (forc) if (forc && s1->leading_underscore
sym_index = find_c_sym(s1, name); #ifdef TCC_TARGET_PE
else /* win32-32bit stdcall symbols always have _ already */
sym_index = find_elf_sym(s1->symtab, name); && !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]; sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
if (!sym_index || sym->st_shndx == SHN_UNDEF) { if (!sym_index || sym->st_shndx == SHN_UNDEF) {
if (err) if (err)
tcc_error("%s not defined", name); tcc_error("%s not defined", name);
return 0; return (addr_t)-1;
} }
return sym->st_value; 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 */ /* list elf symbol names and values */
ST_FUNC void list_elf_symbols(TCCState *s, void *ctx, ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
void (*symbol_cb)(void *ctx, const char *name, const void *val)) 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 */ /* list elf symbol names and values */
LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx, LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
void (*symbol_cb)(void *ctx, const char *name, const void *val)) 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); 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 #ifndef ELF_OBJ_ONLY
static void static void
version_add (TCCState *s1) version_add (TCCState *s1)
@ -1087,7 +1071,7 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
} }
#endif #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) static void build_got(TCCState *s1)
{ {
/* if no got, then create it */ /* if no got, then create it */
@ -1294,7 +1278,7 @@ ST_FUNC void build_got_entries(TCCState *s1)
} }
#endif #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; int shn = sec ? sec->sh_num : offs ? SHN_ABS : SHN_UNDEF;
if (sec && offs == -1) 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) static void add_init_array_defines(TCCState *s1, const char *section_name)
{ {
Section *s; Section *s;
long end_offset; addr_t end_offset;
char buf[1024]; char buf[1024];
s = find_section(s1, section_name); s = find_section(s1, section_name);
if (!s) { if (!s) {

View File

@ -762,10 +762,10 @@ static void macho_write(TCCState *s1, struct macho *mo, FILE *fp)
} }
for (sk = sk_unknown; sk < sk_last; sk++) { 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) if (!skinfo[sk].seg || !mo->sk_to_sect[sk].s)
continue; 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) { for (s = mo->sk_to_sect[sk].s; s; s = s->prev) {
if (s->sh_type != SHT_NOBITS) { if (s->sh_type != SHT_NOBITS) {
while (fileofs < s->sh_offset) while (fileofs < s->sh_offset)
@ -811,7 +811,7 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename)
Section *s; Section *s;
collect_sections(s1, &mo); collect_sections(s1, &mo);
relocate_syms(s1, s1->symtab, 0); 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; - get_segment(&mo, 1)->vmaddr;
if (s1->nb_errors) if (s1->nb_errors)
goto do_ret; goto do_ret;

View File

@ -1891,6 +1891,7 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
: (unicode_entry ? "__wstart" : "__start") : (unicode_entry ? "__wstart" : "__start")
; ;
pe->start_symbol = start_symbol + 1;
if (!s1->leading_underscore || strchr(start_symbol, '@')) if (!s1->leading_underscore || strchr(start_symbol, '@'))
++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) if (TCC_OUTPUT_MEMORY == s1->output_type)
pe_type = PE_RUN; pe_type = PE_RUN;
pe->type = pe_type; pe->type = pe_type;
pe->start_symbol = start_symbol;
} }
static void pe_set_options(TCCState * s1, struct pe_info *pe) 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) pe.start_addr = (DWORD)
((uintptr_t)tcc_get_symbol_err(s1, pe.start_symbol) (get_sym_addr(s1, pe.start_symbol, 1, 1) - pe.imagebase);
- pe.imagebase);
if (s1->nb_errors) if (s1->nb_errors)
ret = -1; ret = -1;
else else

View File

@ -147,15 +147,15 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
#endif #endif
s1->runtime_main = s1->nostdlib ? "_start" : "main"; 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; return 0;
#ifdef CONFIG_TCC_BACKTRACE #ifdef CONFIG_TCC_BACKTRACE
if (s1->do_debug) if (s1->do_debug)
tcc_add_symbol(s1, &"_exit"[!s1->leading_underscore], rt_exit); tcc_add_symbol(s1, "exit", rt_exit);
#endif #endif
if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
return -1; 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 #ifdef CONFIG_TCC_BACKTRACE
memset(rc, 0, sizeof *rc); memset(rc, 0, sizeof *rc);

View File

@ -1,8 +1,6 @@
#include <stdio.h> #include <stdio.h>
#if defined _WIN32 && !defined __TINYC__ #if (defined _WIN32 || defined __APPLE__) && (!defined __TINYC__ || defined __leading_underscore)
# define _ "_"
#elif defined __APPLE__
# define _ "_" # define _ "_"
#else #else
# define _ # define _

View File

@ -1,8 +1,6 @@
#include <stdio.h> #include <stdio.h>
#if defined _WIN32 && !defined __TINYC__ #if (defined _WIN32 || defined __APPLE__) && (!defined __TINYC__ || defined __leading_underscore)
# define _ "_"
#elif defined __APPLE__
# define _ "_" # define _ "_"
#else #else
# define _ # define _

View File

@ -1,8 +1,9 @@
#ifdef __APPLE__ #ifdef __leading_underscore
#define _ "_" # define _ "_"
#else #else
#define _ # define _
#endif #endif
extern int printf (const char *, ...); extern int printf (const char *, ...);
extern void vide(void); extern void vide(void);
__asm__(_"vide: ret"); __asm__(_"vide: ret");

View File

@ -8,7 +8,7 @@ asm (
"ret;" "ret;"
); );
#if 1 #ifndef __leading_underscore
#define us _us #define us _us
#define ss _ss #define ss _ss
#define uc _uc #define uc _uc

View File

@ -5,7 +5,7 @@
#define __fastcall __attribute((fastcall)) #define __fastcall __attribute((fastcall))
#endif #endif
#if 1 #ifndef __leading_underscore
#define SYMBOL(x) _##x #define SYMBOL(x) _##x
#else #else
#define SYMBOL(x) x #define SYMBOL(x) x

View File

@ -1,13 +1,18 @@
/* ---------------------------------------------- */ /* ---------------------------------------------- */
/* chkstk86.s */ /* chkstk86.s */
#ifdef __leading_underscore
# define _(s) _##s
#else
# define _(s) s
#endif
/* ---------------------------------------------- */ /* ---------------------------------------------- */
#ifndef __x86_64__ #ifndef __x86_64__
/* ---------------------------------------------- */ /* ---------------------------------------------- */
.globl __chkstk .globl _(__chkstk)
_(__chkstk):
__chkstk:
xchg (%esp),%ebp /* store ebp, get ret.addr */ xchg (%esp),%ebp /* store ebp, get ret.addr */
push %ebp /* push ret.addr */ push %ebp /* push ret.addr */
lea 4(%esp),%ebp /* setup frame ptr */ lea 4(%esp),%ebp /* setup frame ptr */
@ -31,9 +36,8 @@ P0:
#else #else
/* ---------------------------------------------- */ /* ---------------------------------------------- */
.globl __chkstk .globl _(__chkstk)
_(__chkstk):
__chkstk:
xchg (%rsp),%rbp /* store ebp, get ret.addr */ xchg (%rsp),%rbp /* store ebp, get ret.addr */
push %rbp /* push ret.addr */ push %rbp /* push ret.addr */
lea 8(%rsp),%rbp /* setup frame ptr */ lea 8(%rsp),%rbp /* setup frame ptr */
@ -57,8 +61,8 @@ P0:
/* ---------------------------------------------- */ /* ---------------------------------------------- */
/* setjmp/longjmp support */ /* setjmp/longjmp support */
.globl tinyc_getbp .globl _(tinyc_getbp)
tinyc_getbp: _(tinyc_getbp):
mov %rbp,%rax mov %rbp,%rax
ret ret

View File

@ -34,29 +34,15 @@ int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int glob
void __cdecl __set_app_type(int apptype); void __cdecl __set_app_type(int apptype);
unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask); unsigned int __cdecl _controlfp(unsigned int new_value, unsigned int mask);
extern int _tmain(int argc, _TCHAR * argv[], _TCHAR * env[]); 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); #include "crtinit.c"
extern void (*__fini_array_start[]) (void);
extern void (*__fini_array_end[]) (void);
static int do_main (int argc, _TCHAR * argv[], _TCHAR * env[]) static int do_main (int argc, _TCHAR * argv[], _TCHAR * env[])
{ {
int retval; int retval;
long i; run_ctors(argc, argv, env);
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
}
retval = _tmain(__argc, __targv, _tenviron); retval = _tmain(__argc, __targv, _tenviron);
i = 0; run_dtors();
while (&__fini_array_end[i] != __fini_array_start) {
(*__fini_array_end[--i])();
}
return retval; return retval;
} }

26
win32/lib/crtinit.c Normal file
View File

@ -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])();
}

View File

@ -1,32 +1,18 @@
//+--------------------------------------------------------------------------- //+---------------------------------------------------------------------------
#include <tchar.h>
#include <windows.h> #include <windows.h>
#include "crtinit.c"
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);
BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved); BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved);
BOOL WINAPI _dllstart(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved) BOOL WINAPI _dllstart(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
{ {
BOOL bRet; BOOL bRet;
int i; if (dwReason == DLL_PROCESS_ATTACH) /* ignore DLL_THREAD_ATTACH */
run_ctors(0, 0, 0);
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])();
}
}
bRet = DllMain (hDll, dwReason, lpReserved); bRet = DllMain (hDll, dwReason, lpReserved);
if (dwReason == DLL_PROCESS_DETACH) /* ignore DLL_THREAD_DETACH */
run_dtors();
return bRet; return bRet;
} }

View File

@ -23,21 +23,17 @@ int APIENTRY wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int);
#define _runtwinmain _runwinmain #define _runtwinmain _runwinmain
#endif #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; typedef struct { int newmode; } _startupinfo;
int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*); int __cdecl __tgetmainargs(int *pargc, _TCHAR ***pargv, _TCHAR ***penv, int globb, _startupinfo*);
#include "crtinit.c"
static int go_winmain(TCHAR *arg1) static int go_winmain(TCHAR *arg1)
{ {
STARTUPINFO si; STARTUPINFO si;
_TCHAR *szCmd, *p; _TCHAR *szCmd, *p;
int fShow; int fShow;
int retval; int retval;
int i;
GetStartupInfo(&si); GetStartupInfo(&si);
if (si.dwFlags & STARTF_USESHOWWINDOW) if (si.dwFlags & STARTF_USESHOWWINDOW)
@ -55,19 +51,9 @@ static int go_winmain(TCHAR *arg1)
#if defined __i386__ || defined __x86_64__ #if defined __i386__ || defined __x86_64__
_controlfp(0x10000, 0x30000); _controlfp(0x10000, 0x30000);
#endif #endif
i = 0; run_ctors(__argc, __targv, _tenviron);
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
}
retval = _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow); retval = _tWinMain(GetModuleHandle(NULL), NULL, szCmd, fShow);
i = 0; run_dtors();
while (&__fini_array_end[i] != __fini_array_start) {
(*__fini_array_end[--i])();
}
return retval; return retval;
} }

View File

@ -96,6 +96,7 @@ int gotplt_entry_type (int reloc_type)
return -1; 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) ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr)
{ {
Section *plt = s1->plt; Section *plt = s1->plt;
@ -161,6 +162,7 @@ ST_FUNC void relocate_plt(TCCState *s1)
} }
} }
#endif #endif
#endif
void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val) void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr, addr_t addr, addr_t val)
{ {