runtime_loader: allow the ABI version symbol to be local.

Some libraries buildsystems (eg. zlib) somehow prevent the symbol from
being exported. We should fix that, but binaries with missing symbols
are already out there, so we need to handle them in any case.
This commit is contained in:
Adrien Destugues
2016-10-29 10:16:29 +02:00
parent 7393dae631
commit 61987fe7a2
3 changed files with 15 additions and 6 deletions
@@ -211,10 +211,9 @@ analyze_image_haiku_version_and_abi(int fd, image_t* image, elf_ehdr& eheader,
// Haiku API version // Haiku API version
elf_sym* symbol = find_symbol(image, elf_sym* symbol = find_symbol(image,
SymbolLookupInfo(B_SHARED_OBJECT_HAIKU_VERSION_VARIABLE_NAME, SymbolLookupInfo(B_SHARED_OBJECT_HAIKU_VERSION_VARIABLE_NAME,
B_SYMBOL_TYPE_DATA)); B_SYMBOL_TYPE_DATA, true));
if (symbol != NULL && symbol->st_shndx != SHN_UNDEF if (symbol != NULL && symbol->st_shndx != SHN_UNDEF
&& symbol->st_value > 0 && symbol->st_value > 0
&& symbol->Type() == STT_OBJECT
&& symbol->st_size >= sizeof(uint32)) { && symbol->st_size >= sizeof(uint32)) {
image->api_version image->api_version
= *(uint32*)(symbol->st_value + image->regions[0].delta); = *(uint32*)(symbol->st_value + image->regions[0].delta);
@@ -93,8 +93,18 @@ patch_undefined_symbol(image_t* rootImage, image_t* image, const char* name,
} }
static bool is_symbol_visible(elf_sym* symbol)
{
if (symbol->Bind() == STB_GLOBAL)
return true;
if (symbol->Bind() == STB_WEAK)
return true;
return false;
}
elf_sym* elf_sym*
find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo) find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo, bool allowLocal)
{ {
if (image->dynamic_ptr == 0) if (image->dynamic_ptr == 0)
return NULL; return NULL;
@@ -109,8 +119,7 @@ find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo)
elf_sym* symbol = &image->syms[i]; elf_sym* symbol = &image->syms[i];
if (symbol->st_shndx != SHN_UNDEF if (symbol->st_shndx != SHN_UNDEF
&& ((symbol->Bind() == STB_GLOBAL) && (allowLocal || is_symbol_visible(symbol))
|| (symbol->Bind() == STB_WEAK))
&& !strcmp(SYMNAME(image, symbol), lookupInfo.name)) { && !strcmp(SYMNAME(image, symbol), lookupInfo.name)) {
// check if the type matches // check if the type matches
@@ -128,7 +128,8 @@ void patch_undefined_symbol(image_t* rootImage, image_t* image,
const char* name, image_t** foundInImage, void** symbol, const char* name, image_t** foundInImage, void** symbol,
int32* type); int32* type);
elf_sym* find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo); elf_sym* find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo,
bool allowLocal = false);
status_t find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo, status_t find_symbol(image_t* image, const SymbolLookupInfo& lookupInfo,
void** _location); void** _location);
status_t find_symbol_breadth_first(image_t* image, status_t find_symbol_breadth_first(image_t* image,