是否有一组命令行选项可以说服gcc从自包含的源文件生成一个平面的二进制文件? 例如,假设foo.c的内容是
static int f(int x) { int y = x*x; return y+2; }
没有外部引用,没有什么要导出到链接器。 我想用这个function的机器指令来得到一个小文件,没有任何其他装饰。 有点像(DOS).COM文件,除了32位保护模式。
试试这个:
$ cc -c test.c $ objcopy -O binary test.o binfile
你可以确定它是正确的objdump
:
$ objdump -d test.o test.o: file format pe-i386 Disassembly of section .text: 00000000 <_f>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 83 ec 04 sub $0x4,%esp 6: 8b 45 08 mov 0x8(%ebp),%eax 9: 0f af 45 08 imul 0x8(%ebp),%eax d: 89 45 fc mov %eax,-0x4(%ebp) 10: 8b 45 fc mov -0x4(%ebp),%eax 13: 83 c0 02 add $0x2,%eax 16: c9 leave 17: c3 ret
和二进制文件比较:
$ hexdump -C binfile 00000000 55 89 e5 83 ec 04 8b 45 08 0f af 45 08 89 45 fc |U......E...E..E.| 00000010 8b 45 fc 83 c0 02 c9 c3 |.E......| 00000018
您可以使用objcopy
将文本段拉出.o文件或a.out文件。
$ cat qc f() {} $ cc -S -O qc $ cat qs .file "qc" .text .globl f .type f, @function f: pushl %ebp movl %esp, %ebp popl %ebp ret .size f, .-f .ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3" .section .note.GNU-stack,"",@progbits $ cc -c -O qc $ objcopy -O binary qo q.bin $ od -X q.bin 0000000 5de58955 000000c3 0000005 $ objdump -d qo qo: file format elf32-i386 Disassembly of section .text: 00000000 <f>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 5d pop %ebp 4: c3 ret
其他答案肯定是要走的路。 但是,我不得不指定额外的命令行参数objcopy为了我的输出是预期的。 请注意,我正在开发64位机器上的32位代码,因此是-m32
参数。 此外,我更喜欢英特尔汇编语法,所以你也会在参数中看到。
$ cat test.c int main() { return 0; } $ gcc -nostdinc -m32 -masm=intel -Wall -c test.c -o test.o $ objdump --disassemble --disassembler-options intel test.o test.o: file format elf32-i386 Disassembly of section .text: 00000000 <main>: 0: 55 push ebp 1: 89 e5 mov ebp,esp 3: b8 00 00 00 00 mov eax,0x0 8: 5d pop ebp 9: c3 ret
好的,这里是我必须指定的地方,我特别只想要.text部分:
$ objcopy --only-section=.text --output-target binary test.o test.bin $ hexdump -C test.bin 00000000 55 89 e5 b8 00 00 00 00 5d c3 |U.......].| 0000000a
我花了大约2个小时的阅读和尝试不同的选择,才想出来。 希望这节省了其他人的时间。
您可以直接使用-Wl,<linker option>
将选项传递给链接-Wl,<linker option>
相关文档从man gcc
下面复制
轮候册,选项
将选项作为选项传递给链接器。 如果选项包含逗号,则在逗号处将其拆分为多个选项。 您可以使用此语法将参数传递给选项。 例如,-Wl,-Map,output.map将-map output.map传递给链接器。 当使用GNU链接器时,你也可以用-Wl,-Map = output.map获得同样的效果。
所以,如果你通过-Wl,--oformat=binary
你将生成一个二进制文件,而不是elf格式。 其中--oformat=binary
告诉ld
生成一个二进制文件。
这消除了单独的objcopy
的需要。
请注意,– --oformat=binary
可以在链接器脚本中表示为OUTPUT_FORMAT("binary")
。 如果您想要处理平面二进制文件,那么您很有可能会从链接器脚本提供的高级别控制中受益。