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.
12 #include "native_client/src/include/arm_sandbox.h"
13 #include "native_client/src/shared/platform/nacl_log.h"
14 #include "native_client/src/trusted/debug_stub/abi.h"
15 #include "native_client/src/trusted/debug_stub/platform.h"
17 using port::IPlatform;
21 #define MINIDEF(x, name, purpose) { #name, sizeof(x), Abi::purpose, 0, 0 }
23 static Abi::RegDef RegsX86_64[] = {
24 MINIDEF(uint64_t, rax, GENERAL),
25 MINIDEF(uint64_t, rbx, GENERAL),
26 MINIDEF(uint64_t, rcx, GENERAL),
27 MINIDEF(uint64_t, rdx, GENERAL),
28 MINIDEF(uint64_t, rsi, GENERAL),
29 MINIDEF(uint64_t, rdi, GENERAL),
30 MINIDEF(uint64_t, rbp, X86_64_TRUSTED_PTR),
31 MINIDEF(uint64_t, rsp, X86_64_TRUSTED_PTR),
32 MINIDEF(uint64_t, r8, GENERAL),
33 MINIDEF(uint64_t, r9, GENERAL),
34 MINIDEF(uint64_t, r10, GENERAL),
35 MINIDEF(uint64_t, r11, GENERAL),
36 MINIDEF(uint64_t, r12, GENERAL),
37 MINIDEF(uint64_t, r13, GENERAL),
38 MINIDEF(uint64_t, r14, GENERAL),
39 MINIDEF(uint64_t, r15, READ_ONLY),
40 MINIDEF(uint64_t, rip, X86_64_TRUSTED_PTR),
41 MINIDEF(uint32_t, eflags, GENERAL),
42 MINIDEF(uint32_t, cs, READ_ONLY),
43 MINIDEF(uint32_t, ss, READ_ONLY),
44 MINIDEF(uint32_t, ds, READ_ONLY),
45 MINIDEF(uint32_t, es, READ_ONLY),
46 MINIDEF(uint32_t, fs, READ_ONLY),
47 MINIDEF(uint32_t, gs, READ_ONLY),
50 static Abi::RegDef RegsX86_32[] = {
51 MINIDEF(uint32_t, eax, GENERAL),
52 MINIDEF(uint32_t, ecx, GENERAL),
53 MINIDEF(uint32_t, edx, GENERAL),
54 MINIDEF(uint32_t, ebx, GENERAL),
55 MINIDEF(uint32_t, esp, GENERAL),
56 MINIDEF(uint32_t, ebp, GENERAL),
57 MINIDEF(uint32_t, esi, GENERAL),
58 MINIDEF(uint32_t, edi, GENERAL),
59 MINIDEF(uint32_t, eip, GENERAL),
60 MINIDEF(uint32_t, eflags, GENERAL),
61 MINIDEF(uint32_t, cs, READ_ONLY),
62 MINIDEF(uint32_t, ss, READ_ONLY),
63 MINIDEF(uint32_t, ds, READ_ONLY),
64 MINIDEF(uint32_t, es, READ_ONLY),
65 MINIDEF(uint32_t, fs, READ_ONLY),
66 MINIDEF(uint32_t, gs, READ_ONLY),
69 static Abi::RegDef RegsArm[] = {
70 MINIDEF(uint32_t, r0, GENERAL),
71 MINIDEF(uint32_t, r1, GENERAL),
72 MINIDEF(uint32_t, r2, GENERAL),
73 MINIDEF(uint32_t, r3, GENERAL),
74 MINIDEF(uint32_t, r4, GENERAL),
75 MINIDEF(uint32_t, r5, GENERAL),
76 MINIDEF(uint32_t, r6, GENERAL),
77 MINIDEF(uint32_t, r7, GENERAL),
78 MINIDEF(uint32_t, r8, GENERAL),
79 MINIDEF(uint32_t, r9, GENERAL),
80 MINIDEF(uint32_t, r10, GENERAL),
81 MINIDEF(uint32_t, r11, GENERAL),
82 MINIDEF(uint32_t, r12, GENERAL),
83 MINIDEF(uint32_t, sp, GENERAL),
84 MINIDEF(uint32_t, lr, GENERAL),
85 MINIDEF(uint32_t, pc, GENERAL),
86 MINIDEF(uint32_t, cpsr, GENERAL),
89 static Abi::RegDef RegsMips[] = {
90 MINIDEF(uint32_t, zero, READ_ONLY),
91 MINIDEF(uint32_t, at, GENERAL),
92 MINIDEF(uint32_t, v0, GENERAL),
93 MINIDEF(uint32_t, v1, GENERAL),
94 MINIDEF(uint32_t, a0, GENERAL),
95 MINIDEF(uint32_t, a1, GENERAL),
96 MINIDEF(uint32_t, a2, GENERAL),
97 MINIDEF(uint32_t, a3, GENERAL),
98 MINIDEF(uint32_t, t0, GENERAL),
99 MINIDEF(uint32_t, t1, GENERAL),
100 MINIDEF(uint32_t, t2, GENERAL),
101 MINIDEF(uint32_t, t3, GENERAL),
102 MINIDEF(uint32_t, t4, GENERAL),
103 MINIDEF(uint32_t, t5, GENERAL),
104 MINIDEF(uint32_t, t6, GENERAL),
105 MINIDEF(uint32_t, t7, GENERAL),
106 MINIDEF(uint32_t, s0, GENERAL),
107 MINIDEF(uint32_t, s1, GENERAL),
108 MINIDEF(uint32_t, s2, GENERAL),
109 MINIDEF(uint32_t, s3, GENERAL),
110 MINIDEF(uint32_t, s4, GENERAL),
111 MINIDEF(uint32_t, s5, GENERAL),
112 MINIDEF(uint32_t, s6, GENERAL),
113 MINIDEF(uint32_t, s7, GENERAL),
114 MINIDEF(uint32_t, t8, GENERAL),
115 MINIDEF(uint32_t, t9, GENERAL),
116 MINIDEF(uint32_t, k0, READ_ONLY),
117 MINIDEF(uint32_t, k1, READ_ONLY),
118 MINIDEF(uint32_t, gp, GENERAL),
119 MINIDEF(uint32_t, sp, GENERAL),
120 MINIDEF(uint32_t, fp, GENERAL),
121 MINIDEF(uint32_t, ra, GENERAL),
122 MINIDEF(uint32_t, pc, GENERAL),
125 // Without this XML description, ARM GDB assumes a default register
126 // set with floating point registers f0-f7 and fps between pc and
127 // cpsr, and GDB queries CPSR via the "p" command for reading a single
129 static const char XmlArm[] =
130 "<feature name=\"org.gnu.gdb.arm.core\">\n"
131 " <reg name=\"r0\" bitsize=\"32\" type=\"uint32\"/>\n"
132 " <reg name=\"r1\" bitsize=\"32\" type=\"uint32\"/>\n"
133 " <reg name=\"r2\" bitsize=\"32\" type=\"uint32\"/>\n"
134 " <reg name=\"r3\" bitsize=\"32\" type=\"uint32\"/>\n"
135 " <reg name=\"r4\" bitsize=\"32\" type=\"uint32\"/>\n"
136 " <reg name=\"r5\" bitsize=\"32\" type=\"uint32\"/>\n"
137 " <reg name=\"r6\" bitsize=\"32\" type=\"uint32\"/>\n"
138 " <reg name=\"r7\" bitsize=\"32\" type=\"uint32\"/>\n"
139 " <reg name=\"r8\" bitsize=\"32\" type=\"uint32\"/>\n"
140 " <reg name=\"r9\" bitsize=\"32\" type=\"uint32\"/>\n"
141 " <reg name=\"r10\" bitsize=\"32\" type=\"uint32\"/>\n"
142 " <reg name=\"r11\" bitsize=\"32\" type=\"uint32\"/>\n"
143 " <reg name=\"r12\" bitsize=\"32\" type=\"uint32\"/>\n"
144 " <reg name=\"sp\" bitsize=\"32\" type=\"data_ptr\"/>\n"
145 " <reg name=\"lr\" bitsize=\"32\"/>\n"
146 " <reg name=\"pc\" bitsize=\"32\" type=\"code_ptr\"/>\n"
147 " <reg name=\"cpsr\" bitsize=\"32\" regnum=\"25\"/>\n"
150 // XML description for MIPS.
151 static const char XmlMips[] =
152 "<feature name=\"org.gnu.gdb.mips.cpu\">\n"
153 " <reg name=\"r0\" bitsize=\"32\" regnum=\"0\"/>\n"
154 " <reg name=\"r1\" bitsize=\"32\"/>\n"
155 " <reg name=\"r2\" bitsize=\"32\"/>\n"
156 " <reg name=\"r3\" bitsize=\"32\"/>\n"
157 " <reg name=\"r4\" bitsize=\"32\"/>\n"
158 " <reg name=\"r5\" bitsize=\"32\"/>\n"
159 " <reg name=\"r6\" bitsize=\"32\"/>\n"
160 " <reg name=\"r7\" bitsize=\"32\"/>\n"
161 " <reg name=\"r8\" bitsize=\"32\"/>\n"
162 " <reg name=\"r9\" bitsize=\"32\"/>\n"
163 " <reg name=\"r10\" bitsize=\"32\"/>\n"
164 " <reg name=\"r11\" bitsize=\"32\"/>\n"
165 " <reg name=\"r12\" bitsize=\"32\"/>\n"
166 " <reg name=\"r13\" bitsize=\"32\"/>\n"
167 " <reg name=\"r14\" bitsize=\"32\"/>\n"
168 " <reg name=\"r15\" bitsize=\"32\"/>\n"
169 " <reg name=\"r16\" bitsize=\"32\"/>\n"
170 " <reg name=\"r17\" bitsize=\"32\"/>\n"
171 " <reg name=\"r18\" bitsize=\"32\"/>\n"
172 " <reg name=\"r19\" bitsize=\"32\"/>\n"
173 " <reg name=\"r20\" bitsize=\"32\"/>\n"
174 " <reg name=\"r21\" bitsize=\"32\"/>\n"
175 " <reg name=\"r22\" bitsize=\"32\"/>\n"
176 " <reg name=\"r23\" bitsize=\"32\"/>\n"
177 " <reg name=\"r24\" bitsize=\"32\"/>\n"
178 " <reg name=\"r25\" bitsize=\"32\"/>\n"
179 " <reg name=\"r26\" bitsize=\"32\"/>\n"
180 " <reg name=\"r27\" bitsize=\"32\"/>\n"
181 " <reg name=\"r28\" bitsize=\"32\"/>\n"
182 " <reg name=\"r29\" bitsize=\"32\"/>\n"
183 " <reg name=\"r30\" bitsize=\"32\"/>\n"
184 " <reg name=\"r31\" bitsize=\"32\"/>\n"
185 " <reg name=\"lo\" bitsize=\"32\" regnum=\"33\"/>\n"
186 " <reg name=\"hi\" bitsize=\"32\" regnum=\"34\"/>\n"
187 " <reg name=\"pc\" bitsize=\"32\" regnum=\"32\"/>\n"
189 "<feature name=\"org.gnu.gdb.mips.cp0\">\n"
190 " <reg name=\"status\" bitsize=\"32\" regnum=\"37\"/>\n"
191 " <reg name=\"badvaddr\" bitsize=\"32\" regnum=\"35\"/>\n"
192 " <reg name=\"cause\" bitsize=\"32\" regnum=\"36\"/>\n"
194 "<feature name=\"org.gnu.gdb.mips.fpu\">\n"
195 " <reg name=\"f0\" bitsize=\"32\" type=\"ieee_single\" regnum=\"38\"/>\n"
196 " <reg name=\"f1\" bitsize=\"32\" type=\"ieee_single\"/>\n"
197 " <reg name=\"f2\" bitsize=\"32\" type=\"ieee_single\"/>\n"
198 " <reg name=\"f3\" bitsize=\"32\" type=\"ieee_single\"/>\n"
199 " <reg name=\"f4\" bitsize=\"32\" type=\"ieee_single\"/>\n"
200 " <reg name=\"f5\" bitsize=\"32\" type=\"ieee_single\"/>\n"
201 " <reg name=\"f6\" bitsize=\"32\" type=\"ieee_single\"/>\n"
202 " <reg name=\"f7\" bitsize=\"32\" type=\"ieee_single\"/>\n"
203 " <reg name=\"f8\" bitsize=\"32\" type=\"ieee_single\"/>\n"
204 " <reg name=\"f9\" bitsize=\"32\" type=\"ieee_single\"/>\n"
205 " <reg name=\"f10\" bitsize=\"32\" type=\"ieee_single\"/>\n"
206 " <reg name=\"f11\" bitsize=\"32\" type=\"ieee_single\"/>\n"
207 " <reg name=\"f12\" bitsize=\"32\" type=\"ieee_single\"/>\n"
208 " <reg name=\"f13\" bitsize=\"32\" type=\"ieee_single\"/>\n"
209 " <reg name=\"f14\" bitsize=\"32\" type=\"ieee_single\"/>\n"
210 " <reg name=\"f15\" bitsize=\"32\" type=\"ieee_single\"/>\n"
211 " <reg name=\"f16\" bitsize=\"32\" type=\"ieee_single\"/>\n"
212 " <reg name=\"f17\" bitsize=\"32\" type=\"ieee_single\"/>\n"
213 " <reg name=\"f18\" bitsize=\"32\" type=\"ieee_single\"/>\n"
214 " <reg name=\"f19\" bitsize=\"32\" type=\"ieee_single\"/>\n"
215 " <reg name=\"f20\" bitsize=\"32\" type=\"ieee_single\"/>\n"
216 " <reg name=\"f21\" bitsize=\"32\" type=\"ieee_single\"/>\n"
217 " <reg name=\"f22\" bitsize=\"32\" type=\"ieee_single\"/>\n"
218 " <reg name=\"f23\" bitsize=\"32\" type=\"ieee_single\"/>\n"
219 " <reg name=\"f24\" bitsize=\"32\" type=\"ieee_single\"/>\n"
220 " <reg name=\"f25\" bitsize=\"32\" type=\"ieee_single\"/>\n"
221 " <reg name=\"f26\" bitsize=\"32\" type=\"ieee_single\"/>\n"
222 " <reg name=\"f27\" bitsize=\"32\" type=\"ieee_single\"/>\n"
223 " <reg name=\"f28\" bitsize=\"32\" type=\"ieee_single\"/>\n"
224 " <reg name=\"f29\" bitsize=\"32\" type=\"ieee_single\"/>\n"
225 " <reg name=\"f30\" bitsize=\"32\" type=\"ieee_single\"/>\n"
226 " <reg name=\"f31\" bitsize=\"32\" type=\"ieee_single\"/>\n"
227 " <reg name=\"fcsr\" bitsize=\"32\" group=\"float\"/>\n"
228 " <reg name=\"fir\" bitsize=\"32\" group=\"float\"/>\n"
231 // Although INT3 is the traditional instruction for a debugger to use
232 // as a breakpoint instruction on x86, we use HLT. This is for two
234 // 1) Mac OS X has a kernel bug in which Mach exception handling will
235 // not always report INT3s that occur in x86-32 untrusted code.
236 // See http://code.google.com/p/nativeclient/issues/detail?id=2879
238 // 2) HLT leaves %eip/%rip pointing to the HLT instruction itself,
239 // which makes it easy to determine whether a breakpoint produced
240 // a fault. INT3 leaves %eip/%rip pointing to the address after
241 // the INT3 instruction, which makes it harder to tell
242 // unambiguously whether a fault was produced by an INT3 or the
243 // instruction after it.
244 static uint8_t breakpoint_code_x86[] = { 0xf4 /* HLT */ };
245 static Abi::BPDef breakpoint_x86 = {
246 sizeof(breakpoint_code_x86),
250 // We use an illegal instruction rather than BKPT because BKPT cannot
251 // be caught under qemu-arm whereas illegal instructions can.
252 static uint32_t breakpoint_code_arm[] = { NACL_INSTR_ARM_ABORT_NOW };
253 static Abi::BPDef breakpoint_arm = {
254 sizeof(breakpoint_code_arm),
255 (uint8_t *) breakpoint_code_arm
258 static uint8_t breakpoint_code_mips[] = { 0xd, 0x0, 0x0, 0x0 /* break */ };
259 static Abi::BPDef breakpoint_mips = {
260 sizeof(breakpoint_code_mips),
261 breakpoint_code_mips,
264 static AbiMap_t *GetAbis() {
265 static AbiMap_t *_abis = new AbiMap_t();
269 // AbiInit & AbiIsAvailable
270 // This pair of functions work together as singleton to
271 // ensure the module has been correctly initialized. All
272 // dependant functions should call AbiIsAvailable to ensure
273 // the module is ready.
274 static bool AbiInit() {
275 Abi::Register("i386",
276 RegsX86_32, sizeof(RegsX86_32), 8 /* eip */,
277 &breakpoint_x86, "");
278 Abi::Register("i386:x86-64",
279 RegsX86_64, sizeof(RegsX86_64), 16 /* rip */,
280 &breakpoint_x86, "");
282 // TODO(cbiffle) Figure out how to REALLY detect ARM
283 Abi::Register("iwmmxt",
284 RegsArm, sizeof(RegsArm), 15 /* pc */,
285 &breakpoint_arm, XmlArm);
287 Abi::Register("mips",
288 RegsMips, sizeof(RegsMips), 32 /* pc */,
289 &breakpoint_mips, XmlMips);
294 static bool AbiIsAvailable() {
295 static bool initialized_ = AbiInit();
304 void Abi::Register(const char *name, RegDef *regs,
305 uint32_t bytes, uint32_t ip, const BPDef *bp,
306 const char *target_xml) {
308 const uint32_t cnt = bytes / sizeof(RegDef);
310 // Build indexes and offsets
311 for (uint32_t loop = 0; loop < cnt; loop++) {
312 regs[loop].index_ = loop;
313 regs[loop].offset_ = offs;
314 offs += regs[loop].bytes_;
322 abi->ctxSize_ = offs;
325 abi->target_xml_ = target_xml;
327 AbiMap_t *abis = GetAbis();
331 const Abi* Abi::Find(const char *name) {
332 if (!AbiIsAvailable()) {
333 NaClLog(LOG_ERROR, "Failed to initalize ABIs.");
337 AbiMap_t::const_iterator itr = GetAbis()->find(name);
338 if (itr == GetAbis()->end()) return NULL;
343 const Abi* Abi::Get() {
344 static const Abi* abi = NULL;
346 if ((NULL == abi) && AbiIsAvailable()) {
347 if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 &&
348 NACL_BUILD_SUBARCH == 64) {
349 abi = Abi::Find("i386:x86-64");
350 } else if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 &&
351 NACL_BUILD_SUBARCH == 32) {
352 abi = Abi::Find("i386");
353 } else if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm) {
354 abi = Abi::Find("iwmmxt");
355 } else if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips) {
356 abi = Abi::Find("mips");
358 NaClLog(LOG_FATAL, "Abi::Get: Unknown CPU architecture\n");
365 const char* Abi::GetName() const {
369 const Abi::BPDef *Abi::GetBreakpointDef() const {
373 uint32_t Abi::GetContextSize() const {
377 uint32_t Abi::GetRegisterCount() const {
381 const Abi::RegDef *Abi::GetRegisterDef(uint32_t index) const {
382 if (index >= regCnt_) return NULL;
384 return ®Defs_[index];
387 const Abi::RegDef *Abi::GetInstPtrDef() const {
388 return GetRegisterDef(ipIndex_);
391 } // namespace gdb_rsp