当前位置: 首页 > news >正文

elf 格式 relocation 概念


author: hjjdebug
date: 2026年 01月 08日 星期四 15:12:21 CST
descrip: elf 格式 relocation 概念


文章目录

  • 1. 查看test 的重定位信息
  • 2. .rela.dyn 区与 .rela.plt 区的区别和联系
  • 3 概括动态绑定的过程
  • 4. 介绍 .rela 结构
  • 5. r_info 的type 有多少种?
  • 6. 补充: 节区表

关于符号的概念,请参考链接:
计算机中符号是什么意思

elf 文件仍然采用链接中hello-world 产生的文件 test

1. 查看test 的重定位信息

$ readelf -r test

重定位节 ‘.rela.dyn’ at offset 0x380 contains 2 entries:
偏移量 信息 类型 符号值 符号名称 + 加数
000000600ff0 000200000006 R_X86_64_GLOB_DAT 0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0
000000600ff8 000300000006 R_X86_64_GLOB_DAT 0000000000000000gmon_start+ 0

重定位节 ‘.rela.plt’ at offset 0x3b0 contains 1 entry:
偏移量 信息 类型 符号值 符号名称 + 加数
000000601018 000100000007 R_X86_64_JUMP_SLO 0000000000000000 puts@GLIBC_2.2.5 + 0

2. .rela.dyn 区与 .rela.plt 区的区别和联系

.rela.dyn 和 .rela.plt 是ELF文件格式中用于动态链接的重定位节,
相同点:
从结构上看, .rela.dyn 和 .rela.plt 的重定位条目结构相同(均基于ELF64_Rela或ELF32_Rela),
RELA结构(包含Addend字段),但用途和处理对象有明确区别。

不同点:前者关联动态符号表(.dynsym节)中的数据符号,后者关联动态符号表(.dynsym节)中的函数符号。

.rela.dyn 处理数据符号(如全局变量、静态变量等)的重定位,其重定位目标通常位于.got节中;
.rela.plt 处理函数符号的重定位,目标位于.got.plt节中。
这种分工源于动态链接机制不同:数据引用和函数调用需要不同的绑定策略。

.rela.dyn 通常在程序加载时完成重定位,用于修正数据符号的地址;
.rela.plt 支持延迟绑定(Lazy Binding),即函数重定位在首次调用时才完成,通过.plt节(过程链接表)和.got.plt节协作实现,以提升程序启动效率。
具体延迟绑定细节可以参考以下链接
elf 文件动态加载过程

3 概括动态绑定的过程

这里概括一下, 外部printf函数由于其只调用了字符串太简单被简化为puts 函数调用. 这部分会形成一小段调用代码位于plt.sec 节中
为 jmp (*addr), 从指定的地址中取出目标地址, 到那个地址中去执行
这部分 plt.sec 是代码区, 是不能改的. 可改的是addr 处存储的地址.
那个地址是函数实际的入口地址, 但第一次调用时还不是,第一次调用存储的是地址解析函数调用地址.
其中 addr 所处的那个节叫 .got.plt, 就是说它将来存储实际函数入口地址,第一次存储地址解析函数地址. 是可更改的.

地址解析函数地址所处的节叫plt 节, 也是代码节,不可更改. 它的代码是这样的.
push 0
jmpq resolve
第二个函数调用则是
push 1
jmpq resolve
resolve地址解析函数很厉害, 它根据槽位号能找到外部绑定的函数名,并能确定外部函数地址,并将结果存储到.got.plt对应位置处.
解析一次,以后就不会跳到这里了,而是直接跳转到真实地址去了.

4. 介绍 .rela 结构

首先, 重定位是对符号的重定位, 所以被重定位的符号名称是一项内容.
被重定位的符号值, 肯定都是0. 不知道为什么要定义它
类型. 是外部变量还是外部函数等.
偏移量. 是说明在内存的什么地址来修改, 把原来的0改为解析到的地址.
信息. 就是其它的属性信息.
有了这些基础,我们再看elf64.h 中的结构定义
结构很简单,三个变量. 都是8bytes 数据
typedef struct
{
Elf64_Addr r_offset; /* Address/
Elf64_Xword r_info; /
Relocation type and symbol index/
Elf64_Sxword r_addend; /
Addend */
} Elf64_Rela;

typedef uint64_t Elf64_Addr;
typedef uint64_t Elf64_Xword;
typedef int64_t Elf64_Sxword;

r_offset指示需要修改的地址
r_info的高32位指向符号表索引,低32位指定重定位类型
符号值 + r_addend得到最终地址
r_addend 一般是0, 不是0的情况以后碰到再给实例吧.

5. r_info 的type 有多少种?

