Вызывается ли ld как во время компиляции, так и во время выполнения?
Нет: ld - это , а не , вызываемый при или компиляции или времени выполнения.
Когда gcc вызывается, после предварительной обработки, компиляции и сборки вызывается компоновщик, который связывает все объектные файлы и файлы .a в исполняемый файл
Большинство умеренно сложных программ используют отдельные шаги компиляции и компоновки.
При компиляции создается набор перемещаемых объектных файлов (на этом этапе вызываются предварительная обработка, компиляция и сборка). Дополнительно .o
файлы архивируются в архивную библиотеку (libsomething.a
).
Затем выполняется шаг связывания (часто это называется «статическое связывание», чтобы отличить этот шаг от «динамической загрузки», который будет происходить во время выполнения), создание исполняемого файла или разделяемой библиотеки. Только в вызывается этот шаг /usr/bin/ld
. В Linux ld
является частью пакета binutils.
вместе с минимальными инструкциями о том, как общие библиотеки должны быть «подключены»
Компоновщик записывает, какие общие библиотеки требуются во время выполнения, и, возможно, какие версии библиотек или символов требуются.
Также записывается, какой загрузчик времени выполнения должен использоваться для загрузки необходимых общих библиотек.
Во время выполнения я понимаю, что исполняемый файл загружается в память, хотя я не уверен, как.
Ядро загружает исполняемый файл в память и проверяет, был ли запрошен загрузчик времени выполнения во время статической ссылки. Если это так, динамический загрузчик также загружается в память, и ему передается управление выполнением (вместо основного исполняемого файла).
Тогда задача динамического загрузчика состоит в том, чтобы проверить исполняемый файл на предмет инструкций, по которым требуются другие библиотеки, проверить, можно ли найти правильные версии, загрузить их в память и расположить такие вещи, чтобы разрешение символов работало между основными исполняемые и разделяемые библиотеки. Этот является шагом загрузки во время выполнения, часто также называемым динамическим связыванием.
Динамический загрузчик может быть частью ОС, но в Linux он является частью libc (GLIBC, uClibc и musl имеют свои собственные загрузчики).