gdbserver am33(松下芯片)补丁

来源:互联网 发布:广西广电网络设置上网 编辑:程序博客网 时间:2024/05/16 00:25

以下是我去年对gdb-6.8做gdbserver的补丁,用于支持松下am33。供有兴趣的人员参考。

 

 

<pre>

 

 

diff -ruN gdb-6.8.orig/bfd/elf.c gdb-6.8/bfd/elf.c

--- gdb-6.8.orig/bfd/elf.c2008-02-18 07:45:23.000000000 +0800

+++ gdb-6.8/bfd/elf.c2009-08-24 10:39:21.000000000 +0800

@@ -921,6 +921,7 @@

      PT_NOTEs from the core files are currently not parsed using BFD.  */

   if (hdr->sh_type == SHT_NOTE)

     {

+/* 2009-08-23/zhanzh: http://sourceware.org/ml/binutils/2008-07/msg00331.html

       char *contents;

 

       contents = bfd_malloc (hdr->sh_size);

@@ -934,7 +935,15 @@

   free (contents);

   return FALSE;

 }

-      

+*/

+

+      bfd_byte *contents;

+      if (!bfd_malloc_and_get_section (abfd, newsect, &contents))

+ return FALSE;

+      elf_parse_notes (abfd, (char *) contents, hdr->sh_size, -1);

+

       free (contents);

     }

 

@@ -8473,14 +8482,26 @@

       Elf_External_Note *xnp = (Elf_External_Note *) p;

       Elf_Internal_Note in;

 

+/* 2009-08-23/zhanzh: http://sourceware.org/ml/binutils/2008-07/msg00331.html */

+      if (offsetof (Elf_External_Note, name) > buf - p + size)

+return FALSE;

+

       in.type = H_GET_32 (abfd, xnp->type);

 

       in.namesz = H_GET_32 (abfd, xnp->namesz);

       in.namedata = xnp->name;

+/* 2009-08-23/zhanzh: http://sourceware.org/ml/binutils/2008-07/msg00331.html */

+      if (in.namesz > buf - in.namedata + size)

+return FALSE;

 

       in.descsz = H_GET_32 (abfd, xnp->descsz);

       in.descdata = in.namedata + BFD_ALIGN (in.namesz, 4);

       in.descpos = offset + (in.descdata - buf);

+/* 2009-08-23/zhanzh: http://sourceware.org/ml/binutils/2008-07/msg00331.html */

+      if (in.descsz != 0

+  && (in.descdata >= buf + size

+      || in.descsz > buf - in.descdata + size))

+return FALSE;

 

       switch (bfd_get_format (abfd))

         {

diff -ruN gdb-6.8.orig/gdb/gdbserver/configure.srv gdb-6.8/gdb/gdbserver/configure.srv

--- gdb-6.8.orig/gdb/gdbserver/configure.srv2008-02-12 06:00:31.000000000 +0800

+++ gdb-6.8/gdb/gdbserver/configure.srv2009-07-02 15:09:29.000000000 +0800

@@ -26,6 +26,12 @@

 # Input is taken from the "${target}" variable.

 

 case "${target}" in

+  am*-*-linux*)srv_regobj=reg-am33.o

+srv_tgtobj="linux-low.o linux-am33-low.o"

+srv_linux_usrregs=yes

+#srv_linux_regsets=yes

+srv_linux_thread_db=yes

+;;

   arm*-*-linux*)srv_tgtobj="linux-low.o linux-arm-low.o"

 srv_linux_usrregs=yes

 srv_linux_regsets=yes

diff -ruN gdb-6.8.orig/gdb/gdbserver/linux-am33-low.c gdb-6.8/gdb/gdbserver/linux-am33-low.c

--- gdb-6.8.orig/gdb/gdbserver/linux-am33-low.c1970-01-01 08:00:00.000000000 +0800

+++ gdb-6.8/gdb/gdbserver/linux-am33-low.c2009-07-02 15:09:49.000000000 +0800

@@ -0,0 +1,155 @@

