isamateur
isamateur

Reputation: 129

Does a procedure call in the same object module require relocation in the link stage

I assumed a procedure call in the same object module wouldn't require relocation in the link stage. e.g. following code

void callee()
{
    printf("Should I be relocated\n");
}
void caller()
{
    callee();
}

After compile/assemble, I got following

Relocation section '.rel.text' at offset 0x438 contains 3 entries:
Offset     Info    Type            Sym.Value  Sym. Name
00000009  00000501 R_386_32          00000000   .rodata
0000000e  00000a02 R_386_PC32        00000000   puts
0000001b  00000902 R_386_PC32        00000000   callee

And the result of disassembly:

Disassembly of section .text:

00000000 <callee>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 18                sub    $0x18,%esp
   6:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
   d:   e8 fc ff ff ff          call   e <callee+0xe>
  12:   c9                      leave  
  13:   c3                      ret    

00000014 <caller>:
  14:   55                      push   %ebp
  15:   89 e5                   mov    %esp,%ebp
  17:   83 ec 08                sub    $0x8,%esp
  1a:   e8 fc ff ff ff          call   1b <caller+0x7>
  1f:   c9                      leave  
  20:   c3                      ret  

Why does the procedure call in a same object module (1a: e8 fc ff ff ff call 1b ) need relocation? Does it depend on my toolchain? Does the PC-relative address (the address offset between the caller and callee) ever have chance to change when calling the procedure within a same object module? If not, why not just fix the code at 0x1a to "e8 e1 ff ff ff"

Upvotes: 3

Views: 84

Answers (1)

vgru
vgru

Reputation: 51264

Relocation tables have to be stored inside each module, for that actual module, to allow load-time relocation of shared libs.

Since the dynamic linker in (most) Unix distributions can override functions in shared libraries, this means that the function can be relocated, even if the call happens inside a single module. Tools like Valgrind benefit from such features for instrumentation and leak detection.

So, as noted in comments, if you mark the function static, then the compiler can skip this part altogether and hardcode the jump.

Upvotes: 2

Related Questions