2016-09-23 4 views
5

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

Это имеет смысл для пунктов ввода функций, которые я объявил GLOBAL, а также для начальных частей раздела (например, для раздела .text), но кажется странным, что метки просто используются как точки входа в петлю и такие все рядом появляются в выходном файле. Помимо утечки внутренних деталей реализации, он тратит пространство в таблице символов.

Например, если это короткая программа сборки:

GLOBAL _start 
_start: 
    xor eax, eax 
normal_label: 
    xor eax, eax 
.local_label: 
    xor eax, eax 
    xor edi, edi 
    mov eax, 231 ; exit(0) 
    syscall 

... построен с использованием:

nasm -f elf64 label-test.s 
ld label-test.o -o label-test 

Результаты в l (т.е. местные) символы как объектный файл и связанный исполняемый :

objdump --syms label-test.o 

label-test.o:  file format elf64-x86-64 

SYMBOL TABLE: 
0000000000000000 l df *ABS* 0000000000000000 label-test.s 
0000000000000000 l d .text 0000000000000000 .text 
0000000000000002 l  .text 0000000000000000 normal_label 
0000000000000004 l  .text 0000000000000000 normal_label.local_label 
0000000000000000 g  .text 0000000000000000 _start 

Обратите внимание, что оба normal_label и th e локальная метка local_label оказалась в таблице символов. Все они также попадают в таблицу символов исполняемого файла.

Я не хочу выделять эти символы в окончательный исполняемый файл. Могу ли я сказать nasm, чтобы не включать их? Есть несколько вариантов, которые я мог бы передать на ld, например --strip-all, который удалит эти символы, а также каждый другой символ в исполняемом файле. Это делает его довольно дубину: он устраняет символы я действительно хочу, чтобы сохранить следы читаемым стека, отладки и т.д.


FWIW, как уже упоминалось Питером Кордес, yasm не имеют точно такой же вопрос. С elf64 .o файл построен точно так же, как и выше (но с yasm заменяющей nasm, получим:

objdump --syms label-test-yasm.o 

label-test-yasm.o:  file format elf64-x86-64 

SYMBOL TABLE: 
0000000000000000 l df *ABS* 0000000000000000 label-test.s 
0000000000000004 l  .text 0000000000000000 
0000000000000002 l  .text 0000000000000000 
0000000000000000 l d .text 0000000000000000 .text 
0000000000000000 g  .text 0000000000000000 _start 

Глобальная _start метка все еще включен, но другие две метки не названы - они все еще существуют, но они являются неназванными символами со смещением 4 и 2 (строки 2 и 3 в списке выше). Это подтверждается добавлением большего количества меток - создаются более немаркированные символы.

+0

yasm не делает этого по умолчанию. (Это делается, если вы используете '-gdwarf2') –

+1

Да, да. Так что, может быть, это немного странная причуда. Я добавил это к сути вопроса. Вы упомянули материал '-g', и мне пришло в голову, что они добавлены для первичной отладки, но стоит отметить, что' --strip-debug' в команде 'ld' не удаляет эти (или любые символы) на двоичные файлы, созданные nasm. – BeeOnRope

+0

На этот раз я тяжелее googled, и кажется, что это может быть просто [ограничение в nasm] (https://forum.nasm.us/index.php?topic=1951.0). – BeeOnRope

ответ

3

Насколько я могу судить , это просто ограничение в nasm. См. например, this forum post, где у плаката примерно такая же проблема (хотя 32-битная, а не 64-бит ELF), и никакое решение не предусмотрено, кроме использования инструмента для снятия изоляции.

В моем случае, это, кажется, лишив объектный файл как:

strip --discard-all label-test.o 

должен сделать трюк. Несмотря на название опции --discard-all, он только разбивает локальные символы и оставляет только глобальные символы.Вот таблицу символов, прежде чем зачистки файла:

SYMBOL TABLE: 
0000000000000000 l df *ABS* 0000000000000000 label-test.s 
0000000000000000 l d .text 0000000000000000 .text 
0000000000000002 l  .text 0000000000000000 normal_label 
0000000000000004 l  .text 0000000000000000 normal_label.local_label 
0000000000000000 g  .text 0000000000000000 _start 

и после того, как:

SYMBOL TABLE: 
0000000000000000 l df *ABS* 0000000000000000 label-test.s 
0000000000000000 l d .text 0000000000000000 .text 
0000000000000000 g  .text 0000000000000000 _start 

в частности, отметить, что это был достаточно умен, чтобы оставить символ в .text раздел в одиночку, даже если он является локальным. Конечно, эта опция полосы не может отличить бесполезную (метку цикла) и потенциально полезные символы, например, точки входа в локальную функцию, которые необходимы для правильной трассировки стека с различными инструментами.

Если вы хотите быть умнее об этом, можно избирательно лишить только ASM-местный (т.е. ярлыки, начиная с .), используя --wildcard и --strip-symbol варианты выборочно раздеть только этикетки со встроенным ..

Я все еще ищу лучший ответ, если вы скрываетесь там.

Смежные вопросы