Достъп до функция на споделена библиотека чрез PLT

Има нещо, което не мога да разбера относно достъпа до функция на споделена библиотека от потребителски код.

Не мога да разбера защо PLT е необходим в този случай. Моят собствен код не е споделен, така че може да се променя, така че защо не видим на кой адрес е заредена функцията на споделената библиотека и не променим кода за директен достъп до нея, вместо да минаваме през PLT всеки път.

Дали защото не мога да знам този адрес, докато моят собствен код не бъде зареден в паметта?

Каква точно е причината за това?


person EL_9    schedule 06.06.2020    source източник


Отговори (1)


Моят собствен код не се споделя, така че може да бъде променен,

Вашият собствен код не се споделя само ако стартирате едно копие на вашата програма в системата. Ако стартирате повече от едно копие, вашият код е споделен между процесите и писането в него би предотвратило такова споделяне.

Забележка: това е за независими извиквания на вашия изпълним файл. Споделянето все още е възможно дори за модифициран код, ако множеството процеси имат връзка родител/дете.

Има допълнително съображение за x86_64 ELF системи: в модела на паметта по подразбиране (-mcmodel=medium) просто няма достатъчно място напр. CALL инструкция за извикване на произволен адрес: можете да извиквате само адреси +/-2GiB разстояние от текущата инструкция. Тъй като целта на обаждането може да е (често е) по-далеч, така или иначе ще трябва да използвате PLT запис.

И накрая, извикването чрез PLT позволява мързеливо разделяне на символи, което отлага разходите за изпълнение до времето, когато се извиква функция, и се извършва само за функция, която са извикана. Директното преместване на кода би накарало кода ви да се държи така, сякаш LD_BIND_NOW=1 е в сила, правейки двоичния ви файл да стартира по-бавно (понякога значително по-бавно).

person Employed Russian    schedule 08.06.2020