Вызывается ли ld как во время компиляции, так и во время выполнения? - PullRequest
0 голосов
/ 31 августа 2018

Я пытаюсь понять, как работают ссылки и загрузка. Насколько я понимаю, Unix-программа "ld" содержит функции связывания и загрузки. Когда вызывается gcc, после предварительной обработки, компиляции и сборки вызывается компоновщик, который связывает все объектные файлы и файлы .a в исполняемый файл вместе с минимальными инструкциями о том, как разделяемые библиотеки должны быть «подключены» (какова здесь правильная терминология) ?) во время выполнения. Этот линкер является ld.

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

1) Являются ли общие объектные файлы «связанными» во время компиляции, или есть другое слово для того, что происходит? 2) Во время выполнения ld вызывается во второй раз? Как я могу увидеть подтверждение этого для моего исполняемого файла (в Linux и в MacOS)? 3) Связаны ли общие объектные файлы во время выполнения или есть другое слово для процесса, когда общие объекты читаются из расположения в LD_LIBRARY_PATH во время выполнения?

Спасибо!

Ответы [ 2 ]

0 голосов
/ 01 сентября 2018

Вызывается ли ld как во время компиляции, так и во время выполнения?

Нет: ld - это , а не , вызываемый при или компиляции или времени выполнения.

Когда gcc вызывается, после предварительной обработки, компиляции и сборки вызывается компоновщик, который связывает все объектные файлы и файлы .a в исполняемый файл

Большинство умеренно сложных программ используют отдельные шаги компиляции и компоновки.

При компиляции создается набор перемещаемых объектных файлов (на этом этапе вызываются предварительная обработка, компиляция и сборка). Дополнительно .o файлы архивируются в архивную библиотеку (libsomething.a).

Затем выполняется шаг связывания (часто это называется «статическое связывание», чтобы отличить этот шаг от «динамической загрузки», который будет происходить во время выполнения), создание исполняемого файла или разделяемой библиотеки. Только в вызывается этот шаг /usr/bin/ld. В Linux ld является частью пакета binutils.

вместе с минимальными инструкциями о том, как общие библиотеки должны быть «подключены»

Компоновщик записывает, какие общие библиотеки требуются во время выполнения, и, возможно, какие версии библиотек или символов требуются.

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

Во время выполнения я понимаю, что исполняемый файл загружается в память, хотя я не уверен, как.

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

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

Динамический загрузчик может быть частью ОС, но в Linux он является частью libc (GLIBC, uClibc и musl имеют свои собственные загрузчики).

0 голосов
/ 31 августа 2018

Нет. ld ссылается как при создании библиотеки или exe, ld * .so - это часть загрузки. Также ld * .so является частью ОС, а не gcc suite afaik. ld обычно является частью (GNU) binutils в системе, основанной на gcc (но, например, обычно LLVM lld в системе, основанной на LLVM)

ld * .so - это ld-linux- {arch} .so.2 в Linux и /libexec/ld-elf.so, например, FreeBSD.

...