| @@ -364,31 +364,41 @@ struct pe_info { · 363 unmodified lines |
| 364 | | 364 | |
| 365 | /* --------------------------------------------*/ | 365 | /* --------------------------------------------*/ |
| 366 | | 366 | |
| 367 | static const char* get_alt_symbol(char *buffer, const char *symbol) | 367 | static const char *pe_export_name(TCCState *s1, ElfW(Sym) *sym) |
| 368 | { | 368 | { |
| 369 | const char *p; | 369 | const char *name = symtab_section->link->data + sym->st_name; |
| 370 | p = strrchr(symbol, '@'); | 370 | if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & 2)) |
| 371 | if (p && isnum(p[1]) && symbol[0] == '_') { /* stdcall decor */ | 371 | return name + 1; |
| 372 | strcpy(buffer, symbol+1)[p-symbol-1] = 0; | 372 | return name; |
| 373 | } else if (symbol[0] != '_') { /* try non-ansi function */ | | |
| 374 | buffer[0] = '_', strcpy(buffer + 1, symbol); | | |
| 375 | } else if (0 == memcmp(symbol, "__imp__", 7)) { /* mingw 2.0 */ | | |
| 376 | strcpy(buffer, symbol + 6); | | |
| 377 | } else if (0 == memcmp(symbol, "_imp___", 7)) { /* mingw 3.7 */ | | |
| 378 | strcpy(buffer, symbol + 6); | | |
| 379 | } else { | | |
| 380 | return symbol; | | |
| 381 | } | | |
| 382 | return buffer; | | |
| 383 | } | 373 | } |
| 384 | | 374 | |
| 385 | static int pe_find_import(TCCState * s1, const char *symbol) | 375 | static int pe_find_import(TCCState * s1, ElfW(Sym) *sym) |
| 386 | { | 376 | { |
| 387 | char buffer[200]; | 377 | char buffer[200]; |
| 388 | const char *s; | 378 | const char *s, *p; |
| 389 | int sym_index, n = 0; | 379 | int sym_index, n = 0; |
| | 380 | |
| 390 | do { | 381 | do { |
| 391 | s = n ? get_alt_symbol(buffer, symbol) : symbol; | 382 | s = pe_export_name(s1, sym); |
| | 383 | if (n) { |
| | 384 | /* second try: */ |
| | 385 | if (sym->st_other & 2) { |
| | 386 | /* try w/0 stdcall deco (windows API convention) */ |
| | 387 | p = strrchr(s, '@'); |
| | 388 | if (!p || s[0] != '_') |
| | 389 | break; |
| | 390 | strcpy(buffer, s+1)[p-s-1] = 0; |
| | 391 | } else if (s[0] != '_') { /* try non-ansi function */ |
| | 392 | buffer[0] = '_', strcpy(buffer + 1, s); |
| | 393 | } else if (0 == memcmp(s, "__imp__", 7)) { /* mingw 2.0 */ |
| | 394 | strcpy(buffer, s + 6); |
| | 395 | } else if (0 == memcmp(s, "_imp___", 7)) { /* mingw 3.7 */ |
| | 396 | strcpy(buffer, s + 6); |
| | 397 | } else { |
| | 398 | break; |
| | 399 | } |
| | 400 | s = buffer; |
| | 401 | } |
| 392 | sym_index = find_elf_sym(s1->dynsymtab_section, s); | 402 | sym_index = find_elf_sym(s1->dynsymtab_section, s); |
| 393 | // printf("find (%d) %d %s\n", n, sym_index, s); | 403 | // printf("find (%d) %d %s\n", n, sym_index, s); |
| 394 | } while (0 == sym_index && ++n < 2); | 404 | } while (0 == sym_index && ++n < 2); |
| @@ -899,7 +909,7 @@ static void pe_build_exports(struct pe_info *pe) · 504 unmodified lines |
| 899 | sym_end = symtab_section->data_offset / sizeof(ElfW(Sym)); | 909 | sym_end = symtab_section->data_offset / sizeof(ElfW(Sym)); |
| 900 | for (sym_index = 1; sym_index < sym_end; ++sym_index) { | 910 | for (sym_index = 1; sym_index < sym_end; ++sym_index) { |
| 901 | sym = (ElfW(Sym)*)symtab_section->data + sym_index; | 911 | sym = (ElfW(Sym)*)symtab_section->data + sym_index; |
| 902 | name = symtab_section->link->data + sym->st_name; | 912 | name = pe_export_name(pe->s1, sym); |
| 903 | if ((sym->st_other & 1) | 913 | if ((sym->st_other & 1) |
| 904 | /* export only symbols from actually written sections */ | 914 | /* export only symbols from actually written sections */ |
| 905 | && pe->s1->sections[sym->st_shndx]->sh_addr) { | 915 | && pe->s1->sections[sym->st_shndx]->sh_addr) { |
| @@ -1219,7 +1229,7 @@ static int pe_check_symbols(struct pe_info *pe) · 313 unmodified lines |
| 1219 | | 1229 | |
| 1220 | const char *name = symtab_section->link->data + sym->st_name; | 1230 | const char *name = symtab_section->link->data + sym->st_name; |
| 1221 | unsigned type = ELFW_ST_TYPE(sym->st_info); | 1231 | unsigned type = ELFW_ST_TYPE(sym->st_info); |
| 1222 | int imp_sym = pe_find_import(pe->s1, name); | 1232 | int imp_sym = pe_find_import(pe->s1, sym); |
| 1223 | struct import_symbol *is; | 1233 | struct import_symbol *is; |
| 1224 | | 1234 | |
| 1225 | if (0 == imp_sym) | 1235 | if (0 == imp_sym) |
| @@ -1756,11 +1766,17 @@ static void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe) · 530 unmodified lines |
| 1756 | | 1766 | |
| 1757 | start_symbol = | 1767 | start_symbol = |
| 1758 | TCC_OUTPUT_MEMORY == s1->output_type | 1768 | TCC_OUTPUT_MEMORY == s1->output_type |
| 1759 | ? PE_GUI == pe_type ? "_runwinmain" : NULL | 1769 | ? PE_GUI == pe_type ? "__runwinmain" : "_main" |
| 1760 | : PE_DLL == pe_type ? PE_STDSYM("_dllstart","@12") | 1770 | : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12") |
| 1761 | : PE_GUI == pe_type ? "_winstart" : "_start" | 1771 | : PE_GUI == pe_type ? "__winstart" : "__start" |
| 1762 | ; | 1772 | ; |
| 1763 | | 1773 | |
| | 1774 | if (!s1->leading_underscore || strchr(start_symbol, '@')) { |
| | 1775 | ++start_symbol; |
| | 1776 | if (start_symbol[0] != '_') |
| | 1777 | start_symbol = NULL; |
| | 1778 | } |
| | 1779 | |
| 1764 | /* grab the startup code from libtcc1 */ | 1780 | /* grab the startup code from libtcc1 */ |
| 1765 | if (start_symbol) | 1781 | if (start_symbol) |
| 1766 | add_elf_sym(symtab_section, | 1782 | add_elf_sym(symtab_section, |