+/* GNU/Linux/AM34 specific low level interface, for the remote server for GDB.

+   Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007,

+   2008 Free Software Foundation, Inc.

+

+   This file is part of GDB.

+

+   This program is free software; you can redistribute it and/or modify

+   it under the terms of the GNU General Public License as published by

+   the Free Software Foundation; either version 3 of the License, or

+   (at your option) any later version.

+

+   This program is distributed in the hope that it will be useful,

+   but WITHOUT ANY WARRANTY; without even the implied warranty of

+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+   GNU General Public License for more details.

+

+   You should have received a copy of the GNU General Public License

+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

+

+#include "server.h"

+#include "linux-low.h"

+

+#include "gdb_proc_service.h"

+

+#ifdef HAVE_SYS_REG_H

+#include <sys/reg.h>

+#endif

+

+#include <stddef.h>

+#include <sys/ptrace.h>

+

+#define am_num_regs 27

+

+#define X4(r) (PT_##r * 4)

+

+// from pt_regs to greg_t 

+

+static int am_regmap[] = {

+  // 0~7: "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3",

+  X4(D0), X4(D1), X4(D2), X4(D3), X4(A0), X4(A1), X4(A2), X4(A3),

+  // 8~15: "sp", "pc", "mdr", "psw", "lir", "lar", "mdrq", "r0",

+  X4(SP), X4(PC), X4(MDR), X4(EPSW), X4(LIR), X4(LAR), X4(MDRQ), X4(E0),

+  // 16~22: "r1", "r2", "r3", "r4", "r5", "r6", "r7"

+  X4(E1), X4(E2), X4(E3), X4(E4), X4(E5), X4(E6), X4(E7),

+  // 23~26  "mcrh", "mcrl", "mcvf", "orig_d0"

+  X4(MCRH), X4(MCRL), X4(MCVF), X4(ORIG_D0)

+};

+

+static int

+am_cannot_store_register (int regno)

+{

+  return (regno >= am_num_regs);

+}

+

+static int

+am_cannot_fetch_register (int regno)

+{

+  return (regno >= am_num_regs);

+}

+

+static CORE_ADDR

+am_get_pc ()

+{

+  unsigned long pc;

+

+  collect_register_by_name ("pc", &pc);

+  if (debug_threads)

+    fprintf (stderr, "stop pc (before any decrement) is %08lx/n", pc);

+

+  return pc;

+}

+

+static void

+am_set_pc (CORE_ADDR pc)

+{

+  unsigned long newpc = pc;

+

+  if (debug_threads)

+    fprintf (stderr, "set pc to %08lx/n", (long) newpc);

+

+  supply_register_by_name ("pc", &newpc);

+}

+

+// see mn10300-tdep.c

+static const unsigned char am_breakpoint[] = { 0xff };

+#define am_breakpoint_len 1

+

+static int

+am_breakpoint_at (CORE_ADDR pc)

+{

+  unsigned char c;

+

+  if (debug_threads)

+    fprintf (stderr, "in %s/n", __func__);

+

+  read_inferior_memory (pc, &c, 1);

+  if (c == 0xff)

+    return 1;

+

+  return 0;

+}

+

+static void am_fill_gregset (void *buf)

+{

+  int i;

+

+  if (debug_threads)

+    fprintf(stderr, "*** in %s/n", __func__);

+

+  for (i = 0; i < am_num_regs; i++)

+    if (am_regmap[i] != -1)

+      collect_register (i, (char *) buf + am_regmap[i]);

+}

+

+static void

+am_store_gregset (const void *buf)

+{

+  int i;

+  char zerobuf[4] = { 0 };

+

+  fprintf(stderr, "*** in %s/n", __func__);

+

+  for (i = 0; i < am_num_regs; i++)

+    if (am_regmap[i] != -1)

+      supply_register (i, ((char *) buf) + am_regmap[i]);

+    else

+      supply_register (i, zerobuf);

+}

+

+#ifdef HAVE_LINUX_REGSETS

+

+struct regset_info target_regsets[] = {

+#ifdef HAVE_PTRACE_GETREGS

+  { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),

+    GENERAL_REGS,

+    am_fill_gregset, am_store_gregset },

+#endif

+  { 0, 0, -1, -1, NULL, NULL }

+};

+

+#endif

+

+struct linux_target_ops the_low_target = {

+  am_num_regs,

+  am_regmap,

+  am_cannot_fetch_register,

+  am_cannot_store_register,

+  am_get_pc,

+  am_set_pc,

+  am_breakpoint,

+  am_breakpoint_len,

+  0 /*am_reinsert_addr*/,

+  0,

+  am_breakpoint_at,

+};

diff -ruN gdb-6.8.orig/gdb/gdbserver/Makefile.in gdb-6.8/gdb/gdbserver/Makefile.in

