<div dir="ltr"><div style="font-family:arial,sans-serif;font-size:13px">  Hi,</div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px"> We're working on implementation of Mono JIT/ARM for Native Client, and want to discuss certain details about design of our solution.</div>
<div style="font-family:arial,sans-serif;font-size:13px"> Native Client's sandboxing mechanism, being a SFI solution, has rather strict  limitations on how verifiable machine code may look like. To be precise:</div><div style="font-family:arial,sans-serif;font-size:13px">
<br></div><div style="font-family:arial,sans-serif;font-size:13px"><div class="gmail_default">  1. all code/data access has to be in lower 1G range of address space</div><div class="gmail_default">  2. all branch targets have to be 16 bytes (bundle) aligned, unless</div>
<div class="gmail_default" style>      it's direct branch to the instruction which need no masking (see 3.) </div><div class="gmail_default">  3. code with register arguments (loads, stores, branches) must explicitly enforce 1. and 2. </div>
<div class="gmail_default">      by masking upper and lower bits (by bic reg, reg, #0xc000000f)</div><div class="gmail_default">  4. all code must be valid instructions, not matter if reachable or not</div><div class="gmail_default">
  5. the only exception from 4 is 16 bytes data bundles starting with UNDEF </div><div class="gmail_default">     instruction (0xE125BE70), 12 remaining bytes could be used for anything</div><div class="gmail_default">  6. no executable code could be easily modified in runtime, unless in data bundle, </div>
<div class="gmail_default">      or immediate argument of MOVT (A1), MOVW (A2), ORR/MOV/MVN</div><div class="gmail_default">      Even in this case - NaCl runtime call is needed for modifications to take effect.</div><div class="gmail_default">
  7. No direct PC manipulations allowed (mov, add to PC), it's allowed to be used </div><div class="gmail_default">       like x86 PC register (modulo PC-relative loads).</div><div class="gmail_default">  8. A<span style="white-space:nowrap">ll bl/blx must be bundle-end aligned  </span>and LR is masked before return, as everything else in 3.</div>
<div class="gmail_default" style>  9. Register R9 is used as TLS base, and could only be accessed as</div><div class="gmail_default" style>      ldr rd, [r9] and ldr rd [r9, #4].</div><div class="gmail_default" style><br>
</div></div><div style="font-family:arial,sans-serif;font-size:13px"> Most troublesome part for porting is using of patchable inline constants in trampolines. </div><div style="font-family:arial,sans-serif;font-size:13px">
 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.</div><div style="font-family:arial,sans-serif;font-size:13px">
 So for example, trampoline like this:</div><div style="font-family:arial,sans-serif;font-size:13px"><div>        ldr ip, [pc, #0]</div><div><span style="white-space:pre-wrap">   </span>b skip</div><div>        .word target</div>
<div>      skip:</div><div><span style="white-space:pre-wrap">     </span>mov lr, pc</div><div><span style="white-space:pre-wrap">       </span>mov pc, ip</div><div>would become (if r10 is used as jump table base register):</div><div>
      .align 4 # for NaCl only</div><div>         ldr ip, [r10, #32] # unique (per-method or class) index for every callsite</div><div>         nop  # for NaCl only, to have bl at bundle end</div><div>         bic r10, r10, #0xc000000f # for NaCl only</div>
<div>         bl ip # or blx<br></div></div><div style="font-family:arial,sans-serif;font-size:13px"> r10 could point somewhere in method metadata, where its relocation table is stored.</div><div style="font-family:arial,sans-serif;font-size:13px">
<br></div><div style="font-family:arial,sans-serif;font-size:13px"> 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</div>
<div style="font-family:arial,sans-serif;font-size:13px">such a table (maybe patch info?) are very welcome.</div><div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px">
 There are few advantages and disadvantages of this solution.</div><div style="font-family:arial,sans-serif;font-size:13px">Improvements:</div><div style="font-family:arial,sans-serif;font-size:13px">  - easily maintainable code (single trampoline mechnism with simple patching)</div>
<div style="font-family:arial,sans-serif;font-size:13px">  - no writes to the code being executed</div><div style="font-family:arial,sans-serif;font-size:13px">  - smaller code</div><div style="font-family:arial,sans-serif;font-size:13px">
  - no need to have entries in both i-cache and d-cache for branch destination</div><div style="font-family:arial,sans-serif;font-size:13px">Detriments:<br></div><div style="font-family:arial,sans-serif;font-size:13px">  - extra register used</div>
<div style="font-family:arial,sans-serif;font-size:13px">  - potentially worse cache locality compared to inline cache (although once jump table cached, it could be used few times)</div><div style="font-family:arial,sans-serif;font-size:13px">
  - need to init jump table base on entry to every method which uses trampolines</div><div style="font-family:arial,sans-serif;font-size:13px">  - limitation on number of callsites by immediate length in LDR, see <a href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/BABJGHFJ.html" target="_blank">http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/BABJGHFJ.html</a>; we can only use up to 1K of callsites.</div>
<div style="font-family:arial,sans-serif;font-size:13px">If more than 1K of callsites in method - constant pool index shall be constructed in register. </div><div style="font-family:arial,sans-serif;font-size:13px"><br></div>
<div style="font-family:arial,sans-serif;font-size:13px"> 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.</div>
<div style="font-family:arial,sans-serif;font-size:13px"><br></div><div style="font-family:arial,sans-serif;font-size:13px">  Thanks,</div><div style="font-family:arial,sans-serif;font-size:13px">     Nikolay.</div></div>