我们介绍过linux中的readelf命令, 但迟迟没有介绍objdump命令, 因为其实后者可以看作是前者的子集, 我们来看看官方文档怎么说:
/* The difference between readelf and objdump:
Both programs are capable of displaying the contents of ELF format files,
so why does the binutils project have two file dumpers ?
The reason is that objdump sees an ELF file through a BFD filter of the
world; if BFD has a bug where, say, it disagrees about a machine constant
in e_flags, then the odds are good that it will remain internally
consistent. The linker sees it the BFD way, objdump sees it the BFD way,
GAS sees it the BFD way. There was need for a tool to Go find out what
the file actually says.
This is why the readelf program does not link against the BFD library - it
exists as an independent program to help verify the correct working of BFD.
There is also the case that readelf can provide more information about an
ELF file than is provided by objdump. In particular it can display DWARF
debugging information which (at the moment) objdump cannot. */
可见, readelf比objdump更强大, 想了解objdump的朋友, 可以man objdump或者objdump --help来玩。
要说明的是, objdump可不仅仅是针对object目标文件哦, 它可以针对任何ELF文件。
最后,来看看objdump命令的反汇编功能:
ubuntu@VM-0-15-ubuntu:~$ man objdump
OBJDUMP(1) GNU Development Tools OBJDUMP(1)
NAME
objdump - display information from object files.
SYNOPSIS
objdump [-a|--archive-headers]
[-b bfdname|--target=bfdname]
[-C|--demangle[=style] ]
[-d|--disassemble]
[-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]
[-m machine|--architecture=machine]
[-M options|--disassembler-options=options]
[-p|--private-headers]
[-P options|--private=options]
[-r|--reloc]
[-R|--dynamic-reloc]
[-s|--full-contents]
[-W[lLiaprmfFsoRt]|
--dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames]
[=aranges,=macro,=frames,=frames-interp,=str,=loc]
[=Ranges,=pubtypes,=trace_info,=trace_abbrev]
[=trace_aranges,=gdb_index]
[-G|--stabs]
[-t|--syms]
[-T|--dynamic-syms]
[-x|--all-headers]
[-w|--wide]
[--start-address=address]
[--stop-address=address]
来看看:
ubuntu@VM-0-15-ubuntu:~$ ./hello
hello, world!
ubuntu@VM-0-15-ubuntu:~$
ubuntu@VM-0-15-ubuntu:~$
ubuntu@VM-0-15-ubuntu:~$ objdump -d hello
hello: file format elf64-x86-64
Disassembly of section .text:
00000000004000b0 <_start>:
4000b0: b8 01 00 00 00 mov $0x1,%eax
4000b5: bf 01 00 00 00 mov $0x1,%edi
4000ba: 48 be d8 00 60 00 00 movabs $0x6000d8,%rsi
4000c1: 00 00 00
4000c4: ba 0e 00 00 00 mov $0xe,%edx
4000c9: 0f 05 syscall
4000cb: b8 3c 00 00 00 mov $0x3c,%eax
4000d0: 48 31 ff xor %rdi,%rdi
4000d3: 0f 05 syscall
ubuntu@VM-0-15-ubuntu:~$
ubuntu@VM-0-15-ubuntu:~$
ubuntu@VM-0-15-ubuntu:~$
ubuntu@VM-0-15-ubuntu:~$ objdump -d -M intel hello
hello: file format elf64-x86-64
Disassembly of section .text:
00000000004000b0 <_start>:
4000b0: b8 01 00 00 00 mov eax,0x1
4000b5: bf 01 00 00 00 mov edi,0x1
4000ba: 48 be d8 00 60 00 00 movabs rsi,0x6000d8
4000c1: 00 00 00
4000c4: ba 0e 00 00 00 mov edx,0xe
4000c9: 0f 05 syscall
4000cb: b8 3c 00 00 00 mov eax,0x3c
4000d0: 48 31 ff xor rdi,rdi
4000d3: 0f 05 syscall
ubuntu@VM-0-15-ubuntu:~$
可以看到, linux上默认的是AT&T规范, 加了 -M intel后,可以转为Intel规范(我个人更喜欢这种规范)。