как получить фактический адрес `func` от func@PLT на ARM64(компилятор gcc-4.9.2-arm64)

#assembly #gcc #arm #elf #dynamic-linking

Вопрос:

У меня есть функциональный тест::Foo::bar, адрес функции этой функции в cpp (void *) 0x423e70 _ZN4test3Foo3barEiPvml@plt (gdb) разберите 0x423e70 Дамп кода ассемблера для функции _ZN4test3Foo3barEiPvml@plt:

 0x0000000000423e70 < 0>:     adrp    x16, 0x513000
0x0000000000423e74 < 4>:     ldr     x17, [x16,#2272]
0x0000000000423e78 < 8>:     add     x16, x16, #0x8e0
0x0000000000423e7c < 12>:    br      x17
 

похоже, что адрес функции находится в PLT, а фактический адрес содержится в регистре x17. Мне интересно, могу ли я получить фактический адрес функции в GOT во время выполнения в программе CPP? Есть ли в любом случае возможность получить абсолютный адрес функции через PLT-адрес во время выполнения?

Спасибо

Комментарии:

1. Вы получаете это не из PLT, вы получаете это из записи GOT. (Заглушка PLT использует запись GOT в современных системах, а не изменяется сама по себе.) В зависимости от параметров компилятора и компиляции, использование указателя функции в C может выбрать загрузку из GOT вместо простого построения ссылки на запись PLT, исходя из предположения, что при каждом использовании fptr будет полезно исключить уровень косвенности.

2. Спасибо @PeterCordes, я использую компилятор gcc-4.9.2-arm64. Есть ли какие-либо параметры компиляции, которые могли бы загрузить указатель функции из GOT? Помогает ли-fPIC? или я должен включить-fno-plt. однако это поддерживается после 6.1.1.

3. IIRC, gcc -fPIE делает это. Или да, -fno-plt определенно сработает. Текущий GCC составляет 11 или 12; GCC 6 уже несколько лет и довольно стабилен, так что это может быть веской причиной для оправдания обновления до более нового, лучшего компилятора.