History

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

grischka committed 15 years ago

Commit a3ebdd01 parent 11b2d333 files · +42 −24Browse files

Unified · Split

3 files
  1. libtcc.c +1 −1
  2. tccpe.c +39 −23
  3. win32/lib/chkstk.S +2 −0
libtcc.c+1−1
@@ -991,8 +991,8 @@ LIBTCCAPI TCCState *tcc_new(void) · 990 unmodified lines
991991 #ifdef CHAR_IS_UNSIGNED
992992 s->char_is_unsigned = 1;
993993 #endif
994+ /* enable this if you want symbols with leading underscore on windows: */
994995 #if defined(TCC_TARGET_PE) && 0
995− /* XXX: currently the PE linker is not ready to support that */
996996 s->leading_underscore = 1;
997997 #endif
998998 if (s->section_align == 0)
tccpe.c+39−23
@@ -364,31 +364,41 @@ struct pe_info { · 363 unmodified lines
364364
365365 /* --------------------------------------------*/
366366
367−static const char* get_alt_symbol(char *buffer, const char *symbol)
367+static const char *pe_export_name(TCCState *s1, ElfW(Sym) *sym)
368368 {
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;
383373 }
384374
385−static int pe_find_import(TCCState * s1, const char *symbol)
375+static int pe_find_import(TCCState * s1, ElfW(Sym) *sym)
386376 {
387377 char buffer[200];
388− const char *s;
378+ const char *s, *p;
389379 int sym_index, n = 0;
380+
390381 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+ }
392402 sym_index = find_elf_sym(s1->dynsymtab_section, s);
393403 // printf("find (%d) %d %s\n", n, sym_index, s);
394404 } while (0 == sym_index && ++n < 2);
@@ -899,7 +909,7 @@ static void pe_build_exports(struct pe_info *pe) · 504 unmodified lines
899909 sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
900910 for (sym_index = 1; sym_index < sym_end; ++sym_index) {
901911 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);
903913 if ((sym->st_other & 1)
904914 /* export only symbols from actually written sections */
905915 && pe->s1->sections[sym->st_shndx]->sh_addr) {
@@ -1219,7 +1229,7 @@ static int pe_check_symbols(struct pe_info *pe) · 313 unmodified lines
12191229
12201230 const char *name = symtab_section->link->data + sym->st_name;
12211231 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);
12231233 struct import_symbol *is;
12241234
12251235 if (0 == imp_sym)
@@ -1756,11 +1766,17 @@ static void pe_add_runtime_ex(TCCState *s1, struct pe_info *pe) · 530 unmodified lines
17561766
17571767 start_symbol =
17581768 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"
17621772 ;
17631773
1774+ if (!s1->leading_underscore || strchr(start_symbol, '@')) {
1775+ ++start_symbol;
1776+ if (start_symbol[0] != '_')
1777+ start_symbol = NULL;
1778+ }
1779+
17641780 /* grab the startup code from libtcc1 */
17651781 if (start_symbol)
17661782 add_elf_sym(symtab_section,
win32/lib/chkstk.S+2−0
@@ -150,6 +150,8 @@ seh_scopetable: · 149 unmodified lines
150150 seh_handler:
151151 jmp _except_handler3
152152
153+.globl ___try__
154+___try__:
153155 .globl __try__
154156 __try__:
155157 push %ebp

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t