OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2011 The Native Client Authors. All rights reserved. | |
3 * Use of this source code is governed by a BSD-style license that can | |
4 * be found in the LICENSE file. | |
5 */ | |
6 | |
7 #include "debug_conn/debug_packet.h" | |
8 #include "debug_conn/debug_stub_vsx.h" | |
9 #include "debug_conn/debug_util.h" | |
10 #include "native_client/src/shared/platform/nacl_log.h" | |
11 #include <sstream> | |
12 | |
13 using namespace nacl_debug_conn; | |
14 using namespace std; | |
15 | |
16 DebugPacket::DebugPacket() : seq(-1) {} | |
17 | |
18 void DebugPacket::Clear() { | |
19 data.str(""); | |
20 seq = -1; | |
21 } | |
22 | |
23 void DebugPacket::Rewind() { | |
24 data.seekg(0, ios::beg); | |
25 data.seekp(0, ios::beg); | |
26 } | |
27 | |
28 void DebugPacket::AddRawChar(char ch) { | |
29 data << ch; | |
30 } | |
31 | |
32 void DebugPacket::AddByte(uint8_t ch) { | |
33 char seq1 = debug_int_to_nibble(ch >> 4); | |
34 char seq2 = debug_int_to_nibble(ch & 0xF); | |
35 | |
36 AddRawChar(seq1); | |
37 AddRawChar(seq2); | |
38 } | |
39 | |
40 void DebugPacket::AddBlock(void *ptr, int len) { | |
41 const char *p = (const char *) ptr; | |
42 | |
43 for (int offs = 0; offs < len; offs++) | |
44 AddByte(p[offs]); | |
45 } | |
46 | |
47 void DebugPacket::AddWord16(uint16_t val) { | |
48 AddBlock(&val, sizeof(val)); | |
49 } | |
50 | |
51 void DebugPacket::AddWord32(uint32_t val) { | |
52 AddBlock(&val, sizeof(val)); | |
53 } | |
54 | |
55 void DebugPacket::AddWord64(uint64_t val) { | |
56 AddBlock(&val, sizeof(val)); | |
57 } | |
58 | |
59 void DebugPacket::AddPointer(void *ptr) { | |
60 return AddBlock(&ptr, sizeof(ptr)); | |
61 } | |
62 | |
63 void DebugPacket::AddString(const char *str) { | |
64 data << str; | |
65 } | |
66 | |
67 void DebugPacket::AddHexString(const char *str) { | |
68 while (*str) { | |
69 AddByte(*str); | |
70 str++; | |
71 } | |
72 } | |
73 | |
74 void DebugPacket::AddNumberSep(uint64_t val, char sep) { | |
75 char out[sizeof(val) * 2]; | |
76 int nibbles = 0; | |
77 int a; | |
78 | |
79 // Check for -1 optimization | |
80 if (val == -1) { | |
81 AddRawChar('-'); | |
82 AddRawChar('1'); | |
83 } | |
84 else { | |
85 // Assume we have the valuse 0x00001234 | |
86 for (a=0; a < sizeof(val); a++) { | |
87 uint8_t byte = val & 0xFF; | |
88 // Stream in with bytes reverse, starting at least significant | |
89 // So we store 4, then 3, 2, 1 | |
90 out[nibbles++] = debug_int_to_nibble(byte & 0xF); | |
91 out[nibbles++] = debug_int_to_nibble(byte >> 4); | |
92 | |
93 // Get the next 8 bits; | |
94 val >>= (intptr_t) 8; | |
95 | |
96 // Supress leading zeros, so we are done when val hits zero | |
97 if (val == 0) | |
98 break; | |
99 } | |
100 | |
101 // Strip the high zero for this byte if needed | |
102 if ((nibbles > 2) && (out[nibbles-1] == '0')) | |
103 nibbles--; | |
104 | |
105 // Now write it out reverse to correct the order | |
106 while (nibbles) { | |
107 nibbles--; | |
108 AddRawChar(out[nibbles]); | |
109 } | |
110 } | |
111 | |
112 // If we asked for a sperator, insert it | |
113 if (sep) | |
114 AddRawChar(sep); | |
115 } | |
116 | |
117 bool DebugPacket::GetNumberSep(uint64_t *val, char *sep) { | |
118 uint64_t out = 0; | |
119 char ch; | |
120 if (!GetRawChar(&ch)) | |
121 return false; | |
122 | |
123 // Check for -1 | |
124 if (ch == '-') { | |
125 if (!GetRawChar(&ch)) | |
126 return false; | |
127 if (ch == '1') { | |
128 *val = -1; | |
129 ch = 0; | |
130 GetRawChar(&ch); | |
131 if (sep) | |
132 *sep = ch; | |
133 return true; | |
134 } | |
135 return false; | |
136 } | |
137 | |
138 do { | |
139 uint64_t nib = debug_nibble_to_int(ch); | |
140 | |
141 // If we can't translate, this must be the separator | |
142 if (nib == (uint64_t) -1) | |
143 break; | |
144 | |
145 out = (out << (uint64_t) 4) + nib; | |
146 | |
147 // Get the next character (if availible) | |
148 ch = 0; | |
149 if (!GetRawChar(&ch)) | |
150 break; | |
151 | |
152 } while (1); | |
153 | |
154 // Set the value; | |
155 *val = out; | |
156 | |
157 // If the user want it... | |
158 if (sep) | |
159 *sep = ch; | |
160 | |
161 return true; | |
162 } | |
163 | |
164 bool DebugPacket::GetHexString(const char **sep) { | |
165 string out; | |
166 char ch; | |
167 | |
168 while (GetRawChar(&ch)) | |
169 out += ch; | |
170 | |
171 *sep = strdup(out.data()); | |
172 return true; | |
173 } | |
174 | |
175 bool DebugPacket::GetRawChar(char *ch) { | |
176 if (data.eof()) | |
177 return DS_NONE; | |
178 | |
179 data >> *ch; | |
180 return DS_OK; | |
181 } | |
182 | |
183 bool DebugPacket::GetByte(uint8_t *ch) { | |
184 char seq1, seq2; | |
185 bool res; | |
186 | |
187 res = GetRawChar(&seq1); | |
188 res = GetRawChar(&seq2); | |
189 *ch = debug_nibble_to_int(seq1) << 4; | |
190 *ch += debug_nibble_to_int(seq2); | |
191 | |
192 return res; | |
193 } | |
194 | |
195 bool DebugPacket::GetBlock(void *ptr, int len) { | |
196 uint8_t *p = (uint8_t *) ptr; | |
197 bool res; | |
198 | |
199 for (int offs = 0; offs < len; offs++) { | |
200 res = GetByte(&p[offs]); | |
201 if (false == res) | |
202 break; | |
203 } | |
204 | |
205 return res; | |
206 } | |
207 | |
208 bool DebugPacket::GetWord16(uint16_t *ptr) { | |
209 return GetBlock(ptr, sizeof(*ptr)); | |
210 } | |
211 | |
212 bool DebugPacket::GetWord32(uint32_t *ptr) { | |
213 return GetBlock(ptr, sizeof(*ptr)); | |
214 } | |
215 | |
216 bool DebugPacket::GetWord64(uint64_t *ptr) { | |
217 return GetBlock(ptr, sizeof(*ptr)); | |
218 } | |
219 | |
220 bool DebugPacket::GetPointer(void **ptr) { | |
221 return GetBlock(ptr, sizeof(*ptr)); | |
222 } | |
223 | |
224 bool DebugPacket::PeekString(const char **ppstr) { | |
225 string str = ""; | |
226 if (data.eof()) | |
227 return DS_NONE; | |
228 str = data.str(); | |
229 *ppstr = strdup(str.data()); | |
230 return true; | |
231 } | |
232 | |
233 bool DebugPacket::PeekChar(char *ch) { | |
234 string str = ""; | |
235 if (data.eof()) | |
236 return false; | |
237 str = data.str(); | |
238 *ch = str[0]; | |
239 return true; | |
240 } | |
241 | |
242 bool DebugPacket::GetString(const char **ppstr) { | |
243 string str = ""; | |
244 if (data.eof()) | |
245 return DS_NONE; | |
246 | |
247 const int bufsz = 127; | |
248 char buf[bufsz + 1]; | |
249 while (!data.eof()) { | |
250 data.getline(buf, bufsz); | |
251 str += buf; | |
252 } | |
253 *ppstr = strdup(str.data()); | |
254 return true; | |
255 } | |
256 | |
257 const char *DebugPacket::GetPayload() const { | |
258 string str = data.str(); | |
259 const char *out = str.data(); | |
260 return strdup(out); | |
261 } | |
262 | |
263 bool DebugPacket::GetSequence(int32_t *ch) const { | |
264 // If we don't have one, try and read it from the stream | |
265 if (seq == -1) { | |
266 | |
267 } | |
268 | |
269 if (seq != -1) { | |
270 *ch = seq; | |
271 return true; | |
272 } | |
273 | |
274 return false; | |
275 } | |
276 | |
277 void DebugPacket::SetSequence(int32_t val) { | |
278 seq = val; | |
279 } | |
280 | |
281 | |
282 int nacl_debug_conn::DebugPacket::Read( void *ptr, int len ) { | |
283 uint8_t *p = (uint8_t *) ptr; | |
284 int offs = 0; | |
285 | |
286 for (offs = 0; offs < len; offs++) { | |
287 bool res = GetByte(&p[offs]); | |
288 if (false == res) | |
289 break; | |
290 } | |
291 | |
292 return offs; | |
293 } | |
OLD | NEW |