OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 #include "debugger/nacl-gdb_server/gdb_registers.h" | |
5 #include <string.h> | |
6 | |
7 // Ok, now we have a definite answer on how gdbserver package registers | |
8 // in 'g' command response. | |
9 // You have to download gdb source code, and look there: | |
10 // | |
11 // <gdb_source_root>\gdb\regformats\reg-i32.dat | |
12 // <gdb_source_root>\gdb\regformats\reg-x86-64.dat | |
13 // | |
14 // name:i386 | |
15 // expedite:ebp,esp,eip | |
16 // 32:eax | |
17 // 32:ecx | |
18 // 32:edx | |
19 // 32:ebx | |
20 // 32:esp | |
21 // 32:ebp | |
22 // 32:esi | |
23 // 32:edi | |
24 // 32:eip | |
25 // 32:eflags | |
26 // 32:cs | |
27 // 32:ss | |
28 // 32:ds | |
29 // 32:es | |
30 // 32:fs | |
31 // 32:gs | |
32 // | |
33 // name:x86_64 | |
34 // expedite:rbp,rsp,rip | |
35 // 64:rax | |
36 // 64:rbx | |
37 // 64:rcx | |
38 // 64:rdx | |
39 // 64:rsi | |
40 // 64:rdi | |
41 // 64:rbp | |
42 // 64:rsp | |
43 // 64:r8 | |
44 // 64:r9 | |
45 // 64:r10 | |
46 // 64:r11 | |
47 // 64:r12 | |
48 // 64:r13 | |
49 // 64:r14 | |
50 // 64:r15 | |
51 // 64:rip | |
52 // 32:eflags | |
53 // 32:cs | |
54 // 32:ss | |
55 // 32:ds | |
56 // 32:es | |
57 // 32:fs | |
58 // 32:gs | |
59 | |
60 namespace { | |
61 | |
62 #define X86_64_REGS \ | |
63 REG(rax);\ | |
64 REG(rbx);\ | |
65 REG(rcx);\ | |
66 REG(rdx);\ | |
67 REG(rsi);\ | |
68 REG(rdi);\ | |
69 REG(rbp);\ | |
70 REG(rsp);\ | |
71 REG(r8);\ | |
72 REG(r9);\ | |
73 REG(r10);\ | |
74 REG(r11);\ | |
75 REG(r12);\ | |
76 REG(r13);\ | |
77 REG(r14);\ | |
78 REG(r15);\ | |
79 REG(rip);\ | |
80 REG(eflags);\ | |
81 REG(cs);\ | |
82 REG(ss);\ | |
83 REG(ds);\ | |
84 REG(es);\ | |
85 REG(fs);\ | |
86 REG(gs) | |
87 | |
88 // Registers SegCs, SegSs, SegDs, SegEs, SegFs and SegGs are defined as | |
89 // 64-bit in user.h for linux-64, but passed as 32-bit by RSP protocol. | |
90 // | |
91 bool IsSegmentRegisterIsPassedAs32Bit(const char* register_name) { | |
92 const char* kSegmentRegistersPassedAs32Bit[] = { | |
93 "eflags", | |
94 "cs", | |
95 "ss", | |
96 "ds", | |
97 "es", | |
98 "fs", | |
99 "gs" | |
100 }; | |
101 size_t num = sizeof(kSegmentRegistersPassedAs32Bit) / | |
102 sizeof(kSegmentRegistersPassedAs32Bit[0]); | |
103 for (size_t i = 0; i < num; i++) | |
104 if (strcmp(kSegmentRegistersPassedAs32Bit[i], register_name) == 0) | |
105 return true; | |
106 return false; | |
107 } | |
108 | |
109 /// Copies content of the register |name| from GDB RSP packaged blob | |
110 /// into thread context. | |
111 /// @param[in] blob blob with GDB RSP packaged registers | |
112 /// @param[in] offset offset of the register data from the beginning of the blob | |
113 /// @param[out] dst destination for the register data (inside CONTEXT structure) | |
114 /// @param[int] reg_size size of the register in bytes | |
115 /// @param[in] name name of the register as defined in the CONTEXT structure | |
116 /// @return number of copied bytes | |
117 size_t CopyRegisterFromBlobToCONTEXT(const debug::Blob& blob, | |
118 size_t offset, | |
119 void* dst, | |
120 int reg_size, | |
121 const char* name) { | |
122 if (IsSegmentRegisterIsPassedAs32Bit(name)) | |
123 reg_size = 4; | |
124 | |
125 blob.Peek(offset, dst, reg_size); | |
126 return reg_size; | |
127 } | |
128 | |
129 void CopyRegisterFromCONTEXTToBlob(const void* src, | |
130 int reg_size, | |
131 const char* name, | |
132 debug::Blob* blob) { | |
133 if (IsSegmentRegisterIsPassedAs32Bit(name)) { | |
134 blob->Append(debug::Blob(src, 4)); | |
135 } else { | |
136 blob->Append(debug::Blob(src, reg_size)); | |
137 } | |
138 } | |
139 } // namespace | |
140 | |
141 namespace rsp { | |
142 void GdbRegistersToCONTEXT(const debug::Blob& gdb_regs, user_regs_struct* ct) { | |
143 size_t offset = 0; | |
144 #define REG(name) ct->name = 0;\ | |
145 offset += CopyRegisterFromBlobToCONTEXT(gdb_regs, \ | |
146 offset, \ | |
147 &ct->name, \ | |
148 sizeof(ct->name), \ | |
149 #name) | |
150 X86_64_REGS; | |
151 #undef REG | |
152 } | |
153 | |
154 void CONTEXTToGdbRegisters(const user_regs_struct& ct, debug::Blob* gdb_regs) { | |
155 #define REG(name) CopyRegisterFromCONTEXTToBlob(&ct.name, \ | |
156 sizeof(ct.name), \ | |
157 #name, \ | |
158 gdb_regs) | |
159 X86_64_REGS; | |
160 #undef REG | |
161 } | |
162 } // namespace rsp | |
163 | |
OLD | NEW |