我正在编写代码以在 ELF 文件中查找符号。在我的代码中,我打开一个 ELF 文件,将所有段映射到内存,并将与各个部分和表相关的所有信息存储在这样的结构中。
typedef struct Struct_Obj_Entry{
//Name of the file
const char *filepath;
//File pointer
void* ELF_fp;
//Metadata of ELF header and Progam header tables
Elf32_Ehdr* Ehdr;
Elf32_Phdr* Phdr_array;
//base address of mapped region
uint32 mapbase;
//DYNAMIC Segment
uint32 *dynamic;
//DT_SYMTAB
Elf32_Sym *symtab; //Ptr to DT_SYMTAB
//DT_STRTAB
char *strtab;
//DT_HASH
uint32 *hashtab;//Ptr to DT_HASH
//Hash table variables
int nbuckets, nchains;
uint32 *buckets,
*chains;
} Obj_Entry;
这部分工作得很好,所有结构元素都正确填充,持有映射 ELF 文件区域的有效地址。
这是我搜索符号名称的方法,
void *return_symbol_vaddr(Obj_Entry *obj, const char *name){
unsigned long hash_value;
uint32 y=0,z=0;
/*following part is DLSYM code to locate a symbol in a given file*/
//Lets query for a symbol name
hash_value = elf_Hash(name);
printf("hash value =%lu\n",hash_value);
//See if correct symbol entry found in bucket list
//If it is break out
y = (obj->buckets[hash_value % obj->nbuckets]);
if((!strcmp(name, obj->strtab + obj->symtab[z].st_name))) {
return (void*)(obj->mapbase + (obj->symtab[z]).st_value);
}
//If not there is a collision
else{
while(obj->chains[y] !=0){
z = obj->chains[y];
if((!strcmp(name, obj->strtab + obj->symtab[z].st_name))) {
//return (void*)(obj->symtab[z].st_value);
return (void*)(obj->mapbase + obj->symtab[z].st_value);
}
else{
//If the symbol is not found in chains
//There is double collision
//In that case chain[y] gives the next symbol table entry with the same hash value
y = z;
}
}
}
}
字符串散列函数是标准 ABI 规范:
//Get hash value for a symbol name
unsigned long
elf_Hash(const unsigned char *name)
{
unsigned long h = 0, g;
while (*name)
{
h = (h << 4) + *name++;
if (g = h & 0xf0000000)
h ^= g >> 24;
h &= ~g;
}
return h;
}
现在的问题是当我编译一个与位置无关的so文件并尝试查找符号时。我能够找到一些符号,对于其余的符号,该函数返回 NULL 值。
示例 ELF 文件
typedef struct _data{
int x;
int y;
}data;
int add(void){
return 1;
}
int sub(void){
return 4;
}
data Data ={3, 2};
当我将此文件编译为 ELF 时,我可以找到添加数据符号,但令人惊讶的是,我找不到“子”。当我对 .so 文件执行 readelf 时,我可以看到 sub 出现在动态符号的 DT_SYMTAB 列表中。
任何人都可以指出代码错误?这是一个链接到如何将符号打包在一个 http://docs.oracle.com/cd/E19082-01/819-0690/chapter6-48031/index.html