--- gdb-6.8.orig/gdb/gdbserver/Makefile.in2008-02-12 06:00:31.000000000 +0800

+++ gdb-6.8/gdb/gdbserver/Makefile.in2009-07-02 15:09:41.000000000 +0800

@@ -217,6 +217,7 @@

 rm -f *.o ${ADD_FILES} *~

 rm -f version.c

 rm -f gdbserver$(EXEEXT) gdbreplay$(EXEEXT) core make.log

+rm -f reg-am33.c

 rm -f reg-arm.c reg-i386.c reg-ia64.c reg-m32r.c reg-m68k.c

 rm -f reg-ppc.c reg-sh.c reg-spu.c reg-x86-64.c reg-i386-linux.c

 rm -f reg-cris.c reg-crisv32.c reg-x86-64-linux.c reg-xtensa.c

@@ -301,6 +302,7 @@

 linux-low.o: linux-low.c $(linux_low_h) $(server_h)

 $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< @USE_THREAD_DB@

 

+linux-am33-low.o: linux-am33-low.c $(linux_low_h) $(server_h) 

 linux-arm-low.o: linux-arm-low.c $(linux_low_h) $(server_h) /

 $(gdb_proc_service_h)

 linux-cris-low.o: linux-cris-low.c $(linux_low_h) $(server_h)

@@ -328,6 +330,9 @@

 

 spu-low.o: spu-low.c $(server_h)

 

+reg-am33.o : reg-am33.c $(regdef_h)

+reg-am33.c : $(srcdir)/../regformats/reg-am33.dat $(regdat_sh)

+$(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-am33.dat reg-am33.c

 reg-arm.o : reg-arm.c $(regdef_h)

 reg-arm.c : $(srcdir)/../regformats/reg-arm.dat $(regdat_sh)

 $(SHELL) $(regdat_sh) $(srcdir)/../regformats/reg-arm.dat reg-arm.c

diff -ruN gdb-6.8.orig/gdb/mn10300-linux-tdep.c gdb-6.8/gdb/mn10300-linux-tdep.c

--- gdb-6.8.orig/gdb/mn10300-linux-tdep.c2008-01-22 09:17:25.000000000 +0800

+++ gdb-6.8/gdb/mn10300-linux-tdep.c2009-08-23 12:38:55.000000000 +0800

@@ -32,6 +32,8 @@

 #include "frame.h"

 #include "trad-frame.h"

 #include "tramp-frame.h"

+#include "breakpoint.h"

+#include "target.h"

 

 #include <stdlib.h>

 

@@ -704,7 +706,241 @@

 

   trad_frame_set_id (this_cache, frame_id_build (sc_base, func));

 }

-

+

+typedef unsigned char u8;

+

+#if 0

+

+#define READ_BYTE(p,valp)   /

+    do { *(u8 *)(valp) = *(u8 *)(p); }while(0)

+

+

+#endif

+

+#define READ_BYTE(p,valp)   /

+do { target_read_memory((CORE_ADDR)(p), (gdb_byte*)(valp), 1); } while (0)

+

+#define READ_WORD16(p,valp)                         /

+    do {                                            /

+        READ_BYTE((p),(valp));                      /

+        READ_BYTE((u8 *)(p) + 1, (u8 *)(valp) + 1); /

+    }while(0)

+

+#define READ_WORD32(p,valp)                         /

+    do {                                            /

+        READ_BYTE((p),(valp));                      /

+        READ_BYTE((u8 *)(p) + 1, (u8 *)(valp) + 1); /

+        READ_BYTE((u8 *)(p) + 2, (u8 *)(valp) + 2); /

+        READ_BYTE((u8 *)(p) + 3, (u8 *)(valp) + 3); /

+    }while(0)

+

+/* 2009-08-19/zhanzh: stole from kprobe.c */

+static const unsigned char mn10300_insn_sizes[256] =

+{

+        // 1  2  3  4  5  6  7  8  9  a  b  c  d  e  f

+        1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, 1, 3, 3, 3, // 0

+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1

+        2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, // 2

+        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, // 3

+        1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, // 4

+        1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, // 5

+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6

+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7

+        2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, // 8

+        2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, // 9

+        2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, // a

+        2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, // b

+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 2, // c

+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // d

+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // e

+        0, 2, 2, 2, 2, 2, 2, 4, 0, 3, 0, 4, 0, 6, 7, 1  // f

+};

+

+#define LT (1 << 0)

