OBJDUMP(1)

๐Ÿ“ฆ version 2.45, in ubuntu questing

๐ŸŽ€ OBJDUMP(1) ๐ŸŽ€

GNU Development Tools manual page, bestie ๐Ÿ’–

โœจ NAME โœจ

objdump is the tool that spills all the info from object files ๐Ÿ”. It's basically a little detective for compiled stuff.

๐Ÿงš SYNOPSIS โœจ

objdump [-a|--archive-headers]
        [-b bfdname|--target=bfdname]
        [-C|--demangle[=style] ]
        [-d|--disassemble[=symbol]]
        [-D|--disassemble-all]
        [-z|--disassemble-zeroes]
        [-EB|-EL|--endian={big | little }]
        [-f|--file-headers]
        [-F|--file-offsets]
        [--file-start-context]
        [-g|--debugging]
        [-e|--debugging-tags]
        [-h|--section-headers|--headers]
        [-i|--info]
        [-j section|--section=section]
        [-l|--line-numbers]
        [-S|--source]
        [--source-comment[=text]]
        [-m machine|--architecture=machine]
        [-M options|--disassembler-options=options]
        [-p|--private-headers]
        [-P options|--private=options]
        [-r|--reloc]
        [-R|--dynamic-reloc]
        [-s|--full-contents]
        [-Z|--decompress]
        [-W[lLiaprmfFsoORtUuTgAck]|
         --dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links]]
        [-WK|--dwarf=follow-links]
        [-WN|--dwarf=no-follow-links]
        [-wD|--dwarf=use-debuginfod]
        [-wE|--dwarf=do-not-use-debuginfod]
        [-L|--process-links]
        [--ctf=section]
        [--sframe=section]
        [-G|--stabs]
        [-t|--syms]
        [-T|--dynamic-syms]
        [-x|--all-headers]
        [-w|--wide]
        [--start-address=address]
        [--stop-address=address]
        [--no-addresses]
        [--prefix-addresses]
        [--[no-]show-raw-insn]
        [--adjust-vma=offset]
        [--show-all-symbols]
        [--dwarf-depth=n]
        [--dwarf-start=n]
        [--ctf-parent=section]
        [--no-recurse-limit|--recurse-limit]
        [--special-syms]
        [--prefix=prefix]
        [--prefix-strip=level]
        [--insn-width=width]
        [--visualize-jumps[=color|=extended-color|=off]
        [--disassembler-color=[off|terminal|on|extended]
        [-U method] [--unicode=method]
        [-V|--version]
        [-H|--help]
        objfile...

๐Ÿ’… DESCRIPTION ๐Ÿ’…

okay so objdump shows you info about one or more object files ๐Ÿซถ The options you pick decide exactly what info you get. ngl this is mostly for the programmers who are building the compilation tools themselves ๐Ÿ› ๏ธ, not the ones who just want their program to compile and work and go to bed ๐Ÿ˜ด

objfile... are the object files it'll poke at ๐Ÿ‘€ If you hand it archives, objdump looks at every single member object file inside them. no cap, that's a lot of info โœจ

๐Ÿ‘‘ OPTIONS ๐Ÿ‘‘

The long and short versions of each option are interchangeable, same energy, different outfit ๐ŸŽ€ You must give at least one option from this list: -a, -d, -D, -e, -f, -g, -G, -h, -H, -p, -P, -r, -R, -s, -S, -t, -T, -V, -x. Without one of those, it's giving nothing ๐Ÿ’€

  • -a, --archive-header โ€” ๐Ÿ“ฆ If any of your objfile files are archives, this shows the archive header info (kinda like ls -l). On top of what you'd get from ar tv, objdump -a also shows the object file format of each archive member.
  • --adjust-vma=offset โ€” ๐Ÿฆ‹ When dumping info, it first adds offset to every section address. This is super useful when the section addresses don't line up with the symbol table, which can happen when sections get placed at specific addresses in a format that can't store section addresses, like a.out.
  • -b bfdname, --target=bfdname โ€” ๐ŸŽฏ Tells objdump that the object-code format of your object files is bfdname. You might not even need this, because objdump can often figure out lots of formats on its own ๐Ÿง 

For example, this:

objdump -b oasys -m vax -h fu.o

shows summary info from the section headers (-h) of fu.o, which is explicitly marked (-m) as a VAX object file in the format made by Oasys compilers. want the full list of formats? use the -i option ๐Ÿ“‹

  • -C, --demangle[=style] โ€” ๐Ÿช„ Demangles low-level symbol names back into user-level names. It removes any initial underscore the system tacked on, and it makes C++ function names actually readable ๐Ÿฅน Different compilers mangle names differently, so the optional style argument lets you pick the demangling style that matches your compiler.
  • --recurse-limit, --no-recurse-limit, --recursion-limit, --no-recursion-limit โ€” ๐ŸŒ€ Turns a limit on how deep demangling is allowed to recurse on or off. Name mangling formats allow infinite levels of recursion, so some strings could eat up all the stack space on the host machine and cause a memory fault ๐Ÿ˜ฑ The limit stops that by capping recursion at 2048 levels of nesting.

The limit is on by default, but you might need to turn it off to demangle really complicated names. Just know that if you disable it, stack exhaustion is possible, and any bug reports about that event will be rejected ๐Ÿ™…โ€โ™€๏ธ

  • -g, --debugging โ€” ๐Ÿ”Ž Displays debugging info. It tries to parse the STABS debugging format info stored in the file and prints it out using C-like syntax. If there's no STABS debugging info, this option falls back to the -W option to print any DWARF info in the file instead.
  • -e, --debugging-tags โ€” ๐Ÿท๏ธ Same vibe as -g, but the info is generated in a format that works with the ctags tool.
  • -d, --disassemble, --disassemble=symbol โ€” ๐Ÿงฉ Shows the assembler mnemonics for the machine instructions in the input file. This only disassembles the sections that are expected to hold instructions. If you pass a symbol (you can pass several), it shows the mnemonics starting at (all the) symbol. If the symbol is a function name, disassembly stops at the end of that function; otherwise it stops when the next symbol shows up. If nothing matches any symbol, nothing gets displayed ๐Ÿซ 

Heads up: if --dwarf=follow-links is on, any symbol tables in linked debug info files will be read in and used while disassembling ๐Ÿ”—

  • -D, --disassemble-all โ€” ๐ŸŒŸ Like -d, but it disassembles the contents of every non-empty, non-bss section, not just the ones expected to contain instructions. You can use -j to pick specific sections ๐ŸŽฏ

This one also has a subtle effect on code sections. With -d, objdump assumes any symbols in a code section sit on the boundary between instructions, and it refuses to disassemble across that boundary. With -D, that assumption gets suppressed. So -d and -D can give different output if, say, data is stored in code sections ๐Ÿ‘€

If the target is an ARM architecture, this switch also forces the disassembler to decode pieces of data found in code sections as if they were instructions ๐Ÿค–

Also, again: if --dwarf=follow-links is on, any symbol tables in linked debug info files will be read in and used while disassembling ๐Ÿ”—

  • --no-addresses โ€” ๐Ÿ™ˆ When disassembling, it stops printing addresses on each line, and also for symbols and relocation offsets. Paired with --no-show-raw-insn, this can be handy for comparing compiler output ๐Ÿ’œ
  • --prefix-addresses โ€” ๐Ÿ“œ When disassembling, it prints the complete address on each line. This is the older disassembly format, so it's kinda vintage ๐Ÿ•ฐ๏ธ
  • -EB, -EL, --endian={big|little} โ€” ๐ŸŒŠ Sets the endianness of the object files. This only affects disassembly ๐Ÿง  It's useful when disassembling a file format that doesn't describe endianness, like S-records.
  • -f, --file-headers โ€” ๐Ÿ—‚๏ธ Displays summary info from the overall header of each of the objfile files.
  • -F, --file-offsets โ€” ๐Ÿ“ When disassembling sections, every time a symbol gets displayed, it also shows the file offset of the chunk of data about to be dumped. If zeroes are being skipped, then when disassembly picks back up, it tells you how many zeroes got skipped and the file offset of where disassembly resumes. When dumping sections, it shows the file offset of where the dump starts.
  • --file-start-context โ€” ๐Ÿ“– When displaying interlisted source code and disassembly (this assumes -S) from a file that hasn't been displayed yet, it extends the context all the way back to the start of the file.
  • -h, --section-headers, --headers โ€” ๐Ÿงพ Displays summary info from the section headers of the object file.

Real talk: file segments can get relocated to nonstandard addresses, like with the -Ttext, -Tdata, or -Tbss options to ld. But some object file formats, like a.out, don't store the starting address of file segments. In that case, even though ld relocates the sections correctly, objdump -h can't show the correct addresses. Instead, it shows the usual addresses, which are implicit for the target ๐Ÿคทโ€โ™€๏ธ

Also, in some cases a section can have both the READONLY and NOREAD attributes set. When that happens, NOREAD takes precedence, but objdump reports both anyway, because the exact flag bits might matter ๐Ÿง

  • -H, --help โ€” ๐Ÿ†˜ Prints a summary of the objdump options and then exits.
  • -i, --info โ€” ๐Ÿ“š Displays a list of every architecture and object format you can specify with -b or -m.
  • -j name, --section=name โ€” ๐ŸŽ€ Displays info for the section name. You can use this more than once ๐Ÿ’…
  • -L, --process-links โ€” ๐Ÿ”— Displays the contents of non-debug sections found in separate debuginfo files that are linked to the main file. This automatically implies the -WK option, and only the sections requested by your other command line options get displayed โœจ
  • -l, --line-numbers โ€” okay so this one labels the display with the filename and source line numbers (pulled from debugging info) that match the object code or relocs being shown. It's only useful with -d, -D, or -r. ๐ŸŽ€
  • -m machine, --architecture=machine โ€” tells objdump which architecture to use when disassembling. This is a lifesaver for files that don't describe their own architecture, like S-records. ๐Ÿฆ‹ You can list the available architectures with the -i option.

For most architectures you can give both an architecture name and a machine name, separated by a colon. So foo:bar means the bar machine type in the foo architecture. This is super helpful if objdump has been configured to support multiple architectures ๐Ÿ’…

If the target is an ARM architecture, this switch does something extra: it restricts the disassembly to only the instructions supported by the architecture you pass as machine. ๐Ÿ‘€ If you need this switch because the input file has no architecture info but you still want to disassemble all the instructions, use -marm. ๐Ÿซถ

  • -M options, --disassembler-options=options โ€” passes target-specific info to the disassembler. This is only supported on some targets ๐ŸŒธ If you need more than one disassembler option, you can use multiple -M options or stuff them all into one comma separated list.

For ARC, dsp controls the printing of DSP instructions, spfp selects the printing of FPX single precision FP instructions, dpfp selects the printing of FPX double precision FP instructions, quarkse_em selects the printing of special QuarkSE-EM instructions, fpuda selects the printing of double precision assist instructions, fpus selects the printing of FPU single precision FP instructions, and fpud selects the printing of FPU double precision FP instructions. You can also have all the immediates printed in hexadecimal with hex. By default, short immediates are printed in decimal, while long immediate values are printed as hexadecimal โœจ

cpu=... lets you enforce a particular ISA when disassembling, overriding the -m value or whatever is in the ELF file. This might be useful for picking ARC EM or HS ISA, since the architecture is the same for both and the disassembler relies on private ELF header data to decide whether code is for EM or HS ๐Ÿงš You can specify this option multiple times, but only the latest value is used. Valid values are the same as for the assembler -mcpu=... option.

If the target is an ARM architecture, this switch can select which register name set the disassembler uses. Specifying -M reg-names-std (the default) gives you the register names used in ARM's instruction set documentation, except register 13 is called sp, register 14 is called lr, and register 15 is called pc. Specifying -M reg-names-apcs gives you the name set used by the ARM Procedure Call Standard, and -M reg-names-raw will just use r followed by the register number ๐Ÿ“

There are also two variants of the APCS register naming scheme, enabled by -M reg-names-atpcs and -M reg-names-special-atpcs. These use the ARM/Thumb Procedure Call Standard naming conventions. (You get these either with the normal register names or the special register names.)

This option can also be used on ARM architectures to force the disassembler to read every instruction as a Thumb instruction, using --disassembler-options=force-thumb. This is handy when you're trying to disassemble Thumb code made by other compilers ๐Ÿ’œ

For AArch64 targets, this switch controls whether instructions are disassembled as the most general instruction, using -M no-aliases, or whether instruction notes get generated as comments in the disassembly, using -M notes ๐ŸŒˆ

For x86, some of these options duplicate what the -m switch does, but they give you finer grained control ๐Ÿ’–

  • "x86-64", "i386", "i8086" โ€” select disassembly for the given architecture.
  • "intel", "att" โ€” pick between Intel syntax mode and AT&T syntax mode.
  • "amd64", "intel64" โ€” pick between the AMD64 ISA and the Intel64 ISA.
  • "intel-mnemonic", "att-mnemonic" โ€” pick between Intel mnemonic mode and AT&T mnemonic mode. Note: "intel-mnemonic" implies "intel", and "att-mnemonic" implies "att" ๐Ÿ‘‘
  • "addr64", "addr32", "addr16", "data32", "data16" โ€” set the default address size and operand size. These five get overridden if "x86-64", "i386", or "i8086" show up later in the option string ๐Ÿ™ˆ
  • "suffix" โ€” in AT&T mode (and for a limited set of instructions in Intel mode), this tells the disassembler to print a mnemonic suffix even when the suffix could be inferred from the operands or, for certain instructions, from the execution mode's defaults ๐Ÿ”ฅ

For PowerPC, the -M argument raw selects disassembly of hardware insns instead of aliases. So you'll see rlwinm rather than clrlwi, and addi rather than li โœจ All of the -m arguments for gas that select a CPU are supported. Those are: 403, 405, 440, 464, 476, 601, 603, 604, 620, 7400, 7410, 7450, 7455, 750cl, 821, 850, 860, a2, booke, booke32, cell, com, e200z2, e200z4, e300, e500, e500mc, e500mc64, e500x2, e5500, e6500, efs, power4, power5, power6, power7, power8, power9, power10, power11, ppc, ppc32, ppc64, ppc64bridge, ppcps, pwr, pwr2, pwr4, pwr5, pwr5x, pwr6, pwr7, pwr8, pwr9, pwr10, pwr11, pwrx, titan, vle, and future. ๐Ÿ˜ญ

32 and 64 modify the default or a prior CPU selection, disabling and enabling 64-bit insns respectively. Then altivec, any, lsp, htm, vsx, spe, and spe2 add capabilities to a previous or later CPU selection. any will disassemble any opcode known to binutils, but if an opcode has two different meanings or different arguments, you might not get the disassembly you expect ๐Ÿ’€ If you disassemble without giving a CPU selection, a default gets picked from info BFD pulls out of the object file headers, but again, the result may not be what you expect.

For RISC-V, the following options are supported:

  • "max" โ€” disassembles without checking the architecture string. This is a best effort mode, so for overlapping ISA extensions the first match (possibly incorrect in a given context) gets used to decode the instruction. It's useful when the ELF file doesn't expose an ISA string, which stops automatic ISA subset deduction, and the default fallback ISA string ("rv64gc") doesn't cover all the instructions in the binary ๐ŸŒธ
  • "numeric" โ€” prints numeric register names instead of ABI names, so you'd see "x2" instead of "sp" ๐Ÿ”ข
  • "no-aliases" โ€” disassembles only into canonical instructions. For example, compressed instructions get represented as such, so "addi sp,sp,-128" becomes "c.addi16sp sp,-128" ๐Ÿงธ
  • "priv-spec=SPEC" โ€” prints the CSR according to the chosen privilege spec version (e.g., 1.10, 1.11, 1.12, 1.13) ๐Ÿ“œ

For MIPS, this option controls how instruction mnemonic names and register names get printed. You can specify multiple selections from the list below as a comma separated string. Invalid options are ignored ๐Ÿฆ„

  • "no-aliases" โ€” prints the 'raw' instruction mnemonic instead of a pseudo instruction mnemonic. So you get daddu or or instead of move, and sll instead of nop, and so on.
  • "msa" โ€” disassembles MSA instructions.
  • "virt" โ€” disassembles the virtualization ASE instructions.
  • "xpa" โ€” disassembles the eXtended Physical Address (XPA) ASE instructions.
  • "gpr-names=ABI" โ€” prints GPR (general-purpose register) names as appropriate for the specified ABI. By default, GPR names are picked according to the ABI of the binary being disassembled.
  • "fpr-names=ABI" โ€” prints FPR (floating-point register) names as appropriate for the specified ABI. By default, FPR numbers get printed instead of names.
  • "cp0-names=ARCH" โ€” prints CP0 (system control coprocessor; coprocessor 0) register names as appropriate for the CPU or architecture given as ARCH. By default, CP0 register names are picked according to the architecture and CPU of the binary being disassembled.
  • "hwr-names=ARCH" โ€” prints HWR (hardware register, used by the "rdhwr" instruction) names as appropriate for the CPU or architecture given as ARCH. By default, HWR names are picked according to the architecture and CPU of the binary being disassembled.
  • "reg-names=ABI" โ€” prints GPR and FPR names as appropriate for the selected ABI.
  • "reg-names=ARCH" โ€” prints CPU-specific register names (CP0 register and HWR names) as appropriate for the selected CPU or architecture.

For any of the options above, ABI or ARCH can be set to numeric to print numbers instead of names for the selected types of registers. You can list the available values of ABI and ARCH using the --help option ๐ŸŽ€

For VAX, you can specify function entry addresses with -M entry:0xf00ba. You can use this multiple times to properly disassemble VAX binary files that don't contain symbol tables (like ROM dumps) ๐Ÿงš Without this, the function entry mask would get decoded as VAX instructions, which would probably mess up the rest of the function's disassembly ๐Ÿ™ƒ

  • -p, --private-headers โ€” prints info that's specific to the object file format. The exact info depends on the format, and for some formats no extra info gets printed at all ๐Ÿ“ฆ
  • -P options, --private=options โ€” prints info that's specific to the object file format too. The options argument is a comma separated list that depends on the format (you can see the lists with the help) ๐Ÿ’…

For XCOFF, the available options are:

Okay so the XCOFF list is still going, bestie, and it's literally the menu of section names you can pass in:

  • "header"
  • "aout"
  • "sections"
  • "syms"
  • "relocs"
  • "lineno,"
  • "loader"
  • "except"
  • "typchk"
  • "traceback"
  • "toc"
  • "ldinfo"

For PE files, the only choices are:

  • "header"
  • "sections"
๐Ÿšจ Not every object format supports this option. ELF doesn't use it at all, so don't waste your time there ๐Ÿ’€

  • -r, --reloc โ€” Prints the relocation entries of the file ๐Ÿ”— If you pair it with -d or -D, the relocations get woven in between the disassembly, which is so satisfying โœจ
  • -R, --dynamic-reloc โ€” Prints the dynamic relocation entries ๐Ÿฆ‹ This only matters for dynamic objects, like certain shared libraries. Same deal as -r: add -d or -D and the relocations sit right in the disassembly.
๐Ÿ“ Heads up: objdump can't show RELR type relocations. If you need those, go ask the readelf program instead ๐Ÿ™ˆ
  • -s, --full-contents โ€” Dumps the full contents of sections ๐Ÿ“ฆ It's usually paired with -j so you can pick out specific sections. By default, every non-empty, non-bss section gets shown. Compressed sections show up in their compressed form unless you add the -Z option, which gives you the decompressed version ๐Ÿงš
  • -S, --source โ€” Shows source code mixed in with the disassembly, if that's possible ๐Ÿ’œ It implies -d, so you don't need to add it yourself.
  • --show-all-symbols โ€” When disassembling, shows every symbol matching a given address, not just the first one ๐Ÿ‘‘
  • --source-comment[=txt] โ€” Basically -S, except every source line gets a prefix of txt ๐ŸŽ€ Usually txt is a comment string so you can tell the assembler code apart from the source code. If you don't give txt, the default is "# " (hash followed by a space) โœจ
  • --prefix=prefix โ€” Sets a prefix to stick onto the absolute paths when you use -S ๐ŸŒธ
  • --prefix-strip=level โ€” Tells objdump how many leading directory names to chop off the hardwired absolute paths ๐Ÿช“ It does nothing unless you also use --prefix=prefix.
  • --show-raw-insn โ€” When disassembling, prints each instruction in hex as well as symbolic form ๐Ÿ“ This is the default, except when --prefix-addresses is in play.
  • --no-show-raw-insn โ€” When disassembling, skips the instruction bytes entirely ๐Ÿ™ˆ This is the default when --prefix-addresses is used.
  • --insn-width=width โ€” Shows width bytes on a single line when disassembling instructions ๐Ÿ“
  • --visualize-jumps[=color|=extended-color|=off] โ€” Draws little ASCII art between the start and target addresses for jumps that stay inside a function ๐Ÿฆ‹ Add =color for simple terminal colors, or =extended-color for 8-bit colors, which might not work on every terminal ๐ŸŒˆ

If you turned visualize-jumps on earlier and now want it gone, use visualize-jumps=off ๐Ÿ’…

  • --disassembler-color=off, --disassembler-color=terminal, --disassembler-color=on|color|colour, --disassembler-color=extended|extended-color|extended-colour โ€” Turns colored syntax highlighting in the disassembly on or off ๐ŸŽจ The default is decided by a configure time option. Not every architecture supports colors, and depending on your terminal, the colors might not be very legible ๐Ÿ’€
    • on (or color, or colour) adds colors using simple terminal colors โœจ
    • terminal does the same thing, but only if the output device is a terminal ๐Ÿ–ฅ๏ธ
    • extended (or extended-color, or extended-colour) is like on, but uses 8-bit colors, which may not work everywhere ๐ŸŒˆ
    • off turns colored disassembly off completely ๐Ÿซถ

  • -W[lLiaprmfFsoORtUuTgAckK], `--dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,=frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,=trace_info,=trace_abbrev,=trace_aranges,=gdb_index,=addr,=cu_index,=links,=follow-links] โ€” Displays the DWARF debug sections in the file, if there are any ๐Ÿ” Compressed debug sections get decompressed temporarily before they're shown. If you add one or more of the letters or words after the switch, only those kinds of data get dumped. Here's what each one means:
    • "a", "=abbrev" โ€” Shows the contents of the .debug_abbrev section ๐Ÿ“š
    • "A", "=addr" โ€” Shows the contents of the .debug_addr section ๐Ÿ“
    • "c", "=cu_index" โ€” Shows the contents of the .debug_cu_index and/or .debug_tu_index sections ๐Ÿ—‚๏ธ
    • "f", "=frames" โ€” Displays the raw contents of a .debug_frame section ๐Ÿงฑ
    • "F", "=frames-interp" โ€” Displays the interpreted contents of a .debug_frame section ๐Ÿช„
    • "g", "=gdb_index" โ€” Shows the contents of the .gdb_index and/or .debug_names sections ๐Ÿ”Ž
    • "i", "=info" โ€” Shows the contents of the .debug_info section ๐Ÿ’– Heads up: the output here can also be narrowed down with --dwarf-depth and --dwarf-start.
    • "k", "=links" โ€” Shows the contents of the .gnu_debuglink, .gnu_debugaltlink and .debug_sup sections, if any are present ๐Ÿ”— It also shows any links to separate dwarf object files (dwo), if they're specified by the DW_AT_GNU_dwo_name or DW_AT_dwo_name attributes in the .debug_info section.
    • "K", "=follow-links" โ€” Displays the contents of any selected debug sections found in linked, separate debug info files ๐Ÿ•ต๏ธโ€โ™€๏ธ This can show you multiple versions of the same debug section if it exists in more than one file.

When you're displaying DWARF attributes, if a form points at the separate debug info file, the referenced contents get shown too ๐Ÿซง

โš ๏ธ Note: in some distributions this option is on by default. You can turn it off with the N debug option. The default can be picked when configuring binutils with --enable-follow-debug-links=yes or --enable-follow-debug-links=no. If neither is used, following debug links is enabled by default.
โš ๏ธ Note: if debuginfod support was enabled when binutils was built, this option also tries to contact any debuginfod servers listed in the DEBUGINFOD_URLS environment variable ๐ŸŒ That could take a little while to sort out. You can turn this behaviour off with the =do-not-use-debuginfod debug option.
  • "N", "=no-follow-links" โ€” Stops following links to separate debug info files ๐Ÿšซ
  • "D", "=use-debuginfod" โ€” Lets objdump contact debuginfod servers when it needs to follow debug links ๐ŸŒธ This is the default behaviour.
  • "E", "=do-not-use-debuginfod" โ€” Stops objdump from contacting debuginfod servers when it needs to follow debug links ๐Ÿ™…โ€โ™€๏ธ
  • "l", "=rawline" โ€” Displays the .debug_line section in a raw format ๐Ÿ“œ
  • "L", "=decodedline" โ€” Displays the interpreted contents of the .debug_line section ๐Ÿง 
  • "m", "=macro" โ€” Shows the contents of the .debug_macro and/or .debug_macinfo sections ๐Ÿงฉ
  • "o", "=loc" โ€” Shows the contents of the .debug_loc and/or .debug_loclists sections ๐Ÿ“
  • "O", "=str-offsets" โ€” Shows the contents of the .debug_str_offsets section ๐Ÿ”ข
  • "p", "=pubnames" โ€” Shows the contents of the .debug_pubnames and/or .debug_gnu_pubnames sections ๐Ÿท๏ธ
  • "r", "=aranges" โ€” Shows the contents of the .debug_aranges section ๐ŸŒˆ
  • "R", "=Ranges" โ€” Shows the contents of the .debug_ranges and/or .debug_rnglists sections ๐Ÿ›ค๏ธ
  • "s", "=str" โ€” Shows the contents of the .debug_str, .debug_line_str and/or .debug_str_offsets sections ๐Ÿงต
  • "t", "=pubtype" โ€” Shows the contents of the .debug_pubtypes and/or .debug_gnu_pubtypes sections ๐ŸŽ€
  • "T", "=trace_aranges" โ€” Shows the contents of the .trace_aranges section ๐Ÿ›ฐ๏ธ
  • "u", "=trace_abbrev" โ€” Shows the contents of the .trace_abbrev section ๐Ÿ—ƒ๏ธ
  • "U", "=trace_info" โ€” Shows the contents of the .trace_info section ๐Ÿซง
๐Ÿ™ˆ Note: displaying .debug_static_funcs, .debug_static_vars and debug_weaknames sections isn't supported right now, so don't go looking for them.
  • --dwarf-depth=n โ€” Limits the dump of the ".debug_info" section to n children ๐ŸŒณ This only matters with --debug-dump=info. By default every DIE gets printed, and the special value 0 for n does the same thing ๐Ÿ’ซ

With a non-zero n, DIEs at or deeper than n levels won't be printed. The range for n is zero-based ๐Ÿ”ข

  • --dwarf-start=n โ€” Prints only the DIEs starting with the DIE numbered n ๐ŸŽฏ This only matters with --debug-dump=info.

If you specify it, this option suppresses any header information and every DIE before the DIE numbered n. Only the siblings and children of that specified DIE get printed ๐Ÿ‘‘

This can be combined with --dwarf-depth ๐Ÿซถ

  • --dwarf-check โ€” Turns on extra checks for consistency of DWARF information ๐Ÿ•ต๏ธโ€โ™€๏ธโœจ
  • --ctf[=section] โ€” Displays the contents of the specified CTF section ๐Ÿง CTF sections contain lots of subsections, and they all get displayed in order.

By default, it displays the section named .ctf, which is the name ld emits ๐Ÿ’œ

  • --ctf-parent=member โ€” okay so this one's for CTF archives ๐Ÿ—‚๏ธ If the CTF section has ambiguously-defined types, it becomes an archive of a bunch of CTF dictionaries that all inherit from one parent dictionary holding the unambiguous types. By default that member is named .ctf, same as the section holding it, but you can rename it with the "ctf_link_set_memb_name_changer" function at link time. If you're looking at archives made by a linker that renamed the parent member, --ctf-parent lets you tell objdump what name the parent actually uses โœจ
  • --ctf-parent-section=section โ€” this lets you pick a totally different section for the parent dictionary (the one with unambiguous types) than the one for the child dictionaries holding the ambiguous leftovers ๐ŸŒธ The linker never makes ELF objects shaped like this, but some third-party linkers might. It's also handy when you've got CTF dumped out as multiple raw files you want to glue together with objcopy. objcopy can stick them in different ELF sections, but it can't put them in different members of a single CTF dict ๐Ÿงš
  • --sframe[=section] โ€” displays the contents of the SFrame section you name ๐Ÿฆ‹

By default it shows the section called .sframe, which is the name ld uses.

  • -G, --stabs โ€” displays the full contents of whatever sections you asked for. It also shows the .stab, .stab.index and .stab.excl sections from an ELF file. This only really matters on systems like Solaris 2.0, where ".stab" debugging symbol-table entries live in an ELF section. On most other file formats, debugging entries are mixed in with linkage symbols and you'll see them in the --syms output instead ๐Ÿ™ˆ
  • --start-address=address โ€” starts displaying data from the address you give it. This changes what -d, -r and -s print ๐Ÿ“
  • --stop-address=address โ€” stops displaying data at the address you give it. This also changes what -d, -r and -s print ๐Ÿ›‘
  • -t, --syms โ€” prints the symbol table entries of the file. It's kind of like what nm gives you, but the formatting is different ๐Ÿ’… The layout depends on what kind of file you're dumping, but there are two main styles. The first one looks like this:
[  4](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .bss
[  6](sec  1)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 fred

The number in the square brackets is the entry's number in the symbol table. sec is the section number, fl holds the symbol's flag bits, ty is its type, scl is its storage class, and nx is how many auxiliary entries go with the symbol. The last two fields are the symbol's value and its name ๐Ÿ“š

The other common style, usually seen with ELF-based files, looks like this:

00000000 l    d  .bss   00000000 .bss
00000000 g       .text  00000000 fred

The first number is the symbol's value, which people also call its address. Next comes a run of characters and spaces showing which flag bits are set on the symbol. We'll go through those below ๐Ÿ‘€ After that is the section the symbol belongs to. It shows *ABS* (as in `*ABS*`) if the section is absolute, meaning it isn't tied to any section, or *UND* if the symbol is referenced in the file but not defined there.

Then there's a number. For common symbols it's the alignment, and for everything else it's the size. Last of all, the symbol's name gets displayed ๐ŸŽ€

The flag characters come in 7 groups, and they go like this:

  • l, g, u, ! โ€” this group tells you the binding. l means local, g means global, u means unique global, a space means neither global nor local, and ! means both global and local. A symbol can be neither local nor global for plenty of reasons, like being used for debugging, but if it ever ends up both local and global, that's probably a bug ๐Ÿ› Unique global symbols are a GNU extension to the standard ELF symbol bindings. For one of these, the dynamic linker makes sure there's only one symbol with that name and type in use across the whole process ๐Ÿ‘‘
  • w โ€” the symbol is weak (w) or strong (a space) ๐Ÿ’œ
  • C โ€” the symbol is a constructor (C) or an ordinary symbol (a space) โœจ
  • W โ€” the symbol is a warning (W) or a normal symbol (a space). A warning symbol's name is a message that gets shown if the symbol right after the warning symbol ever gets referenced โš ๏ธ
  • I, i โ€” the symbol is an indirect reference to another symbol (I), a function that gets evaluated during relocation processing (i), or a normal symbol (a space) ๐ŸŒˆ
  • d, D โ€” the symbol is a debugging symbol (d), a dynamic symbol (D), or a normal symbol (a space) ๐Ÿ”
  • F, f, O โ€” the symbol is the name of a function (F), a file (f), an object (O), or just a normal symbol (a space) ๐Ÿง
  • -T, --dynamic-syms โ€” prints the dynamic symbol table entries of the file. This is only meaningful for dynamic objects, like certain shared libraries ๐ŸŒ™ It's similar to what nm shows when you give it -D (--dynamic).

The format is close to --syms, except there's an extra field right before the symbol's name that shows the version info tied to the symbol. If that version is the default one used when resolving unversioned references to the symbol, it gets shown as is. Otherwise it goes inside parentheses ๐ŸŽ€

  • --special-syms โ€” when displaying symbols, this includes the ones the target considers special in some way, which normally wouldn't be interesting to you ๐Ÿ”ฎ
  • -U [d|i|l|e|x|h], --unicode=[default|invalid|locale|escape|hex|highlight] โ€” controls how UTF-8 multibyte characters inside strings get displayed ๐ŸŒ The default, --unicode=default, gives them no special treatment. --unicode=locale shows the sequence in your current locale, which may or may not support them. --unicode=hex and --unicode=invalid display them as hex byte sequences wrapped in either angle brackets or curly braces ๐Ÿญ

--unicode=escape shows them as escape sequences like \uxxxx. --unicode=highlight shows the same escape sequences but in red, if your output device supports colour ๐Ÿšจ The colouring is there to draw your eye to unicode sequences that might be showing up where you didn't expect them ๐Ÿ‘€

  • -V, --version โ€” prints objdump's version number and exits ๐Ÿซถ
  • -x, --all-headers โ€” displays all the header info that's available, including the symbol table and relocation entries. Using -x is the same as specifying all of -a -f -h -p -r -t ๐Ÿ’–
  • -w, --wide โ€” formats some lines for output devices with more than 80 columns. It also stops symbol names from being cut short when they're displayed ๐Ÿ“
  • -z, --disassemble-zeroes โ€” normally the disassembly skips blocks of zeroes. This option tells the disassembler to disassemble them too, just like any other data ๐Ÿซง
  • -Z, --decompress โ€” this one is meant to go with -s. It tells objdump to decompress any compressed sections before showing their contents ๐Ÿ—œ๏ธ
  • @file โ€” reads command-line options from file. The options it reads get slotted in right where the @file option was ๐Ÿงฉ If file doesn't exist or can't be read, then @file gets treated literally and doesn't get removed.

Options inside file are separated by whitespace. If you want a whitespace character inside an option, wrap the whole option in single or double quotes. Any character, including a backslash, can be included by putting a backslash in front of it. The file can also have more @file options inside it, and those get processed recursively too ๐ŸŒ€


๐Ÿ”— SEE ALSO ๐Ÿ”—

nm(1), readelf(1), and the Info entries for binutils. Go check those out, bestie ๐Ÿ“–

Copyright (c) 1991-2025 Free Software Foundation, Inc.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation, with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License" ๐Ÿ“œ


That's the whole OBJDUMP(1) glow-up, bestie! binutils 2.45 from December 3rd, 2025, served with love ๐Ÿ’…๐ŸŒˆ๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from