Что такое объектный файл

Обновлено: 21.11.2024

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

Краткий обзор конвейера компиляции и выполнения (для терминологии):

  1. Lexing производит токены
  2. Синтаксический анализ создает абстрактное синтаксическое дерево
  3. Анализ создает граф потока кода
  4. Оптимизация создает уменьшенную диаграмму потока кода.
  5. Генератор кода создает объектный код
  6. Linkage создает полный исполняемый файл
  7. Загрузчик указывает ОС, как запустить исполняемый файл.

Допустим, у вас есть замечательный код C/C++, но для разделения проблем вы хотите начать перемещать его в отдельные исходные файлы. Принимая во внимание, что раньше в одном файле у вас было:

Теперь у вас есть два исходных файла и, возможно, заголовок:

В версии с одним исходным кодом мы бы скомпилировали и связали его с clang main.c и получили исполняемый файл. В версии с несколькими источниками мы сначала компилируем наши исходные файлы в объектные файлы, а затем связываем их вместе. Это можно сделать отдельно:

Мы также можем выполнить компиляцию и компоновку за один шаг:

Пока ничего особенного; C/C++ 101. В первом случае отдельных этапов компиляции и компоновки у нас остались промежуточные объектные файлы (.o). Что именно?

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

Помните, что если мы не укажем вспомогательный объектный файл, мы получим ошибку неопределенного символа.

Проблема в том, что main.o ссылается на некоторый символ, который называется helper , но сам по себе не содержит никакой дополнительной информации о нем. Допустим, мы хотим знать, какие символы содержит объектный файл или ожидает найти в другом месте. Давайте представим наш первый инструмент, nm. nm напечатает список имен или таблицу символов для данного объекта или исполняемого файла. В OSX перед ними стоит символ подчеркивания.

Давайте разберем, что здесь происходит. Вывод (как понимает man 1 nm ) представляет собой список адресов, типов и имен символов, разделенных пробелами. Мы видим, что адреса являются заполнителями в объектных файлах и окончательными в исполняемых файлах. Имя должно иметь смысл; это имя функции или переменной. Хотя я хотел бы подробно остановиться на различных типах символов и поговорить о разделах, я не думаю, что смог бы сделать такую ​​же замечательную работу, как Питер Ван Дер Линден в его книге «Экспертное программирование на C: секреты глубокого C». /p>

В нашем случае нас интересует только то, определен ли символ в данном объектном файле или нет. Тип U (неопределенный) означает, что этот символ упоминается или используется в этом объектном коде/исполняемом файле, но его значение здесь не определено. Когда мы скомпилировали только main.c и получили ошибку неопределенного символа, теперь должно быть понятно, почему мы получили ошибку неопределенного символа для помощника. main.o содержит символ main и вспомогательные ссылки. helper.o содержит символ помощника и ссылки на puts. Окончательный исполняемый файл содержит символы для основного и вспомогательного файлов, а также ссылки на puts.

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

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

Хотя nm дал нам взглянуть на нашу таблицу символов, я часто использую два других инструмента: objdump в Linux и otool в OSX. Оба они предоставляют дизассемблированные инструкции по сборке и их адреса. Обратите внимание, как символы функций переводятся в метки дизассемблированных функций, и что их адреса указывают на первую инструкцию в этой метке. Поскольку в предыдущих постах я много раз показывал objdump, вот otool .

readelf -s даст нам список символов в Linux. ELF — это формат файла, используемый загрузчиком в Linux, тогда как OSX использует Mach-O. Таким образом, readelf и otool соответственно.

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

*: есть понятие слабых символов и некоторые особенности динамических библиотек, о которых мы поговорим в следующем посте.

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

Будет создавать такие символы, как:

Примечание: GNU nm в дистрибутивах Linux будет иметь параметр --demangle:

В OSX мы можем передать nm в c++filt:

Rust также искажает имена своих функций. Для FFI или интерфейса с функциями C другим языкам обычно приходится искать или отображать символы способом, подходящим для C, наименьшего общего знаменателя. В C++ есть внешние блоки "C", а в Rust есть внешние блоки.

Мы можем использовать strip для удаления символов из двоичного файла. Это может уменьшить размер двоичного файла за счет того, что трассировка стека станет нечитаемой. Если вы делаете это дома, попробуйте сравнить вывод вашего дизассемблера и nm до и после запуска strip на исполняемом файле. К счастью, вы не можете удалить символы из объектных файлов, иначе они будут бесполезны, так как вы больше не сможете их связать.

