通过readelf工具解析ELF可重定位目标文件

通过readelf工具解析ELF可重定位目标文件

  • 创建可重定位目标文件(main.o)
  • ELF可重定位目标文件结构
    • ELF头
      • 说明
    • 节头部表
      • 各节的分布
      • 符号表(.symtab)
        • 说明

创建可重定位目标文件(main.o)

//main.c
int sum(int *a,int n);
int array[2]={1,2};

int mian()
{
	int val=sum(array,2);
	return val;
}
//linux中利用gcc工具将将main.c翻译成main.o
linux>gcc -c main.c

ELF可重定位目标文件结构

  • ELF头
  • 各个节(.text .rodata .data .bss .symtab等 )
  • 节头部表

ELF头

通过readelf工具解析ELF可重定位目标文件_第1张图片

说明

  • magic:头四个字节(7f 45 4c 46)说明该文件是ELF格式的。
  • 可重定位文件不会进行执行,没有程序头表,所以:程序头起点,程序头大小,Number of program headers(程序头表中表项个数)皆为0。
  • Start of section headers:节头部表的偏移量。(本例中672的16进制表示为2a0,所以节头部表从0x2a0的位置开始。)
  • 字符串表索引节头:节头部表中字符串表(strtab)的索引值。

节头部表

通过readelf工具解析ELF可重定位目标文件_第2张图片
(表头弄成两行我也很迷惑,不过还是对齐了的)

各节的分布

现在, 通过ELF头中节头部表的信息,以及节头部表中各表项里偏移和大小的值,我们可以画出文件中各节的分布:
通过readelf工具解析ELF可重定位目标文件_第3张图片
右侧数字表示节的大小,左侧数字表示偏移。(都是用16进制表示的)
(本例中.note.GNU-stack的size是0,这里为了不落下这个节所以画了出来,其实0x9e到0xa0之间是空的。)

符号表(.symtab)

符号表存放在程序中定义和引用的函数和全局变量的信息。 (书上是这么写的)
通过readelf工具解析ELF可重定位目标文件_第4张图片
但我以为符号表从字面上理解是存放符号的信息的,而静态变量也是符号。所以为了弄清符号表到底包不包括静态变量,我把main.c中的main函数稍稍改动了一下,加了个静态变量:

int main()
{
	static int a;
	int val=sum(array,2);
	return val;
}

然后得到新的main.o并且查看符号表

gcc -c main.c
readelf -s main.o

得到结果:通过readelf工具解析ELF可重定位目标文件_第5张图片
由此可知:Bind为LOCAL的a.1836即为我们新加入的静态变量a,且在bss节中。

说明

  • value:距定义目标的节的起始位置的偏移(对可重定位模块来说)
  • Ndx:index,到节头部表的索引。(特殊值:UNDEF表示未定义的符号,ABS表示不该被重定义的符号,COMMON表示未被分配位置未初始化的符号)
  • 所以,array的Ndx为3表示在data节中;main的Ndx为1表示在text节中;sum的Ndx为UND因为是在另一个文件中定义的,而在本文件引用。

你可能感兴趣的:(计算机系统基础)