+#define GT (1 << 1)

+#define GE (1 << 2)

+#define LE (1 << 3)

+#define CS (1 << 4)

+#define HI (1 << 5)

+#define CC (1 << 6)

+#define LS (1 << 7)

+#define EQ (1 << 8)

+#define NE (1 << 9)

+#define RA (1 << 10)

+#define VC (1 << 11)

+#define VS (1 << 12)

+#define NC (1 << 13)

+#define NS (1 << 14)

+

+static const unsigned int cond_table[] = {

+    /*  V  C  N  Z  */

+    /*  0  0  0  0  */ (NE | NC | CC | VC | GE | GT | HI),

+    /*  0  0  0  1  */ (EQ | NC | CC | VC | GE | LE | LS),

+    /*  0  0  1  0  */ (NE | NS | CC | VC | LT | LE | HI),

+    /*  0  0  1  1  */ (EQ | NS | CC | VC | LT | LE | LS),

+    /*  0  1  0  0  */ (NE | NC | CS | VC | GE | GT | LS),

+    /*  0  1  0  1  */ (EQ | NC | CS | VC | GE | LE | LS),

+    /*  0  1  1  0  */ (NE | NS | CS | VC | LT | LE | LS),

+    /*  0  1  1  1  */ (EQ | NS | CS | VC | LT | LE | LS),

+    /*  1  0  0  0  */ (NE | NC | CC | VS | LT | LE | HI),

+    /*  1  0  0  1  */ (EQ | NC | CC | VS | LT | LE | LS),

+    /*  1  0  1  0  */ (NE | NS | CC | VS | GE | GT | HI),

+    /*  1  0  1  1  */ (EQ | NS | CC | VS | GE | LE | LS),

+    /*  1  1  0  0  */ (NE | NC | CS | VS | LT | LE | LS),

+    /*  1  1  0  1  */ (EQ | NC | CS | VS | LT | LE | LS),

+    /*  1  1  1  0  */ (NE | NS | CS | VS | GE | GT | LS),

+    /*  1  1  1  1  */ (EQ | NS | CS | VS | GE | LE | LS),

+};

+

+CORE_ADDR

+am33_next_pc (struct frame_info *frame, CORE_ADDR _pc)

