Подтвердить что ты не робот

Что содержит объектный файл?

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

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

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

Ответ 3

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

Ответ 4

Используйте команду 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

Ответ 5

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

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

Ответ 6

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

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

Как эти информационные "организованы", а в некоторых случаях - в том, что означает "в конечном итоге больше", это зависит от конкретного формата объекта. Некоторые ссылки на wikipedia, в которых перечислены некоторые из возможностей, this, this, this, this...

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

Ответ 7

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

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

Ответ 8

В среде компиляции 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 для исполняемого файла, вы можете видеть намного больше функций (помимо тех, которые находятся внутри объекта). Это доказывает, что объектный файл содержит только функции, определенные в исходном файле со ссылками на другие функции. Эти ссылки будут разрешены на этапе связывания.

Подробнее о ссылка, compilation и объекты.