Skip to contentSkip to conversation

gdb: Port for OpenRISC

PATCH Superseded Stafford Horne 2 participants 21 messages Nov 23, 2016 – Nov 25, 2016

v1 of 7 Superseded Latest is v7 →

lore
Share & tools
lore
#0 lore raw

cover gdb: Port for OpenRISC

Hello,

This is the openrisc port of GDB that has been in openrisc repositories for a very long time. The main original author was Jeremy Bennett as can be seen in file copyrights. Other are willing to do what it takes for FSF copyright assignment.

This along with the sim patches are the last of what has not made its way upstream. The patches are based on current gdb git master branch.

I have run the testsuite and results are as follows:

=== gdb Summary ===

# of expected passes            19209
# of unexpected failures        411
# of expected failures          28
# of known failures             57
# of unresolved testcases       34
# of untested testcases         190
# of unsupported tests          264
/home/shorne/work/openrisc/build-gdb/gdb/gdb version 7.12.50.20161122-git

Thanks,
-Stafford

Franck Jullien (8):
gdb: add or1k and or1knd target support
gdb: or1k: Add a check for NULL ptr in or1k_skip_prologue
gdb: or1k: Add or1k_push_dummy_code and use it.
gdb: add tdesc_find_register functions
gdb: handle arbitrary strings in tdesc_register_in_reggroup_p
gdb: or1k: set gdbarch num regs to gpr + spr regs
gdb: or1k: add target descriptor support
gdb: or1k: change or1k_push_dummy_code stack alignment

Stafford Horne (5):
gdb: testsuite: Add or1k l.nop inscruction
gdb: or1k: Update calling conventions to help pass tests
gdb: Remove corelow object from or1k linux build
gdb: or1k: Updates for compiler type checking
gdb: or1k: Refactor to new bp_kind_from_pc and pb_from_kind

Stefan Kristiansson (2):
gdb: or1k: Silence gcc warning
gdb: or1k: Fixes for things that broke after upstream merge

Stefan Wallentowitz (3):
Add gdb for or1k build
gdb: or1k: Apply changes of the last two years
gdb: Add OpenRISC to texinfo menu

#1 lore raw

PATCH 1/18 gdb: add or1k and or1knd target support

From: Franck Jullien <[email protected]>

This patch is pretty much a copy of the current GDB 7.2 port of the openrisc processor.

It now supports or1knd (no delay slot target). This architecture has not been tested. The default target is or1k (with delay slot). You can change the target arch with:

(gdb) set architecture or1knd
The target architecture is assumed to be or1knd

gdb/ChangeLog:

* or1k-tdesc.c : Add file for or1k support
* or1k-tdesc.h : Add file for or1k support
* configure.tgt : Add or1k targets
* gdb.texinfo : Add OpenRISC documentation

---
 gdb/configure.tgt   |   26 +
 gdb/doc/gdb.texinfo |  102 ++
 gdb/or1k-tdep.c     | 2983 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/or1k-tdep.h     |  432 ++++++++
 4 files changed, 3543 insertions(+)
 create mode 100644 gdb/or1k-tdep.c
 create mode 100644 gdb/or1k-tdep.h
gdb/configure.tgt +26 -0
index 79473c9..2c5418c 100644
@@ -421,6 +421,32 @@ nios2*-*-*)
 	gdb_target_obs="nios2-tdep.o"
 	;;
 
+or1k-*-linux*)
+	# Target: OpenCores OpenRISC 1000 32-bit implementation for Linux
+	gdb_target_obs="or1k-tdep.o corelow.o"
+	gdb_sim=../sim/or1k/libsim.a
+	build_gdbserver=yes
+	;;
+
+or1k-*-*)
+	# Target: OpenCores OpenRISC 1000 32-bit implementation bare metal
+	gdb_target_obs="or1k-tdep.o"
+    gdb_sim=../sim/or1k/libsim.a
+	;;
+
+or1knd-*-linux*)
+	# Target: OpenCores OpenRISC 1000 32-bit implementation for Linux, without delay slot
+	gdb_target_obs="or1k-tdep.o corelow.o"
+    gdb_sim=../sim/or1k/libsim.a
+	build_gdbserver=yes
+	;;
+
+or1knd-*-*)
+	# Target: OpenCores OpenRISC 1000 32-bit implementation bare metal, without delay slot
+	gdb_target_obs="or1k-tdep.o"
+	gdb_sim=../sim/or1k/libsim.a
+	;;
+
 powerpc*-*-freebsd*)
 	# Target: FreeBSD/powerpc
 	gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc64-tdep.o \
gdb/doc/gdb.texinfo +102 -0

114 lines not on this page · raw message

gdb/or1k-tdep.c new file +2983 -0

2,854 lines not on this page · raw message

gdb/or1k-tdep.h new file +432 -0

432 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.7.4

Part of the diff is not shown here. View the raw message.

#2 lore raw

PATCH 2/18 gdb: or1k: Add a check for NULL ptr in or1k_skip_prologue

In reply to Stafford Horne

From: Franck Jullien <[email protected]>

gdb/ChangeLog:

* or1k-tdep.c (or1k_skip_prologue): Add a check for NULL pointer while comparing debugformat to "dwarf".

---
 gdb/or1k-tdep.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
