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

目标文件的段结构及核心组件详解

目标文件(如 .o 或 .obj)是编译器生成的中间文件,其结构遵循 ELF(Linux)或 COFF(Windows)格式。以下是其核心段(Section)和关键机制的详细解析:


1. 目标文件的典型段结构

段名存储内容作用
.text可执行机器指令(函数代码)存放编译后的二进制指令(如成员函数、静态函数)
.data已初始化的全局/静态变量存储显式初始化的数据(如 int x = 5;
.bss未初始化的全局/静态变量(清零)仅记录变量大小,不占磁盘空间(运行时由系统初始化为0)
.rodata只读数据(字符串常量、虚表、RTTI)存储不可修改的数据(如 const char* str = "Hello";
.symtab符号表(函数、变量名及地址)记录符号的元信息,供链接器解析跨文件引用
.rel.text代码段的重定位信息标记 .text 中需要修正的指令(如 call 的目标地址)
.rel.data数据段的重定位信息标记 .data 中需要修正的指针(如跨文件的全局变量引用)
.debug调试信息(DWARF 格式)供调试器使用(如行号、变量类型),发布版可剥离
.eh_frame异常处理信息(栈展开)支持 C++ 异常机制(如 try/catch

2. 符号表(.symtab)详解

(1) 符号表的组成

符号表记录所有 函数、全局变量、静态变量 的信息,每条记录包含:

  • 符号名(如 _ZN7MyClass8funcEv,C++ 名称修饰后的名称)

  • 符号值(临时地址,通常是段内偏移)

  • 符号类型(函数 FUNC、数据 OBJECT、未定义 UND

  • 绑定属性(全局 GLOBAL、局部 LOCAL

  • 所属段(如 .text.data

(2) 符号表示例

bash

readelf -s example.o

输出:

Num:    Value  Size Type    Bind   Vis      Ndx Name1: 00000000    10 FUNC    GLOBAL DEFAULT    1 _ZN7MyClass8funcEv2: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _Z3foov
  • Value=00000000:临时地址(链接后修正)。

  • Ndx=1:符号属于 .text 段(通过节头表索引确定)。

  • UND:未定义符号(需链接时解析)。

(3) 符号表的作用

  • 链接阶段:解析跨文件引用(如 main.o 调用 lib.o 的函数)。

  • 调试阶段:映射机器码到源码符号(如 addr2line 工具)。


3. 重定位表(.rel.text / .rel.data)详解

(1) 重定位的用途

  • 修正代码段(.text)和数据段(.data)中的 临时地址,使其指向正确的最终地址。

  • 解决跨文件引用问题(如调用其他 .o 文件的函数)。

(2) 重定位条目结构

每个条目包含:

  • 偏移量(Offset):需修正的指令/数据在段内的位置。

  • 类型(Type):如何修正(如绝对地址、相对偏移)。

  • 符号(Symbol):目标符号名。

(3) 重定位表示例

bash

readelf -r example.o

输出:

Relocation section '.rel.text':
OFFSET   TYPE           SYMBOL
00000005 R_X86_64_PC32  _Z3foov
  • OFFSET=0x05call 指令的操作数位于 .text 段偏移 0x05 处。

  • TYPE=R_X86_64_PC32:需修正为 相对地址(目标地址 - 下条指令地址)。

  • SYMBOL=_Z3foov:修正目标是函数 foo()

(4) 重定位过程

  1. 链接器 合并所有 .text 段,分配最终地址(如 foo() 的地址为 0x401200)。

  2. 计算修正值:

    • 对于 R_X86_64_PC32

      修正值 = 目标地址(0x401200) - 下条指令地址(0x401005 + 5 = 0x40100A) = 0x1F6
  3. 修改指令:

    asm

    ; 修正前(目标文件)
    call 0x00000000  
    ; 修正后(可执行文件)
    call 0x1F6        ; 实际编码为 E8 F6 01 00 00

4. 代码段(.text)与数据段(.data/.bss)

(1) 代码段(.text)

  • 内容:所有函数的机器码(如 main()MyClass::func())。

  • 特点

    • 只读可执行(防代码注入)。

    • 函数调用通过 call 指令实现(地址由重定位修正)。

(2) 数据段(.data)

  • 内容:已初始化的全局/静态变量(如 int x = 42;)。

  • 特点

    • 可读写,占用磁盘空间(存储初始值)。

    • 加载到内存的 数据段

(3) BSS 段(.bss)

  • 内容:未初始化的全局/静态变量(如 int y;)。

  • 特点

    • 不占用磁盘空间(仅记录大小)。

    • 运行时由系统初始化为0,加载到内存的 BSS 段


5. 动态链接的特殊处理

(1) 全局偏移表(GOT)

  • 存储动态库中符号的绝对地址(如 printf)。

  • 首次访问时由动态链接器填充。

(2) 过程链接表(PLT)

  • 实现 延迟绑定,首次调用函数时触发动态链接器解析地址。

    asm

    复制

    下载

    call printf@plt  ; 首次调用跳转到 PLT

6. 关键总结

组件作用示例工具命令
.text存储可执行指令(函数代码)objdump -d example.o
.data存储已初始化的全局/静态变量readelf -x .data example.o
.bss存储未初始化的全局/静态变量(运行时清零)size example.o
.symtab记录符号名、类型、地址(供链接器使用)readelf -s example.o
.rel.text标记代码段中需要修正的指令(如 callreadelf -r example.o
.rel.data标记数据段中需要修正的指针(如跨文件变量引用)objdump -r -j .data example.o
http://www.xdnf.cn/news/250453.html

相关文章:

  • 多线程系列二:Thread类
  • Window通过虚拟机17安装Ubuntu20.04并安装相关的插件(胎教级教程)
  • 回归树:从原理到Python实战
  • 【C语言】文本操作函数fseek、ftell、rewind
  • 详细介绍Python-pandas-DataFrame全部 功能 函数
  • 存储器层次结构:理解计算机记忆的金字塔
  • 23页PDF | 数据治理实施方案 :规划、执行、评价、改进四步走的管控模式
  • Seata服务端开启事务核心源码解析
  • 位运算题目:寻找重复数
  • 最长公共前缀(14)
  • 基于Koa实现的服务端渲染 ✅
  • 8.进程概念(四)
  • 为什么大模型偏爱Markdown
  • 操作系统(1)多线程
  • 【Machine Learning Q and AI 读书笔记】- 03 小样本学习
  • 数字智慧方案6178丨智慧医院医疗信息化建设之以评促建(61页PPT)(文末有下载方式)
  • 微型计算机串行通信实验三全解析:从原理到实践的探索之旅
  • 《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》章节思维导图
  • 【验证技能】文档要求和好文档注意点
  • Python实现简易博客系统
  • Linux——线程(3)线程同步
  • ✨从噪声到奇迹:扩散模型如何“想象“出世界
  • 本地服务器备份网站数据,本地服务器备份网站的操作步骤
  • 产品手册小程序开发制作方案
  • C++/SDL 进阶游戏开发 —— 双人塔防(代号:村庄保卫战 17)
  • python自动化测试
  • 【业务领域】计算机网络基础知识
  • 基于预计技术研究加速因子:原理、应用场景及模型验证
  • socket-IO复用技术
  • 米酒的功能和优缺点