Inspect Object Files and Disassembly with objdump
You will finish with a repeatable way to identify an object file, inspect its sections and symbols, read relocations, and disassemble a selected function. The examples use GNU Binutils 2.42, installed here as objdump, aarch64-linux-gnu-objdump and x86_64-linux-gnu-objdump. The three installed manpages are identical.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell and a readable ELF object, executable or archive. Every command in this guide is read-only against its input. No elevated privileges are normally needed, and sudo will not make an unreadable file useful unless the file permissions genuinely require it.
1. Confirm the installed command and input
Check which binary your shell will run, then ask for its version:
$ command -v objdump
/usr/bin/objdump
$ objdump --version | head -1
GNU objdump (GNU Binutils for Ubuntu) 2.42
The target file is the final argument. Start with a path you can read, such as /bin/ls, or replace it with /path/to/program. Do not assume that a file named "binary" is an executable; identify it first:
$ file /path/to/program
/path/to/program: ELF 64-bit LSB pie executable, x86-64, ...
Checkpoint: if file reports a script, text file or unrelated format, stop and choose an object file. objdump can recognise many formats, but it cannot turn arbitrary input into useful disassembly.
2. Read the file header and sections
Use -f for the BFD file format, architecture, flags and start address:
$ objdump -f /bin/ls
/bin/ls: file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000006d30
Use -h for section headers. The section name, size, virtual address and file offset are useful when you need to narrow a later dump:
$ objdump -h /bin/ls | sed -n '1,12p'
/bin/ls: file format elf64-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 0000001c 0000000000000318 0000000000000318 00000318 2**0
For a compact overview of most metadata, use -x. It is equivalent to requesting all headers, section headers, private headers, relocations and symbols. The output can be large, so redirect it to a new report file only when you have chosen that destination deliberately.
3. Disassemble code you can relate to a symbol
Use -d to disassemble sections that are expected to contain code. Unlike -D, it does not disassemble every section. Add -C for demangled C++ names:
$ objdump -d -C /path/to/program
/path/to/program: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <add>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
If you know the symbol, --disassemble=SYMBOL limits the output to it. The symbol must be present in the file, and a stripped executable may have no ordinary symbol table to search. If that happens, inspect -h and use a carefully bounded address range instead.
$ objdump --disassemble=main -C /path/to/program
With an object compiled using debug information, -S interleaves source lines with disassembly and implies -d:
$ objdump -S -C /tmp/sample.o | sed -n '1,24p'
Disassembly of section .text:
0000000000000000 <add>:
int add(int left, int right) { return left + right; }
0: 55 push %rbp
No source appears when the file lacks usable debug information. That is a property of the input, not a reason to run the command as root.
4. Inspect symbols and relocations
Use -t for the ordinary symbol table and -T for the dynamic symbol table. A stripped executable can legitimately report no symbols for -t; do not interpret that as proof that the executable contains no functions.
$ objdump -t /bin/ls | sed -n '1,8p'
/bin/ls: file format elf64-x86-64
SYMBOL TABLE:
no symbols
Use -r on an object file to show relocation records, including references that the linker has not resolved yet. This is often the quickest explanation for a call whose displayed target is provisional:
$ objdump -r /tmp/sample.o | sed -n '1,12p'
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
000000000000002b R_X86_64_PLT32 add-0x0000000000000004
For a shared object or executable, -R shows dynamic relocations instead. Keep the two uses distinct when recording a build problem.
5. Dump bytes from one section
Use -s to display section contents, and add -j SECTION to avoid a noisy whole-file dump:
$ objdump -s -j .text /tmp/sample.o | sed -n '1,10p'
Contents of section .text:
0000 f30f1efa 554889e5 897dfc89 75f88b55 ....UH...}..u..U
0010 fc8b45f8 01d05dc3 f30f1efa 554889e5 ..E...].....UH..
Compressed sections are displayed in compressed form by default. Add -Z with -s when you need decompressed contents. Treat this as a diagnostic view: it does not rewrite or decompress the input file on disk.
6. Avoid the common traps
-dand-Dhave different boundaries.-Ddisassembles all sections, including data, so its output can look like instructions where no code exists.- Options such as
--start-address=ADDRESSand--stop-address=ADDRESSaffect-d,-rand-s. Confirm whether your addresses are virtual addresses or file offsets before filtering. - Long symbol names can be truncated for narrow terminals. Add
-wto use wide output and preserve names. - Cross-target aliases do not magically convert an object. Use
aarch64-linux-gnu-objdumpfor AArch64 workflows andx86_64-linux-gnu-objdumpfor x86-64 workflows, then verify the reported format with-f. - Do not pass an untrusted file to a toolchain pipeline that writes elsewhere just because
objdumpitself is read-only. Review redirections and follow-on scripts separately.
Done means
objdump --versionidentifies the installed Binutils release.objdump -f FILEconfirms the format and architecture.objdump -h FILEidentifies the sections you need.- You chose
-d,-t,-ror-s -j SECTIONfor a specific question, rather than treating a large dump as an answer.