2010-09-01 5 views
14

Я хотел бы создать файл, который можно загрузить в память (например, с помощью mmap), а затем перейти к началу этой памяти для запуска кода.Как заставить gcc генерировать только машинный код, который может быть загружен непосредственно в память и выполнен?

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

+0

Это не тот файл объекта? – aaronasterling

+1

Нет, по крайней мере, объектные файлы содержат информацию о том, какие символы они экспортируют (для использования компоновщиком) –

+2

Любые конкретные причины, по которым вы не хотите использовать библиотеку dll/shared? Есть * лот * ловушек с сырыми двоичными файлами. – snemarch

ответ

14

Вы можете сделать это, но вам нужно будет пройти через формат объектного файла. В частности, команда objcopy может преобразовать исполняемый файл в «плоский» двоичный файл (в зависимости от вашей целевой платформы). Возможно, что-то вроде этого:

gcc -o test test.c 
objcopy -O binary test test.bin 

См man objcopy на вашей платформе для более подробной информации.

+0

+1, я знал, что есть что-то, что делало это ,Вы знаете, нужно ли загружать это по определенному адресу? –

+0

Да, вы это сделаете. Это будет адрес, на который связывается линкер. Обратите внимание, что обычно вы не видите файл управления компоновщика, поэтому вы можете не знать, где это .... – RBerteig

+0

Где я могу найти файл управления? –

6

Вы хотите знать о утилите objcopy, которую обычно выпускают вместе с GCC. Это компонент пакета инструментов binutils, наиболее заметным из которых является компоновщик, ld.

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

Это наиболее полезно для подготовки кода, который должен быть запущен с ПЗУ, где вы хотите убедиться, что используете подходящую библиотеку времени выполнения C для целевой платформы и, вероятно, необходимо настроить файл сценария компоновщика, а также предоставить ваш собственный код запуска C.

Если ваша цель - получить что-то вроде файла .so для загрузки в существующий процесс, тогда имейте в виду, что часть работы загрузчика разделяемой библиотеки заключается в том, чтобы фактически завершить привязку, чтобы символы в .so-файле, который ссылается на адреса в основном исполняемом файле (или других .so-файлах), решаются во время загрузки. Использование objcopy этого не сделает, и поэтому для функций, загруженных таким образом, может быть сложно правильно использовать существующую библиотеку времени выполнения C и объекты, которые она поддерживает, например, открытые файлы.

Независимо от ваших целей, вам нужно будет захватить контроль над компоновщиком, чтобы найти ваш бинарный файл по известному адресу. Для этого вам понадобится создать сценарий компоновщика. Документация для языка скриптов находится в the binutils manual. Вас будут интересовать разделы «.text *» и, возможно, в разделах «.rodata *», если вы планируете инициализировать глобальные переменные. Фактически организация этой инициализации остается в качестве упражнения для читателя.

В целом, это только верхушка очень большого айсберга. Я бы предложил потратить некоторое время на сборку кросс-компилятора, чтобы увидеть, как эти вещи используются на практике. Сообщества AVR и MSP430 используют GCC, имеют активное участие и недорогое (и часто даже с открытым исходным кодом) оборудование для начала работы.