Consider the line of code, creating a global variable:

let keys = ["s3kretSkwarl", "Ha!U'llNevar(Find)Me", ...] // the rest doesn't matter

Archive your app. Grep for “Nevar”. Shows up, just like you’d think. Sure. Grep for “s3kret”. Nothing?!?!?!! How is that possible? The program even calls print(keys) at one point, so the characters have to be in there somewhere. I hunt and hunt, and then I find them.

movz       x8, #'wa'
movk       x8, #'rl', lsl #16
movk       x8, #'\x00\xec', lsl #48
movz       x9, #'s3'
movk       x9, #'kr', lsl #16
movk       x9, #'et', lsl #32
movk       x9, #'Sk', lsl #48
stp        x8, x9, [x0, #0x20]
adr        x8, #0x1000067d0 ; "Ha!U'llNevar(Find)Me"

While longer strings are stored in the strings section, apparently shorter strings sometimes are inlined with move instructions. Did not expect that. I expected this for strings shorter than 8 characters (due to tagged pointers), but this is a 12 character string. It takes about 9 instructions to get it in place, but I’m guessing that’s better than storing it in the Strings section.

I am such a novice at understanding ARM assembly. I always feel like I’m wandering around, knocking over shiney things, with no idea what’s the grown-ups have built.


UPDATE: My expected turn takes an unexpected turn: It’s possible it’s an optimizer bug.