I have a very basic program that I compiled with
gcc -m32 -g -o hello32.out hello.c
When I run disassemble main in gdb I get the following output:
0x0000051d <+0>: lea ecx,[esp+0x4]
0x00000521 <+4>: and esp,0xfffffff0
0x00000524 <+7>: push DWORD PTR [ecx-0x4]
0x00000527 <+10>: push ebp
0x00000528 <+11>: mov ebp,esp
0x0000052a <+13>: push ebx
0x0000052b <+14>: push ecx
0x0000052c <+15>: sub esp,0x10
0x0000052f <+18>: call 0x420 <__x86.get_pc_thunk.bx>
0x00000534 <+23>: add ebx,0x1aa4
0x0000053a <+29>: mov DWORD PTR [ebp-0xc],0x0
... [truncated for brevity]
However, when I run
(gdb) break main
(gdb) run
(gdb) info register eip
I get
eip 0x5655553a 0x5655553a <main+29>
Why is main+29 shown as 0x0000053a in the assembler dump but 0x5655553a when the address of eip is given?
Your GCC makes PIE executables by default, so there is no fixed base address in the file (and disassembly shows it relative to 0, i.e. offsets rather than absolute addresses).
Once the kernel's ELF program loader has created a running process from the executable (and chosen a virtual address as the base), GDB can show you the actual runtime virtual addresses. (e.g. starti
to start it running, then disas my_func
to get a valid address within that process; GDB disables ASLR so it will be the same every time only if running under GDB, or with other ways of disabling ASLR for a specific run of a process or system-wide.)
Build with -fno-pie -no-pie
to get position-dependent executables where the runtime address is known from the executable metadata. (You should definitely prefer -fno-pie
for i386 code: without RIP-relative addressing the extra performance / code-size cost of position-independent code is significantly worse than for x86-64.)
Related: 32-bit absolute addresses no longer allowed in x86-64 Linux? for more about PIE (both 32-bit and 64-bit x86, and in general.)
GDB - Address of breakpoint is similar to this but not exactly a duplicate.
User contributions licensed under CC BY-SA 3.0