为什么gdb显示的LOAD程序头虚拟地址和运行时虚拟地址不一样?
why virtual address of LOAD program header and runtime virtual address shown by gdb is different?
我一直在努力了解elf文件格式和elf格式文档,LOAD头的VirtAddr应该是加载段的虚拟地址。但是 gdb memmap 显示要加载到不同 virt 地址的段。
$ readelf -l
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000560 0x0000000000000560 R 0x1000
LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000
0x00000000000001e5 0x00000000000001e5 R E 0x1000
LOAD 0x0000000000002000 0x0000000000002000 0x0000000000002000
0x0000000000000118 0x0000000000000118 R 0x1000
LOAD 0x0000000000002de8 0x0000000000003de8 0x0000000000003de8
0x0000000000000248 0x0000000000000250 RW 0x1000
gdb 内存映射
Entry point: 0x555555555040
0x00005555555542a8 - 0x00005555555542c4 is .interp
0x00005555555542c4 - 0x00005555555542e4 is .note.ABI-tag
0x00005555555542e4 - 0x0000555555554308 is .note.gnu.build-id
0x0000555555554308 - 0x0000555555554324 is .gnu.hash
0x0000555555554328 - 0x00005555555543d0 is .dynsym
0x00005555555543d0 - 0x0000555555554454 is .dynstr
0x0000555555554454 - 0x0000555555554462 is .gnu.version
0x0000555555554468 - 0x0000555555554488 is .gnu.version_r
0x0000555555554488 - 0x0000555555554548 is .rela.dyn
0x0000555555554548 - 0x0000555555554560 is .rela.plt
0x0000555555555000 - 0x000055555555501b is .init
0x0000555555555020 - 0x0000555555555040 is .plt
0x0000555555555040 - 0x00005555555551d5 is .text
0x00005555555551d8 - 0x00005555555551e5 is .fini
0x0000555555556000 - 0x000055555555600a is .rodata
0x000055555555600c - 0x0000555555556040 is .eh_frame_hdr
0x0000555555556040 - 0x0000555555556118 is .eh_frame
0x0000555555557de8 - 0x0000555555557df0 is .init_array
0x0000555555557df0 - 0x0000555555557df8 is .fini_array
0x0000555555557df8 - 0x0000555555557fd8 is .dynamic
0x0000555555557fd8 - 0x0000555555558000 is .got
0x0000555555558000 - 0x0000555555558020 is .got.plt
0x0000555555558020 - 0x0000555555558030 is .data
0x0000555555558030 - 0x0000555555558038 is .bss
VirtAddr of LOAD header should be the virtual address of the loaded segment.
这仅适用于 ET_EXEC
类型的 ELF 图像。
但是你有一个 ET_DYN
类型的 ELF 映像(可能是位置无关的可执行文件),并且这些映像在运行时被重新定位到不同的虚拟地址。
我一直在努力了解elf文件格式和elf格式文档,LOAD头的VirtAddr应该是加载段的虚拟地址。但是 gdb memmap 显示要加载到不同 virt 地址的段。
$ readelf -l
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000560 0x0000000000000560 R 0x1000
LOAD 0x0000000000001000 0x0000000000001000 0x0000000000001000
0x00000000000001e5 0x00000000000001e5 R E 0x1000
LOAD 0x0000000000002000 0x0000000000002000 0x0000000000002000
0x0000000000000118 0x0000000000000118 R 0x1000
LOAD 0x0000000000002de8 0x0000000000003de8 0x0000000000003de8
0x0000000000000248 0x0000000000000250 RW 0x1000
gdb 内存映射
Entry point: 0x555555555040
0x00005555555542a8 - 0x00005555555542c4 is .interp
0x00005555555542c4 - 0x00005555555542e4 is .note.ABI-tag
0x00005555555542e4 - 0x0000555555554308 is .note.gnu.build-id
0x0000555555554308 - 0x0000555555554324 is .gnu.hash
0x0000555555554328 - 0x00005555555543d0 is .dynsym
0x00005555555543d0 - 0x0000555555554454 is .dynstr
0x0000555555554454 - 0x0000555555554462 is .gnu.version
0x0000555555554468 - 0x0000555555554488 is .gnu.version_r
0x0000555555554488 - 0x0000555555554548 is .rela.dyn
0x0000555555554548 - 0x0000555555554560 is .rela.plt
0x0000555555555000 - 0x000055555555501b is .init
0x0000555555555020 - 0x0000555555555040 is .plt
0x0000555555555040 - 0x00005555555551d5 is .text
0x00005555555551d8 - 0x00005555555551e5 is .fini
0x0000555555556000 - 0x000055555555600a is .rodata
0x000055555555600c - 0x0000555555556040 is .eh_frame_hdr
0x0000555555556040 - 0x0000555555556118 is .eh_frame
0x0000555555557de8 - 0x0000555555557df0 is .init_array
0x0000555555557df0 - 0x0000555555557df8 is .fini_array
0x0000555555557df8 - 0x0000555555557fd8 is .dynamic
0x0000555555557fd8 - 0x0000555555558000 is .got
0x0000555555558000 - 0x0000555555558020 is .got.plt
0x0000555555558020 - 0x0000555555558030 is .data
0x0000555555558030 - 0x0000555555558038 is .bss
VirtAddr of LOAD header should be the virtual address of the loaded segment.
这仅适用于 ET_EXEC
类型的 ELF 图像。
但是你有一个 ET_DYN
类型的 ELF 映像(可能是位置无关的可执行文件),并且这些映像在运行时被重新定位到不同的虚拟地址。