make: make shorter command lines

Put former NATIVE_DEFINES into config.h.  Such tcc can be run
and tested directly from source more easily, like for example:

    tcc -run tcc.c -B. -run test.c

Also:
- tccelf.c: cleanup
- tccpp.c: avoid stupid clang warning
- configure: reduce -Wno- switches
- tcc.h: inline wait/post_sem()
- tccpe.c: simplify import (assume STT_NOTYPE is function)
This commit is contained in:
grischka
2024-11-21 12:03:32 +01:00
parent 4b0402825e
commit 729918ef35
21 changed files with 379 additions and 472 deletions

178
tccpe.c
View File

@@ -384,47 +384,6 @@ static const char *pe_export_name(TCCState *s1, ElfW(Sym) *sym)
return name;
}
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) {
/* try w/0 stdcall deco (windows API convention) */
p = strrchr(s, '@');
if (!p || s[0] != '_')
break;
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_", 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 {
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 n == 2 ? err : sym_index;
}
/*----------------------------------------------------------------------------*/
static int dynarray_assoc(void **pp, int n, int key)
{
@@ -905,12 +864,16 @@ static void pe_build_imports(struct pe_info *pe)
int iat_index = p->symbols[k]->iat_index;
int sym_index = p->symbols[k]->sym_index;
ElfW(Sym) *imp_sym = (ElfW(Sym) *)pe->s1->dynsymtab_section->data + sym_index;
ElfW(Sym) *org_sym = (ElfW(Sym) *)symtab_section->data + iat_index;
const char *name = (char*)pe->s1->dynsymtab_section->link->data + imp_sym->st_name;
int ordinal;
org_sym->st_value = thk_ptr;
org_sym->st_shndx = pe->thunk->sh_num;
/* patch symbol (and possibly its underscored alias) */
do {
ElfW(Sym) *esym = (ElfW(Sym) *)symtab_section->data + iat_index;
iat_index = esym->st_value;
esym->st_value = thk_ptr;
esym->st_shndx = pe->thunk->sh_num;
} while (iat_index);
if (dllref)
v = 0, ordinal = imp_sym->st_value; /* ordinal from pe_load_def */
@@ -1276,34 +1239,9 @@ add_section:
return 0;
}
/*----------------------------------------------------------------------------*/
static int pe_isafunc(TCCState *s1, int sym_index)
{
Section *sr = text_section->reloc;
ElfW_Rel *rel, *rel_end;
ElfW(Addr)info = ELFW(R_INFO)(sym_index, R_XXX_FUNCCALL);
#ifdef R_XXX_FUNCCALL2
ElfW(Addr)info2 = ELFW(R_INFO)(sym_index, R_XXX_FUNCCALL2);
#endif
if (!sr)
return 0;
rel_end = (ElfW_Rel *)(sr->data + sr->data_offset);
for (rel = (ElfW_Rel *)sr->data; rel < rel_end; rel++) {
if (rel->r_info == info)
return 1;
#ifdef R_XXX_FUNCCALL2
if (rel->r_info == info2)
return 1;
#endif
}
return 0;
}
/*----------------------------------------------------------------------------*/
static int pe_check_symbols(struct pe_info *pe)
{
ElfW(Sym) *sym;
int sym_index, sym_end;
int ret = 0;
TCCState *s1 = pe->s1;
@@ -1312,34 +1250,54 @@ static int pe_check_symbols(struct pe_info *pe)
sym_end = symtab_section->data_offset / sizeof(ElfW(Sym));
for (sym_index = 1; sym_index < sym_end; ++sym_index) {
sym = (ElfW(Sym) *)symtab_section->data + sym_index;
ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index;
if (sym->st_shndx == SHN_UNDEF) {
const char *name = (char*)symtab_section->link->data + sym->st_name;
unsigned type = ELFW(ST_TYPE)(sym->st_info);
int imp_sym = pe_find_import(pe->s1, sym);
int imp_sym;
struct import_symbol *is;
if (imp_sym <= 0)
goto not_found;
int _imp_, n;
char buffer[200];
const char *s, *p;
if (type == STT_NOTYPE) {
/* symbols from assembler have no type, find out which */
if (pe_isafunc(s1, sym_index))
type = STT_FUNC;
else
type = STT_OBJECT;
}
n = _imp_ = 0;
do {
s = pe_export_name(s1, sym);
if (n) {
/* second try: */
if (sym->st_other & ST_PE_STDCALL) {
/* try w/0 stdcall deco (windows API convention) */
p = strrchr(s, '@');
if (!p || s[0] != '_')
break;
strcpy(buffer, s+1)[p-s-1] = 0, s = buffer;
} else if (s[0] != '_') { /* try non-ansi function */
buffer[0] = '_', strcpy(buffer + 1, s), s = buffer;
} else if (0 == memcmp(s, "_imp__", 6)) { /* mingw 3.7 */
s += 6, _imp_ = 1;
} else if (0 == memcmp(s, "__imp_", 6)) { /* mingw 2.0 */
s += 6, _imp_ = 1;
} else {
break;
}
}
imp_sym = find_elf_sym(s1->dynsymtab_section, s);
} while (0 == imp_sym && ++n < 2);
//printf("pe_find_export (%d) %4x %s\n", n, imp_sym, name);
if (0 == imp_sym)
continue; /* will throw the 'undefined' error in relocate_syms() */
is = pe_add_import(pe, imp_sym);
if (type == STT_FUNC) {
if (type == STT_FUNC
/* symbols from assembler often have no type */
|| type == STT_NOTYPE) {
unsigned offset = is->thk_offset;
if (offset) {
/* got aliased symbol, like stricmp and _stricmp */
} else {
char buffer[100];
unsigned char *p;
/* add a helper symbol, will be patched later in
@@ -1372,29 +1330,19 @@ static int pe_check_symbols(struct pe_info *pe)
}
/* tcc_realloc might have altered sym's address */
sym = (ElfW(Sym) *)symtab_section->data + sym_index;
/* patch the original symbol */
sym->st_value = offset;
sym->st_shndx = text_section->sh_num;
sym->st_other &= ~ST_PE_EXPORT; /* do not export */
continue;
}
if (type == STT_OBJECT) { /* data, ptr to that should be */
if (0 == is->iat_index) {
/* original symbol will be patched later in pe_build_imports */
is->iat_index = sym_index;
continue;
}
} else { /* STT_OBJECT */
if (0 == _imp_ && 0 == (sym->st_other & ST_PE_IMPORT))
ret = tcc_error_noabort("symbol '%s' is missing __declspec(dllimport)", name);
/* original symbol will be patched later in pe_build_imports */
sym->st_value = is->iat_index; /* chain potential alias */
is->iat_index = sym_index;
}
not_found:
if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
/* STB_WEAK undefined symbols are accepted */
continue;
ret = tcc_error_noabort("undefined symbol '%s'%s", name,
imp_sym < 0 ? ", missing __declspec(dllimport)?":"");
} else if (pe->s1->rdynamic
&& ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
/* if -rdynamic option, then export all non local symbols */
@@ -1544,36 +1492,6 @@ static void pe_print_sections(TCCState *s1, const char *fname)
#endif
/* ------------------------------------------------------------- */
/* helper function for load/store to insert one more indirection */
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
ST_FUNC SValue *pe_getimport(SValue *sv, SValue *v2)
{
int r2;
if ((sv->r & (VT_VALMASK|VT_SYM)) != (VT_CONST|VT_SYM) || (sv->r2 != VT_CONST))
return sv;
if (!sv->sym->a.dllimport)
return sv;
// 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;
v2->sym = sv->sym;
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;
}
#endif
ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t value)
{