]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - kernel/debug/gdbstub.c
kgdb,kdb: individual register set and and get API
[net-next-2.6.git] / kernel / debug / gdbstub.c
index 4b17b32695259060260f9748d2c51490397c4888..006bad8905d395585ca8134e05678f2c815e07f1 100644 (file)
@@ -52,17 +52,6 @@ static unsigned long         gdb_regs[(NUMREGBYTES +
  * GDB remote protocol parser:
  */
 
-static int hex(char ch)
-{
-       if ((ch >= 'a') && (ch <= 'f'))
-               return ch - 'a' + 10;
-       if ((ch >= '0') && (ch <= '9'))
-               return ch - '0';
-       if ((ch >= 'A') && (ch <= 'F'))
-               return ch - 'A' + 10;
-       return -1;
-}
-
 #ifdef CONFIG_KGDB_KDB
 static int gdbstub_read_wait(void)
 {
@@ -123,8 +112,8 @@ static void get_packet(char *buffer)
                buffer[count] = 0;
 
                if (ch == '#') {
-                       xmitcsum = hex(gdbstub_read_wait()) << 4;
-                       xmitcsum += hex(gdbstub_read_wait());
+                       xmitcsum = hex_to_bin(gdbstub_read_wait()) << 4;
+                       xmitcsum += hex_to_bin(gdbstub_read_wait());
 
                        if (checksum != xmitcsum)
                                /* failed checksum */
@@ -280,8 +269,8 @@ int kgdb_hex2mem(char *buf, char *mem, int count)
        tmp_hex = tmp_raw - 1;
        while (tmp_hex >= buf) {
                tmp_raw--;
-               *tmp_raw = hex(*tmp_hex--);
-               *tmp_raw |= hex(*tmp_hex--) << 4;
+               *tmp_raw = hex_to_bin(*tmp_hex--);
+               *tmp_raw |= hex_to_bin(*tmp_hex--) << 4;
        }
 
        return probe_kernel_write(mem, tmp_raw, count);
@@ -304,7 +293,7 @@ int kgdb_hex2long(char **ptr, unsigned long *long_val)
                (*ptr)++;
        }
        while (**ptr) {
-               hex_val = hex(**ptr);
+               hex_val = hex_to_bin(**ptr);
                if (hex_val < 0)
                        break;
 
@@ -339,6 +328,32 @@ static int kgdb_ebin2mem(char *buf, char *mem, int count)
        return probe_kernel_write(mem, c, size);
 }
 
+#if DBG_MAX_REG_NUM > 0
+void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+       int i;
+       int idx = 0;
+       char *ptr = (char *)gdb_regs;
+
+       for (i = 0; i < DBG_MAX_REG_NUM; i++) {
+               dbg_get_reg(i, ptr + idx, regs);
+               idx += dbg_reg_def[i].size;
+       }
+}
+
+void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
+{
+       int i;
+       int idx = 0;
+       char *ptr = (char *)gdb_regs;
+
+       for (i = 0; i < DBG_MAX_REG_NUM; i++) {
+               dbg_set_reg(i, ptr + idx, regs);
+               idx += dbg_reg_def[i].size;
+       }
+}
+#endif /* DBG_MAX_REG_NUM > 0 */
+
 /* Write memory due to an 'M' or 'X' packet. */
 static int write_mem_msg(int binary)
 {
@@ -378,28 +393,31 @@ static void error_packet(char *pkt, int error)
  * remapped to negative TIDs.
  */
 
-#define BUF_THREAD_ID_SIZE     16
+#define BUF_THREAD_ID_SIZE     8
 
 static char *pack_threadid(char *pkt, unsigned char *id)
 {
-       char *limit;
+       unsigned char *limit;
+       int lzero = 1;
+
+       limit = id + (BUF_THREAD_ID_SIZE / 2);
+       while (id < limit) {
+               if (!lzero || *id != 0) {
+                       pkt = pack_hex_byte(pkt, *id);
+                       lzero = 0;
+               }
+               id++;
+       }
 
-       limit = pkt + BUF_THREAD_ID_SIZE;
-       while (pkt < limit)
-               pkt = pack_hex_byte(pkt, *id++);
+       if (lzero)
+               pkt = pack_hex_byte(pkt, 0);
 
        return pkt;
 }
 
 static void int_to_threadref(unsigned char *id, int value)
 {
-       unsigned char *scan;
-       int i = 4;
-
-       scan = (unsigned char *)id;
-       while (i--)
-               *scan++ = 0;
-       put_unaligned_be32(value, scan);
+       put_unaligned_be32(value, id);
 }
 
 static struct task_struct *getthread(struct pt_regs *regs, int tid)
@@ -612,7 +630,7 @@ static void gdb_cmd_query(struct kgdb_state *ks)
 {
        struct task_struct *g;
        struct task_struct *p;
-       unsigned char thref[8];
+       unsigned char thref[BUF_THREAD_ID_SIZE];
        char *ptr;
        int i;
        int cpu;
@@ -621,10 +639,8 @@ static void gdb_cmd_query(struct kgdb_state *ks)
        switch (remcom_in_buffer[1]) {
        case 's':
        case 'f':
-               if (memcmp(remcom_in_buffer + 2, "ThreadInfo", 10)) {
-                       error_packet(remcom_out_buffer, -EINVAL);
+               if (memcmp(remcom_in_buffer + 2, "ThreadInfo", 10))
                        break;
-               }
 
                i = 0;
                remcom_out_buffer[0] = 'm';
@@ -634,8 +650,7 @@ static void gdb_cmd_query(struct kgdb_state *ks)
                        for_each_online_cpu(cpu) {
                                ks->thr_query = 0;
                                int_to_threadref(thref, -cpu - 2);
-                               pack_threadid(ptr, thref);
-                               ptr += BUF_THREAD_ID_SIZE;
+                               ptr = pack_threadid(ptr, thref);
                                *(ptr++) = ',';
                                i++;
                        }
@@ -644,8 +659,7 @@ static void gdb_cmd_query(struct kgdb_state *ks)
                do_each_thread(g, p) {
                        if (i >= ks->thr_query && !finished) {
                                int_to_threadref(thref, p->pid);
-                               pack_threadid(ptr, thref);
-                               ptr += BUF_THREAD_ID_SIZE;
+                               ptr = pack_threadid(ptr, thref);
                                *(ptr++) = ',';
                                ks->thr_query++;
                                if (ks->thr_query % KGDB_MAX_THREAD_QUERY == 0)
@@ -665,10 +679,9 @@ static void gdb_cmd_query(struct kgdb_state *ks)
                pack_threadid(remcom_out_buffer + 2, thref);
                break;
        case 'T':
-               if (memcmp(remcom_in_buffer + 1, "ThreadExtraInfo,", 16)) {
-                       error_packet(remcom_out_buffer, -EINVAL);
+               if (memcmp(remcom_in_buffer + 1, "ThreadExtraInfo,", 16))
                        break;
-               }
+
                ks->threadid = 0;
                ptr = remcom_in_buffer + 17;
                kgdb_hex2long(&ptr, &ks->threadid);
@@ -865,7 +878,7 @@ int gdb_serial_stub(struct kgdb_state *ks)
        memset(remcom_out_buffer, 0, sizeof(remcom_out_buffer));
 
        if (kgdb_connected) {
-               unsigned char thref[8];
+               unsigned char thref[BUF_THREAD_ID_SIZE];
                char *ptr;
 
                /* Reply to host that an exception has occurred */