Страницы

Поиск по вопросам

понедельник, 16 декабря 2019 г.

Как работает компоновка С-приложений?

#c #dll #компиляция #lib #компоновщик


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

Как устроена статическая линковка библиотек? Неразрешённые символы таблицы символов
компоновщик ищет в указанных библиотеках. Так понимаю, в библиотеке тоже должно быть
указано где находится искомая функция и её размер. Далее функция включается в исполняемый
файл. Выходит, .lib не нужно за собой таскать раз функция уже в .exe?

Как устроена динамическая линковка библиотек? ОС должна используя таблицу импорта
найти нужные функции в .dll и загрузить эти функции в оперативную память процесса?

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



CORRECTED: Уточняю свои вопросы:


Объектные файлы. Компилятор выполняет создание объектного файла, который в общем
виде представлен заголовком, содержащим различную информацию о программе, и скомпилированным
кодом, который так же зависит от RTL и, в зависимости от компилятора, содержит те или
иные ссылки на функции из библиотек RTL. Заголовок так же содержит таблицу символов
(где находится информация обо всех методах и глобальных переменных (размер, тип, адреса
и т.п.), а так же, в случае С++, описания методов классов, запись названий которых
осуществляется при помощи декорирования имён ввиду некоторых ограничений на символы
(в случае dll, это затрудняет использование классов при явной компоновке, как я понял)).
Скомпилированный код просто представлен сплошными инструкциями, которые как-то разделяются
по функциям, на начала которых указывают символы в таблице символов. Когда объектных
файлов несколько, таблицы символов сливаются, как и код, а из повторяющихся символов
выбирается самый "массивный". Верно ли? Чем вы можете дополнить это?.
Статическая компоновка. Неразрешённые символы из таблицы символов объектного файла
компоновщик ищет в подключаемых библиотеках. В случае статической компоновки .lib файл
используется лишь как ресурс для функций, откуда копируются в целевой .exe их содержимое
(т.е. .lib за собой таскать не надо?).
Динамическая компоновка. При динамической линковке, компоновщик помечает неразрешённые
символы как IOU ("я тебе должен") (ищет ли он их определения в указанных .dll? надо
же быть уверенным, что такая .dll, которую указал пользователь вообще существует и
в ней есть этот метод. Разве нет?). При запуске .exe ОС подключает нужные .dll (ищет
их в нужных местах) и загружает в память. Только, вроде как, при неявной компоновке
если какая-то .dll уже есть в памяти, она не будет загружена снова. Но как ОС знает
по какому адресу эта .dll загружена? Методы заменяются на ссылки на функции загруженной
.dll или как? При явной загрузке все функции .dll вроде просто выгружаются в память
на ровне с функциями самого .exe и в таблице данных есть адреса этих функций в оперативной
памяти - или как это вообще выглядит? При передаче переменной в метод её имя заменяется
на адрес из блока данных? Как это выглядит?

    


Ответы

Ответ 1



Извините конечно, но на тему ваших вопросов можно целую книгу написать... Если очень грубо, то формат объектного файла в целом описывается стандартом ELF - Executable & Linkable File - по сути это файл с неким заголовком и произвольным набором секций, именование секций вообще говоря зависит от платформы. Для старых Windows программ формат объектных файлов описывается COFF - Common Object File Format - структурно формат схож с ELF, но он более Windows ориентирован, в то время как ELF - кроссплатформенный. Если охота поразбираться в кишках - то велкам сюда

Комментариев нет:

Отправить комментарий