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
This commit is contained in:
41
tccpe.c
41
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)
|
||||
if (!(sv->sym->type.t & VT_IMPORT))
|
||||
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))
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user