mirror of
https://github.com/frida/tinycc
synced 2024-12-24 22:16:49 +03:00
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
This commit is contained in:
parent
11b2d33523
commit
a3ebdd0aeb
2
libtcc.c
2
libtcc.c
@ -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
62
tccpe.c
@ -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,
|
||||
|
@ -150,6 +150,8 @@ seh_scopetable:
|
||||
seh_handler:
|
||||
jmp _except_handler3
|
||||
|
||||
.globl ___try__
|
||||
___try__:
|
||||
.globl __try__
|
||||
__try__:
|
||||
push %ebp
|
||||
|
Loading…
Reference in New Issue
Block a user