2013-12-11 8 views
14

Я пытаюсь отладить проблему с компоновщиком, которую у меня есть, при написании ядра.Сценарии компоновщика: стратегии для отладки?

Проблема в том, что у меня есть переменная SCAN_CODE_MAPPING, которую я не могу использовать - она ​​кажется пустой или что-то еще. Я могу исправить это, изменив способ связи моей программы, но я не знаю, почему.

Когда я заглядываю в сгенерированный двоичный файл, используя objdump, данные для переменной определенно существуют, поэтому есть что-то сломанное со ссылкой на него.

Here's a gist с обоими скриптами компоновщика и частью таблицы символов, которая отличается между двумя файлами.

Что меня смущает, так это то, что обе таблицы символов имеют одинаковые символы, они имеют одинаковую длину и, по-видимому, содержат правильные данные. Единственное отличие, которое я вижу, это то, что они не в одном порядке.

До сих пор я пытался

  • осмотра места SCAN_CODE_MAPPING памяти, чтобы убедиться, что он имеет данные я ожидаю и не обнулены
  • проверки того, что все символы одинаковы
  • проверки того, что все содержимое символов имеют одинаковую длину
  • глядя на .data.rel.ro.local, чтобы убедиться, что он имеет адрес данных

Один возможный ключ это предупреждение:

warning: uninitialized space declared in non-BSS section `.text': zeroing

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

Что мне делать дальше?

+0

Голосование, чтобы закрыть, как отладки помощи. –

ответ

3

Вы можете получить тонну дополнительной информации, используя «readelf».

В частности, обратите внимание на заголовки программ:

readelf -l программа

Ваш ПБС раздел сильно отличается от стандартного, который, вероятно, вызывает предупреждение. Вот что по умолчанию выглядит на моей системе:

.bss   : 
    { 
    *(.dynbss) 
    *(.bss .bss.* .gnu.linkonce.b.*) 
    *(COMMON) 
    /* Align here to ensure that the .bss section occupies space up to 
     _end. Align after .bss to ensure correct alignment even if the 
     .bss section disappears because there are no input sections. 
     FIXME: Why do we need it? When there is no .bss section, we don't 
     pad the .data section. */ 
    . = ALIGN(. != 0 ? 64/8 : 1); 
    } 

Если входная секция ничего не соответствует в вашем сценарии компоновки, компоновщик еще должен поместить его куда-нибудь. Убедитесь, что вы покрываете все входные разделы.

Обратите внимание, что существует разница между разделами и сегментами. Разделы используются компоновщиком, но единственное, на что смотрит программный загрузчик, - это сегменты. Текстовый сегмент включает текстовый раздел, но он также включает в себя другие разделы. Разделы, идущие в один и тот же сегмент, должны быть смежными. Так что порядок имеет значение.

Раздел rodata обычно проходит после текстового раздела. Они доступны только для чтения во время выполнения и будут отображаться один раз в ваших заголовках программ как запись LOAD с чтением & разрешения на выполнение. Эта запись LOAD является текстовым сегментом.

Раздел bss обычно проходит после раздела данных. Они записываются во время выполнения и будут отображаться один раз в заголовках вашей программы в виде записи LOAD с чтением разрешений на запись &. Эта запись LOAD является сегментом данных.

Если вы меняете заказ, это влияет на то, как компоновщик генерирует заголовки программ. Заголовки программ, а не заголовки разделов, используются при загрузке вашей программы перед ее выполнением. Обязательно проверяйте заголовки программ при использовании специального скрипта компоновщика.

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

+0

Это была не проблема, с которой я столкнулся (я писал ядро, поэтому структура финального исполняемого файла не имела большого значения). Однако полезная информация. – jvns

5

Проблема оказалась в том, что я писал ОС, и только 12k ее загружалось, а не всего. Таким образом, скрипт компоновщика действительно работал нормально.

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

  • нм
  • objdump
  • readelf