31

I'm really trying to understand the steps from high level code -> executable.. but am having some difficulties.

I've written an empty int main() {} C file and am trying to decipher the disassembly via objdump -d. Here's what's going on:

  • in _start, set up alignment, push arguments on stack, call __libc_start_main
  • in __libc_start_main, the first line to execute is jmp *0x8049658

However, upon using objdump -R to check out the relocation records, the value in 0x8049658 is __libc_start_main itself!

I'm missing something here..

edit: here's some of the source;

 080482c0 <__libc_start_main@plt>:
 80482c0:       ff 25 58 96 04 08       jmp    *0x8049658
 80482c6:       68 08 00 00 00          push   $0x8
 80482cb:       e9 d0 ff ff ff          jmp    80482a0 <_init+0x2c>

Disassembly of section .text:

080482d0 <_start>:
 80482d0:       31 ed                   xor    %ebp,%ebp
 80482d2:       5e                      pop    %esi
 80482d3:       89 e1                   mov    %esp,%ecx
 80482d5:       83 e4 f0                and    $0xfffffff0,%esp
 80482d8:       50                      push   %eax
 80482d9:       54                      push   %esp
 80482da:       52                      push   %edx
 80482db:       68 50 84 04 08          push   $0x8048450
 80482e0:       68 e0 83 04 08          push   $0x80483e0
 80482e5:       51                      push   %ecx
 80482e6:       56                      push   %esi
 80482e7:       68 d0 83 04 08          push   $0x80483d0
 80482ec:       e8 cf ff ff ff          call   80482c0 <__libc_start_main@plt>
 80482f1:       f4                      hlt
 80482f2:       66 90                   xchg   %ax,%ax



 DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE 
08049644 R_386_GLOB_DAT    __gmon_start__
08049654 R_386_JUMP_SLOT   __gmon_start__
08049658 R_386_JUMP_SLOT   __libc_start_main
gone
  • 2,587
  • 6
  • 25
  • 32
  • Also, can you post the full assembly code you are referencing? It will make our lives much easier. – Richard J. Ross III Jun 06 '13 at 19:14
  • 2
    What happens if you step through the assembly with a debugger? It's possible that the dynamic linker overwrites the value at memory location 0x8049658, so by the time the program gets to the `jmp *0x8049658` instruction, it jumps to whatever value got written there at runtime. – Adam Rosenfield Jun 06 '13 at 19:28
  • @AdamRosenfield I'm not 100% how to do that. I know how to set gdb up to step through my C code, but don't know how to do it for the assembly :S – gone Jun 06 '13 at 19:39
  • @AdamRosenfield gdb won't even let me run the program. I get `[Inferior 1 (process 24455) exited with code 01]` – gone Jun 06 '13 at 19:50
  • 2
    `__libc_start_main@plt` is not the same symbol as `__libc_start_main` – Michael Burr Jun 06 '13 at 21:04
  • 1
    @Zak You should not need any special gdb setup. Simply use the gdb commands si and ni to execute your program one instruction at a time. – sigjuice Jun 06 '13 at 21:35
  • @MichaelBurr well no plain `__libc_start_main` symbol appears in my objdump – gone Jun 10 '13 at 15:12

1 Answers1

19

The first block, ending in "@plt", is the procedure linkage table (https://stackoverflow.com/a/5469334/994153). The jmp *0x8049658 is an indirect branch instruction, so it actually is jumping to __libc_start_main wherever it actually ends up getting loaded in RAM at runtime.

The real RAM address of __libc_start_main is found in the DYNAMIC RELOCATION RECORDS table, which is created in RAM by the dynamic loader when the program is loaded.

Community
  • 1
  • 1
Colin D Bennett
  • 11,294
  • 5
  • 49
  • 66
  • 1
    It actually gets resolved on first call these days, this blog post shows how one can watch the dynamic linker working at run-time http://dustin.schultz.io/how-is-glibc-loaded-at-runtime.html – falstaff May 14 '17 at 01:31
  • 1
    ^ This is called `lazy loading` for those searching by keyword. – sherrellbc Oct 13 '17 at 23:41