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

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

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

45
задан Null 2 September 2015 в 16:14
поделиться

8 ответов

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

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

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

47
ответ дан 26 November 2019 в 21:20
поделиться

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

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

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

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

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

8
ответ дан 26 November 2019 в 21:20
поделиться

Для подобных вещей используйте команду 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
4
ответ дан 26 November 2019 в 21:20
поделиться

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

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

3
ответ дан 26 November 2019 в 21:20
поделиться

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

5
ответ дан 26 November 2019 в 21:20
поделиться

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

Как видите, объект содержит только код функций, объявленных/ссылающихся в скомпилированном файле (файл содержит только функцию main с вызовом 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
ответ дан 26 November 2019 в 21:20
поделиться

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

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

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

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

3
ответ дан 26 November 2019 в 21:20
поделиться

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

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

1
ответ дан 26 November 2019 в 21:20
поделиться