Skip to content
Advertisement

why virtual address of LOAD program header and runtime virtual address shown by gdb is different?

I’ve been trying to understand elf file format and on elf format documentation, VirtAddr of LOAD header should be the virtual address of the loaded segment. But gdb memmap shows segments to be loaded at different virt address.

$ 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 memmap

    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

Advertisement

Answer

VirtAddr of LOAD header should be the virtual address of the loaded segment.

This is only true for ELF images of type ET_EXEC.

But you have an ELF image of type ET_DYN (probably a position independent executable), and these are relocated at runtime to a different virtual address.

Advertisement