我是靠谱客的博主 腼腆小兔子,最近开发中收集的这篇文章主要介绍C程序中各个段的含义,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

首先应该知道几个查看段信息的指令:
readelf -S file 查看各个段的名称,地址,大小等信息
objdump -s file 查看各个段的二进制和字符格式内容
hexdump -C file 查看整个二进制文件的二进制和字符格式内容
(1).text 程序的正文段,一般为本文件中的函数指令
(2).data 程序的数据段,一般静态变量和初始化的全局变量定义在此
(3).bss 也是程序的数据段,一般包括未初始化的全局变量
(4).interp 此程序在加载时所需要使用的动态连接器的位置

Contents of section .interp:
400200 2f6c6962 36342f6c 642d6c69 6e75782d
/lib64/ld-linux-
400210 7838362d 36342e73 6f2e3200
x86-64.so.2. 

说明当前程序需要加载时,使用到/lib64/ld-linux-x86-64.so.2这个动态链接器
(5).rodata 只读数据,比如说C++中的const变量,字符串常量,比如说程序中有这么一段:

printf("in main.c a=%dn", a);
printf("in main.c &a=%pn", &a);

对应.rodata的内容:

Contents of section .rodata:
4007a0 01000200 696e206d 61696e2e 6320613d
....in main.c a=
4007b0 25640a00 696e206d 61696e2e 63202661
%d..in main.c &a
4007c0 3d25700a 00
=%p..

(6).symtab 符号表信息(readelf -s file),可以看出各个符号的地址
(7).strtab 字符串表信息,一般和符号表中符号对应的字符串对应
(8).rela.text 一般中间对象文件会有这个段,因为text段引用了其他外部函数
(9).got 用于动态链接,保存代码段中引用动态链接库中数据的地址,一般在运行时确定
(10).got.plt 类似于.got,保存代码段中引用动态链接库中函数的地址,一般在运行时确定
(11).plt 用于动态链接时的延迟绑定,运行时,当遇到动态链接库中的函数或数据时,会跳到这个段内,用于解析地址
(12).rela.dyn 用于查看.got段和数据段(一般是.bss)需要修正的符号
(13).rela.plt 用于查看需要修正.got.plt中的数据
针对(12)(13)举个例子:
有两个文件a.c b.c,a.c编译成动态链接库,b.c为主程序:

//a.c
int a = 2;
void foo(void)
{
a++;
return;
}
//b.c
#include <stdio.h>
extern int a;
extern void foo(void);
int main(void)
{
a = a+1;
foo();
return 0;
}

按上面的要求进行编译,分别查看a.so和b的。rela.dyn和rela.plt内容

$ readelf -r a.so
Relocation section '.rela.dyn' at offset 0x3e0 contains 9 entries:
Offset
Info
Type
Sym. Value
Sym. Name + Addend
0000002008b0
000500000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
0000002008b8
000800000006 R_X86_64_GLOB_DAT 0000000000200900 a + 0
$ readelf -r b
Relocation section '.rela.dyn' at offset 0x4b0 contains 2 entries:
Offset
Info
Type
Sym. Value
Sym. Name + Addend
000000600a00
000500000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
000000600a40
000800000005 R_X86_64_COPY
0000000000600a40 a + 0
Relocation section '.rela.plt' at offset 0x4e0 contains 2 entries:
Offset
Info
Type
Sym. Value
Sym. Name + Addend
000000600a20
000400000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main + 0
000000600a28
000600000007 R_X86_64_JUMP_SLO 0000000000000000 foo + 0

从上面的信息可以看出,对于a.so变量a位于.got段,对于b来说,变量a也需要重定向,位于.bss段,在.rela.dyn中说明此符号需要重定位,并且b引用了foo这个动态链接库函数,在.rela.plt中给出信息需要在.got.plt中重定位。
(14).dynsym段,类似于.symtab,也是一个符号表,但是这个符号表只记录与动态链接有关的符号
(15).dynstr段,类似于.strtab,记录动态链接符号的字符串表
(16).hash段,由于动态链接的时候需要快速查找,因此使用了一个哈希表,用来记录符号的地址。
(17).dynamic 是和记录动态链接属性的一些信息,比如说:动态链接重定位表的位置,.got的位置,.got.plt的位置等。

最后

以上就是腼腆小兔子为你收集整理的C程序中各个段的含义的全部内容,希望文章能够帮你解决C程序中各个段的含义所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(73)

评论列表共有 0 条评论

立即
投稿
返回
顶部