Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / native_client / src / trusted / debug_stub / abi.cc
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 static AbiMap_t *GetAbis() {
265   static AbiMap_t *_abis = new AbiMap_t();
266   return _abis;
267 }
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 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, "");
281
282   // TODO(cbiffle) Figure out how to REALLY detect ARM
283   Abi::Register("iwmmxt",
284                 RegsArm, sizeof(RegsArm), 15 /* pc */,
285                 &breakpoint_arm, XmlArm);
286
287   Abi::Register("mips",
288                 RegsMips, sizeof(RegsMips), 32 /* pc */,
289                 &breakpoint_mips, XmlMips);
290
291   return true;
292 }
293
294 static bool AbiIsAvailable() {
295   static bool initialized_ = AbiInit();
296   return initialized_;
297 }
298
299
300
301 Abi::Abi() {}
302 Abi::~Abi() {}
303
304 void Abi::Register(const char *name, RegDef *regs,
305                    uint32_t bytes, uint32_t ip, const BPDef *bp,
306                    const char *target_xml) {
307   uint32_t offs = 0;
308   const uint32_t cnt = bytes / sizeof(RegDef);
309
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_;
315   }
316
317   Abi *abi = new Abi;
318
319   abi->name_ = name;
320   abi->regCnt_ = cnt;
321   abi->regDefs_= regs;
322   abi->ctxSize_ = offs;
323   abi->bpDef_ = bp;
324   abi->ipIndex_ = ip;
325   abi->target_xml_ = target_xml;
326
327   AbiMap_t *abis = GetAbis();
328   (*abis)[name] = abi;
329 }
330
331 const Abi* Abi::Find(const char *name) {
332   if (!AbiIsAvailable()) {
333     NaClLog(LOG_ERROR, "Failed to initalize ABIs.");
334     return NULL;
335   }
336
337   AbiMap_t::const_iterator itr = GetAbis()->find(name);
338   if (itr == GetAbis()->end()) return NULL;
339
340   return itr->second;
341 }
342
343 const Abi* Abi::Get() {
344   static const Abi* abi = NULL;
345
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");
357     } else {
358       NaClLog(LOG_FATAL, "Abi::Get: Unknown CPU architecture\n");
359     }
360   }
361
362   return abi;
363 }
364
365 const char* Abi::GetName() const {
366   return name_;
367 }
368
369 const Abi::BPDef *Abi::GetBreakpointDef() const {
370   return bpDef_;
371 }
372
373 uint32_t Abi::GetContextSize() const {
374   return ctxSize_;
375 }
376
377 uint32_t Abi::GetRegisterCount() const {
378   return regCnt_;
379 }
380
381 const Abi::RegDef *Abi::GetRegisterDef(uint32_t index) const {
382   if (index >= regCnt_) return NULL;
383
384   return &regDefs_[index];
385 }
386
387 const Abi::RegDef *Abi::GetInstPtrDef() const {
388   return GetRegisterDef(ipIndex_);
389 }
390
391 }  // namespace gdb_rsp