符号在一个独立的位置查找文件

时间:2013-07-01 16:47:10

标签: c elf symbols dynamic-loading

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

现在的问题是当我编译一个独立于位置的文件并尝试查找符号时。我能够找到一些符号,其余的函数返回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时,我可以找到add,Data符号,但令人惊讶的是我找不到'sub'。当我在.so文件上执行readelf时,我可以看到sub出现在DT_SYMTAB动态符号列表中。

任何人都可以指出代码错误? 这是一个如何打包符号的链接 http://docs.oracle.com/cd/E19082-01/819-0690/chapter6-48031/index.html

0 个答案:

没有答案