aboutsummaryrefslogtreecommitdiff
path: root/tccpe.c
diff options
context:
space:
mode:
authorgrischka <grischka>2017-04-04 08:34:52 +0200
committergrischka <grischka>2017-04-04 08:34:52 +0200
commit536ed76d5a69d8e3c0e247d6557f5942818cb253 (patch)
treed3cf8de45fcc8493fb7f9acd5239e63ec4a7b92e /tccpe.c
parentc4c3f5009e086b2eca472f61b99da1ade6d33286 (diff)
downloadtinycc-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.c41
1 files changed, 18 insertions, 23 deletions
diff --git a/tccpe.c b/tccpe.c
index 287eb99..2b0ea9a 100644
--- a/tccpe.c
+++ b/tccpe.c
@@ -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;