switch(ELF64_R_TYPE(r_info)) { case 1: return "R_X86_64_32"; case 2: return "R_X86_64_PC32"; case 5: return "R_X86_64_COPY"; case 6: return "R_X86_64_GLOB_DAT"; case 7: return "R_X86_64_JUMP_SLOT"; default: return "OTHERS";

6. 补充: 节区表

想看看前边提到的重定位地址 0x600ff0, 0x600ff8, 0x601018属于哪个节区,
可以打出节表, 如下. 即知:
0x600ff0,0x600ff8 属于 .got 区
0x601018 属于 属于 .got.plt 区

$ readelf-S test There are34section headers,starting at offset0x2120:节头:[]名称 类型 地址 偏移量 大小 全体大小 旗标 链接 信息 对齐[0]NULL00000000000000000000000000000000000000000000000000000000000[1].interp PROGBITS000000000040023800000238000000000000001c0000000000000000A001[2].note.ABI-tag NOTE00000000004002540000025400000000000000200000000000000000A004[3].note.gnu.build-i NOTE00000000004002740000027400000000000000240000000000000000A004[4].gnu.hash GNU_HASH000000000040029800000298000000000000001c0000000000000000A508[5].dynsym DYNSYM00000000004002b8000002b800000000000000600000000000000018A618[6].dynstr STRTAB000000000040031800000318000000000000003d0000000000000000A001[7].gnu.version VERSYM00000000004003560000035600000000000000080000000000000002A502[8].gnu.version_r VERNEED00000000004003600000036000000000000000200000000000000000A618[9].rela.dyn RELA00000000004003800000038000000000000000300000000000000018A508[10].rela.plt RELA00000000004003b0000003b000000000000000180000000000000018AI5228[11].init PROGBITS00000000004003c8000003c800000000000000170000000000000000AX004[12].plt PROGBITS00000000004003e0000003e000000000000000200000000000000010AX0016[13].text PROGBITS00000000004004000000040000000000000001720000000000000000AX0016[14].fini PROGBITS00000000004005740000057400000000000000090000000000000000AX004[15].rodata PROGBITS000000000040058000000580000000000000000a0000000000000000A004[16].eh_frame_hdr PROGBITS000000000040058c0000058c000000000000003c0000000000000000A004[17].eh_frame PROGBITS00000000004005c8000005c800000000000001000000000000000000A008[18].init_array INIT_ARRAY0000000000600e1000000e1000000000000000080000000000000008WA008[19].fini_array FINI_ARRAY0000000000600e1800000e1800000000000000080000000000000008WA008[20].dynamic DYNAMIC0000000000600e2000000e2000000000000001d00000000000000010WA608[21].got PROGBITS0000000000600ff000000ff000000000000000100000000000000008WA008[22].got.plt PROGBITS00000000006010000000100000000000000000200000000000000008WA008[23].data PROGBITS00000000006010200000102000000000000000100000000000000000WA008[24].bss NOBITS00000000006010300000103000000000000000080000000000000000WA001[25].comment PROGBITS00000000000000000000103000000000000000290000000000000001MS001[26].debug_aranges PROGBITS00000000000000000000105900000000000000300000000000000000001[27].debug_info PROGBITS000000000000000000001089000000000000031d0000000000000000001[28].debug_abbrev PROGBITS0000000000000000000013a600000000000000e00000000000000000001[29].debug_line PROGBITS00000000000000000000148600000000000000d10000000000000000001[30].debug_str PROGBITS00000000000000000000155700000000000002840000000000000001MS001[31].symtab SYMTAB0000000000000000000017e00000000000000630000000000000001832488[32].strtab STRTAB000000000000000000001e1000000000000001c80000000000000000001[33].shstrtab STRTAB000000000000000000001fd800000000000001430000000000000000001Key to Flags:W(write),A(alloc),X(execute),M(merge),S(strings),I(info),L(link order),O(extra OS processing required),G(group),T(TLS),C(compressed),x(unknown),o(OS specific),E(exclude),l(large),p(processor specific)

参考代码: https://gitee.com/hejinjing/elf-parser.git

http://www.jsqmd.com/news/217234/

相关文章:

  • 计算机深度学习毕设实战-基于python-CNN卷积神经网络对盆栽识别
  • 5V供电 2A单节开关型锂电池充电芯片 XR4420
  • 给wordpress网站的图片加alt标签
  • 计算机三级-嵌入式组-考点汇总-嵌入式系统软件
  • 【实战案例】火语言RPA获取下拉联想推荐词
  • 2026 年用什么 CMS 做网站更合适?一些实际对比思考
  • 【行业深度】2025中国酒店业法务数字化转型洞察报告:大型集团如何破解“规模负重”难题?
  • 华为OD技术面真题 - 计算机网络 - 2
  • 深度学习毕设选题推荐:基于python-CNN卷积神经网络对盆栽识别
  • 计算机中的符号是什么意思?
  • 通信协议仿真:通信协议基础_(7).协议仿真的工具与软件
  • 导师严选8个AI论文写作软件,专科生搞定毕业论文+格式规范!
  • 导师推荐9个一键生成论文工具,自考本科生轻松搞定毕业论文!
  • SnapShot硬盘备份软件:一款小巧强大的德国军工级数据备份方案
  • mysql的分区表
  • 【干货收藏】RAG调优完整指南:从基础到GraphRAG,提升大模型回答准确率
  • 保姆级教程:使用Dify搭建知识库+Ollama部署本地模型,零基础也能轻松上手!
  • 最新APP导航下载页系统源码 带后台
  • 你画我猜计时答题对战房间酒馆互动神器H5开源
  • AI产品经理进阶指南+大模型全栈学习路线:104G资源包助你从零到实战
  • 深度学习毕设选题推荐:基于python_CNN卷积神经网络对甜点识别
  • 公众号图片圆角与阴影样式配置实战(以135编辑器为例)
  • 千寻运动助手V3.1小程序源码 全开源版
  • 基于C++Qt实现邮政客户投诉工单处理系统[2026-01-07]
  • 《计算机网络》深入学:组帧
  • MySQL数据误删或者误更新如何恢复(详细步骤,一看就会)
  • 空间计算开发者技能指南 2026
  • mysql数据被误删的恢复方案
  • 《庄子》导读
  • AcuKG:大模型+知识图谱双轮驱动的中医针灸全面知识图谱自动构建及中医科研交互式知识发现