在ELF文件中,_start的地址是如何确定的?
我一直在阅读ELF规范,但无法弄清楚程序入口点和_start地址来自哪里。
看起来它们应该位于一个非常一致的位置,但我制作了一些简单的程序,并且 _start 总是位于不同的位置。
谁能澄清一下吗?
I've been reading the ELF specification and cannot figure out where the program entry point and _start address come from.
It seems like they should have to be in a pretty consistent place, but I made a few trivial programs, and _start is always in a different place.
Can anyone clarify?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
_start
符号可以在任何目标文件中定义。通常它是自动生成的(对应于C中的main
)。您可以自己生成它,例如在汇编源文件中:当链接器处理完所有目标文件后,它会查找
_start
符号并将其值放入e_entry
字段中elf 标头。加载器从该字段获取地址,并在完成加载内存中的所有部分并准备好执行文件后调用它。The
_start
symbol may be defined in any object file. Normally it is generated automatically (it corresponds tomain
in C). You can generate it yourself, for instance in an assembler source file:When the linker has processed all object files it looks for the
_start
symbol and puts its value in thee_entry
field of the elf header. The loader takes the address from this field and makes a call to it after it has finished loading all sections in memory and is ready to execute the file.看一下
ld
使用的链接器脚本:格式记录在:https://sourceware.org/binutils/docs-2.25/ld/Scripts.html
它基本上决定了如何生成可执行文件的所有内容。
在 Binutils 2.24 Ubuntu 14.04 64 位上,它包含以下行:
将入口点设置为
_start
符号(转到 ctn 提到的 ELF 标头)然后:
将入口点设置为第一个标头为
0x400000
+SIZEOF_HEADERS
。我已将该地址修改为
0x800000
,并使用ld -T
传递了我的自定义脚本,并且它有效:readelf -s
表示_start
位于该地址。另一种更改它的方法是使用 -Ttext-segment=0x800000 选项。
使用
0x400000
= 4Mb =getconf PAGE_SIZE
的原因是按照以下要求从第二页的开头开始:为什么 ELF 执行入口点虚拟地址的形式为 0x80xxxxx 和不为零 0x0?一个问题描述了如何从命令行设置
_start
:为什么 ELF 入口点 0x8048000 不能使用“ld -e”选项更改?SIZEOF_HEADERS
是大小ELF + 程序头,位于 ELF 文件的开头。该数据由 Linux 加载到虚拟内存空间的最开始位置(为什么要这样做?)在具有 2 个程序头的最小 Linux x86-64 hello world 中,它的值是0xb0
,因此_start
符号位于 0x4000b0。Take a look at the linker script
ld
is using:The format is documented at: https://sourceware.org/binutils/docs-2.25/ld/Scripts.html
It determines basically everything about how the executable will be generated.
On Binutils 2.24 Ubuntu 14.04 64-bit, it contains the line:
which sets the entry point to the
_start
symbol (goes to the ELF header as mentioned by ctn)And then:
which sets the address of the first headers to
0x400000
+SIZEOF_HEADERS
.I have modified that address to
0x800000
, passed my custom script withld -T
and it worked:readelf -s
says that_start
is at that address.Another way to change it is to use the
-Ttext-segment=0x800000
option.The reason for using
0x400000
= 4Mb =getconf PAGE_SIZE
is to start at the beginning of the second page as asked at: Why is the ELF execution entry point virtual address of the form 0x80xxxxx and not zero 0x0?A question describes how to set
_start
from the command line: Why is the ELF entry point 0x8048000 not changeable with the "ld -e" option?SIZEOF_HEADERS
is the size of the ELF + program headers, which are at the beginning of the ELF file. That data gets loaded into the very beginning of the virtual memory space by Linux (TODO why?) In a minimal Linux x86-64 hello world with 2 program headers it is worth0xb0
, so that the_start
symbol comes at 0x4000b0.我不确定,但请尝试此链接 http://www.docstoc。 com/docs/23942105/UNIX-ELF-文件格式
第 8 页显示了入口点(如果可执行)的位置。基本上你需要计算偏移量并且你得到了它。
确保记住 x86 的小字节序(我猜你使用它)并在你阅读字节编辑时重新排序:或者也许不是,老实说我对此不太确定。
I'm not sure but try this link http://www.docstoc.com/docs/23942105/UNIX-ELF-File-Format
at page 8 it is shown where the entry point is if it is executable. Basically you need to calculate the offset and you got it.
Make sure to remember the little endianness of x86 ( i guess you use it) and reorder if you read bytewise edit: or maybe not i'm not quit sure about this to be honest.