В вашем описании несколько неточностей, и неясно, неточны ли вы в понимании процесса обработки или в описании их.
Когда вы пишете C приложение, и вы компилируете его (скажем, с помощью g cc), оно переводится в машинные инструкции, которые представляют код и данные.
Это не совсем точно: между машинными инструкциями есть разница "и" машинный код ".
Когда вы компилируете файл .c
, некоторые компиляторы преобразуют его в машинные инструкции (сборка), а затем передают его ассемблеру для получения машинного кода (G CC делает который). Другие компиляторы имеют встроенный ассемблер и фактически пропускают этап генерации сборки (это делает Clang).
Результат вызова компилятора - файл elf.
On некоторые , но не все системы, результатом компиляции является перемещаемый файл ELF. Другие системы создают объектные файлы в другом формате, например, XCOFF или Mach-O.
Файл elf содержит (среди прочего) заголовок раздела, который в основном представляет собой серию Elf64_Shdr для каждого раздела. Ваше скомпилированное приложение содержит.
Приложение еще не создано, поэтому это неточно. Кроме того, Elf64_Shdr
относится только к 64-битным платформам ELF; на 32-битных машинах это Elf32_Ehdr
.
Когда мы запускаем команду make
Команда make
не имеет ничего , имеющего отношение к что-нибудь. Он просто вызывает компилятор и компоновщик (или другие инструменты) в зависимости от ситуации. Вы можете заменить его сценарием оболочки или просто набрать команды вручную.
и передать ему файл эльфа
Шаг ссылки включает один или больше (обычно больше) перемещаемых ELF
объектных файлов, архивных библиотек и динамических c библиотек.
компоновщик входит в игру и просматривает все разделы, созданные компилятором, на их присваивает имена и атрибуты и группирует их в «сегменты» в соответствии с правилами файла сценария ld
Чтобы понять, что делает компоновщик, вы можете прочитать эту серию сообщений в блоге .
Ваше описание упрощает работу компоновщика. Компоновщик намного сложнее и выполняет разрешение перемещения, о котором вы не упомянули, и много других задач.
и создает исполняемый файл, который мы можем запустить.
Обычно true.
Вы можете попросить компоновщика объединить несколько перемещаемых объектных файлов в объединенный объектный файл (с ld -r foo.o bar.o -o combined.o
), и в этом случае результат будет не быть исполняемым файлом.
Вы также можете попросить компоновщика связать совместно используемую библиотеку вместо ссылки на исполняемый файл.
Таким образом, в основном сегменты представляют собой не более чем разделы с одинаковыми атрибутами сгруппированы вместе в общем разделе с указанным c именем.
False. lot больше для связывания, чем группирование разделов вместе.
Затем, когда мы фактически запускаем созданный исполняемый файл, загрузчик входит в игру
Загрузчик вступает в игру только для динамически связанных исполняемых файлов. Полностью исполняемые c исполняемые файлы не имеют загрузчика и запускаются непосредственно самим ядром.
и просматривает эти сегменты, созданные компоновщиком, и, читая эту информацию, отображает их на карте инструкции машины к различным ячейкам памяти, чтобы процесс мог работать. Это то, что называется (в моем понимании) образом памяти.
В основном правильно. Некоторые части образа памяти вообще не берутся с диска (например, локальное хранилище потока и содержимое объединенных .bss
разделов)