【Linux】GCC程序开发工具(下)
00. 目录
01. GCC的二进制工具
objdump 显示目标文件信息
objcopy 复制目标文件
02. objdump
objdump用于显示一个或者多个目标文件的信息,由其选项来控制显示那些特定的信息。可以通过objdump软件反汇编执行程序,获得执行程序的汇编格式。
objdump用法如下
[email protected]:~$ objdump --help
用法:objdump <选项> <文件>
显示来自目标 <文件> 的信息。
至少必须给出以下选项之一:
-a, --archive-headers 显示头信息
-f, --file-headers 全面显示文件头
-p, --private-headers 显示对象格式指定文件头信息
-P, --private=OPT,OPT... Display object format specific contents
-h, --[section-]headers 显示接头中的内容
-x, --all-headers 显示所有可用到的头信息,包括符号表和重定位入口。
-d, --disassemble 显示目标文件中的机器指令使用的汇编语言。该选项仅仅反汇编那些应该含有指令机器码的节。
-D, --disassemble-all 反汇编所有节的内容
--disassemble=<sym> Display assembler contents from <sym>
-S, --source 尽可能显示与反汇编混合的源代码
--source-comment[=<txt>] Prefix lines of source code with <txt>
-s, --full-contents 显示任何指定节的全部内容
-g, --debugging 显示目标文件调试信息
-e, --debugging-tags 显示目标文件使用ctags格式调试信息
-G, --stabs 显示所有文件中的STABS信息
-W[lLiaprmfFsoRtUuTgAckK] or
--dwarf[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,
=frames-interp,=str,=loc,=Ranges,=pubtypes,
=gdb_index,=trace_info,=trace_abbrev,=trace_aranges,
=addr,=cu_index,=links,=follow-links]
Display DWARF info in the file
--ctf=SECTION Display CTF info from SECTION
-t, --syms 显示符号表内容
-T, --dynamic-syms 显示动态符号表内容
-r, --reloc 显示文件的重定向入口
-R, --dynamic-reloc Display the dynamic relocation entries in the file
@<file> Read options from <file>
-v, --version Display this program's version number
-i, --info List object formats and architectures supported
-H, --help Display this information
以下选项是可选的:
-b, --target=BFDNAME 指定目标对象格式为BFDNAME
-m, --architecture=MACHINE 指定体系结构为MACHINE
-j, --section=NAME 只显示名称为NAME的节信息
-M, --disassembler-options=OPT 反汇编器中通过文本OPT
-EB --endian=big 指定大端格式
-EL --endian=little 指定小端格式
--file-start-context 包含从文件开始的上下文(与-S一起使用)
-I, --include=DIR 增加目录为搜索路径
-l, --line-numbers 在输出中包含行号和文件名
-F, --file-offsets Include file offsets when displaying information
-C, --demangle[=STYLE] 将底层的符号解码位用户层的符号
The STYLE, if specified, can be `auto', `gnu',
`lucid', `arm', `hp', `edg', `gnu-v3', `java'
or `gnat'
--recurse-limit Enable a limit on recursion whilst demangling. [Default]
--no-recurse-limit Disable a limit on recursion whilst demangling
-w, --wide 对超过80列的输出设备指定一些行的格式
-z, --disassemble-zeroes Do not skip blocks of zeroes when disassembling
--start-address=ADDR Only process data whose address is >= ADDR
--stop-address=ADDR Only process data whose address is < ADDR
--prefix-addresses Print complete address alongside disassembly
--[no-]show-raw-insn 在符号反汇编前显示十六进制信息
--insn-width=WIDTH Display WIDTH bytes on a single line for -d
--adjust-vma=OFFSET 在所有节地址前增加OFFSET偏移量
--special-syms 在符号dumps中包含特殊符号
--inlines Print all inlines for source line (with -l)
--prefix=PREFIX Add PREFIX to absolute paths for -S
--prefix-strip=LEVEL Strip initial directory names for -S
--dwarf-depth=N Do not display DIEs at depth N or greater
--dwarf-start=N Display DIEs starting with N, at the same depth
or deeper
--dwarf-check Make additional dwarf internal consistency checks.
--ctf-parent=SECTION Use SECTION as the CTF parent
--visualize-jumps Visualize jumps by drawing ASCII art lines
--visualize-jumps=color Use colors in the ASCII art
--visualize-jumps=extended-color Use extended 8-bit color codes
--visualize-jumps=off Disable jump visualization
objdump:支持的目标: elf64-x86-64 elf32-i386 elf32-iamcu elf32-x86-64 pei-i386 pei-x86-64 elf64-l1om
elf64-k1om elf64-little elf64-big elf32-little elf32-big pe-x86-64 pe-bigobj-x86-64 pe-i386 srec
symbolsrec verilog tekhex binary ihex plugin
objdump:支持的体系结构: i386 i386:x86-64 i386:x64-32 i8086 i386:intel i386:x86-64:intel i386:x64-32:intel
i386:nacl i386:x86-64:nacl i386:x64-32:nacl iamcu iamcu:intel l1om l1om:intel k1om k1om:intel
The following i386/x86-64 specific disassembler options are supported for use
with the -M switch (multiple options should be separated by commas):
x86-64 Disassemble in 64bit mode
i386 Disassemble in 32bit mode
i8086 Disassemble in 16bit mode
att Display instruction in AT&T syntax
intel Display instruction in Intel syntax
att-mnemonic
Display instruction in AT&T mnemonic
intel-mnemonic
Display instruction in Intel mnemonic
addr64 Assume 64bit address size
addr32 Assume 32bit address size
addr16 Assume 16bit address size
data32 Assume 32bit data size
data16 Assume 16bit data size
suffix Always display instruction suffix in AT&T syntax
amd64 Display instruction in AMD64 ISA
intel64 Display instruction in Intel64 ISA
将 bug 报告到 <http://www.sourceware.org/bugzilla/>。
[email protected]:~$
2.1 查看目标文件ELF头信息
[email protected]:~/share/3rd/1static_lib$ objdump -h add.o
add.o: 文件格式 elf64-x86-64
节:
Idx Name Size VMA LMA File off Algn
0 .text 00000018 0000000000000000 0000000000000000 00000040 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000000 0000000000000000 0000000000000000 00000058 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 0000000000000000 0000000000000000 00000058 2**0
ALLOC
3 .comment 00000025 0000000000000000 0000000000000000 00000058 2**0
CONTENTS, READONLY
4 .note.GNU-stack 00000000 0000000000000000 0000000000000000 0000007d 2**0
CONTENTS, READONLY
5 .note.gnu.property 00000020 0000000000000000 0000000000000000 00000080 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .eh_frame 00000038 0000000000000000 0000000000000000 000000a0 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
[email protected]:~/share/3rd/1static_lib$
2.2 查看可执行文件ELF头信息
[email protected]:~/test$ objdump -h a.out
a.out: 文件格式 elf64-x86-64
节:
Idx Name Size VMA LMA File off Algn
0 .interp 0000001c 0000000000000318 0000000000000318 00000318 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.gnu.property 00000020 0000000000000338 0000000000000338 00000338 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.gnu.build-id 00000024 0000000000000358 0000000000000358 00000358 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .note.ABI-tag 00000020 000000000000037c 000000000000037c 0000037c 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .gnu.hash 00000024 00000000000003a0 00000000000003a0 000003a0 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynsym 000000a8 00000000000003c8 00000000000003c8 000003c8 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .dynstr 00000082 0000000000000470 0000000000000470 00000470 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version 0000000e 00000000000004f2 00000000000004f2 000004f2 2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .gnu.version_r 00000020 0000000000000500 0000000000000500 00000500 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rela.dyn 000000c0 0000000000000520 0000000000000520 00000520 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .rela.plt 00000018 00000000000005e0 00000000000005e0 000005e0 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
11 .init 0000001b 0000000000001000 0000000000001000 00001000 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .plt 00000020 0000000000001020 0000000000001020 00001020 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .plt.got 00000010 0000000000001040 0000000000001040 00001040 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .plt.sec 00000010 0000000000001050 0000000000001050 00001050 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
15 .text 00000185 0000000000001060 0000000000001060 00001060 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
16 .fini 0000000d 00000000000011e8 00000000000011e8 000011e8 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
17 .rodata 00000010 0000000000002000 0000000000002000 00002000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
18 .eh_frame_hdr 00000044 0000000000002010 0000000000002010 00002010 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
19 .eh_frame 00000108 0000000000002058 0000000000002058 00002058 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
20 .init_array 00000008 0000000000003db8 0000000000003db8 00002db8 2**3
CONTENTS, ALLOC, LOAD, DATA
21 .fini_array 00000008 0000000000003dc0 0000000000003dc0 00002dc0 2**3
CONTENTS, ALLOC, LOAD, DATA
22 .dynamic 000001f0 0000000000003dc8 0000000000003dc8 00002dc8 2**3
CONTENTS, ALLOC, LOAD, DATA
23 .got 00000048 0000000000003fb8 0000000000003fb8 00002fb8 2**3
CONTENTS, ALLOC, LOAD, DATA
24 .data 00000010 0000000000004000 0000000000004000 00003000 2**3
CONTENTS, ALLOC, LOAD, DATA
25 .bss 00000008 0000000000004010 0000000000004010 00003010 2**0
ALLOC
26 .comment 00000024 0000000000000000 0000000000000000 00003010 2**0
CONTENTS, READONLY
[email protected]:~/test$
2.3 对二进制文件进行反汇编
[email protected]:~/share/3rd/1static_lib$ objdump -D add.o
add.o: 文件格式 elf64-x86-64
Disassembly of section .text:
0000000000000000 <add>:
0: f3 0f 1e fa endbr64
4: 55 push %rbp
5: 48 89 e5 mov %rsp,%rbp
8: 89 7d fc mov %edi,-0x4(%rbp)
b: 89 75 f8 mov %esi,-0x8(%rbp)
e: 8b 55 fc mov -0x4(%rbp),%edx
11: 8b 45 f8 mov -0x8(%rbp),%eax
14: 01 d0 add %edx,%eax
16: 5d pop %rbp
17: c3 retq
Disassembly of section .comment:
0000000000000000 <.comment>:
0: 00 47 43 add %al,0x43(%rdi)
3: 43 3a 20 rex.XB cmp (%r8),%spl
6: 28 55 62 sub %dl,0x62(%rbp)
9: 75 6e jne 79 <add+0x79>
b: 74 75 je 82 <add+0x82>
d: 20 39 and %bh,(%rcx)
f: 2e 33 2e xor %cs:(%rsi),%ebp
12: 30 2d 31 30 75 62 xor %ch,0x62753031(%rip) # 62753049 <add+0x62753049>
18: 75 6e jne 88 <add+0x88>
1a: 74 75 je 91 <add+0x91>
1c: 32 29 xor (%rcx),%ch
1e: 20 39 and %bh,(%rcx)
20: 2e 33 2e xor %cs:(%rsi),%ebp
23: 30 00 xor %al,(%rax)
Disassembly of section .note.gnu.property:
0000000000000000 <.note.gnu.property>:
0: 04 00 add $0x0,%al
2: 00 00 add %al,(%rax)
4: 10 00 adc %al,(%rax)
6: 00 00 add %al,(%rax)
8: 05 00 00 00 47 add $0x47000000,%eax
d: 4e 55 rex.WRX push %rbp
f: 00 02 add %al,(%rdx)
11: 00 00 add %al,(%rax)
13: c0 04 00 00 rolb $0x0,(%rax,%rax,1)
17: 00 03 add %al,(%rbx)
19: 00 00 add %al,(%rax)
1b: 00 00 add %al,(%rax)
1d: 00 00 add %al,(%rax)
...
Disassembly of section .eh_frame:
0000000000000000 <.eh_frame>:
0: 14 00 adc $0x0,%al
2: 00 00 add %al,(%rax)
4: 00 00 add %al,(%rax)
6: 00 00 add %al,(%rax)
8: 01 7a 52 add %edi,0x52(%rdx)
b: 00 01 add %al,(%rcx)
d: 78 10 js 1f <.eh_frame+0x1f>
f: 01 1b add %ebx,(%rbx)
11: 0c 07 or $0x7,%al
13: 08 90 01 00 00 1c or %dl,0x1c000001(%rax)
19: 00 00 add %al,(%rax)
1b: 00 1c 00 add %bl,(%rax,%rax,1)
1e: 00 00 add %al,(%rax)
20: 00 00 add %al,(%rax)
22: 00 00 add %al,(%rax)
24: 18 00 sbb %al,(%rax)
26: 00 00 add %al,(%rax)
28: 00 45 0e add %al,0xe(%rbp)
2b: 10 86 02 43 0d 06 adc %al,0x60d4302(%rsi)
31: 4f 0c 07 rex.WRXB or $0x7,%al
34: 08 00 or %al,(%rax)
...
[email protected]:~/share/3rd/1static_lib$
03. objcopy命令
objcopy工具用于对某种格式的目标文件内容进行转换,输出为另一种格式的目标文件。objcopy使用GNU BFD库读写目标文件,通过这个BFD库,objcopy能够以一种不同与源目标文件的格式来生成目标文件。
objcopy通过访问BFD库中描述的所有格式的目标文件来识别大部分可执行文件的格式。例如,指定"srec"的输出目标格式(使用 -O srec),objcopy就能够生成S-records格式的目标文件。如果指定"binary"的输出目标格式(使用-O binary)。objcopy能够生成原始的二进制文件,即通常所说的image文件。当objcopy生成一个原始的二进制文件时,它必然会产生输入目标文件内容的一个内存信息存储。所有的符号和重定位信息将被丢弃,且内存信息转储将从已经复制到输出文件的最底端的虚拟地址开始。当生成S-record或原始二进制文件时,使用-S有助于objcopy工具取出元文件中包含的调试信息。在某系情况下,-R可以用于去除二进制文件并不需要的信息。
[email protected]:~/share/3rd/1static_lib$ objcopy --help
用法:objcopy [选项] 输入文件 [输出文件]
复制二进制文件,可能在此过程中进行变换
选项为:
-I --input-target <bfdname> 假设输入文件格式为bfdname
-O --output-target <bfdname> 建立格式为bfdname的输出文件
-B --binary-architecture <arch> 当输入为二进制文件的时候,指定输出的架构
-F --target <bfdname> 设定输入和输出文件格式为bdfname
--debugging 如果有可能,转换调试信息
-p --preserve-dates 保留修改 访问输出的时间戳
-D --enable-deterministic-archives
Produce deterministic output when stripping archives (default)
-U --disable-deterministic-archives
Disable -D behavior
-j --only-section <name> 只复制名称为name的节到输出
--add-gnu-debuglink=<file> 增加.gnu_debuglink节连接到<file>
-R --remove-section <name> 从输出中删除名为name的节
--remove-relocations <name> Remove relocations from section <name>
-S --strip-all 不复制源文件中重定位和符号信息
-g --strip-debug 不复制元文件中的调试信息
--strip-dwo Remove all DWO sections
--strip-unneeded Remove all symbols not needed by relocations
-N --strip-symbol <name> 不复制符号<name>
--strip-unneeded-symbol <name>
取出重定位处理不需要的所有符号
--only-keep-debug 只保留调试符号
--extract-dwo Copy only DWO sections
--extract-symbol Remove section contents but keep symbols
--keep-section <name> Do not strip section <name>
-K --keep-symbol <name> Do not strip symbol <name>
--keep-file-symbols Do not strip file symbol(s)
--localize-hidden Turn all ELF hidden symbols into locals
-L --localize-symbol <name> 强制符号name定义为局部的
--globalize-symbol <name> Force symbol <name> to be marked as a global
-G --keep-global-symbol <name> 除了名称为name的符号,其它符号局部化
-W --weaken-symbol <name> Force symbol <name> to be marked as a weak
--weaken 弱化文件中所有全局符号
-w --wildcard 允许在符号比较中使用通配符
-x --discard-all 不从源文件中复制非全局符号
-X --discard-locals 不复制编译器生成的局部符号
-i --interleave[=<number>] 只从number个字节中复制一份
--interleave-width <number> Set N for --interleave
-b --byte <num> Select byte <num> in every interleaved block
--gap-fill <val> Fill gaps between sections with <val>
--pad-to <addr> Pad the last section up to address <addr>
--set-start <addr> Set the start address to <addr>
{--change-start|--adjust-start} <incr>
Add <incr> to the start address
{--change-addresses|--adjust-vma} <incr>
Add <incr> to LMA, VMA and start addresses
{--change-section-address|--adjust-section-vma} <name>{=|+|-}<val>
Change LMA and VMA of section <name> by <val>
--change-section-lma <name>{=|+|-}<val>
Change the LMA of section <name> by <val>
--change-section-vma <name>{=|+|-}<val>
Change the VMA of section <name> by <val>
{--[no-]change-warnings|--[no-]adjust-warnings}
Warn if a named section does not exist
--set-section-flags <name>=<flags>
Set section <name>'s properties to <flags>
--set-section-alignment <name>=<align>
Set section <name>'s alignment to <align> bytes
--add-section <name>=<file> Add section <name> found in <file> to output
--update-section <name>=<file>
Update contents of section <name> with
contents found in <file>
--dump-section <name>=<file> Dump the contents of section <name> into <file>
--rename-section <old>=<new>[,<flags>] Rename section <old> to <new>
--long-section-names {enable|disable|keep}
Handle long section names in Coff objects.
--change-leading-char Force output format's leading character style
--remove-leading-char Remove leading character from global symbols
--reverse-bytes=<num> Reverse <num> bytes at a time, in output sections with content
--redefine-sym <old>=<new> Redefine symbol name <old> to <new>
--redefine-syms <file> --redefine-sym for all symbol pairs
listed in <file>
--srec-len <number> Restrict the length of generated Srecords
--srec-forceS3 Restrict the type of generated Srecords to S3
--strip-symbols <file> -N for all symbols listed in <file>
--strip-unneeded-symbols <file>
--strip-unneeded-symbol for all symbols listed
in <file>
--keep-symbols <file> -K for all symbols listed in <file>
--localize-symbols <file> -L for all symbols listed in <file>
--globalize-symbols <file> --globalize-symbol for all in <file>
--keep-global-symbols <file> -G for all symbols listed in <file>
--weaken-symbols <file> -W for all symbols listed in <file>
--add-symbol <name>=[<section>:]<value>[,<flags>] Add a symbol
--alt-machine-code <index> Use the target's <index>'th alternative machine
--writable-text Mark the output text as writable
--readonly-text Make the output text write protected
--pure Mark the output file as demand paged
--impure Mark the output file as impure
--prefix-symbols <prefix> Add <prefix> to start of every symbol name
--prefix-sections <prefix> Add <prefix> to start of every section name
--prefix-alloc-sections <prefix>
Add <prefix> to start of every allocatable
section name
--file-alignment <num> Set PE file alignment to <num>
--heap <reserve>[,<commit>] Set PE reserve/commit heap to <reserve>/
<commit>
--image-base <address> Set PE image base to <address>
--section-alignment <num> Set PE section alignment to <num>
--stack <reserve>[,<commit>] Set PE reserve/commit stack to <reserve>/
<commit>
--subsystem <name>[:<version>]
Set PE subsystem to <name> [& <version>]
--compress-debug-sections[={none|zlib|zlib-gnu|zlib-gabi}]
Compress DWARF debug sections using zlib
--decompress-debug-sections Decompress DWARF debug sections using zlib
--elf-stt-common=[yes|no] Generate ELF common symbols with STT_COMMON
type
--verilog-data-width <number> Specifies data width, in bytes, for verilog output
-M --merge-notes Remove redundant entries in note sections
--no-merge-notes Do not attempt to remove redundant notes (default)
-v --verbose List all object files modified
@<file> Read options from <file>
-V --version Display this program's version number
-h --help Display this output
--info List object formats & architectures supported
objcopy:支持的目标: elf64-x86-64 elf32-i386 elf32-iamcu elf32-x86-64 pei-i386 pei-x86-64 elf64-l1om elf64-k1om
elf64-little elf64-big elf32-little elf32-big pe-x86-64 pe-bigobj-x86-64 pe-i386 srec symbolsrec verilog tekhex
binary ihex plugin
将 bug 报告到 <http://www.sourceware.org/bugzilla/>
[email protected]:~/share/3rd/1static_lib$
3.1 生成纯二进制文件
[email protected]:~/test$ gcc test.c -o test
[email protected]:~/test$ objcopy test -O binary test_bindata
# 仅包含机器码和数据
[email protected]:~/test$ file test_bindata
test_bindata: data
[email protected]:~/test$
3.2 生成S-record格式的文件
[email protected]:~/test$ objcopy test -O srec test_srec
[email protected]:~/test$ file test_srec
test_srec: Motorola S-Record; binary data in text format
[email protected]:~/test$
3.3 更改部分输出文件的信息
# -S选项表示不复制重定位和符号信息 生成去掉符号后的可执行文件 与strip类似
[email protected]:~/test$ objcopy test -S test_stripped
[email protected]:~/test$ nm test_stripped
nm: test_stripped:无符号
[email protected]:~/test$
3.4 指定要删除的段
# 删除了数据段的可执行文件
[email protected]:~/test$ objcopy test -R .data test_removed
[email protected]:~/test$ ./test_removed
hello world
[email protected]:~/test$
3.5 应用示例
#include <stdio.h>
int bss_arrary[1024 * 1024] = {0};
int main(void)
{
printf("hello world\n");
return 0;
}
编译之后的代码
[email protected]:~/test$ gcc test.c -o test
[email protected]:~/test$ size test
text data bss dec hex filename
1565 600 4194336 4196501 400895 test
[email protected]:~/test$
[email protected]:~/test$ ls -lh test
-rwxrwxr-x 1 deng deng 17K 6月 18 22:31 test
[email protected]:~/test$
# 使用strip去掉符号
[email protected]:~/test$ strip test -o test_strip
[email protected]:~/test$ ls -lh test test_strip
-rwxrwxr-x 1 deng deng 17K 6月 18 22:31 test
-rwxrwxr-x 1 deng deng 15K 6月 18 22:32 test_strip
[email protected]:~/test$
[email protected]:~/test$ objcopy -R .comment -R .note.ABI-tag -R .gnu.version test test1
[email protected]:~/test$ ls -lh test test1
-rwxrwxr-x 1 deng deng 17K 6月 18 22:31 test
-rwxrwxr-x 1 deng deng 16K 6月 18 22:34 test1
[email protected]:~/test$
04. 总结
GCC二进制工具中,ar用于生成归档文件,readelf、string、nm、objdump属于信息获取工具,strip、objcopy属于目标文件转换工具。
05. 附录
5.1 【Linux】GCC程序开发工具(上)
5.2 【Linux】GCC程序开发工具(中)
5.3 【Linux】GCC程序开发工具(下)
上一篇: Rtsp支持Scale的抓包
下一篇: YUV格式大全