objcopy prepends directory pathname to symbol name

c, c++, objcopy

Solution

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

Problem

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?

Original source