PERFORCE change 30481 for review
Marcel Moolenaar
marcel at FreeBSD.org
Sat May 3 15:13:00 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=30481
Change 30481 by marcel at marcel_nfs on 2003/05/03 15:12:53
Get i386 to compile again. MD support functions for GDB
support have been put in db_interface.c. This should have
the MI framework mostly in good shape. The only real
hardcoding is in the first packet: we assume there's a
PC, FP and SP. Porting the other architectures should make
it clear whether we can get away with it or not. I'll
cross that bridge when I come to it.
Affected files ...
.. //depot/projects/sio/sys/ddb/db_gdb.c#2 edit
.. //depot/projects/sio/sys/i386/i386/db_interface.c#3 edit
.. //depot/projects/sio/sys/i386/include/db_machdep.h#3 edit
Differences ...
==== //depot/projects/sio/sys/ddb/db_gdb.c#2 (text+ko) ====
@@ -224,6 +224,94 @@
static int encdecsz;
static __inline void
+gdb_dec_begin(char *buf, int size)
+{
+ encdecp = buf;
+ encdecsz = size;
+}
+
+static __inline int
+gdb_dec_char(void)
+{
+ int c;
+ if (encdecsz > 0) {
+ c = *encdecp++;
+ encdecsz--;
+ } else
+ c = -1;
+ return (c);
+}
+
+static __inline int
+gdb_dec_int8(void)
+{
+ int h, l;
+ h = gdb_hex(gdb_dec_char());
+ l = gdb_hex(gdb_dec_char());
+ if (h != -1 && l != -1)
+ return ((h << 4) | (l & 0xf));
+ else
+ return (-1);
+}
+
+static __inline int
+gdb_dec_int16(void)
+{
+ int h, l;
+ h = gdb_dec_int8();
+ l = gdb_dec_int8();
+ if (h != -1 && l != -1)
+ return ((h << 8) | (l & 0xff));
+ else
+ return (-1);
+}
+
+static __inline int32_t
+gdb_dec_int32(void)
+{
+ int32_t h, l;
+ h = gdb_dec_int16();
+ l = gdb_dec_int16();
+ if (h != -1 && l != -1)
+ return ((h << 16) | (l & 0xffff));
+ else
+ return (-1);
+}
+
+static __inline uint64_t
+gdb_dec_int64(void)
+{
+ int64_t h, l;
+ h = gdb_dec_int32();
+ l = gdb_dec_int32();
+ if (h != -1 && l != -1)
+ return ((h << 32) | (l & 0xffffffff));
+ else
+ return (-1);
+}
+
+static __inline int
+gdb_dec_block(gdb_addr addr, int len)
+{
+ uint8_t *p = (void*)(intptr_t)addr;
+ int c;
+ while (len > 0) {
+ c = gdb_dec_int8();
+ if (c == -1)
+ return (-1);
+ *p++ = c;
+ len--;
+ }
+ return 0;
+}
+
+static __inline int
+gdb_dec_registers(struct gdb_registers *regs)
+{
+ return (gdb_dec_block((intptr_t)regs, sizeof(*regs)));
+}
+
+static __inline void
gdb_enc_begin(char *buf, int size)
{
encdecp = buf;
@@ -280,6 +368,20 @@
gdb_enc_int32(i & 0xffffffff);
}
+static __inline void
+gdb_enc_block(gdb_addr addr, int len)
+{
+ uint8_t *p = (void*)(intptr_t)addr;
+ while (len > 0)
+ gdb_enc_int8(*p++), len--;
+}
+
+static __inline void
+gdb_enc_registers(struct gdb_registers *regs)
+{
+ gdb_enc_block((intptr_t)regs, sizeof(*regs));
+}
+
/*
* gdb_handle_exception
*
@@ -327,8 +429,12 @@
int
gdb_handle_exception(db_regs_t *raw_regs, int type)
{
- char *ptr;
- int addr, error, length, regno;
+ struct gdb_registers regs;
+ gdb_addr addr;
+ gdb_reg reg;
+ int c, error, len, regno;
+
+ gdb_getregs(®s, raw_regs);
/* "TxxPC:xxxxxxxx;FP:xxxxxxxx;SP:xxxxxxxx;" */
gdb_enc_begin(gdb_buffer, sizeof(gdb_buffer));
@@ -336,19 +442,18 @@
gdb_enc_int8(gdb_signal(type));
gdb_enc_int8(GDB_REGNUM_PC);
gdb_enc_char(':');
- gdb_enc_register(raw_regs->eip);
+ gdb_enc_reg(gdb_getreg(®s, GDB_REGNUM_PC));
gdb_enc_char(';');
gdb_enc_int8(GDB_REGNUM_FP);
gdb_enc_char(':');
- gdb_enc_register(raw_regs->ebp);
+ gdb_enc_reg(gdb_getreg(®s, GDB_REGNUM_FP));
gdb_enc_char(';');
gdb_enc_int8(GDB_REGNUM_SP);
gdb_enc_char(':');
- gdb_enc_register(raw_regs->esp);
+ gdb_enc_reg(gdb_getreg(®s, GDB_REGNUM_SP));
gdb_enc_char(';');
- error = gdb_enc_end();
- if (!error)
- error = gdb_putpacket(gdb_buffer);
+ gdb_enc_end();
+ error = gdb_putpacket(gdb_buffer);
if (error)
return (error);
@@ -356,7 +461,8 @@
error = gdb_getpacket(gdb_buffer);
if (error)
return (error);
- switch (*gdb_buffer) {
+ gdb_dec_begin(gdb_buffer, sizeof(gdb_buffer));
+ switch (gdb_dec_char()) {
case '?':
gdb_enc_begin(gdb_buffer, sizeof(gdb_buffer));
gdb_enc_char('S');
@@ -373,25 +479,25 @@
case 'g':
/* Return the value of the CPU registers */
- mem2hex((vm_offset_t)®isters, gdb_buffer,
- NUMREGBYTES);
+ gdb_enc_begin(gdb_buffer, sizeof(gdb_buffer));
+ gdb_enc_registers(®s);
+ gdb_enc_end();
gdb_putpacket(gdb_buffer);
break;
case 'G':
/* Set the value of the CPU registers - return OK */
- hex2mem(gdb_buffer + 1, (vm_offset_t)®isters,
- NUMREGBYTES);
+ gdb_dec_registers(®s);
gdb_putpacket("OK");
break;
case 'P':
/* Set the value of one register */
- ptr = gdb_buffer + 1;
- if (hexToInt(&ptr, ®no) && *ptr++ == '=' &&
- regno < NUM_REGS) {
- hex2mem(ptr,
- (vm_offset_t)®isters + regno * 4, 4);
+ regno = gdb_dec_int32();
+ c = gdb_dec_char();
+ reg = gdb_dec_reg();
+ if (regno > 0 && c == '=') {
+ gdb_setreg(®s, regno, reg);
gdb_putpacket("OK");
} else
gdb_putpacket("P01");
@@ -400,15 +506,15 @@
case 'm':
/* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
/* Try to read %x,%x. */
- ptr = gdb_buffer + 1;
- if (hexToInt(&ptr, &addr) && *(ptr++) == ',' &&
- hexToInt (&ptr, &length)) {
- if (mem2hex((vm_offset_t)addr,
- gdb_buffer, length) == NULL)
- gdb_putpacket("E03");
- else
- gdb_putpacket(gdb_buffer);
- break;
+ addr = gdb_dec_addr();
+ c = gdb_dec_char();
+ len = gdb_dec_int32();
+ if (c == ',' && len > 0) {
+ gdb_enc_begin(gdb_buffer, sizeof(gdb_buffer));
+ gdb_enc_block(addr, len);
+ gdb_enc_end();
+ gdb_putpacket(gdb_buffer);
+ /* XXX return "E03" when encoding fails. */
} else
gdb_putpacket("E01");
break;
@@ -417,31 +523,34 @@
/* MAA..AA,LLLL: Write LLLL bytes at address AA.AA */
/* return OK */
/* Try to read '%x,%x:'. */
- ptr = gdb_buffer + 1;
- if (hexToInt(&ptr,&addr) && *(ptr++) == ',' &&
- hexToInt(&ptr, &length) && *(ptr++) == ':') {
- if (hex2mem(ptr, (vm_offset_t)addr, length)
- == NULL)
- gdb_putpacket("E03");
- else
- gdb_putpacket("OK");
+ addr = gdb_dec_addr();
+ c = gdb_dec_char();
+ len = gdb_dec_int32();
+ if (c == ',' && len > 0 && gdb_dec_char() == ':') {
+ gdb_dec_block(addr, len);
+ gdb_putpacket("OK");
+ /* XXX return "E03" when decoding fails. */
} else
gdb_putpacket("E02");
break;
case 'c' :
/* cAA..AA Continue at address AA..AA (opt) */
- /* FALLTHROUGH */
+ gdb_singlestep(®s, 0);
+ addr = gdb_dec_addr();
+ if (addr != ~0U)
+ gdb_setreg(®s, GDB_REGNUM_PC, addr);
+ gdb_setregs(®s, raw_regs);
+ return (0);
+
case 's' :
/* sAA..AA Step one instruction from AA..AA (opt) */
- gdb_cpu_set_regs(®s);
- /* try to read optional parameter */
- ptr = gdb_buffer + 1;
- if (hexToInt(&ptr,&addr))
- gdb_cpu_set_pc(addr);
- /* set the trace bit if we're stepping */
- gdb_cpu_singlestep((*gdb_buffer == 's') ? 1 : 0);
- return 0;
+ gdb_singlestep(®s, 1);
+ addr = gdb_dec_addr();
+ if (addr != ~0U)
+ gdb_setreg(®s, GDB_REGNUM_PC, addr);
+ gdb_setregs(®s, raw_regs);
+ return (0);
} /* switch */
}
==== //depot/projects/sio/sys/i386/i386/db_interface.c#3 (text+ko) ====
@@ -303,6 +303,100 @@
}
}
+int
+gdb_signal(int vector)
+{
+ switch (vector & ~T_USER) {
+ case 0: return (SIGFPE); /* divide by zero */
+ case 1: return (SIGTRAP); /* debug exception */
+ case 3: return (SIGTRAP); /* breakpoint */
+ case 4: return (SIGURG); /* into instr (overflow) */
+ case 5: return (SIGURG); /* bound instruction */
+ case 6: return (SIGILL); /* Invalid opcode */
+ case 7: return (SIGFPE); /* npx not available */
+ case 8: return (SIGEMT); /* double fault */
+ case 9: return (SIGSEGV); /* npx segment overrun */
+ case 10: return (SIGTRAP); /* Invalid TSS (also single-step) */
+ case 11: return (SIGSEGV); /* Segment not present */
+ case 12: return (SIGSEGV); /* stack exception */
+ case 13: return (SIGSEGV); /* general protection */
+ case 14: return (SIGSEGV); /* page fault */
+ case 16: return (SIGEMT); /* coprocessor error */
+ }
+ return (SIGEMT);
+}
+
+gdb_reg
+gdb_getreg(struct gdb_registers *regs, int regnum)
+{
+ gdb_reg *regp;
+
+ regp = (void*)regs;
+ if ((void*)(regp + regnum) < (void*)(regs + 1))
+ return (regp[regnum]);
+ /* XXX complain. */
+ return (~0);
+}
+
+void
+gdb_setreg(struct gdb_registers *regs, int regnum, gdb_reg val)
+{
+ gdb_reg *regp;
+
+ regp = (void*)regs;
+ if ((void*)(regp + regnum) < (void*)(regs + 1))
+ regp[regnum] = val;
+}
+
+void
+gdb_getregs(struct gdb_registers *regs, db_regs_t *raw_regs)
+{
+
+ regs->eax = raw_regs->tf_eax;
+ regs->ebx = raw_regs->tf_ebx;
+ regs->ecx = raw_regs->tf_ecx;
+ regs->edx = raw_regs->tf_edx;
+ regs->esp = raw_regs->tf_esp;
+ regs->ebp = raw_regs->tf_ebp;
+ regs->esi = raw_regs->tf_esi;
+ regs->edi = raw_regs->tf_edi;
+ regs->eip = raw_regs->tf_eip;
+ regs->eflags = raw_regs->tf_eflags;
+ regs->cs = raw_regs->tf_cs;
+ regs->ss = raw_regs->tf_ss;
+ regs->ds = raw_regs->tf_ds;
+ regs->es = raw_regs->tf_es;
+}
+
+void
+gdb_setregs(struct gdb_registers *regs, db_regs_t *raw_regs)
+{
+
+ raw_regs->tf_eax = regs->eax;
+ raw_regs->tf_ebx = regs->ebx;
+ raw_regs->tf_ecx = regs->ecx;
+ raw_regs->tf_edx = regs->edx;
+ raw_regs->tf_esp = regs->esp;
+ raw_regs->tf_ebp = regs->ebp;
+ raw_regs->tf_esi = regs->esi;
+ raw_regs->tf_edi = regs->edi;
+ raw_regs->tf_eip = regs->eip;
+ raw_regs->tf_eflags = regs->eflags;
+ raw_regs->tf_cs = regs->cs;
+ raw_regs->tf_ss = regs->ss;
+ raw_regs->tf_ds = regs->ds;
+ raw_regs->tf_es = regs->es;
+}
+
+void
+gdb_singlestep(struct gdb_registers *regs, int set)
+{
+ if (set)
+ regs->eflags |= PSL_T;
+ else
+ regs->eflags &= ~PSL_T;
+}
+
/*
* XXX
* Move this to machdep.c and allow it to be called if any debugger is
==== //depot/projects/sio/sys/i386/include/db_machdep.h#3 (text+ko) ====
@@ -97,9 +97,35 @@
#define GDB_REGNUM_FP 5
#define GDB_REGNUM_PC 8
-/* What size are registers? */
-#define gdb_enc_register gdb_enc_int32
+typedef uint32_t gdb_reg;
+typedef uint32_t gdb_addr;
+
+#define gdb_dec_addr gdb_dec_int32
+#define gdb_dec_reg gdb_dec_int32
+#define gdb_enc_reg gdb_enc_int32
+
+struct gdb_registers {
+ gdb_reg eax;
+ gdb_reg ecx;
+ gdb_reg edx;
+ gdb_reg ebx;
+ gdb_reg esp;
+ gdb_reg ebp;
+ gdb_reg esi;
+ gdb_reg edi;
+ gdb_reg eip;
+ gdb_reg eflags;
+ gdb_reg cs;
+ gdb_reg ss;
+ gdb_reg ds;
+ gdb_reg es;
+};
-int gdb_signal(int);
+gdb_reg gdb_getreg(struct gdb_registers *, int);
+void gdb_getregs(struct gdb_registers *, db_regs_t *);
+void gdb_setreg(struct gdb_registers *, int, gdb_reg);
+void gdb_setregs(struct gdb_registers *, db_regs_t *);
+void gdb_singlestep(struct gdb_registers *, int);
+int gdb_signal(int);
#endif /* !_MACHINE_DB_MACHDEP_H_ */
More information about the p4-projects
mailing list