我正在遵循的课程Baking Pi – 操作系统开发。他们在其中创建了另一个部分.init
。
那么我们是否可以创建任意数量的部分(不仅仅是.data, .bss, .text
),并且我们可以将代码和数据(初始化为否)放入其中的任何一个部分中吗?
如果是这样,那么节的目的是什么?
答案1
初步研究
乍一看,答案似乎是否定的,ELF 规范只允许以下部分。
C32/kernel/bin/.process.o
architecture: i386, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000333 00000000 00000000 00000040 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000050 00000000 00000000 00000380 2**5
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 000003d0 2**2
ALLOC
3 .note 00000014 00000000 00000000 000003d0 2**0
CONTENTS, READONLY
4 .stab 000020e8 00000000 00000000 000003e4 2**2
CONTENTS, RELOC, READONLY, DEBUGGING
5 .stabstr 00008f17 00000000 00000000 000024cc 2**0
CONTENTS, READONLY, DEBUGGING
6 .rodata 000001e4 00000000 00000000 0000b400 2**5
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .comment 00000023 00000000 00000000 0000b5e4 2**0
CONTENTS, READONLY
其他来源(例如维基百科)也仅显示最基本的部分名称,让您相信这些都是允许的。额外的搜索显示还有以下两个部分:
.fini
该部分包含有助于进程终止代码的可执行指令。即当一个程序正常退出时,系统会安排执行这一段代码。
。在里面
该部分包含有助于进程初始化代码的可执行指令。也就是说,当程序开始运行时,系统会安排在主程序入口点(C 程序中称为 main)之前执行本节中的代码。
.init
和部分.fini
有特殊用途。如果一个函数被放置在该.init
节中,系统将在主函数之前执行它。此外,放置在该部分中的函数.fini
将在主函数返回后由系统执行。编译器利用此功能在 C++ 中实现全局构造函数和析构函数。
来源:http://l4u-00.jinr.ru/usoft/WWW/www_debian.org/Documentation/elf/node3.html
但是,是的,你可以有任何部分
但感谢@A程序员为我指出实际情况ELF 规范 v1.2,第 1-16 页有一段内容如下:
带点 (.) 前缀的节名称是为系统保留的,尽管应用程序可以使用这些节(如果它们的现有含义令人满意)。应用程序可以使用不带前缀的名称,以避免与系统部分发生冲突。目标文件格式允许定义不在上面列表中的部分。一个目标文件可能有多个同名的部分。
因此,看起来完全取决于程序想要使用哪些部分。
答案2
允许的节和节名称取决于文件格式。对于 ELF 来说,格式的定义定义其中的一些及其目的,然后说:
带点 (.) 前缀的节名称是为系统保留的,尽管应用程序可以使用这些节(如果它们的现有含义令人满意)。应用程序可以使用不带前缀的名称,以避免与系统部分发生冲突。目标文件格式允许定义不在上面列表中的部分。一个目标文件可能有多个同名的部分。
所以是的,您可以使用任何您想要的名称创建节,系统处理它们的方式由它们的类型和属性决定。