How to make gcc generate only machine code that can be loaded directly into memory and executed?

依然范特西╮ 提交于 2019-11-28 08:20:48

You can do this but you will need to go through the object file format. In particular, the objcopy command can transform an executable file to a "flat" binary file (depending on your target platform). Perhaps something like this:

gcc -o test test.c
objcopy -O binary test test.bin

See man objcopy on your platform for more details.

You want to know about the utility objcopy, which is usually available along with GCC. It is a component of the binutils package of tools, the most visible member of which is the linker, ld.

The process is that you compile your source file(s) and link them generally as usual. That gives you a finished executable in elf (or another relocatable platform-dependent binary) format. You then use objcopy to transform the executable to a flat binary image.

This is most useful for preparing code to be run from ROM, where you would want to make sure you are using a suitable C runtime library for your target platform, and likely need to customize the linker script file as well as provide your own C runtime startup code.

If your goal is to get something that is sort of like a .so file, to be loaded into an existing process, then be aware that some of the work of the shared library loader is to actually finish linking so that symbols in the .so file that refer to addresses in the main executable (or other .so files) get resolved at load time. Using objcopy won't do that, and so it might be difficult for functions loaded this way to properly use your existing C runtime library and objects it maintains such as open files.

Regardless of your goals, you are going to need to seize control of the linker in order to locate your binary at a known address. To do that, you will need to craft a linker script. Documentation for the script language is in the binutils manual. You will be primarily interested in the ".text*" sections, and possibly in the ".rodata*" sections if you plan to have any initialized global variables. Actually arranging for that initialization is left as an exercise for the reader.

Overall, this is just the tip of a very large iceberg. I'd suggest spending some time with a cross compiler build to see how these things are used in practice. The AVR and MSP430 communities use GCC, have active participation, and inexpensive (and often even open source) hardware to get started.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!