ELF文件信息一览

news2024/9/24 11:29:09

准备开个专栏,记录《从零开始实现链接器》的学习过程,先占个坑。

之前一直想把自己的学习过程记录在个人博客网站上,但这个要自己维护,上传图片什么的比较麻烦。关键是没有人互动,自己也没有怎么去看,慢慢的就遗忘了。在CSDN上有人点赞的时候我会看一下对应的博客,还能复习一下,索性后面的内容全部记录在CSDN上了。
学的过程中有一些零零散散的东西要记录,但可能没时间整理,索性先记一些关键词在这里,有空的时候在扩充和整理。所以我的博客可能经常不完整,像一个草稿,随记随保存。


参考链接:
静态链接和加载;最小动态加载器[南京大学(蒋炎岩)]
深入理解计算机系统——链接
从零开始实现链接器——第二课
https://en.wikipedia.org/wiki/GNU_Binutils

了解elf文件中的调试信息

有时候编译好程序调试的时候,虽然设置了断点,但程序并没有在断点的位置停下来。这可能是由于编译时没有创建调试信息。当使用g++编译程序时,通过-g参数可生成调试信息:

$ g++ -g elfinfo.cpp -o elfinfo
$ file elfinfo
elfinfo: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=c814baea7a3040d5463c6a203dfb82c8a7f235b1, for GNU/Linux 3.2.0, with debug_info, not stripped
$ readelf -S elfinfo | grep debug
  [29] .debug_aranges    PROGBITS         0000000000000000  00007043
  [30] .debug_info       PROGBITS         0000000000000000  000075d3
  [31] .debug_abbrev     PROGBITS         0000000000000000  00010cf5
  [32] .debug_line       PROGBITS         0000000000000000  000118bb
  [33] .debug_str        PROGBITS         0000000000000000  00012a7f
  [34] .debug_line_str   PROGBITS         0000000000000000  0001cb79
  [35] .debug_rnglists   PROGBITS         0000000000000000  0001cfa1

上面的命令先带-g去编译程序,通过file命令看到最后的信息为with debug_info, not stripped,说明时存在调试信息的,这类文件可以被调试。如果用readelf -S elfinfo查看Section Header Table里的信息,会发现存在一些debug段,调试器通过这些段来完成调试。如果不带-g进行编译,则没有这些段,因此不能调试。

ELF符号信息及其读取

这部分内容通过debug代码来了解符号的读取过程会更好理解。在github上有相关的项目:https://github.com/finixbit/elf-parser

有时候为了进一步缩小文件尺寸,还会使用strip命令删除文件中不重要的段,在strip后,通过file命令输出的信息中会显示stripped。当对比strip文件和未被strip的文件时,会发现strip后的文件少了两个段.symtab和.strtab。同时nm命令的输出结果为空,如下:

$ g++ elfinfo.cpp  -o elfinfo
$ nm -a ./elfinfo | wc
    186     507   11412
$ strip elfinfo
$ nm -a ./elfinfo | wc
nm: ./elfinfo: no symbols
      0       0       0

实际上符号有静态和动态两类,在strip后,只删除了静态符号(对应.symstr和.strtab),动态符号(对应.dynsym和.dynstr)依然保留,他们可以通过nm -D ./your_elf_file_path来查看。

在elf文件中,符号信息保存在.symstr.dynsym段中,这两个段其实就是两个数组,数组中的每个元素代表一条符号信息,每元素的长度是一样的。 但我们在用readelf工具去显示其中的符号时,会发现每个符号的字符串长度各不相同,有长有短,那么字符串在这两个段中是如何保存的呢?

这就需要用到.strtab.dynstr两个段了。.synstrdynsym本身并不存储符号的字符串信息,而是将其中涉及的字符串分别保存到.strtab.dynstr两个段。

下面是readelf命令从ELF文件中读取静态符号的过程:
在这里插入图片描述
nm命令从符号表.strtab .symtab中读取符号信息。通过readelf -x .strtab your_elf_file_path可以查看elf文件.strtab段的二进制内容:

$ readelf -x .strtab ./examples/sections | less
Hex dump of section '.strtab':
  0x00000000 00637274 73747566 662e6300 64657265 .crtstuff.c.dere
  0x00000010 67697374 65725f74 6d5f636c 6f6e6573 gister_tm_clones
  0x00000020 005f5f64 6f5f676c 6f62616c 5f64746f .__do_global_dto
  0x00000030 72735f61 75780063 6f6d706c 65746564 rs_aux.completed
  0x00000040 2e383036 31005f5f 646f5f67 6c6f6261 .8061.__do_globa
  0x00000050 6c5f6474 6f72735f 6175785f 66696e69 l_dtors_aux_fini
  0x00000060 5f617272 61795f65 6e747279 00667261 _array_entry.fra

