linuxassemblyx86elfrelocation

ELF label address


I have the following code in .s file:

pushq $afterjmp
    nop
afterjmp:
    movl %eax, %edx

Its object file has the following:

20: 68 00 00 00 00          pushq  $0x0
25: 90                      nop
0000000000000026 <afterjmp>:
26: 89 c2                   mov    %eax,%edx

After linking, it becomes:

400572: 68 78 05 40 00          pushq  $0x400578
400577: 90                      nop
400578: 89 c2                   mov    %eax,%edx

How does the argument 0x0 to pushq at byte 20 of the object file gets converted to 0x400578 in the final executable?

Which section of the object file contains this information?


Solution

  • You answered your own question: After linking....

    Here is a good article:

    Linkers and Loaders

    In particular, note the section about "symbol relocation":

    Relocation. Compilers and assemblers generate the object code for each input module with a starting address of zero. Relocation is the process of assigning load addresses to different parts of the program by merging all sections of the same type into one section. The code and data section also are adjusted so they point to the correct runtime addresses.

    There's no way to know the program address of "afterjmp" when a single object file is assembled. It's only when all the object files are assembled into an executable image can the addresses (relative to offset "0") be computed. That's one of the jobs of the linker: to keep track of "symbol references" (like "afterjmp"), and compute the machine address ("symbol relocation").