1 : /*
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.
5 : */
6 :
7 : #include <assert.h>
8 :
9 : #include <map>
10 : #include <string>
11 :
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"
16 :
17 : using port::IPlatform;
18 :
19 : namespace gdb_rsp {
20 :
21 : #define MINIDEF(x, name, purpose) { #name, sizeof(x), Abi::purpose, 0, 0 }
22 :
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),
48 : };
49 :
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),
67 : };
68 :
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),
87 : };
88 :
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),
123 : };
124 :
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
128 : // register.
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"
148 : "</feature>\n";
149 :
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"
188 : "</feature>\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"
193 : "</feature>\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"
229 : "</feature>\n";
230 :
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
233 : // reasons:
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
237 : // for more details.
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),
247 : breakpoint_code_x86
248 : };
249 :
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
256 : };
257 :
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,
262 : };
263 :
264 1 : static AbiMap_t *GetAbis() {
265 1 : static AbiMap_t *_abis = new AbiMap_t();
266 1 : return _abis;
267 1 : }
268 :
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 1 : static bool AbiInit() {
275 : Abi::Register("i386",
276 : RegsX86_32, sizeof(RegsX86_32), 8 /* eip */,
277 1 : &breakpoint_x86, "");
278 : Abi::Register("i386:x86-64",
279 : RegsX86_64, sizeof(RegsX86_64), 16 /* rip */,
280 1 : &breakpoint_x86, "");
281 :
282 : // TODO(cbiffle) Figure out how to REALLY detect ARM
283 : Abi::Register("iwmmxt",
284 : RegsArm, sizeof(RegsArm), 15 /* pc */,
285 1 : &breakpoint_arm, XmlArm);
286 :
287 : Abi::Register("mips",
288 : RegsMips, sizeof(RegsMips), 32 /* pc */,
289 1 : &breakpoint_mips, XmlMips);
290 :
291 1 : return true;
292 1 : }
293 :
294 1 : static bool AbiIsAvailable() {
295 1 : static bool initialized_ = AbiInit();
296 1 : return initialized_;
297 1 : }
298 :
299 :
300 :
301 1 : Abi::Abi() {}
302 0 : Abi::~Abi() {}
303 :
304 : void Abi::Register(const char *name, RegDef *regs,
305 : uint32_t bytes, uint32_t ip, const BPDef *bp,
306 1 : const char *target_xml) {
307 1 : uint32_t offs = 0;
308 1 : const uint32_t cnt = bytes / sizeof(RegDef);
309 :
310 : // Build indexes and offsets
311 1 : for (uint32_t loop = 0; loop < cnt; loop++) {
312 1 : regs[loop].index_ = loop;
313 1 : regs[loop].offset_ = offs;
314 1 : offs += regs[loop].bytes_;
315 1 : }
316 :
317 1 : Abi *abi = new Abi;
318 :
319 1 : abi->name_ = name;
320 1 : abi->regCnt_ = cnt;
321 1 : abi->regDefs_= regs;
322 1 : abi->ctxSize_ = offs;
323 1 : abi->bpDef_ = bp;
324 1 : abi->ipIndex_ = ip;
325 1 : abi->target_xml_ = target_xml;
326 :
327 1 : AbiMap_t *abis = GetAbis();
328 1 : (*abis)[name] = abi;
329 1 : }
330 :
331 1 : const Abi* Abi::Find(const char *name) {
332 1 : if (!AbiIsAvailable()) {
333 0 : NaClLog(LOG_ERROR, "Failed to initalize ABIs.");
334 0 : return NULL;
335 : }
336 :
337 1 : AbiMap_t::const_iterator itr = GetAbis()->find(name);
338 1 : if (itr == GetAbis()->end()) return NULL;
339 :
340 1 : return itr->second;
341 1 : }
342 :
343 1 : const Abi* Abi::Get() {
344 : static const Abi* abi = NULL;
345 :
346 1 : if ((NULL == abi) && AbiIsAvailable()) {
347 : if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 &&
348 1 : NACL_BUILD_SUBARCH == 64) {
349 0 : abi = Abi::Find("i386:x86-64");
350 0 : } else if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 &&
351 1 : NACL_BUILD_SUBARCH == 32) {
352 1 : abi = Abi::Find("i386");
353 0 : } else if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm) {
354 0 : abi = Abi::Find("iwmmxt");
355 0 : } else if (NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips) {
356 0 : abi = Abi::Find("mips");
357 0 : } else {
358 0 : NaClLog(LOG_FATAL, "Abi::Get: Unknown CPU architecture\n");
359 : }
360 : }
361 :
362 1 : return abi;
363 1 : }
364 :
365 1 : const char* Abi::GetName() const {
366 1 : return name_;
367 1 : }
368 :
369 0 : const Abi::BPDef *Abi::GetBreakpointDef() const {
370 0 : return bpDef_;
371 0 : }
372 :
373 1 : uint32_t Abi::GetContextSize() const {
374 1 : return ctxSize_;
375 1 : }
376 :
377 1 : uint32_t Abi::GetRegisterCount() const {
378 1 : return regCnt_;
379 1 : }
380 :
381 1 : const Abi::RegDef *Abi::GetRegisterDef(uint32_t index) const {
382 1 : if (index >= regCnt_) return NULL;
383 :
384 1 : return ®Defs_[index];
385 1 : }
386 :
387 1 : const Abi::RegDef *Abi::GetInstPtrDef() const {
388 1 : return GetRegisterDef(ipIndex_);
389 1 : }
390 :
391 : } // namespace gdb_rsp
|