[Mono-dev] ARM/NativeClient port

Paolo Molaro 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
> bundle,
>       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
>       skip:
> 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
> callsite
>          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 mailing list