0%

objdump 解析目标文件各个段

目标文件 .otextbssdatarodata 区别和联系

目标文件只是ELF文件的可重定位文件(Relocatable file),常用分析ELF文件工具如下

  1. objdump
  2. readelf
  3. nm

.text

代码段,也有可能包含一些只读的常数变量,例如字符串常量等。只读。

.bss

没有初始化的和初始化为0的全局变量和静态变量,并不给该段的数据分配空间,只是记录数据所需空间的大小,运行时在栈上分配。

.data

已初始化非0全局变量和静态变量,需要分配空间用于存储数据。

.rodata

ro 表示为只读数据段,存放C中的字符串和常量,优化后会只存储一份。常量并不一定在此段,有可能存放在代码段。

example

static int x1 = 0;
static int x2 = 1234;

int main()
{
    return 0;
}

使用 objdump -x -s -d a.out 查找如下

00000000006bb330 l     O .bss   0000000000000004 x1
00000000006b90f0 l     O .data  0000000000000004 x2
.
Contents of section .data:
 6b90e0 00000000 00000000 00000000 00000000  ................
 6b90f0 34120000 00000000 00080000 00000000  4...............

x1 放入 .bss 段;x2 放入 .data 段。

nm vs objdump

nmobjdump 标志不统一,需要注意区分

nm

nm symbols 类型及程序组成

查看详细信息 man nm

objdump

查看详细信息 man objdump

  • l local
  • g global
  • u unique global
  • ! both global and local
  • w weak
  • C The symbol denotes a constructor
  • W warning
  • I The symbol is an indirect reference to another symbol
  • i a function to be evaluated during reloc processing
  • d a debugging symbol
  • D a dynamic symbol
  • F function
  • f file
  • O object

example

$ tree
.
├── a.out
├── one.c   // extern unsigned long start_time;
├── two.c   // unsigned long start_time = 0;
└── main.c  // start_time = _get_time();

$ nm one.o | grep start_time
00000004 C start_time
$ nm two.o | grep start_time
00000000 B start_time
$ nm main.o | grep start_time
00000004 C start_time
$ nm a.out | grep start_time
97d6c6c4 B start_time

$ objdump -x -s a.out | grep start_time
97d6c6c4 g     O .bss    00000004 start_time
 0640 0e000067 5f737461 72745f74 696d6500  ...start_time.
 1ae0 675f7374 6172745f 74696d65 00df0e00  start_time....
$ objdump -x -s one.o | grep start_time
00000004       O *COM*    00000004 start_time
00000ef5 ADDR32   start_time
0000003c ADDR32   start_time
$ objdump -x -s main.o | grep start_time
00000004       O *COM*    00000004 start_time
00000262 ADDR32   start_time
000000e4 ADDR32   start_time
$ objdump -x -s two.o | grep start_time
 32 .bss.start_time 00000004  00000000  00000000  000015c8  2**2
00000000 l    d  .bss.start_time    00000000 .bss.start_time
00000000 g     O .bss.start_time    00000004 start_time
000006d7 ADDR32   .bss.start_time

注意变量 start_time 在各个文件中的标志

Ref

  1. 程序的结构体系(十)
  2. 使用readelf和objdump解析目标文件