Что означает инструкция «adrp x0, idmap_pg_dir» в сборке arm64?

#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 - .) .