tccpe: support leading underscore for symbols

To make this the default, enable this line in libtcc.c:tcc_new:

    #if defined(TCC_TARGET_PE) && 0
        s->leading_underscore = 1;

and then recompile tcc and also libtcc1.a
master
grischka 2011-02-13 17:41:05 +01:00
parent 11b2d33523
commit a3ebdd0aeb
3 changed files with 42 additions and 24 deletions

View File

@ -991,8 +991,8 @@ LIBTCCAPI TCCState *tcc_new(void)
#ifdef CHAR_IS_UNSIGNED
s->char_is_unsigned = 1;
#endif
/* enable this if you want symbols with leading underscore on windows: */
#if defined(TCC_TARGET_PE) && 0
/* XXX: currently the PE linker is not ready to support that */
s->leading_underscore = 1;
#endif
if (s->section_align == 0)

62
tccpe.c
View File

@ -364,31 +364,41 @@ struct pe_info {
/* --------------------------------------------*/
static const char* get_alt_symbol(char *buffer, const char *symbol)
static const char *pe_export_name(TCCState *s1, ElfW(Sym) *sym)
{
const char *p;
p = strrchr(symbol, '@');
if (p && isnum(p[1]) && symbol[0] == '_') { /* stdcall decor */
strcpy(buffer, symbol+1)[p-symbol-1] = 0;
} else if (symbol[0] != '_') { /* try non-ansi function */
buffer[0] = '_', strcpy(buffer + 1, symbol);
} else if (0 == memcmp(symbol, "__imp__", 7)) { /* mingw 2.0 */
strcpy(buffer, symbol + 6);
} else if (0 == memcmp(symbol, "_imp___", 7)) { /* mingw 3.7 */
strcpy(buffer, symbol + 6);
} else {
return symbol;
}
return buffer;
const char *name = symtab_section->link->data + sym->st_name;
if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & 2))
return name + 1;
return name;
}
static int pe_find_import(TCCState * s1, const char *symbol)
static int pe_find_import(TCCState * s1, ElfW(Sym) *sym)
{
char buffer[200];
const char *s;
const char *s, *p;
int sym_index, n = 0;
do {
s = n ? get_alt_symbol(buffer, symbol) : symbol;
s = pe_export_name(s1, sym);
if (n) {
/* second try: */
if (sym->st_other & 2) {
/* try w/0 stdcall deco (windows API convention) */
p = strrchr(s, '@');
if (!p || s[0] != '_')
break;
strcpy(buffer, s+1)[p-s-1] = 0;
} else if (s[0] != '_') { /* try non-ansi function */
buffer[0] = '_', strcpy(buffer + 1, s);
} else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */
strcpy(buffer, s + 6);
} else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */
strcpy(buffer, s + 6);
} else {
break;
}
s = buffer;
}
sym_index = find_elf_sym(s1->dynsymtab_section, s);
// printf("find (%d) %d %s\n", n, sym_index, s);
} while (0 == sym_index && ++n < 2);
@ -899,7 +909,7 @@ static void pe_build_exports(struct pe_info *pe)
sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
for (sym_index = 1; sym_index < sym_end; ++sym_index) {
sym = (ElfW(Sym)*)symtab_section->data + sym_index;
name = symtab_section->link->data + sym->st_name;
name = pe_export_name(pe->s1, sym);
if ((sym->st_other & 1)
/* export only symbols from actually written sections */
&& pe->s1->sections[sym->st_shndx]->sh_addr) {
@ -1219,7 +1229,7 @@ static int pe_check_symbols(struct pe_info *pe)
const char *name = symtab_section->link->data + sym->st_name;
unsigned type = ELFW_ST_TYPE(sym->st_info);
int imp_sym = pe_find_import(pe->s1, name);
int imp_sym = pe_find_import(pe->s1, sym);
struct import_symbol *is;
if (0 == imp_sym)
@ -1756,11 +1766,17 @@ static void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe)
start_symbol =
TCC_OUTPUT_MEMORY == s1->output_type
? PE_GUI == pe_type ? "_runwinmain" : NULL
: PE_DLL == pe_type ? PE_STDSYM("_dllstart","@12")
: PE_GUI == pe_type ? "_winstart" : "_start"
? PE_GUI == pe_type ? "__runwinmain" : "_main"
: PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12")
: PE_GUI == pe_type ? "__winstart" : "__start"
;
if (!s1->leading_underscore || strchr(start_symbol, '@')) {
++start_symbol;
if (start_symbol[0] != '_')
start_symbol = NULL;
}
/* grab the startup code from libtcc1 */
if (start_symbol)
add_elf_sym(symtab_section,

View File

@ -150,6 +150,8 @@ seh_scopetable:
seh_handler:
jmp _except_handler3
.globl ___try__
___try__:
.globl __try__
__try__:
push %ebp