当需要在程序启动时运行一段代码(Linux),如何正确使用可执行文件(ELF32-i386)的.init_section
?我有以下代码(GNU Assembler),它有 ctor
初始化函数,这个函数的地址放在 .init_array
部分:
.intel_syntax noprefix
.data
s1: .asciz "Init code\n"
s2: .asciz "Main code\n"
.global _start
.global ctor
.text
ctor:
mov eax, 4 # sys_write()
mov ebx, 1 # stdout
mov ecx, offset s1
mov edx, 10
int 0x80
ret
.section .init_array
.long ctor
.text
_start:
mov eax, 4
mov ebx, 1
mov ecx, offset s2
mov edx, 10
int 0x80
mov eax, 1
mov ebx, 0
int 0x80
此代码与:
as -o init.o init.asm
ld -o init init.o
运行生成的可执行文件时,只会打印“Main code”字符串。如何正确使用 .init_array 部分?
编辑 1:我想使用 .init_array,因为有多个源文件都有自己的初始化代码。可以在启动时“手动”调用所有这些代码,并在每次将源文件添加到项目或从项目中删除时修改它,但是 .init_array
似乎是专门为这种情况设计的:
Before transferring control to an application, the runtime linker processes any initialization sections found in the application and any loaded dependencies. The initialization sections .preinit_array, .init_array, and .init are created by the link-editor when a dynamic object is built.
The runtime linker executes functions whose addresses are contained in the .preinit_array and .init_array sections. These functions are executed in the same order in which their addresses appear in the array.
如果在没有 gcc 的情况下创建可执行文件,链接器似乎不会执行启动代码。我尝试编写自己的标准 init 例程,它读取 .init_array 部分中的函数指针并调用它们。它适用于一个文件,其中可以标记该部分的结尾,例如,用零标记。但是对于多个文件,这个零可以重新定位在部分的中间。如何正确确定由多个源文件组装而成的节的大小?
最佳答案
如果您按照自己的方式创建一个静态链接 裸可执行文件,在_start
入口点使用您自己的代码,您的代码就从该点开始运行。如果你想让某事发生,你的代码必须让它发生。没有魔法。
使用节对于将来自多个源文件的启动代码组合在一起很有用,因此所有启动代码都是冷的并且可能被调出页面,或者至少不需要 TLB 条目。
因此,您通过将函数放在那里并从 _start
之后某个时间运行的代码调用它们来“正确使用”部分。
在您的代码示例中,.init_array
看起来像是一个函数指针列表。我假设标准 CRT 启动文件读取 ELF 文件并找到该部分的长度,然后通过它间接调用这些函数。由于您正在编写自定义代码,因此调用一个执行所有操作的 init 函数会更快。
动态链接:
“运行时链接器”是动态二进制文件的 ELF 解释器。它在 _start
之前在您的进程中运行代码,所以是的,显然它确实处理了 ELF 部分并让奇迹发生了。
因此,为了响应您的编辑,您的选择是:自己实现 .init_array
的处理,或者创建动态可执行文件。我很确定其他问题已经涵盖了这个过程,而且我没有时间为仍然没有链接 libc 的动态可执行文件研究正确的命令行。 (尽管您可能只想使用 gcc -nostartfiles
或其他东西。)
如果您遇到困难,请发表评论。当我有更多时间时,我可能会稍后更新它,或者随时在工作命令中进行编辑。
关于linux - 使用 ELF 文件的 ".init_array"部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35827230/