better st_other support

This commit is contained in:
bellard 2005-04-13 21:37:06 +00:00
parent ef156f0c44
commit d733dc752e
2 changed files with 47 additions and 43 deletions

View File

@ -178,7 +178,7 @@ void *tcc_get_symbol_err(TCCState *s, const char *name)
/* add an elf symbol : check if it is already defined and patch /* add an elf symbol : check if it is already defined and patch
it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */ it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
static int add_elf_sym(Section *s, unsigned long value, unsigned long size, static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
int info, int sh_num, const char *name) int info, int other, int sh_num, const char *name)
{ {
Elf32_Sym *esym; Elf32_Sym *esym;
int sym_bind, sym_index, sym_type, esym_bind; int sym_bind, sym_index, sym_type, esym_bind;
@ -217,11 +217,12 @@ static int add_elf_sym(Section *s, unsigned long value, unsigned long size,
esym->st_shndx = sh_num; esym->st_shndx = sh_num;
esym->st_value = value; esym->st_value = value;
esym->st_size = size; esym->st_size = size;
esym->st_other = other;
} }
} else { } else {
do_def: do_def:
sym_index = put_elf_sym(s, value, size, sym_index = put_elf_sym(s, value, size,
ELF32_ST_INFO(sym_bind, sym_type), 0, ELF32_ST_INFO(sym_bind, sym_type), other,
sh_num, name); sh_num, name);
} }
return sym_index; return sym_index;
@ -675,7 +676,7 @@ static void build_got(TCCState *s1)
s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE); s1->got = new_section(s1, ".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
s1->got->sh_entsize = 4; s1->got->sh_entsize = 4;
add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), add_elf_sym(symtab_section, 0, 4, ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT),
s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_"); 0, s1->got->sh_num, "_GLOBAL_OFFSET_TABLE_");
ptr = section_ptr_add(s1->got, 3 * sizeof(int)); ptr = section_ptr_add(s1->got, 3 * sizeof(int));
/* keep space for _DYNAMIC pointer, if present */ /* keep space for _DYNAMIC pointer, if present */
put32(ptr, 0); put32(ptr, 0);
@ -943,11 +944,11 @@ static void add_init_array_defines(TCCState *s1, const char *section_name)
add_elf_sym(symtab_section, add_elf_sym(symtab_section,
0, 0, 0, 0,
ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
s->sh_num, sym_start); s->sh_num, sym_start);
add_elf_sym(symtab_section, add_elf_sym(symtab_section,
end_offset, 0, end_offset, 0,
ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
s->sh_num, sym_end); s->sh_num, sym_end);
} }
@ -967,7 +968,7 @@ static void tcc_add_runtime(TCCState *s1)
ptr = section_ptr_add(bounds_section, sizeof(unsigned long)); ptr = section_ptr_add(bounds_section, sizeof(unsigned long));
*ptr = 0; *ptr = 0;
add_elf_sym(symtab_section, 0, 0, add_elf_sym(symtab_section, 0, 0,
ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
bounds_section->sh_num, "__bounds_start"); bounds_section->sh_num, "__bounds_start");
/* add bound check code */ /* add bound check code */
snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o"); snprintf(buf, sizeof(buf), "%s/%s", tcc_lib_path, "bcheck.o");
@ -1010,15 +1011,15 @@ static void tcc_add_linker_symbols(TCCState *s1)
add_elf_sym(symtab_section, add_elf_sym(symtab_section,
text_section->data_offset, 0, text_section->data_offset, 0,
ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
text_section->sh_num, "_etext"); text_section->sh_num, "_etext");
add_elf_sym(symtab_section, add_elf_sym(symtab_section,
data_section->data_offset, 0, data_section->data_offset, 0,
ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
data_section->sh_num, "_edata"); data_section->sh_num, "_edata");
add_elf_sym(symtab_section, add_elf_sym(symtab_section,
bss_section->data_offset, 0, bss_section->data_offset, 0,
ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
bss_section->sh_num, "_end"); bss_section->sh_num, "_end");
/* horrible new standard ldscript defines */ /* horrible new standard ldscript defines */
add_init_array_defines(s1, ".preinit_array"); add_init_array_defines(s1, ".preinit_array");
@ -1047,12 +1048,12 @@ static void tcc_add_linker_symbols(TCCState *s1)
snprintf(buf, sizeof(buf), "__start_%s", s->name); snprintf(buf, sizeof(buf), "__start_%s", s->name);
add_elf_sym(symtab_section, add_elf_sym(symtab_section,
0, 0, 0, 0,
ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
s->sh_num, buf); s->sh_num, buf);
snprintf(buf, sizeof(buf), "__stop_%s", s->name); snprintf(buf, sizeof(buf), "__stop_%s", s->name);
add_elf_sym(symtab_section, add_elf_sym(symtab_section,
s->data_offset, 0, s->data_offset, 0,
ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
s->sh_num, buf); s->sh_num, buf);
} }
next_sec: ; next_sec: ;
@ -1919,7 +1920,8 @@ static int tcc_load_object_file(TCCState *s1,
/* add symbol */ /* add symbol */
name = strtab + sym->st_name; name = strtab + sym->st_name;
sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size, sym_index = add_elf_sym(symtab_section, sym->st_value, sym->st_size,
sym->st_info, sym->st_shndx, name); sym->st_info, sym->st_other,
sym->st_shndx, name);
old_to_new_syms[i] = sym_index; old_to_new_syms[i] = sym_index;
} }
@ -2093,7 +2095,7 @@ static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
{ {
Elf32_Ehdr ehdr; Elf32_Ehdr ehdr;
Elf32_Shdr *shdr, *sh, *sh1; Elf32_Shdr *shdr, *sh, *sh1;
int i, nb_syms, nb_dts, sym_bind, ret; int i, nb_syms, nb_dts, sym_bind, ret, other;
Elf32_Sym *sym, *dynsym; Elf32_Sym *sym, *dynsym;
Elf32_Dyn *dt, *dynamic; Elf32_Dyn *dt, *dynamic;
unsigned char *dynstr; unsigned char *dynstr;
@ -2173,8 +2175,15 @@ static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
if (sym_bind == STB_LOCAL) if (sym_bind == STB_LOCAL)
continue; continue;
name = dynstr + sym->st_name; name = dynstr + sym->st_name;
#ifdef TCC_TARGET_PE
/* in the PE format we need to know the DLL from which the
symbol comes. XXX: add a new array for that ? */
other = s1->nb_loaded_dlls - 1;
#else
other = sym->st_other;
#endif
add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size, add_elf_sym(s1->dynsymtab_section, sym->st_value, sym->st_size,
sym->st_info, sym->st_shndx, name); sym->st_info, other, sym->st_shndx, name);
} }
/* load all referenced DLLs */ /* load all referenced DLLs */

53
tccpe.c
View File

@ -414,24 +414,25 @@ void *resolve_sym(struct TCCState *s1, const char *symbol, int type)
char buffer[100], *p = buffer; char buffer[100], *p = buffer;
void *a = NULL; void *a = NULL;
int sym_index = pe_find_import(s1, symbol, p); int sym_index = pe_find_import(s1, symbol, p);
int dll_index;
const char *dll_name;
void *hm;
if (sym_index) { if (sym_index) {
int dll_index = dll_index = ((Elf32_Sym *) s1->dynsymtab_section->data)[sym_index].
((Elf32_Sym *) s1->dynsymtab_section->data)[sym_index].
st_other; st_other;
if (dll_index) { dll_name = s1->loaded_dlls[dll_index]->name;
const char *dll_name = s1->loaded_dlls[dll_index - 1]->name; hm = GetModuleHandleA(dll_name);
void *hm = GetModuleHandleA(dll_name); if (NULL == hm)
if (NULL == hm) hm = LoadLibraryA(dll_name);
hm = LoadLibraryA(dll_name); if (hm) {
if (hm) { a = GetProcAddress(hm, buffer);
a = GetProcAddress(hm, buffer); if (a && STT_OBJECT == type) {
if (a && STT_OBJECT == type) { // need to return a pointer to the address for data objects
// need to return a pointer to the address for data objects dynarray_add(&pe_imp, &nb_pe_imp, a);
dynarray_add(&pe_imp, &nb_pe_imp, a); a = &pe_imp[nb_pe_imp - 1];
a = &pe_imp[nb_pe_imp - 1]; }
} }
}
}
} }
return a; return a;
} }
@ -642,9 +643,6 @@ ST int pe_add_import(struct pe_info *pe, int sym_index, DWORD offset)
dll_index = dll_index =
((Elf32_Sym *) pe->s1->dynsymtab_section->data)[sym_index]. ((Elf32_Sym *) pe->s1->dynsymtab_section->data)[sym_index].
st_other; st_other;
if (0 == dll_index)
return 0;
i = dynarray_assoc((void **) pe->imp_info, pe->imp_count, dll_index); i = dynarray_assoc((void **) pe->imp_info, pe->imp_count, dll_index);
if (-1 != i) { if (-1 != i) {
p = pe->imp_info[i]; p = pe->imp_info[i];
@ -694,7 +692,7 @@ ST void pe_build_imports(struct pe_info *pe)
struct pe_import_header *hdr; struct pe_import_header *hdr;
int k, n, v; int k, n, v;
struct pe_import_info *p = pe->imp_info[i]; struct pe_import_info *p = pe->imp_info[i];
const char *name = pe->s1->loaded_dlls[p->dll_index - 1]->name; const char *name = pe->s1->loaded_dlls[p->dll_index]->name;
/* put the dll name into the import header */ /* put the dll name into the import header */
if (0 == strncmp(name, "lib", 3)) if (0 == strncmp(name, "lib", 3))
@ -1079,7 +1077,7 @@ int pe_load_def_file(TCCState * s1, FILE * fp)
{ {
DLLReference *dllref; DLLReference *dllref;
int f = 0, sym_index; int f = 0, sym_index;
char *p, *p_other, line[120], dllname[40]; char *p, line[120], dllname[40];
while (fgets(line, sizeof line, fp)) { while (fgets(line, sizeof line, fp)) {
p = strchr(line, 0); p = strchr(line, 0);
while (p > line && p[-1] <= ' ') while (p > line && p[-1] <= ' ')
@ -1116,16 +1114,13 @@ int pe_load_def_file(TCCState * s1, FILE * fp)
++f; ++f;
default: default:
/* tccpe needs to know from what dll it should import
the sym */
sym_index = add_elf_sym(s1->dynsymtab_section, sym_index = add_elf_sym(s1->dynsymtab_section,
0, 0, ELF32_ST_INFO(STB_GLOBAL, 0, 0, ELF32_ST_INFO(STB_GLOBAL,
STT_FUNC), STT_FUNC),
s1->nb_loaded_dlls - 1,
text_section->sh_num, p); text_section->sh_num, p);
/*gr: tccpe needs to know from what dll it should import the sym */
p_other =
&((Elf32_Sym *) s1->dynsymtab_section->
data)[sym_index].st_other;
if (0 == *p_other)
*p_other = s1->nb_loaded_dlls;
continue; continue;
} }
} }
@ -1151,7 +1146,7 @@ unsigned long pe_add_runtime(TCCState * s1)
if (start_symbol) if (start_symbol)
add_elf_sym(symtab_section, add_elf_sym(symtab_section,
0, 0, 0, 0,
ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
SHN_UNDEF, start_symbol); SHN_UNDEF, start_symbol);
if (0 == s1->nostdlib) { if (0 == s1->nostdlib) {
@ -1171,7 +1166,7 @@ unsigned long pe_add_runtime(TCCState * s1)
/* for -run GUI's, put '_runwinmain' instead of 'main' */ /* for -run GUI's, put '_runwinmain' instead of 'main' */
add_elf_sym(symtab_section, add_elf_sym(symtab_section,
addr, 0, addr, 0,
ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), ELF32_ST_INFO(STB_GLOBAL, STT_NOTYPE), 0,
text_section->sh_num, "main"); text_section->sh_num, "main");
/* FreeConsole(); */ /* FreeConsole(); */