diff --git a/src/system/runtime_loader/arch/x86/arch_relocate.cpp b/src/system/runtime_loader/arch/x86/arch_relocate.cpp index e0090d02b6..d47f3af629 100644 --- a/src/system/runtime_loader/arch/x86/arch_relocate.cpp +++ b/src/system/runtime_loader/arch/x86/arch_relocate.cpp @@ -31,29 +31,22 @@ relocate_rel(image_t *rootImage, image_t *image, struct Elf32_Rel *rel, for (i = 0; i * (int)sizeof(struct Elf32_Rel) < rel_len; i++) { unsigned type = ELF32_R_TYPE(rel[i].r_info); + unsigned symbolIndex = ELF32_R_SYM(rel[i].r_info); - switch (type) { - case R_386_32: - case R_386_PC32: - case R_386_GLOB_DAT: - case R_386_JMP_SLOT: - case R_386_GOTOFF: - case R_386_TLS_DTPOFF32: - { - struct Elf32_Sym *sym; - status_t status; - sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info)); - - status = resolve_symbol(rootImage, image, sym, cache, &S); - if (status < B_OK) { - TRACE(("resolve symbol \"%s\" returned: %ld\n", - SYMNAME(image, sym), status)); - printf("resolve symbol \"%s\" returned: %ld\n", - SYMNAME(image, sym), status); - return status; - } + image_t* symbolImage = NULL; + if (symbolIndex != 0) { + Elf32_Sym* sym = SYMBOL(image, symbolIndex); + status_t status = resolve_symbol(rootImage, image, sym, cache, &S, + &symbolImage); + if (status < B_OK) { + TRACE(("resolve symbol \"%s\" returned: %ld\n", + SYMNAME(image, sym), status)); + printf("resolve symbol \"%s\" returned: %ld\n", + SYMNAME(image, sym), status); + return status; } } + switch (type) { case R_386_NONE: continue; @@ -92,7 +85,8 @@ relocate_rel(image_t *rootImage, image_t *image, struct Elf32_Rel *rel, break; #endif case R_386_TLS_DTPMOD32: - final_val = image->dso_tls_id; + final_val = symbolImage == NULL + ? image->dso_tls_id : symbolImage->dso_tls_id; break; case R_386_TLS_DTPOFF32: final_val = S; diff --git a/src/system/runtime_loader/arch/x86_64/arch_relocate.cpp b/src/system/runtime_loader/arch/x86_64/arch_relocate.cpp index b681a2164a..fda4c27c33 100644 --- a/src/system/runtime_loader/arch/x86_64/arch_relocate.cpp +++ b/src/system/runtime_loader/arch/x86_64/arch_relocate.cpp @@ -21,13 +21,14 @@ relocate_rela(image_t* rootImage, image_t* image, Elf64_Rela* rel, int type = ELF64_R_TYPE(rel[i].r_info); int symIndex = ELF64_R_SYM(rel[i].r_info); Elf64_Addr symAddr = 0; + image_t* symbolImage = NULL; // Resolve the symbol, if any. if (symIndex != 0) { Elf64_Sym* sym = SYMBOL(image, symIndex); status_t status = resolve_symbol(rootImage, image, sym, cache, - &symAddr); + &symAddr, &symbolImage); if (status != B_OK) { TRACE(("resolve symbol \"%s\" returned: %" B_PRId32 "\n", SYMNAME(image, sym), status)); @@ -57,7 +58,8 @@ relocate_rela(image_t* rootImage, image_t* image, Elf64_Rela* rel, relocValue = image->regions[0].delta + rel[i].r_addend; break; case R_X86_64_DTPMOD64: - relocValue = image->dso_tls_id; + relocValue = symbolImage == NULL + ? image->dso_tls_id : symbolImage->dso_tls_id; break; case R_X86_64_DTPOFF32: case R_X86_64_DTPOFF64: diff --git a/src/system/runtime_loader/elf_symbol_lookup.cpp b/src/system/runtime_loader/elf_symbol_lookup.cpp index 1a8ea17804..d6e87c655e 100644 --- a/src/system/runtime_loader/elf_symbol_lookup.cpp +++ b/src/system/runtime_loader/elf_symbol_lookup.cpp @@ -474,7 +474,7 @@ find_undefined_symbol_add_on(image_t* rootImage, image_t* image, int resolve_symbol(image_t* rootImage, image_t* image, elf_sym* sym, - SymbolLookupCache* cache, addr_t* symAddress) + SymbolLookupCache* cache, addr_t* symAddress, image_t** symbolImage) { uint32 index = sym - image->syms; @@ -581,6 +581,8 @@ resolve_symbol(image_t* rootImage, image_t* image, elf_sym* sym, cache->SetSymbolValueAt(index, (addr_t)location); + if (symbolImage) + *symbolImage = sharedImage; *symAddress = (addr_t)location; return B_OK; } diff --git a/src/system/runtime_loader/runtime_loader_private.h b/src/system/runtime_loader/runtime_loader_private.h index d00eb5f4cd..7774e1297c 100644 --- a/src/system/runtime_loader/runtime_loader_private.h +++ b/src/system/runtime_loader/runtime_loader_private.h @@ -76,7 +76,7 @@ status_t get_library_symbol(void* handle, void* caller, const char* symbolName, status_t get_next_image_dependency(image_id id, uint32* cookie, const char** _name); int resolve_symbol(image_t* rootImage, image_t* image, elf_sym* sym, - SymbolLookupCache* cache, addr_t* sym_addr); + SymbolLookupCache* cache, addr_t* sym_addr, image_t** symbolImage = NULL); status_t elf_verify_header(void* header, size_t length);