gdb/or1k-tdep.c +1 -1
index 6d27a0d..55b9522 100644
@@ -949,7 +949,7 @@ or1k_skip_prologue (struct gdbarch *gdbarch,
 	  struct symtab_and_line  prologue_sal = find_pc_line (start_pc, 0);
 	  const char *debug_format = prologue_sal.symtab->debugformat;
 
-	  if ((strlen ("dwarf") <= strlen (debug_format))
+	  if ((NULL != debug_format) && (strlen ("dwarf") <= strlen (debug_format))
 	      && (0 == strncasecmp ("dwarf", debug_format, strlen ("dwarf"))))
 	    {
 	      return  (prologue_end > pc) ? prologue_end : pc;
Signature · 1 line
2.7.4
#3 lore raw

PATCH 3/18 gdb: or1k: Add or1k_push_dummy_code and use it.

In reply to Stafford Horne

From: Franck Jullien <[email protected]>

gdb/ChangeLog:

* or1k-tdep.c (or1k_push_dummy_code): New function. (or1k_gdbarch_init): Override default behavior and call dummy from the stack. Set the push_dummy_code handler to or1k_push_dummy_code.

---
 gdb/or1k-tdep.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
gdb/or1k-tdep.c +43 -0
index 55b9522..d660a39 100644
@@ -1112,6 +1112,47 @@ or1k_unwind_sp (struct gdbarch    *gdbarch,
 
 }	/* or1k_unwind_sp() */
 
+/*----------------------------------------------------------------------------*/
+/*!Provides return address for dummy call
+
+   Provides an address on the stack where to put a breakpoint as return
+   address for function. bp_addr is the address to which the function should
+   return (which is breakpointed, so gdb can regain control, hence the name).
+
+   @param[in] gdbarch        The architecture to use
+   @param[in] sp             The stack pointer
+   @param[in] function       Pointer to the function that will be called
+   @param[in] args           The arguments
+   @param[in] nargs          Number of ags to push
+   @param[in] value_type     Type of the function result
+   @param[in] real_pc        Resume address
+   @param[in] bp_addr        Breakpoint address
+   @param[in] regcache       The register cache to use
+
+   @return  The breakpoint address */
+/*---------------------------------------------------------------------------*/
+
+static CORE_ADDR
+or1k_push_dummy_code (struct gdbarch *gdbarch,
+		      CORE_ADDR sp,
+		      CORE_ADDR function,
+		      struct value **args,
+		      int nargs,
+		      struct type *value_type,
+		      CORE_ADDR *real_pc,
+		      CORE_ADDR *bp_addr,
+		      struct regcache *regcache)
+{
+  /* Allocate space sufficient for a breakpoint, keeping the stack aligned.  */
+  sp = (sp - 4) & ~15;
+  /* Store the address of that breakpoint */
+  *bp_addr = sp;
+  /* The call starts at the callee's entry point.  */
+  *real_pc = function;
+
+  return sp;
+
+}	/* or1k_push_dummy_code() */
 
 /*----------------------------------------------------------------------------*/
 /*!Create a dummy stack frame
@@ -1888,6 +1929,8 @@ or1k_gdbarch_init (struct gdbarch_info  info,
   set_gdbarch_unwind_sp             (gdbarch, or1k_unwind_sp);
 
   /* Functions handling dummy frames */
+  set_gdbarch_call_dummy_location   (gdbarch, ON_STACK);
+  set_gdbarch_push_dummy_code       (gdbarch, or1k_push_dummy_code);
   set_gdbarch_push_dummy_call       (gdbarch, or1k_push_dummy_call);
   set_gdbarch_dummy_id              (gdbarch, or1k_dummy_id);
 
Signature · 1 line
2.7.4
#4 lore raw

PATCH 4/18 gdb: add tdesc_find_register functions

In reply to Stafford Horne

From: Franck Jullien <[email protected]>

In order to get registers names and groups from the target descriptor file, some new functions are needed.

This patch adds:

- tdesc_find_register_name: Search FEATURE for a register REGNO and return its name.

- tdesc_find_register_group_name: Search FEATURE for a register REGNO and return its group name.

gdb/ChangeLog:

* target-descriptions.c: (tdesc_find_register_name) create (tdesc_find_register_group_name) create
* target-descriptions.h: (tdesc_find_register_name) create (tdesc_find_register_group_name) create

---
 gdb/target-descriptions.c | 34 ++++++++++++++++++++++++++++++++++
 gdb/target-descriptions.h | 12 ++++++++++++
 2 files changed, 46 insertions(+)
gdb/target-descriptions.c +34 -0
index 40f0478..18c39cd 100644
@@ -900,6 +900,40 @@ tdesc_numbered_register (const struct tdesc_feature *feature,
   return 1;
 }
 
+/* Search FEATURE for a register REGNO and return its name. */
+char *
+tdesc_find_register_name (const struct tdesc_feature *feature,
+			   int regno)
+{
+  int ixr;
+  struct tdesc_reg *reg;
+
+  for (ixr = 0;
+       VEC_iterate (tdesc_reg_p, feature->registers, ixr, reg);
+       ixr++)
+    if (ixr == regno)
+      return reg->name;
+
+  return NULL;
+}
+
+/* Search FEATURE for a register REGNO and return its group name. */
+char *
+tdesc_find_register_group_name (const struct tdesc_feature *feature,
+			   int regno)
+{
+  int ixr;
+  struct tdesc_reg *reg;
+
+  for (ixr = 0;
+       VEC_iterate (tdesc_reg_p, feature->registers, ixr, reg);
+       ixr++)
+    if (ixr == regno)
+      return reg->group;
+
+  return NULL;
+}
+
 /* Search FEATURE for a register named NAME, but do not assign a fixed
    register number to it.  */
 
gdb/target-descriptions.h +12 -0
index ef97d1d..0d8f03f 100644
@@ -111,6 +111,18 @@ struct tdesc_arch_data *tdesc_data_alloc (void);
 
 void tdesc_data_cleanup (void *data_untyped);
 
+/* Search FEATURE for a register REGNO and return its name. */
+
+char *tdesc_find_register_name (const struct tdesc_feature *feature,
+				int regno);
+
+
+/* Search FEATURE for a register REGNO and return its group name. */
+
+char *tdesc_find_register_group_name (const struct tdesc_feature *feature,
+				      int regno);
+
+
 /* Search FEATURE for a register named NAME.  Record REGNO and the
    register in DATA; when tdesc_use_registers is called, REGNO will be
    assigned to the register.  1 is returned if the register was found,
Signature · 1 line
2.7.4
#5 lore raw

PATCH 5/18 gdb: handle arbitrary strings in tdesc_register_in_reggroup_p

In reply to Stafford Horne

From: Franck Jullien <[email protected]>

tdesc_register_in_reggroup_p in now able to handle arbitrary groups. This is useful when groups are created while the target descriptor file is received from the remote.

This can be the case of a soft core target processor where registers/groups can change.

gdb/ChangeLog:

* target-descriptions.c: (tdesc_register_in_reggroup_p) support arbitrary groups.

---
 gdb/target-descriptions.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
gdb/target-descriptions.c +6 -6
index 18c39cd..a542ef9 100644
@@ -1118,12 +1118,8 @@ tdesc_remote_register_number (struct gdbarch *gdbarch, int regno)
    return -1 if it does not know; the caller should handle registers
    with no specified group.
 
-   Arbitrary strings (other than "general", "float", and "vector")
-   from the description are not used; they cause the register to be
-   displayed in "info all-registers" but excluded from "info
-   registers" et al.  The names of containing features are also not
-   used.  This might be extended to display registers in some more
-   useful groupings.
+   The names of containing features are also not used.  This might be
+   extended to display registers in some more useful groupings.
 
    The save-restore flag is also implemented here.  */
 
@@ -1152,6 +1148,10 @@ tdesc_register_in_reggroup_p (struct gdbarch *gdbarch, int regno,
 
       if (reggroup == general_reggroup)
 	return general_p;
+
+      if (strcmp (reg->group, reggroup_name (reggroup)) == 0)
+	return 1;
+
     }
 
   if (reg != NULL
Signature · 1 line
2.7.4
#6 lore raw

PATCH 6/18 gdb: or1k: set gdbarch num regs to gpr + spr regs

In reply to Stafford Horne

From: Franck Jullien <[email protected]>

Add a definition for SPR maximum number (OR1K_MAX_SPR_REGS). This value is set to 64K (32 groups of 2048 registers).

gdb/ChangeLog:

* or1k-tdep.c: use OR1K_MAX_SPR_REGS
* or1k-tdep.h: add OR1K_MAX_SPR_REGS

---
 gdb/or1k-tdep.c |  6 +++---
 gdb/or1k-tdep.h | 14 ++++++++------
 2 files changed, 11 insertions(+), 9 deletions(-)
gdb/or1k-tdep.c +3 -3
index d660a39..1a3c16b 100644
@@ -684,7 +684,7 @@ static const char *
 or1k_register_name (struct gdbarch *gdbarch,
 		    int             regnum)
 {
-  static char *or1k_gdb_reg_names[OR1K_TOTAL_NUM_REGS] =
+  static char *or1k_gdb_reg_names[OR1K_NUM_REGS_CACHED] =
     {
       /* general purpose registers */
       "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
@@ -784,7 +784,7 @@ or1k_registers_info (struct gdbarch    *gdbarch,
   if (-1 == regnum)
     {
       /* Do all (valid) registers */
-      unsigned int  lim = all ? OR1K_NUM_REGS : OR1K_MAX_GPR_REGS;
+      unsigned int  lim = all ? OR1K_NUM_REGS_CACHED : OR1K_MAX_GPR_REGS;
 
       for (regnum = 0; regnum < lim; regnum++) {
 	if ('\0' != *(or1k_register_name (gdbarch, regnum)))
@@ -837,7 +837,7 @@ or1k_register_reggroup_p (struct gdbarch  *gdbarch,
   if (group == all_reggroup)
     {
       return ((regnum >= 0) &&
-	      (regnum < OR1K_TOTAL_NUM_REGS) &&
+	      (regnum < OR1K_NUM_REGS_CACHED) &&
 	      (or1k_register_name (gdbarch, regnum)[0] != '\0'));
     }
 
gdb/or1k-tdep.h +8 -6
index 3179537..f0afc8f 100644
@@ -317,19 +317,21 @@
 #define OR1K_SPR_DCFGR_WPCI     0x00000008  /* Watchpoint ctrs implemented */
 
 /* Properties of the architecture. GDB mapping of registers is all the GPRs
-   followed by the PPC, NPC and SR at the end. Red zone is the area past the
-   end of the stack reserved for exception handlers etc. */
-#define OR1K_MAX_GPR_REGS           32
+   and SPRs followed by the PPC, NPC and SR@the end. Red zone is the area
+   past the end of the stack reserved for exception handlers etc. */
+#define OR1K_MAX_GPR_REGS            32
+#define OR1K_MAX_SPR_REGS           (32 * 2048)
 #define OR1K_NUM_PSEUDO_REGS         0
-#define OR1K_NUM_REGS               (OR1K_MAX_GPR_REGS + 3)
+#define OR1K_NUM_REGS_CACHED        (OR1K_MAX_GPR_REGS + 3)
+#define OR1K_NUM_REGS               (OR1K_NUM_REGS_CACHED + OR1K_MAX_SPR_REGS)
 #define OR1K_TOTAL_NUM_REGS         (OR1K_NUM_REGS + OR1K_NUM_PSEUDO_REGS)
 #define OR1K_MAX_MATCHPOINTS         8
 #define OR1K_MAX_HW_WATCHES          OR1K_MAX_MATCHPOINTS
 #define OR1K_STACK_ALIGN             4
 #define OR1K_INSTLEN                 4
-#define OR1K_INSTBITLEN              (OR1K_INSTLEN * 8)
+#define OR1K_INSTBITLEN             (OR1K_INSTLEN * 8)
 #define OR1K_NUM_TAP_RECORDS         8
-#define OR1K_FRAME_RED_ZONE_SIZE  2536
+#define OR1K_FRAME_RED_ZONE_SIZE     2536
 
 /* OR1K exception vectors */
 
Signature · 1 line
2.7.4
#7 lore raw

PATCH 7/18 gdb: or1k: add target descriptor support

In reply to Stafford Horne

From: Franck Jullien <[email protected]>

This patch adds target support to or1k.

Registers names and groups are dynamically created from the tdesc remote file.

For example, we could have:

<feature name="org.gnu.gdb.or1k.group10">

    <reg name="ttmr"  bitsize="32" regnum="2216" group="timer"/>
    <reg name="ttcr"  bitsize="32" regnum="2217" group="timer"/>

</feature>

Then, a group "timer" would be created and timer registers would be accessible using "info registers timer" and "set $ttmr ..."

While receiving a tdesc file from the remote, found registers and corresponding groups can displayed using "set debug arch 1" before setting the target to remote.

For example:

Remote debugging using :50001
Found 93 registers in feature org.gnu.gdb.or1k.group0
Found 1035 registers in feature org.gnu.gdb.or1k.group1 Found 1035 registers in feature org.gnu.gdb.or1k.group2

Found    6 registers in feature org.gnu.gdb.or1k.group3
Found    4 registers in feature org.gnu.gdb.or1k.group4
Found    2 registers in feature org.gnu.gdb.or1k.group5
Found   22 registers in feature org.gnu.gdb.or1k.group6
Found   16 registers in feature org.gnu.gdb.or1k.group7
Found    1 registers in feature org.gnu.gdb.or1k.group8
Found    2 registers in feature org.gnu.gdb.or1k.group9
Found    2 registers in feature org.gnu.gdb.or1k.group10

Found 2218 registers in the tdesc file

Available groups can be displayed with:

(gdb) maintenance print reggroups

 Group      Type
 system     user
 dmmu       user
 immu       user
 dcache     user
 icache     user
 mac        user
 debug      user
 perf       user
 power      user
 pic        user
 timer      user

gdb/ChangeLog:

* or1k-tdep.c: changes

---
 gdb/or1k-tdep.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 214 insertions(+), 4 deletions(-)
gdb/or1k-tdep.c +214 -4
index 1a3c16b..cb0871f 100644
@@ -115,6 +115,8 @@
 #include "dwarf2-frame.h"
 #include "trad-frame.h"
 #include "regset.h"
+#include "remote.h"
+#include "target-descriptions.h"
 
 #include <inttypes.h>
 
@@ -699,7 +701,18 @@ or1k_register_name (struct gdbarch *gdbarch,
 	 the future. */
     };
 
-  return or1k_gdb_reg_names[regnum];
+  /* If we have a target description, use it */
+  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
+    return tdesc_register_name (gdbarch, regnum);
+  else
+    {
+      if (0 <= regnum && regnum < OR1K_NUM_REGS_CACHED)
+	{
+	  return or1k_gdb_reg_names[regnum];
+	}
+      else
+	return NULL;
+    }
 
 }	/* or1k_register_name() */
 
@@ -781,6 +794,8 @@ or1k_registers_info (struct gdbarch    *gdbarch,
 		     int                regnum,
 		     int                all)
 {
+  struct regcache *regcache = get_current_regcache ();
+
   if (-1 == regnum)
     {
       /* Do all (valid) registers */
@@ -796,12 +811,19 @@ or1k_registers_info (struct gdbarch    *gdbarch,
   else
     {
       /* Do one specified register - if it is part of this architecture */
-      if ('\0' == *(or1k_register_name (gdbarch, regnum)))
+      if ((regnum < OR1K_NUM_REGS_CACHED)
+	  && ('\0' == *(or1k_register_name (gdbarch, regnum))))
 	{
 	  error ("Not a valid register for the current processor type");
 	}
       else
 	{
+	  /* If the register is not in the g/G packet, fetch it from the
+	   * target with a p/P packet.
+	   */
+	  if (regnum >= OR1K_NUM_REGS_CACHED)
+	    target_fetch_registers (regcache, regnum);
+
 	  default_print_registers_info (gdbarch, file, frame, regnum, all);
 	}
     }
@@ -860,8 +882,16 @@ or1k_register_reggroup_p (struct gdbarch  *gdbarch,
       return 0;			/* No vector regs.  */
     }
 
-  /* For any that are not handled above.  */
-  return default_register_reggroup_p (gdbarch, regnum, group);
+  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
+    {
+      if ((tdesc_register_in_reggroup_p (gdbarch, regnum, group)) != 1)
+	return 0;
+      else
+	return 1;
+    }
+  else
+    /* For any that are not handled above.  */
+    return default_register_reggroup_p (gdbarch, regnum, group);
 
 }	/* or1k_register_reggroup_p() */
 
@@ -1839,6 +1869,115 @@ or1k_regset_from_core_section (struct gdbarch *gdbarch,
 
 }	/* or1k_regset_from_core_section () */
 
+/* -------------------------------------------------------------------------- */
+/*!Create a register group based on a group name.
+
+   We create a group only if group_name is not already a register group name.
+
+   @param[in] gdbarch     The GDB architecture we are using.
+   @param[in] group_name  Name of the new register group.
+
+   @return  1 if the group has been created, 0 otherwise. */
+/* -------------------------------------------------------------------------- */
+static int
+create_register_group (struct gdbarch *gdbarch, const char *group_name)
+{
+  struct reggroup *group;
+  static int first = 1;
+  int group_exist = 0;
+
+  if (group_name == NULL)
+    return 0;
+
+  if (!first)
+    {
+      for (group = reggroup_next (gdbarch, NULL);
+	   group != NULL; group = reggroup_next (gdbarch, group))
+	{
+	  if (strcmp (group_name, reggroup_name (group)) == 0)
+	    group_exist = 1;
+	}
+
+      if (!group_exist)
+	{
+	  /* If the group doesn't exist, create it */
+	  reggroup_add (gdbarch, reggroup_new (group_name, USER_REGGROUP));
+	  return 1;
+	}
+    }
+  else
+    {
+      /* reggroup_next cannot be called during architecture. However,
+       * a first call to reggroup_add execute reggroups_init and then
+       * reggroup_next can be use. We assume the first group name we
+       * create does not exist.
+       */
+      reggroup_add (gdbarch, reggroup_new (group_name, USER_REGGROUP));
+      first = 0;
+    }
+
+  return 0;
+}
+
+/* -------------------------------------------------------------------------- */
+/*!Register all reg found in a feature section.
+
+   Register all reg found in a feature section and create a group for each
+   new register group name found in the tdesc file.
+
+   @param[in]  feature    The feature to search for registers.
+   @param[out] tdesc_data The target descriptor data to fill.
+   @param[out] reg_index  Register index in tdesc_data.
+   @param[in]  gdbarch    The GDB architecture we are using.
+
+   @return  Number of registers found, -1 if error.                           */
+/* -------------------------------------------------------------------------- */
+static int
+get_feature_registers (const struct tdesc_feature *feature,
+		       struct tdesc_arch_data *tdesc_data, int *reg_index,
+		       struct gdbarch *gdbarch)
+{
+  int valid_p;
+  int i;
+  char *name;
+  char *group_name;
+
+  if (feature)
+    {
+      valid_p = 1;
+      i = 0;
+      while (1)
+	{
+	  name = tdesc_find_register_name (feature, i);
+	  if (name)
+	    {
+	      valid_p &=
+		tdesc_numbered_register (feature, tdesc_data, (*reg_index)++,
+					 name);
+	      if (valid_p)
+		{
+		  group_name = tdesc_find_register_group_name (feature, i);
+		  if (group_name)
+		    create_register_group (gdbarch, group_name);
+		}
+	      i++;
+	    }
+	  else
+	    break;
+	}
+
+      if (!valid_p)
+	{
+	  tdesc_data_cleanup (tdesc_data);
+	  return -1;
+	}
+
+      return i;
+
+    }
+
+  return 0;
+}
 
 /* -------------------------------------------------------------------------- */
 /*!Architecture initialization for OpenRISC 1000
@@ -1859,6 +1998,12 @@ or1k_gdbarch_init (struct gdbarch_info  info,
   struct        gdbarch       *gdbarch;
   struct        gdbarch_tdep  *tdep;
   const struct  bfd_arch_info *binfo;
+  struct tdesc_arch_data      *tdesc_data = NULL;
+
+  int i;
+  int reg_index = 0;
+  int retval;
+  int group;
 
   /* Find a candidate among the list of pre-declared architectures.  */
   arches = gdbarch_list_lookup_by_info (arches, &info);
@@ -1971,6 +2116,68 @@ or1k_gdbarch_init (struct gdbarch_info  info,
                                     (gdbarch, or1k_single_step_through_delay);
     }
 
+ /* Check any target description for validity.  */
+  if (tdesc_has_registers (info.target_desc))
+    {
+
+      const struct tdesc_feature *feature;
+      int total_regs = 0;
+      int nb_features;
+      char feature_name[30];
+
+      tdesc_data = tdesc_data_alloc ();
+
+      /* OpenRisc architecture manual define a maximum of 32 registers groups */
+      for (group = 0; group < 32; group++)
+	{
+
+	  sprintf (feature_name, "org.gnu.gdb.or1k.group%d", group);
+	  feature = tdesc_find_feature (info.target_desc, feature_name);
+
+	  retval =
+	    get_feature_registers (feature, tdesc_data, &reg_index, gdbarch);
+
+	  if (retval < 0)
+	    {
+	      tdesc_data_cleanup (tdesc_data);
+	      return NULL;
+	    }
+	  else
+	    {
+	      total_regs += retval;
+	      if (retval && gdbarch_debug)
+		fprintf_unfiltered (gdb_stdout,
+				    "Found %4d registers in feature %s\n",
+				    retval, feature_name);
+	    }
+	}
+      if (gdbarch_debug)
+	fprintf_unfiltered (gdb_stdout,
+			    "Found %4d registers in the tdesc file\n",
+			    total_regs);
+
+      if (!total_regs)
+	{
+	  tdesc_data_cleanup (tdesc_data);
+	  return NULL;
+	}
+    }
+
+  if (tdesc_data)
+    {
+      tdesc_use_registers (gdbarch, info.target_desc, tdesc_data);
+
+      /* Override the normal target description methods to handle our
+         dual real and pseudo registers.  */
+      set_gdbarch_register_name (gdbarch, or1k_register_name);
+      set_gdbarch_register_reggroup_p (gdbarch, or1k_register_reggroup_p);
+
+      set_gdbarch_register_name (gdbarch, or1k_register_name);
+      set_gdbarch_sp_regnum (gdbarch, OR1K_SP_REGNUM);
+      set_gdbarch_pc_regnum (gdbarch, OR1K_NPC_REGNUM);
+      set_gdbarch_num_pseudo_regs (gdbarch, OR1K_NUM_PSEUDO_REGS);
+    }
+
   return gdbarch;
 
 }	/* or1k_gdbarch_init() */
@@ -3017,6 +3224,9 @@ _initialize_or1k_tdep (void)
      they have their BFD defined. */
   gdbarch_register (bfd_arch_or1k, or1k_gdbarch_init, or1k_dump_tdep);
 
+  /* Tell remote stub that we support XML target description.  */
+  register_remote_support_xml ("or1k");
+
   /* Commands to show and set special purpose registers */
   add_info ("spr", or1k_info_spr_command,
 	    "Show the value of a special purpose register");
Signature · 1 line
2.7.4
#8 lore raw

PATCH 8/18 gdb: or1k: change or1k_push_dummy_code stack alignment

In reply to Stafford Horne

From: Franck Jullien <[email protected]>

gdb/ChangeLog
* or1k-tdep.c (or1k_push_dummy_code) : Use or1k_frame_align to align the stack pointer.

---
 gdb/or1k-tdep.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
gdb/or1k-tdep.c +7 -3
index cb0871f..81bb541 100644
@@ -1173,10 +1173,14 @@ or1k_push_dummy_code (struct gdbarch *gdbarch,
 		      CORE_ADDR *bp_addr,
 		      struct regcache *regcache)
 {
-  /* Allocate space sufficient for a breakpoint, keeping the stack aligned.  */
-  sp = (sp - 4) & ~15;
+  CORE_ADDR bp_slot;
+
+  /* Reserve enough room on the stack for our breakpoint instruction.  */
+  bp_slot = sp - 4;
   /* Store the address of that breakpoint */
-  *bp_addr = sp;
+  *bp_addr = bp_slot;
+  /* keeping the stack aligned.  */
+  sp = or1k_frame_align (gdbarch, bp_slot);
   /* The call starts at the callee's entry point.  */
   *real_pc = function;
 
Signature · 1 line
2.7.4
#9 lore raw

PATCH 9/18 gdb: or1k: Silence gcc warning

In reply to Stafford Horne

From: Stefan Kristiansson <[email protected]>

gdb/ChangeLog:

* or1k-tdep.c (or1k_regset_from_core_section) : Silence gcc warning by using %z format for size_t.

---
 gdb/or1k-tdep.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
gdb/or1k-tdep.c +1 -1
index 81bb541..f938077 100644
@@ -1868,7 +1868,7 @@ or1k_regset_from_core_section (struct gdbarch *gdbarch,
 			       const char     *sect_name,
 			       size_t          sect_size)
 {
-  printf ("sect_name \"%s\", sect_size %d\n", sect_name, sect_size);
+  printf ("sect_name \"%s\", sect_size %zd\n", sect_name, sect_size);
   return NULL;
 
 }	/* or1k_regset_from_core_section () */
Signature · 1 line
2.7.4
#10 lore raw

PATCH 10/18 gdb: or1k: Fixes for things that broke after upstream merge

In reply to Stafford Horne

From: Stefan Kristiansson <[email protected]>

gdb/ChangeLog:

* or1k-tdep.c (or1k_fetch_instruction): Change char to gdb_byte to prevent pointer signedness error. (or1k_push_dummy_code): Likewise.

---
 gdb/or1k-tdep.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
gdb/or1k-tdep.c +7 -7
index f938077..ae57734 100644
@@ -164,7 +164,7 @@ or1k_fetch_instruction (struct gdbarch *gdbarch,
 			CORE_ADDR       addr)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  char            buf[OR1K_INSTLEN];
+  gdb_byte        buf[OR1K_INSTLEN];
   int             status;
 
   status = target_read_memory (addr, buf, OR1K_INSTLEN);
@@ -1247,8 +1247,8 @@ or1k_push_dummy_call (struct gdbarch  *gdbarch,
   /* Put as many args as possible in registers */
   for (argnum = 0; argnum < nargs; argnum++)
     {
-      char           *val;
-      char            valbuf[sizeof (ULONGEST) ];
+      const gdb_byte *val;
+      gdb_byte        valbuf[sizeof (ULONGEST)];
 
       struct value   *arg      = args[argnum];
       struct type    *arg_type = check_typedef (value_type (arg));
@@ -1266,7 +1266,7 @@ or1k_push_dummy_call (struct gdbarch  *gdbarch,
       else
 	{
 	  /* Everything else, we just get the value. */
-	  val = (char *) value_contents (arg);
+	  val = value_contents (arg);
 	}
 
       /* Stick the value in a register */
@@ -1346,8 +1346,8 @@ or1k_push_dummy_call (struct gdbarch  *gdbarch,
   /* Push the remaining args on the stack */
   for (argnum = first_stack_arg; argnum < nargs; argnum++)
     {
-      char           *val;
-      char            valbuf[sizeof (ULONGEST) ];
+      const gdb_byte *val;
+      gdb_byte        valbuf[sizeof (ULONGEST) ];
 
       struct value   *arg      = args[argnum];
       struct type    *arg_type = check_typedef (value_type (arg));
@@ -1364,7 +1364,7 @@ or1k_push_dummy_call (struct gdbarch  *gdbarch,
 	}
       else
 	{
-	  val = (char *) value_contents (arg);
+	  val = value_contents (arg);
 	}
 
       gdb_assert (len <= (bpw * 2));
Signature · 1 line
2.7.4
#11 lore raw

PATCH 11/18 Add gdb for or1k build

In reply to Stafford Horne

From: Stefan Wallentowitz <[email protected]>

* ChangeLog:

* configure.ac: remove logic adding gdb to noconfigsdirs for or1k
* configure: regenerate

---
 configure    | 7 -------
 configure.ac | 7 -------
 2 files changed, 14 deletions(-)
configure +0 -7
index a5f4fc5..0a23491 100755
@@ -3729,10 +3729,6 @@ case "${target}" in
     ;;
   *-*-rtems*)
     noconfigdirs="$noconfigdirs target-libgloss"
-    # this is not caught below because this stanza matches earlier
-    case $target in
-      or1k*-*-*) noconfigdirs="$noconfigdirs gdb" ;;
-    esac
     ;;
     # The tpf target doesn't support gdb yet.
   *-*-tpf*)
@@ -3940,9 +3936,6 @@ case "${target}" in
   nvptx*-*-*)
     noconfigdirs="$noconfigdirs target-libssp target-libstdc++-v3 target-libobjc"
     ;;
-  or1k*-*-*)
-    noconfigdirs="$noconfigdirs gdb"
-    ;;
   sh-*-* | sh64-*-*)
     case "${target}" in
       sh*-*-elf)
configure.ac +0 -7
index a27985c..ddaab5a 100644
@@ -1065,10 +1065,6 @@ case "${target}" in
     ;;
   *-*-rtems*)
     noconfigdirs="$noconfigdirs target-libgloss"
-    # this is not caught below because this stanza matches earlier
-    case $target in
-      or1k*-*-*) noconfigdirs="$noconfigdirs gdb" ;;
-    esac
     ;;
     # The tpf target doesn't support gdb yet.
   *-*-tpf*)
@@ -1276,9 +1272,6 @@ case "${target}" in
   nvptx*-*-*)
     noconfigdirs="$noconfigdirs target-libssp target-libstdc++-v3 target-libobjc"
     ;;
-  or1k*-*-*)
-    noconfigdirs="$noconfigdirs gdb"
-    ;;
   sh-*-* | sh64-*-*)
     case "${target}" in
       sh*-*-elf)
Signature · 1 line
2.7.4
#12 lore raw

PATCH 12/18 gdb: or1k: Apply changes of the last two years

In reply to Stafford Horne

From: Stefan Wallentowitz <[email protected]>

gdb/ChangeLog:

* or1k-tdep.c (or1k_analyse_inst): s/fatal/throw_quit/ (or1k_skip_prologue): use SYMTAB_COMPUNIT and COMPUNIT_DEBUGFORMAT
(or1k_frame_cache): s/fatal/throw_quit/ (or1k_regset_from_core_section): remove (or1k_iterate_over_regset_sections): create, blank implementation

---
 gdb/or1k-tdep.c | 44 ++++++++++++++++----------------------------
 1 file changed, 16 insertions(+), 28 deletions(-)
gdb/or1k-tdep.c +16 -28
index ae57734..8cfa440 100644
@@ -89,7 +89,7 @@
 
 #include "demangle.h"
 #include "defs.h"
-#include "gdb_string.h"
+#include <string.h>
 #include "frame.h"
 #include "inferior.h"
 #include "symtab.h"
@@ -260,7 +260,7 @@ or1k_analyse_inst (uint32_t    inst,
 	  /* Check we got something, and if so skip on */
 	  if (start_ptr == end_ptr)
 	    {
-	      fatal ("bitstring \"%s\" at offset %d has no length field.\n",
+	      throw_quit ("bitstring \"%s\" at offset %d has no length field.\n",
 		     format, i);
 	    }
 
@@ -271,7 +271,7 @@ or1k_analyse_inst (uint32_t    inst,
 	     just should not be wrong. */
 	  if ('b' != format[i++])
 	    {
-	      fatal ("bitstring \"%s\" at offset %d has no terminating 'b'.\n",
+	      throw_quit ("bitstring \"%s\" at offset %d has no terminating 'b'.\n",
 		     format, i);
 	    }
 
@@ -292,7 +292,7 @@ or1k_analyse_inst (uint32_t    inst,
 	  break;
 
 	default:
-	  fatal ("invalid character in bitstring \"%s\" at offset %d.\n",
+	  throw_quit ("invalid character in bitstring \"%s\" at offset %d.\n",
 		 format, i);
 	  break;
 	}
@@ -977,7 +977,8 @@ or1k_skip_prologue (struct gdbarch *gdbarch,
       if (0 != prologue_end)
   	{
 	  struct symtab_and_line  prologue_sal = find_pc_line (start_pc, 0);
-	  const char *debug_format = prologue_sal.symtab->debugformat;
+	  struct compunit_symtab *compunit = SYMTAB_COMPUNIT(prologue_sal.symtab);
+	  const char *debug_format = COMPUNIT_DEBUGFORMAT(compunit);
 
 	  if ((NULL != debug_format) && (strlen ("dwarf") <= strlen (debug_format))
 	      && (0 == strncasecmp ("dwarf", debug_format, strlen ("dwarf"))))
@@ -1575,7 +1576,7 @@ or1k_frame_cache (struct frame_info  *this_frame,
      are frameless and can give up here. */
   if (end_addr < start_addr)
     {
-      fatal ("end addr 0x%08x is less than start addr 0x%08x\n",
+      throw_quit ("end addr 0x%08x is less than start addr 0x%08x\n",
 	     (unsigned int) end_addr, (unsigned int) start_addr);
     }
 
@@ -1850,28 +1851,15 @@ or1k_frame_base_sniffer (struct frame_info *this_frame)
 }	/* or1k_frame_base_sniffer () */
 #endif
 
-
-/* -------------------------------------------------------------------------- */
-/*!Return information needed to handle a core file.
-
-   We put together a regset structure that tells the system how to transfer
-   registers to and from a core file image.
-
-   @param[in] gdbarch    The GDB architecture we are using.
-   @param[in] sect_name  The name of the section being considered.
-   @param[in] sect_size  The size of the section being considered.
-
-   @return  A regset structure for the section, or NULL if none is available. */
-/* -------------------------------------------------------------------------- */
-static const struct regset *
-or1k_regset_from_core_section (struct gdbarch *gdbarch,
-			       const char     *sect_name,
-			       size_t          sect_size)
+/* Iterate over core file register note sections.  */
+static void
+or1k_iterate_over_regset_sections (struct gdbarch *gdbarch,
+				   iterate_over_regset_sections_cb *cb,
+                                   void *cb_data,
+                                   const struct regcache *regcache)
 {
-  printf ("sect_name \"%s\", sect_size %zd\n", sect_name, sect_size);
-  return NULL;
-
-}	/* or1k_regset_from_core_section () */
+  // TODO: Do we need to put something here? (wallento)
+}
 
 /* -------------------------------------------------------------------------- */
 /*!Create a register group based on a group name.
@@ -2091,7 +2079,7 @@ or1k_gdbarch_init (struct gdbarch_info  info,
 #endif
 
   /* Handle core files */
-  set_gdbarch_regset_from_core_section (gdbarch, or1k_regset_from_core_section);
+  set_gdbarch_iterate_over_regset_sections (gdbarch, or1k_iterate_over_regset_sections);
 
   /* Frame unwinders. Use DWARF debug info if available, otherwise use our
      own unwinder. */
Signature · 1 line
2.7.4
#13 lore raw

PATCH 13/18 gdb: Add OpenRISC to texinfo menu

In reply to Stafford Horne

From: Stefan Wallentowitz <[email protected]>

Fixes an error during make install

gdb/ChangeLog:

* gdb/doc/gdb.texinfo: add openrisc to suppress an error

---
 gdb/doc/gdb.texinfo | 1 +
 1 file changed, 1 insertion(+)
gdb/doc/gdb.texinfo +1 -0
index 50f27b3..296534b 100644
@@ -22026,6 +22026,7 @@ acceptable commands.
 * M68K::                        Motorola M68K
 * MicroBlaze::			Xilinx MicroBlaze
 * MIPS Embedded::               MIPS Embedded
+* OpenRISC 1000::               OpenRISC 1000 (or1k)
 * PowerPC Embedded::            PowerPC Embedded
 * AVR::                         Atmel AVR
 * CRIS::                        CRIS
Signature · 1 line
2.7.4
#14 lore raw

PATCH 14/18 gdb: testsuite: Add or1k l.nop inscruction

In reply to Stafford Horne

The test case requires adding a nop instruction. For or1k the instruction is l.nop. This change uses the correct operation.

---
 gdb/testsuite/gdb.base/bp-permanent.c | 2 ++
 1 file changed, 2 insertions(+)
gdb/testsuite/gdb.base/bp-permanent.c +2 -0
index 541a89b..7e17dc7 100644
@@ -26,6 +26,8 @@
 
 #if defined(__s390__) || defined(__s390x__)
 #define NOP asm("nopr 0")
+#elif defined(__or1k__)
+#define NOP asm("l.nop")
 #else
 #define NOP asm("nop")
 #endif
Signature · 1 line
2.7.4
#15 lore raw

PATCH 15/18 gdb: or1k: Update calling conventions to help pass tests

In reply to Stafford Horne

The calling conventions for handling struct/array return, large scalars and variadic args were incomplete and causing several gdb testsuite tests to fail.

These changes were developed with help from olofk.

---
 gdb/or1k-tdep.c | 78 +++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 53 insertions(+), 25 deletions(-)
gdb/or1k-tdep.c +53 -25
index 8cfa440..a0fd651 100644
@@ -439,12 +439,12 @@ or1k_return_value (struct gdbarch  *gdbarch,
   unsigned int    rv_size    = TYPE_LENGTH (valtype);
   unsigned int    bpw        = (gdbarch_tdep (gdbarch))->bytes_per_word;
 
-  /* Deal with struct/union first. If this won't fit in a single register it
-     is returned in memory. Large (2 word) scalars are returned in r11 and r12
-     (this is a change from GCC 4.2.2, when they were apparently returned in
-     memory). */
-  if (((TYPE_CODE_STRUCT == rv_type) || (TYPE_CODE_UNION  == rv_type)) &&
-      (rv_size >  bpw))
+  /* Deal with struct/union as addresses. If an array won't fit in a single
+     register it is returned as address. Anything larger than 2 registers needs
+     to also be passed as address (this is from gcc default_return_in_memory) */
+  if ((TYPE_CODE_STRUCT == rv_type) || (TYPE_CODE_UNION == rv_type) ||
+      ((TYPE_CODE_ARRAY == rv_type) && rv_size > bpw) ||
+      (rv_size > 2*bpw))
     {
       if (readbuf)
 	{
@@ -1225,9 +1225,12 @@ or1k_push_dummy_call (struct gdbarch  *gdbarch,
   int             argnum;
   int             first_stack_arg;
   int             stack_offset = 0;
+  int             heap_offset = 0;
+  CORE_ADDR       heap_sp = sp - 128;
 
   unsigned int    bpa = (gdbarch_tdep (gdbarch))->bytes_per_address;
   unsigned int    bpw = (gdbarch_tdep (gdbarch))->bytes_per_word;
+  struct type *func_type = value_type (function);
 
   /* Return address */
   regcache_cooked_write_unsigned (regcache, OR1K_LR_REGNUM, bp_addr);
@@ -1237,7 +1240,6 @@ or1k_push_dummy_call (struct gdbarch  *gdbarch,
 
   /* Location for a returned structure. This is passed as a silent first
      argument. */
-
   if (struct_return)
     {
       regcache_cooked_write_unsigned (regcache, OR1K_FIRST_ARG_REGNUM,
@@ -1256,13 +1258,31 @@ or1k_push_dummy_call (struct gdbarch  *gdbarch,
       int             len      = arg_type->length;
       enum type_code  typecode = arg_type->main_type->code;
 
-      /* Handle the different argument types. */
-      if((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode))
+      if (TYPE_VARARGS (func_type) && argnum >= TYPE_NFIELDS(func_type))
+        {
+          break; /* end or regular args, varargs go to stack */
+        }
+
+      /* Extract the value, either a reference or the data */
+      if ((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode) || (len > bpw*2))
 	{
-	  /* The ABI passes all structures by reference, so get its address. */
-	  store_unsigned_integer (valbuf, bpa, byte_order, value_address (arg));
-	  len      = bpa;
-	  val      = valbuf;
+          CORE_ADDR valaddr = value_address (arg);
+
+          /* if the arg is fabricated (i.e. 3*i, instead of i) valaddr is undefined */
+          if (valaddr == 0) {
+              /* The argument needs to be copied into the target space. Since
+                 the bottom of the stack is reserved for function arguments
+                 we store this at the these at the top growing down. */
+              heap_offset += align_up (len, bpw);
+              valaddr = heap_sp + heap_offset;
+
+              write_memory (valaddr, value_contents(arg), len);
+          }
+
+          /* The ABI passes all structures by reference, so get its address. */
+          store_unsigned_integer (valbuf, bpa, byte_order, valaddr);
+          len      = bpa;
+          val      = valbuf;
 	}
       else
 	{
@@ -1273,9 +1293,7 @@ or1k_push_dummy_call (struct gdbarch  *gdbarch,
       /* Stick the value in a register */
       if(len > bpw)
 	{
-	  /* Big scalars use two registers, but need NOT be pair aligned. This
-	     code breaks if we can have quad-word scalars (e.g. long
-	     double). */
+	  /* Big scalars use two registers, but need NOT be pair aligned. */
 
 	  if (argreg <= (OR1K_LAST_ARG_REGNUM - 1))
 	    {
@@ -1286,8 +1304,6 @@ or1k_push_dummy_call (struct gdbarch  *gdbarch,
 	      ULONGEST      lo   = regval & mask;
 	      ULONGEST      hi   = regval >> bits_per_word;
 
-	      gdb_assert (len <= (bpw * 2));
-
 	      regcache_cooked_write_unsigned (regcache, argreg,     hi);
 	      regcache_cooked_write_unsigned (regcache, argreg + 1, lo);
 	      argreg += 2;
@@ -1328,7 +1344,7 @@ or1k_push_dummy_call (struct gdbarch  *gdbarch,
       int             len      = arg_type->length;
       enum type_code  typecode = arg_type->main_type->code;
 
-      if((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode))
+      if ((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode) || (len > bpw*2))
 	{
 	  /* Structures are passed as addresses */
 	  sp -= bpa;
@@ -1337,8 +1353,12 @@ or1k_push_dummy_call (struct gdbarch  *gdbarch,
 	{
 	/* Big scalars use more than one word. Code here allows for future
 	 quad-word entities (e.g. long double) */
-	  sp -= ((len + bpw - 1) / bpw) * bpw;
+	  sp -= align_up(len, bpw);
 	}
+
+      /* ensure our dummy heap doesn't touch the stack, this could only happen
+         if we have many arguments including fabricated arguments */
+      gdb_assert(heap_offset == 0 || ((heap_sp + heap_offset) < sp));
     }
 
   sp           = gdbarch_frame_align (gdbarch, sp);
@@ -1354,10 +1374,9 @@ or1k_push_dummy_call (struct gdbarch  *gdbarch,
       struct type    *arg_type = check_typedef (value_type (arg));
       int             len      = arg_type->length;
       enum type_code  typecode = arg_type->main_type->code;
-
       /* The EABI passes structures that do not fit in a register by
 	 reference. In all other cases, pass the structure by value.  */
-      if((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode))
+      if ((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode) || (len > bpw*2))
 	{
 	  store_unsigned_integer (valbuf, bpa, byte_order, value_address (arg));
 	  len      = bpa;
@@ -1368,15 +1387,24 @@ or1k_push_dummy_call (struct gdbarch  *gdbarch,
 	  val = value_contents (arg);
 	}
 
-      gdb_assert (len <= (bpw * 2));
+      while (len > 0)
+        {
+          int partial_len = (len < bpw ? len : bpw);
 
-      write_memory (sp + stack_offset, val, len);
-      stack_offset += ((len + bpw - 1) / bpw) * bpw;
+          write_memory (sp + stack_offset, val, partial_len);
+          stack_offset += align_up (partial_len, bpw);
+          len -= partial_len;
+          val += partial_len;
+        }
     }
 
   /* Save the updated stack pointer */
   regcache_cooked_write_unsigned (regcache, OR1K_SP_REGNUM, sp);
 
+  if (heap_offset > 0) {
+    sp = heap_sp;
+  }
+
   return sp;
 
 }	/* or1k_push_dummy_call() */
Signature · 1 line
2.7.4
#16 lore raw

PATCH 16/18 gdb: Remove corelow object from or1k linux build

In reply to Stafford Horne

Corelow is no longer needed in configure.tgt as its already included.

gdb/ChangeLog:

* configure.tgt: remove corelow for or1k

---
 gdb/configure.tgt | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
gdb/configure.tgt +4 -4
index 2c5418c..3a3df97 100644
@@ -423,7 +423,7 @@ nios2*-*-*)
 
 or1k-*-linux*)
 	# Target: OpenCores OpenRISC 1000 32-bit implementation for Linux
-	gdb_target_obs="or1k-tdep.o corelow.o"
+	gdb_target_obs="or1k-tdep.o"
 	gdb_sim=../sim/or1k/libsim.a
 	build_gdbserver=yes
 	;;
@@ -431,13 +431,13 @@ or1k-*-linux*)
 or1k-*-*)
 	# Target: OpenCores OpenRISC 1000 32-bit implementation bare metal
 	gdb_target_obs="or1k-tdep.o"
-    gdb_sim=../sim/or1k/libsim.a
+	gdb_sim=../sim/or1k/libsim.a
 	;;
 
 or1knd-*-linux*)
 	# Target: OpenCores OpenRISC 1000 32-bit implementation for Linux, without delay slot
-	gdb_target_obs="or1k-tdep.o corelow.o"
-    gdb_sim=../sim/or1k/libsim.a
+	gdb_target_obs="or1k-tdep.o"
+	gdb_sim=../sim/or1k/libsim.a
 	build_gdbserver=yes
 	;;
 
Signature · 1 line
2.7.4
#17 lore raw

PATCH 17/18 gdb: or1k: Updates for compiler type checking

In reply to Stafford Horne

There are several new compiler type checking enabled in latest build/toolchain. Fix issues where void* cannot be blindly cast to type* also issues with enum vs int.

gdb/ChangeLog:

* or1k-tdep.c (or1k_fetch_instruction): dont pass status directly to memory_error as they are different types (or1k_pseudo_register_read): return proper typed REG_UNKNOWN (or1k_frame_cache): cast result to trad_frame_cache (or1k_gdbarch_init): init gdbarch_tdep with XNEW

---
 gdb/or1k-tdep.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)
gdb/or1k-tdep.c +5 -10
index a0fd651..5aa0e7c 100644
@@ -87,9 +87,7 @@
    been removed.                                                             */
 /*---------------------------------------------------------------------------*/
 
-#include "demangle.h"
 #include "defs.h"
-#include <string.h>
 #include "frame.h"
 #include "inferior.h"
 #include "symtab.h"
@@ -165,13 +163,10 @@ or1k_fetch_instruction (struct gdbarch *gdbarch,
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   gdb_byte        buf[OR1K_INSTLEN];
-  int             status;
 
-  status = target_read_memory (addr, buf, OR1K_INSTLEN);
-
-  if (status)
+  if (target_read_memory (addr, buf, OR1K_INSTLEN))
     {
-      memory_error (status, addr);
+      memory_error (TARGET_XFER_E_IO, addr);
     }
 
   return  extract_unsigned_integer (buf, OR1K_INSTLEN, byte_order);
@@ -638,7 +633,7 @@ or1k_pseudo_register_read (struct gdbarch  *gdbarch,
 			   int              regnum,
 			   gdb_byte        *buf)
 {
-  return 0;
+  return REG_UNKNOWN;
 }	/* or1k_pseudo_register_read() */
 
 
@@ -1545,7 +1540,7 @@ or1k_frame_cache (struct frame_info  *this_frame,
   /* Nothing to do if we already have this info */
   if (NULL != *prologue_cache)
     {
-      return *prologue_cache;
+      return (struct trad_frame_cache *) *prologue_cache;
     }
 
   /* Get a new prologue cache and populate it with default values */
@@ -2037,7 +2032,7 @@ or1k_gdbarch_init (struct gdbarch_info  info,
      know which target we are talking to, but put in some defaults for now. */
 
   binfo                   = info.bfd_arch_info;
-  tdep                    = xmalloc (sizeof *tdep);
+  tdep                    = XNEW (struct gdbarch_tdep);
   tdep->num_matchpoints   = OR1K_MAX_MATCHPOINTS;
   tdep->num_gpr_regs      = OR1K_MAX_GPR_REGS;
   tdep->bytes_per_word    = binfo->bits_per_word    / binfo->bits_per_byte;
Signature · 1 line
2.7.4
#18 lore raw

PATCH 18/18 gdb: or1k: Refactor to new bp_kind_from_pc and pb_from_kind

In reply to Stafford Horne

Updates to mirror refactorings by Yao Qi in cd6c3b4ffc.

New gdbarch methods breakpoint_kind_from_pc and sw_breakpoint_from_kind

gdb/ChangeLog:

* or1k-tdep.c (or1k_breakpoint_kind_from_pc): New function (or1k_sw_breakpoint_from_kind): New function (or1k_breakpoint_from_pc): Remove

---
 gdb/or1k-tdep.c | 52 +++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 43 insertions(+), 9 deletions(-)
gdb/or1k-tdep.c +43 -9
index 5aa0e7c..dfaee96 100644
@@ -124,6 +124,14 @@
 
 
 
+/* Enum describing different kinds of breakpoints for or1k */
+
+enum or1k_breakpoint_kind
+{
+  /* 32-bit standard OpenRISC breakpoint */
+  OR1K_BP_KIND_OR1K = 2,
+};
+
 /* The gdbarch_tdep structure.  */
 
 /*! OR1K specific per-architecture information. Replaces
@@ -526,6 +534,25 @@ or1k_return_value (struct gdbarch  *gdbarch,
 }	/* or1k_return_value() */
 
 
+
+/*----------------------------------------------------------------------------*/
+/*!Determine the kind of breakpoint based on the current pc
+
+   Given the pc address, return the type of breapoint that should be used.
+   For or1k we only use one type which is a 32-bit trap instruction.
+
+   @param[in]  gdbarch  The GDB architecture being used
+   @param[in]  pcptr    The program counter address in question
+
+   @return  The breakpoint type */
+/*----------------------------------------------------------------------------*/
+
+static int
+or1k_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
+{
+  return OR1K_BP_KIND_OR1K;
+}	/* or1k_breakpoint_kind_from_pc() */
+
 /*----------------------------------------------------------------------------*/
 /*!Determine the instruction to use for a breakpoint.
 
@@ -543,16 +570,22 @@ or1k_return_value (struct gdbarch  *gdbarch,
 /*---------------------------------------------------------------------------*/
 
 static const gdb_byte *
-or1k_breakpoint_from_pc (struct gdbarch *gdbarch,
-			 CORE_ADDR      *bp_addr,
-			 int            *bp_size)
+or1k_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
 {
-  static const gdb_byte breakpoint[] = OR1K_BRK_INSTR_STRUCT;
 
-  *bp_size = OR1K_INSTLEN;
-  return breakpoint;
-
-}	/* or1k_breakpoint_from_pc() */
+  switch (kind)
+    {
+    case OR1K_BP_KIND_OR1K:
+      {
+        static const gdb_byte breakpoint[] = OR1K_BRK_INSTR_STRUCT;
+        
+        *size = OR1K_INSTLEN;
+        return breakpoint;
+      }
+    default:
+      gdb_assert_not_reached ("unexpected or1k breakpoint kind");
+    };
+}	/* or1k_sw_breakpoint_from_kind() */
 
 
 /*----------------------------------------------------------------------------*/
@@ -2056,7 +2089,8 @@ or1k_gdbarch_init (struct gdbarch_info  info,
 
   /* Information about the target architecture */
   set_gdbarch_return_value          (gdbarch, or1k_return_value);
-  set_gdbarch_breakpoint_from_pc    (gdbarch, or1k_breakpoint_from_pc);
+  set_gdbarch_breakpoint_kind_from_pc (gdbarch, or1k_breakpoint_kind_from_pc);
+  set_gdbarch_sw_breakpoint_from_kind (gdbarch, or1k_sw_breakpoint_from_kind);
   set_gdbarch_have_nonsteppable_watchpoint
                                     (gdbarch, 1);
 
Signature · 1 line
2.7.4
#19 lore raw

cover gdb: Port for OpenRISC

In reply to Stafford Horne
Quoted 7 lines · Stafford Horne

Hello,

This is the openrisc port of GDB that has been in openrisc repositories for a very long time. The main original author was Jeremy Bennett as can be seen in file copyrights. Other are willing to do what it takes for FSF copyright assignment.

Hi Stafford,
It is a new port in FSF GDB, and we want the quality of this new port is good enough, so the history of openrisc branch isn't very important in the patch review. Please put all or1k-tdep.{c,h} changes into a single patch, and the authors in the ChangeLog entry should be all the contributors to or1k-tdep.{c,h}. The target independent changes can still sit in each patch if necessary.

Please look at https://sourceware.org/gdb/wiki/ContributionChecklist

Signature · 1 line
Yao 
#20 lore raw

cover gdb: Port for OpenRISC

Quoted 9 lines · Yao Qi
Quoted 7 lines · Stafford Horne

Hello,

This is the openrisc port of GDB that has been in openrisc repositories for a very long time. The main original author was Jeremy Bennett as can be seen in file copyrights. Other are willing to do what it takes for FSF copyright assignment.

Quoted 7 lines

Hi Stafford,
It is a new port in FSF GDB, and we want the quality of this new port is good enough, so the history of openrisc branch isn't very important in the patch review. Please put all or1k-tdep.{c,h} changes into a single patch, and the authors in the ChangeLog entry should be all the contributors to or1k-tdep.{c,h}. The target independent changes can still sit in each patch if necessary.

Thanks I am working on this. Getting the changelog fixed up is taking time as not all authors over the years maintained this so well.

Quoted 1 line

Please look at https://sourceware.org/gdb/wiki/ContributionChecklist

Thanks this is helpful.

-Stafford