debuggers.hg

view xen/arch/x86/pdb-stub.c @ 3674:fb875591fd72

bitkeeper revision 1.1159.223.63 (42028527-fv-d9BM0_LRp8UKGP19gQ)

Fix NMI deferral.
Signed-off-by: keir.fraser@cl.cam.ac.uk
author kaf24@scramble.cl.cam.ac.uk
date Thu Feb 03 20:10:15 2005 +0000 (2005-02-03)
parents dee91b44a753
children 51052c8b6456 0dc3b8b8c298
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 pdb_breakpoint *bkpt;
783 list_for_each_entry ( bkpt, &breakpoints.list, list )
784 {
785 if ( bkpt->cr3 == cr3 && bkpt->address == address )
786 return bkpt;
787 }
789 return NULL;
790 }
792 /*
793 * Remove a breakpoint to the list of known breakpoints.
794 * Return 1 if the element was not found, otherwise 0.
795 */
796 int pdb_bkpt_remove (unsigned long cr3, unsigned long address)
797 {
798 struct pdb_breakpoint *bkpt;
800 list_for_each_entry ( bkpt, &breakpoints.list, list )
801 {
802 if ( bkpt->cr3 == cr3 && bkpt->address == address )
803 {
804 list_del(&bkpt->list);
805 xfree(bkpt);
806 return 0;
807 }
808 }
810 return 1;
811 }
813 /*
814 * Check to see if a memory write is really gdb setting a breakpoint
815 */
816 void pdb_bkpt_check (u_char *buffer, int length,
817 unsigned long cr3, unsigned long addr)
818 {
819 if (length == 1 && buffer[0] == 'c' && buffer[1] == 'c')
820 {
821 /* inserting a new breakpoint */
822 pdb_bkpt_add(cr3, addr);
823 TRC(printk("pdb breakpoint detected at 0x%lx:0x%lx\n", cr3, addr));
824 }
825 else if ( pdb_bkpt_remove(cr3, addr) == 0 )
826 {
827 /* removing a breakpoint */
828 TRC(printk("pdb breakpoint cleared at 0x%lx:0x%lx\n", cr3, addr));
829 }
830 }
832 /***********************************************************************/
834 int pdb_change_values(u_char *buffer, int length,
835 unsigned long cr3, unsigned long addr, int rw);
836 int pdb_change_values_one_page(u_char *buffer, int length,
837 unsigned long cr3, unsigned long addr, int rw);
839 #define __PDB_GET_VAL 1
840 #define __PDB_SET_VAL 2
842 /*
843 * Set memory in a domain's address space
844 * Set "length" bytes at "address" from "domain" to the values in "buffer".
845 * Return the number of bytes set, 0 if there was a problem.
846 */
848 int pdb_set_values(u_char *buffer, int length,
849 unsigned long cr3, unsigned long addr)
850 {
851 int count = pdb_change_values(buffer, length, cr3, addr, __PDB_SET_VAL);
852 return count;
853 }
855 /*
856 * Read memory from a domain's address space.
857 * Fetch "length" bytes at "address" from "domain" into "buffer".
858 * Return the number of bytes read, 0 if there was a problem.
859 */
861 int pdb_get_values(u_char *buffer, int length,
862 unsigned long cr3, unsigned long addr)
863 {
864 return pdb_change_values(buffer, length, cr3, addr, __PDB_GET_VAL);
865 }
867 /*
868 * Read or write memory in an address space
869 */
870 int pdb_change_values(u_char *buffer, int length,
871 unsigned long cr3, unsigned long addr, int rw)
872 {
873 int remaining; /* number of bytes to touch past this page */
874 int bytes = 0;
876 while ( (remaining = (addr + length - 1) - (addr | (PAGE_SIZE - 1))) > 0)
877 {
878 bytes += pdb_change_values_one_page(buffer, length - remaining,
879 cr3, addr, rw);
880 buffer = buffer + (2 * (length - remaining));
881 length = remaining;
882 addr = (addr | (PAGE_SIZE - 1)) + 1;
883 }
885 bytes += pdb_change_values_one_page(buffer, length, cr3, addr, rw);
886 return bytes;
887 }
889 /*
890 * Change memory in a process' address space in one page
891 * Read or write "length" bytes at "address" into/from "buffer"
892 * from the virtual address space referenced by "cr3".
893 * Return the number of bytes read, 0 if there was a problem.
894 */
896 int pdb_change_values_one_page(u_char *buffer, int length,
897 unsigned long cr3, unsigned long addr, int rw)
898 {
899 l2_pgentry_t* l2_table = NULL; /* page directory */
900 l1_pgentry_t* l1_table = NULL; /* page table */
901 u_char *page; /* 4k page */
902 int bytes = 0;
904 l2_table = map_domain_mem(cr3);
905 l2_table += l2_table_offset(addr);
906 if (!(l2_pgentry_val(*l2_table) & _PAGE_PRESENT))
907 {
908 if (pdb_page_fault_possible == 1)
909 {
910 pdb_page_fault = 1;
911 TRC(printk("pdb: L2 error (0x%lx)\n", addr));
912 }
913 else
914 {
915 printk ("pdb error: cr3: 0x%lx dom0cr3: 0x%lx\n", cr3,
916 dom0->mm.shadow_mode ? pagetable_val(dom0->mm.shadow_table)
917 : pagetable_val(dom0->mm.pagetable));
918 printk ("pdb error: L2:0x%p (0x%lx)\n",
919 l2_table, l2_pgentry_val(*l2_table));
920 }
921 goto exit2;
922 }
924 if (l2_pgentry_val(*l2_table) & _PAGE_PSE)
925 {
926 #define PSE_PAGE_SHIFT L2_PAGETABLE_SHIFT
927 #define PSE_PAGE_SIZE (1UL << PSE_PAGE_SHIFT)
928 #define PSE_PAGE_MASK (~(PSE_PAGE_SIZE-1))
930 #define L1_PAGE_BITS ( (ENTRIES_PER_L1_PAGETABLE - 1) << L1_PAGETABLE_SHIFT )
932 #define pse_pgentry_to_phys(_x) (l2_pgentry_val(_x) & PSE_PAGE_MASK)
934 page = map_domain_mem(pse_pgentry_to_phys(*l2_table) + /* 10 bits */
935 (addr & L1_PAGE_BITS)); /* 10 bits */
936 page += addr & (PAGE_SIZE - 1); /* 12 bits */
937 }
938 else
939 {
940 l1_table = map_domain_mem(l2_pgentry_to_phys(*l2_table));
941 l1_table += l1_table_offset(addr);
942 if (!(l1_pgentry_val(*l1_table) & _PAGE_PRESENT))
943 {
944 if (pdb_page_fault_possible == 1)
945 {
946 pdb_page_fault = 1;
947 TRC(printk ("pdb: L1 error (0x%lx)\n", addr));
948 }
949 else
950 {
951 printk ("L2:0x%p (0x%lx) L1:0x%p (0x%lx)\n",
952 l2_table, l2_pgentry_val(*l2_table),
953 l1_table, l1_pgentry_val(*l1_table));
954 }
955 goto exit1;
956 }
958 page = map_domain_mem(l1_pgentry_to_phys(*l1_table));
959 page += addr & (PAGE_SIZE - 1);
960 }
962 switch (rw)
963 {
964 case __PDB_GET_VAL: /* read */
965 memcpy (buffer, page, length);
966 bytes = length;
967 break;
968 case __PDB_SET_VAL: /* write */
969 hex2mem (buffer, page, length);
970 bytes = length;
971 break;
972 default: /* unknown */
973 printk ("error: unknown RW flag: %d\n", rw);
974 return 0;
975 }
977 unmap_domain_mem((void *)page);
978 exit1:
979 if (l1_table != NULL)
980 unmap_domain_mem((void *)l1_table);
981 exit2:
982 unmap_domain_mem((void *)l2_table);
984 return bytes;
985 }
987 /***********************************************************************/
989 void breakpoint(void);
991 /* send the packet in buffer. */
992 void pdb_put_packet (unsigned char *buffer, int ack)
993 {
994 unsigned char checksum;
995 int count;
996 char ch;
998 /* $<packet info>#<checksum> */
999 /* do */
1001 pdb_put_char ('$');
1002 checksum = 0;
1003 count = 0;
1005 while ((ch = buffer[count]))
1007 pdb_put_char (ch);
1008 checksum += ch;
1009 count += 1;
1012 pdb_put_char('#');
1013 pdb_put_char(hexchars[checksum >> 4]);
1014 pdb_put_char(hexchars[checksum % 16]);
1017 if (ack)
1019 if ((ch = pdb_get_char()) != '+')
1021 printk(" pdb return error: %c 0x%x [%s]\n", ch, ch, buffer);
1026 void pdb_get_packet(char *buffer)
1028 int count;
1029 char ch;
1030 unsigned char checksum = 0;
1031 unsigned char xmitcsum = 0;
1033 do
1035 while ((ch = pdb_get_char()) != '$');
1037 count = 0;
1038 checksum = 0;
1040 while (count < BUFMAX)
1042 ch = pdb_get_char();
1043 if (ch == '#') break;
1044 checksum += ch;
1045 buffer[count] = ch;
1046 count++;
1048 buffer[count] = 0;
1050 if (ch == '#')
1052 xmitcsum = hex(pdb_get_char()) << 4;
1053 xmitcsum += hex(pdb_get_char());
1055 if (xmitcsum == checksum)
1057 pdb_put_char('+');
1058 if (buffer[2] == ':')
1060 printk ("pdb: obsolete gdb packet (sequence ID)\n");
1063 else
1065 pdb_put_char('-');
1068 } while (checksum != xmitcsum);
1070 return;
1073 /*
1074 * process a machine interrupt or exception
1075 * Return 1 if pdb is not interested in the exception; it should
1076 * be propagated to the guest os.
1077 */
1079 int pdb_handle_exception(int exceptionVector,
1080 struct xen_regs *xen_regs)
1082 int signal = 0;
1083 struct pdb_breakpoint* bkpt;
1084 int watchdog_save;
1085 unsigned long cr3 = read_cr3();
1087 /* No vm86 handling here as yet. */
1088 if ( VM86_MODE(xen_regs) )
1089 return 1;
1091 /* If the exception is an int3 from user space then pdb is only
1092 interested if it re-wrote an instruction set the breakpoint.
1093 This occurs when leaving a system call from a domain.
1094 */
1095 if ( (exceptionVector == 3) &&
1096 RING_3(xen_regs) &&
1097 (xen_regs->eip != (pdb_system_call_next_addr + 1)) )
1099 TRC(printf("pdb: user bkpt (0x%x) at 0x%x:0x%lx:0x%x\n",
1100 exceptionVector, xen_regs->cs & 3, cr3, xen_regs->eip));
1101 return 1;
1104 /*
1105 * If PDB didn't set the breakpoint, is not single stepping,
1106 * is not entering a system call in a domain,
1107 * the user didn't press the magic debug key,
1108 * then we don't handle the exception.
1109 */
1110 bkpt = pdb_bkpt_search(cr3, xen_regs->eip - 1);
1111 if ( (bkpt == NULL) &&
1112 !pdb_stepping &&
1113 !pdb_system_call &&
1114 xen_regs->eip != pdb_system_call_next_addr + 1 &&
1115 (exceptionVector != KEYPRESS_EXCEPTION) &&
1116 xen_regs->eip < 0xc0000000) /* Linux-specific for now! */
1118 TRC(printf("pdb: user bkpt (0x%x) at 0x%lx:0x%x\n",
1119 exceptionVector, cr3, xen_regs->eip));
1120 return 1;
1123 printk("pdb_handle_exception [0x%x][0x%lx:0x%x]\n",
1124 exceptionVector, cr3, xen_regs->eip);
1126 if ( pdb_stepping )
1128 /* Stepped one instruction; now return to normal execution. */
1129 xen_regs->eflags &= ~X86_EFLAGS_TF;
1130 pdb_stepping = 0;
1133 if ( pdb_system_call )
1135 pdb_system_call = 0;
1137 pdb_linux_syscall_exit_bkpt (xen_regs, &pdb_ctx);
1139 /* we don't have a saved breakpoint so we need to rewind eip */
1140 xen_regs->eip--;
1142 /* if ther user doesn't care about breaking when entering a
1143 system call then we'll just ignore the exception */
1144 if ( (pdb_ctx.system_call & 0x01) == 0 )
1146 return 0;
1150 if ( exceptionVector == BREAKPT_EXCEPTION && bkpt != NULL)
1152 /* Executed Int3: replace breakpoint byte with real program byte. */
1153 xen_regs->eip--;
1156 /* returning to user space after a system call */
1157 if ( xen_regs->eip == pdb_system_call_next_addr + 1)
1159 u_char instr[2]; /* REALLY REALLY REALLY STUPID */
1161 mem2hex (&pdb_system_call_leave_instr, instr, sizeof(instr));
1163 pdb_linux_set_values (instr, 1, pdb_system_call_next_addr,
1164 pdb_ctx.process, pdb_ctx.ptbr);
1166 pdb_system_call_next_addr = 0;
1167 pdb_system_call_leave_instr = 0;
1169 /* manually rewind eip */
1170 xen_regs->eip--;
1172 /* if the user doesn't care about breaking when returning
1173 to user space after a system call then we'll just ignore
1174 the exception */
1175 if ( (pdb_ctx.system_call & 0x02) == 0 )
1177 return 0;
1181 /* Generate a signal for GDB. */
1182 switch ( exceptionVector )
1184 case KEYPRESS_EXCEPTION:
1185 signal = 2; break; /* SIGINT */
1186 case DEBUG_EXCEPTION:
1187 signal = 5; break; /* SIGTRAP */
1188 case BREAKPT_EXCEPTION:
1189 signal = 5; break; /* SIGTRAP */
1190 default:
1191 printk("pdb: can't generate signal for unknown exception vector %d\n",
1192 exceptionVector);
1193 break;
1196 pdb_out_buffer[0] = 'S';
1197 pdb_out_buffer[1] = hexchars[signal >> 4];
1198 pdb_out_buffer[2] = hexchars[signal % 16];
1199 pdb_out_buffer[3] = 0;
1200 pdb_put_packet(pdb_out_buffer, 1);
1202 watchdog_save = watchdog_on;
1203 watchdog_on = 0;
1205 do {
1206 pdb_out_buffer[0] = 0;
1207 pdb_get_packet(pdb_in_buffer);
1209 while ( pdb_process_command(pdb_in_buffer, xen_regs, cr3, signal) == 0 );
1211 watchdog_on = watchdog_save;
1213 return 0;
1216 void pdb_key_pressed(unsigned char key)
1218 struct xen_regs *regs = (struct xen_regs *)get_execution_context();
1219 pdb_handle_exception(KEYPRESS_EXCEPTION, regs);
1222 void pdb_handle_debug_trap(struct xen_regs *regs, long error_code)
1224 unsigned int condition;
1225 struct domain *d = current;
1226 struct trap_bounce *tb = &d->thread.trap_bounce;
1228 __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
1229 if ( (condition & (1 << 14)) != (1 << 14) )
1230 printk("\nwarning: debug trap w/o BS bit [0x%x]\n\n", condition);
1231 __asm__("movl %0,%%db6" : : "r" (0));
1233 if ( pdb_handle_exception(1, regs) != 0 )
1235 d->thread.debugreg[6] = condition;
1237 tb->flags = TBF_EXCEPTION;
1238 tb->cs = d->thread.traps[1].cs;
1239 tb->eip = d->thread.traps[1].address;
1243 void initialize_pdb()
1245 /* Certain state must be initialised even when PDB will not be used. */
1246 memset((void *) &breakpoints, 0, sizeof(breakpoints));
1247 INIT_LIST_HEAD(&breakpoints.list);
1248 pdb_stepping = 0;
1250 if ( strcmp(opt_pdb, "none") == 0 )
1251 return;
1253 if ( (pdb_serhnd = parse_serial_handle(opt_pdb)) == -1 )
1255 printk("error: failed to initialize PDB on port %s\n", opt_pdb);
1256 return;
1259 pdb_ctx.valid = 1;
1260 pdb_ctx.domain = -1;
1261 pdb_ctx.process = -1;
1262 pdb_ctx.system_call = 0;
1263 pdb_ctx.ptbr = 0;
1265 printk("pdb: pervasive debugger (%s) www.cl.cam.ac.uk/netos/pdb\n",
1266 opt_pdb);
1268 /* Acknowledge any spurious GDB packets. */
1269 pdb_put_char('+');
1271 register_keyhandler('D', pdb_key_pressed, "enter pervasive debugger");
1273 pdb_initialized = 1;
1276 void breakpoint(void)
1278 if ( pdb_initialized )
1279 asm("int $3");