I built an executable for a simple program, by statically linking libc library, in x86 arch. The relocation table for that executable is empty as expected:
$ readelf -r test There are no relocations in this file. $
While when I built an executable for the same program, by statically linking libc library, in x86_64 arch, the relocation table is not empty:
$ readelf -r test Relocation section '.rela.plt' at offset 0x1d8 contains 12 entries: Offset Info Type Sym. Value Sym. Name + Addend 0000006c2058 000000000025 R_X86_64_IRELATIV 000000000042de70 0000006c2050 000000000025 R_X86_64_IRELATIV 00000000004829d0 0000006c2048 000000000025 R_X86_64_IRELATIV 000000000042dfe0 0000006c2040 000000000025 R_X86_64_IRELATIV 000000000040a330 0000006c2038 000000000025 R_X86_64_IRELATIV 0000000000432520 0000006c2030 000000000025 R_X86_64_IRELATIV 0000000000409ef0 0000006c2028 000000000025 R_X86_64_IRELATIV 0000000000445ca0 0000006c2020 000000000025 R_X86_64_IRELATIV 0000000000437f40 0000006c2018 000000000025 R_X86_64_IRELATIV 00000000004323b0 0000006c2010 000000000025 R_X86_64_IRELATIV 0000000000430540 0000006c2008 000000000025 R_X86_64_IRELATIV 0000000000430210 0000006c2000 000000000025 R_X86_64_IRELATIV 0000000000432400 $
I googled up relocation type "R_X86_64_IRELATIV" but I could find any info about it. So can someone please tell me what does it mean?
I thought if I debug the executable with gdb I might find an answer. But rather it actually brought up lot of questions :) Here is my bit of analysis:
The Sym.Name field in the above table lists the virtual address of some libc functions. When I objdump'd executable 'test' I found virtual address 0x430210 contains strcpy function. While on loading the corresponding PLT entry found at location 0x6c2008 gets changed from 0x400326 (virtual addr of next instruction ie)setting up the resolver) to 0x0x443cc0 (virtual addr of a libc function named __strcpy_sse2_unaligned) I dont why it gets resolved to a different function instead of strcpy? I assume its a different variant of strcpy.
Having done this analysis I realized I missed the basic point upfront "How come dynamic linker can come into picture when loading a static executable?" I dont find a .interp section so dynamic linker is not involved for sure. Then I observed, a libc function "__libc_csu_irel()" modifies the PLT entries and NOT dynamic linker.
If my analysis makes more sense to anyone, please let me know whats it all about. I would be happy to know the reasons behind it.
Thanks a lot!!!