Meaning of ELF64_R_SYM(rela->r_info)

Fangrui Song i@maskray.me
Wed Apr 21 23:08:59 GMT 2021


On 2021-04-21, Peng Yu via Binutils wrote:
>To put this into more complete context, here is the assembly code that
>the a.o file is generated from.
>
>Besides the questions that I asked in the previous email, I also have
>other questions.
>
>Why "call" is used here? Isn't it better to use "call" in both the
>assembly code and the objdump output to make the result consistent?
>
>Also, this assembly code is not very human writable. For example, "s"
>definition is split into 5 lines. I am more familiar with nasm syntax,
>in which, the code can be written much short. Is the as syntax this
>verbose? Or it is because it is machine generated assembly code, it is
>OK to be verbose? What the equivalent more writable code looks like?
>
>"leaq" becomes "lea" in the objdump output which is exactly the
>opposite of the "call" case (as "q" is added by objdump disassembly).
>This is again confusing. Why is so? How to know when the -q version
>should be used when the non-q version should be used? Isn't it better
>to make them consistent throughout?
>
>    .file    "a.c"
>    .text
>    .globl    s
>    .section    .rodata
>    .align 8
>    .type    s, @object
>    .size    s, 14
>s:
>    .string    "Hello World2!"
>.LC0:
>    .string    "Hello World!"
>    .text
>    .globl    main
>    .type    main, @function
>main:
>.LFB0:
>    .cfi_startproc
>    pushq    %rbp
>    .cfi_def_cfa_offset 16
>    .cfi_offset 6, -16
>    movq    %rsp, %rbp
>    .cfi_def_cfa_register 6
>    leaq    .LC0(%rip), %rdi
>    call    puts@PLT
>    leaq    s(%rip), %rdi
>    call    puts@PLT
>    movl    $0, %eax
>    popq    %rbp
>    .cfi_def_cfa 7, 8
>    ret
>    .cfi_endproc
>.LFE0:
>    .size    main, .-main
>    .ident    "GCC: (Debian 10.2.1-6) 10.2.1 20210110"
>    .section    .note.GNU-stack,"",@progbits
>
>
>On Wed, Apr 21, 2021 at 12:28 PM Peng Yu <pengyu.ut@gmail.com> wrote:
>>
>> On 4/21/21, Nick Clifton <nickc@redhat.com> wrote:
>> > Hi Peng,
>> >
>> >> What is "a" in ".rodata + a"?
>> >
>> > It is an offset, in hexadecimal.  So in this case "a" is 0xa or 10.
>> >
>> >> What the offset refers to? I don't quite follow the document.
>> >
>> > The offset is part of the relocation.  So for example:
>> >
>> >  > Relocation section '.rela.text' at offset 0x248 contains 4 entries:
>> >  >      Offset             Info             Type               Symbol's
>> >  > Value  Symbol's Name + Addend
>> >  > 0000000000000007  0000000500000002 R_X86_64_PC32
>> >  > 0000000000000000 .rodata + a
>> >
>> > This first relocation says that the operation R_X86_64_PC32 should be
>> > applied to the sum of the value of symbol .rodata and the constant 0xa
>> > and the result stored at an offset of 0x0000000000000007 in the .text
>> > section.

The readelf -WS output should give the meaning of the symbol index 5.
It is a section symbol (STT_SECTION) whose st_shndx is the index into
the section header table. The section is .rodata


>> > The operation to be applied and the symbol it uses are extracted from
>> > the r_info field of the the relocation.  The value to be added to the
>> > symbol is extracted from the r_addend field of the relocation, and the
>> > offset in the .text section into which the result is applied is taken
>> > from the r_offset field.
>> >
>> >
>> >> Of the two "puts - 4", could anybody explain how
>> >> r_offset is computed?
>> >
>> > The *r_offset* field is computed by whichever tool create the object
>> > file.  Typically either the assembler or the compiler.  When the
>> > instruction to be affected by the relocation is added to a given
>> > section, the tool computes the offset of that instruction from the start
>> > of the section and places it into the r_offset field of the relocation.
>> >
>> > The *r_addend* field is also computed by the tool that creates the
>> > object file.  The value is architecture and relocation specific, and
>> > generally speaking you need to be familiar with the instruction set of
>> > the processor in order to be able to understand the addends.
>> >
>> > In your example the -4 comes from the fact that the CALLQ instruction
>> > biases the constant part of its operand by +4.  So if you want to branch
>> > to the "puts" function you need to store "puts -4" in the CALLQ
>> > instruction.
>>
>> I don't understand the -4 part. Could you show me the definition of CALLQ?
>>
>> > As an aside you may find it helpful to use the objdump tool to see more
>> > about relocations.  If you combine its disassembly output with its
>> > relocation output you can see the instructions to which relocs refer:
>> >
>> >    $ objdump -dr hello.o
>> >    [...]
>> >     9:        e8 00 00 00 00          callq  e <main+0xe>
>> >                       a: R_X86_64_PLT32       puts-0x4
>>
>> Here is the `objdump -dr` output of a.o and a.out of the two-puts c file.

