Can anyone explain how the contents of a section are relocated using the -R
option for readelf
?
I would like to see an example of this so I can understand how it works.
When I build an executable using g++
like this:
g++ -o main main.cpp
The output for -R
and -x
are the same.
When I create an object file like this:
g++ -g -c -o main.o main.cpp
I get some warnings when using -R
option with readelf
.
readelf -R .text main.o**
readelf: Warning: unable to apply unsupported reloc type 4 to section .text
readelf: Warning: unable to apply unsupported reloc type 42 to section .text
readelf: Warning: unable to apply unsupported reloc type 4 to section .text
readelf: Warning: unable to apply unsupported reloc type 42 to section .text
readelf: Warning: unable to apply unsupported reloc type 4 to section .text
What do these warnings mean and how is -R different from -x?
source: https://manpages.ubuntu.com/manpages/bionic/man1/readelf.1.html
Let's use the following main.cpp
as our example:
#include <iostream>
int main()
{
std::cout << "Hellp" << std::endl;
}
After g++ -c main.cpp
(using Debian 13.2.0-13
), we have:
readelf -Wr main.o
Relocation section '.rela.text' at offset 0x398 contains 5 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000007 0000000300000002 R_X86_64_PC32 0000000000000000 .rodata - 4
0000000000000011 0000000900000002 R_X86_64_PC32 0000000000000000 _ZSt4cout - 4
0000000000000019 0000000a00000004 R_X86_64_PLT32 0000000000000000 _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc - 4
0000000000000020 0000000c0000002a R_X86_64_REX_GOTPCRELX 0000000000000000 _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_ - 4
000000000000002b 0000000d00000004 R_X86_64_PLT32 0000000000000000 _ZNSolsEPFRSoS_E - 4
What are numeric values of the different R_*
relocations?
egrep 'define R_X86_64_(PC32|PLT32|REX_GOTPCRELX)' /usr/include/elf.h
#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
#define R_X86_64_PLT32 4 /* 32 bit PLT address */
#define R_X86_64_REX_GOTPCRELX 42 /* Load from 32 bit signed pc relative
So the warning about 4
and 42
corresponds to the R_X86_64_PLT32
and R_X86_64_REX_GOTPCRELX
relocations respectively.
Why couldn't readelf
apply PLT32
and REX_GOTPCRELX
relocations?
Because main.o
is a relocatable object -- unlike main
executable, it hasn't yet been fully linked yet, and where its .text
section will end up is yet to be determined.
And thus the addresses to which .text
will be relocated once main.o
is fully linked aren't yet known, so readelf
can't display them.