diff options
| author | grischka <grischka> | 2017-04-04 08:34:52 +0200 |
|---|---|---|
| committer | grischka <grischka> | 2017-04-04 08:34:52 +0200 |
| commit | 536ed76d5a69d8e3c0e247d6557f5942818cb253 (patch) | |
| tree | d3cf8de45fcc8493fb7f9acd5239e63ec4a7b92e /tccpe.c | |
| parent | c4c3f5009e086b2eca472f61b99da1ade6d33286 (diff) | |
| download | tinycc-536ed76d5a69d8e3c0e247d6557f5942818cb253.tar.gz tinycc-536ed76d5a69d8e3c0e247d6557f5942818cb253.tar.bz2 | |
tccgen/win32: let __declspec(dllimport) imply extern
Also, retain storage qualifiers in type_decl, in particular
also for function pointers. This allows to get rid of this
very early hack in decl()
type.t |= (btype.t & VT_STATIC); /* Retain "static". */
which was to fix the case of
int main() { static int (*foo)(); ...
Also:
- missing __declspec(dllimport) is an error now
- except if the symbol is "_imp__symbol"
- demonstrate export/import of data in the dll example (while
'extern' isn't strictly required with dllimport anymore)
- new function 'patch_storage()' replaces 'weaken_symbol()'
and 'apply_visibility()'
- new function 'update_storage()' applies storage attributes
to Elf symbols.
- put_extern_sym/2 accepts new pseudo section SECTION_COMMON
- add -Wl,-export-all-symbols as alias for -rdynamic
- add -Wl,-subsystem=windows for mingw compatibility
- redefinition of 'sym' error for initialized global data
Diffstat (limited to 'tccpe.c')
| -rw-r--r-- | tccpe.c | 41 |
1 files changed, 18 insertions, 23 deletions
@@ -396,9 +396,11 @@ static int pe_find_import(TCCState * s1, ElfW(Sym) *sym) char buffer[200]; const char *s, *p; int sym_index = 0, n = 0; + int a, err = 0; do { s = pe_export_name(s1, sym); + a = 0; if (n) { /* second try: */ if (sym->st_other & ST_PE_STDCALL) { @@ -409,19 +411,24 @@ static int pe_find_import(TCCState * s1, ElfW(Sym) *sym) 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 if (0 == memcmp(s, "__imp_", 6)) { /* mingw 2.0 */ + strcpy(buffer, s + 6), a = 1; + } else if (0 == memcmp(s, "_imp__", 6)) { /* mingw 3.7 */ + strcpy(buffer, s + 6), a = 1; } else { - break; + continue; } s = buffer; } sym_index = find_elf_sym(s1->dynsymtab_section, s); // printf("find (%d) %d %s\n", n, sym_index, s); + if (sym_index + && ELFW(ST_TYPE)(sym->st_info) == STT_OBJECT + && 0 == (sym->st_other & ST_PE_IMPORT) + && 0 == a + ) err = -1, sym_index = 0; } while (0 == sym_index && ++n < 2); - return sym_index; + return n == 2 ? err : sym_index; } /*----------------------------------------------------------------------------*/ @@ -1239,7 +1246,7 @@ static int pe_check_symbols(struct pe_info *pe) int imp_sym = pe_find_import(pe->s1, sym); struct import_symbol *is; - if (0 == imp_sym) + if (imp_sym <= 0) goto not_found; if (type == STT_NOTYPE) { @@ -1313,7 +1320,8 @@ static int pe_check_symbols(struct pe_info *pe) if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK) /* STB_WEAK undefined symbols are accepted */ continue; - tcc_error_noabort("undefined symbol '%s'", name); + tcc_error_noabort("undefined symbol '%s'%s", name, + imp_sym < 0 ? ", missing __declspec(dllimport)?":""); ret = -1; } else if (pe->s1->rdynamic @@ -1470,23 +1478,12 @@ static void pe_print_sections(TCCState *s1, const char *fname) #ifndef TCC_TARGET_ARM ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2) { - Sym *sym; - ElfW(Sym) *esym; int r2; - if ((sv->r & (VT_VALMASK|VT_SYM)) != (VT_CONST|VT_SYM) || (sv->r2 != VT_CONST)) return sv; - sym = sv->sym; - if ((sym->type.t & (VT_EXTERN|VT_STATIC)) != VT_EXTERN) - return sv; - if (!sym->c) - put_extern_sym(sym, NULL, 0, 0); - esym = &((ElfW(Sym) *)symtab_section->data)[sym->c]; - if (!(esym->st_other & ST_PE_IMPORT)) + if (!(sv->sym->type.t & VT_IMPORT)) return sv; - - // printf("import %04x %04x %04x %s\n", sv->type.t, sym->type.t, sv->r, get_tok_str(sv->sym->v, NULL)); - + // printf("import %04x %04x %04x %s\n", sv->type.t, sv->sym->type.t, sv->r, get_tok_str(sv->sym->v, NULL)); memset(v2, 0, sizeof *v2); v2->type.t = VT_PTR; v2->r = VT_CONST | VT_SYM | VT_LVAL; @@ -1495,14 +1492,12 @@ ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2) r2 = get_reg(RC_INT); load(r2, v2); v2->r = r2; - if ((uint32_t)sv->c.i) { vpushv(v2); vpushi(sv->c.i); gen_opi('+'); *v2 = *vtop--; } - v2->type.t = sv->type.t; v2->r |= sv->r & VT_LVAL; return v2; |
