assemblyarmarm64instructions

How does the label in an ADRP instruction work in arm64?


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?


Solution

  • 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.