linux - 程序可以读取自己的 Sprite 部分吗?

标签 linux elf backtrace

我想使用 ld 的 --build-id 选项来将构建信息添加到我的二进制文件中。但是,我不确定如何在程序中提供这些信息。假设我想编写一个程序,在每次发生异常时写入回溯,以及一个解析此信息的脚本。该脚本读取程序的符号表并搜索回溯中打印的地址(我被迫使用这样的脚本,因为该程序是静态链接的并且 backtrace_symbols 不起作用)。为了使脚本正常工作,我需要将程序的构建版本与创建回溯的程序的构建版本相匹配。如何从程序本身打印程序的构建版本(位于 .note.gnu.build-id elf 部分)?

最佳答案

How can I print the build version of the program (located in the .note.gnu.build-id elf section) from the program itself?

  1. 您需要阅读 ElfW(Ehdr)(在文件开头)以在您的二进制文件中找到程序头(.e_phoff.e_phnum 会告诉你程序头在哪里,以及要读多少)。

  2. 然后阅读程序头,直到找到程序的 PT_NOTE 段。该段将告诉您二进制文件中所有注释开头的偏移量。

  3. 然后您需要阅读 ElfW(Nhdr) 并跳过笔记的其余部分(笔记的总大小为 sizeof(Nhdr) + .n_namesz + .n_descsz ,正确对齐),直到找到带有 .n_type == NT_GNU_BUILD_ID 的注释。

  4. 一旦找到 NT_GNU_BUILD_ID 注释,跳过它的 .n_namesz,并阅读 .n_descsz 字节以阅读实际构建-id.

您可以通过将读取的内容与 readelf -n a.out 的输出进行比较来验证您正在读取正确的数据。

附言

如果您要像上面那样麻烦地解码 build-id,并且如果您的可执行文件没有被剥离,那么您最好只解码并打印 symbol 而不是名称(即复制 backtrace_symbols 的作用)——这实际上比解码 ELF 注释更容易,因为符号表包含固定大小的条目。

关于linux - 程序可以读取自己的 Sprite 部分吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17637745/

相关文章:

使用 mcmodel=medium 编译时 C++ 程序崩溃

c - mmap 区域上的 memset/memcpy 失败

C++ 程序在 gcc 的 SIGSEGV 期间不处理任何函数调用或 printf

c - 有没有gcc宏来确定帧指针没有被消除?

android - 在特定设备上获取 native Android Crash/system/lib64/libc.so (tgkill+8)

linux - 将多个文件从一个目录移动到远程 sftp 服务器上的另一个目录

linux - 解压缩文件夹的所有文件(错误处理)

linux - ioread32 后跟 iowrite32 没有给出相同的值

linux - 如何重命名目录中的所有文件添加当前 unix 日期的前缀

linux - 为什么.data可执行?