Если мы компилируем с флагом -g, мы можем создать другой тип символа; символы отладки. В зависимости от вашего компилятора + хост-ОС вы получите еще один файл, который вы можете запустить через nm, чтобы увидеть запись для каждого символа. Вы получите больше информации, используя dwarfdump для этого файла. Символы отладки сохранят исходную информацию, такую ​​как имя файла и номер строки, для всех символов.

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

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

Что такое объектный файл в C++?

Объектный файл C++ — это промежуточный файл, созданный компилятором C++ из файла реализации C++ и файлов заголовков C++, которые включены в файл реализации. Компоновщик C++ создает выходной исполняемый файл или библиотеку вашего проекта из ваших объектных файлов C++.

Можете ли вы запустить объектный файл?

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

Как работают объектные файлы?

5 ответов. Объектный файл — это реальный результат этапа компиляции. В основном это машинный код, но он содержит информацию, которая позволяет компоновщику видеть, какие символы в нем содержатся, а также символы, необходимые для работы. (Для справки, «символы» — это в основном имена глобальных объектов, функций и т. д.) 11 октября 2011 г.

В чем разница между объектным файлом и исполняемым файлом?

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

Является ли объектный файл двоичным файлом?

Объектные файлы. Эти файлы создаются как выходные данные компилятора. Они состоят из определений функций в двоичной форме, но сами по себе не являются исполняемыми.

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

Объектный файл — это компьютерный файл, содержащий объектный код, то есть машинный код, выводимый ассемблером или компилятором. Объектный код обычно можно перемещать, и обычно он не может выполняться напрямую.

Что такое объектный файл в Java?

Объектные файлы — это текстовые файлы, поддерживающие как многоугольную, так и произвольную геометрию (кривые и поверхности). Ява 3D. загрузчик файлов obj поддерживает подмножество форматов файлов, но его достаточно для загрузки почти всех общедоступных объектных файлов.

Что такое объектный файл и что такое символы?

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

Почему он называется объектным файлом?

Если у вас есть проект со многими файлами C (например), вы скомпилируете каждый из них в объектный код, а затем свяжете все объектные файлы вместе, чтобы получить конечный продукт. Термин «объект» здесь обозначает последовательности несвязанного машинного кода (в основном). Объектный файл содержит объекты.

Какой файл преобразуется в объектный файл?

Какой файл преобразуется в объектный файл? Объяснение: выходные данные препроцессора передаются компилятору, который создает ассемблерный файл из кодов инструкций процессора и имеет библиотеки. Затем файл сборки преобразуется в объектный файл, содержащий шестнадцатеричное кодирование.

Зависит ли платформа объектных файлов?

Объектные файлы зависят от компилятора. Некоторые компиляторы выдают COFF, другие выдают ELF и т. д. Кроме того, вам нужно беспокоиться о соглашениях о вызовах, системных вызовах и т. д. Это зависит от платформы.

Что такое формат объектных файлов в технологии программного обеспечения?

OBJ — это распространенный формат файлов, используемый в 3D-печати. Многие программы САПР экспортируют 3D-объекты в форматы OBJ. Файл OBJ принимается большинством программ для 3D-принтеров, где он подготовлен для 3D-печати. Файл OBJ изначально был разработан Wavefront Technologies для использования в пакете анимации Advanced Visualizer.

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

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

Сколько разделов в объектном файле?

Загрузчику ELF нужна информация о сегменте, но не нужна информация о разделе. Стандарт ELF позволяет компоновщику полностью исключить информацию о разделе ELF из исполняемого объектного файла. Объектные файлы обычно содержат три раздела по умолчанию: (1) Некоторые цели разрешают содержимое, отличное от текста, например константы, в формате .

Является ли исполняемый файл объектным кодом?

Этот файл создается компилятором и называется объектным кодом ( .obj ), но такая программа, как программа «hello world», состоит из написанной нами части и части библиотеки C++. Компоновщик связывает эти две части программы и создает исполняемый файл ( .exe ).

Почему объектный файл не является исполняемым?

Во-первых, вы создаете не объектный файл, а исполняемый файл. Объектные файлы — это промежуточный файл, используемый компоновщиком в качестве входного файла для создания исполняемого файла. То, что вы называете его с суффиксом .o, не имеет значения.

