/* for the -run option: dynamically load symbol from dll */ void *resolve_sym(struct TCCState *s1, const char *symbol, int type) { char buffer[100]; int sym_index, dll_index; void *addr, **m; DLLReference *dllref; sym_index = pe_find_import(s1, symbol); if (0 == sym_index) return NULL; dll_index = ((Elf32_Sym *)s1->dynsymtab_section->data + sym_index)->st_value; dllref = s1->loaded_dlls[dll_index-1]; if ( !dllref->handle ) { dllref->handle = LoadLibrary(dllref->name); } addr = GetProcAddress(dllref->handle, symbol); if (NULL == addr) addr = GetProcAddress(dllref->handle, get_alt_symbol(buffer, symbol)); if (addr && STT_OBJECT == type) { /* need to return a pointer to the address for data objects */ m = (void**)tcc_malloc(sizeof addr), *m = addr, addr = m; #ifdef MEM_DEBUG /* yep, we don't free it */ mem_cur_size -= sizeof (void*); #endif } return addr; }
static int pe_check_symbols(struct pe_info *pe) { Elf32_Sym *sym; int sym_index, sym_end; int ret = 0; pe_align_section(text_section, 8); sym_end = symtab_section->data_offset / sizeof(Elf32_Sym); for (sym_index = 1; sym_index < sym_end; ++sym_index) { sym = (Elf32_Sym *) symtab_section->data + sym_index; if (sym->st_shndx == SHN_UNDEF) { const char *name = symtab_section->link->data + sym->st_name; unsigned type = ELF32_ST_TYPE(sym->st_info); int imp_sym = pe_find_import(pe->s1, name); struct import_symbol *is; if (imp_sym == 0) goto not_found; is = pe_add_import(pe, imp_sym); if (!is) goto not_found; if (type == STT_FUNC) { unsigned long offset = is->thk_offset; if (offset) { // Got aliased symbol, like stricmp and _stricmp } else { char buffer[100]; offset = text_section->data_offset; // Add the 'jmp IAT[x]' instruction *(WORD *) section_ptr_add(text_section, 8) = 0x25FF; // Add a helper symbol, will be patched later in pe_build_imports sprintf(buffer, "IAT.%s", name); is->iat_index = put_elf_sym(symtab_section, 0, sizeof(DWORD), ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT), 0, SHN_UNDEF, buffer); put_elf_reloc(symtab_section, text_section, offset + 2, R_386_32, is->iat_index); is->thk_offset = offset; } // tcc_realloc might have altered sym's address sym = (Elf32_Sym *) symtab_section->data + sym_index; // Patch the original symbol sym->st_value = offset; sym->st_shndx = text_section->sh_num; sym->st_other &= ~1; // Do not export continue; } if (type == STT_OBJECT) { if (is->iat_index == 0) { // Original symbol will be patched later in pe_build_imports is->iat_index = sym_index; continue; } } not_found: error_noabort("undefined symbol '%s'", name); ret = 1; } else if (pe->s1->rdynamic && ELF32_ST_BIND(sym->st_info) != STB_LOCAL) { // If -rdynamic option, then export all non local symbols sym->st_other |= 1; } } return ret; }