#assembly #linux-kernel #arm64
#сборка #linux-ядро #arm64
Вопрос:
Вопрос по языку ассемблера arm64.
Например, в исходном коде linux 5.9.15 в arch/arm64/kernel/vmlinux.lds.S (сценарий компоновщика) есть строка idmap_pg_dir = .;
. итак, idmap_pg_dir — это адрес. Теперь в arch/arm64/kernel/head.S есть строка adrp x0, idmap_pg_dir
. Означает ли это
1) x0 = PC idmap_pg_dir or
2) x0 = idmap_pg_dir ?
Я думал, когда мы это делаем adrp x0, addr1
, обычно addr1
это смещение адреса относительно ПК, и x0 становится PC addr
. Но сценарий компоновщика, похоже, говорит idmap_pg_dir
, что это просто абсолютный адрес. (не так ли?) Так что я в замешательстве. Пожалуйста, кто-нибудь, поправьте меня.
Комментарии:
1. Он станет относительным адресом ПК, но компоновщик вычисляет смещение таким образом, чтобы в конечном итоге он давал правильный результат, поэтому
x0 = idmap_pg_dir
(при условии, что он выровнен по странице). Если вы это сделаетеobjdump -dr
head.o
, вы должны увидеть тип перемещения.2. Вы имеете в виду, что компилятор / компоновщик генерирует позиционно-независимый код (PIC), поэтому даже переменный адрес в скрипте компоновщика преобразуется в значения, относящиеся к ПК, и конечный результат является правильным? Похоже на то. (вы можете дать ответ, и я могу его выбрать). Вещь objdump -dr, которую я проверю завтра. Спасибо!
Ответ №1:
В справочном руководстве по архитектуре ARMv8 в разделе инструкций ADRP говорится,
Это метка программы, адрес страницы которой 4 КБ должен быть вычислен. Его смещение от адреса страницы этой инструкции в диапазоне /-4 ГБ кодируется как «immhi: immlo», умноженное на 4096.
Итак, компилятор «вычисляет» «смещение» к «метке». Таким образом, вместо абсолютного адреса метки используется «смещение» от текущего параметра.
Комментарии:
1. По сути, это
x0 = pc (idmap_pg_dir - .)
.