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

2

18

I would like to produce a file that I can load into memory (for example with mmap) and then jump to the start of that memory to run the code.

Ideally, I'd like the option of either making the code relocatable (which might be inefficient) or specifying an explicit address that the code expects to be loaded at (which is a pain), but either one would probably work fine on its own.

Murry answered 1/9, 2010 at 6:0 Comment(4)
isn't this what an object file is?Wojcik
no, at the very least, object files contain information on what symbols they export (for use by the linker)Murry
Any specific reason you don't want to use a dll/shared library instead? There's a lot of pitfalls with raw binaries.Footloose
@snemarch, I know that, and if I were trying to write a library or plugin system, I would use a shared object, but I'm not doing that. (mmap was a (bad) example, but the only good ones I can think of involve bios calls or the poking of device control registers, which I didnt want look up)Murry
U
16

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.

Underbred answered 1/9, 2010 at 6:35 Comment(4)
+1, I knew there was something that did this. Do you know whether I need to load this at a specific address?Murry
Yes you will. It will be the address that the linker was told to link at. Note that you don't normally see the linker's control file, so you may not know where that is....Pagurian
Where would I find the control file?Murry
Try ld --verbose or to make sure your seeing the name of the real one, gcc -Wl,--verbose. You'll need to search through the verbose stuff a bit ;-). I've added a link to the relevant bit of the ld manual in my answer.Pagurian
P
8

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.

Pagurian answered 1/9, 2010 at 6:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.