ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c-在ELF文件中存储和检索版本信息

2019-10-25 18:50:48  阅读:324  来源: 互联网

标签:elf bfd c-3 linux


我试图找出一种在Linux上的C/C++可执行文件和库中存储和检索版本信息的好方法.我正在为我的C和C程序使用GCC编译器.

存储部分非常简单;声明这样的变量会将其存储在输出文件的.rodata节中:

const char MY_VERSION[] = "some_version_information";

但是,从外部程序中检索信息非常困难.使用共享库,使用dlopen和dlsym加载一个库并查找一个符号相当容易,但这可能不是最佳的实现方式,并且对可执行文件完全无效.另外,如果可能的话,我希望它可以与为不同体系结构构建的可执行文件和库一起使用.

我认为,由于共享库和可执行文件都使用ELF格式,因此使用知道如何读取ELF文件的库是有意义的.我能够找到的两个是libelf和BFD.我正在努力为每个文件寻找体面的文档.也许有更好的库可供使用?

到目前为止,这是我使用BFD的结果:

#include <stdio.h>                                                                                                                                                                                                               [6/1356]
#include <string.h>
#include <bfd.h>

int main(int argc, char* argv[])
{
    const char *filename;
    int i;
    size_t storage;
    bfd *b = NULL;
    asymbol **symbol_table;
    long num_symbols;

    if(argc != 2) return 1; // todo: print a useful message
    else filename = argv[1];

    b = bfd_openr(filename, NULL);

    if(b == NULL){
        fprintf(stderr, "Error: failed to open %s\n", filename);
        return 1;
    }

    // make sure we're opening a file that BFD understands
    if(!bfd_check_format(b, bfd_object)){
        fprintf(stderr, "Error: unrecognized format\n");
        return 1;
    }

    // how much memory is needed to store the symbol table
    storage = bfd_get_symtab_upper_bound(b);

    if(storage < 0){
        fprintf(stderr, "Error: unable to find storage bound of symbol table\n");
        return 1;
    } else if((symbol_table = malloc(storage)) == NULL){
        fprintf(stderr, "Error: failed to allocate memory for symbol table\n");
        return 1;
    } else {
        num_symbols = bfd_canonicalize_symtab(b, symbol_table);
    }

    for(i = 0; i < num_symbols; i++){
        if(strcmp(symbol_table[i]->name, "MY_VERSION") == 0){
            fprintf(stderr, "found MY_VERSION\n");

            // todo: print the string?
        }
    }

    return 0;
}

我意识到,由于ELF格式,打印字符串可能不是很简单.

有没有一种直接的方法来打印存储在ELF文件中的字符串符号?

解决方法:

从可执行文件内部,只需声明

 extern const char MY_VERSION[];

顺便说一句,对于C来说,最好将extern“ C”声明为该符号(即使在定义它的文件中).

然后,您的问题是如何在某些外部ELF可执行文件中找到符号MY_VERSION(最简单的方法可能是打开某些nm进程,请参见nm(1)).顺便说一句,它与功能符号(或数据符号)相同.您可以使用libelflibelfin(或古老的libbfd)之类的库,也可以自己解析ELF格式(请务必先阅读that Wikipage)

您应该学习并理解ELF格式.您需要仔细阅读有关ELF和x86-64 ABI的文档.使用objdump(1)& readelf(1).另请参见elf(5).阅读如何表示符号表以及如何计算其哈希码.当然,请详细阅读所有可能的relocations.您可以阅读Levine在Linkers and Loaders上的书,在Drepper在How to Write Shared Libraries上的书(均解释ELF),以及Assembler Language HowTo,和Ian Taylor的paper on goldELF: better symbol lookup via DT_GNU_HASH.在Hash Table Section和OSDEV ELF tutorial& ELF

您不需要任何特定的部分(或细分).

(我大约在20年前就为Sparc做到了;这并不难)

您也可以查看emacs源代码,其unexec.c正在编写一些ELF文件

顺便说一句,ELF有一些带有符号的版本控制信息,请参见例如dlvsym(3)

您可能还想了解execve(2)ld-linux(8)的工作原理,进程的虚拟地址空间是什么(请参阅proc(5),请尝试使用cat / proc / $$/ maps)

标签:elf,bfd,c-3,linux
来源: https://codeday.me/bug/20191025/1930530.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有