I am tying to use objcopy
to include a binary form of a text file into an executable. (At runtime I need the file as a string). This works fine until the linker needs to find the references from the symbol names. The problem is that objcopy
prepends the symbol names with the pathname to the file. Since I am using GNU Autotools to ship the package this prepended pathname changes and I don't know what external linker symbol to use in the C/C++ program.
nm libtest.a |grep textfile
textfile.o:
00001d21 D _binary__home_git_textfile_end
00001d21 A _binary__home_git_textfile_size
00000000 D _binary__home_git_textfile_start
libtest.a
was produced with (extract from Makefile.am):
SUFFIXES = .txt
.txt.$(OBJEXT):
objcopy --input binary --output elf32-i386 --binary-architecture i386 $< $@
How can I tell objcopy
to only us the stem of the filename as linker symbols? Or is there another way around the problem?
Generic method of including raw data into ELF is supported by .incbin assembler directive.
The trick is to create template .S file that could look like this:
.global foo_start
foo_start:
.incbin "foo.raw"
.global foo_end
foo_end:
This file is preprocessed via cpp so we don't have to hardcode file name there, eg. we can write:
.incbin __raw_file_path__
... and then pass it while compiling:
gcc -D__raw_file_path__='"data/foo.png"' foo.S -c -o data/foo.o
Lastly, as we prepare .S file ourself we can add some extra data and/or information. If you include raw "text files" and want these to be available as C strings you can add '0' byte just after raw data:
.global foo_start
foo_start:
.incbin "foo.raw"
.global foo_end
foo_end:
.byte 0
.global foo_size
foo_size:
.int foo_end - foo_start
If you want full-blown flexibility, you can of course pre-process file manually to alter any part of it, eg.
.global @sym@_start
@sym@_start:
.incbin "@file@"
.global @sym@_end
@sym@_end:
... and then compile it:
sed -e "s,@sym@,passwd,g" -e "s,@file@,/etc/passwd," <foo.S.in | gcc -x assembler-with-cpp - -o passwd.o -c
Somewhat ironically you can use objcopy
to solve the problem via the --redefine-sym
option that allows renaming of symbols...
If I use objcopy to create an object file from a PNG in another directory:
$ objcopy -I binary -O elf64-x86-64 -B i386 --rename-section .data=.rodata,alloc,load,data,contents,readonly ../../resources/test.png test_png.o
The resulting object has the following symbols:
$readelf -s test_png.o -W Symbol table '.symtab' contains 5 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 SECTION LOCAL DEFAULT 1 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 1 _binary_______resources_test_png_start 3: 0000000000003aaa 0 NOTYPE GLOBAL DEFAULT 1 _binary_______resources_test_png_end 4: 0000000000003aaa 0 NOTYPE GLOBAL DEFAULT ABS _binary_______resources_test_png_size
These can then be renamed:
$objcopy --redefine-sym _binary_______resources_test_png_start=_binary_test_png_start test_png.o $objcopy --redefine-sym _binary_______resources_test_png_size=_binary_test_png_size test_png.o $objcopy --redefine-sym _binary_______resources_test_png_end=_binary_test_png_end test_png.o
Resulting in an object with the symbol names that objcopy would have generated if the PNG had been located in the current directory:
$readelf -s test_png.o -W Symbol table '.symtab' contains 5 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 SECTION LOCAL DEFAULT 1 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 1 _binary_test_png_start 3: 0000000000003aaa 0 NOTYPE GLOBAL DEFAULT 1 _binary_test_png_end 4: 0000000000003aaa 0 NOTYPE GLOBAL DEFAULT ABS _binary_test_png_size
Another alternative which I have used is to cd
to the source directory and then give objcopy
the basename of the source. In bash
, this would be:
cd $(dirname $SOURCE)
objcopy ... $(basename $SOURCE) $TARGET
This way the symbols generated are always _binary_file_name_xxx
without the path.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With