* Added SymbolLookupInfo::requestingSymbol which is passed in by

resolve_symbol().
* find_undefined_symbol_beos(): Does now check whether
  SymbolLookupInfo::requestingSymbol is defined, and, if so, returns it
  directly. This saves the time for the hash table lookup and also works
  around broken files like SoundPlay. Fixes the runtime loader part of #7094.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40211 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2011-01-12 12:43:13 +00:00
parent d49e0a272c
commit ca7aa99f98
2 changed files with 24 additions and 7 deletions

View File

@ -109,7 +109,7 @@ find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo)
Elf32_Sym* symbol = &image->syms[i]; Elf32_Sym* symbol = &image->syms[i];
if (symbol->st_shndx != SHN_UNDEF if (symbol->st_shndx != SHN_UNDEF
&& ((ELF32_ST_BIND(symbol->st_info)== STB_GLOBAL) && ((ELF32_ST_BIND(symbol->st_info) == STB_GLOBAL)
|| (ELF32_ST_BIND(symbol->st_info) == STB_WEAK)) || (ELF32_ST_BIND(symbol->st_info) == STB_WEAK))
&& !strcmp(SYMNAME(image, symbol), lookupInfo.name)) { && !strcmp(SYMNAME(image, symbol), lookupInfo.name)) {
@ -300,13 +300,25 @@ find_undefined_symbol_beos(image_t* rootImage, image_t* image,
{ {
// BeOS style symbol resolution: It is sufficient to check the image itself // BeOS style symbol resolution: It is sufficient to check the image itself
// and its direct dependencies. The linker would have complained, if the // and its direct dependencies. The linker would have complained, if the
// symbol wasn't there. // symbol wasn't there. First we check whether the requesting symbol is
// defined already -- then we can simply return it, since, due to symbolic
// linking, that's the one we'd find anyway.
if (Elf32_Sym* symbol = lookupInfo.requestingSymbol) {
if (symbol->st_shndx != SHN_UNDEF
&& ((ELF32_ST_BIND(symbol->st_info) == STB_GLOBAL)
|| (ELF32_ST_BIND(symbol->st_info) == STB_WEAK))) {
return symbol;
}
}
// lookup in image
Elf32_Sym* symbol = find_symbol(image, lookupInfo); Elf32_Sym* symbol = find_symbol(image, lookupInfo);
if (symbol != NULL) { if (symbol != NULL) {
*foundInImage = image; *foundInImage = image;
return symbol; return symbol;
} }
// lookup in dependencies
for (uint32 i = 0; i < image->num_needed; i++) { for (uint32 i = 0; i < image->num_needed; i++) {
if (image->needed[i]->dynamic_ptr) { if (image->needed[i]->dynamic_ptr) {
symbol = find_symbol(image->needed[i], lookupInfo); symbol = find_symbol(image->needed[i], lookupInfo);
@ -479,7 +491,7 @@ resolve_symbol(image_t* rootImage, image_t* image, struct Elf32_Sym* sym,
// search the symbol // search the symbol
sharedSym = rootImage->find_undefined_symbol(rootImage, image, sharedSym = rootImage->find_undefined_symbol(rootImage, image,
SymbolLookupInfo(symName, type, versionInfo), &sharedImage); SymbolLookupInfo(symName, type, versionInfo, 0, sym), &sharedImage);
} }
enum { enum {

View File

@ -25,26 +25,31 @@ struct SymbolLookupInfo {
uint32 hash; uint32 hash;
uint32 flags; uint32 flags;
const elf_version_info* version; const elf_version_info* version;
Elf32_Sym* requestingSymbol;
SymbolLookupInfo(const char* name, int32 type, uint32 hash, SymbolLookupInfo(const char* name, int32 type, uint32 hash,
const elf_version_info* version = NULL, uint32 flags = 0) const elf_version_info* version = NULL, uint32 flags = 0,
Elf32_Sym* requestingSymbol = NULL)
: :
name(name), name(name),
type(type), type(type),
hash(hash), hash(hash),
flags(flags), flags(flags),
version(version) version(version),
requestingSymbol(requestingSymbol)
{ {
} }
SymbolLookupInfo(const char* name, int32 type, SymbolLookupInfo(const char* name, int32 type,
const elf_version_info* version = NULL, uint32 flags = 0) const elf_version_info* version = NULL, uint32 flags = 0,
Elf32_Sym* requestingSymbol = NULL)
: :
name(name), name(name),
type(type), type(type),
hash(elf_hash(name)), hash(elf_hash(name)),
flags(flags), flags(flags),
version(version) version(version),
requestingSymbol(requestingSymbol)
{ {
} }
}; };