2

我正在编写代码以在 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

4

0 回答 0