| @@ -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; |
| 370 | | − p = strrchr(symbol, '@'); |
| 371 | | − if (p && isnum(p[1]) && symbol[0] == '_') { /* stdcall decor */ |
| 372 | | − strcpy(buffer, symbol+1)[p-symbol-1] = 0; |
| 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; |
| 369 | + const char *name = symtab_section->link->data + sym->st_name; |
| 370 | + if (s1->leading_underscore && name[0] == '_' && !(sym->st_other & 2)) |
| 371 | + return name + 1; |
| 372 | + return name; |
| 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 | 377 | char buffer[200]; |
| 388 | | − const char *s; |
| 378 | + const char *s, *p; |
| 389 | 379 | int sym_index, n = 0; |
| 380 | + |
| 390 | 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 | 402 | sym_index = find_elf_sym(s1->dynsymtab_section, s); |
| 393 | 403 | // printf("find (%d) %d %s\n", n, sym_index, s); |
| 394 | 404 | } while (0 == sym_index && ++n < 2); |
| @@ -899,7 +909,7 @@ static void pe_build_exports(struct pe_info *pe) · 504 unmodified lines |
| 899 | 909 | sym_end = symtab_section->data_offset / sizeof(ElfW(Sym)); |
| 900 | 910 | for (sym_index = 1; sym_index < sym_end; ++sym_index) { |
| 901 | 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 | 913 | if ((sym->st_other & 1) |
| 904 | 914 | /* export only symbols from actually written sections */ |
| 905 | 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 | 1230 | const char *name = symtab_section->link->data + sym->st_name; |
| 1221 | 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 | 1233 | struct import_symbol *is; |
| 1224 | 1234 | |
| 1225 | 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 | 1767 | start_symbol = |
| 1758 | 1768 | TCC_OUTPUT_MEMORY == s1->output_type |
| 1759 | | − ? PE_GUI == pe_type ? "_runwinmain" : NULL |
| 1760 | | − : PE_DLL == pe_type ? PE_STDSYM("_dllstart","@12") |
| 1761 | | − : PE_GUI == pe_type ? "_winstart" : "_start" |
| 1769 | + ? PE_GUI == pe_type ? "__runwinmain" : "_main" |
| 1770 | + : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12") |
| 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 | 1780 | /* grab the startup code from libtcc1 */ |
| 1765 | 1781 | if (start_symbol) |
| 1766 | 1782 | add_elf_sym(symtab_section, |