#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 уже несколько лет и довольно стабилен, так что это может быть веской причиной для оправдания обновления до более нового, лучшего компилятора.