ia64/xen-unstable

view xen/arch/x86/pdb-stub.c @ 3371:f913da82d617

bitkeeper revision 1.1159.212.1 (41d59cb5edkDeCOlUSEcFsW0oqB4mw)

Merge scramble.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-2.0-testing.bk
into scramble.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk
author kaf24@scramble.cl.cam.ac.uk
date Fri Dec 31 18:38:45 2004 +0000 (2004-12-31)
parents b2fa96909734 7b517e31b8e4
children aa7ce8a31f3d 51052c8b6456
line source
2 /*
3 * pervasive debugger
4 * www.cl.cam.ac.uk/netos/pdb
5 *
6 * alex ho
7 * 2004
8 * university of cambridge computer laboratory
9 *
10 * code adapted originally from kgdb, nemesis, & gdbserver
11 */
13 #include <xen/lib.h>
14 #include <xen/sched.h>
15 #include <asm/regs.h>
16 #include <xen/keyhandler.h>
17 #include <asm/apic.h>
18 #include <asm/domain_page.h> /* [un]map_domain_mem */
19 #include <asm/processor.h>
20 #include <asm/pdb.h>
21 #include <xen/list.h>
22 #include <xen/serial.h>
23 #include <xen/softirq.h>
24 #include <xen/init.h>
26 /* opt_pdb: Name of serial port for Xen pervasive debugger (and enable pdb) */
27 static unsigned char opt_pdb[10] = "none";
28 string_param("pdb", opt_pdb);
30 #define PDB_DEBUG_TRACE
31 #ifdef PDB_DEBUG_TRACE
32 #define TRC(_x) _x
33 #else
34 #define TRC(_x)
35 #endif
37 #define DEBUG_EXCEPTION 0x01
38 #define BREAKPT_EXCEPTION 0x03
39 #define PDB_LIVE_EXCEPTION 0x58
40 #define KEYPRESS_EXCEPTION 0x88
42 #define BUFMAX 400
44 static const char hexchars[] = "0123456789abcdef";
46 static int remote_debug;
48 #define PDB_BUFMAX 1024
49 static char pdb_in_buffer[PDB_BUFMAX];
50 static char pdb_out_buffer[PDB_BUFMAX];
51 static char pdb_buffer[PDB_BUFMAX];
53 struct pdb_context pdb_ctx;
54 int pdb_continue_thread = 0;
55 int pdb_general_thread = 0;
57 void pdb_put_packet (unsigned char *buffer, int ack);
58 void pdb_bkpt_check (u_char *buffer, int length,
59 unsigned long cr3, unsigned long addr);
61 int pdb_initialized = 0;
62 int pdb_page_fault_possible = 0;
63 int pdb_page_fault_scratch = 0; /* just a handy variable */
64 int pdb_page_fault = 0;
65 static int pdb_serhnd = -1;
66 static int pdb_stepping = 0;
68 int pdb_system_call = 0;
69 unsigned char pdb_system_call_enter_instr = 0; /* original enter instr */
70 unsigned char pdb_system_call_leave_instr = 0; /* original next instr */
71 unsigned long pdb_system_call_next_addr = 0; /* instr after int 0x80 */
72 unsigned long pdb_system_call_eflags_addr = 0; /* saved eflags on stack */
74 static inline void pdb_put_char(unsigned char c)
75 {
76 serial_putc(pdb_serhnd, c);
77 }
79 static inline unsigned char pdb_get_char(void)
80 {
81 return serial_getc(pdb_serhnd);
82 }
84 int
85 get_char (char *addr)
86 {
87 return *addr;
88 }
90 void
91 set_char (char *addr, int val)
92 {
93 *addr = val;
94 }
96 void
97 pdb_process_query (char *ptr)
98 {
99 if (strcmp(ptr, "C") == 0)
100 {
101 /* empty string */
102 }
103 else if (strcmp(ptr, "fThreadInfo") == 0)
104 {
105 #ifdef PDB_PAST
106 struct domain *p;
107 #endif /* PDB_PAST */
109 int buf_idx = 0;
111 pdb_out_buffer[buf_idx++] = 'l';
112 pdb_out_buffer[buf_idx++] = 0;
114 #ifdef PDB_PAST
115 switch (pdb_level)
116 {
117 case PDB_LVL_XEN: /* return a list of domains */
118 {
119 int count = 0;
121 read_lock(&domlist_lock);
123 pdb_out_buffer[buf_idx++] = 'm';
124 for_each_domain ( p )
125 {
126 domid_t domain = p->domain + PDB_ID_OFFSET;
128 if (count > 0)
129 {
130 pdb_out_buffer[buf_idx++] = ',';
131 }
132 if (domain > 15)
133 {
134 pdb_out_buffer[buf_idx++] = hexchars[domain >> 4];
135 }
136 pdb_out_buffer[buf_idx++] = hexchars[domain % 16];
137 count++;
138 }
139 pdb_out_buffer[buf_idx++] = 0;
141 read_unlock(&domlist_lock);
142 break;
143 }
144 case PDB_LVL_GUESTOS: /* return a list of processes */
145 {
146 int foobar[20];
147 int loop, total;
149 /* this cr3 is wrong! */
150 total = pdb_linux_process_list(pdb_ctx[pdb_level].info_cr3,
151 foobar, 20);
153 pdb_out_buffer[buf_idx++] = 'm';
154 pdb_out_buffer[buf_idx++] = '1'; /* 1 is to go back */
155 for (loop = 0; loop < total; loop++)
156 {
157 int pid = foobar[loop] + PDB_ID_OFFSET;
159 pdb_out_buffer[buf_idx++] = ',';
160 if (pid > 15)
161 {
162 pdb_out_buffer[buf_idx++] = hexchars[pid >> 4];
163 }
164 pdb_out_buffer[buf_idx++] = hexchars[pid % 16];
165 }
166 pdb_out_buffer[buf_idx++] = 0;
167 break;
168 }
169 case PDB_LVL_PROCESS: /* hmmm... */
170 {
171 pdb_out_buffer[buf_idx++] = 'm';
172 pdb_out_buffer[buf_idx++] = '1'; /* 1 is to go back */
173 break;
174 }
175 default:
176 break;
177 }
178 #endif /* PDB_PAST */
180 }
181 else if (strcmp(ptr, "sThreadInfo") == 0)
182 {
183 int buf_idx = 0;
185 pdb_out_buffer[buf_idx++] = 'l';
186 pdb_out_buffer[buf_idx++] = 0;
187 }
188 else if (strncmp(ptr, "ThreadExtraInfo,", 16) == 0)
189 {
190 int thread = 0;
191 char *message = "foobar ?";
193 ptr += 16;
194 if (hexToInt (&ptr, &thread))
195 {
196 mem2hex (message, pdb_out_buffer, strlen(message) + 1);
197 }
199 #ifdef PDB_PAST
200 int thread = 0;
201 char message[16];
202 struct domain *p;
204 strncpy (message, dom0->name, 16);
206 ptr += 16;
207 if (hexToInt (&ptr, &thread))
208 {
209 mem2hex ((char *)message, pdb_out_buffer, strlen(message) + 1);
210 }
211 #endif /* PDB_PAST */
213 #ifdef PDB_FUTURE
214 {
215 char string[task_struct_comm_length];
217 string[0] = 0;
218 pdb_linux_process_details (cr3, pid, string);
219 printk (" (%s)", string);
220 }
221 #endif /* PDB_FUTURE*/
223 }
224 else if (strcmp(ptr, "Offsets") == 0)
225 {
226 /* empty string */
227 }
228 else if (strncmp(ptr, "Symbol", 6) == 0)
229 {
230 strcpy (pdb_out_buffer, "OK");
231 }
232 else
233 {
234 printk("pdb: error, unknown query [%s]\n", ptr);
235 }
236 }
238 void
239 pdb_x86_to_gdb_regs (char *buffer, struct xen_regs *regs)
240 {
241 int idx = 0;
243 mem2hex ((char *)&regs->eax, &buffer[idx], sizeof(regs->eax));
244 idx += sizeof(regs->eax) * 2;
245 mem2hex ((char *)&regs->ecx, &buffer[idx], sizeof(regs->ecx));
246 idx += sizeof(regs->ecx) * 2;
247 mem2hex ((char *)&regs->edx, &buffer[idx], sizeof(regs->edx));
248 idx += sizeof(regs->edx) * 2;
249 mem2hex ((char *)&regs->ebx, &buffer[idx], sizeof(regs->ebx));
250 idx += sizeof(regs->ebx) * 2;
251 mem2hex ((char *)&regs->esp, &buffer[idx], sizeof(regs->esp));
252 idx += sizeof(regs->esp) * 2;
253 mem2hex ((char *)&regs->ebp, &buffer[idx], sizeof(regs->ebp));
254 idx += sizeof(regs->ebp) * 2;
255 mem2hex ((char *)&regs->esi, &buffer[idx], sizeof(regs->esi));
256 idx += sizeof(regs->esi) * 2;
257 mem2hex ((char *)&regs->edi, &buffer[idx], sizeof(regs->edi));
258 idx += sizeof(regs->edi) * 2;
259 mem2hex ((char *)&regs->eip, &buffer[idx], sizeof(regs->eip));
260 idx += sizeof(regs->eip) * 2;
261 mem2hex ((char *)&regs->eflags, &buffer[idx], sizeof(regs->eflags));
262 idx += sizeof(regs->eflags) * 2;
263 mem2hex ((char *)&regs->cs, &buffer[idx], sizeof(regs->cs));
264 idx += sizeof(regs->cs) * 2;
265 mem2hex ((char *)&regs->ss, &buffer[idx], sizeof(regs->ss));
266 idx += sizeof(regs->ss) * 2;
267 mem2hex ((char *)&regs->ds, &buffer[idx], sizeof(regs->ds));
268 idx += sizeof(regs->ds) * 2;
269 mem2hex ((char *)&regs->es, &buffer[idx], sizeof(regs->es));
270 idx += sizeof(regs->es) * 2;
271 mem2hex ((char *)&regs->fs, &buffer[idx], sizeof(regs->fs));
272 idx += sizeof(regs->fs) * 2;
273 mem2hex ((char *)&regs->gs, &buffer[idx], sizeof(regs->gs));
274 }
276 /* at this point we allow any register to be changed, caveat emptor */
277 void
278 pdb_gdb_to_x86_regs (struct xen_regs *regs, char *buffer)
279 {
280 hex2mem(buffer, (char *)&regs->eax, sizeof(regs->eax));
281 buffer += sizeof(regs->eax) * 2;
282 hex2mem(buffer, (char *)&regs->ecx, sizeof(regs->ecx));
283 buffer += sizeof(regs->ecx) * 2;
284 hex2mem(buffer, (char *)&regs->edx, sizeof(regs->edx));
285 buffer += sizeof(regs->edx) * 2;
286 hex2mem(buffer, (char *)&regs->ebx, sizeof(regs->ebx));
287 buffer += sizeof(regs->ebx) * 2;
288 hex2mem(buffer, (char *)&regs->esp, sizeof(regs->esp));
289 buffer += sizeof(regs->esp) * 2;
290 hex2mem(buffer, (char *)&regs->ebp, sizeof(regs->ebp));
291 buffer += sizeof(regs->ebp) * 2;
292 hex2mem(buffer, (char *)&regs->esi, sizeof(regs->esi));
293 buffer += sizeof(regs->esi) * 2;
294 hex2mem(buffer, (char *)&regs->edi, sizeof(regs->edi));
295 buffer += sizeof(regs->edi) * 2;
296 hex2mem(buffer, (char *)&regs->eip, sizeof(regs->eip));
297 buffer += sizeof(regs->eip) * 2;
298 hex2mem(buffer, (char *)&regs->eflags, sizeof(regs->eflags));
299 buffer += sizeof(regs->eflags) * 2;
300 hex2mem(buffer, (char *)&regs->cs, sizeof(regs->cs));
301 buffer += sizeof(regs->cs) * 2;
302 hex2mem(buffer, (char *)&regs->ss, sizeof(regs->ss));
303 buffer += sizeof(regs->ss) * 2;
304 hex2mem(buffer, (char *)&regs->ds, sizeof(regs->ds));
305 buffer += sizeof(regs->ds) * 2;
306 hex2mem(buffer, (char *)&regs->es, sizeof(regs->es));
307 buffer += sizeof(regs->es) * 2;
308 hex2mem(buffer, (char *)&regs->fs, sizeof(regs->fs));
309 buffer += sizeof(regs->fs) * 2;
310 hex2mem(buffer, (char *)&regs->gs, sizeof(regs->gs));
311 }
313 int
314 pdb_process_command (char *ptr, struct xen_regs *regs, unsigned long cr3,
315 int sigval)
316 {
317 int length;
318 unsigned long addr;
319 int ack = 1; /* wait for ack in pdb_put_packet */
320 int go = 0;
322 TRC(printf("pdb: [%s]\n", ptr));
324 pdb_out_buffer[0] = 0;
326 if (pdb_ctx.valid == 1)
327 {
328 if (pdb_ctx.domain == -1) /* pdb context: xen */
329 {
330 struct domain *p;
332 p = &idle0_task;
333 if (p->mm.shadow_mode)
334 pdb_ctx.ptbr = pagetable_val(p->mm.shadow_table);
335 else
336 pdb_ctx.ptbr = pagetable_val(p->mm.pagetable);
337 }
338 else if (pdb_ctx.process == -1) /* pdb context: guest os */
339 {
340 struct domain *p;
342 if (pdb_ctx.domain == -2)
343 {
344 p = find_last_domain();
345 }
346 else
347 {
348 p = find_domain_by_id(pdb_ctx.domain);
349 }
350 if (p == NULL)
351 {
352 printk ("pdb error: unknown domain [0x%x]\n", pdb_ctx.domain);
353 strcpy (pdb_out_buffer, "E01");
354 pdb_ctx.domain = -1;
355 goto exit;
356 }
357 if (p->mm.shadow_mode)
358 pdb_ctx.ptbr = pagetable_val(p->mm.shadow_table);
359 else
360 pdb_ctx.ptbr = pagetable_val(p->mm.pagetable);
361 put_domain(p);
362 }
363 else /* pdb context: process */
364 {
365 struct domain *p;
366 unsigned long domain_ptbr;
368 p = find_domain_by_id(pdb_ctx.domain);
369 if (p == NULL)
370 {
371 printk ("pdb error: unknown domain [0x%x][0x%x]\n",
372 pdb_ctx.domain, pdb_ctx.process);
373 strcpy (pdb_out_buffer, "E01");
374 pdb_ctx.domain = -1;
375 goto exit;
376 }
377 if (p->mm.shadow_mode)
378 domain_ptbr = pagetable_val(p->mm.shadow_table);
379 else
380 domain_ptbr = pagetable_val(p->mm.pagetable);
381 put_domain(p);
383 pdb_ctx.ptbr = domain_ptbr;
384 /*pdb_ctx.ptbr=pdb_linux_pid_ptbr(domain_ptbr, pdb_ctx.process);*/
385 }
387 pdb_ctx.valid = 0;
388 TRC(printk ("pdb change context (dom:%d, proc:%d) now 0x%lx\n",
389 pdb_ctx.domain, pdb_ctx.process, pdb_ctx.ptbr));
390 }
392 switch (*ptr++)
393 {
394 case '?':
395 pdb_out_buffer[0] = 'S';
396 pdb_out_buffer[1] = hexchars[sigval >> 4];
397 pdb_out_buffer[2] = hexchars[sigval % 16];
398 pdb_out_buffer[3] = 0;
399 break;
400 case 'S': /* step with signal */
401 case 's': /* step */
402 {
403 if ( pdb_system_call_eflags_addr != 0 )
404 {
405 unsigned long eflags;
406 char eflags_buf[sizeof(eflags)*2]; /* STUPID STUPID STUPID */
408 pdb_linux_get_values((u_char*)&eflags, sizeof(eflags),
409 pdb_system_call_eflags_addr,
410 pdb_ctx.process, pdb_ctx.ptbr);
411 eflags |= X86_EFLAGS_TF;
412 mem2hex ((u_char *)&eflags, eflags_buf, sizeof(eflags));
413 pdb_linux_set_values(eflags_buf, sizeof(eflags),
414 pdb_system_call_eflags_addr,
415 pdb_ctx.process, pdb_ctx.ptbr);
416 }
418 regs->eflags |= X86_EFLAGS_TF;
419 pdb_stepping = 1;
420 return 1;
421 /* not reached */
422 }
423 case 'C': /* continue with signal */
424 case 'c': /* continue */
425 {
426 if ( pdb_system_call_eflags_addr != 0 )
427 {
428 unsigned long eflags;
429 char eflags_buf[sizeof(eflags)*2]; /* STUPID STUPID STUPID */
431 pdb_linux_get_values((u_char*)&eflags, sizeof(eflags),
432 pdb_system_call_eflags_addr,
433 pdb_ctx.process, pdb_ctx.ptbr);
434 eflags &= ~X86_EFLAGS_TF;
435 mem2hex ((u_char *)&eflags, eflags_buf, sizeof(eflags));
436 pdb_linux_set_values(eflags_buf, sizeof(eflags),
437 pdb_system_call_eflags_addr,
438 pdb_ctx.process, pdb_ctx.ptbr);
439 }
441 regs->eflags &= ~X86_EFLAGS_TF;
442 return 1; /* jump out before replying to gdb */
443 /* not reached */
444 }
445 case 'd':
446 remote_debug = !(remote_debug); /* toggle debug flag */
447 break;
448 case 'D': /* detach */
449 return go;
450 /* not reached */
451 case 'g': /* return the value of the CPU registers */
452 {
453 pdb_x86_to_gdb_regs (pdb_out_buffer, regs);
454 break;
455 }
456 case 'G': /* set the value of the CPU registers - return OK */
457 {
458 pdb_gdb_to_x86_regs (regs, ptr);
459 break;
460 }
461 case 'H':
462 {
463 int thread;
464 char *next = &ptr[1];
466 if (hexToInt (&next, &thread))
467 {
468 if (*ptr == 'c')
469 {
470 pdb_continue_thread = thread;
471 }
472 else if (*ptr == 'g')
473 {
474 pdb_general_thread = thread;
475 }
476 else
477 {
478 printk ("pdb error: unknown set thread command %c (%d)\n",
479 *ptr, thread);
480 strcpy (pdb_out_buffer, "E00");
481 break;
482 }
483 }
484 strcpy (pdb_out_buffer, "OK");
485 break;
486 }
487 case 'k': /* kill request */
488 {
489 strcpy (pdb_out_buffer, "OK"); /* ack for fun */
490 printk ("don't kill bill...\n");
491 ack = 0;
492 break;
493 }
495 case 'q':
496 {
497 pdb_process_query(ptr);
498 break;
499 }
501 /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
502 case 'm':
503 {
504 /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */
505 if (hexToInt (&ptr, (int *)&addr))
506 if (*(ptr++) == ',')
507 if (hexToInt (&ptr, &length))
508 {
509 ptr = 0;
511 pdb_page_fault_possible = 1;
512 pdb_page_fault = 0;
513 if (addr >= PAGE_OFFSET)
514 {
515 mem2hex ((char *) addr, pdb_out_buffer, length);
516 }
517 else if (pdb_ctx.process != -1)
518 {
519 pdb_linux_get_values(pdb_buffer, length, addr,
520 pdb_ctx.process, pdb_ctx.ptbr);
521 mem2hex (pdb_buffer, pdb_out_buffer, length);
522 }
523 else
524 {
525 pdb_get_values (pdb_buffer, length,
526 pdb_ctx.ptbr, addr);
527 mem2hex (pdb_buffer, pdb_out_buffer, length);
528 }
530 pdb_page_fault_possible = 0;
531 if (pdb_page_fault)
532 {
533 strcpy (pdb_out_buffer, "E03");
534 }
535 }
537 if (ptr)
538 {
539 strcpy (pdb_out_buffer, "E01");
540 }
541 break;
542 }
544 /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
545 case 'M':
546 {
547 /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */
548 if (hexToInt (&ptr, (int *)&addr))
549 if (*(ptr++) == ',')
550 if (hexToInt (&ptr, &length))
551 if (*(ptr++) == ':')
552 {
554 pdb_page_fault_possible = 1;
555 pdb_page_fault = 0;
556 if (addr >= PAGE_OFFSET)
557 {
558 hex2mem (ptr, (char *)addr, length);
559 pdb_bkpt_check(ptr, length, pdb_ctx.ptbr, addr);
560 }
561 else if (pdb_ctx.process != -1)
562 {
563 pdb_linux_set_values(ptr, length, addr,
564 pdb_ctx.process,
565 pdb_ctx.ptbr);
566 pdb_bkpt_check(ptr, length, pdb_ctx.ptbr, addr);
567 }
568 else
569 {
570 pdb_set_values (ptr, length,
571 pdb_ctx.ptbr, addr);
572 pdb_bkpt_check(ptr, length, pdb_ctx.ptbr, addr);
573 }
574 pdb_page_fault_possible = 0;
575 if (pdb_page_fault)
576 {
577 strcpy (pdb_out_buffer, "E03");
578 }
579 else
580 {
581 strcpy (pdb_out_buffer, "OK");
582 }
584 ptr = 0;
585 }
586 if (ptr)
587 {
588 strcpy (pdb_out_buffer, "E02");
589 }
590 break;
591 }
592 case 'T':
593 {
594 int id;
596 if (hexToInt (&ptr, &id))
597 {
598 strcpy (pdb_out_buffer, "E00");
600 #ifdef PDB_PAST
602 switch (pdb_level) /* previous level */
603 {
604 case PDB_LVL_XEN:
605 {
606 struct domain *p;
607 id -= PDB_ID_OFFSET;
608 if ( (p = find_domain_by_id(id)) == NULL)
609 strcpy (pdb_out_buffer, "E00");
610 else
611 strcpy (pdb_out_buffer, "OK");
612 put_domain(p);
614 pdb_level = PDB_LVL_GUESTOS;
615 pdb_ctx[pdb_level].ctrl = id;
616 pdb_ctx[pdb_level].info = id;
617 break;
618 }
619 case PDB_LVL_GUESTOS:
620 {
621 if (pdb_level == -1)
622 {
623 pdb_level = PDB_LVL_XEN;
624 }
625 else
626 {
627 pdb_level = PDB_LVL_PROCESS;
628 pdb_ctx[pdb_level].ctrl = id;
629 pdb_ctx[pdb_level].info = id;
630 }
631 break;
632 }
633 case PDB_LVL_PROCESS:
634 {
635 if (pdb_level == -1)
636 {
637 pdb_level = PDB_LVL_GUESTOS;
638 }
639 break;
640 }
641 default:
642 {
643 printk ("pdb internal error: invalid level [%d]\n",
644 pdb_level);
645 }
646 }
648 #endif /* PDB_PAST */
649 }
650 break;
651 }
652 }
654 exit:
655 /* reply to the request */
656 pdb_put_packet (pdb_out_buffer, ack);
658 return go;
659 }
661 /*
662 * process an input character from the serial line.
663 *
664 * return "1" if the character is a gdb debug string
665 * (and hence shouldn't be further processed).
666 */
668 int pdb_debug_state = 0; /* small parser state machine */
670 int hex(char ch)
671 {
672 if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10);
673 if ((ch >= '0') && (ch <= '9')) return (ch-'0');
674 if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10);
675 return (-1);
676 }
678 /* convert the memory pointed to by mem into hex, placing result in buf */
679 /* return a pointer to the last char put in buf (null) */
680 char *
681 mem2hex (mem, buf, count)
682 char *mem;
683 char *buf;
684 int count;
685 {
686 int i;
687 unsigned char ch;
689 for (i = 0; i < count; i++)
690 {
691 ch = get_char (mem++);
692 *buf++ = hexchars[ch >> 4];
693 *buf++ = hexchars[ch % 16];
694 }
695 *buf = 0;
696 return (buf);
697 }
699 /* convert the hex array pointed to by buf into binary to be placed in mem */
700 /* return a pointer to the character AFTER the last byte written */
701 char *
702 hex2mem (buf, mem, count)
703 char *buf;
704 char *mem;
705 int count;
706 {
707 int i;
708 unsigned char ch;
710 for (i = 0; i < count; i++)
711 {
712 ch = hex (*buf++) << 4;
713 ch = ch + hex (*buf++);
714 set_char (mem++, ch);
715 }
716 return (mem);
717 }
719 int
720 hexToInt (char **ptr, int *intValue)
721 {
722 int numChars = 0;
723 int hexValue;
724 int negative = 0;
726 *intValue = 0;
728 if (**ptr == '-')
729 {
730 negative = 1;
731 numChars++;
732 (*ptr)++;
733 }
735 while (**ptr)
736 {
737 hexValue = hex (**ptr);
738 if (hexValue >= 0)
739 {
740 *intValue = (*intValue << 4) | hexValue;
741 numChars++;
742 }
743 else
744 break;
746 (*ptr)++;
747 }
749 if ( negative )
750 *intValue *= -1;
752 return (numChars);
753 }
755 /***********************************************************************/
756 /***********************************************************************/
759 /*
760 * Add a breakpoint to the list of known breakpoints.
761 * For now there should only be two or three breakpoints so
762 * we use a simple linked list. In the future, maybe a red-black tree?
763 */
764 struct pdb_breakpoint breakpoints;
766 void pdb_bkpt_add (unsigned long cr3, unsigned long address)
767 {
768 struct pdb_breakpoint *bkpt = xmalloc(sizeof(*bkpt));
769 bkpt->cr3 = cr3;
770 bkpt->address = address;
771 list_add(&bkpt->list, &breakpoints.list);
772 }
774 /*
775 * Check to see of the breakpoint is in the list of known breakpoints
776 * Return 1 if it has been set, NULL otherwise.
777 */
778 struct pdb_breakpoint* pdb_bkpt_search (unsigned long cr3,
779 unsigned long address)
780 {
781 struct list_head *list_entry;
782 struct pdb_breakpoint *bkpt;
784 list_for_each(list_entry, &breakpoints.list)
785 {
786 bkpt = list_entry(list_entry, struct pdb_breakpoint, list);
787 if ( bkpt->cr3 == cr3 && bkpt->address == address )
788 return bkpt;
789 }
791 return NULL;
792 }
794 /*
795 * Remove a breakpoint to the list of known breakpoints.
796 * Return 1 if the element was not found, otherwise 0.
797 */
798 int pdb_bkpt_remove (unsigned long cr3, unsigned long address)
799 {
800 struct list_head *list_entry;
801 struct pdb_breakpoint *bkpt;
803 list_for_each(list_entry, &breakpoints.list)
804 {
805 bkpt = list_entry(list_entry, struct pdb_breakpoint, list);
806 if ( bkpt->cr3 == cr3 && bkpt->address == address )
807 {
808 list_del(&bkpt->list);
809 xfree(bkpt);
810 return 0;
811 }
812 }
814 return 1;
815 }
817 /*
818 * Check to see if a memory write is really gdb setting a breakpoint
819 */
820 void pdb_bkpt_check (u_char *buffer, int length,
821 unsigned long cr3, unsigned long addr)
822 {
823 if (length == 1 && buffer[0] == 'c' && buffer[1] == 'c')
824 {
825 /* inserting a new breakpoint */
826 pdb_bkpt_add(cr3, addr);
827 TRC(printk("pdb breakpoint detected at 0x%lx:0x%lx\n", cr3, addr));
828 }
829 else if ( pdb_bkpt_remove(cr3, addr) == 0 )
830 {
831 /* removing a breakpoint */
832 TRC(printk("pdb breakpoint cleared at 0x%lx:0x%lx\n", cr3, addr));
833 }
834 }
836 /***********************************************************************/
838 int pdb_change_values(u_char *buffer, int length,
839 unsigned long cr3, unsigned long addr, int rw);
840 int pdb_change_values_one_page(u_char *buffer, int length,
841 unsigned long cr3, unsigned long addr, int rw);
843 #define __PDB_GET_VAL 1
844 #define __PDB_SET_VAL 2
846 /*
847 * Set memory in a domain's address space
848 * Set "length" bytes at "address" from "domain" to the values in "buffer".
849 * Return the number of bytes set, 0 if there was a problem.
850 */
852 int pdb_set_values(u_char *buffer, int length,
853 unsigned long cr3, unsigned long addr)
854 {
855 int count = pdb_change_values(buffer, length, cr3, addr, __PDB_SET_VAL);
856 return count;
857 }
859 /*
860 * Read memory from a domain's address space.
861 * Fetch "length" bytes at "address" from "domain" into "buffer".
862 * Return the number of bytes read, 0 if there was a problem.
863 */
865 int pdb_get_values(u_char *buffer, int length,
866 unsigned long cr3, unsigned long addr)
867 {
868 return pdb_change_values(buffer, length, cr3, addr, __PDB_GET_VAL);
869 }
871 /*
872 * Read or write memory in an address space
873 */
874 int pdb_change_values(u_char *buffer, int length,
875 unsigned long cr3, unsigned long addr, int rw)
876 {
877 int remaining; /* number of bytes to touch past this page */
878 int bytes = 0;
880 while ( (remaining = (addr + length - 1) - (addr | (PAGE_SIZE - 1))) > 0)
881 {
882 bytes += pdb_change_values_one_page(buffer, length - remaining,
883 cr3, addr, rw);
884 buffer = buffer + (2 * (length - remaining));
885 length = remaining;
886 addr = (addr | (PAGE_SIZE - 1)) + 1;
887 }
889 bytes += pdb_change_values_one_page(buffer, length, cr3, addr, rw);
890 return bytes;
891 }
893 /*
894 * Change memory in a process' address space in one page
895 * Read or write "length" bytes at "address" into/from "buffer"
896 * from the virtual address space referenced by "cr3".
897 * Return the number of bytes read, 0 if there was a problem.
898 */
900 int pdb_change_values_one_page(u_char *buffer, int length,
901 unsigned long cr3, unsigned long addr, int rw)
902 {
903 l2_pgentry_t* l2_table = NULL; /* page directory */
904 l1_pgentry_t* l1_table = NULL; /* page table */
905 u_char *page; /* 4k page */
906 int bytes = 0;
908 l2_table = map_domain_mem(cr3);
909 l2_table += l2_table_offset(addr);
910 if (!(l2_pgentry_val(*l2_table) & _PAGE_PRESENT))
911 {
912 if (pdb_page_fault_possible == 1)
913 {
914 pdb_page_fault = 1;
915 TRC(printk("pdb: L2 error (0x%lx)\n", addr));
916 }
917 else
918 {
919 printk ("pdb error: cr3: 0x%lx dom0cr3: 0x%lx\n", cr3,
920 dom0->mm.shadow_mode ? pagetable_val(dom0->mm.shadow_table)
921 : pagetable_val(dom0->mm.pagetable));
922 printk ("pdb error: L2:0x%p (0x%lx)\n",
923 l2_table, l2_pgentry_val(*l2_table));
924 }
925 goto exit2;
926 }
928 if (l2_pgentry_val(*l2_table) & _PAGE_PSE)
929 {
930 #define PSE_PAGE_SHIFT L2_PAGETABLE_SHIFT
931 #define PSE_PAGE_SIZE (1UL << PSE_PAGE_SHIFT)
932 #define PSE_PAGE_MASK (~(PSE_PAGE_SIZE-1))
934 #define L1_PAGE_BITS ( (ENTRIES_PER_L1_PAGETABLE - 1) << L1_PAGETABLE_SHIFT )
936 #define pse_pgentry_to_phys(_x) (l2_pgentry_val(_x) & PSE_PAGE_MASK)
938 page = map_domain_mem(pse_pgentry_to_phys(*l2_table) + /* 10 bits */
939 (addr & L1_PAGE_BITS)); /* 10 bits */
940 page += addr & (PAGE_SIZE - 1); /* 12 bits */
941 }
942 else
943 {
944 l1_table = map_domain_mem(l2_pgentry_to_phys(*l2_table));
945 l1_table += l1_table_offset(addr);
946 if (!(l1_pgentry_val(*l1_table) & _PAGE_PRESENT))
947 {
948 if (pdb_page_fault_possible == 1)
949 {
950 pdb_page_fault = 1;
951 TRC(printk ("pdb: L1 error (0x%lx)\n", addr));
952 }
953 else
954 {
955 printk ("L2:0x%p (0x%lx) L1:0x%p (0x%lx)\n",
956 l2_table, l2_pgentry_val(*l2_table),
957 l1_table, l1_pgentry_val(*l1_table));
958 }
959 goto exit1;
960 }
962 page = map_domain_mem(l1_pgentry_to_phys(*l1_table));
963 page += addr & (PAGE_SIZE - 1);
964 }
966 switch (rw)
967 {
968 case __PDB_GET_VAL: /* read */
969 memcpy (buffer, page, length);
970 bytes = length;
971 break;
972 case __PDB_SET_VAL: /* write */
973 hex2mem (buffer, page, length);
974 bytes = length;
975 break;
976 default: /* unknown */
977 printk ("error: unknown RW flag: %d\n", rw);
978 return 0;
979 }
981 unmap_domain_mem((void *)page);
982 exit1:
983 if (l1_table != NULL)
984 unmap_domain_mem((void *)l1_table);
985 exit2:
986 unmap_domain_mem((void *)l2_table);
988 return bytes;
989 }
991 /***********************************************************************/
993 void breakpoint(void);
995 /* send the packet in buffer. */
996 void pdb_put_packet (unsigned char *buffer, int ack)
997 {
998 unsigned char checksum;
999 int count;
1000 char ch;
1002 /* $<packet info>#<checksum> */
1003 /* do */
1005 pdb_put_char ('$');
1006 checksum = 0;
1007 count = 0;
1009 while ((ch = buffer[count]))
1011 pdb_put_char (ch);
1012 checksum += ch;
1013 count += 1;
1016 pdb_put_char('#');
1017 pdb_put_char(hexchars[checksum >> 4]);
1018 pdb_put_char(hexchars[checksum % 16]);
1021 if (ack)
1023 if ((ch = pdb_get_char()) != '+')
1025 printk(" pdb return error: %c 0x%x [%s]\n", ch, ch, buffer);
1030 void pdb_get_packet(char *buffer)
1032 int count;
1033 char ch;
1034 unsigned char checksum = 0;
1035 unsigned char xmitcsum = 0;
1037 do
1039 while ((ch = pdb_get_char()) != '$');
1041 count = 0;
1042 checksum = 0;
1044 while (count < BUFMAX)
1046 ch = pdb_get_char();
1047 if (ch == '#') break;
1048 checksum += ch;
1049 buffer[count] = ch;
1050 count++;
1052 buffer[count] = 0;
1054 if (ch == '#')
1056 xmitcsum = hex(pdb_get_char()) << 4;
1057 xmitcsum += hex(pdb_get_char());
1059 if (xmitcsum == checksum)
1061 pdb_put_char('+');
1062 if (buffer[2] == ':')
1064 printk ("pdb: obsolete gdb packet (sequence ID)\n");
1067 else
1069 pdb_put_char('-');
1072 } while (checksum != xmitcsum);
1074 return;
1077 /*
1078 * process a machine interrupt or exception
1079 * Return 1 if pdb is not interested in the exception; it should
1080 * be propagated to the guest os.
1081 */
1083 int pdb_handle_exception(int exceptionVector,
1084 struct xen_regs *xen_regs)
1086 int signal = 0;
1087 struct pdb_breakpoint* bkpt;
1088 int watchdog_save;
1089 unsigned long cr3 = read_cr3();
1091 /* No vm86 handling here as yet. */
1092 if ( VM86_MODE(xen_regs) )
1093 return 1;
1095 /* If the exception is an int3 from user space then pdb is only
1096 interested if it re-wrote an instruction set the breakpoint.
1097 This occurs when leaving a system call from a domain.
1098 */
1099 if ( (exceptionVector == 3) &&
1100 RING_3(xen_regs) &&
1101 (xen_regs->eip != (pdb_system_call_next_addr + 1)) )
1103 TRC(printf("pdb: user bkpt (0x%x) at 0x%x:0x%lx:0x%x\n",
1104 exceptionVector, xen_regs->cs & 3, cr3, xen_regs->eip));
1105 return 1;
1108 /*
1109 * If PDB didn't set the breakpoint, is not single stepping,
1110 * is not entering a system call in a domain,
1111 * the user didn't press the magic debug key,
1112 * then we don't handle the exception.
1113 */
1114 bkpt = pdb_bkpt_search(cr3, xen_regs->eip - 1);
1115 if ( (bkpt == NULL) &&
1116 !pdb_stepping &&
1117 !pdb_system_call &&
1118 xen_regs->eip != pdb_system_call_next_addr + 1 &&
1119 (exceptionVector != KEYPRESS_EXCEPTION) &&
1120 xen_regs->eip < 0xc0000000) /* Linux-specific for now! */
1122 TRC(printf("pdb: user bkpt (0x%x) at 0x%lx:0x%x\n",
1123 exceptionVector, cr3, xen_regs->eip));
1124 return 1;
1127 printk("pdb_handle_exception [0x%x][0x%lx:0x%x]\n",
1128 exceptionVector, cr3, xen_regs->eip);
1130 if ( pdb_stepping )
1132 /* Stepped one instruction; now return to normal execution. */
1133 xen_regs->eflags &= ~X86_EFLAGS_TF;
1134 pdb_stepping = 0;
1137 if ( pdb_system_call )
1139 pdb_system_call = 0;
1141 pdb_linux_syscall_exit_bkpt (xen_regs, &pdb_ctx);
1143 /* we don't have a saved breakpoint so we need to rewind eip */
1144 xen_regs->eip--;
1146 /* if ther user doesn't care about breaking when entering a
1147 system call then we'll just ignore the exception */
1148 if ( (pdb_ctx.system_call & 0x01) == 0 )
1150 return 0;
1154 if ( exceptionVector == BREAKPT_EXCEPTION && bkpt != NULL)
1156 /* Executed Int3: replace breakpoint byte with real program byte. */
1157 xen_regs->eip--;
1160 /* returning to user space after a system call */
1161 if ( xen_regs->eip == pdb_system_call_next_addr + 1)
1163 u_char instr[2]; /* REALLY REALLY REALLY STUPID */
1165 mem2hex (&pdb_system_call_leave_instr, instr, sizeof(instr));
1167 pdb_linux_set_values (instr, 1, pdb_system_call_next_addr,
1168 pdb_ctx.process, pdb_ctx.ptbr);
1170 pdb_system_call_next_addr = 0;
1171 pdb_system_call_leave_instr = 0;
1173 /* manually rewind eip */
1174 xen_regs->eip--;
1176 /* if the user doesn't care about breaking when returning
1177 to user space after a system call then we'll just ignore
1178 the exception */
1179 if ( (pdb_ctx.system_call & 0x02) == 0 )
1181 return 0;
1185 /* Generate a signal for GDB. */
1186 switch ( exceptionVector )
1188 case KEYPRESS_EXCEPTION:
1189 signal = 2; break; /* SIGINT */
1190 case DEBUG_EXCEPTION:
1191 signal = 5; break; /* SIGTRAP */
1192 case BREAKPT_EXCEPTION:
1193 signal = 5; break; /* SIGTRAP */
1194 default:
1195 printk("pdb: can't generate signal for unknown exception vector %d\n",
1196 exceptionVector);
1197 break;
1200 pdb_out_buffer[0] = 'S';
1201 pdb_out_buffer[1] = hexchars[signal >> 4];
1202 pdb_out_buffer[2] = hexchars[signal % 16];
1203 pdb_out_buffer[3] = 0;
1204 pdb_put_packet(pdb_out_buffer, 1);
1206 watchdog_save = watchdog_on;
1207 watchdog_on = 0;
1209 do {
1210 pdb_out_buffer[0] = 0;
1211 pdb_get_packet(pdb_in_buffer);
1213 while ( pdb_process_command(pdb_in_buffer, xen_regs, cr3, signal) == 0 );
1215 watchdog_on = watchdog_save;
1217 return 0;
1220 void pdb_key_pressed(unsigned char key)
1222 struct xen_regs *regs = (struct xen_regs *)get_execution_context();
1223 pdb_handle_exception(KEYPRESS_EXCEPTION, regs);
1226 void pdb_handle_debug_trap(struct xen_regs *regs, long error_code)
1228 unsigned int condition;
1229 struct domain *d = current;
1230 struct trap_bounce *tb = &d->thread.trap_bounce;
1232 __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
1233 if ( (condition & (1 << 14)) != (1 << 14) )
1234 printk("\nwarning: debug trap w/o BS bit [0x%x]\n\n", condition);
1235 __asm__("movl %0,%%db6" : : "r" (0));
1237 if ( pdb_handle_exception(1, regs) != 0 )
1239 d->thread.debugreg[6] = condition;
1241 tb->flags = TBF_EXCEPTION;
1242 tb->cs = d->thread.traps[1].cs;
1243 tb->eip = d->thread.traps[1].address;
1247 void initialize_pdb()
1249 /* Certain state must be initialised even when PDB will not be used. */
1250 memset((void *) &breakpoints, 0, sizeof(breakpoints));
1251 INIT_LIST_HEAD(&breakpoints.list);
1252 pdb_stepping = 0;
1254 if ( strcmp(opt_pdb, "none") == 0 )
1255 return;
1257 if ( (pdb_serhnd = parse_serial_handle(opt_pdb)) == -1 )
1259 printk("error: failed to initialize PDB on port %s\n", opt_pdb);
1260 return;
1263 pdb_ctx.valid = 1;
1264 pdb_ctx.domain = -1;
1265 pdb_ctx.process = -1;
1266 pdb_ctx.system_call = 0;
1267 pdb_ctx.ptbr = 0;
1269 printk("pdb: pervasive debugger (%s) www.cl.cam.ac.uk/netos/pdb\n",
1270 opt_pdb);
1272 /* Acknowledge any spurious GDB packets. */
1273 pdb_put_char('+');
1275 register_keyhandler('D', pdb_key_pressed, "enter pervasive debugger");
1277 pdb_initialized = 1;
1280 void breakpoint(void)
1282 if ( pdb_initialized )
1283 asm("int $3");