dodle
November 27th, 2011, 03:41 PM
I have an archive, files.tgz, that I converted into an object file with objcopy and linked it into my executable. But, I have no idea of how to access it and extract it. Here is what I want to happen: When the executable is run files.tgz is extracted and placed into the directory.
I used readelf to find the tags in the executable:
$ readelf -a test | grep -i "files_tgz"
73: 0804a0a4 0 NOTYPE GLOBAL DEFAULT 25 _binary_files_tgz_end
75: 00000074 0 NOTYPE GLOBAL DEFAULT ABS _binary_files_tgz_size
80: 0804a030 0 NOTYPE GLOBAL DEFAULT 25 _binary_files_tgz_start
So now how do I use this in my code? Do I use a preprocessor to define the data?
#define _binary_files_tgz_end
#define _binary_files_tgz_size
#define _binary_files_tgz_start
I found the following at http://stackoverflow.com/questions/4864866/c-c-with-gcc-statically-add-resource-files-to-executable-library, but it is unclear to me what I need to do.
I have used objcopy (GNU binutils) to link the binary data from a file foo-data.bin into the data section of the executable:
objcopy -B i386 -I binary -O elf32-i386 foo-data.bin foo-data.o
This gives you a foo-data.o object file which you can link into your executable. The C interface looks something like
/** created from binary via objcopy */
extern uint8_t foo_data[] asm("_binary_foo_data_bin_start");
extern uint8_t foo_data_size[] asm("_binary_foo_data_bin_size");
extern uint8_t foo_data_end[] asm("_binary_foo_data_bin_end");
so you can do stuff like
for (uint8_t *byte=foo_data; byte<foo_data_end; ++byte) {
transmit_single_byte(*byte);
}
or
size_t foo_size = (size_t)((void *)foo_data_size;
void *foo_copy = malloc(foo_size);
memcpy(foo_copy, foo_data, foo_size);
If your target architecture has special constraints as to where constant and variable data is stored, or you want to store that data in the .text segment to make it fit into the same memory type as your program code, you can play with the objcopy parameters some more.
I used readelf to find the tags in the executable:
$ readelf -a test | grep -i "files_tgz"
73: 0804a0a4 0 NOTYPE GLOBAL DEFAULT 25 _binary_files_tgz_end
75: 00000074 0 NOTYPE GLOBAL DEFAULT ABS _binary_files_tgz_size
80: 0804a030 0 NOTYPE GLOBAL DEFAULT 25 _binary_files_tgz_start
So now how do I use this in my code? Do I use a preprocessor to define the data?
#define _binary_files_tgz_end
#define _binary_files_tgz_size
#define _binary_files_tgz_start
I found the following at http://stackoverflow.com/questions/4864866/c-c-with-gcc-statically-add-resource-files-to-executable-library, but it is unclear to me what I need to do.
I have used objcopy (GNU binutils) to link the binary data from a file foo-data.bin into the data section of the executable:
objcopy -B i386 -I binary -O elf32-i386 foo-data.bin foo-data.o
This gives you a foo-data.o object file which you can link into your executable. The C interface looks something like
/** created from binary via objcopy */
extern uint8_t foo_data[] asm("_binary_foo_data_bin_start");
extern uint8_t foo_data_size[] asm("_binary_foo_data_bin_size");
extern uint8_t foo_data_end[] asm("_binary_foo_data_bin_end");
so you can do stuff like
for (uint8_t *byte=foo_data; byte<foo_data_end; ++byte) {
transmit_single_byte(*byte);
}
or
size_t foo_size = (size_t)((void *)foo_data_size;
void *foo_copy = malloc(foo_size);
memcpy(foo_copy, foo_data, foo_size);
If your target architecture has special constraints as to where constant and variable data is stored, or you want to store that data in the .text segment to make it fit into the same memory type as your program code, you can play with the objcopy parameters some more.