Как компоновщик преобразует объектный файл в исполняемый файл?

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

В чем разница между объектным файлом и двоичным файлом?

Объектный файл содержит те же инструкции в машиночитаемой двоичной форме. Файлы сборки могут быть преобразованы в объектные файлы ассемблером (as). Файл битового кода LLVM (.bc) содержит инструкции LLVM в двоичной форме.

Что такое файл .exe в C?

Исполняемый файл (exe-файл) – это компьютерный файл, содержащий закодированную последовательность инструкций, которые система может выполнить непосредственно, когда пользователь щелкнет значок файла.

Как выглядит объектный код?

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

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

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

Что такое объектный модуль?

Объектный модуль, также называемый объектным файлом, представляет собой раздел кода в объектно-ориентированном программировании, используемый другими объектными модулями или создаваемой программой. Объектные модули содержат определенную функцию, например включение устройства на компьютере.

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

Мужчина держит компьютер

Обычно объектный файл обозначается расширением ".obj". Однако существует несколько различных форматов для этих файлов. Наиболее распространенными являются формат перемещаемых объектных модулей Intel® (OMF) и общий формат объектных файлов (COFF) Windows® и UNIX® System V.Во многих системах INIX® исполняемый и связываемый формат (ELF) пришел на смену COFF.

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

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

Благодаря динамической компоновке объектный файл может одновременно использоваться несколькими выполняющимися программами. Вместо привязки объектного кода к программе при компоновке он извлекается при загрузке программы или во время выполнения при обращении к процедуре. В среде Windows® они известны как библиотеки динамической компоновки и обозначаются расширением «.dll». Системы, подобные Unix®, часто называют этот тип файла динамическим общим объектом (DSO). Этот тип объектного файла также может быть реализован для использования с определенной программой и будет частью установки этой программы.


Объектный файл C++ – это промежуточный файл, созданный компилятором C++ из файла реализации C++ и файлов заголовков C++, которые включены в файл реализации. Компоновщик C++ создает выходной исполняемый файл или библиотеку вашего проекта из ваших объектных файлов C++.

RAD Studio может создавать объектные файлы C++ как из проектов Delphi, так и из проектов C++.

Расширение файла объектных файлов C++:

  • obj при сборке проекта для 32-разрядной версии Windows.
  • o при создании проекта для любой другой поддерживаемой платформы.

Объектные файлы C++Builder

Когда вы создаете проект C++, RAD Studio создает объектный файл C++ для каждого модуля в вашем проекте и объектный файл C++ для вашего проекта.

Когда вы создаете свой проект C++, RAD Studio по умолчанию создает ваши объектные файлы C++ в C:\Users\\Documents\Embarcadero\Studio\Projects\

\ .
Для пакетов RAD Studio также создает статическую версию ваших объектных файлов C++, сгенерированных по умолчанию в C:\Users\\Documents\Embarcadero\Studio\Projects\

\\staticobjs . Дополнительные сведения см. в разделе Создание статических пакетов.

Чтобы изменить выходной каталог, используйте параметр Выходной каталог объектного файла в меню Проект > Параметры > Компилятор C++ > Каталоги и условия .

Объектные файлы C++ в проектах Delphi

Когда вы создаете проекты Delphi, RAD Studio создает объектный файл C++ для каждого модуля в вашем проекте и объектный файл C++ для вашего проекта, если вы выберете любое из следующих значений для параметра создания выходного файла C/C++ в Project > Параметры > Компилятор Delphi > Вывод — C/C++:

  • "Создать C .objs"
  • "Создать C++ .objs"
  • "Создать C++ .objs, заголовки"
  • "Создание C++ .objs, заголовков, пространств имен"
  • "Создать C++ .objs, заголовки, пространства имен, экспортировать"
  • "Создание C++ .objs, пространств имен"
  • "Создать C++ .objs, пространства имен, экспортировать"
  • "Создать C++ .objs, заголовки, экспортировать"
  • "Создание C++ .objs, экспорт"
  • "Создать все файлы C++Builder (включая библиотеки пакетов)"

Когда вы создаете проект Delphi, RAD Studio по умолчанию создает ваши объектные файлы C++ в C:\Users\\Documents\Embarcadero\Studio\Projects\

\ .
Чтобы изменить каталог вывода, используйте параметр каталога вывода C/C++ .obj/.lib в меню Проект > Параметры > Компилятор Delphi > Вывод — C/C++ .

Читайте также: