Как заставить GCC экспортировать ВСЕ символы в выходной файл

Я разрабатываю операционную систему, и мне нужно загрузить некоторые модули ДО того, как будет настроена подкачка. Так как на данный момент подкачка не настроена, мне нужно переместить все символы в программе на физический адрес. Моя проблема в том, что не все символы можно найти в таблице символов и не всю информацию о перемещении можно найти в rel.text. Как я могу заставить GCC экспортировать все данные символов???


person user1454902    schedule 21.01.2013    source источник
comment
Таблица перемещения должна содержать достаточно информации для перемещения исполняемого файла в произвольное место. Эта информация не обязательно должна охватывать все символы. Например, ваши локальные переменные не перемещаются.   -  person Alexey Frunze    schedule 21.01.2013
comment
Вы пытались скомпилировать с -fPIC для независимого от позиции кода?   -  person Vlad Krasnov    schedule 21.01.2013


Ответы (2)


Безусловно, ВСЕ, что требует перемещения, будет в таблице перемещений. Как еще его можно было загрузить? Независимо от того, включена подкачка или нет, перемещение работает точно так же — записи, которые являются абсолютными местоположениями в двоичном файле, перечислены со смещением, а затем обрабатываются программой загрузки. Все остальное должно быть в порядке без переезда.

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

Возможно, вы думаете о символах в самой вашей ОС? Если это так, то это действительно случай экспорта символов из вашей ОС соответствующим образом. В Linux есть EXPORT_SYMBOL(name), который строит таблицу символов внутри самого ядра. [Обратите внимание, что это НЕ символы, сгенерированные gcc или ld, а символы, созданные макросами и обработанные в ядре.

Отредактируйте, чтобы уточнить, так как мне не хватило места в «комментарии»: существует два типа «перемещений»: внутренние — когда у вас есть абсолютные ссылки на вещи в вашем собственном модуле, например. указатели на строки, указатели на функции, таблицы переходов для операторов switch и т. д. — это должен быть просто вопрос сложения текущего значения со смещением того места, где фактически находится двоичный файл (конечно, виртуальный адрес). Другой - "внешние ссылки", например, когда ваш модуль вызывает, скажем, spinlock() - это не реализовано внутри модуля, поэтому у него будет "внешняя ссылка". В этом случае будет запись о перемещении с именем «spinlock» и смещением того места, где в модуле происходит вызов spinlock. Теперь вам, очевидно, нужна таблица символов, чтобы найти, где в вашем ядре находится «спин-блокировка» [и если вы хотите быть действительно сложным, разрешите модулям ссылаться на другие модули, но я бы оставил это до тех пор, пока у вас не будет загрузки одного модуля в порядке первый!].

person Mats Petersson    schedule 21.01.2013
comment
Я немного запутался, потому что думал, что индекс символа хранится в reloc_info. Единственными другими данными в записи о перемещении является адрес, по которому было применено перемещение. Таким образом, вам нужно будет получить адрес того, что находится в rel_offset, просмотрев таблицу символов и найдя значение для этого символа, верно? - person user1454902; 21.01.2013
comment
Я не уверен на 100%, что вы пытаетесь решить (и собираетесь попытаться добраться до работы, так что придется вернуться к вам сегодня вечером). Я внес изменения в свой первоначальный ответ, чтобы попытаться прояснить два случая перемещения вещей. Если это не распространяется, то, пожалуйста, объясните более подробно, возможно, с примером, что вы пытаетесь решить. - person Mats Petersson; 21.01.2013

На самом деле ваш вопрос касается компоновщика. И ответ зависит от компоновщика, который вы используете.

Если это стандартный компоновщик ld в gcc, попробуйте опцию "-Wl,-r".

person Konstantin Vladimirov    schedule 21.01.2013