I learned a useful trick today for embedding arbitrary data in an ELF executable. This is an easy way bundle RAM disks and other resources when you’re running on bare hardware.
The first step is to turn our binary data into an ELF object file:
echo yahyahyah > yah objcopy -I binary -O elf32-i386 -B i386 \ --rename-section .data=.yah yah yah.o
The -I
and -O
mean we are converting from raw binary to our target format elf32-i386. The -B
option sets the architecture field of the output file: this is required by ld. By default the binary data is placed in the .data
section; --rename-section
changes this to a name we can refer to in our linker script. You can omit this flag if you don’t care about the layout of your executable.
nick@pickle:~$ objdump -x yah.o yah.o: file format elf32-i386 yah.o architecture: i386, flags 0x00000010: HAS_SYMS start address 0x00000000 Sections: Idx Name Size VMA LMA File off Algn 0 .yah 0000000a 00000000 00000000 00000034 2**0 CONTENTS, ALLOC, LOAD, DATA SYMBOL TABLE: 00000000 l d .yah 00000000 .yah 00000000 g .yah 00000000 _binary_yah_start 0000000a g .yah 00000000 _binary_yah_end 0000000a g *ABS* 00000000 _binary_yah_size
You can see objcopy has created three symbols which we can use to access the data at runtime like so:
extern void _binary_yah_start, _binary_yah_end; extern void _binary_yah_size; void *yah = &_binary_yah_start; size_t yah_size = (size_t)&_binary_yah_size;
By renaming the output section we can place the data wherever we like using a linker script like this:
.yah : AT(some_address) { *(.yah) . = ALIGN(4096); /* Optional */ }
What fun! Hopefully someone will find it useful.
Something important that drove me nuts was that the order in which you list this object on a gcc compile line matters. I was getting very elusive errors until I put the object file before the C file.
May 8, 2010 @ 1:08 pm
Also, I just wanted to thank you for posting this info. It’s the best guide to embedding data into an object file I’ve found. It works, and I you taught me how to rename stuff in an object file. With a bit more digging I found you can also change _binary_yah_start to what ever you want like this…
objcopy –redefine-sym _binary_yah_start=_pink
May 8, 2010 @ 1:14 pm
Thanks, I appreciate it!
May 9, 2010 @ 5:47 pm