有没有办法让 gcc 输出原始二进制文件?
- 2024-10-30 08:36:00
- admin 原创
- 43
问题描述:
是否有一组命令行选项可以说服 gcc 从自包含源文件生成平面二进制文件?例如,假设 foo.c 的内容是
static int f(int x)
{
int y = x*x;
return y+2;
}
没有外部引用,无需导出到链接器。我想获取一个只有该函数的机器指令的小文件,不带任何其他修饰。有点像 (DOS) .COM 文件,只是 32 位保护模式。
解决方案 1:
尝试一下:
$ gcc -c test.c
$ objcopy -O binary -j .text 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
解决方案 2:
您可以使用以下方式直接将选项传递给链接器-Wl,<linker option>
相关文件摘自man gcc
-Wl,option
将 option 作为选项传递给链接器。如果 option 包含逗号,则会在逗号处将其拆分为多个选项。您可以使用此语法将参数传递给选项。例如,-Wl,-Map,output.map 将 -Map output.map 传递给链接器。使用 GNU 链接器时,您也可以使用 -Wl,-Map=output.map 获得相同的效果。
因此,当使用 gcc 进行编译时,如果通过,-Wl,--oformat=binary
您将生成一个二进制文件,而不是 elf 格式。哪里--oformat=binary
告诉ld
生成一个二进制文件。
这样就无需objcopy
单独进行。
请注意,可以在链接器脚本--oformat=binary
中表示为。如果您想处理平面二进制文件,则很有可能从链接器脚本提供的高级别控制中受益。OUTPUT_FORMAT("binary")
解决方案 3:
您可以使用objcopy
将文本段从.o 文件或 a.out 文件中提取出来。
$ cat q.c
f() {}
$ cc -S -O q.c
$ cat q.s
.file "q.c"
.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 q.c
$ objcopy -O binary q.o q.bin
$ od -X q.bin
0000000 5de58955 000000c3
0000005
$ objdump -d q.o
q.o: 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
解决方案 4:
其他答案肯定是正确的。但是,我必须为 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 个小时阅读并尝试不同的选项才弄清楚。希望这能节省其他人的时间。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件