explain/tinyelf-arm.md
... ...
@@ -8,17 +8,17 @@ Looks like breadbox didn't want to go down *this* rabbithole. So we'll have to d
8 8
* There's a "Thumb" mode, with reduced instructions (eg. no free shifts, no 3-operand instructions) where all instructions are 2 bytes wide
9 9
* Switch to Thumb like this: `add lr, pc, #1; bx lr`
10 10
* On older ARMs, it was possible to directly write to `pc` and switch mode, but this doesn't seem to be possible on ARMv6 anymore.
11
-* The `mov` opcode doesn't accept arbitrary immediate values, so you sometimes have to spill values to a "constant pool"
11
+* The `mov` opcode doesn't accept arbitrary immediate values, so you sometimes have to spill values to a "constant pool", or be creative with assignments and register write-backs in load/store ops
12 12
* Null bytes decode to `andeq r0, r0` in ARM mode, or to `movs r0, r0` in Thumb mode, both are no-ops, unlike in x86 where null bytes cause a segfault.
13 13
* Instruction encoding is relatively sane, so you can predict what low-value 32-bit ints will decode to so you can treat them as (almost-)no-ops.
14 14
* It's a RISC, so you don't have one-byte-instructions, flexible addressing modes or stringops, but there are a few useful parts in ARM:
15 15
* `pc`, `sp` etc. behave as regular registers
16 16
* You can shift one operand of an instruction by a constant value for free, it doesn't cost any bytes. (ARM mode only) This can also be used to do fixed-point multiplications etc. (eg. `add r0, r0, lsr #1` for `r0*1.5`)
17 17
* `ldmia`/`stmia` are great for copying stuff around
18
-* [`e_machine` seems to be the only checked header field](https://code.woboq.org/linux/linux/arch/arm/kernel/elf.c.html) (`e_entry` alignment checks are normal, because if it wouldn't be aligned, the code would segfault on entry.)
19
-* `phdr` parsing etc. is done architecture-independent, so the same tricks should be usable here as well.
18
+* [`e_machine` (and `e_type`) seem to be the only checked header fields](https://code.woboq.org/linux/linux/arch/arm/kernel/elf.c.html) (`e_entry` alignment checks are normal, because if it wouldn't be aligned, the code would segfault on entry.)
19
+* `phdr` parsing etc. is done architecture-independently, so the same tricks should be usable here as well.
20 20
* Turns out it's even more relaxed than x86 when messing with `p_paddr`, `p_padding` and `p_flags`. It seems to be the case that the kernel & CPU will happily let you execute code in read-write pages.
21
-* Apparently the kernel doesn't look at the immediate field of `swi` instructions __if it's configured as EABI-only__ (which we assume).
21
+* Apparently the kernel doesn't look at the immediate field of `swi` and `bkpt` instructions __if it's configured as EABI-only__ (which we assume).
22 22
* [Dynamic linking stuff](https://linux.weeaboo.software/explain/rtld#dynamic-linking_arm)
23 23
24 24
### Minimal ELF Poc