Линкер выбрасывает неопределенный символ - PullRequest
3 голосов
/ 10 марта 2010

Я строю исполняемый файл, используя GCC 3.4.0. Цель - встроенная система. Я использовал способ модульного определения «обработчиков команд консоли» путем определения указателя функции на обработчик в любом модуле компиляции, который должен находиться в определенном разделе компоновщика. Во время выполнения, когда команда вводится на консоли, я могу проходить по всем обработчикам в «разделе данных обработчика консоли», не имея центральной таблицы со ссылками на каждый обработчик.

Умный, умный, правильный, ну, теперь он кусает меня. Когда я делаю это в файле c, который не имеет других внешних ссылок на символы (например, мой обработчик является единственной функцией), компоновщик выбрасывает все это. Мой обработчик не включен в окончательный исполняемый файл, как и ничего другого в модуле компиляции.

  • Хак - это определить фиктивную глобальную переменную в файле c и ссылаться на нее где-нибудь еще, тогда мой обработчик в этом разделе специальных данных включен.
  • Я также могу использовать -u для компоновщика, и он работает, но поражает цель модульности.
  • Я попытался использовать атрибут ((используется)) для моего обратного вызова, но безуспешно - похоже, его игнорируют.
  • В моем специальном разделе есть спецификация KEEP, но это не помогает.

Есть идеи?

Спасибо, Kurt

Ответы [ 2 ]

0 голосов
/ 10 марта 2010

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

.mysection : {
       PROVIDE(_mysection = .);
       KEEP (callbacks.o(.text*))
}

поместит секцию .text из callbacks.o в секцию .mysection в выходной файл. Однако я ожидаю, что компилятор сделает это с атрибут «used», но, возможно, компоновщик его не получает. Если вы посмотрите при вызове ld (например, с флагом -v для gcc) делает Ваш объектный файл обратного вызова включается туда (то есть это компилятор или компоновщик, который его отбрасывает)?

0 голосов
/ 10 марта 2010

Помимо написания сценария компоновщика, в котором у вас есть все элементы управления, которые вам когда-либо понадобятся, чтобы решить, что будет включено / удалено и т. Д., Попробуйте создать .a из всего вашего объектного файла и указать -whole-archive для компоновщика, или вам нужно выяснить все символы, которые вы хотите, и указать их с помощью --retain-symbols-file

...