objcopy добавляет путь к каталогу к имени символа

Я привязываюсь к использованию objcopy включить двоичную форму текстового файла в исполняемый файл. (Во время выполнения мне нужен файл в виде строки). Это работает нормально, пока компоновщик не должен найти ссылки из имен символов. Проблема в том, что objcopy предварительно добавляет имена символов с путем к файлу. Так как я использую GNU Autotools для доставки пакета, это предварительное имя пути изменяется, и я не знаю, какой символ внешнего компоновщика использовать в программе C / C ++.

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 был произведен с (выдержка из Makefile.am):

SUFFIXES = .txt
.txt.$(OBJEXT):
objcopy --input binary --output elf32-i386 --binary-architecture i386 $< $@

Как я могу сказать objcopy только нам ствол имени файла в качестве символов компоновщика? Или есть другой способ обойти проблему?

9

Решение

Как ни странно, вы можете использовать objcopy решить проблему через --redefine-sym опция, позволяющая переименовывать символы …

Если я использую objcopy для создания объектного файла из PNG в другом
каталог:

$ objcopy -I binary -O elf64-x86-64 -B i386 --rename-section .data=.rodata,alloc,load,data,contents,readonly ../../resources/test.png test_png.o

Полученный объект имеет следующие символы:

$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

Затем они могут быть переименованы:

$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

В результате получается объект с именами символов, которые будут иметь objcopy
генерируется, если PNG был расположен в текущем каталоге:

$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
8

Другие решения

Общий метод включения необработанных данных в ELF поддерживается .INCBIN Директива ассемблера.

Хитрость в том, чтобы создать шаблонный файл .S, который может выглядеть следующим образом:

        .global foo_start
foo_start:
.incbin "foo.raw"
.global foo_end
foo_end:

Этот файл предварительно обрабатывается через cpp, поэтому нам не нужно жестко задавать имя файла, например. мы можем написать:

        .incbin __raw_file_path__

… а затем передать его при компиляции:

gcc -D__raw_file_path__='"data/foo.png"' foo.S -c -o data/foo.o

Наконец, когда мы сами готовим файл .S, мы можем добавить дополнительные данные и / или информацию. Если вы включили необработанные «текстовые файлы» и хотите, чтобы они были доступны как строки C, вы можете добавить байт «0» сразу после необработанных данных:

        .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

Если вам нужна полная гибкость, вы, конечно, можете предварительно обработать файл вручную, чтобы изменить любую его часть, например.

.global @sym@_start
@sym@_start:
.incbin "@file@".global @sym@_end
@sym@_end:

… и затем скомпилируйте это:

sed -e "s,@sym@,passwd,g" -e "s,@file@,/etc/passwd," <foo.S.in | gcc -x assembler-with-cpp - -o passwd.o -c
7

Другой альтернативой, которую я использовал, является cd в исходный каталог, а затем дать objcopy базовое имя источника. В bash, это было бы:

cd $(dirname $SOURCE)
objcopy ... $(basename $SOURCE) $TARGET

Таким образом, генерируемые символы всегда _binary_file_name_xxx без пути.

4

Одним из простых решений является преобразование вашего текстового файла в то, что можно использовать для инициализации массива char. Таким образом, вы получите 0x41,0x42,0x43,0x30,0x31,0x32 для «ABC012». Затем вы можете #include эту последовательность байтов. Вы также можете побег все не-ASCII-символы вместо того, чтобы преобразовывать все в байты, так что большая часть текста по-прежнему читается в сгенерированном включаемом файле.

0
По вопросам рекламы [email protected]