gcc命令之-objdump
objdump参数
![objdump参数](https://img.taocdn.com/s3/m/eba7b6fb370cba1aa8114431b90d6c85ed3a8854.png)
objdump参数Objdump 是一个非常强大的调试工具,它可以分析可执行文件与目标文件里的所有符号、展开指令、调用堆栈信息等等,以便进行调试。
它的作用在于检验二进制文件是否正确,可以在调试时拓展二进制文件的可读性和可视性。
在本篇文章中,我们将会详细探讨 objdump 常见的参数、含义及使用方法。
## objdump 的基础参数objdump 命令的通用语法如下:```bash objdump 选项文件名 ```其中,选项可以是 objdump 的不同参数选项。
下面是 objdump 常见的参数:### -d- 可读性高的反汇编代码 - 可读性非常高,指令的每个部分都会有注释解释作用使用示例:```bash objdump -d demo # 查看 demo 可执行文件的反汇编代码 ```### -x- 打印出头信息 - 打印可执行文件的文件头、程序头、段表,以及段的详细信息使用示例:```bash objdump -x demo # 查看 demo 可执行文件的头信息 ```### -D- 可读性高的反汇编代码 - 与 -d 差别在于是否显示符号信息使用示例:```bash objdump -D demo # 查看 demo 可执行文件的反汇编代码及符号信息 ```### -f- 可以输出一些文件的格式 - 显示可执行文件的文件格式以及其他相关信息,例如 ELF 元素头信息、处理器架构等等使用示例:```bash objdump -f demo # 查看 demo 可执行文件的格式信息 ```### -s- 可以展示文件的所有段信息 - 显示可执行文件的段信息,例如代码段、数据段、bss 段等等使用示例:```bash objdump -s demo # 查看 demo 可执行文件的段信息 ```### -t- 查看文件的符号表 - 显示可执行文件中的所有符号信息,包括函数名、局部变量名、全局变量名等等使用示例:```bash objdump -t demo # 查看 demo 可执行文件的符号表 ```### -G- 可以输出动态符号的信息 - 显示可执行文件的动态符号信息,包括函数名、局部变量名、全局变量名等等使用示例:```bash objdump -G demo # 查看 demo 可执行文件的动态符号表 ```### -g- 显示所有符号信息,包括调试符号 - 显示可执行文件中的所有符号信息,包括调试符号,例如调试符号信息、函数参数、本地变量使用示例:```bash objdump -g demo # 查看 demo 可执行文件的所有符号表 ```### -j- 选择指定的节 - 查看指定节的反汇编代码,只能在ELF 文件中执行使用示例:```bash objdump -j .text demo # 查看 demo 可执行文件中的 `.text` 节反汇编代码 ```## 关于 objdump 的其他参数在 objdump 命令中还有许多其它参数。
objdump与readelf
![objdump与readelf](https://img.taocdn.com/s3/m/74f2c10914791711cc7917fa.png)
objdump与readelf对比objdump与readelfobjdump和readelf都可以用来查看二进制文件的一些内部信息. 区别在于objdump借助BFD而更加通用一些, 可以应付不同文件格式, readelf 则并不借助BFD,而是直接读取ELF格式文件的信息, 按readelf手册页上所说, 得到的信息也略细致一些.几个功能对比. 1. 反汇编代码查看源代码被翻译成的汇编代码, 大概有3种方法,1) 通过编译器直接从源文件生成, 如gcc -S2) 对目标代码反汇编, 一种是静态反汇编, 就是使用objdump3) 另外一种就是对运行时的代码反汇编, 一般通过gdbreadelf并不提供反汇编功能. objdump可以指定反汇编哪个节, 一般只有对包含指令的节反汇编才有意义. 而对于一些其他的类型的节, objdump也可以将特殊节的数据以解析后的形式呈现出来,例如对于.plt, 输出如下: [qtl@courier lib]$ objdump -d -j .plt libfoobar.so libfoobar.so: file formatelf32-i386Disassembly of section .plt:000003a4<__gmon_start__@plt-0x10>:3a4: ff b3 04 00 00 00 pushl 0x4(%ebx)3aa: ff a3 08 00 00 00 jmp *0x8(%ebx)3b0: 00 00 add %al,(%eax)...000003b4 <__gmon_start__@plt>:3b4: ff a3 0c 00 00 00 jmp *0xc(%ebx)3ba: 68 00 00 00 00 push $0x03bf: e9 e0 ff ff ff jmp 3a4<_init+0x18>000003c4 <cos@plt>:3c4: ff a3 10 00 00 00 jmp *0x10(%ebx) 3ca: 68 08 00 00 00 push $0x83cf: e9 d0 ff ff ff jmp 3a4<_init+0x18>000003d4 <fwrite@plt>:3d4: ff a3 14 00 00 00 jmp *0x14(%ebx) 3da: 68 10 00 00 00 push $0x103df: e9 c0 ff ff ff jmp 3a4<_init+0x18>000003e4 <fprintf@plt>:3e4: ff a3 18 00 00 00 jmp *0x18(%ebx) 3ea: 68 18 00 00 00 push $0x183ef: e9 b0 ff ff ff jmp 3a4<_init+0x18>000003f4 <__cxa_finalize@plt>:3f4: ff a3 1c 00 00 00 jmp *0x1c(%ebx)3fa: 68 20 00 00 00 push $0x203ff: e9 a0 ff ff ff jmp 3a4<_init+0x18>2. 显示relocation节的条目-r参数显示elf文件的类型为REL的节的信息, 使用-S参数可以列出elf文件的所有节的信息, 其中也就包括了REL节. 对于可重定位文件两者显示条目一致, 最重要的offset和type以及 都有.下面是两者输出的对比. [qtl@courier lib]$ readelf -r bar.o Relocation section '.rel.text' at offset 0x4bc contains 6 entries:Offset Info Type Sym.Value Sym.Name00000008 00000b02 R_386_PC32 00000000 __i686.get_pc_thunk.bx0000000e 00000c0a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_00000025 00000d04 R_386_PLT32 00000000 cos0000002e 00000e03 R_386_GOT32 00000000 stdout00000044 00000509 R_386_GOTOFF00000000 .rodata00000050 00000f04 R_386_PLT32 00000000 fprintf[qtl@courier lib]$ objdump -r bar.o bar.o: file format elf32-i386RELOCATION RECORDS FOR [.text]:OFFSET TYPE VALUE00000008 R_386_PC32 __i686.get_pc_thunk.bx0000000e R_386_GOTPC_GLOBAL_OFFSET_TABLE_00000025 R_386_PLT32 cos0000002e R_386_GOT32 stdout00000044 R_386_GOTOFF .rodata00000050 R_386_PLT32 fprintf对于共享库,[qtl@courier lib]$ readelf -r libfoobar.so Relocation section '.rel.dyn' at offset 0x334 contains 6 entries:Offset Info Type Sym.Value Sym. Name00001608 00000008 R_386_RELATIVE00001704 00000008 R_386_RELATIVE000016d4 00000106 R_386_GLOB_DAT 00000000 __gmon_start__000016d8 00000206 R_386_GLOB_DAT 00000000 _Jv_RegisterClasses000016dc 00000606 R_386_GLOB_DAT 00000000 stdout000016e0 00000706 R_386_GLOB_DAT 00000000 __cxa_finalizeRelocation section '.rel.plt' at offset 0x364 contains 5 entries:Offset Info Type Sym.Value Sym. Name000016f0 00000107 R_386_JUMP_SLOT 00000000 __gmon_start__000016f4 00000307 R_386_JUMP_SLOT 00000000 cos000016f8 00000407 R_386_JUMP_SLOT 00000000 fwrite000016fc 00000507 R_386_JUMP_SLOT 00000000 fprintf00001700 00000707 R_386_JUMP_SLOT 00000000 __cxa_finalize[qtl@courier lib]$ objdump -R libfoobar.so libfoobar.so: file format elf32-i386DYNAMIC RELOCATION RECORDSOFFSET TYPE VALUE00001608 R_386_RELATIVE *ABS*00001704 R_386_RELATIVE *ABS*000016d4 R_386_GLOB_DAT __gmon_start__000016d8 R_386_GLOB_DAT _Jv_RegisterClasses000016dc R_386_GLOB_DAT stdout000016e0 R_386_GLOB_DAT __cxa_finalize000016f0 R_386_JUMP_SLOT __gmon_start__000016f4 R_386_JUMP_SLOT cos000016f8 R_386_JUMP_SLOT fwrite000016fc R_386_JUMP_SLOT fprintf00001700 R_386_JUMP_SLOT __cxa_finalize有上面可以看出, readelf的显示分节, 而objdump则将两个节合在一起. readelf的显示更加清晰一些. 3. 显示动态重定位条目(或者可以认为是动态链接相关的重定位条目)(按objdump的man page说明, 只对dynamic object有效, 如某些类型的共享库)readelf和objdump等价的命令为readelf -D -r file和objdump -R file. 对readelf使用-r和-D -r的区别, 对于共享库在于数据的呈现方式略有不同. 这两种都将数据解析后呈现出来. 前者显示的是相对于基地址的偏移, 后者则显示绝对偏移量.前者显示条目数, 后者显示字节数. 两者输出对比:[qtl@courier lib]$ readelf -D -r libfoobar.so 'REL' relocation section at offset 0x334 contains 48 bytes:Offset Info Type Sym.Value Sym. Name00001608 00000008 R_386_RELATIVE00001704 00000008 R_386_RELATIVE000016d4 00000106 R_386_GLOB_DAT 00000000 __gmon_start__000016d8 00000206 R_386_GLOB_DAT 00000000 _Jv_RegisterClasses000016dc 00000606 R_386_GLOB_DAT 00000000 stdout000016e0 00000706 R_386_GLOB_DAT 00000000 __cxa_finalize'PLT' relocation section at offset 0x364 contains 40 bytes:Offset Info Type Sym.Value Sym. Name000016f0 00000107 R_386_JUMP_SLOT 00000000 __gmon_start__000016f4 00000307 R_386_JUMP_SLOT 00000000 cos000016f8 00000407 R_386_JUMP_SLOT 00000000 fwrite000016fc 00000507 R_386_JUMP_SLOT 00000000 fprintf00001700 00000707 R_386_JUMP_SLOT 00000000 __cxa_finalize[qtl@courier lib]$ objdump -R libfoobar.so libfoobar.so: file format elf32-i386DYNAMIC RELOCATION RECORDSOFFSET TYPE VALUE00001608 R_386_RELATIVE *ABS*00001704R_386_RELATIVE *ABS*000016d4 R_386_GLOB_DAT __gmon_start__000016d8 R_386_GLOB_DAT _Jv_RegisterClasses000016dc R_386_GLOB_DAT stdout000016e0 R_386_GLOB_DAT __cxa_finalize000016f0 R_386_JUMP_SLOT __gmon_start__000016f4 R_386_JUMP_SLOT cos000016f8 R_386_JUMP_SLOT fwrite000016fc R_386_JUMP_SLOT fprintf00001700 R_386_JUMP_SLOT __cxa_finalize另外有必要说明的是如果对可重定位文件(.o文件)应用这两个命令是无效的,错误提示如下:[qtl@courier lib]$ readelf -D -r bar.oThere are no dynamic relocations in this file.[qtl@courier lib]$ objdump -Rbar.obar.o: file format elf32-i386objdump: bar.o: not a dynamic objectobjdump: bar.o: Invalid operation4. 显示节信息: readelf -S 和objdump -h对于可重定位文件, objdump -h不能显示.rel开头的节和.shstrtab, .symtab, .strtab.而readelf的显示有一个.group节, 其内容为节的group, 可以用-g参数查看.输出如下:[qtl@courier lib]$ readelf -S bar.oThere are 13 section headers, starting at offset0x150:Section Headers:[Nr] Name Type AddrOff Size ES Flg Lk Inf Al[ 0] NULL 00000000 000000 000000 00 0 0 0[ 1] .group GROUP 00000000 000034 000008 04 11 11 4[ 2] .text PROGBITS 0000000000003c 00005c 00 AX 0 0 4[ 3] .rel.text REL 00000000 0004bc 000030 08 11 2 4[ 4] .data PROGBITS 00000000 000098 000000 00 WA 0 0 4[ 5] .bss NOBITS 00000000 000098 000000 00 WA 0 0 4[ 6] .rodata PROGBITS 00000000 000098 00000e 00 A 0 0 1[ 7] .comment PROGBITS 00000000 0000a6 00002e 00 0 0 1[ 8] .text.__i686.get_ PROGBITS 00000000 0000d4 000004 00 AXG 0 0 1[ 9] .note.GNU-stack PROGBITS 00000000 0000d8 000000 00 0 0 1[10] .shstrtab STRTAB 00000000 0000d8 000075 00 0 0 1[11] .symtab SYMTAB 00000000 000358 000110 10 12 10 4[12] .strtab STRTAB 00000000 000468 000053 00 0 0 1Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings)I (info), L (link order), G (group), x (unknown)O (extra OS processing required) o (OS specific), p (processor specific)[qtl@courier lib]$ objdump -hbar.obar.o: file format elf32-i386Sections:Idx Name Size VMA LMAFile off Algn0 __i686.get_pc_thunk.bx 00000008 00000000 00000000 00000034 2**2CONTENTS, READONLY, EXCLUDE, GROUP, LINK_ONCE_DISCARD1 .text 0000005c 00000000 00000000 0000003c 2**2CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE2 .data 00000000 00000000 00000000 00000098 2**2CONTENTS, ALLOC, LOAD, DATA3 .bss 00000000 00000000 00000000 00000098 2**2ALLOC4 .rodata 0000000e 00000000 00000000 00000098 2**0CONTENTS, ALLOC, LOAD, READONLY, DATA5 .comment 0000002e 00000000 00000000 000000a6 2**0CONTENTS, READONLY6 .text.__i686.get_pc_thunk.bx 00000004 00000000 00000000 000000d4 2**0CONTENTS, ALLOC, LOAD, READONLY, CODE7 .note.GNU-stack 00000000 00000000 00000000 000000d8 2**0CONTENTS, READONLY对于共享库,objdump -h仍然不能显示.shstrtab, .symtab, .strtab三个节, 另外还有一个区别在于readelf从一个NULL类型的节开始, 而objdump的输出去掉了这个空的节.[qtl@courier lib]$ readelf -S libfoobar.soThere are 27 section headers, starting at offset0x8f0:Section Headers:[Nr] Name Type AddrOff Size ES Flg Lk Inf Al[ 0] NULL 00000000 000000 000000 00 0 0 0[ 1] .gnu.hash GNU_HASH 000000b4 0000b4 000048 04 A 2 0 4[ 2] .dynsym DYNSYM 000000fc 0000fc 000110 10 A 3 1 4[ 3] .dynstr STRTAB 0000020c 00020c 0000b3 00 A 0 0 1[ 4] .gnu.version VERSYM 000002c0 0002c0 000022 02 A 2 0 2[ 5] .gnu.version_r VERNEED 000002e4 0002e4 000050 00 A 3 2 4[ 6] .rel.dyn REL 00000334 000334 000030 08 A 2 0 4[ 7] .rel.plt REL 00000364 000364 000028 08 A 2 9 4[ 8] .init PROGBITS 0000038c 00038c 000017 00 AX 0 0 4[ 9] .plt PROGBITS 000003a4 0003a4 000060 04 AX 0 0 4[10] .text PROGBITS 00000410 000410 0001a4 00 AX 0 0 16[11] .fini PROGBITS 000005b4 0005b4 00001c 00 AX 0 0 4[12] .rodata PROGBITS 000005d0 0005d0 00001d 00 A 0 0 1[13] .eh_frame PROGBITS 000005f0 0005f0 000004 00 A 0 0 4[14] .ctors PROGBITS 000015f4 0005f4 000008 00 WA 0 0 4[15] .dtors PROGBITS 000015fc 0005fc 000008 00 WA 0 0 4[16] .jcr PROGBITS 00001604 000604 000004 00 WA 0 0 4[17] .data.rel.ro PROGBITS 00001608000608 000004 00 WA 0 0 4[18] .dynamic DYNAMIC 0000160c 00060c 0000c8 08 WA 3 0 4[19] .got PROGBITS 000016d4 0006d4 000010 04 WA 0 0 4[20] .got.plt PROGBITS 000016e4 0006e4 000020 04 WA 0 0 4[21] .data PROGBITS 00001704 000704 000004 00 WA 0 0 4[22] .bss NOBITS 00001708 000708 000010 00 WA 0 0 4[23] .comment PROGBITS 00000000 000708 000114 00 0 0 1[24] .shstrtab STRTAB 00000000 00081c 0000d2 00 0 0 1[25] .symtab SYMTAB 00000000 000d28 0003d0 10 26 45 4[26] .strtab STRTAB 00000000 0010f8 0001d7 00 0 0 1Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings)I (info), L (link order), G (group), x (unknown)O (extra OS processing required) o (OS specific), p (processor specific)[qtl@courier lib]$ objdump -h libfoobar.so libfoobar.so: file formatelf32-i386Sections:Idx Name Size VMA LMAFile off Algn0 .gnu.hash 00000048 000000b4 000000b4000000b4 2**2CONTENTS, ALLOC, LOAD, READONLY, DATA1 .dynsym 00000110 000000fc 000000fc 000000fc 2**2CONTENTS, ALLOC, LOAD, READONLY, DATA2 .dynstr 000000b3 0000020c 0000020c 0000020c 2**0CONTENTS, ALLOC, LOAD, READONLY, DATA3 .gnu.version 00000022 000002c0 000002c0 000002c0 2**1CONTENTS, ALLOC, LOAD, READONLY, DATA4 .gnu.version_r 00000050 000002e4 000002e4 000002e4 2**2CONTENTS, ALLOC, LOAD, READONLY, DATA5 .rel.dyn 00000030 00000334 00000334 00000334 2**2CONTENTS, ALLOC, LOAD, READONLY, DATA6 .rel.plt 00000028 00000364 00000364 00000364 2**2CONTENTS, ALLOC, LOAD, READONLY, DATA7 .init 00000017 0000038c 0000038c 0000038c 2**2CONTENTS, ALLOC, LOAD, READONLY, CODE8 .plt 00000060 000003a4 000003a4 000003a4 2**2CONTENTS, ALLOC, LOAD, READONLY, CODE9 .text 000001a4 00000410 00000410 00000410 2**4CONTENTS, ALLOC, LOAD, READONLY, CODE10 .fini 0000001c 000005b4 000005b4 000005b4 2**2CONTENTS, ALLOC, LOAD, READONLY, CODE11 .rodata 0000001d 000005d0 000005d0CONTENTS, ALLOC, LOAD, READONLY, DATA12 .eh_frame 00000004 000005f0 000005f0 000005f0 2**2CONTENTS, ALLOC, LOAD, READONLY, DATA13 .ctors 00000008 000015f4 000015f4 000005f4 2**2CONTENTS, ALLOC, LOAD, DATA14 .dtors 00000008 000015fc 000015fc 000005fc 2**2CONTENTS, ALLOC, LOAD, DATA15 .jcr 00000004 00001604 00001604CONTENTS, ALLOC, LOAD, DATA16 .data.rel.ro 00000004 00001608 00001608 00000608 2**2CONTENTS, ALLOC, LOAD, DATA17 .dynamic 000000c8 0000160c 0000160c 0000060c 2**2CONTENTS, ALLOC, LOAD, DATA18 .got 00000010 000016d4 000016d4 000006d4 2**2CONTENTS, ALLOC, LOAD, DATA19 .got.plt 00000020 000016e4 000016e4 000006e4 2**2CONTENTS, ALLOC, LOAD, DATA20 .data 00000004 00001704 00001704 00000704 2**2CONTENTS, ALLOC, LOAD, DATA21 .bss 00000010 00001708 00001708 00000708 2**2ALLOC22 .comment 00000114 00000000 00000000 00000708 2**0CONTENTS, READONLY5. 显示.dynamic节信息只readelf -d有对应的功能, objdump没有. 另外需要注意, 看重定位文件不需要动态链接(加载), 所以没有.dynamic节. 对于共享库文件输出如下: [qtl@courier lib]$ readelf -d libfoobar.so Dynamic section at offset 0x60c contains 21 entries:Tag TypeName/Value0x00000001 (NEEDED) Shared library: [libm.so.6]0x00000001 (NEEDED) Shared library: [libc.so.6]0x0000000c (INIT) 0x38c0x0000000d (FINI) 0x5b40x6ffffef5 (GNU_HASH) 0xb40x00000005 (STRTAB) 0x20c0x00000006 (SYMTAB) 0xfc0x0000000a (STRSZ) 179 (bytes)0x0000000b (SYMENT) 16 (bytes)0x00000003 (PLTGOT) 0x16e40x00000002 (PLTRELSZ) 40 (bytes)0x00000014 (PLTREL) REL0x00000017 (JMPREL) 0x3640x00000011 (REL) 0x3340x00000012 (RELSZ) 48 (bytes)0x00000013 (RELENT) 8 (bytes)0x6ffffffe (VERNEED) 0x2e40x6fffffff (VERNEEDNUM) 20x6ffffff0 (VERSYM) 0x2c00x6ffffffa (RELCOUNT) 20x00000000 (NULL) 0x06. 显示程序段信息第二个readelf支持而objdump没有的功能. 命令参数为readelf -l.同样, 对于可重定位文件而言没有段. 这一点也可以从ELF 头中看到, 命令为readelf -h. [qtl@courier lib]$ readelf -l libfoobar.so Elf file type is DYN (Shared object file)Entry point 0x410There are 4 program headers, starting at offset 52Program Headers:Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg AlignLOAD 0x000000 0x00000000 0x00000000 0x005f4 0x005f4 R E 0x1000LOAD 0x0005f4 0x000015f4 0x000015f4 0x00114 0x00124 RW 0x1000DYNAMIC 0x00060c 0x0000160c 0x0000160c 0x000c8 0x000c8 RW 0x4GNU_STACK 0x000000 0x000000000x00000000 0x00000 0x00000 RW 0x4 Section to Segment mapping:Segment Sections...00 .gnu.hash .dynsym .dynstr .gnu.version .gnu.versi on_r .rel.dyn.rel.plt .init .plt .text .fini .rodata .eh_frame01 .ctors .dtors .jcr .data.rel.ro .dynamic .got .got.plt . data .bss02 .dynamic03 7. 以字节(HEX或字符)形式dump某节的内容readelf -x <secname>objdump -s后者默认一次dump所有节的内容. 如果只想dump某节的内容, 则用-j <secname>参数指定. readelf一次只能dump某一节的内容. 两者输出如下: [qtl@courier lib]$ readelf -x .dynamic libfoobar.so Hex dump of section '.dynamic':0x0000160c 0000007b 00000001 00000071 00000001 ....q.......{...0x0000161c 000005b4 0000000d 0000038c0000000c ................0x0000162c 0000020c 00000005 000000b4 6ffffef5 ...o............0x0000163c 000000b3 0000000a 000000fc 00000006 ................0x0000164c 000016e4 00000003 00000010 0000000b ................0x0000165c 00000011 00000014 00000028 00000002 ....(...........0x0000166c 00000334 00000011 00000364 00000017 ....d.......4...0x0000167c 00000008 00000013 00000030 00000012 ....0...........0x0000168c 00000002 6fffffff 000002e46ffffffe ...o.......o....0x0000169c 00000002 6ffffffa 000002c06ffffff0 ...o.......o....0x000016ac 00000000 00000000 00000000 00000000 ................0x000016bc 00000000 00000000 00000000 00000000 ................0x000016cc 0000000000000000 ........[qtl@courier lib]$ objdump -s -j .dynamic libfoobar.so libfoobar.so: file formatelf32-i386Contents of section .dynamic:160c 01000000 71000000 010000007b000000 ....q.......{...161c 0c000000 8c030000 0d000000b4050000 ................162c f5feff6f b4000000 05000000 0c020000 ...o............163c 06000000 fc000000 0a000000b3000000 ................164c 0b000000 10000000 03000000e4160000 ................165c 02000000 28000000 1400000011000000 ....(...........166c 17000000 64030000 1100000034030000 ....d.......4...167c 12000000 30000000 1300000008000000 ....0...........168c feffff6f e4020000 ffffff6f 02000000 ...o.......o.... 169c f0ffff6f c0020000 faffff6f 02000000 ...o.......o....16ac 00000000 00000000 0000000000000000 ................16bc 00000000 00000000 0000000000000000 ................16cc 00000000 00000000 ........8. 查看ELF程序头信息readelf -h提供完整的信息, objdump -f只提供很少的信息. 9. 查看符号信息readelf -sobjdump -t两个命令都提供类似nm的信息. 输出如下: [qtl@courier lib]$ readelf -s libfoobar.so Symbol table '.dynsym' contains 17 entries:Num: Value Size Type Bind Vis Ndx Name0: 00000000 0 NOTYPE LOCAL DEFAULTUND1: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__2: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses3: 00000000 38 FUNC GLOBAL DEFAULT UND cos@GLIBC_2.0 (2)4: 00000000 351 FUNC GLOBAL DEFAULT UND fwrite@GLIBC_2.0 (3)5: 00000000 36 FUNC GLOBAL DEFAULT UND fprintf@GLIBC_2.0 (3)6: 00000000 4 OBJECT GLOBAL DEFAULT UND stdout@GLIBC_2.0 (3)7: 00000000 346 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.1.3(4)8: 00000520 92 FUNC GLOBAL DEFAULT 10 bar9: 000004dc 66 FUNC GLOBAL DEFAULT 10 foo10: 00001718 0 NOTYPE GLOBAL DEFAULT ABS _end11: 00001708 0 NOTYPE GLOBAL DEFAULT ABS _edata12: 0000170c 4 OBJECT GLOBAL DEFAULT 22 foo_var13: 00001708 0 NOTYPE GLOBAL DEFAULT ABS __bss_start14: 0000038c 0 FUNC GLOBAL DEFAULT8 _init15: 000005b4 0 FUNC GLOBAL DEFAULT 11 _fini16: 00001710 8 OBJECT GLOBAL DEFAULT 22 bar_varSymbol table '.symtab' contains 61 entries:Num: Value Size Type Bind Vis Ndx Name0: 00000000 0 NOTYPE LOCAL DEFAULT UND1: 000000b4 0 SECTION LOCAL DEFAULT 12: 000000fc 0 SECTION LOCAL DEFAULT 23: 0000020c 0 SECTION LOCAL DEFAULT 34: 000002c0 0 SECTION LOCAL DEFAULT 45: 000002e4 0 SECTION LOCAL DEFAULT 56: 00000334 0 SECTION LOCAL DEFAULT 67: 00000364 0 SECTION LOCAL DEFAULT 78: 0000038c 0 SECTION LOCAL DEFAULT 89: 000003a4 0 SECTION LOCAL DEFAULT 910: 00000410 0 SECTION LOCAL DEFAULT 1011: 000005b4 0 SECTION LOCAL DEFAULT 1112: 000005d0 0 SECTION LOCAL DEFAULT 1213: 000005f0 0 SECTION LOCAL DEFAULT 1314: 000015f4 0 SECTION LOCAL DEFAULT 1415: 000015fc 0 SECTION LOCAL DEFAULT 1516: 00001604 0 SECTION LOCAL DEFAULT 1617: 00001608 0 SECTION LOCAL DEFAULT 1718: 0000160c 0 SECTION LOCAL DEFAULT1819: 000016d4 0 SECTION LOCAL DEFAULT 1920: 000016e4 0 SECTION LOCAL DEFAULT 2021: 00001704 0 SECTION LOCAL DEFAULT 2122: 00001708 0 SECTION LOCAL DEFAULT 2223: 00000000 0 SECTION LOCAL DEFAULT 2324: 00000410 0 FUNC LOCAL DEFAULT 10 call_gmon_start25: 00000000 0 FILE LOCAL DEFAULT ABS crtstuff.c26: 000015f4 0 OBJECT LOCAL DEFAULT 14 __CTOR_LIST__27: 000015fc 0 OBJECT LOCAL DEFAULT 15 __DTOR_LIST__28: 00001604 0 OBJECT LOCAL DEFAULT 16 __JCR_LIST__29: 00001708 1 OBJECT LOCAL DEFAULT 22 completed.575830: 00001704 0 OBJECT LOCAL DEFAULT 21 p.575631: 00000440 0 FUNC LOCAL DEFAULT 10 __do_global_dtors_aux32: 000004a0 0 FUNC LOCAL DEFAULT 10 frame_dummy33: 00000000 0 FILE LOCAL DEFAULT ABS crtstuff.c34: 000015f8 0 OBJECT LOCAL DEFAULT 14 __CTOR_END__35: 00001600 0 OBJECT LOCAL DEFAULT 15 __DTOR_END__36: 000005f0 0 OBJECT LOCAL DEFAULT 13 __FRAME_END__37: 00001604 0 OBJECT LOCAL DEFAULT 16 __JCR_END__38: 00000580 0 FUNC LOCAL DEFAULT 10 __do_global_ctors_aux39: 00000000 0 FILE LOCAL DEFAULT ABS foo.c40: 00000000 0 FILE LOCAL DEFAULTABS bar.c41: 000016e4 0 OBJECT LOCAL HIDDEN ABS _GLOBAL_OFFSET_TABLE_42: 00001608 0 OBJECT LOCAL HIDDEN 17 __dso_handle43: 000004d7 0 FUNC LOCAL HIDDEN 10 __i686.get_pc_thunk.bx44: 0000160c 0 OBJECT LOCAL HIDDEN ABS _DYNAMIC45: 00000520 92 FUNC GLOBAL DEFAULT 10 bar46: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__47: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses48: 000005b4 0 FUNC GLOBAL DEFAULT 11 _fini49: 0000170c 4 OBJECT GLOBAL DEFAULT 22 foo_var50: 000004dc 66 FUNC GLOBAL DEFAULT 10 foo51: 00000000 38 FUNC GLOBAL DEFAULT UND cos@@GLIBC_2.052: 00000000 351 FUNC GLOBAL DEFAULT UND fwrite@@GLIBC_2.053: 00000000 36 FUNC GLOBAL DEFAULT UND fprintf@@GLIBC_2.054: 00001708 0 NOTYPE GLOBAL DEFAULT ABS __bss_start55: 00001718 0 NOTYPE GLOBAL DEFAULT ABS _end56: 00000000 4 OBJECT GLOBAL DEFAULT UND stdout@@GLIBC_2.057: 00001710 8 OBJECT GLOBAL DEFAULT 22 bar_var58: 00001708 0 NOTYPE GLOBAL DEFAULT ABS _edata59: 00000000 346 FUNC WEAK DEFAULT UND __cxa_finalize@@GLIBC_2.160: 0000038c 0 FUNC GLOBAL DEFAULT8 _init[qtl@courier lib]$ objdump -t libfoobar.so libfoobar.so: file format elf32-i386SYMBOL TABLE:000000b4 l d .gnu.hash00000000 .gnu.hash000000fc l d .dynsym00000000 .dynsym0000020c l d .dynstr00000000 .dynstr000002c0 l d .gnu.version00000000 .gnu.version000002e4 l d .gnu.version_r00000000 .gnu.version_r00000334 l d .rel.dyn00000000 .rel.dyn00000364 l d .rel.plt00000000 .rel.plt0000038c l d .init 00000000 .init 000003a4 l d .plt 00000000 .plt。
objdump命令
![objdump命令](https://img.taocdn.com/s3/m/cecd2a0259eef8c75fbfb3c9.png)
objdump命令objdump命令是用查看目标文件或者可执行的目标文件的构成的gcc工具。
选项--archive-headers-a显示档案库的成员信息,类似ls -l将lib*.a的信息列出。
-b bfdname--target=bfdname指定目标码格式。
这不是必须的,objdump能自动识别许多格式,比如:objdump -b oasys -m vax -h fu.o显示fu.o的头部摘要信息,明确指出该文件是Vax系统下用Oasys编译器生成的目标文件。
objdump -i将给出这里可以指定的目标码格式列表。
-C--demangle将底层的符号名解码成用户级名字,除了去掉所开头的下划线之外,还使得C++函数名以可理解的方式显示出来。
--debugging-g显示调试信息。
企图解析保存在文件中的调试信息并以C语言的语法显示出来。
仅仅支持某些类型的调试信息。
有些其他的格式被readelf -w支持。
-e--debugging-tags类似-g选项,但是生成的信息是和ctags工具相兼容的格式。
--disassemble-d从objfile中反汇编那些特定指令机器码的section。
-D--disassemble-all与-d 类似,但反汇编所有section.--prefix-addresses反汇编的时候,显示每一行的完整地址。
这是一种比较老的反汇编格式。
-EB-EL--endian={big|little}指定目标文件的小端。
这个项将影响反汇编出来的指令。
在反汇编的文件没描述小端信息的时候用。
例如S-records.-f--file-headers显示objfile中每个文件的整体头部摘要信息。
-h--section-headers--headers显示目标文件各个section的头部摘要信息。
-H--help简短的帮助信息。
-i--info显示对于-b 或者-m 选项可用的架构和目标格式列表。
objdump 函数
![objdump 函数](https://img.taocdn.com/s3/m/492a144c4b7302768e9951e79b89680202d86b4f.png)
objdump 函数objdump 是 GNU 二进制工具集(GNU Binutils)中的一个工具,它可以用来查看目标文件、可执行文件、共享库等二进制文件的反汇编和符号信息。
objdump 可以通过命令行参数来指定要显示的信息类型,如反汇编指令、符号表、调试信息等,并且可以以不同的格式(如十六进制、源代码、汇编代码等)来显示这些信息。
以下是对 objdump 的一些常用用法和参数的介绍:1. 常用命令行参数:-d:显示反汇编指令。
-t:显示符号表。
-S:将反汇编指令和源代码交叉显示。
-f:显示目标文件格式信息。
-r:显示重定位表。
-x:显示所有节的详细信息。
-s:显示目标文件的内容。
-h:显示目标文件的节头表。
等等。
2. 反汇编指令:objdump 可以通过指定 -d 参数来显示目标文件的反汇编指令。
反汇编指令可以帮助理解程序的执行过程,了解程序的控制结构、函数调用等关键信息。
反汇编指令还可以用于进行逆向工程、调试和研究。
3. 符号表:符号表包含了目标文件中定义和引用的全局符号的信息,如函数、变量等。
通过指定 -t 参数,objdump 可以将符号表的信息显示出来。
符号表的信息对于调试和分析程序非常有用,可以帮助定位问题、理解代码的结构和逻辑。
4. 调试信息:若目标文件包含调试信息,可以通过 -S 参数来将反汇编指令和源代码进行交叉显示。
这样做可以方便地查看源代码和对应的机器码,有助于理解程序的执行流程和调试代码。
objdump 还支持其他格式显示调试信息,如使用 -G 参数以 gas 语法显示,使用 -W 参数显示 DWARF 格式调试信息等。
5. 目标文件格式信息:使用 -f 参数可以显示目标文件的格式信息,包括目标文件类型、CPU 架构、节的数量和大小等。
了解目标文件的格式信息对于理解二进制文件的结构和特性至关重要。
6. 重定位信息:重定位表记录了目标文件中需要进行修正的地方,如函数调用、全局变量等。
使用objdump命令反汇编二进制文件
![使用objdump命令反汇编二进制文件](https://img.taocdn.com/s3/m/bef3d9540a4e767f5acfa1c7aa00b52acec79c50.png)
使用objdump命令反汇编二进制文件objdump 是 GNU Binutils 工具包中的一个工具,用于反汇编二进制文件。
它可以将二进制文件转换为汇编代码,帮助我们理解程序的内部细节和执行流程。
使用 objdump 命令反汇编二进制文件可以帮助开发人员进行调试、研究安全漏洞、逆向工程等操作。
以下是使用 objdump 命令反汇编二进制文件的具体步骤和使用示例。
步骤一:安装 GNU Binutils 工具包objdump 命令属于 GNU Binutils 工具包的一部分,因此首先需要安装 Binutils 工具包。
可以通过包管理器进行安装,例如在 Ubuntu 系统中,可以使用以下命令进行安装:```sudo apt-get install binutils```步骤二:反汇编二进制文件一旦安装完成 Binutils 工具包,就可以使用 objdump 命令来反汇编二进制文件。
下面是 objdump 命令的基本语法:```objdump [选项] <二进制文件>```以下是一些常用的选项:- `-d`:反汇编所有节 (sections) 的内容- `-S`:反汇编并显示源代码(如果可用)- `-t`:显示二进制文件中的符号表使用 objdump 命令进行反汇编可以提供更多有关二进制文件内部的信息。
例如,通过 objdump 命令可以查看可执行文件的代码段、数据段、符号表等信息。
以下是一个使用 objdump 命令反汇编可执行文件的示例:```objdump -d ./a.out```上述命令将会反汇编当前目录下的可执行文件 a.out,并输出其汇编代码。
步骤三:分析汇编代码一旦成功运行 objdump 命令并反汇编了目标二进制文件,就可以分析所得到的汇编代码了。
汇编代码可以让我们更深入了解程序的执行流程、指令的功能和数据的存储方式。
通过分析汇编代码,我们还可以判断程序是否存在漏洞或者进行程序优化。
objdump 使用方法 -回复
![objdump 使用方法 -回复](https://img.taocdn.com/s3/m/01606ffd1b37f111f18583d049649b6648d70901.png)
objdump 使用方法-回复关于"objdump 使用方法"的文章,将详细介绍该工具的步骤和用法。
objdump是一个十分有用的命令行工具,它可以用于分析可执行文件和目标文件。
无论是在逆向工程、代码审计还是调试过程中,objdump都扮演着重要的角色,它可以帮助开发者理解和调试指令的执行流程,查看变量和符号表以及分析代码中的漏洞。
接下来,我们将详细介绍objdump 的使用方法。
第一步:安装objdumpobjdump是GNU Binutils软件包的一部分,因此你需要确保已经安装了Binutils。
在大多数Linux发行版中,Binutils默认安装。
如果没有安装,可以使用包管理器安装。
例如,在Ubuntu或Debian系统上,可以使用以下命令安装:sudo apt-get install binutils第二步:了解objdump的基本用法objdump这个命令有很多选项和参数,因此在使用之前,先了解一些基本的用法是很重要的。
可以通过以下命令来查看objdump的基本用法:objdump help这将显示所有可用的选项和参数。
在下面的步骤中,我们将介绍一些常用的选项。
第三步:查看可执行文件或目标文件的头部信息objdump可以用来查看一个可执行文件或目标文件的头部信息。
头部信息包含了关于文件类型、目标体系结构以及程序入口点等重要的信息。
可以使用以下命令来查看头部信息:objdump -f <file>其中,`<file>`是需要分析的可执行文件或目标文件。
第四步:反汇编代码objdump最常用的功能之一是反汇编代码。
通过反汇编代码,我们可以查看可执行文件或目标文件中的汇编指令。
下面的命令会将代码以汇编指令的形式输出:objdump -d <file>这将显示整个可执行文件或目标文件的汇编代码。
如果只想查看特定函数的汇编代码,可以使用以下命令:objdump -d <file> -j .text -M intel其中,`-j .text`表示只查看.text节的内容,`-M intel`表示以Intel格式显示汇编代码。
objdump反汇编指令
![objdump反汇编指令](https://img.taocdn.com/s3/m/29c9c71dcdbff121dd36a32d7375a417866fc1f9.png)
objdump反汇编指令
objdump是一个反汇编工具,用于将一个二进制文件中的机器指令转化为汇编指令。
以下是objdump的一些常用选项以及对应的反汇编指令:
1. -d: 反汇编所有的代码段。
输出结果包括机器指令和对应的汇编指令。
2. -D: 类似于-d选项,但是输出结果还包括符号表、调试信息等。
3. -S: 反汇编代码段,并且将反汇编指令与源代码进行交替显示。
输出结果类似于源代码和对应的汇编指令的混合。
4. -M: 指定反汇编器的架构。
例如,使用-M x86-64选项可以指定反汇编目标为x86-64架构。
5. -m: 显示可执行文件的某一特定部分的反汇编结果。
6. -r: 显示重定位信息,包括重定位表和符号表。
7. -t: 显示BSS段的内容。
8. -j: 选择特定的代码段进行反汇编。
例如,-j .text可以只反汇编.text段。
9. -C: 还原由C++编译的函数名。
以上是一些常用的objdump选项和对应的反汇编指令。
使用objdump可以帮助我们查看二进制文件中的机器指令,以及对应的汇编指令,从而进行代码分析和调试。
mingw基本命令
![mingw基本命令](https://img.taocdn.com/s3/m/5570a1336d85ec3a87c24028915f804d2b16872e.png)
mingw基本命令Mingw基本命令Mingw是一套用于Windows操作系统上的开发工具链,它允许开发者在Windows环境下编译和构建Unix-like系统的应用程序。
本文将介绍Mingw的基本命令,以帮助读者更好地使用该工具。
1. gcc命令gcc是Mingw提供的编译器,用于将C/C++源代码编译成可执行文件。
常用的gcc命令选项包括:- -c:只编译源文件,生成目标文件(.o或.obj文件),不进行链接。
- -o:指定生成的可执行文件的名称。
- -I:指定头文件的搜索路径。
- -L:指定库文件的搜索路径。
- -l:链接指定的库文件。
2. g++命令g++是Mingw提供的C++编译器,用法与gcc类似。
通过g++命令,可以将C++源代码编译成可执行文件。
3. make命令make是一个常用的自动化构建工具,可根据Makefile文件中的规则自动编译和链接源代码。
在Mingw中,make命令通常与gcc 或g++命令配合使用。
使用make命令可以简化编译和构建过程,提高开发效率。
4. ar命令ar命令用于创建、修改和提取静态库。
在Mingw中,静态库的文件扩展名通常为.a。
通过ar命令,可以将多个目标文件打包成一个静态库文件,供其他程序使用。
5. dlltool命令dlltool命令用于创建和管理动态链接库(DLL)。
通过dlltool命令,可以从目标文件中提取导出函数,并生成一个.def文件。
然后,可以使用这个.def文件和gcc命令将目标文件编译成DLL。
6. objdump命令objdump命令用于反汇编目标文件或可执行文件,并显示其汇编代码。
通过objdump命令,可以查看程序的汇编实现,以便进行调试和优化。
7. gdb命令gdb是一个强大的调试器,可用于调试C和C++程序。
在Mingw 中,使用gdb命令可以对可执行文件进行调试,查看变量的值、执行流程等。
8. strip命令strip命令用于去除可执行文件或目标文件中的符号表和调试信息,以减小文件大小。
arm-linux-gccldobjcopyobjdump使用总结
![arm-linux-gccldobjcopyobjdump使用总结](https://img.taocdn.com/s3/m/54d3d47c168884868762d6d5.png)
arm-linux工具的功能如下:arm-linux-addr2line 把程序地址转换为文件名和行号。
在命令行中给它一个地址和一个可执行文件名,它就会使用这个可执行文件的调试信息指出在给出的地址上是哪个文件以及行号。
arm-linux-ar 建立、修改、提取归档文件。
归档文件是包含多个文件内容的一个大文件,其结构保证了可以恢复原始文件内容。
arm-linux-c++flit 连接器使用它来过滤 C++ 和 Java 符号,防止重载函数冲突。
arm-linux-gprof 显示程序调用段的各种数据。
arm-linux-ld 是连接器,它把一些目标和归档文件结合在一起,重定位数据,并连接符号引用。
通常,建立一个新编译程序的最后一步就是调用ld。
arm-linux-nm 列出目标文件中的符号。
arm-linux-objcopy 把一种目标文件中的内容复制到另一种类型的目标文件中。
arm-linux-objdump 显示一个或者更多目标文件的信息。
使用选项来控制其显示的信息,它所显示的信息通常只有编写编译工具的人才感兴趣。
arm-linux-ranlib 产生归档文件索引,并将其保存到这个归档文件中。
在索引中列出了归档文件各成员所定义的可重分配目标文件。
arm-linux-readelf 显示elf格式可执行文件的信息。
arm-linux-size 列出目标文件每一段的大小以及总体的大小。
默认情况下,对于每个目标文件或者一个归档文件中的每个模块只产生一行输出。
arm-linux-string 打印某个文件的可打印字符串,这些字符串最少4个字符长,也可以使用选项-n设置字符串的最小长度。
默认情况下,它只打印目标文件初始化和可加载段中的可打印字符;对于其他类型的文件它打印整个文件的可打印字符。
这个程序对于了解非文本文件的内容很有帮助。
arm-linux-strip 丢弃目标文件中的全部或者特定符号。
arm-linux-gcc -wall -O2 -c -o $@ $<-o 只激活预处理,编译,和汇编,也就是他只把程序做成obj文件-Wall 指定产生全部的警告信息-O2 编译器对程序提供的编译优化选项,在编译的时候使用该选项,可以使生成的执行文件的执行效率提高-c 表示只要求编译器进行编译,而不要进行链接,生成以源文件的文件名命名但把其后缀由 .c 或 .cc 变成 .o 的目标文件-S 只激活预处理和编译,就是指把文件编译成为汇编代码arm-linux-ld 直接指定代码段,数据段,BSS段的起始地址-Tbss ADDRESS Set address of .bss section-Tdata ADDRESS Set address of .data section-Ttext ADDRESS Set address of .text section示例:${CROSS}ld -Ttext=0x33000000 led.o -o led.elf使用连接脚本设置地址:arm-linux-ld -Tbeep.lds start.o beep.o -o beep.elf其中beep.lds 为连接脚本如下:arm-linux-objcopy被用来复制一个目标文件的内容到另一个文件中,可用于不同源文件的之间的格式转换示例:arm-linux-objcopy –o binary –S elf_file bin_file常用的选项:input-file , outflie输入和输出文件,如果没有outfile,则输出文件名为输入文件名2.-l bfdname或—input-target=bfdname用来指明源文件的格式,bfdname是BFD库中描述的标准格式名,如果没指明,则arm-linux-objcopy自己分析3.-O bfdname 输出的格式4.-F bfdname 同时指明源文件,目的文件的格式5.-R sectionname 从输出文件中删除掉所有名为sectionname的段6.-S 不从源文件中复制重定位信息和符号信息到目标文件中7.-g 不从源文件中复制调试符号到目标文件中arm-linux-objdump查看目标文件(.o文件)和库文件(.a文件)信息arm-linux-objdump -D -m arm beep.elf > beep.dis-D 显示文件中所有汇编信息-m machine指定反汇编目标文件时使用的架构,当待反汇编文件本身没有描述架构信息的时候(比如S-records),这个选项很有用。
gcc, as, ld的一些笔记
![gcc, as, ld的一些笔记](https://img.taocdn.com/s3/m/5d3a81afdd3383c4bb4cd25f.png)
gcc, as, ld的一些笔记(一)(原创)1.本文不是教程,只是描述c语言(gcc环境),编译器,连接器,加载器,at&t汇编,ia32一些相关知识和笔记,很多需要深入的地方需要大家寻找相关的资料学习。
如果发现错误,请留言或通知我jinglexy at yahoo dot com dot cn,这个是我的msn。
打字不易,请转载时保留作者。
2.gcc安装的各个部分:g++ c++编译器,链接时使用c++库gcc c编译器,链接时使用c库cc1 实际的c编译器cc1plus 实际的c++编译器collect2 使用collect2产生特定的全局初始化代码,后台处理是传递参数给ld完成实际的链接工作。
crt0.o 初始化和结束代码libgcc 平台相关的库gcc安装需要的文件:gcc-core-3.4.6.tar.gz2 gcc核心编译器,默认只包含c编译器gcc-g++-3.4.6.tar.bz2 g++编译器gcc-testsuite-3.4.6.tar.bz2 测试套件./configure && make && make install3.binutils安装的各个部分as gnu汇编工具gprof 性能分析工具ld gnu链接器makeobjcopy 目标文件从二进制格式翻译或复制到另一种objdump 显示目标文件的各种信息strings 显示文件的字符串strip 去除符合表readelf 分析elf并显示信息链接器可以读写各种目标文件中的信息,通过BFD(binary file descriptor)提供的工具实现,BFD定义了类似a.out, elf, coff 等目标文件的格式。
4.gcc预处理程序1)define指令#可将传递的宏字符串化##将两个名字连接成一个(注意不是连接成字符串)例:#define TEST(ARGTERM) \printf(“the term “ #ARGTERM “is a string\n”) 使用__VA_ARGS__定义可变参数宏例:#define err(...) fprintf(stderr, __VA_ARGS)err (“%s %d\n”, “error code is”, 48);为了消除无参数时的逗号,可以用下面方法定义:# define err(...) fprintf(stderr, ##__VA_ARGS)一种等同的方法是:#define dprintf(fmt, arg...) printf(fmt, ##arg) 其他例:#define PASTE(a, b) a##b2)error 和 warning指令#error “y here? bad boy!”3)if, elif, else, endif指令支持的运算符:加减乘除,位移,&&,||,!等示例:#if defined (CONFIG_A) || defined (CONFIG_B)……#endif4)gcc预定义宏__BASE_FILE__ 完整的源文件名路径__cplusplus 测试c++程序__DATE____FILE__ 源文件名__func__ 替代__FUNCTION__,__FUNCTION__以被GNU不推荐使用__TIME____LINE____VERSION__ gcc版本5)几个简单例子:例1:#define min(X, Y) \(__extension__ ({typeof (X) __x = (X), __y = (Y); \(__x < __y) ? __x : __y; }))#define max(X, Y) \(__extension__ ({typeof (X) __x = (X), __y = (Y); \(__x > __y) ? __x : __y; }))这样做的目的是消除宏对X,Y的改变的影响,例如:result = min(x++, --y); printf(x, y);补充:圆括号定义的符合语句可以生成返回值,例:result = ({ int a = 5;int b;b = a + 3;}); 将返回8例2:#define dprintfbin(buf, size) do{ int i; \printf("%s(%d)@", \__FUNCTION__, __LINE__); \for(i = 0; i < size - 1; i++){ \if(0 == i % 16) \printf("\n"); \printf("0x%02x ", ((char*)buf)[i]); \} \printf("0x%02x\n", ((char*)buf)[i]); \}while(0)这个比较简单,不用解释了例3:#ifdef __cplusplusextern "C"{#endifint foo1(void);int foo2(void);#ifdef __cplusplus}#endif作用:在c++程序中使用c函数及库,c++编译程序时将函数名粉碎成自己的方式,在没有extern的情况下可能是_Z3_foo1,_Z3_foo2将导致连接错误,这里的extern表示在连接库时,使用foo1,foo2函数名。
objdump 参数
![objdump 参数](https://img.taocdn.com/s3/m/61780c7a30126edb6f1aff00bed5b9f3f90f72e9.png)
objdump 参数objdump 是一个用于查看可执行文件、目标文件和动态库的工具。
它可以展示这些文件的汇编代码、符号表信息、重定位表和其他相关信息。
objdump 提供了多种参数,让开发者可以根据需要查看不同的信息。
下面将介绍几个常用的 objdump 参数。
1. -d/--disassemble 参数:使用objdump -d 命令可以显示目标文件的汇编代码。
这对于调试代码非常有用,可以帮助开发者理解程序的执行过程,查找代码中的问题。
例如,使用objdump -d myprogram 可以显示 myprogram 可执行文件的汇编代码。
2. -t/--syms 参数:使用 objdump -t 命令可以显示目标文件的符号表信息。
符号表包含了函数、变量以及其他标识符的名称和地址。
通过查看符号表,开发者可以了解程序中定义的函数和变量的信息。
例如,使用objdump -t myprogram 可以显示myprogram 可执行文件的符号表信息。
3. -r/--reloc 参数:使用 objdump -r 命令可以显示目标文件的重定位表信息。
重定位表包含了需要在链接时进行地址修正的符号的信息。
通过查看重定位表,开发者可以了解程序中需要进行地址修正的符号和修正的方式。
例如,使用objdump -r myprogram 可以显示myprogram 可执行文件的重定位表信息。
4. -S/--source 参数:使用 objdump -S 命令可以显示目标文件的源代码。
这对于理解程序的逻辑和结构非常有用。
通过查看源代码,开发者可以追踪程序的执行流程,查找代码中的问题。
例如,使用objdump -S myprogram 可以显示myprogram 可执行文件的源代码。
objdump 是一个非常有用的工具,可以帮助开发者深入了解可执行文件、目标文件和动态库。
通过查看汇编代码、符号表信息和重定位表信息,开发者可以理解程序的执行过程、查找代码中的问题。
gcc命令之-objcopy
![gcc命令之-objcopy](https://img.taocdn.com/s3/m/671bcde9856a561252d36f39.png)
gcc命令之-------objcopyobjcopy参数[url=javascript:void(null)]推荐[/url]objcopy把一种目标文件中的内容复制到另一种类型的目标文件中.(1)将图像编译到可执行文件内Q: 如何将一个二进制文件,比如图片,词典一类的东西做为.o文件,直接链接到可执行文件内部呢?A:$ objcopy -I binary -O elf32-i386 -B i386 14_95_13.jpg image.o$ gcc image.o tt.o -o tt$ nm tt | grep 14_950805d6c7 D _binary_14_95_13_jpg_end00014213 A _binary_14_95_13_jpg_size080494b4 D _binary_14_95_13_jpg_start(2)使用objcopy把不用的信息去掉:$ objcopy -R .comment -R .note halo halo.min(3)$ objcopy -R .note -R .comment -S -O binary xyb xyb.bin-R .note -R .comment 表示移掉 .note 与 .comment 段-S 表示移出所有的标志及重定位信息-O binary xyb xyb.bin 表示由xyb生成二进制文件xyb.binobjcopy工具使用指南objcopy Utilityobjcopy [ -F bfdname | --target=bfdname ][ -I bfdname | --input-target=bfdname ][ -O bfdname | --output-target= bfdname ][ -S | --strip-all ] [ -g | --strip-debug ][ -K symbolname | --keep-symbol= symbolname ][ -N symbolname | --strip-symbol= symbolname ][ -L symbolname | --localize-symbol= symbolname ][ -W symbolname | --weaken-symbol= symbolname ][ -x | --discard-all ] [ -X | --discard-locals ][ -b byte | --byte= byte ][ -i interleave | --interleave= interleave ][ -R sectionname | --remove-section= sectionname ][ -p | --preserve-dates ] [ --debugging ][ --gap-fill= val ] [ --pad-to= address ][ --set-start= val ] [ --adjust-start= incr ][ --change-address= incr ][ --change-section-address= section{=,+,-} val ][ --change-warnings ] [ --no-change-warnings ][ --set-section-flags= section= flags ][ --add-section= sectionname= filename ][ --change-leading char ] [--remove-leading-char ][ --weaken ][ -v | --verbose ] [ -V | --version ] [ --help ]input-file [ outfile ]GNU实用工具程序objcopy的作用是拷贝一个目标文件的内容到另一个目标文件中。
objdump的使用方法
![objdump的使用方法](https://img.taocdn.com/s3/m/69c220884128915f804d2b160b4e767f5bcf8012.png)
钢铁是怎样炼成的排比感想100字objdump是gcc工具,用来查看编译后目标文件的组成。
下面是其基本使用方法:1. objdump -x obj:以某种分类信息的形式把目标文件的数据组成输出。
2. objdump -t obj:输出目标文件的符号表。
3. objdump -h obj:输出目标文件的所有段概括。
4. objdump -j ./text/.data -S obj:输出指定段的信息(反汇编源代码)。
5. objdump -S obj:输出目标文件的符号表。
当gcc -g时打印更明显。
6. objdump -j .text -Sl stack1 | more -S 尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。
隐含了-d 参数。
7. -l 用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r 一起使用。
使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。
8. objdump -g vmlinux:显示调试信息。
9. objdump -r vmlinux:显示文件的重定位入口。
10. objdump -R vmlinux:显示动态链接重定位信息。
11. objdump -S -l -z -jxxxx(section name) vmlinux > vmlinux.dump反汇编linux 内核段xxxx 到文件vmlinux.dump 中。
12. objdump -x vmlinux > x.dump vmliux中所有段的头信息,其中包口vmlinux的入口地址等。
13. objdump --debugging vmlinux > debugging.dump 很多有用的debug信息,如函数名,结构体定义等。
使用objdump工具可以了解目标文件的组成,并进行调试和分析。
希望对您有所帮助!。
使用C编译器制作简单二进制文件
![使用C编译器制作简单二进制文件](https://img.taocdn.com/s3/m/a0974575f46527d3240ce079.png)
1 需要些什么工具?
?一个i386或跟高的PC机器
?像Red Hat或Slackware的一个Linux发行版操作系统
?GNU GCC 编译器。这个C编译器常被用于Linux系统中。使用下面的命令方式检测你的GCC版本:
gcc –version
gcc –c test.c
ld test.o –o test.bin –Ttext 0x0 –e main –oformat binary
这个将如先前的方法一样生成一个一模一样的二进制代码。
3 使用局部变量编程
下面我们将看GCC如何控制一个局部变量。此处我们创建一个新的test.c文件,其包含:
2 用C创建第一个简单的二进制文件
使用文本编辑器创建一个test.c文件,输入:
int main(){
}
输入编译:
gcc –c test.c
ld –o test –Ttext 0x0 –e main test.o
objcopy –R .note –R .comment –S –o binary test test.bin
00000000 55 push ebp
00000001 89E5 mov ebp,esp
00000003 C9 leave
00000004 C3 ret
00000005 0000 add [eax],al
00000007 007856 add [eax+0x56],bh
使用C编译器制作简单二进制文件(i386+)
Cornelis Frank 著
newrain 译
00000004 C3 ret
将得到三列,第一列包括指令的内存地址,第二列包括指令的字节代码,最后一列为指令本身。
gcc编程环境基础4--ld命令和u-boot中的lds文件实例和简单实例分析
![gcc编程环境基础4--ld命令和u-boot中的lds文件实例和简单实例分析](https://img.taocdn.com/s3/m/6a254b85d0d233d4b14e69bb.png)
gcc编程环境基础4--ld命令和u-boot中的lds文件实例和简单实例分析ld选项和lds文件==================================================================================0. Contents1. 概论2. 基本概念3. 脚本格式4. 简单例子5. 简单脚本命令6. 对符号的赋值7. SECTIONS命令8. MEMORY命令9. PHDRS命令10. VERSION命令11. 脚本内的表达式12. 暗含的连接脚本1. 概论--------------------------------------------------------------------------------每一个链接过程都由链接脚本(linker script, 一般以lds作为文件的后缀名)控制. 链接脚本主要用于规定如何把输入文件内的section放入输出文件内, 并控制输出文件内各部分在程序地址空间内的布局. 但你也可以用连接命令做一些其他事情.连接器有个默认的内置连接脚本, 可用ld --verbose查看. 连接选项-r和-N可以影响默认的连接脚本(如何影响?).-T选项用以指定自己的链接脚本, 它将代替默认的连接脚本.你也可以使用<暗含的连接脚本>以增加自定义的链接命令.以下没有特殊说明,连接器指的是静态连接器.2. 基本概念--------------------------------------------------------------------------------链接器把一个或多个输入文件合成一个输出文件.输入文件: 目标文件或链接脚本文件.输出文件: 目标文件或可执行文件.目标文件(包括可执行文件)具有固定的格式, 在UNIX或GNU/Linux平台下, 一般为ELF格式. 若想了解更多, 可参考UNIX/Linux平台可执行文件格式分析有时把输入文件内的section称为输入section(input section), 把输出文件内的section称为输出section(output sectin).目标文件的每个section至少包含两个信息: 名字和大小. 大部分section还包含与它相关联的一块数据, 称为section contents(section内容). 一个section可被标记为“loadable(可加载的)”或“allocatable(可分配的)”.loadable section: 在输出文件运行时, 相应的section内容将被载入进程地址空间中.allocatable section: 内容为空的section可被标记为“可分配的”. 在输出文件运行时, 在进程地址空间中空出大小同section指定大小的部分. 某些情况下, 这块内存必须被置零.如果一个section不是“可加载的”或“可分配的”, 那么该section通常包含了调试信息. 可用objdump -h命令查看相关信息.每个“可加载的”或“可分配的”输出section通常包含两个地址: VMA(virtual memory address虚拟内存地址或程序地址空间地址)和LMA(load memory address加载内存地址或进程地址空间地址). 通常VMA和LMA是相同的.在目标文件中, loadable或allocatable的输出section有两种地址: VMA(virtual Memory Address)和LMA(Load Memory Address). VMA是执行输出文件时section所在的地址, 而LMA是加载输出文件时section所在的地址. 一般而言, 某section的VMA == LMA. 但在嵌入式系统中, 经常存在加载地址和执行地址不同的情况: 比如将输出文件加载到开发板的flash中(由LMA指定), 而在运行时将位于flash中的输出文件复制到SDRAM中(由VMA指定).可这样来理解VMA和LMA, 假设:(1) .data section对应的VMA地址是0x08050000, 该section内包含了3个32位全局变量, i、j和k, 分别为1,2,3.(2) .text section内包含由"printf( "j=%d ", j );"程序片段产生的代码.连接时指定.data section的VMA为0x08050000, 产生的printf指令是将地址为0x08050004处的4字节内容作为一个整数打印出来.如果.data section的LMA为0x08050000,显然结果是j=2如果.data section的LMA为0x08050004,显然结果是j=1还可这样理解LMA:.text section内容的开始处包含如下两条指令(intel i386指令是10字节,每行对应5字节):jmp 0x08048285movl $0x1,%eax如果.text section的LMA为0x08048280, 那么在进程地址空间内0x08048280处为“jmp 0x08048285”指令, 0x08048285处为movl $0x1,%eax 指令. 假设某指令跳转到地址0x08048280, 显然它的执行将导致%eax寄存器被赋值为1.如果.text section的LMA为0x08048285, 那么在进程地址空间内0x08048285处为“jmp 0x08048285”指令, 0x0804828a处为movl $0x1,%eax 指令. 假设某指令跳转到地址0x08048285, 显然它的执行又跳转到进程地址空间内0x08048285处, 造成死循环.符号(symbol): 每个目标文件都有符号表(SYMBOL TABLE), 包含已定义的符号(对应全局变量和static变量和定义的函数的名字)和未定义符号(未定义的函数的名字和引用但没定义的符号)信息.符号值: 每个符号对应一个地址, 即符号值(这与c程序内变量的值不一样, 某种情况下可以把它看成变量的地址). 可用nm命令查看它们. (nm的使用方法可参考本blog的GNU binutils笔记)3. 脚本格式--------------------------------------------------------------------------------链接脚本由一系列命令组成, 每个命令由一个关键字(一般在其后紧跟相关参数)或一条对符号的赋值语句组成. 命令由分号…;‟分隔开.文件名或格式名内如果包含分号';'或其他分隔符, 则要用引号…"‟将名字全称引用起来. 无法处理含引号的文件名./* */之间的是注释.4. 简单例子--------------------------------------------------------------------------------在介绍链接描述文件的命令之前, 先看看下述的简单例子:以下脚本将输出文件的text section定位在0x10000, data section定位在0x8000000:SECTIONS{. = 0x10000;.text : { *(.text) }. = 0x8000000;.data : { *(.data) }.bss : { *(.bss) }}解释一下上述的例子:. = 0x10000 : 把定位器符号置为0x10000 (若不指定, 则该符号的初始值为0)..text : { *(.text) } : 将所有(*符号代表任意输入文件)输入文件的.text section合并成一个.text section, 该section的地址由定位器符号的值指定, 即0x10000.. = 0x8000000 :把定位器符号置为0x8000000.data : { *(.data) } : 将所有输入文件的.text section合并成一个.data section, 该section的地址被置为0x8000000..bss : { *(.bss) } : 将所有输入文件的.bss section合并成一个.bss section,该section的地址被置为0x8000000+.data section的大小.连接器每读完一个section描述后, 将定位器符号的值*增加*该section的大小. 注意: 此处没有考虑对齐约束.5. 简单脚本命令--------------------------------------------------------------------------------- 1 -ENTRY(SYMBOL) : 将符号SYMBOL的值设置成入口地址.入口地址(entry point): 进程执行的第一条用户空间的指令在进程地址空间的地址)ld有多种方法设置进程入口地址, 按一下顺序: (编号越前, 优先级越高)1, ld命令行的-e选项2, 连接脚本的ENTRY(SYMBOL)命令3, 如果定义了start符号, 使用start符号值4, 如果存在.text section, 使用.text section的第一字节的位置值5, 使用值0- 2 -INCLUDE filename : 包含其他名为filename的链接脚本相当于c程序内的的#include指令, 用以包含另一个链接脚本.脚本搜索路径由-L选项指定. INCLUDE指令可以嵌套使用, 最大深度为10. 即: 文件1内INCLUDE文件2, 文件2内INCLUDE文件3... , 文件10内INCLUDE文件11. 那么文件11内不能再出现INCLUDE指令了.- 3 -INPUT(files): 将括号内的文件做为链接过程的输入文件ld首先在当前目录下寻找该文件, 如果没找到, 则在由-L指定的搜索路径下搜索. file可以为-lfile形式,就象命令行的-l选项一样. 如果该命令出现在暗含的脚本内, 则该命令内的file在链接过程中的顺序由该暗含的脚本在命令行内的顺序决定.- 4 -GROUP(files) : 指定需要重复搜索符号定义的多个输入文件file必须是库文件, 且file文件作为一组被ld重复扫描,直到不在有新的未定义的引用出现.- 5 -OUTPUT(FILENAME) : 定义输出文件的名字同ld的-o选项, 不过-o选项的优先级更高. 所以它可以用来定义默认的输出文件名. 如a.out- 6 -SEARCH_DIR(PATH) :定义搜索路径,同ld的-L选项, 不过由-L指定的路径要比它定义的优先被搜索.- 7 -STARTUP(filename) : 指定filename为第一个输入文件在链接过程中, 每个输入文件是有顺序的. 此命令设置文件filename为第一个输入文件.- 8 -OUTPUT_FORMAT(BFDNAME) : 设置输出文件使用的BFD格式同ld选项-o format BFDNAME, 不过ld选项优先级更高.- 9 -OUTPUT_FORMAT(DEFAULT,BIG,LITTLE) : 定义三种输出文件的格式(大小端)若有命令行选项-EB, 则使用第2个BFD格式; 若有命令行选项-EL,则使用第3个BFD格式.否则默认选第一个BFD格式.TARGET(BFDNAME):设置输入文件的BFD格式同ld选项-b BFDNAME. 若使用了TARGET命令, 但未使用OUTPUT_FORMAT命令, 则最用一个TARGET命令设置的BFD格式将被作为输出文件的BFD 格式.另外还有一些:ASSERT(EXP, MESSAGE):如果EXP不为真,终止连接过程EXTERN(SYMBOL SYMBOL ...):在输出文件中增加未定义的符号,如同连接器选项-uFORCE_COMMON_ALLOCATION:为common symbol(通用符号)分配空间,即使用了-r连接选项也为其分配NOCROSSREFS(SECTION SECTION ...):检查列出的输出section,如果发现他们之间有相互引用,则报错.对于某些系统,特别是内存较紧张的嵌入式系统,某些section是不能同时存在内存中的,所以他们之间不能相互引用.OUTPUT_ARCH(BFDARCH):设置输出文件的machine architecture(体系结构),BFDARCH为被BFD库使用的名字之一.可以用命令objdump -f查看. 可通过man -S 1 ld查看ld的联机帮助, 里面也包括了对这些命令的介绍.6. 对符号的赋值--------------------------------------------------------------------------------在目标文件内定义的符号可以在链接脚本内被赋值. (注意和C语言中赋值的不同!) 此时该符号被定义为全局的. 每个符号都对应了一个地址, 此处的赋值是更改这个符号对应的地址.e.g. 通过下面的程序查看变量a的地址:/* a.c */#include <stdio.h>int a = 100;int main(void){printf( "&a=0x%p ", &a );return 0;}/* a.lds */a = 3;$ gcc -Wall -o a-without-lds a.c&a = 0x8049598$ gcc -Wall -o a-with-lds a.c a.lds&a = 0x3注意: 对符号的赋值只对全局变量起作用!一些简单的赋值语句能使用任何c语言内的赋值操作:SYMBOL = EXPRESSION ;SYMBOL += EXPRESSION ;SYMBOL -= EXPRESSION ;SYMBOL *= EXPRESSION ;SYMBOL /= EXPRESSION ;SYMBOL <<= EXPRESSION ;SYMBOL >>= EXPRESSION ;SYMBOL &= EXPRESSION ;SYMBOL |= EXPRESSION ;除了第一类表达式外, 使用其他表达式需要SYMBOL被定义于某目标文件.. 是一个特殊的符号,它是定位器,一个位置指针,指向程序地址空间内的某位置(或某section内的偏移,如果它在SECTIONS命令内的某section描述内),该符号只能在SECTIONS命令内使用.注意:赋值语句包含4个语法元素:符号名、操作符、表达式、分号;一个也不能少.被赋值后,符号所属的section被设值为表达式EXPRESSION所属的SECTION(参看11. 脚本内的表达式)赋值语句可以出现在连接脚本的三处地方:SECTIONS命令内,SECTIONS命令内的section描述内和全局位置;如下,floating_point = 0; /* 全局位置*/SECTIONS{.text :{*(.text)_etext = .; /* section描述内*/}_bdata = (. + 3) & ~ 4; /* SECTIONS命令内*/.data : { *(.data) }}PROVIDE关键字该关键字用于定义这类符号:在目标文件内被引用,但没有在任何目标文件内被定义的符号.例子:SECTIONS{.text :{*(.text)_etext = .;PROVIDE(etext = .);}}当目标文件内引用了etext符号,确没有定义它时,etext符号对应的地址被定义为.text section之后的第一个字节的地址.7. SECTIONS命令--------------------------------------------------------------------------------SECTIONS命令告诉ld如何把输入文件的sections映射到输出文件的各个section: 如何将输入section合为输出section; 如何把输出section放入程序地址空间(VMA)和进程地址空间(LMA).该命令格式如下:SECTIONS{SECTIONS-COMMANDSECTIONS-COMMAND...}SECTION-COMMAND有四种:(1) ENTRY命令(2) 符号赋值语句(3) 一个输出section的描述(output section description)(4) 一个section叠加描述(overlay description)如果整个连接脚本内没有SECTIONS命令, 那么ld将所有同名输入section合成为一个输出section内, 各输入section的顺序为它们被连接器发现的顺序. 如果某输入section没有在SECTIONS命令中提到, 那么该section将被直接拷贝成输出section.输出section描述输出section描述具有如下格式:SECTION [ADDRESS] [(TYPE)] : [AT(LMA)]{OUTPUT-SECTION-COMMANDOUTPUT-SECTION-COMMAND...} [>REGION] [AT>LMA_REGION] [:PHDR :PHDR ...] [=FILLEXP][ ]内的内容为可选选项, 一般不需要.SECTION:section名字SECTION左右的空白、圆括号、冒号是必须的,换行符和其他空格是可选的.每个OUTPUT-SECTION-COMMAND为以下四种之一,符号赋值语句一个输入section描述直接包含的数据值一个特殊的输出section关键字输出section名字(SECTION):输出section名字必须符合输出文件格式要求,比如:a.out格式的文件只允许存在.text、.data和.bss section名.而有的格式只允许存在数字名字,那么此时应该用引号将所有名字内的数字组合在一起;另外,还有一些格式允许任何序列的字符存在于section名字内,此时如果名字内包含特殊字符(比如空格、逗号等),那么需要用引号将其组合在一起.输出section地址(ADDRESS):ADDRESS是一个表达式,它的值用于设置VMA.如果没有该选项且有REGION选项,那么连接器将根据REGION设置VMA;如果也没有REGION选项,那么连接器将根据定位符号….‟的值设置该section的VMA,将定位符号的值调整到满足输出section对齐要求后的值,输出section的对齐要求为:该输出section描述内用到的所有输入section的对齐要求中最严格的.例子:.text . : { *(.text) }和.text : { *(.text) }这两个描述是截然不同的,第一个将.text section的VMA设置为定位符号的值,而第二个则是设置成定位符号的修调值,满足对齐要求后的.ADDRESS可以是一个任意表达式,比如ALIGN(0x10)这将把该section的VMA设置成定位符号的修调值,满足16字节对齐后的.注意:设置ADDRESS值,将更改定位符号的值.输入section描述:最常见的输出section描述命令是输入section描述.输入section描述是最基本的连接脚本描述.输入section描述基础:基本语法:FILENAME([EXCLUDE_FILE (FILENAME1 FILENAME2 ...) SECTION1 SECTION2 ...)FILENAME文件名,可以是一个特定的文件的名字,也可以是一个字符串模式.SECTION名字,可以是一个特定的section名字,也可以是一个字符串模式例子是最能说明问题的,*(.text) :表示所有输入文件的.text section(*(EXCLUDE_FILE (*crtend.o *otherfile.o) .ctors)) :表示除crtend.o、otherfile.o文件外的所有输入文件的.ctors section.data.o(.data) :表示data.o文件的.data sectiondata.o :表示data.o文件的所有section*(.text .data) :表示所有文件的.text section和.data section,顺序是:第一个文件的.text section,第一个文件的.data section,第二个文件的.text section,第二个文件的.data section,...*(.text) *(.data) :表示所有文件的.text section和.data section,顺序是:第一个文件的.text section,第二个文件的.text section,...,最后一个文件的.text section,第一个文件的.data section,第二个文件的.data section,...,最后一个文件的.data section下面看连接器是如何找到对应的文件的.当FILENAME是一个特定的文件名时,连接器会查看它是否在连接命令行内出现或在INPUT命令中出现.当FILENAME是一个字符串模式时,连接器仅仅只查看它是否在连接命令行内出现.注意:如果连接器发现某文件在INPUT命令内出现,那么它会在-L指定的路径内搜寻该文件.字符串模式内可存在以下通配符:* :表示任意多个字符? :表示任意一个字符[CHARS] :表示任意一个CHARS内的字符,可用-号表示范围,如:a-z:表示引用下一个紧跟的字符在文件名内,通配符不匹配文件夹分隔符/,但当字符串模式仅包含通配符*时除外.任何一个文件的任意section只能在SECTIONS命令内出现一次.看如下例子,SECTIONS {.data : { *(.data) }.data1 : { data.o(.data) }}data.o文件的.data section在第一个OUTPUT-SECTION-COMMAND命令内被使用了,那么在第二个OUTPUT-SECTION-COMMAND命令内将不会再被使用,也就是说即使连接器不报错,输出文件的.data1 section的内容也是空的.再次强调:连接器依次扫描每个OUTPUT-SECTION-COMMAND命令内的文件名,任何一个文件的任何一个section都只能使用一次.读者可以用-M连接命令选项来产生一个map文件,它包含了所有输入section到输出section的组合信息.再看个例子,SECTIONS {.text : { *(.text) }.DATA : { [A-Z]*(.data) }.data : { *(.data) }.bss : { *(.bss) }}这个例子中说明,所有文件的输入.text section组成输出.text section;所有以大写字母开头的文件的.data section组成输出.DATA section,其他文件的.data section组成输出.data section;所有文件的输入.bss section组成输出.bss section.可以用SORT()关键字对满足字符串模式的所有名字进行递增排序,如SORT(.text*).通用符号(common symbol)的输入section:在许多目标文件格式中,通用符号并没有占用一个section.连接器认为:输入文件的所有通用符号在名为COMMON的section内.例子,.bss { *(.bss) *(COMMON) }这个例子中将所有输入文件的所有通用符号放入输出.bss section内.可以看到COMMOM section的使用方法跟其他section的使用方法是一样的.有些目标文件格式把通用符号分成几类.例如,在MIPS elf目标文件格式中,把通用符号分成standard common symbols(标准通用符号)和small common symbols(微通用符号,不知道这么译对不对?),此时连接器认为所有standard common symbols在COMMON section内,而small common symbols 在.scommon section内.在一些以前的连接脚本内可以看见[COMMON],相当于*(COMMON),不建议继续使用这种陈旧的方式.输入section和垃圾回收:在连接命令行内使用了选项--gc-sections后,连接器可能将某些它认为没用的section过滤掉,此时就有必要强制连接器保留一些特定的section,可用KEEP()关键字达此目的.如KEEP(*(.text))或KEEP(SORT(*)(.text))最后看个简单的输入section相关例子:SECTIONS {outputa 0x10000 :{all.ofoo.o (.input1)}outputb :{foo.o (.input2)foo1.o (.input1)}outputc :{*(.input1)*(.input2)}}本例中,将all.o文件的所有section和foo.o文件的所有(一个文件内可以有多个同名section).input1 section依次放入输出outputa section内,该section 的VMA是0x10000;将foo.o文件的所有.input2 section和foo1.o文件的所有.input1 section依次放入输出outputb section内,该section的VMA 是当前定位器符号的修调值(对齐后);将其他文件(非all.o、foo.o、foo1.o)文件的. input1 section和.input2 section放入输出outputc section内.在输出section存放数据命令:能够显示地在输出section内填入你想要填入的信息(这样是不是可以自己通过连接脚本写程序?当然是简单的程序).BYTE(EXPRESSION) 1 字节SHORT(EXPRESSION) 2 字节LOGN(EXPRESSION) 4 字节QUAD(EXPRESSION) 8 字节SQUAD(EXPRESSION) 64位处理器的代码时,8 字节输出文件的字节顺序big endianness 或little endianness,可以由输出目标文件的格式决定;如果输出目标文件的格式不能决定字节顺序,那么字节顺序与第一个输入文件的字节顺序相同.如:BYTE(1)、LANG(addr).注意,这些命令只能放在输出section描述内,其他地方不行.错误:SECTIONS { .text : { *(.text) } LONG(1) .data : { *(.data) } }正确:SECTIONS { .text : { *(.text) LONG(1) } .data : { *(.data) } }在当前输出section内可能存在未描述的存储区域(比如由于对齐造成的空隙),可以用FILL(EXPRESSION)命令决定这些存储区域的内容,EXPRESSION 的前两字节有效,这两字节在必要时可以重复被使用以填充这类存储区域.如FILE(0x9090).在输出section描述中可以有=FILEEXP属性,它的作用如同FILE()命令,但是FILE命令只作用于该FILE指令之后的section区域,而=FILEEXP属性作用于整个输出section区域,且FILE命令的优先级更高!!!输出section内命令的关键字:CREATE_OBJECT_SYMBOLS :为每个输入文件建立一个符号,符号名为输入文件的名字.每个符号所在的section是出现该关键字的section. CONSTRUCTORS :与c++内的(全局对象的)构造函数和(全局对像的)析构函数相关,下面将它们简称为全局构造和全局析构.对于a.out目标文件格式,连接器用一些不寻常的方法实现c++的全局构造和全局析构.当连接器生成的目标文件格式不支持任意section名字时,比如说ECOFF、XCOFF格式,连接器将通过名字来识别全局构造和全局析构,对于这些文件格式,连接器把与全局构造和全局析构的相关信息放入出现CONSTRUCTORS关键字的输出section内.符号__CTORS_LIST__表示全局构造信息的的开始处,__CTORS_END__表示全局构造信息的结束处.符号__DTORS_LIST__表示全局构造信息的的开始处,__DTORS_END__表示全局构造信息的结束处.这两块信息的开始处是一字长的信息,表示该块信息有多少项数据,然后以值为零的一字长数据结束.一般来说,GNU C++在函数__main内安排全局构造代码的运行,而__main函数被初始化代码(在main函数调用之前执行)调用.是不是对于某些目标文件格式才这样???对于支持任意section名的目标文件格式,比如COFF、ELF格式,GNU C++将全局构造和全局析构信息分别放入.ctors section和.dtors section内,然后在连接脚本内加入如下,__CTOR_LIST__ = .;LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)*(.ctors)LONG(0)__CTOR_END__ = .;__DTOR_LIST__ = .;LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)*(.dtors)LONG(0)__DTOR_END__ = .;如果使用GNU C++提供的初始化优先级支持(它能控制每个全局构造函数调用的先后顺序),那么请在连接脚本内把CONSTRUCTORS替换成SORT (CONSTRUCTS),把*(.ctors)换成*(SORT(.ctors)),把*(.dtors)换成*(SORT(.dtors)).一般来说,默认的连接脚本已作好的这些工作.输出section的丢弃:例子,.foo { *(.foo) },如果没有任何一个输入文件包含.foo section,那么连接器将不会创建.foo输出section.但是如果在这些输出section描述内包含了非输入section描述命令(如符号赋值语句),那么连接器将总是创建该输出section.有一个特殊的输出section,名为/DISCARD/,被该section引用的任何输入section将不会出现在输出文件内,这就是DISCARD的意思吧.如果/DISCARD/ section被它自己引用呢?想想看.输出section属性:终于讲到这里了,呵呵.我们再回顾以下输出section描述的文法:SECTION [ADDRESS] [(TYPE)] : [AT(LMA)]{OUTPUT-SECTION-COMMANDOUTPUT-SECTION-COMMAND...} [>REGION] [AT>LMA_REGION] [:PHDR :PHDR ...] [=FILLEXP]前面我们浏览了SECTION、ADDRESS、OUTPUT-SECTION-COMMAND相关信息,下面我们将浏览其他属性.TYPE :每个输出section都有一个类型,如果没有指定TYPE类型,那么连接器根据输出section引用的输入section的类型设置该输出section的类型.它可以为以下五种值,NOLOAD :该section在程序运行时,不被载入内存.DSECT,COPY,INFO,OVERLAY :这些类型很少被使用,为了向后兼容才被保留下来.这种类型的section必须被标记为“不可加载的”,以便在程序运行不为它们分配内存.输出section的LMA :默认情况下,LMA等于VMA,但可以通过关键字AT()指定LMA.用关键字AT()指定,括号内包含表达式,表达式的值用于设置LMA.如果不用AT()关键字,那么可用AT>LMA_REGION表达式设置指定该section加载地址的范围.这个属性主要用于构件ROM境象.例子,SECTIONS{.text 0x1000 : { *(.text) _etext = . ; }.mdata 0x2000 :AT ( ADDR (.text) + SIZEOF (.text) ){ _data = . ; *(.data); _edata = . ; }.bss 0x3000 :{ _bstart = . ; *(.bss) *(COMMON) ; _bend = . ;}}程序如下,extern char _etext, _data, _edata, _bstart, _bend;char *src = &_etext;char *dst = &_data;/* ROM has data at end of text; copy it. */while (dst < &_edata) {*dst++ = *src++;}/* Zero bss */for (dst = &_bstart; dst< &_bend; dst++)*dst = 0;此程序将处于ROM内的已初始化数据拷贝到该数据应在的位置(VMA地址),并将为初始化数据置零.读者应该认真的自己分析以上连接脚本和程序的作用.输出section区域:可以将输出section放入预先定义的内存区域内,例子,MEMORY { rom : ORIGIN = 0x1000, LENGTH = 0x1000 }SECTIONS { ROM : { *(.text) } >rom }输出section所在的程序段:可以将输出section放入预先定义的程序段(program segment)内.如果某个输出section设置了它所在的一个或多个程序段,那么接下来定义的输出section的默认程序段与该输出section的相同.除非再次显示地指定.例子,PHDRS { text PT_LOAD ; }SECTIONS { .text : { *(.text) } :text }可以通过:NONE指定连接器不把该section放入任何程序段内.详情请查看PHDRS命令输出section的填充模版:这个在前面提到过,任何输出section描述内的未指定的内存区域,连接器用该模版填充该区域.用法:=FILEEXP,前两字节有效,当区域大于两字节时,重复使用这两字节以将其填满.例子,SECTIONS { .text : { *(.text) } =0x9090 }覆盖图(overlay)描述:覆盖图描述使两个或多个不同的section占用同一块程序地址空间.覆盖图管理代码负责将section的拷入和拷出.考虑这种情况,当某存储块的访问速度比其他存储块要快时,那么如果将section拷到该存储块来执行或访问,那么速度将会有所提高,覆盖图描述就很适合这种情形.文法如下,SECTIONS {...OVERLAY [START] : [NOCROSSREFS] [AT ( LDADDR )]{SECNAME1{OUTPUT-SECTION-COMMANDOUTPUT-SECTION-COMMAND...} [:PHDR...] [=FILL]SECNAME2{OUTPUT-SECTION-COMMANDOUTPUT-SECTION-COMMAND...} [:PHDR...] [=FILL]...} [>REGION] [:PHDR...] [=FILL]...}由以上文法可以看出,同一覆盖图内的section具有相同的VMA.SECNAME2的LMA为SECTNAME1的LMA加上SECNAME1的大小,同理计算SECNAME2,3,4...的LMA.SECNAME1的LMA由LDADDR决定,如果它没有被指定,那么由START决定,如果它也没有被指定,那么由当前定位符号的值决定.NOCROSSREFS关键字指定各section之间不能交叉引用,否则报错.对于OVERLAY描述的每个section,连接器将定义两个符号__load_start_SECNAME和__load_stop_SECNAME,这两个符号的值分别代表SECNAME section的LMA地址的开始和结束.连接器处理完OVERLAY描述语句后,将定位符号的值加上所有覆盖图内section大小的最大值.看个例子吧,SECTIONS{...OVERLAY 0x1000 : AT (0x4000){.text0 { o1/*.o(.text) }.text1 { o2/*.o(.text) }}...}.text0 section和.text1 section的VMA地址是0x1000,.text0 section加载于地址0x4000,.text1 section紧跟在其后.程序代码,拷贝.text1 section代码,extern char __load_start_text1, __load_stop_text1;memcpy ((char *) 0x1000, &__load_start_text1,&__load_stop_text1 - &__load_start_text1);8. 内存区域命令---------------注意:以下存储区域指的是在程序地址空间内的.在默认情形下,连接器可以为section分配任意位置的存储区域.你也可以用MEMORY命令定义存储区域,并通过输出section描述的> REGION属性显示地将该输出section限定于某块存储区域,当存储区域大小不能满足要求时,连接器会报告该错误.MEMORY命令的文法如下,MEMORY {NAME1 [(ATTR)] : ORIGIN = ORIGIN1, LENGTH = LEN2NAME2 [(ATTR)] : ORIGIN = ORIGIN2, LENGTH = LEN2...}NAME :存储区域的名字,这个名字可以与符号名、文件名、section名重复,因为它处于一个独立的名字空间.ATTR :定义该存储区域的属性,在讲述SECTIONS命令时提到,当某输入section没有在SECTIONS命令内引用时,连接器会把该输入section直接拷贝成输出section,然后将该输出section放入内存区域内.如果设置了内存区域设置了ATTR属性,那么该区域只接受满足该属性的section(怎么判断该section是否满足?输出section描述内好象没有记录该section的读写执行属性).ATTR属性内可以出现以下7个字符,R 只读sectionW 读/写sectionX 可执行sectionA …可分配的‟sectionI 初始化了的sectionL 同I! 不满足该字符之后的任何一个属性的sectionORIGIN :关键字,区域的开始地址,可简写成org或oLENGTH :关键字,区域的大小,可简写成len或l例子,MEMORY{rom (rx) : ORIGIN = 0, LENGTH = 256Kram (!rx) : org = 0x40000000, l = 4M}此例中,把在SECTIONS命令内*未*引用的且具有读属性或写属性的输入section放入rom区域内,把其他未引用的输入section放入ram.如果某输出section要被放入某内存区域内,而该输出section又没有指明ADDRESS属性,那么连接器将该输出section放在该区域内下一个能使用位置.9. PHDRS命令------------该命令仅在产生ELF目标文件时有效.ELF目标文件格式用program headers程序头(程序头内包含一个或多个segment程序段描述)来描述程序如何被载入内存.可以用objdump -p命令查看. 当在本地ELF系统运行ELF目标文件格式的程序时,系统加载器通过读取程序头信息以知道如何将程序加载到内存.要了解系统加载器如何解析程序头,请参考ELF ABI文档.在连接脚本内不指定PHDRS命令时,连接器能够很好的创建程序头,但是有时需要更精确的描述程序头,那么PAHDRS命令就派上用场了.注意:一旦在连接脚本内使用了PHDRS命令,那么连接器**仅会**创建PHDRS命令指定的信息,所以使用时须谨慎.PHDRS命令文法如下,PHDRS{NAME TYPE [ FILEHDR ] [ PHDRS ] [ AT ( ADDRESS ) ][ FLAGS ( FLAGS ) ] ;}其中FILEHDR、PHDRS、AT、FLAGS为关键字.NAME :为程序段名,此名字可以与符号名、section名、文件名重复,因为它在一个独立的名字空间内.此名字只能在SECTIONS命令内使用.一个程序段可以由多个…可加载‟的section组成.通过输出section描述的属性:PHDRS可以将输出section加入一个程序段,: PHDRS中的PHDRS为程序。
C之bss、data存储位置区分,使用objdump-t反汇编查看变量所处存储位置
![C之bss、data存储位置区分,使用objdump-t反汇编查看变量所处存储位置](https://img.taocdn.com/s3/m/852f71c5b04e852458fb770bf78a6529657d355f.png)
objdump -t main.o | grep "\.bss" 0000000000600810 l d .bss 0000000000000000 0000000000600810 l O .bss 0000000000000001 0000000000600818 l O .bss 0000000000000008 0000000000600824 l O .bss 0000000000000004 0000000000600828 l O .bss 0000000000000004 0000000000600820 g O .bss 0000000000000004 000000000060082c g O .bss 0000000000000004
return 0; }
将main.c编译为汇编语言:gcc main.c -o main.o
objdump -t main.o | grep "\.data" 0000000000600800 l d .data 0000000000000000 0000000000600808 l O .data 0000000000000004 0000000000600800 w .data 0000000000000000 0000000000600800 g .data 0000000000000000 0000000000600804 g O .data 0000000000000004
objdump反汇编插入代码段
![objdump反汇编插入代码段](https://img.taocdn.com/s3/m/67ace1c282d049649b6648d7c1c708a1294a0a55.png)
Objdump是一个用于查看目标文件(如可执行文件、目标文件、共享库文件)的工具,它可以展示文件的相关信息,包括反汇编的代码段。
本文将介绍如何使用objdump进行反汇编,并插入代码段进行分析。
二、Objdump的基本用法1. 安装objdump在Linux系统中,objdump通常随着binutils一起安装,可以通过包管理器进行安装。
在Ubuntu系统中,可以使用以下命令进行安装:```shellsudo apt-get install binutils```2. 查看目标文件信息使用objdump可以查看目标文件的相关信息,比如符号表、段表、符号位置区域等。
可以使用以下命令进行查看:```shellobjdump -h -S <file>```其中,-h选项用于显示段表信息,-S选项用于显示反汇编代码。
3. 反汇编代码段使用objdump可以对目标文件进行反汇编,从而查看其汇编代码。
可以使用以下命令进行反汇编:objdump -d <file>```其中,-d选项用于显示反汇编代码。
三、插入代码段进行分析1. 生成汇编代码在进行反汇编分析之前,我们首先需要得到目标文件的汇编代码。
可以使用gcc命令将源文件编译成汇编代码,例如:```shellgcc -S <source_file.c>```这将生成一个以.s为后缀的汇编代码文件。
2. 汇编代码段插入将汇编代码段插入到目标文件的反汇编结果中,可以使用objdump 的反汇编选项和插入汇编代码的命令。
例如:```shellobjdump -d <file> > disassembly_code.txt```打开生成的disassembly_code.txt文件,在需要插入汇编代码段的地方进行插入,并保存文件。
3. 分析插入的代码段在插入汇编代码段后,可以通过对代码进行逐行分析,查看反汇编结果与源代码的对应关系,从而更好地理解目标文件的执行流程和代码逻辑。
objdump ghs编译
![objdump ghs编译](https://img.taocdn.com/s3/m/e714f8f1a0c7aa00b52acfc789eb172ded6399fb.png)
objdump ghs编译(最新版)目录1.objdump 和 ghs 编译简介2.objdump 的功能和用法3.ghs 编译器的特点和应用4.使用 objdump 进行 ghs 编译的实例正文1.objdump 和 ghs 编译简介objdump 是一个用于解析和转换目标文件格式的工具,通常用于编译器和链接器中。
它可以将编译后的目标文件转换成不同的格式,如汇编语言、C 语言等。
ghs 编译器(GCC Hello World Compiler)是一个基于 GCC (GNU Compiler Collection)的简单编译器,用于教授编程语言和编译器原理。
2.objdump 的功能和用法objdump 的主要功能包括:- 显示目标文件的结构和内容- 转换目标文件格式,如将二进制文件转换成汇编语言文件- 提取目标文件中的符号和数据objdump 的基本用法如下:```objdump [options] object-file```其中,object-file 是待解析的目标文件,options 是可选的参数。
例如,要显示一个名为“example.o”的目标文件的结构,可以使用以下命令:```objdump -f example.o```3.ghs 编译器的特点和应用ghs 编译器具有以下特点:- 基于 GCC,具有 GCC 的强大功能和优化- 用于教授编程语言和编译器原理,易于学习和使用- 支持多种编程语言,如 C、C++、Fortran 等ghs 编译器广泛应用于教育、研究和开发领域,可以帮助用户更好地理解编译器的工作原理和编程语言的实现。
4.使用 objdump 进行 ghs 编译的实例假设我们使用 ghs 编译器编写了一个简单的 C 语言程序,如下所示:```c#include <stdio.h>int main() {printf("Hello, world!");return 0;}```使用 ghs 编译器编译该程序,可以得到一个名为“hello.o”的目标文件。
objdump ghs编译
![objdump ghs编译](https://img.taocdn.com/s3/m/88f8b0a650e79b89680203d8ce2f0066f533649c.png)
objdump ghs编译【原创版】目录1.objdump 的概述2.ghs 编译器的简介3.objdump 与 ghs 编译器的关系4.使用 objdump 进行 ghs 编译的步骤5.编译过程中可能遇到的问题及解决方法正文1.objdump 的概述objdump 是一个用于解析和转换目标文件格式的工具,通常用于获取和分析编译后的程序。
它可以将目标文件转换成较为易读的形式,方便程序员查看和理解程序的结构。
objdump 支持多种目标文件格式,如 ELF、COFF 等。
2.ghs 编译器的简介ghs(GCC High-Level Optimizing Compiler)是 GCC(GNU Compiler Collection)编译器套件中的一个重要组成部分,主要用于编译 C 和 C++语言的源代码。
ghs 编译器通过对源代码进行优化,可以生成更高效的可执行文件。
3.objdump 与 ghs 编译器的关系objdump 和 ghs 编译器在编译过程中的作用不同,但它们之间存在紧密的联系。
当使用 ghs 编译器编译源代码时,编译器会生成一个目标文件(如 ELF 格式的可执行文件),然后可以使用 objdump 工具对这个目标文件进行反汇编,从而查看程序的结构和代码。
4.使用 objdump 进行 ghs 编译的步骤下面是一个简单的使用 objdump 进行 ghs 编译的步骤示例:(1)编写 C 或 C++源代码(2)使用 ghs 编译器编译源代码:`g++ -o output source_code.c`(假设源代码文件名为 source_code.c)(3)使用 objdump 工具查看编译后的目标文件:`objdump -d output`(4)查看反汇编后的代码:`less -S output.dis`(假设输出文件名为 output.dis)5.编译过程中可能遇到的问题及解决方法在编译过程中,可能会遇到一些问题,如编译器无法识别源代码文件类型、目标文件无法生成等。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
gcc命令之objdump 收藏---------------objdump是用查看目标文件或者可执行的目标文件的构成的gcc工具---------------以下3条命令足够那些喜欢探索目标文件与源代码之间的丝丝的关系的朋友。
objdump -x obj 以某种分类信息的形式把目标文件的数据组织(被分为几大块)输出<可查到该文件的所有动态库>objdump -t obj 输出目标文件的符号表()objdump -h obj 输出目标文件的所有段概括()objdump -j .text/.data -S obj 输出指定段的信息,大概就是反汇编源代码把objdump -S obj C语言与汇编语言同时显示以下为网上摘录文章。
关于nm -s的显示请自己man nm查看objdump命令的man手册objdump - 显示二进制文件信息objdump[-a] [-b bfdname |--target=bfdname] [-C] [--debugging][-d] [-D][--disassemble-zeroes][-EB|-EL|--endian={big|little}] [-f][-h] [-i|--info][-j section | --section=section][-l] [-m machine ] [--prefix-addresses][-r] [-R][-s|--full-contents] [-S|--source][--[no-]show-raw-insn] [--stabs] [-t][-T] [-x][--start-address=address] [--stop-address=address][--adjust-vma=offset] [--version] [--help]objfile...--archive-headers-a 显示档案库的成员信息,与ar tv 类似objdump -a libpcap.a和ar -tv libpcap.a 显示结果比较比较显然这个选项没有什么意思。
--adjust-vma=offsetWhen dumping information, first add offset to allthe section addresses. This is useful if the sec-tion addresses do not correspond to the symboltable, which can happen when putting sections atparticular addresses when using a format which cannot represent section addresses, such as a.out.-b bfdname--target=bfdname指定目标码格式。
这不是必须的,objdump能自动识别许多格式,比如:objdump -b oasys -m vax -h fu.o显示fu.o的头部摘要信息,明确指出该文件是Vax系统下用Oasys编译器生成的目标文件。
objdump -i将给出这里可以指定的目标码格式列表--demangle-C 将底层的符号名解码成用户级名字,除了去掉所有开头的下划线之外,还使得C++函数名以可理解的方式显示出来。
--debugging显示调试信息。
企图解析保存在文件中的调试信息并以C语言的语法显示出来。
仅仅支持某些类型的调试信息。
--disassemble-d 反汇编那些应该还有指令机器码的section--disassemble-all-D 与-d 类似,但反汇编所有section--prefix-addresses反汇编的时候,显示每一行的完整地址。
这是一种比较老的反汇编格式。
显示效果并不理想,但可能会用到其中的某些显示,自己可以对比。
--disassemble-zeroes一般反汇编输出将省略大块的零,该选项使得这些零块也被反汇编。
-EB-EL--endian={big|little}这个选项将影响反汇编出来的指令。
little-endian就是我们当年在dos下玩汇编的时候常说的高位在高地址,x86都是这种。
--file-headers-f 显示objfile中每个文件的整体头部摘要信息。
--section-headers--headers-h 显示目标文件各个section的头部摘要信息。
--help 简短的帮助信息。
--info-i 显示对于-b 或者-m 选项可用的架构和目标格式列表。
--section=name-j name 仅仅显示指定section的信息--line-numbers-l 用文件名和行号标注相应的目标代码,仅仅和-d、-D或者-r一起使用使用-ld和使用-d的区别不是很大,在源码级调试的时候有用,要求编译时使用了-g之类的调试编译选项。
--architecture=machine-m machine指定反汇编目标文件时使用的架构,当待反汇编文件本身没有描述架构信息的时候(比如S-records),这个选项很有用。
可以用-i选项列出这里能够指定的架构--reloc-r 显示文件的重定位入口。
如果和-d或者-D一起使用,重定位部分以反汇编后的格式显示出来。
--dynamic-reloc-R 显示文件的动态重定位入口,仅仅对于动态目标文件有意义,比如某些共享库。
--full-contents-s 显示指定section的完整内容。
objdump --section=.text -s inet.o | more--source-S 尽可能反汇编出源代码,尤其当编译的时候指定了-g这种调试参数时,效果比较明显。
隐含了-d参数。
--show-raw-insn反汇编的时候,显示每条汇编指令对应的机器码,除非指定了--prefix-addresses,这将是缺省选项。
--no-show-raw-insn反汇编时,不显示汇编指令的机器码,这是指定--prefix-addresses选项时的缺省设置。
--stabsDisplay the contents of the .stab, .stab.index, and.stab.excl sections from an ELF file. This is onlyuseful on systems (such as Solaris 2.0) in which.stab debugging symbol-table entries are carried inan ELF section. In most other file formats, debug-ging symbol-table entries are interleaved withlinkage symbols, and are visible in the --syms output.--start-address=address从指定地址开始显示数据,该选项影响-d、-r和-s选项的输出。
--stop-address=address显示数据直到指定地址为止,该选项影响-d、-r和-s选项的输出。
--syms-t 显示文件的符号表入口。
类似于nm -s提供的信息--dynamic-syms-T 显示文件的动态符号表入口,仅仅对动态目标文件有意义,比如某些共享库。
它显示的信息类似于nm -D|--dynamic 显示的信息。
--version 版本信息objdump --version--all-headers-x 显示所有可用的头信息,包括符号表、重定位入口。
-x 等价于-a -f -h -r -t 同时指定。
objdump -x inet.o参看nm(1)★objdump应用举例(待增加)/*g++ -g -Wstrict-prototypes -Wall -Wunused -o objtest objtest.c*/#include#includeint main ( int argc, char * argv[] ){execl( "/bin/sh", "/bin/sh", "-i", 0 );return 0;}g++ -g -Wstrict-prototypes -Wall -Wunused -o objtest objtest.cobjdump -j .text -Sl objtest | more/main(查找)08048750:main():/home/scz/src/objtest.c:7*/#include#includeint main ( int argc, char * argv[] ){8048750: 55 pushl %ebp 8048751: 89 e5 movl %esp,%ebp/home/scz/src/objtest.c:8execl( "/bin/sh", "/bin/sh", "-i", 0 );8048753: 6a 00 pushl $0x0 8048755: 68 d0 87 04 08 pushl $0x80487d0 804875a: 68 d3 87 04 08 pushl $0x80487d3 804875f: 68 d3 87 04 08 pushl $0x80487d3 8048764: e8 db fe ff ff call 8048644 <_init+0x40> 8048769: 83 c4 10 addl $0x10,%esp/home/scz/src/objtest.c:9return 0;804876c: 31 c0 xorl %eax,%eax 804876e: eb 04 jmp 8048774 8048770: 31 c0 xorl %eax,%eax 8048772: eb 00 jmp 8048774/home/scz/src/objtest.c:10}8048774: c9 leave8048775: c3 ret8048776: 90 nop如果说上面还不够清楚,可以用下面的命令辅助一下:objdump -j .text -Sl objtest --prefix-addresses | moreobjdump -j .text -Dl objtest | more用以上不同的命令去试会得到惊喜!。