我目前正在编写一个编译器(如果您好奇的话,可以使用),并且在试图在最新的Linux内核上运行生成的ELF二进制文件时遇到了一个奇怪的错误。同样的二进制文件可以在旧内核上运行(我已经在几个Ubuntu框上试过,uname 4.4.0-1049-aws),但是在我更新的Arch框(uname 4.17.11-arch1)上,我甚至不能在GDB下打开它们。
GDB给出的错误消息是During startup program terminated with signal SIGSEGV, Segmentation fault,据我所知,这表明在运行第一条指令之前无法加载程序段。
我用GCC/NASM编
我试图通过读取程序头来定位libc程序段在程序内存中的位置。
在Centos 6上,当我在libc.so.6文件上使用read亲自时,VirtAddr包含在进程内存中加载程序段的正确地址:
[user@centos6 src]$ readelf -l /lib64/libc.so.6 --wide
Elf file type is DYN (Shared object file)
Entry point 0x3032c1ee30
There are 10 program headers, starting at offset 64
Program Headers:
Type
我知道两者之间的关系:
虚拟地址mod页面对齐==文件偏移mod页面对齐
但是有人能告诉我这两个数字是朝哪个方向计算的吗?
虚拟地址是根据上述关系从文件偏移量计算的,还是反之亦然?
更新
下面是一些更详细的信息:当链接器写入ELF文件头时,它会设置程序头的虚拟地址和文件偏移量。
例如,有readelf -l someELFfile的输出
Elf file type is EXEC (Executable file)
Entry point 0x8048094
Program Headers:
Type Offset VirtAddr PhysAddr
我试图了解Linux中编译的程序与如何在主内存中加载程序之间的关系。
我知道当一个程序加载到内存中时,它的所有虚拟页面都在主内存的一些“页面帧”中。
下面是我的程序可读性输出的片段。
readelf --segments a.out
Elf file type is DYN (Shared object file)
Entry point 0x1060
There are 13 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr
来自便携式可执行程序和Windows,我正在尝试创建一个ELF可执行文件,并在Linux中使用NASM (Ubuntu AMD64)。我的小代码如下所示:
BITS 64
; The default virtual address where the executable is linked
_START_VAD equ 0x400000
; Here I write the header byte by byte
ELF_HEADER:
.ident_magic db 0x7f, "ELF"
如何从ELF文件中单独提取可加载的程序头?通过使用readelf检查二进制文件,可以获得与以下类似的输出:
$ readelf -l helloworld
Elf file type is EXEC (Executable file)
Entry point 0x400440
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz
int i;
int main() {
return i;
}
在-static编译之后,readelf -l显示来自elf的程序头文件:
Elf file type is EXEC (Executable file)
Entry point 0xxxxx30
There are 6 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD
我使用的是binutils-2.21.53.0.1-6.fc16.x86_64。
我有一个很小的对象文件,hello.o,它只有足够的“内容”来包含所有部分的内容:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 000000
我正在处理elf64文件,我想知道两件事,第一件事是,在哪一段中存储了可重构的文件,因为没有显示readelf -l。还有另一个问题(来自第一个问题),一个部分不可能在一个片段中吗?
我还注意到了一些片段之间的“空白”。这些缺口里面是什么?
我使用的是以下示例,即hello_world.c:
readelf -lW hello
El tipo del fichero elf es DYN (Fichero objeto compartido)
Entry point 0x1040
There are 11 p