Что содержит объектный файл? - PullRequest
44 голосов
/ 15 июня 2010

На разных этапах компиляции в C или C ++ я знаю, что создается объектный файл (то есть файл any_name.o). Что содержит этот .o файл? Я не могу открыть его, так как это бинарный файл.

Может ли кто-нибудь помочь мне? Является ли содержимое объектного файла в основном зависимым от компилятора, который мы используем в Unix?

Ответы [ 8 ]

46 голосов
/ 15 июня 2010

Объектные файлы могут содержать кучу вещей: в основном это часть или весь список ниже:

  • Имена символов
  • Скомпилированный код
  • Постоянные данные, например. Строки
  • Imports - на какие символы ссылается скомпилированный код (исправляется компоновщиком)
  • Экспорт - какие символы объектный файл делает доступными для ДРУГИХ объектных файлов.

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

8 голосов
/ 15 июня 2010

Существует несколько стандартизированных форматов (COFF, ELF в Unix), в основном это варианты тех же форматов, которые используются для исполняемых файлов, но в которых отсутствует некоторая информация. Эти недостающие данные будут заполнены при ссылке.

Файлы форматов объектов в основном содержат одинаковую информацию:

  • двоичный код, полученный в результате компиляции (для целевого процессора)
  • статические данные, используемые этой частью программы (например, константы и т. Д.). Вы можете провести более четкое различие между BSS (экспортируемые данные) и Text (данные, которые не будут изменены программой). Но это в основном важно для компилятора и компоновщика. Обратите внимание, что, как и в двоичном коде, данные также зависят от цели (с прямым порядком байтов, с прямым порядком байтов, 32 бита, 64 бита).
  • таблицы символов, экспортируемых этой частью программы (в основном это точки входа функций)
  • таблицы внешних символов, используемых этой частью программы

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

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

5 голосов
/ 15 июня 2010

Сначала прочитайте вики-страницу . Вы можете использовать objdump для проверки такого файла:)

4 голосов
/ 15 июня 2010

Используйте команду file для таких вещей. Это объектный файл ELF в современной системе Linux. Например. если скомпилировано для 32-битного x86.

ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

Напротив, динамически связанный исполняемый файл может выглядеть так:

ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped

Чтобы увидеть заголовки, включая названия разделов, вы можете использовать:

objdump -x any_name.o

Разобрать:

objdump -d any_name.o
3 голосов
/ 15 июня 2010

Во-первых, двоичные файлы могут быть открыты !Не бойтесь этого, вам нужны только правильные инструменты!Будучи двоичными данными, текстовый редактор, конечно же, не является правильным инструментом;правильным инструментом может быть шестнадцатеричный редактор или расширенный редактор, такой как emacs, или инструмент, который вместо того, чтобы просто «выводить» байты в их «шестнадцатеричном» представлении и позволяющий вам самостоятельно интерпретировать данные, знает этот конкретный формат и «интерпретирует «данные должным образом, на некотором уровне (например, GIMP интерпретирует файл PNG как изображение и показывает его, анализатор PNG будет« разлагать »данные внутри секций PNG, показывая вам флаги в определенных байтах и ​​т. д.).

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

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

Каждыйиз них могут быть свои инструменты для анализа контента;например, readelf для ELF, objdump для нескольких форматов (попробуйте objdump -i) в зависимости от того, как он был скомпилирован.

3 голосов
/ 15 июня 2010

Объектный файл является скомпилированным источником.

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

1 голос
/ 15 июня 2010

В среде компиляции GNU вы можете посмотреть с помощью objdump как в исполняемом файле, так и в объектном файле.

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

$ objdump -t scanf_sample.o

scanf_sample.o:     file format pe-i386

SYMBOL TABLE:
[  0](sec -2)(fl 0x00)(ty   0)(scl 103) (nx 1) 0x00000000 scanf_sample.c
File
[  2](sec  1)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _main
[  3](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .text
AUX scnlen 0x91 nreloc 9 nlnno 0
[  5](sec  2)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .data
AUX scnlen 0x0 nreloc 0 nlnno 0
[  7](sec  3)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .bss
AUX scnlen 0x0 nreloc 0 nlnno 0
[  9](sec  4)(fl 0x00)(ty   0)(scl   3) (nx 1) 0x00000000 .rdata
AUX scnlen 0x54 nreloc 0 nlnno 0
[ 11](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 1) 0x00000000 ___main
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[ 13](sec  0)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 __alloca
[ 14](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _memset
[ 15](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _scanf
[ 16](sec  0)(fl 0x00)(ty  20)(scl   2) (nx 0) 0x00000000 _printf

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

Подробнее о связывании , компиляции и объектов .

1 голос
/ 15 июня 2010

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

В информатике объектный файл организованная коллекция отдельных, именованные последовательности машины код [цитата нужна]. Каждая последовательность, или объект, как правило, содержит инструкция для хоста выполнить какую-то задачу, возможно сопровождается соответствующими данными и метаданные (например, перемещение информация, разматывание стека информация, комментарии, программа символы, отладка или профилирование Информация). Линкер обычно используется для генерации исполняемого файла или библиотека путем объединения частей объекта файлы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...