The relocation (r_offset: 0xa) modifies the bytes from 0xa to 0xd.
x86 lets a relocation start at the first byte the relocation applies.

On RISC architectures a common convention is to use the first byte of
the containing instruction.

As of `callq e`, objdump disassembles the instruction without taking
into consideration of potential linker effects wrt the relocation.
The raw e8 00 00 00 00 decodes to a call to the next instruction, which
is `callq 0xe` in this case. objdump on many architectures omit the 0x
prefix.

>> `# b <main+0xb>` and `# 17 <main+0x17>` add no information, as they
>> appear to be just the addresses of the next instructions? So I can
>> just ignore them?
>>
>> The numbers "10" and "1c" in "callq  10" and "callq  1c" just mean
>> that upon returning from callq, the next instruction to run is at
>> address 10 and 1c? They are derived by the disassembly (as in the
>> binary, the addresses are just zero)?
>>
>> "7: R_X86_64_PC32       .rodata+0xa" is just a reitteration of the entries
>> in .rela.text "000000000007  000500000002 R_X86_64_PC32
>> 0000000000000000 .rodata + a"? So that it brings the relocation to the
>> context of the assembly code for easier reading?
>>
>> How "a" is derived? "Hello World!" starts at the 15th character
>> (indexed at 14) in .rodata. I don't understand how "a" is computed
>> from 14?
>>
>> $ readelf -x .rodata a.o
>>
>> Hex dump of section '.rodata':
>>   0x00000000 48656c6c 6f20576f 726c6432 21004865 Hello World2!.He
>>   0x00000010 6c6c6f20 576f726c 642100            llo World!.
>>
>> How 0xed6 in the output of a.out is derived from that of a.o? Could
>> you show the exact arithmetics? Thanks.
>>
>> $ objdump -dr a.o
>> ....
>> 0000000000000000 <main>:
>>    0:   55                      push   %rbp
>>    1:   48 89 e5                mov    %rsp,%rbp
>>    4:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # b <main+0xb>
>>                         7: R_X86_64_PC32        .rodata+0xa
>>    b:   e8 00 00 00 00          callq  10 <main+0x10>
>>                         c: R_X86_64_PLT32       puts-0x4
>>   10:   48 8d 3d 00 00 00 00    lea    0x0(%rip),%rdi        # 17 <main+0x17>
>>                         13: R_X86_64_PC32       s-0x4
>>   17:   e8 00 00 00 00          callq  1c <main+0x1c>
>>                         18: R_X86_64_PLT32      puts-0x4
>>   1c:   b8 00 00 00 00          mov    $0x0,%eax
>>   21:   5d                      pop    %rbp
>>   22:   c3                      retq
>> $ objdump -dr a.out
>> ...
>> 0000000000001030 <puts@plt>:
>>     1030: ff 25 e2 2f 00 00     jmpq   *0x2fe2(%rip)        # 4018
>> <puts@GLIBC_2.2.5>
>>     1036: 68 00 00 00 00        pushq  $0x0
>>     103b: e9 e0 ff ff ff        jmpq   1020 <.plt>
>> ...
>> 0000000000001135 <main>:
>>     1135: 55                    push   %rbp
>>     1136: 48 89 e5              mov    %rsp,%rbp
>>     1139: 48 8d 3d d6 0e 00 00  lea    0xed6(%rip),%rdi        # 2016 <s+0xe>
>>     1140: e8 eb fe ff ff        callq  1030 <puts@plt>
>>     1145: 48 8d 3d bc 0e 00 00  lea    0xebc(%rip),%rdi        # 2008 <s>
>>     114c: e8 df fe ff ff        callq  1030 <puts@plt>
>>     1151: b8 00 00 00 00        mov    $0x0,%eax
>>     1156: 5d                    pop    %rbp
>>     1157: c3                    retq
>>     1158: 0f 1f 84 00 00 00 00  nopl   0x0(%rax,%rax,1)
>>     115f: 00
>>
>> --
>> Regards,
>> Peng
>
>
>
>-- 
>Regards,
>Peng


More information about the Binutils mailing list