blob: 9a431a9077f389c43c0930d3e5bba430e496ee1d [file] [log] [blame]
Greg Claytone51dc6f2011-05-20 02:00:47 +00001#!/usr/bin/perl
2
3use strict;
4
5#----------------------------------------------------------------------
6# Globals
7#----------------------------------------------------------------------
Greg Clayton86729962011-06-02 22:21:38 +00008our $unimplemented_str = "UNIMPLEMENTED";
Greg Claytone51dc6f2011-05-20 02:00:47 +00009our $success_str = "OK";
10our $swap = 1;
11our $addr_size = 4;
12our $thread_suffix_supported = 0;
13our $max_bytes_per_line = 32;
14our $addr_format = sprintf("0x%%%u.%ux", $addr_size*2, $addr_size*2);
15our $pid_format = "%04.4x";
16our $tid_format = "%04.4x";
17our $reg8_href = { extract => \&get8, format => "0x%2.2x" };
18our $reg16_href = { extract => \&get16, format => "0x%4.4x" };
19our $reg32_href = { extract => \&get32, format => "0x%8.8x" };
20our $reg64_href = { extract => \&get64, format => "0x%s" };
21our $reg80_href = { extract => \&get80, format => "0x%s" };
22our $reg128_href = { extract => \&get128, format => "0x%s" };
Greg Clayton9163c392011-09-17 05:45:35 +000023our $reg256_href = { extract => \&get256, format => "0x%s" };
Greg Claytone51dc6f2011-05-20 02:00:47 +000024our $float32_href = { extract => \&get32, format => "0x%8.8x" };
25our $float64_href = { extract => \&get64, format => "0x%s" };
26our $float96_href = { extract => \&get96, format => "0x%s" };
27our $curr_cmd = undef;
28our $reg_cmd_reg;
29our %reg_map = (
30 'i386-gdb' => [
31 { name => 'eax', info => $reg32_href },
32 { name => 'ecx', info => $reg32_href },
33 { name => 'edx', info => $reg32_href },
34 { name => 'ebx', info => $reg32_href },
35 { name => 'esp', info => $reg32_href },
36 { name => 'ebp', info => $reg32_href },
37 { name => 'esi', info => $reg32_href },
38 { name => 'edi', info => $reg32_href },
39 { name => 'eip', info => $reg32_href },
40 { name => 'eflags', info => $reg32_href },
41 { name => 'cs', info => $reg32_href },
42 { name => 'ss', info => $reg32_href },
43 { name => 'ds', info => $reg32_href },
44 { name => 'es', info => $reg32_href },
45 { name => 'fs', info => $reg32_href },
46 { name => 'gs', info => $reg32_href },
47 { name => 'st0', info => $reg80_href },
48 { name => 'st1', info => $reg80_href },
49 { name => 'st2', info => $reg80_href },
50 { name => 'st3', info => $reg80_href },
51 { name => 'st4', info => $reg80_href },
52 { name => 'st5', info => $reg80_href },
53 { name => 'st6', info => $reg80_href },
54 { name => 'st7', info => $reg80_href },
55 { name => 'fctrl', info => $reg32_href },
56 { name => 'fstat', info => $reg32_href },
57 { name => 'ftag', info => $reg32_href },
58 { name => 'fiseg', info => $reg32_href },
59 { name => 'fioff', info => $reg32_href },
60 { name => 'foseg', info => $reg32_href },
61 { name => 'fooff', info => $reg32_href },
62 { name => 'fop', info => $reg32_href },
63 { name => 'xmm0', info => $reg128_href },
64 { name => 'xmm1', info => $reg128_href },
65 { name => 'xmm2', info => $reg128_href },
66 { name => 'xmm3', info => $reg128_href },
67 { name => 'xmm4', info => $reg128_href },
68 { name => 'xmm5', info => $reg128_href },
69 { name => 'xmm6', info => $reg128_href },
70 { name => 'xmm7', info => $reg128_href },
71 { name => 'mxcsr', info => $reg32_href },
72 { name => 'mm0', info => $reg64_href },
73 { name => 'mm1', info => $reg64_href },
74 { name => 'mm2', info => $reg64_href },
75 { name => 'mm3', info => $reg64_href },
76 { name => 'mm4', info => $reg64_href },
77 { name => 'mm5', info => $reg64_href },
78 { name => 'mm6', info => $reg64_href },
79 { name => 'mm7', info => $reg64_href },
80 ],
81
82 'i386-lldb' => [
83 { name => 'eax', info => $reg32_href },
84 { name => 'ebx', info => $reg32_href },
85 { name => 'ecx', info => $reg32_href },
86 { name => 'edx', info => $reg32_href },
87 { name => 'edi', info => $reg32_href },
88 { name => 'esi', info => $reg32_href },
89 { name => 'ebp', info => $reg32_href },
90 { name => 'esp', info => $reg32_href },
91 { name => 'ss', info => $reg32_href },
92 { name => 'eflags', info => $reg32_href },
93 { name => 'eip', info => $reg32_href },
94 { name => 'cs', info => $reg32_href },
95 { name => 'ds', info => $reg32_href },
96 { name => 'es', info => $reg32_href },
97 { name => 'fs', info => $reg32_href },
98 { name => 'gs', info => $reg32_href },
99 { name => 'fctrl', info => $reg16_href },
100 { name => 'fstat', info => $reg16_href },
101 { name => 'ftag', info => $reg8_href },
102 { name => 'fop', info => $reg16_href },
103 { name => 'fioff', info => $reg32_href },
104 { name => 'fiseg', info => $reg16_href },
105 { name => 'fooff', info => $reg32_href },
106 { name => 'foseg', info => $reg16_href },
107 { name => 'mxcsr', info => $reg32_href },
108 { name => 'mxcsrmask', info => $reg32_href },
109 { name => 'stmm0', info => $reg80_href },
110 { name => 'stmm1', info => $reg80_href },
111 { name => 'stmm2', info => $reg80_href },
112 { name => 'stmm3', info => $reg80_href },
113 { name => 'stmm4', info => $reg80_href },
114 { name => 'stmm5', info => $reg80_href },
115 { name => 'stmm6', info => $reg80_href },
116 { name => 'stmm7', info => $reg80_href },
117 { name => 'xmm0', info => $reg128_href },
118 { name => 'xmm1', info => $reg128_href },
119 { name => 'xmm2', info => $reg128_href },
120 { name => 'xmm3', info => $reg128_href },
121 { name => 'xmm4', info => $reg128_href },
122 { name => 'xmm5', info => $reg128_href },
123 { name => 'xmm6', info => $reg128_href },
124 { name => 'xmm7', info => $reg128_href },
125 { name => 'trapno', info => $reg32_href },
126 { name => 'err', info => $reg32_href },
127 { name => 'faultvaddr', info => $reg32_href },
128 ],
129
130 'arm-gdb' => [
131 { name => 'r0' , info => $reg32_href },
132 { name => 'r1' , info => $reg32_href },
133 { name => 'r2' , info => $reg32_href },
134 { name => 'r3' , info => $reg32_href },
135 { name => 'r4' , info => $reg32_href },
136 { name => 'r5' , info => $reg32_href },
137 { name => 'r6' , info => $reg32_href },
138 { name => 'r7' , info => $reg32_href },
139 { name => 'r8' , info => $reg32_href },
140 { name => 'r9' , info => $reg32_href },
141 { name => 'r10' , info => $reg32_href },
142 { name => 'r11' , info => $reg32_href },
143 { name => 'r12' , info => $reg32_href },
144 { name => 'sp' , info => $reg32_href },
145 { name => 'lr' , info => $reg32_href },
146 { name => 'pc' , info => $reg32_href },
147 { name => 'f0' , info => $float96_href },
148 { name => 'f1' , info => $float96_href },
149 { name => 'f2' , info => $float96_href },
150 { name => 'f3' , info => $float96_href },
151 { name => 'f4' , info => $float96_href },
152 { name => 'f5' , info => $float96_href },
153 { name => 'f6' , info => $float96_href },
154 { name => 'f7' , info => $float96_href },
155 { name => 'fps' , info => $reg32_href },
156 { name => 'cpsr' , info => $reg32_href },
157 { name => 's0' , info => $float32_href },
158 { name => 's1' , info => $float32_href },
159 { name => 's2' , info => $float32_href },
160 { name => 's3' , info => $float32_href },
161 { name => 's4' , info => $float32_href },
162 { name => 's5' , info => $float32_href },
163 { name => 's6' , info => $float32_href },
164 { name => 's7' , info => $float32_href },
165 { name => 's8' , info => $float32_href },
166 { name => 's9' , info => $float32_href },
167 { name => 's10' , info => $float32_href },
168 { name => 's11' , info => $float32_href },
169 { name => 's12' , info => $float32_href },
170 { name => 's13' , info => $float32_href },
171 { name => 's14' , info => $float32_href },
172 { name => 's15' , info => $float32_href },
173 { name => 's16' , info => $float32_href },
174 { name => 's17' , info => $float32_href },
175 { name => 's18' , info => $float32_href },
176 { name => 's19' , info => $float32_href },
177 { name => 's20' , info => $float32_href },
178 { name => 's21' , info => $float32_href },
179 { name => 's22' , info => $float32_href },
180 { name => 's23' , info => $float32_href },
181 { name => 's24' , info => $float32_href },
182 { name => 's25' , info => $float32_href },
183 { name => 's26' , info => $float32_href },
184 { name => 's27' , info => $float32_href },
185 { name => 's28' , info => $float32_href },
186 { name => 's29' , info => $float32_href },
187 { name => 's30' , info => $float32_href },
188 { name => 's31' , info => $float32_href },
189 { name => 'fpscr' , info => $reg32_href },
190 { name => 'd16' , info => $float64_href },
191 { name => 'd17' , info => $float64_href },
192 { name => 'd18' , info => $float64_href },
193 { name => 'd19' , info => $float64_href },
194 { name => 'd20' , info => $float64_href },
195 { name => 'd21' , info => $float64_href },
196 { name => 'd22' , info => $float64_href },
197 { name => 'd23' , info => $float64_href },
198 { name => 'd24' , info => $float64_href },
199 { name => 'd25' , info => $float64_href },
200 { name => 'd26' , info => $float64_href },
201 { name => 'd27' , info => $float64_href },
202 { name => 'd28' , info => $float64_href },
203 { name => 'd29' , info => $float64_href },
204 { name => 'd30' , info => $float64_href },
205 { name => 'd31' , info => $float64_href },
206 ],
207
Greg Clayton5fe15d22011-05-20 03:15:54 +0000208
209 'arm-lldb' => [
210 { name => 'r0' , info => $reg32_href },
211 { name => 'r1' , info => $reg32_href },
212 { name => 'r2' , info => $reg32_href },
213 { name => 'r3' , info => $reg32_href },
214 { name => 'r4' , info => $reg32_href },
215 { name => 'r5' , info => $reg32_href },
216 { name => 'r6' , info => $reg32_href },
217 { name => 'r7' , info => $reg32_href },
218 { name => 'r8' , info => $reg32_href },
219 { name => 'r9' , info => $reg32_href },
220 { name => 'r10' , info => $reg32_href },
221 { name => 'r11' , info => $reg32_href },
222 { name => 'r12' , info => $reg32_href },
223 { name => 'sp' , info => $reg32_href },
224 { name => 'lr' , info => $reg32_href },
225 { name => 'pc' , info => $reg32_href },
226 { name => 'cpsr' , info => $reg32_href },
227 { name => 's0' , info => $float32_href },
228 { name => 's1' , info => $float32_href },
229 { name => 's2' , info => $float32_href },
230 { name => 's3' , info => $float32_href },
231 { name => 's4' , info => $float32_href },
232 { name => 's5' , info => $float32_href },
233 { name => 's6' , info => $float32_href },
234 { name => 's7' , info => $float32_href },
235 { name => 's8' , info => $float32_href },
236 { name => 's9' , info => $float32_href },
237 { name => 's10' , info => $float32_href },
238 { name => 's11' , info => $float32_href },
239 { name => 's12' , info => $float32_href },
240 { name => 's13' , info => $float32_href },
241 { name => 's14' , info => $float32_href },
242 { name => 's15' , info => $float32_href },
243 { name => 's16' , info => $float32_href },
244 { name => 's17' , info => $float32_href },
245 { name => 's18' , info => $float32_href },
246 { name => 's19' , info => $float32_href },
247 { name => 's20' , info => $float32_href },
248 { name => 's21' , info => $float32_href },
249 { name => 's22' , info => $float32_href },
250 { name => 's23' , info => $float32_href },
251 { name => 's24' , info => $float32_href },
252 { name => 's25' , info => $float32_href },
253 { name => 's26' , info => $float32_href },
254 { name => 's27' , info => $float32_href },
255 { name => 's28' , info => $float32_href },
256 { name => 's29' , info => $float32_href },
257 { name => 's30' , info => $float32_href },
258 { name => 's31' , info => $float32_href },
259 { name => 'd0' , info => $float64_href },
260 { name => 'd1' , info => $float64_href },
261 { name => 'd2' , info => $float64_href },
262 { name => 'd3' , info => $float64_href },
263 { name => 'd4' , info => $float64_href },
264 { name => 'd5' , info => $float64_href },
265 { name => 'd6' , info => $float64_href },
266 { name => 'd7' , info => $float64_href },
267 { name => 'd8' , info => $float64_href },
268 { name => 'd9' , info => $float64_href },
269 { name => 'd10' , info => $float64_href },
270 { name => 'd11' , info => $float64_href },
271 { name => 'd12' , info => $float64_href },
272 { name => 'd13' , info => $float64_href },
273 { name => 'd14' , info => $float64_href },
274 { name => 'd15' , info => $float64_href },
275 { name => 'd16' , info => $float64_href },
276 { name => 'd17' , info => $float64_href },
277 { name => 'd18' , info => $float64_href },
278 { name => 'd19' , info => $float64_href },
279 { name => 'd20' , info => $float64_href },
280 { name => 'd21' , info => $float64_href },
281 { name => 'd22' , info => $float64_href },
282 { name => 'd23' , info => $float64_href },
283 { name => 'd24' , info => $float64_href },
284 { name => 'd25' , info => $float64_href },
285 { name => 'd26' , info => $float64_href },
286 { name => 'd27' , info => $float64_href },
287 { name => 'd28' , info => $float64_href },
288 { name => 'd29' , info => $float64_href },
289 { name => 'd30' , info => $float64_href },
290 { name => 'd31' , info => $float64_href },
291 { name => 'fpscr' , info => $reg32_href },
292 { name => 'exc' , info => $reg32_href },
293 { name => 'fsr' , info => $reg32_href },
294 { name => 'far' , info => $reg32_href },
295 ],
296
Greg Claytone51dc6f2011-05-20 02:00:47 +0000297 'x86_64-gdb' => [
298 { name => 'rax' , info => $reg64_href },
299 { name => 'rbx' , info => $reg64_href },
300 { name => 'rcx' , info => $reg64_href },
301 { name => 'rdx' , info => $reg64_href },
302 { name => 'rsi' , info => $reg64_href },
303 { name => 'rdi' , info => $reg64_href },
304 { name => 'rbp' , info => $reg64_href },
305 { name => 'rsp' , info => $reg64_href },
306 { name => 'r8' , info => $reg64_href },
307 { name => 'r9' , info => $reg64_href },
308 { name => 'r10' , info => $reg64_href },
309 { name => 'r11' , info => $reg64_href },
310 { name => 'r12' , info => $reg64_href },
311 { name => 'r13' , info => $reg64_href },
312 { name => 'r14' , info => $reg64_href },
313 { name => 'r15' , info => $reg64_href },
314 { name => 'rip' , info => $reg64_href },
315 { name => 'eflags' , info => $reg32_href },
316 { name => 'cs' , info => $reg32_href },
317 { name => 'ss' , info => $reg32_href },
318 { name => 'ds' , info => $reg32_href },
319 { name => 'es' , info => $reg32_href },
320 { name => 'fs' , info => $reg32_href },
321 { name => 'gs' , info => $reg32_href },
322 { name => 'stmm0' , info => $reg80_href },
323 { name => 'stmm1' , info => $reg80_href },
324 { name => 'stmm2' , info => $reg80_href },
325 { name => 'stmm3' , info => $reg80_href },
326 { name => 'stmm4' , info => $reg80_href },
327 { name => 'stmm5' , info => $reg80_href },
328 { name => 'stmm6' , info => $reg80_href },
329 { name => 'stmm7' , info => $reg80_href },
330 { name => 'fctrl' , info => $reg32_href },
331 { name => 'fstat' , info => $reg32_href },
332 { name => 'ftag' , info => $reg32_href },
333 { name => 'fiseg' , info => $reg32_href },
334 { name => 'fioff' , info => $reg32_href },
335 { name => 'foseg' , info => $reg32_href },
336 { name => 'fooff' , info => $reg32_href },
337 { name => 'fop' , info => $reg32_href },
338 { name => 'xmm0' , info => $reg128_href },
339 { name => 'xmm1' , info => $reg128_href },
340 { name => 'xmm2' , info => $reg128_href },
341 { name => 'xmm3' , info => $reg128_href },
342 { name => 'xmm4' , info => $reg128_href },
343 { name => 'xmm5' , info => $reg128_href },
344 { name => 'xmm6' , info => $reg128_href },
345 { name => 'xmm7' , info => $reg128_href },
346 { name => 'xmm8' , info => $reg128_href },
347 { name => 'xmm9' , info => $reg128_href },
348 { name => 'xmm10' , info => $reg128_href },
349 { name => 'xmm11' , info => $reg128_href },
350 { name => 'xmm12' , info => $reg128_href },
351 { name => 'xmm13' , info => $reg128_href },
352 { name => 'xmm14' , info => $reg128_href },
353 { name => 'xmm15' , info => $reg128_href },
354 { name => 'mxcsr' , info => $reg32_href },
355 ],
356
357 'x86_64-lldb' => [
358 { name => 'rax' , info => $reg64_href },
359 { name => 'rbx' , info => $reg64_href },
360 { name => 'rcx' , info => $reg64_href },
361 { name => 'rdx' , info => $reg64_href },
362 { name => 'rdi' , info => $reg64_href },
363 { name => 'rsi' , info => $reg64_href },
364 { name => 'rbp' , info => $reg64_href },
365 { name => 'rsp' , info => $reg64_href },
366 { name => 'r8 ' , info => $reg64_href },
367 { name => 'r9 ' , info => $reg64_href },
368 { name => 'r10' , info => $reg64_href },
369 { name => 'r11' , info => $reg64_href },
370 { name => 'r12' , info => $reg64_href },
371 { name => 'r13' , info => $reg64_href },
372 { name => 'r14' , info => $reg64_href },
373 { name => 'r15' , info => $reg64_href },
374 { name => 'rip' , info => $reg64_href },
375 { name => 'rflags' , info => $reg64_href },
376 { name => 'cs' , info => $reg64_href },
377 { name => 'fs' , info => $reg64_href },
378 { name => 'gs' , info => $reg64_href },
379 { name => 'fctrl' , info => $reg16_href },
380 { name => 'fstat' , info => $reg16_href },
381 { name => 'ftag' , info => $reg8_href },
382 { name => 'fop' , info => $reg16_href },
383 { name => 'fioff' , info => $reg32_href },
384 { name => 'fiseg' , info => $reg16_href },
385 { name => 'fooff' , info => $reg32_href },
386 { name => 'foseg' , info => $reg16_href },
387 { name => 'mxcsr' , info => $reg32_href },
388 { name => 'mxcsrmask' , info => $reg32_href },
389 { name => 'stmm0' , info => $reg80_href },
390 { name => 'stmm1' , info => $reg80_href },
391 { name => 'stmm2' , info => $reg80_href },
392 { name => 'stmm3' , info => $reg80_href },
393 { name => 'stmm4' , info => $reg80_href },
394 { name => 'stmm5' , info => $reg80_href },
395 { name => 'stmm6' , info => $reg80_href },
396 { name => 'stmm7' , info => $reg80_href },
397 { name => 'xmm0' , info => $reg128_href },
398 { name => 'xmm1' , info => $reg128_href },
399 { name => 'xmm2' , info => $reg128_href },
400 { name => 'xmm3' , info => $reg128_href },
401 { name => 'xmm4' , info => $reg128_href },
402 { name => 'xmm5' , info => $reg128_href },
403 { name => 'xmm6' , info => $reg128_href },
404 { name => 'xmm7' , info => $reg128_href },
405 { name => 'xmm8' , info => $reg128_href },
406 { name => 'xmm9' , info => $reg128_href },
407 { name => 'xmm10' , info => $reg128_href },
408 { name => 'xmm11' , info => $reg128_href },
409 { name => 'xmm12' , info => $reg128_href },
410 { name => 'xmm13' , info => $reg128_href },
411 { name => 'xmm14' , info => $reg128_href },
412 { name => 'xmm15' , info => $reg128_href },
413 { name => 'trapno' , info => $reg32_href },
414 { name => 'err' , info => $reg32_href },
415 { name => 'faultvaddr' , info => $reg64_href },
416 ]
417);
418
419our $max_register_name_len = 0;
420calculate_max_register_name_length();
421our @point_types = ( "software_bp", "hardware_bp", "write_wp", "read_wp", "access_wp" );
422our $opt_v = 0; # verbose
423our $opt_g = 0; # debug
424our $opt_q = 0; # quiet
425our $opt_r = undef;
426use Getopt::Std;
427getopts('gvqr:');
428
429our $registers_aref = undef;
430
431if (length($opt_r))
432{
Greg Clayton86729962011-06-02 22:21:38 +0000433 if (exists $reg_map{$opt_r})
434 {
435 $registers_aref = $reg_map{$opt_r};
436 }
437 else
438 {
439 die "Can't get registers group for '$opt_r'\n";
440 }
Greg Claytone51dc6f2011-05-20 02:00:47 +0000441}
442
443sub extract_key_value_pairs
444{
445 my $kv_href = {};
446 my $arrayref = shift;
447 my $str = join('',@$arrayref);
448 my @kv_strs = split(/;/, $str);
449 foreach my $kv_str (@kv_strs)
450 {
451 my ($key, $value) = split(/:/, $kv_str);
452 $kv_href->{$key} = $value;
453 }
454 return $kv_href;
455}
456
457sub get_thread_from_thread_suffix
458{
459 if ($thread_suffix_supported)
460 {
461 my $arrayref = shift;
462 # Skip leading semi-colon if needed
463 $$arrayref[0] == ';' and shift @$arrayref;
464 my $thread_href = extract_key_value_pairs ($arrayref);
465 if (exists $thread_href->{thread})
466 {
467 return $thread_href->{thread};
468 }
469 }
470 return undef;
471}
472
473sub calculate_max_register_name_length
474{
475 $max_register_name_len = 7;
476 foreach my $reg_href (@$registers_aref)
477 {
478 my $name_len = length($reg_href->{name});
479 if ($max_register_name_len < $name_len)
480 {
481 $max_register_name_len = $name_len;
482 }
483 }
484}
485#----------------------------------------------------------------------
486# Hash that maps command characters to the appropriate functions using
487# the command character as the key and the value being a reference to
488# the dump function for dumping the command itself.
489#----------------------------------------------------------------------
490our %cmd_callbacks =
491(
492 '?' => \&dump_last_signal_cmd,
493 'H' => \&dump_set_thread_cmd,
494 'T' => \&dump_thread_is_alive_cmd,
495 'q' => \&dump_general_query_cmd,
496 'Q' => \&dump_general_set_cmd,
497 'g' => \&dump_read_regs_cmd,
498 'G' => \&dump_write_regs_cmd,
499 'p' => \&dump_read_single_register_cmd,
500 'P' => \&dump_write_single_register_cmd,
501 'm' => \&dump_read_mem_cmd,
502 'M' => \&dump_write_mem_cmd,
503 'X' => \&dump_write_mem_binary_cmd,
504 'Z' => \&dump_bp_wp_command,
505 'z' => \&dump_bp_wp_command,
506 'k' => \&dump_kill_cmd,
507 'A' => \&dump_A_command,
508 'c' => \&dump_continue_cmd,
509 'C' => \&dump_continue_with_signal_cmd,
510 '_M' => \&dump_allocate_memory_cmd,
511 '_m' => \&dump_deallocate_memory_cmd,
512 # extended commands
513 'v' => \&dump_extended_cmd
514);
515
516#----------------------------------------------------------------------
517# Hash that maps command characters to the appropriate functions using
518# the command character as the key and the value being a reference to
519# the dump function for the response to the command.
520#----------------------------------------------------------------------
521our %rsp_callbacks =
522(
523 'c' => \&dump_stop_reply_packet,
524 'C' => \&dump_stop_reply_packet,
525 '?' => \&dump_stop_reply_packet,
526 'T' => \&dump_thread_is_alive_rsp,
527 'H' => \&dump_set_thread_rsp,
528 'q' => \&dump_general_query_rsp,
529 'g' => \&dump_read_regs_rsp,
530 'p' => \&dump_read_single_register_rsp,
531 'm' => \&dump_read_mem_rsp,
532 '_M' => \&dump_allocate_memory_rsp,
533
534 # extended commands
535 'v' => \&dump_extended_rsp,
536);
537
538
539sub dump_register_value
540{
541 my $indent = shift;
542 my $arrayref = shift;
543 my $reg_num = shift;
544
545 if ($reg_num >= @$registers_aref)
546 {
547 printf("\tinvalid register index %d\n", $reg_num);
548 }
549
550 my $reg_href = $$registers_aref[$reg_num];
551 my $reg_name = $reg_href->{name};
552 if ($$arrayref[0] eq '#')
553 {
554 printf("\t%*s: error: EOS reached when trying to read register %d\n", $max_register_name_len, $reg_name, $reg_num);
555 }
556
557 my $reg_info = $reg_href->{info};
558 my $reg_extract = $reg_info->{extract};
559 my $reg_format = $reg_info->{format};
560 my $reg_val = &$reg_extract($arrayref);
561 if ($indent) {
562 printf("\t%*s = $reg_format", $max_register_name_len, $reg_name, $reg_val);
563 } else {
564 printf("%s = $reg_format", $reg_name, $reg_val);
565 }
566}
567
568#----------------------------------------------------------------------
569# Extract the command into an array of ASCII char strings for easy
570# processing
571#----------------------------------------------------------------------
572sub extract_command
573{
574 my $cmd_str = shift;
575 my @cmd_chars = split(/ */, $cmd_str);
576 if ($cmd_chars[0] ne '$')
577 {
578 # only set the current command if it isn't a reply
579 $curr_cmd = $cmd_chars[0];
580 }
581 return @cmd_chars;
582}
583
584#----------------------------------------------------------------------
585# Strip the 3 checksum array entries after we don't need them anymore
586#----------------------------------------------------------------------
587sub strip_checksum
588{
589 my $arrayref = shift;
590 splice(@$arrayref, -3);
591}
592
593#----------------------------------------------------------------------
594# Dump all strings in array by joining them together with no space
595# between them
596#----------------------------------------------------------------------
597sub dump_chars
598{
599 print join('',@_);
600}
601
602#----------------------------------------------------------------------
603# Check if the response is an error 'EXX'
604#----------------------------------------------------------------------
605sub is_error_response
606{
607 if ($_[0] eq 'E')
608 {
609 shift;
610 print "ERROR = " . join('',@_) . "\n";
611 return 1;
612 }
613 return 0;
614}
615
616#----------------------------------------------------------------------
617# 'H' command
618#----------------------------------------------------------------------
619sub dump_set_thread_cmd
620{
621 my $cmd = shift;
622 my $mod = shift;
623 print "set_thread ( $mod, " . join('',@_) . " )\n";
624}
625
626#----------------------------------------------------------------------
627# 'T' command
628#----------------------------------------------------------------------
629our $T_cmd_tid = -1;
630sub dump_thread_is_alive_cmd
631{
632 my $cmd = shift;
633 $T_cmd_tid = get_hex(\@_);
634 printf("thread_is_alive ( $tid_format )\n", $T_cmd_tid);
635}
636
637sub dump_thread_is_alive_rsp
638{
639 my $rsp = join('',@_);
640
641 printf("thread_is_alive ( $tid_format ) =>", $T_cmd_tid);
642 if ($rsp eq 'OK')
643 {
644 print " alive.\n";
645 }
646 else
647 {
648 print " dead.\n";
649 }
650}
651
652#----------------------------------------------------------------------
653# 'H' response
654#----------------------------------------------------------------------
655sub dump_set_thread_rsp
656{
657 if (!is_error_response(@_))
658 {
659 print join('',@_) . "\n";
660 }
661}
662
663#----------------------------------------------------------------------
664# 'q' command
665#----------------------------------------------------------------------
666our $gen_query_cmd;
Greg Clayton86729962011-06-02 22:21:38 +0000667our $qRegisterInfo_reg_num = -1;
Greg Claytone51dc6f2011-05-20 02:00:47 +0000668sub dump_general_query_cmd
669{
670 $gen_query_cmd = join('',@_);
671 if ($gen_query_cmd eq 'qC')
672 {
673 print 'get_current_pid ()';
674 }
675 elsif ($gen_query_cmd eq 'qfThreadInfo')
676 {
677 print 'get_first_active_threads ()';
678 }
679 elsif ($gen_query_cmd eq 'qsThreadInfo')
680 {
681 print 'get_subsequent_active_threads ()';
682 }
683 elsif (index($gen_query_cmd, 'qThreadExtraInfo') == 0)
684 {
685 # qThreadExtraInfo,id
686 print 'get_thread_extra_info ()';
687 }
688 elsif (index($gen_query_cmd, 'qThreadStopInfo') == 0)
689 {
690 # qThreadStopInfoXXXX
691 @_ = splice(@_, length('qThreadStopInfo'));
692 my $tid = get_addr(\@_);
693 printf('get_thread_stop_info ( thread = 0x%4.4x )', $tid);
694 }
695 elsif (index($gen_query_cmd, 'qSymbol:') == 0)
696 {
697 # qCRC:addr,length
698 print 'gdb_ready_to_serve_symbol_lookups ()';
699 }
700 elsif (index($gen_query_cmd, 'qCRC:') == 0)
701 {
702 # qCRC:addr,length
703 @_ = splice(@_, length('qCRC:'));
704 my $address = get_addr(\@_);
705 shift @_;
706 my $length = join('', @_);
707 printf("compute_crc (addr = $addr_format, length = $length)", $address);
708 }
709 elsif (index($gen_query_cmd, 'qGetTLSAddr:') == 0)
710 {
711 # qGetTLSAddr:thread-id,offset,lm
712 @_ = splice(@_, length('qGetTLSAddr:'));
713 my ($tid, $offset, $lm) = split (/,/, join('', @_));
714 print "get_thread_local_storage_addr (thread-id = $tid, offset = $offset, lm = $lm)";
715 }
716 elsif ($gen_query_cmd eq 'qOffsets')
717 {
718 print 'get_section_offsets ()';
719 }
720 elsif (index($gen_query_cmd, 'qRegisterInfo') == 0)
721 {
722 @_ = splice(@_, length('qRegisterInfo'));
Greg Clayton86729962011-06-02 22:21:38 +0000723 $qRegisterInfo_reg_num = get_hex(\@_);
724
725 printf "get_dynamic_register_info ($qRegisterInfo_reg_num)";
Greg Claytone51dc6f2011-05-20 02:00:47 +0000726 }
727 else
728 {
729 print $gen_query_cmd;
730 }
731 print "\n";
732}
733
734#----------------------------------------------------------------------
735# 'q' response
736#----------------------------------------------------------------------
737sub dump_general_query_rsp
738{
739 my $gen_query_rsp = join('',@_);
Greg Clayton86729962011-06-02 22:21:38 +0000740 my $gen_query_rsp_len = length ($gen_query_rsp);
Greg Claytone51dc6f2011-05-20 02:00:47 +0000741 if ($gen_query_cmd eq 'qC' and index($gen_query_rsp, 'QC') == 0)
742 {
743 shift @_; shift @_;
744 my $pid = get_hex(\@_);
Greg Clayton86729962011-06-02 22:21:38 +0000745 printf("pid = $pid_format\n", $pid);
Greg Claytone51dc6f2011-05-20 02:00:47 +0000746 return;
747 }
748 elsif (index($gen_query_cmd, 'qRegisterInfo') == 0)
749 {
Greg Clayton86729962011-06-02 22:21:38 +0000750 if ($gen_query_rsp_len == 0)
Greg Claytone51dc6f2011-05-20 02:00:47 +0000751 {
Greg Clayton86729962011-06-02 22:21:38 +0000752 print "$unimplemented_str\n";
Greg Claytone51dc6f2011-05-20 02:00:47 +0000753 }
754 else
755 {
Greg Clayton86729962011-06-02 22:21:38 +0000756 if (index($gen_query_rsp, 'name') == 0)
757 {
758 $qRegisterInfo_reg_num == 0 and $registers_aref = [];
759
760 my @name_and_values = split (/;/, $gen_query_rsp);
761
762 my $reg_name = undef;
763 my $byte_size = 0;
764 foreach (@name_and_values)
765 {
766 my ($name, $value) = split /:/;
767 if ($name eq "name") { $reg_name = $value; }
768 elsif ($name eq "bitsize") { $byte_size = $value / 8; last; }
769 }
770 if (defined $reg_name and $byte_size > 0)
771 {
772 if ($byte_size == 4) {push @$registers_aref, { name => $reg_name, info => $reg32_href };}
773 elsif ($byte_size == 8) {push @$registers_aref, { name => $reg_name, info => $reg64_href };}
Greg Clayton9163c392011-09-17 05:45:35 +0000774 elsif ($byte_size == 1) {push @$registers_aref, { name => $reg_name, info => $reg8_href };}
775 elsif ($byte_size == 2) {push @$registers_aref, { name => $reg_name, info => $reg16_href };}
Greg Clayton86729962011-06-02 22:21:38 +0000776 elsif ($byte_size == 10) {push @$registers_aref, { name => $reg_name, info => $reg80_href };}
777 elsif ($byte_size == 12) {push @$registers_aref, { name => $reg_name, info => $float96_href };}
778 elsif ($byte_size == 16) {push @$registers_aref, { name => $reg_name, info => $reg128_href };}
Greg Clayton9163c392011-09-17 05:45:35 +0000779 elsif ($byte_size == 32) {push @$registers_aref, { name => $reg_name, info => $reg256_href };}
Greg Clayton86729962011-06-02 22:21:38 +0000780 }
781 }
782 elsif ($gen_query_rsp_len == 3 and index($gen_query_rsp, 'E') == 0)
783 {
784 calculate_max_register_name_length();
785 }
Greg Claytone51dc6f2011-05-20 02:00:47 +0000786 }
787 }
788 elsif ($gen_query_cmd =~ 'qThreadStopInfo')
789 {
790 dump_stop_reply_packet (@_);
791 }
792 if (dump_standard_response(\@_))
793 {
794 # Do nothing...
795 }
796 else
797 {
798 print join('',@_) . "\n";
799 }
800}
801
802#----------------------------------------------------------------------
803# 'Q' command
804#----------------------------------------------------------------------
805our $gen_set_cmd;
806sub dump_general_set_cmd
807{
808 $gen_query_cmd = join('',@_);
809 if ($gen_query_cmd eq 'QStartNoAckMode')
810 {
811 print "StartNoAckMode ()"
812 }
813 elsif ($gen_query_cmd eq 'QThreadSuffixSupported')
814 {
815 $thread_suffix_supported = 1;
816 print "ThreadSuffixSupported ()"
817 }
818 elsif (index($gen_query_cmd, 'QSetMaxPayloadSize:') == 0)
819 {
820 @_ = splice(@_, length('QSetMaxPayloadSize:'));
821 my $max_payload_size = get_hex(\@_);
822 # QSetMaxPayloadSize:XXXX where XXXX is a hex length of the max
823 # packet payload size supported by gdb
824 printf("SetMaxPayloadSize ( 0x%x (%u))", $max_payload_size, $max_payload_size);
825 }
Greg Clayton86729962011-06-02 22:21:38 +0000826 elsif (index ($gen_query_cmd, 'QSetSTDIN:') == 0)
827 {
828 @_ = splice(@_, length('QSetSTDIN:'));
829 printf ("SetSTDIN (path ='%s')\n", get_hex_string (\@_));
830 }
831 elsif (index ($gen_query_cmd, 'QSetSTDOUT:') == 0)
832 {
833 @_ = splice(@_, length('QSetSTDOUT:'));
834 printf ("SetSTDOUT (path ='%s')\n", get_hex_string (\@_));
835 }
836 elsif (index ($gen_query_cmd, 'QSetSTDERR:') == 0)
837 {
838 @_ = splice(@_, length('QSetSTDERR:'));
839 printf ("SetSTDERR (path ='%s')\n", get_hex_string (\@_));
840 }
Greg Claytone51dc6f2011-05-20 02:00:47 +0000841 else
842 {
843 print $gen_query_cmd;
844 }
845 print "\n";
846}
847
848#----------------------------------------------------------------------
849# 'k' command
850#----------------------------------------------------------------------
851sub dump_kill_cmd
852{
853 my $cmd = shift;
854 print "kill (" . join('',@_) . ")\n";
855}
856
857#----------------------------------------------------------------------
858# 'g' command
859#----------------------------------------------------------------------
860sub dump_read_regs_cmd
861{
862 my $cmd = shift;
863 print "read_registers ()\n";
864}
865
866#----------------------------------------------------------------------
867# 'G' command
868#----------------------------------------------------------------------
869sub dump_write_regs_cmd
870{
871 print "write_registers:\n";
872 my $cmd = shift;
873 foreach my $reg_href (@$registers_aref)
874 {
875 last if ($_[0] eq '#');
876 my $reg_info_href = $reg_href->{info};
877 my $reg_name = $reg_href->{name};
878 my $reg_extract = $reg_info_href->{extract};
879 my $reg_format = $reg_info_href->{format};
880 my $reg_val = &$reg_extract(\@_);
881 printf("\t%*s = $reg_format\n", $max_register_name_len, $reg_name, $reg_val);
882 }
883}
884
885sub dump_read_regs_rsp
886{
887 print "read_registers () =>\n";
888 if (!is_error_response(@_))
889 {
890 # print join('',@_) . "\n";
891 foreach my $reg_href (@$registers_aref)
892 {
893 last if ($_[0] eq '#');
894 my $reg_info_href = $reg_href->{info};
895 my $reg_name = $reg_href->{name};
896 my $reg_extract = $reg_info_href->{extract};
897 my $reg_format = $reg_info_href->{format};
898 my $reg_val = &$reg_extract(\@_);
899 printf("\t%*s = $reg_format\n", $max_register_name_len, $reg_name, $reg_val);
900 }
901 }
902}
903
904sub dump_read_single_register_rsp
905{
906 dump_register_value(0, \@_, $reg_cmd_reg);
907 print "\n";
908}
909
910#----------------------------------------------------------------------
911# '_M' - allocate memory command (LLDB extension)
912#
913# Command: '_M'
914# Arg1: Hex byte size as big endian hex string
915# Separator: ','
916# Arg2: permissions as string that must be a string that contains any
917# combination of 'r' (readable) 'w' (writable) or 'x' (executable)
918#
919# Returns: The address that was allocated as a big endian hex string
920# on success, else an error "EXX" where XX are hex bytes
921# that indicate an error code.
922#
923# Examples:
924# _M10,rw # allocate 16 bytes with read + write permissions
925# _M100,rx # allocate 256 bytes with read + execute permissions
926#----------------------------------------------------------------------
927sub dump_allocate_memory_cmd
928{
929 shift; shift; # shift off the '_' and the 'M'
930 my $byte_size = get_addr(\@_);
931 shift; # Skip ','
932 printf("allocate_memory ( byte_size = %u (0x%x), permissions = %s)\n", $byte_size, $byte_size, join('',@_));
933}
934
935sub dump_allocate_memory_rsp
936{
937 if (@_ == 3 and $_[0] == 'E')
938 {
939 printf("allocated memory addr = ERROR (%s))\n", join('',@_));
940 }
941 else
942 {
943 printf("allocated memory addr = 0x%s\n", join('',@_));
944 }
945}
946
Greg Claytone51dc6f2011-05-20 02:00:47 +0000947#----------------------------------------------------------------------
948# '_m' - deallocate memory command (LLDB extension)
949#
950# Command: '_m'
951# Arg1: Hex address as big endian hex string
952#
953# Returns: "OK" on success "EXX" on error
954#
955# Examples:
956# _m201000 # Free previously allocated memory at address 0x201000
957#----------------------------------------------------------------------
958sub dump_deallocate_memory_cmd
959{
960 shift; shift; # shift off the '_' and the 'm'
961 printf("deallocate_memory ( addr = 0x%s)\n", join('',@_));
962}
963
964
965#----------------------------------------------------------------------
966# 'p' command
967#----------------------------------------------------------------------
968sub dump_read_single_register_cmd
969{
970 my $cmd = shift;
Greg Clayton9163c392011-09-17 05:45:35 +0000971 $reg_cmd_reg = get_hex(\@_);
Greg Claytone51dc6f2011-05-20 02:00:47 +0000972 my $thread = get_thread_from_thread_suffix (\@_);
Greg Clayton9163c392011-09-17 05:45:35 +0000973 my $reg_href = $$registers_aref[$reg_cmd_reg];
Greg Clayton86729962011-06-02 22:21:38 +0000974
Greg Claytone51dc6f2011-05-20 02:00:47 +0000975 if (defined $thread)
976 {
Greg Clayton86729962011-06-02 22:21:38 +0000977 print "read_register ( reg = \"$reg_href->{name}\", thread = $thread )\n";
Greg Claytone51dc6f2011-05-20 02:00:47 +0000978 }
979 else
980 {
Greg Clayton86729962011-06-02 22:21:38 +0000981 print "read_register ( reg = \"$reg_href->{name}\" )\n";
Greg Claytone51dc6f2011-05-20 02:00:47 +0000982 }
983}
984
985
986#----------------------------------------------------------------------
987# 'P' command
988#----------------------------------------------------------------------
989sub dump_write_single_register_cmd
990{
991 my $cmd = shift;
992 my $reg_num = get_hex(\@_);
993 shift (@_); # Discard the '='
994
995 print "write_register ( ";
996 dump_register_value(0, \@_, $reg_num);
997 my $thread = get_thread_from_thread_suffix (\@_);
998 if (defined $thread)
999 {
1000 print ", thread = $thread";
1001 }
1002 print " )\n";
1003}
1004
1005#----------------------------------------------------------------------
1006# 'm' command
1007#----------------------------------------------------------------------
1008our $read_mem_address = 0;
1009sub dump_read_mem_cmd
1010{
1011 my $cmd = shift;
1012 $read_mem_address = get_addr(\@_);
1013 shift; # Skip ','
1014 printf("read_mem ( $addr_format, %s )\n", $read_mem_address, join('',@_));
1015}
1016
1017#----------------------------------------------------------------------
1018# 'm' response
1019#----------------------------------------------------------------------
1020sub dump_read_mem_rsp
1021{
1022 # If the memory read was 2 or 4 bytes, print it out in native format
1023 # instead of just as bytes.
1024 my $num_nibbles = @_;
1025 if ($num_nibbles == 2)
1026 {
1027 printf(" 0x%2.2x", get8(\@_));
1028 }
1029 elsif ($num_nibbles == 4)
1030 {
1031 printf(" 0x%4.4x", get16(\@_));
1032 }
1033 elsif ($num_nibbles == 8)
1034 {
1035 printf(" 0x%8.8x", get32(\@_));
1036 }
1037 elsif ($num_nibbles == 16)
1038 {
1039 printf(" 0x%s", get64(\@_));
1040 }
1041 else
1042 {
1043 my $curr_address = $read_mem_address;
1044 my $nibble;
1045 my $nibble_offset = 0;
1046 my $max_nibbles_per_line = 2 * $max_bytes_per_line;
1047 foreach $nibble (@_)
1048 {
1049 if (($nibble_offset % $max_nibbles_per_line) == 0)
1050 {
1051 ($nibble_offset > 0) and print "\n ";
1052 printf("$addr_format: ", $curr_address + $nibble_offset/2);
1053 }
1054 (($nibble_offset % 2) == 0) and print ' ';
1055 print $nibble;
1056 $nibble_offset++;
1057 }
1058 }
1059 print "\n";
1060}
1061
1062#----------------------------------------------------------------------
1063# 'c' command
1064#----------------------------------------------------------------------
1065sub dump_continue_cmd
1066{
1067 my $cmd = shift;
1068 my $address = -1;
1069 if (@_)
1070 {
1071 my $address = get_addr(\@_);
1072 printf("continue ($addr_format)\n", $address);
1073 }
1074 else
1075 {
1076 printf("continue ()\n");
1077 }
1078}
1079
1080#----------------------------------------------------------------------
1081# 'Css' continue (C) with signal (ss where 'ss' is two hex digits)
1082#----------------------------------------------------------------------
1083sub dump_continue_with_signal_cmd
1084{
1085 my $cmd = shift;
1086 my $address = -1;
1087 my $signal = get_hex(\@_);
1088 if (@_)
1089 {
1090 my $address = 0;
1091 if (@_ && $_[0] == ';')
1092 {
1093 shift;
1094 $address = get_addr(\@_);
1095 }
1096 }
1097
1098 if ($address != -1)
1099 {
1100 printf("continue_with_signal (signal = 0x%2.2x, address = $addr_format)\n", $signal, $address);
1101 }
1102 else
1103 {
1104 printf("continue_with_signal (signal = 0x%2.2x)\n", $signal);
1105 }
1106}
1107
1108#----------------------------------------------------------------------
1109# 'A' command
1110#----------------------------------------------------------------------
1111sub dump_A_command
1112{
1113 my $cmd = get_exptected_char(\@_, 'A') or print "error: incorrect command letter for argument packet, exptected 'A'\n";
1114 printf("set_program_arguments (\n");
1115 do
1116 {
1117 my $arg_len = get_uint(\@_);
1118 get_exptected_char(\@_, ',') or die "error: missing comma after argument length...?\n";
1119 my $arg_idx = get_uint(\@_);
1120 get_exptected_char(\@_, ',') or die "error: missing comma after argument number...?\n";
1121
1122 my $arg = '';
1123 my $num_hex8_bytes = $arg_len/2;
1124 for (1 .. $num_hex8_bytes)
1125 {
1126 $arg .= sprintf("%c", get8(\@_))
1127 }
1128 printf(" <%3u> argv[%u] = '%s'\n", $arg_len, $arg_idx, $arg);
1129 if (@_ > 0)
1130 {
1131 get_exptected_char(\@_, ',') or die "error: missing comma after argument argument ASCII hex bytes...?\n";
1132 }
1133 } while (@_ > 0);
1134 printf(" )\n");
1135}
1136
1137
1138#----------------------------------------------------------------------
1139# 'z' and 'Z' command
1140#----------------------------------------------------------------------
1141sub dump_bp_wp_command
1142{
1143 my $cmd = shift;
1144 my $type = shift;
1145 shift; # Skip ','
1146 my $address = get_addr(\@_);
1147 shift; # Skip ','
1148 my $length = join('',@_);
1149 if ($cmd eq 'z')
1150 {
1151 printf("remove $point_types[$type]($addr_format, %d)\n", $address, $length);
1152 }
1153 else
1154 {
1155 printf("insert $point_types[$type]($addr_format, %d)\n", $address, $length);
1156 }
1157}
1158
1159
1160#----------------------------------------------------------------------
1161# 'X' command
1162#----------------------------------------------------------------------
1163sub dump_write_mem_binary_cmd
1164{
1165 my $cmd = shift;
1166 my $address = get_addr(\@_);
1167 shift; # Skip ','
1168
1169 my ($length, $binary) = split(/:/, join('',@_));
1170 printf("write_mem_binary ( $addr_format, %d, %s)\n", $address, $length, $binary);
1171
1172}
1173
1174#----------------------------------------------------------------------
1175# 'M' command
1176#----------------------------------------------------------------------
1177sub dump_write_mem_cmd
1178{
1179 my $cmd = shift;
1180 my $address = get_addr(\@_);
1181 shift; # Skip ','
1182 my ($length, $hex_bytes) = split(/:/, join('',@_));
1183# printf("write_mem ( $addr_format, %d, %s)\n", $address, $length, $hex_bytes);
1184 printf("write_mem ( addr = $addr_format, len = %d (0x%x), bytes = ", $address, $length, $length);
1185 splice(@_, 0, length($length)+1);
1186
1187 my $curr_address = $address;
1188 my $nibble;
1189 my $nibble_count = 0;
1190 my $max_nibbles_per_line = 2 * $max_bytes_per_line;
1191 foreach $nibble (@_)
1192 {
1193 (($nibble_count % 2) == 0) and print ' ';
1194 print $nibble;
1195 $nibble_count++;
1196 }
1197
1198 # If the memory to write is 2 or 4 bytes, print it out in native format
1199 # instead of just as bytes.
1200 if (@_ == 4)
1201 {
1202 printf(" ( 0x%4.4x )", get16(\@_));
1203 }
1204 elsif (@_ == 8)
1205 {
1206 printf(" ( 0x%8.8x )", get32(\@_));
1207 }
1208 print " )\n";
1209
1210}
1211
1212#----------------------------------------------------------------------
1213# 'v' command
1214#----------------------------------------------------------------------
1215our $extended_rsp_callback = 0;
1216sub dump_extended_cmd
1217{
1218 $extended_rsp_callback = 0;
1219 if (join('', @_[0..4]) eq "vCont")
1220 {
1221 dump_extended_continue_cmd(splice(@_,5));
1222 }
1223 elsif (join('', @_[0..11]) eq 'vAttachWait;')
1224 {
1225 dump_attach_wait_command (splice(@_,12));
1226 }
1227}
1228
1229#----------------------------------------------------------------------
1230# 'v' response
1231#----------------------------------------------------------------------
1232sub dump_extended_rsp
1233{
1234 if ($extended_rsp_callback)
1235 {
1236 &$extended_rsp_callback(@_);
1237 }
1238 $extended_rsp_callback = 0;
1239}
1240
1241#----------------------------------------------------------------------
1242# 'vAttachWait' command
1243#----------------------------------------------------------------------
1244sub dump_attach_wait_command
1245{
Greg Claytone51dc6f2011-05-20 02:00:47 +00001246 print "attach_wait ( ";
1247 while (@_)
1248 {
1249 printf("%c", get8(\@_))
1250 }
1251 printf " )\n";
1252
1253}
1254
1255#----------------------------------------------------------------------
1256# 'vCont' command
1257#----------------------------------------------------------------------
1258sub dump_extended_continue_cmd
1259{
Greg Claytone51dc6f2011-05-20 02:00:47 +00001260 print "extended_continue ( ";
1261 my $cmd = shift;
1262 if ($cmd eq '?')
1263 {
1264 print "list supported modes )\n";
1265 $extended_rsp_callback = \&dump_extended_continue_rsp;
1266 }
1267 elsif ($cmd eq ';')
1268 {
1269 $extended_rsp_callback = \&dump_stop_reply_packet;
1270 my $i = 0;
1271 while ($#_ >= 0)
1272 {
1273 if ($i > 0)
1274 {
1275 print ", ";
1276 }
1277 my $continue_cmd = shift;
1278 my $tmp;
1279 if ($continue_cmd eq 'c')
1280 {
1281 print "continue";
1282 }
1283 elsif ($continue_cmd eq 'C')
1284 {
1285 print "continue with signal ";
1286 print shift;
1287 print shift;
1288 }
1289 elsif ($continue_cmd eq 's')
1290 {
1291 print "step";
1292 }
1293 elsif ($continue_cmd eq 'S')
1294 {
1295 print "step with signal ";
1296 print shift;
1297 print shift;
1298 }
1299
1300 if ($_[0] eq ':')
1301 {
1302 shift; # Skip ':'
1303 print " for thread ";
1304 while ($#_ >= 0)
1305 {
1306 $tmp = shift;
1307 if (length($tmp) > 0 && $tmp ne ';') {
1308 print $tmp;
1309 } else {
1310 last;
1311 }
1312 }
1313 }
1314 $i++;
1315 }
1316
1317 printf " )\n";
1318 }
1319}
1320
1321#----------------------------------------------------------------------
1322# 'vCont' response
1323#----------------------------------------------------------------------
1324sub dump_extended_continue_rsp
1325{
Greg Clayton86729962011-06-02 22:21:38 +00001326 if (scalar(@_) == 0)
1327 {
1328 print "$unimplemented_str\n";
1329 }
1330 else
1331 {
1332 print "extended_continue supports " . join('',@_) . "\n";
1333 }
Greg Claytone51dc6f2011-05-20 02:00:47 +00001334}
1335
1336#----------------------------------------------------------------------
1337# Dump the command ascii for any unknown commands
1338#----------------------------------------------------------------------
1339sub dump_other_cmd
1340{
1341 print "other = " . join('',@_) . "\n";
1342}
1343
1344#----------------------------------------------------------------------
1345# Check to see if the response was unsupported with appropriate checksum
1346#----------------------------------------------------------------------
1347sub rsp_is_unsupported
1348{
1349 return join('',@_) eq "#00";
1350}
1351
1352#----------------------------------------------------------------------
1353# Check to see if the response was "OK" with appropriate checksum
1354#----------------------------------------------------------------------
1355sub rsp_is_OK
1356{
1357 return join('',@_) eq "OK#9a";
1358}
1359
1360#----------------------------------------------------------------------
1361# Dump a response for an unknown command
1362#----------------------------------------------------------------------
1363sub dump_other_rsp
1364{
1365 print "other = " . join('',@_) . "\n";
1366}
1367
1368#----------------------------------------------------------------------
1369# Get a byte from the ascii string assuming that the 2 nibble ascii
1370# characters are in hex.
1371#
1372# The argument for this function needs to be a reference to an array
1373# that contains single character strings and the array will get
1374# updated by shifting characters off the front of it (no leading # "0x")
1375#----------------------------------------------------------------------
1376sub get8
1377{
1378 my $arrayref = shift;
1379 my $val = hex(shift(@$arrayref) . shift(@$arrayref));
1380 return $val;
1381}
1382
1383#----------------------------------------------------------------------
1384# Get a 16 bit integer and swap if $swap global is set to a non-zero
1385# value.
1386#
1387# The argument for this function needs to be a reference to an array
1388# that contains single character strings and the array will get
1389# updated by shifting characters off the front of it (no leading # "0x")
1390#----------------------------------------------------------------------
1391sub get16
1392{
1393 my $arrayref = shift;
1394 my $val = 0;
1395 if ($swap)
1396 {
1397 $val = get8($arrayref) |
1398 get8($arrayref) << 8;
1399 }
1400 else
1401 {
1402 $val = get8($arrayref) << 8 |
1403 get8($arrayref) ;
1404 }
1405 return $val;
1406}
1407
1408#----------------------------------------------------------------------
1409# Get a 32 bit integer and swap if $swap global is set to a non-zero
1410# value.
1411#
1412# The argument for this function needs to be a reference to an array
1413# that contains single character strings and the array will get
1414# updated by shifting characters off the front of it (no leading # "0x")
1415#----------------------------------------------------------------------
1416sub get32
1417{
1418 my $arrayref = shift;
1419 my $val = 0;
1420 if ($swap)
1421 {
1422 $val = get8($arrayref) |
1423 get8($arrayref) << 8 |
1424 get8($arrayref) << 16 |
1425 get8($arrayref) << 24 ;
1426 }
1427 else
1428 {
1429 $val = get8($arrayref) << 24 |
1430 get8($arrayref) << 16 |
1431 get8($arrayref) << 8 |
1432 get8($arrayref) ;
1433 }
1434 return $val;
1435}
1436
1437#----------------------------------------------------------------------
1438# Get a 64 bit hex value as a string
1439#
1440# The argument for this function needs to be a reference to an array
1441# that contains single character strings and the array will get
1442# updated by shifting characters off the front of it (no leading # "0x")
1443#----------------------------------------------------------------------
1444sub get64
1445{
1446 my $arrayref = shift;
1447 my $val = '';
1448 my @nibbles;
1449 if ($swap)
1450 {
1451 push @nibbles, splice(@$arrayref, 14, 2);
1452 push @nibbles, splice(@$arrayref, 12, 2);
1453 push @nibbles, splice(@$arrayref, 10, 2);
1454 push @nibbles, splice(@$arrayref, 8, 2);
1455 push @nibbles, splice(@$arrayref, 6, 2);
1456 push @nibbles, splice(@$arrayref, 4, 2);
1457 push @nibbles, splice(@$arrayref, 2, 2);
1458 push @nibbles, splice(@$arrayref, 0, 2);
1459 }
1460 else
1461 {
Greg Clayton9163c392011-09-17 05:45:35 +00001462 (@nibbles) = splice(@$arrayref, 0, ((64/8) * 2));
Greg Claytone51dc6f2011-05-20 02:00:47 +00001463 }
1464 $val = join('', @nibbles);
1465 return $val;
1466}
1467
1468#----------------------------------------------------------------------
1469# Get a 80 bit hex value as a string
1470#
1471# The argument for this function needs to be a reference to an array
1472# that contains single character strings and the array will get
1473# updated by shifting characters off the front of it (no leading # "0x")
1474#----------------------------------------------------------------------
1475sub get80
1476{
1477 my $arrayref = shift;
1478 my $val = '';
1479 my @nibbles;
1480 if ($swap)
1481 {
1482 push @nibbles, splice(@$arrayref, 18, 2);
1483 push @nibbles, splice(@$arrayref, 16, 2);
1484 push @nibbles, splice(@$arrayref, 14, 2);
1485 push @nibbles, splice(@$arrayref, 12, 2);
1486 push @nibbles, splice(@$arrayref, 10, 2);
1487 push @nibbles, splice(@$arrayref, 8, 2);
1488 push @nibbles, splice(@$arrayref, 6, 2);
1489 push @nibbles, splice(@$arrayref, 4, 2);
1490 push @nibbles, splice(@$arrayref, 2, 2);
1491 push @nibbles, splice(@$arrayref, 0, 2);
1492 }
1493 else
1494 {
Greg Clayton9163c392011-09-17 05:45:35 +00001495 (@nibbles) = splice(@$arrayref, 0, ((80/8) * 2));
Greg Claytone51dc6f2011-05-20 02:00:47 +00001496 }
1497 $val = join('', @nibbles);
1498 return $val;
1499}
1500
1501#----------------------------------------------------------------------
1502# Get a 96 bit hex value as a string
1503#
1504# The argument for this function needs to be a reference to an array
1505# that contains single character strings and the array will get
1506# updated by shifting characters off the front of it (no leading # "0x")
1507#----------------------------------------------------------------------
1508sub get96
1509{
1510 my $arrayref = shift;
1511 my $val = '';
1512 my @nibbles;
1513 if ($swap)
1514 {
1515 push @nibbles, splice(@$arrayref, 22, 2);
1516 push @nibbles, splice(@$arrayref, 20, 2);
1517 push @nibbles, splice(@$arrayref, 18, 2);
1518 push @nibbles, splice(@$arrayref, 16, 2);
1519 push @nibbles, splice(@$arrayref, 14, 2);
1520 push @nibbles, splice(@$arrayref, 12, 2);
1521 push @nibbles, splice(@$arrayref, 10, 2);
1522 push @nibbles, splice(@$arrayref, 8, 2);
1523 push @nibbles, splice(@$arrayref, 6, 2);
1524 push @nibbles, splice(@$arrayref, 4, 2);
1525 push @nibbles, splice(@$arrayref, 2, 2);
1526 push @nibbles, splice(@$arrayref, 0, 2);
1527 }
1528 else
1529 {
Greg Clayton9163c392011-09-17 05:45:35 +00001530 (@nibbles) = splice(@$arrayref, 0, ((96/8) * 2));
Greg Claytone51dc6f2011-05-20 02:00:47 +00001531 }
1532 $val = join('', @nibbles);
1533 return $val;
1534}
1535
1536#----------------------------------------------------------------------
1537# Get a 128 bit hex value as a string
1538#
1539# The argument for this function needs to be a reference to an array
1540# that contains single character strings and the array will get
1541# updated by shifting characters off the front of it (no leading # "0x")
1542#----------------------------------------------------------------------
1543sub get128
1544{
1545 my $arrayref = shift;
1546 my $val = '';
1547 my @nibbles;
1548 if ($swap)
1549 {
1550 push @nibbles, splice(@$arrayref, 30, 2);
1551 push @nibbles, splice(@$arrayref, 28, 2);
1552 push @nibbles, splice(@$arrayref, 26, 2);
1553 push @nibbles, splice(@$arrayref, 24, 2);
1554 push @nibbles, splice(@$arrayref, 22, 2);
1555 push @nibbles, splice(@$arrayref, 20, 2);
1556 push @nibbles, splice(@$arrayref, 18, 2);
1557 push @nibbles, splice(@$arrayref, 16, 2);
1558 push @nibbles, splice(@$arrayref, 14, 2);
1559 push @nibbles, splice(@$arrayref, 12, 2);
1560 push @nibbles, splice(@$arrayref, 10, 2);
1561 push @nibbles, splice(@$arrayref, 8, 2);
1562 push @nibbles, splice(@$arrayref, 6, 2);
1563 push @nibbles, splice(@$arrayref, 4, 2);
1564 push @nibbles, splice(@$arrayref, 2, 2);
1565 push @nibbles, splice(@$arrayref, 0, 2);
1566 }
1567 else
1568 {
Greg Clayton9163c392011-09-17 05:45:35 +00001569 (@nibbles) = splice(@$arrayref, 0, ((128/8) * 2));
1570 }
1571 $val = join('', @nibbles);
1572 return $val;
1573}
1574
1575#----------------------------------------------------------------------
1576# Get a 256 bit hex value as a string
1577#
1578# The argument for this function needs to be a reference to an array
1579# that contains single character strings and the array will get
1580# updated by shifting characters off the front of it (no leading # "0x")
1581#----------------------------------------------------------------------
1582sub get256
1583{
1584 my $arrayref = shift;
1585 my $val = '';
1586 my @nibbles;
1587 if ($swap)
1588 {
1589 push @nibbles, splice(@$arrayref, 62, 2);
1590 push @nibbles, splice(@$arrayref, 60, 2);
1591 push @nibbles, splice(@$arrayref, 58, 2);
1592 push @nibbles, splice(@$arrayref, 56, 2);
1593 push @nibbles, splice(@$arrayref, 54, 2);
1594 push @nibbles, splice(@$arrayref, 52, 2);
1595 push @nibbles, splice(@$arrayref, 50, 2);
1596 push @nibbles, splice(@$arrayref, 48, 2);
1597 push @nibbles, splice(@$arrayref, 46, 2);
1598 push @nibbles, splice(@$arrayref, 44, 2);
1599 push @nibbles, splice(@$arrayref, 42, 2);
1600 push @nibbles, splice(@$arrayref, 40, 2);
1601 push @nibbles, splice(@$arrayref, 38, 2);
1602 push @nibbles, splice(@$arrayref, 36, 2);
1603 push @nibbles, splice(@$arrayref, 34, 2);
1604 push @nibbles, splice(@$arrayref, 32, 2);
1605 push @nibbles, splice(@$arrayref, 30, 2);
1606 push @nibbles, splice(@$arrayref, 28, 2);
1607 push @nibbles, splice(@$arrayref, 26, 2);
1608 push @nibbles, splice(@$arrayref, 24, 2);
1609 push @nibbles, splice(@$arrayref, 22, 2);
1610 push @nibbles, splice(@$arrayref, 20, 2);
1611 push @nibbles, splice(@$arrayref, 18, 2);
1612 push @nibbles, splice(@$arrayref, 16, 2);
1613 push @nibbles, splice(@$arrayref, 14, 2);
1614 push @nibbles, splice(@$arrayref, 12, 2);
1615 push @nibbles, splice(@$arrayref, 10, 2);
1616 push @nibbles, splice(@$arrayref, 8, 2);
1617 push @nibbles, splice(@$arrayref, 6, 2);
1618 push @nibbles, splice(@$arrayref, 4, 2);
1619 push @nibbles, splice(@$arrayref, 2, 2);
1620 push @nibbles, splice(@$arrayref, 0, 2);
1621 }
1622 else
1623 {
1624 (@nibbles) = splice(@$arrayref, 0, ((256/8) * 2));
Greg Claytone51dc6f2011-05-20 02:00:47 +00001625 }
1626 $val = join('', @nibbles);
1627 return $val;
1628}
1629
1630#----------------------------------------------------------------------
1631# Get a an unsigned integer value by grabbing items off the front of
1632# the array stopping when a non-digit char string is encountered.
1633#
1634# The argument for this function needs to be a reference to an array
1635# that contains single character strings and the array will get
1636# updated by shifting characters off the front of it
1637#----------------------------------------------------------------------
1638sub get_uint
1639{
1640 my $arrayref = shift;
1641 @$arrayref == 0 and return 0;
1642 my $val = 0;
1643 while ($$arrayref[0] =~ /[0-9]/)
1644 {
1645 $val = $val * 10 + int(shift(@$arrayref));
1646 }
1647 return $val;
1648}
1649
1650#----------------------------------------------------------------------
1651# Check the first character in the array and if it matches the expected
1652# character, return that character, else return undef;
1653#
1654# The argument for this function needs to be a reference to an array
1655# that contains single character strings and the array will get
1656# updated by shifting characters off the front of it. If the expected
1657# character doesn't match, it won't touch the array. If the first
1658# character does match, it will shift it off and return it.
1659#----------------------------------------------------------------------
1660sub get_exptected_char
1661{
1662 my $arrayref = shift;
1663 my $expected_char = shift;
1664 if ($expected_char eq $$arrayref[0])
1665 {
1666 return shift(@$arrayref);
1667 }
1668 return undef;
1669}
1670#----------------------------------------------------------------------
1671# Get a hex value by grabbing items off the front of the array and
1672# stopping when a non-hex char string is encountered.
1673#
1674# The argument for this function needs to be a reference to an array
1675# that contains single character strings and the array will get
1676# updated by shifting characters off the front of it (no leading # "0x")
1677#----------------------------------------------------------------------
1678sub get_hex
1679{
1680 my $arrayref = shift;
1681 my $my_swap = @_ ? shift : 0;
1682 my $shift = 0;
1683 my $val = 0;
1684 while ($$arrayref[0] =~ /[0-9a-fA-F]/)
1685 {
1686 if ($my_swap)
1687 {
1688 my $byte = hex(shift(@$arrayref)) << 4 | hex(shift(@$arrayref));
1689 $val |= $byte << $shift;
1690 $shift += 8;
1691 }
1692 else
1693 {
1694 $val <<= 4;
1695 $val |= hex(shift(@$arrayref));
1696 }
1697 }
1698 return $val;
1699}
1700
1701#----------------------------------------------------------------------
1702# Get an address value by grabbing items off the front of the array.
1703#
1704# The argument for this function needs to be a reference to an array
1705# that contains single character strings and the array will get
1706# updated by shifting characters off the front of it (no leading # "0x")
1707#----------------------------------------------------------------------
1708sub get_addr
1709{
1710 get_hex(shift);
1711}
1712
Greg Clayton86729962011-06-02 22:21:38 +00001713sub get_hex_string
1714{
1715 my $arrayref = shift;
1716 my $str = '';
1717 while ($$arrayref[0] =~ /[0-9a-fA-F]/ and $$arrayref[1] =~ /[0-9a-fA-F]/)
1718 {
1719 my $hi_nibble = hex(shift(@$arrayref));
1720 my $lo_nibble = hex(shift(@$arrayref));
1721 my $byte = ($hi_nibble << 4) | $lo_nibble;
1722 $str .= chr($byte);
1723 }
1724 return $str;
1725}
1726
Greg Claytone51dc6f2011-05-20 02:00:47 +00001727sub dump_stop_reply_data
1728{
1729 while ($#_ >= 0)
1730 {
1731 last unless ($_[0] ne '#');
1732
1733
1734 my $key = '';
1735 my $value = '';
1736 if ($_[0] =~ /[0-9a-fA-F]/ && $_[1] =~ /[0-9a-fA-F]/)
1737 {
1738 my $reg_num = get8(\@_);
1739 shift(@_); # Skip ':'
1740 if (defined ($registers_aref) && $reg_num < @$registers_aref)
1741 {
1742 dump_register_value(1, \@_, $reg_num);
1743 print "\n";
1744 shift(@_); # Skip ';'
1745 next;
1746 }
1747 $key = sprintf("reg %u", $reg_num);
1748 }
1749 my $char;
1750
1751 if (length($key) == 0)
1752 {
1753 while (1)
1754 {
1755 $char = shift(@_);
1756 if (length($char) == 0 or $char eq ':' or $char eq '#') { last; }
1757 $key .= $char;
1758 }
1759 }
1760
1761 while (1)
1762 {
1763 $char = shift(@_);
1764 if (length($char) == 0 or $char eq ';' or $char eq '#') { last; }
1765 $value .= $char;
1766 }
1767 printf("\t%*s = %s\n", $max_register_name_len, $key, $value);
1768 }
1769}
1770
1771#----------------------------------------------------------------------
1772# Dumps a Stop Reply Packet which happens in response to a step,
1773# continue, last signal, and probably a few other commands.
1774#----------------------------------------------------------------------
1775sub dump_stop_reply_packet
1776{
1777 my $what = shift(@_);
1778 if ($what eq 'S')
1779 {
1780 print 'signal ( 0x' . shift(@_) . shift(@_) . " )\n";
1781 }
1782 elsif ($what eq 'T')
1783 {
1784 print 'signal ( 0x' . shift(@_) . shift(@_) . " )\n";
1785 dump_stop_reply_data (@_);
1786 }
1787 elsif ($what eq 'W')
1788 {
1789 print 'process_exited( ' . shift(@_) . shift(@_) . " )\n";
1790 }
1791 elsif ($what eq 'X')
1792 {
1793 print 'process_terminated( ' . shift(@_) . shift(@_) . " )\n";
1794 }
1795 elsif ($what eq 'O')
1796 {
1797 my $console_output = '';
1798 my $num_hex8_bytes = @_/2;
1799 for (1 .. $num_hex8_bytes)
1800 {
1801 $console_output .= sprintf("%c", get8(\@_))
1802 }
1803
1804 print "program_console_output('$console_output')\n";
1805 }
1806}
1807
1808#----------------------------------------------------------------------
1809# '?' command
1810#----------------------------------------------------------------------
1811sub dump_last_signal_cmd
1812{
1813 my $cmd = shift;
1814 print 'last_signal (' . join('',@_) . ")\n";
1815}
1816
1817sub dump_raw_command
1818{
1819 my $cmd_aref = shift;
1820 my $callback_ref;
1821 $curr_cmd = $$cmd_aref[0];
1822 $curr_cmd eq '_' and $curr_cmd .= $$cmd_aref[1];
1823
1824 $callback_ref = $cmd_callbacks{$curr_cmd};
1825 if ($callback_ref)
1826 {
1827 &$callback_ref(@$cmd_aref);
1828 }
1829 else
1830 {
1831 # Strip the command byte for responses since we injected that above
1832 dump_other_cmd(@$cmd_aref);
1833 }
1834}
1835
1836sub dump_standard_response
1837{
1838 my $cmd_aref = shift;
1839
Greg Clayton86729962011-06-02 22:21:38 +00001840 my $cmd_len = scalar(@$cmd_aref);
1841 if ($cmd_len == 0)
Greg Claytone51dc6f2011-05-20 02:00:47 +00001842 {
Greg Clayton86729962011-06-02 22:21:38 +00001843 print "$unimplemented_str\n";
Greg Claytone51dc6f2011-05-20 02:00:47 +00001844 return 1;
1845 }
1846
1847 my $response = join('', @$cmd_aref);
1848 if ($response eq 'OK')
1849 {
1850 print "$success_str\n";
1851 return 1;
1852 }
1853
Greg Clayton86729962011-06-02 22:21:38 +00001854 if ($cmd_len == 3 and index($response, 'E') == 0)
Greg Claytone51dc6f2011-05-20 02:00:47 +00001855 {
1856 print "ERROR: " . substr($response, 1) . "\n";
1857 return 1;
1858 }
1859
1860 return 0;
1861}
1862sub dump_raw_response
1863{
1864 my $cmd_aref = shift;
1865 my $callback_ref;
1866
1867 $callback_ref = $rsp_callbacks{$curr_cmd};
1868
1869 if ($callback_ref)
1870 {
1871 &$callback_ref(@$cmd_aref);
1872 }
1873 else
1874 {
1875 dump_standard_response($cmd_aref) or dump_other_rsp(@$cmd_aref);
1876 }
1877
1878}
1879#----------------------------------------------------------------------
1880# Dumps any command and handles simple error checking on the responses
1881# for commands that are unsupported or OK.
1882#----------------------------------------------------------------------
1883sub dump_command
1884{
1885 my $cmd_str = shift;
1886
1887 # Dump the original command string if verbose is on
1888 if ($opt_v)
1889 {
1890 print "dump_command($cmd_str)\n ";
1891 }
1892
1893 my @cmd_chars = extract_command($cmd_str);
1894 my $is_cmd = 1;
1895
1896 my $cmd = $cmd_chars[0];
1897 if ($cmd eq '$')
1898 {
1899 $is_cmd = 0; # Note that this is a reply
1900 $cmd = $curr_cmd; # set the command byte appropriately
1901 shift @cmd_chars; # remove the '$' from the cmd bytes
1902 }
1903
1904 # Check for common responses across all commands and handle them
1905 # if we can
1906 if ( $is_cmd == 0 )
1907 {
1908 if (rsp_is_unsupported(@cmd_chars))
1909 {
Greg Clayton86729962011-06-02 22:21:38 +00001910 print "$unimplemented_str\n";
Greg Claytone51dc6f2011-05-20 02:00:47 +00001911 return;
1912 }
1913 elsif (rsp_is_OK(@cmd_chars))
1914 {
1915 print "$success_str\n";
1916 return;
1917 }
1918 # Strip the checksum information for responses
1919 strip_checksum(\@cmd_chars);
1920 }
1921
1922 my $callback_ref;
1923 if ($is_cmd) {
1924 $callback_ref = $cmd_callbacks{$cmd};
1925 } else {
1926 $callback_ref = $rsp_callbacks{$cmd};
1927 }
1928
1929 if ($callback_ref)
1930 {
1931 &$callback_ref(@cmd_chars);
1932 }
1933 else
1934 {
1935 # Strip the command byte for responses since we injected that above
1936 if ($is_cmd) {
1937 dump_other_cmd(@cmd_chars);
1938 } else {
1939 dump_other_rsp(@cmd_chars);
1940 }
1941
1942 }
1943}
1944
1945
1946#----------------------------------------------------------------------
1947# Process a gdbserver log line by looking for getpkt and putkpt and
1948# tossing any other lines.
1949#----------------------------------------------------------------------
1950sub process_log_line
1951{
1952 my $line = shift;
1953 #($opt_v and $opt_g) and print "# $line";
1954 my $extract_cmd = 0;
1955 if ($line =~ /getpkt /)
1956 {
1957 $extract_cmd = 1;
1958 print "\n--> ";
1959 }
1960 elsif ($line =~ /putpkt /)
1961 {
1962 $extract_cmd = 1;
1963 print "<-- ";
1964 }
1965 elsif ($line =~ /.*Sent: \[[0-9]+\.[0-9]+[:0-9]*\] (.*)/)
1966 {
1967 $opt_g and print "maintenance dump-packets command: $1\n";
1968 my @raw_cmd_bytes = split(/ */, $1);
1969 print "\n--> ";
1970 dump_raw_command(\@raw_cmd_bytes);
1971 process_log_line($2);
1972 }
1973 elsif ($line =~ /.*Recvd: \[[0-9]+\.[0-9]+[:0-9]*\] (.*)/)
1974 {
1975 $opt_g and print "maintenance dump-packets reply: $1\n";
1976 my @raw_rsp_bytes = split(/ */, $1);
1977 print "<-- ";
1978 dump_raw_response(\@raw_rsp_bytes);
1979 print "\n";
1980 }
1981 elsif ($line =~ /getpkt: (.*)/)
1982 {
1983 if ($1 =~ /\$([^#]+)#[0-9a-fA-F]{2}/)
1984 {
1985 $opt_g and print "command: $1\n";
1986 my @raw_cmd_bytes = split(/ */, $1);
1987 print "--> ";
1988 dump_raw_command(\@raw_cmd_bytes);
1989 }
1990 elsif ($1 =~ /\+/)
1991 {
1992 #print "--> ACK\n";
1993 }
1994 elsif ($1 =~ /-/)
1995 {
1996 #print "--> NACK\n";
1997 }
1998 }
1999 elsif ($line =~ /putpkt: (.*)/)
2000 {
2001 if ($1 =~ /\$([^#]+)#[0-9a-fA-F]{2}/)
2002 {
2003 $opt_g and print "response: $1\n";
2004 my @raw_rsp_bytes = split(/ */, $1);
2005 print "<-- ";
2006 dump_raw_response(\@raw_rsp_bytes);
2007 print "\n";
2008 }
2009 elsif ($1 =~ /\+/)
2010 {
2011 #print "<-- ACK\n";
2012 }
2013 elsif ($1 =~ /-/)
2014 {
2015 #print "<-- NACK\n";
2016 }
2017 }
2018 elsif ($line =~ /send packet: (.*)/)
2019 {
2020 if ($1 =~ /\$([^#]+)#[0-9a-fA-F]{2}/)
2021 {
2022 $opt_g and print "command: $1\n";
2023 my @raw_cmd_bytes = split(/ */, $1);
2024 print "--> ";
2025 dump_raw_command(\@raw_cmd_bytes);
2026 }
2027 elsif ($1 =~ /\+/)
2028 {
2029 #print "--> ACK\n";
2030 }
2031 elsif ($1 =~ /-/)
2032 {
2033 #print "--> NACK\n";
2034 }
2035 }
2036 elsif ($line =~ /read packet: (.*)/)
2037 {
Greg Clayton86729962011-06-02 22:21:38 +00002038 if ($1 =~ /\$([^#]*)#[0-9a-fA-F]{2}/)
Greg Claytone51dc6f2011-05-20 02:00:47 +00002039 {
2040 $opt_g and print "response: $1\n";
2041 my @raw_rsp_bytes = split(/ */, $1);
2042 print "<-- ";
2043 dump_raw_response(\@raw_rsp_bytes);
2044 print "\n";
2045 }
2046 elsif ($1 =~ /\+/)
2047 {
2048 #print "<-- ACK\n";
2049 }
2050 elsif ($1 =~ /-/)
2051 {
2052 #print "<-- NACK\n";
2053 }
2054 }
2055 elsif ($line =~ /Sending packet: \$([^#]+)#[0-9a-fA-F]{2}\.\.\.(.*)/)
2056 {
2057 $opt_g and print "command: $1\n";
2058 my @raw_cmd_bytes = split(/ */, $1);
2059 print "\n--> ";
2060 dump_raw_command(\@raw_cmd_bytes);
2061 process_log_line($2);
2062 }
2063 elsif ($line =~ /Packet received: (.*)/)
2064 {
2065 $opt_g and print "response: $1\n";
2066 my @raw_rsp_bytes = split(/ */, $1);
2067 print "<-- ";
2068 dump_raw_response(\@raw_rsp_bytes);
2069 print "\n";
2070 }
2071
2072 if ($extract_cmd)
2073 {
2074 my $beg = index($line, '("') + 2;
2075 my $end = rindex($line, '");');
2076 dump_command(substr($line, $beg, $end - $beg));
2077 }
2078}
2079
2080
2081our $line_num = 0;
2082while(<>)
2083{
2084 $line_num++;
2085 $opt_q or printf("# %5d: $_", $line_num);
2086 process_log_line($_);
2087}
2088
2089
2090
2091
2092
2093