2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
7 #include "native_client/src/shared/platform/nacl_check.h"
8 #include "native_client/src/trusted/service_runtime/nacl_globals.h"
9 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
10 #include "native_client/src/trusted/service_runtime/arch/arm/sel_ldr_arm.h"
11 #include "native_client/src/trusted/service_runtime/arch/arm/tramp_arm.h"
14 /* NOTE(robertm): the trampoline organization for ARM is currenly assuming
15 * NACL_TRAMPOLINE_SIZE == 32. This is contrary to the bundle size
16 * which is 16. The reason for this is tramp.S which has a payload
17 * 5 instr + one data item
21 * Install a syscall trampoline at target_addr. NB: Thread-safe.
22 * The code being patched is from tramp.S
24 void NaClPatchOneTrampolineCall(uintptr_t call_target_addr,
25 uintptr_t target_addr) {
26 struct NaClPatchInfo patch_info;
27 struct NaClPatch patch_syscall_seg;
30 * For ARM we only need to patch in the address of NaClSyscallSeg.
31 * We only do even that in case we're PIC (to avoid a TEXTREL).
34 NaClPatchInfoCtor(&patch_info);
36 patch_info.dst = target_addr;
37 patch_info.src = (uintptr_t) &NaCl_trampoline_seg_code;
38 patch_info.nbytes = ((uintptr_t) &NaCl_trampoline_seg_end
39 - (uintptr_t) &NaCl_trampoline_seg_code) - 4;
41 patch_info.num_abs32 = 1;
42 patch_info.abs32 = &patch_syscall_seg;
43 patch_syscall_seg.target = (uintptr_t) &NaCl_trampoline_syscall_seg_addr;
44 patch_syscall_seg.value = call_target_addr;
46 NaClApplyPatchToMemory(&patch_info);
49 void NaClPatchOneTrampoline(struct NaClApp *nap,
50 uintptr_t target_addr) {
51 UNREFERENCED_PARAMETER(nap);
53 NaClPatchOneTrampolineCall((uintptr_t) &NaClSyscallSeg, target_addr);
57 void NaClFillMemoryRegionWithHalt(void *start, size_t size) {
58 #if defined(NACL_TARGET_ARM_THUMB2_MODE)
59 uint16_t *inst = (uint16_t *) start;
61 uint32_t *inst = (uint32_t *) start;
62 #endif /* defined(NACL_TARGET_ARM_THUMB2_MODE) */
65 CHECK(sizeof *inst == NACL_HALT_LEN);
66 CHECK(0 == size % NACL_HALT_LEN);
67 /* check that the region start is 4 bytes aligned */
68 CHECK(0 == (uint32_t)start % NACL_HALT_LEN);
70 for (i = 0; i < (size / NACL_HALT_LEN); i++)
71 inst[i] = NACL_HALT_OPCODE;
75 void NaClFillTrampolineRegion(struct NaClApp *nap) {
76 NaClFillMemoryRegionWithHalt((void *)(nap->mem_start + NACL_TRAMPOLINE_START),
77 NACL_TRAMPOLINE_SIZE);
81 void NaClLoadSpringboard(struct NaClApp *nap) {
82 UNREFERENCED_PARAMETER(nap);