Im trying to figure out how ADRP works. I have this line of code:
0x100595c74 <+0>: adrp x17, 13159
My initial understanding of ADRP is that the program adds 0x100595c74
with an integer 13159
then makes the 12 lowest bits all 0 before storing this value into register x17
13159 = 0x3367
0x100595c74 + 0x3367 = 0x100598FDB
//Zeroing out the 12 lowest bits
0x100598FDB --> 0x100598000
Based on my calculations, 0x100598000
should be the value stored in x17
However, the value in the register is a total different number
(lldb) register read x17
x17 = 0x00000001038fc000
I did some research and found some information.
From the arm64 documentation, they explain the syntax of adrp64 as follows:
ADRP Xd, label
Where:
Xd
is the 64-bit name of the general-purpose destination register, in the range 0 to 31.
label
is the program label whose 4KB page address is to be calculated. An offset from the page address of this instruction, in the range ±4GB.
So, what is a program label? How do I calculate the actual value that is stored in the register?
If the integer 13159
is an offset from the page address of this instruction, how do I find the page address?
Your disassembler seems to be providing the operand in the raw form, how it is encoded in the instruction which is already page granular. You need to add the 12 trailing zero bits. Thus the calculation should look more like 0x100595c74 + 0x3367000 = 0x1038fcc74
which will give the expected 0x1038fc000
page address.