第一列表示该行二进制的起始位置,随后四列为二进制数据,最后一列为二进制的字符串表示,这里将字符串的结束标志00表示为.

虽然这些字符是连在一起的,但通过这样的分隔标志即可划分每个字符串,在读取的时候,并不需要知道字符串的长度信息。在C++中,将这样的字符序列传递给std::string,它只会读取到第一个字符串,在00之后的则会被忽略。

结合上面的图示,在每一个Section Header中,都有一个offset用于说明对应节相对elf文件开头位置的偏移量。比如上面图示中,.symstr段的开始位置在离文件开头位置第337384个字节处,可以通过dd命令来验证:

$ dd if=./symbols bs=1 skip=337384 count=300 | xxd
00000000: 0063 7274 7374 7566 662e 6300 6465 7265  .crtstuff.c.dere
00000010: 6769 7374 6572 5f74 6d5f 636c 6f6e 6573  gister_tm_clones
00000020: 005f 5f64 6f5f 676c 6f62 616c 5f64 746f  .__do_global_dto
00000030: 7273 5f61 7578 0063 6f6d 706c 6574 6564  rs_aux.completed
00000040: 2e38 3036 3100 5f5f 646f 5f67 6c6f 6261  .8061.__do_globa
00000050: 6c5f 6474 6f72 735f 6175 785f 6669 6e69  l_dtors_aux_fini
00000060: 5f61 7272 6179 5f65 6e74 7279 0066 7261  _array_entry.fra
00000070: 6d65 5f64 756d 6d79 005f 5f66 7261 6d65  me_dummy.__frame
00000080: 5f64 756d 6d79 5f69 6e69 745f 6172 7261  _dummy_init_arra
00000090: 795f 656e 7472 7900 7379 6d62 6f6c 732e  y_entry.symbols.

这和先前由readelf -x .strtab ./examples/sections读取到的内容一致。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1353177.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

麒麟云增加计算节点

一、安装基座系统并配置好各项设置 追加的计算节点服务器,安装好系统,把主机名、网络网线(网线要和其他网线插的位置一样)、hosts这些配置好,在所有节点的/etc/hosts里面添加信息 在控制节点添加/kylincloud/multinod…

解决Redis序列化乱码问题

如果我们使用原生的JDK序列化&#xff0c;那么当我们将数据存储到Redis中就会出现乱码的情况 为了解决这个问题我们需要重写RedisTemplate从而解决序列化乱码问题 首先在Maven中引入相应的依赖 <dependency> <groupId>com.fasterxml.jackson.core</group…

交换机01_以太网

1、交换机工作原理 交换机是数据链路层的设备&#xff0c;数据链路层传输的是数据帧&#xff0c;所以封装的是MAC头部&#xff08;主要有源MAC地址和目的MAC地址&#xff09; 2、数据链路层的功能&#xff1a; 建立逻辑连接&#xff0c;进行物理地址寻址&#xff0c;差错校验…

CMake入门教程【核心篇】安装(install)

&#x1f608;「CSDN主页」&#xff1a;传送门 &#x1f608;「Bilibil首页」&#xff1a;传送门 &#x1f608;「本文的内容」&#xff1a;CMake入门教程 &#x1f608;「动动你的小手」&#xff1a;点赞&#x1f44d;收藏⭐️评论&#x1f4dd; 文章目录 1. 概述2. 使用方法2…

基于头脑风暴算法优化的Elman神经网络数据预测 - 附代码

基于头脑风暴算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于头脑风暴算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于头脑风暴优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要&…

软碟通UltraISO制作U盘安装Ubuntu

清华大学开源软件镜像站https://mirrors.tuna.tsinghua.edu.cn/ 从里面下载ubuntu-22.04-desktop-amd64.iso UltraISO是一款非常不错的U盘启动盘制作工具&#xff0c;一直被许多网友们所喜欢&#xff0c;使用简单、方便。 UltraISO官方下载地址&#xff1a;https://cn.ultrais…

Halcon顶帽运算与底帽运算的应用

Halcon顶帽运算与底帽运算的应用 文章目录 Halcon顶帽运算与底帽运算的应用1. 提取小的物件2. 校正非均匀光照 正如上文所说的&#xff0c;顶帽运算返回的像素部分是尺寸比结构元素小的&#xff0c;并且比较亮的局部小区域&#xff1b;底帽运算返回的像素部分是尺寸比结构元素小…

