The VikiD Truth

Knowledge base / Computing

objdump

The truth behind every program you run: it is just bytes, and those bytes are instructions you can read. objdump is the tool that turns the bytes back into something a human can follow.

What it is, in plain words

objdump is part of GNU binutils (along with as, ld, nm, readelf, strings). Point it at an object file, executable or shared library and it will show you:

LLVM ships a near drop-in twin, llvm-objdump, with the same main flags.

Why it matters

Source code is what you meant; the binary is what the machine does. objdump lets you check the difference. You use it to:

An everyday analogy: reading the recipe back from the cake

Normally the recipe produces the cake. objdump is a food scientist who takes the cake apart and writes down, as faithfully as possible, every step that must have happened. Some things are lost – the cook’s comments, the names of intermediate bowls – but the steps are all there.

flowchart LR
  S[hello.c] -- gcc -c --> O[hello.o]
  O -- ld --> E[hello ELF]
  E -- objdump -d --> A[assembly listing]
  O -- objdump -d --> A

A hands-on example

Write a tiny C program:

/* add.c */
int add(int a, int b) { return a + b; }

int main(void) { return add(2, 3); }

Compile it and look inside:

gcc -O1 -g -c add.c -o add.o
objdump -d add.o

On x86-64 you’ll see something like:

0000000000000000 <add>:
   0:   8d 04 37                lea    (%rdi,%rsi,1),%eax
   3:   c3                      ret

0000000000000004 <main>:
   4:   b8 05 00 00 00          mov    $0x5,%eax
   9:   c3                      ret

Three columns: the address, the raw bytes, and the instruction. Notice two truths at once. First, add doesn’t use add at all – the compiler used lea because it’s a cheap way to add two registers. Second, main never calls add; the optimiser worked out 2 + 3 = 5 at compile time.

Prefer Intel syntax (what most tutorials and Windows tools use)?

objdump -d -M intel add.o

Interleave the original source with the assembly (needs -g):

objdump -d -S add.o

The flags you’ll actually use

FlagShows
-ffile header (format, architecture, entry point)
-hsection headers
-tsymbol table
-Tdynamic symbols (what a shared library exports/imports)
-ddisassemble executable sections
-Ddisassemble everything, data included
-Smix in source lines
-r / -Rrelocations (static / dynamic)
-sfull hex dump of sections
--visualize-jumpsASCII arrows for branches
-Cdemangle C++ names

Flat binaries: boot sectors and firmware

A raw binary (a boot sector, a ROM dump) has no headers, so you have to tell objdump what it is:

objdump -D -b binary -m i8086 boot.bin            # 16-bit real mode
objdump -D -b binary -m i386:x86-64 blob.bin      # 64-bit

That’s the trick the Stack Overflow link below explains.

Common misconceptions

Connections

Last edited · 3 revisions

Tags: #Computing