Reading objdump output without going cross-eyed
objdump is a workhorse and a wall of text in equal measure. The right flags and a sense of which section answers which question turn it into something you actually use.
objdump is the binutils Swiss Army knife: ancient, faintly grumpy, and sitting on every Linux machine you've ever logged into. It will dump your binary in fifteen different ways and reward exactly none of them with friendly formatting. The trick is knowing which flag to reach for and which section of the output answers which question. Once you have that mapping, the wall of text turns into something useful.
The four flags you'll use most
objdump -d binaryDisassemble executable sections. AT&T syntax by default, which is half the reason people give up on objdump.
objdump -d -M intel binarySame, in Intel syntax. mov rax, rbx instead of movq %rbx, %rax. If you've spent more time in Ghidra and IDA than in the GNU toolchain, you'll find the Intel mode dramatically easier on the eyes.
objdump -S binarySource-interleaved disassembly, when the binary still has DWARF debug info. Each line of source code shows up above the instructions it lowered to, which is the cheapest way to see what an optimiser actually did with your code. Compile with -g -O2 and read the output — you'll learn more about what your compiler can elide than any blog post will teach you.
objdump -r binary.oPrint relocations. Mostly useful on .o files before linking, less useful on stripped executables. When you're debugging linker errors or trying to understand why a symbol resolves the way it does, this is where you look.
objdump -x binaryThe kitchen sink: file headers, section headers, symbol table, dynamic symbol table, relocations, version definitions, the lot. Pipe it to less and scroll, or grep for what you want. This is the "dump everything you know" command.
A combination I use constantly:
objdump -d -M intel -S --no-show-raw-insn binary | lessDisassembly, Intel syntax, source-interleaved where possible, suppressing the raw instruction bytes (which are noise unless you're patching the binary). It's the closest objdump gets to comfortable reading.
What the sections of the output mean
Run objdump -d on a small binary and you'll see something like:
Disassembly of section .init:
0000000000001000 <_init>: 1000: endbr64 1004: sub $0x8,%rsp...
Disassembly of section .plt:
0000000000001020 <.plt>: 1020: push QWORD PTR [rip+0x2fda] # 4000 <_GLOBAL_OFFSET_TABLE_+0x8>...
Disassembly of section .text:
0000000000001140 <main>: 1140: push %rbp 1141: mov %rsp,%rbp...A quick map of what each section is for:
.init/.fini: runs beforemainand aftermainreturns. Glue from the C runtime..plt/.plt.got: procedure linkage table. The trampolines that jump into shared libraries via the GOT. If you seecall <foo@plt>from.text, the actualfoolives in libc..text: your code, plus everything the linker pulled in (constructors, libc startup helpers, etc.)..rodata: read-only data. String literals, switch tables, virtual function tables in C++..data/.bss: initialised and zero-initialised mutable globals..got/.got.plt: global offset table entries that the runtime linker patches with the real addresses of imported symbols..eh_frame/.eh_frame_hdr: exception-handling unwind info. Mostly noise unless you're debugging a stack trace.
Knowing which section contains what means objdump -d -j .text binary (-j selects a section) restricts the output to just your code. Useful when the binary is large.
Finding what you're looking for
Symbol table:
objdump -t binary | grep -i allocDynamic symbol table (imports and exports for shared libraries):
objdump -T binary | headStrings with addresses (often more useful than strings alone, because you get where the string lives):
objdump -s -j .rodata binary | lessJust the file header (for the entry point address, the architecture, the type):
objdump -f binaryA quick "what does this function look like?" without scrolling:
objdump -d --disassemble=main binary--disassemble=NAME is the flag I wish I'd known existed for years. It dumps just the named function instead of the whole binary.
When to reach for objdump versus the alternatives
objdump wins when you want one function quickly, when you're on a remote box, when you want grep-friendly output, or when you're inspecting .o files before linking. It's unbeatable for "did the compiler actually inline this?" or "what did -O3 do to my hot loop?". Stick -S on, grep for the function, read.
Ghidra wins when you'll spend more than an hour with the binary. Type propagation, cross-references that update as you rename, a decompiler that turns a thousand instructions into thirty lines of pseudo-C — worth the project-setup overhead the moment your investigation gets serious.
radare2 (or its kinder fork, rizin) wins when you want a scriptable terminal REPL that's strictly more powerful than objdump. Visual graph mode (VV) reads control flow over SSH without forwarding X.
gdb wins when the binary has to actually run, because the answer depends on runtime values, indirect jumps, or input-dependent behaviour static disassembly can't see.
In practice, you'll use several. objdump -d to confirm nothing weird, gdb to step to the interesting function, Ghidra for proper analysis.
A few habits that pay off
Alias your usual flags. alias od='objdump -d -M intel --no-show-raw-insn' saves four flags every time. When chasing an address, pipe through grep -B 5 -A 5 for context. On stripped binaries, --disassemble is useless (no symbols), but --start-address=0xADDR --stop-address=0xADDR works. For ELF headers, readelf -a is sharper than objdump -x; they overlap, but readelf knows ELF and only ELF.
Where this fits
If the assembly itself is what's slowing you down, Module 21: Assembly Language is the foundation: registers, calling conventions, addressing modes, the difference between Intel and AT&T syntax, what every common x86-64 instruction actually does. If the binary is the harder part (sections, symbols, dynamic linking, the things objdump exists to show you), Module 68: Binary Analysis with Ghidra gets you fluent in the file format and the tools that operate on it.