【EI会议征稿通知】第三届艺术设计与数字化技术国际学术会议( ADDT 2024)

第三届艺术设计与数字化技术国际学术会议( ADDT 2024&#xff09; 2024 3rd International Conference on Art Design and Digital Technology 所谓艺术设计&#xff0c;就是将艺术的审美感应用到与日常生活密切相关的设计中&#xff0c;使其不仅具有审美功能&#xff0c;而且…

Arduino定时器和定时器中断

目录 一、定时器中断库函数方式说明 1、定时器中断编号和引脚说明 2、库文件安装 3、MsTimer2库文件使用 4、TimerOne库文件使用 5、注意事项 二、定时器的寄存器配置说明 1、定时器寄存器列表说明 2、Timer0寄存器说明 3、预分频系数与比较匹配器 4、定时器模式 …

天津大数据培训机构 大数据时代已到来!

大数据时代已经来临&#xff0c;越来越多的人开始关注大数据&#xff0c;并且准备转行大数据。但是&#xff0c;对于一个外行人或者小白来说&#xff0c;大数据是什么&#xff1f;大数据需要学什么&#xff1f;什么样的大数据培训机构是靠谱的&#xff1f;这几个简单的问题就足…

xpath定位--切换frame/窗口

在web自动化中&#xff0c;有时候我们界面上明明定位到了该元素&#xff0c;但是就是点击不到&#xff0c;怎么回事&#xff1f; --可能是没有切换到对应的frame或者没有切换到对应窗口&#xff01;&#xff01;&#xff01; 切换frame用于在同一个窗口中切换到frame上下文&a…

SpringBoot之多环境开发配置

1 多环境开发配置 问题导入 在实际开发中&#xff0c;项目的开发环境、测试环境、生产环境的配置信息是否会一致&#xff1f;如何快速切换&#xff1f; 1.1 多环境启动配置 yaml文件多环境启动 不同环境使用—隔开 示例代码&#xff1a; spring:profiles:active: dev#生产…

Spring Bean的生命周期(钩子函数)

借鉴&#xff1a;https://www.cnblogs.com/liweimingbk/p/17843970.html https://blog.csdn.net/lxz352907839/article/details/128634404 一、Spring Bean生命周期 如果Spring配置文件中所定义的Bean类实现了ApplicationContextAware 接口&#xff0c;那么在加载Spring配置文…

C++多态性——(3)动态联编的实现——虚函数

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 成功的秘诀就在于多努力一次&#xff…

后端杂七杂八系列篇一

后端杂七杂八系列篇一 ① MySQL选择合适的数据类型① Char与Varchar② Text与Blob ② EqualsAndHashCode(callSuper true)的作用③ mybatis-plus 相关① 主键生成策略② 使用Model实现CRUD③ Wrapper的用法① Wrapper的继承关系② 项目中最常用的warpper [LambdaQueryWrapper]…

大数据Doris(四十九):Doris数据导出介绍

文章目录 Doris数据导出介绍 一、​​​​​​​使用示例

基于回溯搜索算法优化的Elman神经网络数据预测 - 附代码

基于回溯搜索算法优化的Elman神经网络数据预测 - 附代码 文章目录 基于回溯搜索算法优化的Elman神经网络数据预测 - 附代码1.Elman 神经网络结构2.Elman 神经用络学习过程3.电力负荷预测概述3.1 模型建立 4.基于回溯搜索优化的Elman网络5.测试结果6.参考文献7.Matlab代码 摘要&…

【人工智能】为什么说大模型会有「幻觉」问题,又如何去解决呢

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读文章&#xff01; 此篇是【话题达人】序列文章&#xff0c;这一次的话题是《如何解决大模型的幻觉问题》 目录 大模型模型幻觉模型预训练庞大文本数据集语义关系 模型微调特定任务少量标签数据 如何解决普遍方法 大模型 先来…

C# 反射 入门到详解

1.什么是反射 首先看一张流程图 反射最最要的关注的地方 就在metadata 元数据 元数据&#xff1a;描述DLL/EXE文件中有什么内容 点击生成之后&#xff0c;就会在文件中生成DLL/EXE文件 点击打开文件夹 在bin/Debug 文件下就会生成该文件 exe/dll文件的区别&#xff1a;…

Allegro看不到PCB元件的丝印和装配层

#创作灵感# PCB板到处Gerber文件加工回来&#xff0c;板子上没有元件边框丝印&#xff0c;但是有元件编号。因为只是样板&#xff0c;影响不大&#xff0c;就没有当回事。直到发出去贴片&#xff0c;发送了钢网层和装配层&#xff0c;反馈说不知道元器件的极性。这就纳闷了&…