Relative References in ARM64 Disassembly

POV: You are a compiler targeting arm641, and you want some code to reference this global variable from the same library. The classic way to do this is to emit an instruction that loads “the address of X”, which will be determined at run time by the dynamic loader. But that’s not super efficient! For one thing, addresses are 64 bits long, and instructions are only 32 bits, so you can either break it up into multiple instructions, or load the address from some other location. But more importantly, the global variable is in the same library. The dynamic loader isn’t going to break it up from this code2, and if we knew how far away it was we could reference it that way.

That’s what the adrp instruction’s for.


This is going to be another one of those posts where I did something ridiculous and then show you how I got there, so let’s just get right to it.

Automatic Reference Counting

In the Cocoa world, the big news from WWDC is the advent of Automatic Reference Counting, or ARC. The only real documentation for the system is an unlinked reference page on the Clang website, but as Clang is open source and the implementation’s in the latest builds now, that counts as public information.

The Cocoa frameworks have long used a reference-count-based system, but as of Mac OS X v10.5, Apple added optional garbage collection. As with most GC systems, you can mark certain references as __weak (which automatically become nil when their target is collected), and the actual collection of…