+{

+        unsigned size;

+        char x8;

+        short x16;

+        int x32;

+        unsigned char opc, *pc, *sp, *next;

+CORE_ADDR epsw, mdr, a0, a1, a2, a3, ssp;

+unsigned char insn[4] =  { 0 };

+

+        epsw = get_frame_register_unsigned (frame, E_PSW_REGNUM);

+        mdr = get_frame_register_unsigned (frame, E_MDR_REGNUM);

+        a0 = get_frame_register_unsigned (frame, E_A0_REGNUM);

+        a1 = get_frame_register_unsigned (frame, E_A1_REGNUM);

+        a2 = get_frame_register_unsigned (frame, E_A2_REGNUM);

+        a3 = get_frame_register_unsigned (frame, E_A3_REGNUM);

+        ssp = get_frame_register_unsigned (frame, E_SP_REGNUM);

+sp = (unsigned char*)ssp;

+

+        target_read_memory(_pc, insn, 4);

+        pc = (unsigned char*)_pc;

+        next = 0;

+        //opc = read_memory_unsigned_integer(_pc, 1);

+        target_read_memory(_pc, &opc, 1);

+        //opc = *pc;

+

+        size = mn10300_insn_sizes[opc];

+        if (size > 0) {

+                next = (unsigned char*)pc + size;

+        } else {

+                switch (opc) {

+                /* Bxx (d8,PC) */

+                case 0xc0 ... 0xca:

+                        x8 = 2;

+                        if (cond_table[epsw & 0xf] & (1 << (opc & 0xf)))

+                                x8 = (int8_t)insn[1];

+                        next = pc + x8;

+                        break;

+

+                /* JMP (d16,PC) or CALL (d16,PC) */

+                case 0xcc:

+                case 0xcd:

+                        READ_WORD16(pc + 1, &x16);

+                        next = pc + x16;

+                        break;

+

+                /* JMP (d32,PC) or CALL (d32,PC) */

+                case 0xdc:

+                case 0xdd:

+                        READ_WORD32(pc + 1, &x32);

+                        next = pc + x32;

+                        break;

+

+                /* RETF */

+                case 0xde:

+                        next = (unsigned char *)mdr;

+                        break;

+

+                /* RET */

+                case 0xdf:

+                        sp += insn[2];

+                        READ_WORD32(sp, &x32);

+                        next = (unsigned char *)x32;

+                        break;

+

+                case 0xf0:

+                        next = pc + 2;

+                        opc = insn[1];

+                        if (opc >= 0xf0 && opc <= 0xf7) {

+                                /* JMP (An) / CALLS (An) */

+                                switch (opc & 3) {

+                                case 0:

+                                        next = (unsigned char *)a0;

+                                        break;

+                                case 1:

+                                        next = (unsigned char *)a1;

+                                        break;

+                                case 2:

+                                        next = (unsigned char *)a2;

+                                        break;

+                                case 3:

+                                        next = (unsigned char *)a3;

+                                        break;

+                                }

+                        } else if (opc == 0xfc) {

+                                /* rets */

+                                READ_WORD32(sp, &x32);

+                                next = (unsigned char *)x32;

+                        } else if (opc == 0xfd) {

+                                /* rti */

+                                READ_WORD32(sp+4, &x32);

+                                next = (unsigned char *)x32;

+                        }

+                        break;

+                /* potential 3-byte conditional branches */

+                case 0xf8:

+                        next = pc + 3;

+                        opc = insn[1];

+                        if (opc >= 0xe8 && opc <= 0xeb &&

+                            (cond_table[epsw & 0xf] & (1 << ((opc & 0xf) + 3)))) {

+                                READ_BYTE(pc+2, &x8);

+                                next = pc + x8;

+                        }

+                        break;

+

+                case 0xfa:

+                        if (insn[1] == 0xff) {

+                                /* CALLS (d16,PC) */

+                                READ_WORD16(pc+2, &x16);

+                                next = pc + x16;

+                        } else

+                                next = pc + 4;

+                        break;

+

+                case 0xfc:

+                        x32 = 6;

+                        if (insn[1] == 0xff) {

+                                /* CALLS (d32,PC) */

+                                READ_WORD32(pc+2, &x32);

+                        }

+                        next = pc + x32;

+                        break;

+                /* LXX (d8,PC) */

+                /* SETLB - loads the next for bytes into the LIR register */

+                case 0xd0 ... 0xda:

+                case 0xdb:

+// FIXME: error

+                        break;

+                }

+        }

+        return (unsigned)next;

+}

+

+int

+am33_linux_software_single_step (struct frame_info *frame)

+{

+  CORE_ADDR pc, next_pc;

+

+  pc = get_frame_pc (frame);

+  next_pc = am33_next_pc (frame, pc);

+

+  fprintf(stderr, "in %s, pc: 0x%lx, next_pc: 0x%lx/n", __func__, pc, next_pc);

+

+  insert_single_step_breakpoint (next_pc);

+

+  return 1;

+}

+

 /* AM33 GNU/Linux osabi has been recognized.

    Now's our chance to register our corefile handling.  */

 

@@ -716,6 +952,9 @@

   set_solib_svr4_fetch_link_map_offsets

     (gdbarch, svr4_ilp32_fetch_link_map_offsets);

 

+  /* 2009-08-19/zhanzh: Single stepping.  */

+  set_gdbarch_software_single_step (gdbarch, am33_linux_software_single_step);

+

   tramp_frame_prepend_unwinder (gdbarch, &am33_linux_sigframe);

   tramp_frame_prepend_unwinder (gdbarch, &am33_linux_rt_sigframe);

 }

diff -ruN gdb-6.8.orig/gdb/regformats/reg-am33.dat gdb-6.8/gdb/regformats/reg-am33.dat

--- gdb-6.8.orig/gdb/regformats/reg-am33.dat1970-01-01 08:00:00.000000000 +0800

+++ gdb-6.8/gdb/regformats/reg-am33.dat2009-07-02 15:08:12.000000000 +0800

@@ -0,0 +1,29 @@

+name:am33

+expedite:a3,sp,pc

+32:d0

+32:d1

+32:d2

+32:d3

+32:a0

+32:a1

+32:a2

+32:a3

+32:sp

+32:pc

+32:mdr

+32:epsw

+32:lir

+32:lar

+32:mdrq

+32:e0

+32:e1

+32:e2

+32:e3

+32:e4

+32:e5

+32:e6

+32:e7

+32:mcrh

+32:mcrl

+32:mcvf

+32:orig_d0

 

 

</pre>

原创粉丝点击