запись перемещения в связывании (программирование на C) - PullRequest
0 голосов
/ 09 ноября 2018

все еще пытается понять запись перемещения в Перемещаемых объектных файлах, скажем, у меня есть эта простая программа на C:

//main1.c

void functionTest();

functionTest(){
   ...
}

int main()
{
   functionTest();
   return 0;
}

мои вопросы:

Q1. поскольку все известно main1, поэтому в разделе .rel.text или .rel.data файла main1.o нет записи о перемещении, верно ли мое понимание?

Q2. На рисунке ниже показано, как работает DLL,

enter image description here

для libc.so все известно (оно имеет все определения, как и main1), так почему же в libc.so все еще есть записи о перемещении? Я понимаю, что информацию таблицы символов нужно копировать, потому что она существует, как вы можете скопировать то, что не существует?

Q3. допустим, ниже приведена структура записи о перемещении;

typedef struct {
   int offset; /* Offset of the reference to relocate */
   int symbol:24, /* Symbol the reference should point to */
   type:8; /* Relocation type */
} Elf32_Rel;

так что я понимаю, что уже есть запись перемещения в main2.o для printf (), поэтому смещение будет примерно равно 8 или 9 байтам смещения от вызывающей функции, символ будет 'printf', тип R_386_PC32, поэтому если есть еще один файл, который нужно скопировать из libc.so в main2.o, какова структура этой записи о перемещении?

1 Ответ

0 голосов
/ 09 ноября 2018

Q1: Да, если вы скомпилируете main1.c в своем вопросе, он создаст без необходимости связывать что-либо, потому что он не использует функции, которые определены в другом месте.

Q2: Эта диаграмма неприменима к зданию main1.c, поскольку main1.c не использует внешние функции.Но в программе, которая имеет вызов, скажем, printf(), вот что происходит: диаграмма показывает, что записи о перемещении о libc.so размещаются в main2.o.Вы спрашиваете, "почему в libc.so все еще есть записи о перемещении?"но записи о перемещении не помещаются в libc.so;они помещаются в main2.o, и они относятся к вещам в libc.so.

Q2, продолжение # 1: Когда вы говорите "за libc"так что все известно ", это верно только в пределах libc.so.Все, что использует функцию, определенную в libc.so, будет не знать, как определена эта функция, , пока не произойдет связывание .Это функция ld: скопировать справочную информацию из библиотеки типа libc.so в программу , которая создается , например main2 на диаграмме.Справочная информация позволяет ядру, выполняющему от main2 до , также загружать libc.so в память таким образом, что выполнение может перетекать из кода main2 в код libc.so и обратно в main2 везде, где main2 вызывает функцию, определение / код которой находится в libc.so.

Q3: Я думаю, что лучший способ выразить это так: информация, которая используется для заполнить структура перемещения в пределах main2.o происходит от libc.so.Когда я говорю, что записи о перемещении копируются из libc.so, я имею в виду следующее: информация о цели (например, printf()) берется из libc.so и используется для предоставления значений для записи о перемещении в main2.o, целью которой являетсясообщить загрузчику, откуда загружать код для printf().

Q3, продолжение # 1: Есть еще один смысл, в котором libc.so имеет записи о перемещении:встроенный libc.so добавил записи перемещения в libc.so, так что все, что хочет использовать его (экспортируемые) функции и переменные, могут это делать. Эти не нужно никуда копировать.Частью построения объектного файла является создание информации для внутренних вещей, которые могут использовать другие программы;и частью построения программы является заполнение информацией о внешних вещах, которые она использует.Но мне кажется, что диаграмма показывает, что информация о libc.so и libvector.so добавляется в main2.o, так что загрузчик может загрузить весь необходимый код в память, когда main2выполняется.

...