[Mono-dev] ARM/NativeClient port
lupus at oddwiz.org
Mon Feb 4 14:36:30 UTC 2013
On 01/30/13 Nikolay Igotti wrote:
> 1. all code/data access has to be in lower 1G range of address space
> 2. all branch targets have to be 16 bytes (bundle) aligned, unless
> it's direct branch to the instruction which need no masking (see 3.)
> 3. code with register arguments (loads, stores, branches) must explicitly
> enforce 1. and 2.
> by masking upper and lower bits (by bic reg, reg, #0xc000000f)
> 4. all code must be valid instructions, not matter if reachable or not
> 5. the only exception from 4 is 16 bytes data bundles starting with UNDEF
> instruction (0xE125BE70), 12 remaining bytes could be used for anything
> 6. no executable code could be easily modified in runtime, unless in data
> or immediate argument of MOVT (A1), MOVW (A2), ORR/MOV/MVN
> Even in this case - NaCl runtime call is needed for modifications to
> take effect.
> 7. No direct PC manipulations allowed (mov, add to PC), it's allowed to
> be used
> like x86 PC register (modulo PC-relative loads).
> 8. All bl/blx must be bundle-end aligned and LR is masked before return,
> as everything else in 3.
Can you define precisely what a bundle is in this context? 16 bytes? Does it
need to be aligned? Do the data bundles need alignment, too?
> 9. Register R9 is used as TLS base, and could only be accessed as
> ldr rd, [r9] and ldr rd [r9, #4].
> Most troublesome part for porting is using of patchable inline constants
> in trampolines.
> Our idea is to emit per-method (or per class?) "jump table" somewhere in
> .data, which contains list of all relocations, and use some register to
> point to this table.
> So for example, trampoline like this:
> ldr ip, [pc, #0]
> b skip
> .word target
> mov lr, pc
> mov pc, ip
> would become (if r10 is used as jump table base register):
> .align 4 # for NaCl only
> ldr ip, [r10, #32] # unique (per-method or class) index for every
> nop # for NaCl only, to have bl at bundle end
> bic r10, r10, #0xc000000f # for NaCl only
> bl ip # or blx
> r10 could point somewhere in method metadata, where its relocation table
> is stored.
> So our question is if someone sees problem with such approach, or could
> suggest better alternative. Also advises which register could be used as
> the jump table base, and where to store
> such a table (maybe patch info?) are very welcome.
> If there will be no strong objections, we plan to implement such a
> solution under configure/compilation flag for both NaCl and generic ARM
> port, and ask Mono maintainers to commit it.
The use of an extra register makes this unsuitable for the genric ARM port, IMHO.
Can't you combine a data bundle with up to three trampolines which can easily access
the 12 bytes in the data bundle with pc-relative addressing?
IE, assuming a bundle is 16 bytes, you allocate 64 at a time and the layout is:
[data bundle: undef, data1, data2, data3]
[tramp1: ldr ip [pc, data1]; nop; bic...; blx ip]
[tramp2: ldr ip [pc, data2]; nop; bic...; blx ip]
[tramp3: ldr ip [pc, data3]; nop; bic...; blx ip]
and then you hand out the individual trampolines from this chunk until full.
More information about the Mono-devel-list