ELF 文件格式常见段名称及自定义段

9 篇文章 0 订阅
4 篇文章 0 订阅
除了最常见的为 .text, .data, .bss 这 3 个段之外,还有其它的一些常见段,如下所示:

.strtab : String Table 字符串表,用于存储 ELF 文件中用到的各种字符串。

.symtab : Symbol Table 符号表,从这里可以所以文件中的各个符号。

.shstrtab : 是各个段的名称表,实际上是由各个段的名字组成的一个字符串数组。

.hash : 符号哈希表。

.line : 调试时的行号表,即源代码行号与编译后指令的对应表。

.dynamic : 动态链接信息。

.debug : 调试信息。

.comment : 存放编译器版本信息,比如 "GCC:(GNU)4.2.0"。

.plt 和 .got : 动态链接的跳转表和全局入口表。

.init 和 .fini : 程序初始化和终结代码段。

.rodata1 : Read Only Data,只读数据段,存放字符串常量,全局 const 变量,该段和 .rodata 一样。


由上可见,这些段的名字前都有一个 '.' 点符号前缀,其义表示这些段的名字为系统所保留。应用程序可以使用非系统保留的名字作为自己的自定义段名,但是自定义的段名就不能使用 '.' 符号作为前缀,否则容易和系统保留的段名冲突。

一个 ELF 文件中允许存在两个及以上的同名段,比如可能会看到多个 .text 段。

可以用 objcopy 命令将一个普通二进制文件,如图片,多媒体之类的东西作为目标文件中的一个段。制作方法如下:
[beyes@beyes ELF]$ objcopy -I binary -O elf32-i386 -B i386 mypic.jpg temp.o
[beyes@beyes ELF]$ objdump -t temp.o
temp.o:     file format elf32-i386
SYMBOL TABLE:
00000000 l    d  .data  00000000 .data
00000000 g       .data  00000000 _binary_mypic_jpg_start
00011855 g       .data  00000000 _binary_mypic_jpg_end
00011855 g       *ABS*  00000000 _binary_mypic_jpg_size

objcopy 命令用于将目标文件的的部分或全部内容拷贝到另一个目标文件中,并可以实现格式的变换。
上面的 objcopy 命令中:
-I 选项表示指定输入的目标文件格式。

-O 选项表示指定输出的目标文件格式。

-B 选项指定要欲转入目标文件的输入文件的适用平台。这里指定 i386 表示该图片格式适用于 i386 平台。但由于 objcopy 所使用的 BFD 库中已经识别了 i386 平台,所以这里不用 -B 选项也是可以的。

在使用 objcopy 将图片文件转换进目标文件 temp.o 中后,默认会用  _binary_objfile_start 和  _binary_objfile_end 来标识被转换文件在内存中的起始地址,结束地址;以及使用 _binary_objfile_size 来表示大小。

自定义段

通常,在 gcc 编译出来的目标文件中,代码一般是放到 .text 段,全局变量和静态变量被放到 .data 和 .bss 段。这只是默认行为,我们有时可能希望变量或某些代码放在一个自定义的段中去以实现某些特定功能,比如为了满足某些硬件的内存和 I/O 地址布局,或者像 Linux 内核中用来完成一些初始化和用户控件复制时出现的错误异常等。GCC 提供了一个扩展机制,使得我们可以将变量放在我们自定义的段中。如下代码示例:

#include <stdio.h>
 
__attribute__((section("myvarsection"))) int global_var = 18;
 
__attribute__((section("myfuncsection"))) void hello(void);
 
void hello(void)
{
        printf ("hello world\n");
 
        printf ("my global_var:%d\n", global_var);
 
}
 
int main()
{
        hello();
 
        return 0;
}

查看相应的目标文件:
[beyes@beyes ELF]$ objdump -h sefsec.o

sefsec.o:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000012  00000000  00000000  00000034  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000000  00000000  00000000  00000048  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00000000  00000000  00000048  2**2
                  ALLOC
   3 myvarsection  00000004  00000000  00000000  00000048  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  4 .rodata       0000001e  00000000  00000000  0000004c  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
5 myfuncsection 0000002b  00000000  00000000  0000006a  2**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  6 .comment      0000002e  00000000  00000000  00000095  2**0
                  CONTENTS, READONLY
  7 .note.GNU-stack 00000000  00000000  00000000  000000c3  2**0
                  CONTENTS, READONLY
  8 .eh_frame     00000058  00000000  00000000  000000c4  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

程序中使用 GCC 的扩展机制 __attribute__((section()) 来自定义自己的段。


  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值