#include "resolve.h"
#include "vars.h"
#include "object_info.h"
#include <string.h>
static const Elf32_Sym *lookup_symbol(const char *symbol_name, const struct object_info_struct *object_info)
{
const char *string_table;
const Elf32_Sym *symbol_table;
const Elf32_Word *symbol_hash_table;
int nbuckets;
const Elf32_Word *bucket_array;
const Elf32_Word *chain_array;
register int idx;
string_table = object_info->dynamic_data.string_table;
symbol_table = object_info->dynamic_data.symbol_table;
symbol_hash_table = object_info->dynamic_data.symbol_hash_table;
nbuckets = symbol_hash_table[0];
if (nbuckets == 0)
return NULL;
bucket_array = symbol_hash_table + 2;
chain_array = bucket_array + nbuckets;
idx = bucket_array[elf_hash((const unsigned char *)symbol_name) % nbuckets];
while (1) {
if (!strcmp(symbol_name, string_table + symbol_table[idx].st_name))
return &symbol_table[idx];
if (chain_array[idx] == STN_UNDEF)
return NULL;
idx = chain_array[idx];
}
}
static const Elf32_Sym *search_symbol_definition(const char *symbol_name, struct object_info_struct *object_info)
{
const Elf32_Sym *symbol;
if (!(symbol = lookup_symbol(symbol_name, object_info)))
return NULL;
if (symbol->st_shndx != SHN_UNDEF)
return symbol;
if (object_info->type == OI_EXEC && ELF32_ST_TYPE(symbol->st_info) == STT_FUNC && symbol->st_value)
return symbol;
return NULL;
}
int resolve_symbol(struct object_info_struct *object_info, const Elf32_Sym *symbol, int flags, struct object_info_struct **found_object_info, const Elf32_Sym **found_symbol)
{
const char *symbol_name;
struct object_info_struct *object_info_1;
if (!symbol->st_name)
return 0;
symbol_name = object_info->dynamic_data.string_table + symbol->st_name;
if (object_info->type != OI_EXEC && object_info->dynamic_data.symbolic)
if ((*found_symbol = search_symbol_definition(symbol_name, object_info))) {
*found_object_info = object_info;
return 1;
}
if (!(flags & RF_NOEXEC))
if ((*found_symbol = search_symbol_definition(symbol_name, &executable_info))) {
*found_object_info = &executable_info;
return 1;
}
for (object_info_1 = shared_object_info_list.first; object_info_1; object_info_1 = object_info_1->next)
if ((*found_symbol = search_symbol_definition(symbol_name, object_info_1))) {
*found_object_info = object_info_1;
return 1;
}
if (ELF32_ST_BIND(symbol->st_info) == STB_WEAK) {
*found_symbol = NULL;
*found_object_info = NULL;
return 1;
}
return 0;
}