Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* RFA: ``set mips abi''
@ 2002-06-13 11:51 Daniel Jacobowitz
  2002-06-18 14:22 ` Andrew Cagney
  2002-06-19  9:45 ` Daniel Jacobowitz
  0 siblings, 2 replies; 8+ messages in thread
From: Daniel Jacobowitz @ 2002-06-13 11:51 UTC (permalink / raw)
  To: gdb-patches

As per our previous conversation.  This adds the user-settable knob, and
then sets the default to O32 when nothing else has a better suggestion.

OK to commit?

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer

2002-06-13  Daniel Jacobowitz  <drow@mvista.com>

	* mips-tdep.c (enum mips_abi): Explicitly start at 0.
	(mips_abi_string, mips_abi_strings): New.
	(struct gdbarch_tdep): Remove mips_abi_string, add found_abi.
	(mips_gdbarch_init): Set tdep->found_abi.  Don't set
	tdep->mips_abi_string.  Honor mips_abi_string.  Default to
	O32 if no ABI is found.
	(mips_dump_tdep): Use mips_abi_strings.
	(mips_abi_update): New function.
	(_initialize_mips_tdep): Initialize mips_abi_string.  Add
	``set mips abi'' and ``show mips abi''.

Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.76
diff -u -p -r1.76 mips-tdep.c
--- mips-tdep.c	11 Jun 2002 17:51:54 -0000	1.76
+++ mips-tdep.c	13 Jun 2002 18:25:23 -0000
@@ -61,7 +61,7 @@ enum
 
 enum mips_abi
   {
-    MIPS_ABI_UNKNOWN,
+    MIPS_ABI_UNKNOWN = 0,
     MIPS_ABI_N32,
     MIPS_ABI_O32,
     MIPS_ABI_O64,
@@ -69,6 +69,17 @@ enum mips_abi
     MIPS_ABI_EABI64
   };
 
+static const char *mips_abi_string;
+static const char *mips_abi_strings[] = {
+  "auto",
+  "n32",
+  "o32",
+  "o64",
+  "eabi32",
+  "eabi64",
+  NULL
+};
+
 struct frame_extra_info
   {
     mips_extra_func_info_t proc_desc;
@@ -117,7 +128,7 @@ struct gdbarch_tdep
 
     /* mips options */
     enum mips_abi mips_abi;
-    const char *mips_abi_string;
+    enum mips_abi found_abi;
     enum mips_fpu_type mips_fpu_type;
     int mips_last_arg_regnum;
     int mips_last_fp_arg_regnum;
@@ -4099,6 +4258,21 @@ mips_find_abi_section (bfd *abfd, asecti
     warning ("unsupported ABI %s.", name + 8);
 }
 
+static enum mips_abi
+global_mips_abi (void)
+{
+  int i = 0;
+
+  while (mips_abi_strings[i])
+    if (mips_abi_strings[i] == mips_abi_string)
+      return (enum mips_abi) i;
+    else
+      i ++;
+
+  internal_error (__FILE__, __LINE__,
+		  "unknown ABI string");
+}
+
 static struct gdbarch *
 mips_gdbarch_init (struct gdbarch_info info,
 		   struct gdbarch_list *arches)
@@ -4108,7 +4282,7 @@ mips_gdbarch_init (struct gdbarch_info i
   struct gdbarch *gdbarch;
   struct gdbarch_tdep *tdep;
   int elf_flags;
-  enum mips_abi mips_abi;
+  enum mips_abi mips_abi, found_abi, wanted_abi;
   enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
 
   /* Reset the disassembly info, in case it was set to something
@@ -4157,6 +4331,11 @@ mips_gdbarch_init (struct gdbarch_info i
   if (mips_abi == MIPS_ABI_UNKNOWN && info.abfd != NULL)
     bfd_map_over_sections (info.abfd, mips_find_abi_section, &mips_abi);
 
+  /* If we have no bfd, then mips_abi will still be MIPS_ABI_UNKNOWN.
+     Use the ABI from the last architecture if there is one.  */
+  if (info.abfd == NULL && arches != NULL)
+    mips_abi = gdbarch_tdep (arches->gdbarch)->found_abi;
+
   /* Try the architecture for any hint of the corect ABI */
   if (mips_abi == MIPS_ABI_UNKNOWN
       && info.bfd_arch_info != NULL
@@ -4177,11 +4356,22 @@ mips_gdbarch_init (struct gdbarch_info i
 	  break;
 	}
     }
+
 #ifdef MIPS_DEFAULT_ABI
   if (mips_abi == MIPS_ABI_UNKNOWN)
     mips_abi = MIPS_DEFAULT_ABI;
 #endif
 
+  if (mips_abi == MIPS_ABI_UNKNOWN)
+    mips_abi = MIPS_ABI_O32;
+
+  /* Now that we have found what the ABI for this binary would be,
+     check whether the user is overriding it.  */
+  found_abi = mips_abi;
+  wanted_abi = global_mips_abi ();
+  if (wanted_abi != MIPS_ABI_UNKNOWN)
+    mips_abi = wanted_abi;
+
   if (gdbarch_debug)
     {
       fprintf_unfiltered (gdb_stdlog,
@@ -4190,6 +4380,9 @@ mips_gdbarch_init (struct gdbarch_info i
       fprintf_unfiltered (gdb_stdlog,
 			  "mips_gdbarch_init: mips_abi = %d\n",
 			  mips_abi);
+      fprintf_unfiltered (gdb_stdlog,
+			  "mips_gdbarch_init: found_mips_abi = %d\n",
+			  found_abi);
     }
 
   /* try to find a pre-existing architecture */
@@ -4220,12 +4413,12 @@ mips_gdbarch_init (struct gdbarch_info i
   set_gdbarch_double_bit (gdbarch, 64);
   set_gdbarch_long_double_bit (gdbarch, 64);
   set_gdbarch_register_raw_size (gdbarch, mips_register_raw_size);
+  tdep->found_abi = found_abi;
   tdep->mips_abi = mips_abi;
 
   switch (mips_abi)
     {
     case MIPS_ABI_O32:
-      tdep->mips_abi_string = "o32";
       tdep->mips_default_saved_regsize = 4;
       tdep->mips_default_stack_argsize = 4;
       tdep->mips_fp_register_double = 0;
@@ -4239,7 +4432,6 @@ mips_gdbarch_init (struct gdbarch_info i
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
     case MIPS_ABI_O64:
-      tdep->mips_abi_string = "o64";
       tdep->mips_default_saved_regsize = 8;
       tdep->mips_default_stack_argsize = 8;
       tdep->mips_fp_register_double = 1;
@@ -4253,7 +4445,6 @@ mips_gdbarch_init (struct gdbarch_info i
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
     case MIPS_ABI_EABI32:
-      tdep->mips_abi_string = "eabi32";
       tdep->mips_default_saved_regsize = 4;
       tdep->mips_default_stack_argsize = 4;
       tdep->mips_fp_register_double = 0;
@@ -4267,7 +4458,6 @@ mips_gdbarch_init (struct gdbarch_info i
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
     case MIPS_ABI_EABI64:
-      tdep->mips_abi_string = "eabi64";
       tdep->mips_default_saved_regsize = 8;
       tdep->mips_default_stack_argsize = 8;
       tdep->mips_fp_register_double = 1;
@@ -4281,7 +4471,6 @@ mips_gdbarch_init (struct gdbarch_info i
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
     case MIPS_ABI_N32:
-      tdep->mips_abi_string = "n32";
       tdep->mips_default_saved_regsize = 4;
       tdep->mips_default_stack_argsize = 8;
       tdep->mips_fp_register_double = 1;
@@ -4306,19 +4495,8 @@ mips_gdbarch_init (struct gdbarch_info i
 	tm_print_insn_info.mach = bfd_mach_mips8000;
       break;
     default:
-      tdep->mips_abi_string = "default";
-      tdep->mips_default_saved_regsize = MIPS_REGSIZE;
-      tdep->mips_default_stack_argsize = MIPS_REGSIZE;
-      tdep->mips_fp_register_double = (REGISTER_VIRTUAL_SIZE (FP0_REGNUM) == 8);
-      tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
-      tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
-      tdep->mips_regs_have_home_p = 1;
-      tdep->gdb_target_is_mips64 = 0;
-      tdep->default_mask_address_p = 0;
-      set_gdbarch_long_bit (gdbarch, 32);
-      set_gdbarch_ptr_bit (gdbarch, 32);
-      set_gdbarch_long_long_bit (gdbarch, 64);
-      break;
+      internal_error (__FILE__, __LINE__,
+		      "unknown ABI in switch");
     }
 
   /* FIXME: jlarmour/2000-04-07: There *is* a flag EF_MIPS_32BIT_MODE
@@ -4430,6 +4608,17 @@ mips_gdbarch_init (struct gdbarch_info i
   return gdbarch;
 }
 
+static void mips_abi_update (char *ignore_args, int from_tty, 
+			     struct cmd_list_element *c)
+{
+  struct gdbarch_info info;
+
+  /* Force the architecture to update, and (if it's a MIPS architecture)
+     mips_gdbarch_init will take care of the rest.  */
+  gdbarch_info_init (&info);
+  gdbarch_update_p (info);
+}
+
 static void
 mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
 {
@@ -4471,7 +4660,7 @@ mips_dump_tdep (struct gdbarch *current_
       fprintf_unfiltered (file,
 			  "mips_dump_tdep: tdep->mips_abi = %d (%s)\n",
 			  tdep->mips_abi,
-			  tdep->mips_abi_string);
+			  mips_abi_strings[tdep->mips_abi]);
       fprintf_unfiltered (file,
 			  "mips_dump_tdep: mips_mask_address_p() %d (default %d)\n",
 			  mips_mask_address_p (),
@@ -4847,6 +5036,8 @@ _initialize_mips_tdep (void)
   static struct cmd_list_element *mipsfpulist = NULL;
   struct cmd_list_element *c;
 
+  mips_abi_string = mips_abi_strings [MIPS_ABI_UNKNOWN];
+
   gdbarch_register (bfd_arch_mips, mips_gdbarch_init, mips_dump_tdep);
   if (!tm_print_insn)		/* Someone may have already set it */
     tm_print_insn = gdb_print_insn_mips;
@@ -4888,6 +5079,21 @@ This option can be set to one of:\n\
           target and executable (default)",
 				       &setmipscmdlist),
 		     &showmipscmdlist);
+
+  /* Allow the user to override the ABI. */
+  c = add_set_enum_cmd
+    ("abi", class_obscure, mips_abi_strings, &mips_abi_string,
+     "Set the ABI used by this program.\n"
+     "This option can be set to one of:\n"
+     "  auto  - the default ABI associated with the current binary\n"
+     "  o32\n"
+     "  o64\n"
+     "  n32\n"
+     "  eabi32\n"
+     "  eabi64",
+     &setmipscmdlist);
+  add_show_from_set (c, &showmipscmdlist);
+  set_cmd_sfunc (c, mips_abi_update);
 
   /* Let the user turn off floating point and set the fence post for
      heuristic_proc_start.  */


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RFA: ``set mips abi''
  2002-06-13 11:51 RFA: ``set mips abi'' Daniel Jacobowitz
@ 2002-06-18 14:22 ` Andrew Cagney
  2002-06-18 14:34   ` Daniel Jacobowitz
  2002-06-19  9:45 ` Daniel Jacobowitz
  1 sibling, 1 reply; 8+ messages in thread
From: Andrew Cagney @ 2002-06-18 14:22 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

> 2002-06-13  Daniel Jacobowitz  <drow@mvista.com>
> 
> 	* mips-tdep.c (enum mips_abi): Explicitly start at 0.
> 	(mips_abi_string, mips_abi_strings): New.
> 	(struct gdbarch_tdep): Remove mips_abi_string, add found_abi.
> 	(mips_gdbarch_init): Set tdep->found_abi.  Don't set
> 	tdep->mips_abi_string.  Honor mips_abi_string.  Default to
> 	O32 if no ABI is found.
> 	(mips_dump_tdep): Use mips_abi_strings.
> 	(mips_abi_update): New function.
> 	(_initialize_mips_tdep): Initialize mips_abi_string.  Add
> 	``set mips abi'' and ``show mips abi''.
> 

I think the way to construct this table:

> +static const char *mips_abi_string;
> +static const char *mips_abi_strings[] = {
> +  "auto",
> +  "n32",
> +  "o32",
> +  "o64",
> +  "eabi32",
> +  "eabi64",
> +  NULL
> +};

is like:

> /* Various MIPS ISA options (related to stack analysis) can be
>    overridden dynamically.  Establish an enum/array for managing
>    them. */
> 
> static const char size_auto[] = "auto";
> static const char size_32[] = "32";
> static const char size_64[] = "64";
> 
> static const char *size_enums[] = {
>   size_auto,
>   size_32,
>   size_64,
>   0
> };

and then:

> static unsigned int
> mips_saved_regsize (void)
> {
>   if (mips_saved_regsize_string == size_auto)
>     return MIPS_DEFAULT_SAVED_REGSIZE;
>   else if (mips_saved_regsize_string == size_64)
>     return 8;
>   else /* if (mips_saved_regsize_string == size_32) */
>     return 4;
> }
> 

That avoids needing to keep the enum and string in sync.
(Having an enum mechanism that bound a number to a name would be nice).

Otherwize yes, ok.

enjoy,
Andrew



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RFA: ``set mips abi''
  2002-06-18 14:22 ` Andrew Cagney
@ 2002-06-18 14:34   ` Daniel Jacobowitz
  2002-06-18 15:26     ` Andrew Cagney
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2002-06-18 14:34 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

On Tue, Jun 18, 2002 at 05:22:28PM -0400, Andrew Cagney wrote:
> >2002-06-13  Daniel Jacobowitz  <drow@mvista.com>
> >
> >	* mips-tdep.c (enum mips_abi): Explicitly start at 0.
> >	(mips_abi_string, mips_abi_strings): New.
> >	(struct gdbarch_tdep): Remove mips_abi_string, add found_abi.
> >	(mips_gdbarch_init): Set tdep->found_abi.  Don't set
> >	tdep->mips_abi_string.  Honor mips_abi_string.  Default to
> >	O32 if no ABI is found.
> >	(mips_dump_tdep): Use mips_abi_strings.
> >	(mips_abi_update): New function.
> >	(_initialize_mips_tdep): Initialize mips_abi_string.  Add
> >	``set mips abi'' and ``show mips abi''.
> >
> 
> I think the way to construct this table:
> 
> >+static const char *mips_abi_string;
> >+static const char *mips_abi_strings[] = {
> >+  "auto",
> >+  "n32",
> >+  "o32",
> >+  "o64",
> >+  "eabi32",
> >+  "eabi64",
> >+  NULL
> >+};
> 
> is like:
> 
> >/* Various MIPS ISA options (related to stack analysis) can be
> >   overridden dynamically.  Establish an enum/array for managing
> >   them. */
> >
> >static const char size_auto[] = "auto";
> >static const char size_32[] = "32";
> >static const char size_64[] = "64";
> >
> >static const char *size_enums[] = {
> >  size_auto,
> >  size_32,
> >  size_64,
> >  0
> >};
> 
> and then:
> 
> >static unsigned int
> >mips_saved_regsize (void)
> >{
> >  if (mips_saved_regsize_string == size_auto)
> >    return MIPS_DEFAULT_SAVED_REGSIZE;
> >  else if (mips_saved_regsize_string == size_64)
> >    return 8;
> >  else /* if (mips_saved_regsize_string == size_32) */
> >    return 4;
> >}
> >
> 
> That avoids needing to keep the enum and string in sync.

If we didn't already have and need the enum all over that file, I'd
agree with you.  I don't see a point in all the extra globals.  But
hey, I don't mind.

> (Having an enum mechanism that bound a number to a name would be nice).

You can do it very easily with designated initializers, but they are
not adequately portable.  You can do it very easily building the array
at runtime but why bother?  Keeping two lists in sync is not the most
complicated thing in the world.

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RFA: ``set mips abi''
  2002-06-18 14:34   ` Daniel Jacobowitz
@ 2002-06-18 15:26     ` Andrew Cagney
  2002-06-18 15:34       ` Daniel Jacobowitz
  0 siblings, 1 reply; 8+ messages in thread
From: Andrew Cagney @ 2002-06-18 15:26 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

> 
> If we didn't already have and need the enum all over that file, I'd
> agree with you.  I don't see a point in all the extra globals.  But
> hey, I don't mind.

Yes, I noticed that.  I was thinking of just changing the global_...() 
function to be:

	if (mips_abi == mips_abi_o32)
	  return MIPS_ABI_O32;
	else if (...)
	..
	else
	  internal error()

so that the rest didn't need to be changed.  It is how it has been done 
in the past.

>> (Having an enum mechanism that bound a number to a name would be nice).

> You can do it very easily with designated initializers, but they are
> not adequately portable.  You can do it very easily building the array
> at runtime but why bother?  Keeping two lists in sync is not the most
> complicated thing in the world.

(what's a designated initializer?)

True, if there is a way to do it reliably though.

Andrew



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RFA: ``set mips abi''
  2002-06-18 15:26     ` Andrew Cagney
@ 2002-06-18 15:34       ` Daniel Jacobowitz
  2002-06-19  2:00         ` Andreas Schwab
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2002-06-18 15:34 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

On Tue, Jun 18, 2002 at 06:25:57PM -0400, Andrew Cagney wrote:
> >
> >If we didn't already have and need the enum all over that file, I'd
> >agree with you.  I don't see a point in all the extra globals.  But
> >hey, I don't mind.
> 
> Yes, I noticed that.  I was thinking of just changing the global_...() 
> function to be:
> 
> 	if (mips_abi == mips_abi_o32)
> 	  return MIPS_ABI_O32;
> 	else if (...)
> 	..
> 	else
> 	  internal error()
> 
> so that the rest didn't need to be changed.  It is how it has been done 
> in the past.

Then you've got a function and an enum to keep in sync.  That's even
more complicated than an array and an enum, in my opinion... not an
advantage at all.  I guess the internal_error will kick you if you do
that... I'll clean this up before I commit it.

> >>(Having an enum mechanism that bound a number to a name would be nice).
> 
> >You can do it very easily with designated initializers, but they are
> >not adequately portable.  You can do it very easily building the array
> >at runtime but why bother?  Keeping two lists in sync is not the most
> >complicated thing in the world.
> 
> (what's a designated initializer?)

I think I'm mixing terms here; I'm thinking of two language extensions
in GCC and c99.  The pertinent one is:

void *array[] = {
  [1] NULL,
  [2] some_void_ptr,
  [3] NULL,
};

I think you can use enum values as the tags but I'm not quite sure.

-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RFA: ``set mips abi''
  2002-06-18 15:34       ` Daniel Jacobowitz
@ 2002-06-19  2:00         ` Andreas Schwab
  0 siblings, 0 replies; 8+ messages in thread
From: Andreas Schwab @ 2002-06-19  2:00 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: gdb-patches

Daniel Jacobowitz <drow@mvista.com> writes:

|> > >You can do it very easily with designated initializers, but they are
|> > >not adequately portable.  You can do it very easily building the array
|> > >at runtime but why bother?  Keeping two lists in sync is not the most
|> > >complicated thing in the world.
|> > 
|> > (what's a designated initializer?)
|> 
|> I think I'm mixing terms here; I'm thinking of two language extensions
|> in GCC and c99.  The pertinent one is:

The term is correct, but the C99 syntax is different.

|> void *array[] = {
|>   [1] NULL,
|>   [2] some_void_ptr,
|>   [3] NULL,
|> };

void *array[] = {
  [1] = NULL,
  [2] = some_void_ptr,
  [3] = NULL,
};

|> I think you can use enum values as the tags but I'm not quite sure.

You can use any constant expression in an array designator.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RFA: ``set mips abi''
  2002-06-13 11:51 RFA: ``set mips abi'' Daniel Jacobowitz
  2002-06-18 14:22 ` Andrew Cagney
@ 2002-06-19  9:45 ` Daniel Jacobowitz
  2002-06-19 11:43   ` Andrew Cagney
  1 sibling, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2002-06-19  9:45 UTC (permalink / raw)
  To: gdb-patches

On Thu, Jun 13, 2002 at 02:51:51PM -0400, Daniel Jacobowitz wrote:
> As per our previous conversation.  This adds the user-settable knob, and
> then sets the default to O32 when nothing else has a better suggestion.
> 
> OK to commit?

Here's what I checked in.  I compromised; I filed a PR saying we need a
standard mechanism for matching string->enum in order to postpone the
discussion, and I added a static check that the size of the two match.


-- 
Daniel Jacobowitz                           Carnegie Mellon University
MontaVista Software                         Debian GNU/Linux Developer

2002-06-19  Daniel Jacobowitz  <drow@mvista.com>

	* mips-tdep.c (enum mips_abi): Explicitly start at 0.  Add
	MIPS_ABI_LAST.
	(mips_abi_string, mips_abi_strings): New.
	(struct gdbarch_tdep): Remove mips_abi_string, add found_abi.
	(mips_gdbarch_init): Set tdep->found_abi.  Don't set
	tdep->mips_abi_string.  Honor mips_abi_string.  Default to
	O32 if no ABI is found.
	(mips_dump_tdep): Use mips_abi_strings.
	(mips_abi_update): New function.
	(_initialize_mips_tdep): Initialize mips_abi_string.  Add
	``set mips abi'' and ``show mips abi''.  Check the size of
	mips_abi_strings.

Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.80
diff -u -p -r1.80 mips-tdep.c
--- mips-tdep.c	17 Jun 2002 23:32:32 -0000	1.80
+++ mips-tdep.c	19 Jun 2002 16:27:01 -0000
@@ -61,14 +61,27 @@ enum
 
 enum mips_abi
   {
-    MIPS_ABI_UNKNOWN,
+    MIPS_ABI_UNKNOWN = 0,
     MIPS_ABI_N32,
     MIPS_ABI_O32,
     MIPS_ABI_O64,
     MIPS_ABI_EABI32,
-    MIPS_ABI_EABI64
+    MIPS_ABI_EABI64,
+    MIPS_ABI_LAST
   };
 
+static const char *mips_abi_string;
+
+static const char *mips_abi_strings[] = {
+  "auto",
+  "n32",
+  "o32",
+  "o64",
+  "eabi32",
+  "eabi64",
+  NULL
+};
+
 struct frame_extra_info
   {
     mips_extra_func_info_t proc_desc;
@@ -117,7 +130,7 @@ struct gdbarch_tdep
 
     /* mips options */
     enum mips_abi mips_abi;
-    const char *mips_abi_string;
+    enum mips_abi found_abi;
     enum mips_fpu_type mips_fpu_type;
     int mips_last_arg_regnum;
     int mips_last_fp_arg_regnum;
@@ -4247,6 +4260,19 @@ mips_find_abi_section (bfd *abfd, asecti
     warning ("unsupported ABI %s.", name + 8);
 }
 
+static enum mips_abi
+global_mips_abi (void)
+{
+  int i;
+
+  for (i = 0; mips_abi_strings[i] != NULL; i++)
+    if (mips_abi_strings[i] == mips_abi_string)
+      return (enum mips_abi) i;
+
+  internal_error (__FILE__, __LINE__,
+		  "unknown ABI string");
+}
+
 static struct gdbarch *
 mips_gdbarch_init (struct gdbarch_info info,
 		   struct gdbarch_list *arches)
@@ -4256,7 +4282,7 @@ mips_gdbarch_init (struct gdbarch_info i
   struct gdbarch *gdbarch;
   struct gdbarch_tdep *tdep;
   int elf_flags;
-  enum mips_abi mips_abi;
+  enum mips_abi mips_abi, found_abi, wanted_abi;
   enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
 
   /* Reset the disassembly info, in case it was set to something
@@ -4305,6 +4331,11 @@ mips_gdbarch_init (struct gdbarch_info i
   if (mips_abi == MIPS_ABI_UNKNOWN && info.abfd != NULL)
     bfd_map_over_sections (info.abfd, mips_find_abi_section, &mips_abi);
 
+  /* If we have no bfd, then mips_abi will still be MIPS_ABI_UNKNOWN.
+     Use the ABI from the last architecture if there is one.  */
+  if (info.abfd == NULL && arches != NULL)
+    mips_abi = gdbarch_tdep (arches->gdbarch)->found_abi;
+
   /* Try the architecture for any hint of the corect ABI */
   if (mips_abi == MIPS_ABI_UNKNOWN
       && info.bfd_arch_info != NULL
@@ -4325,11 +4356,22 @@ mips_gdbarch_init (struct gdbarch_info i
 	  break;
 	}
     }
+
 #ifdef MIPS_DEFAULT_ABI
   if (mips_abi == MIPS_ABI_UNKNOWN)
     mips_abi = MIPS_DEFAULT_ABI;
 #endif
 
+  if (mips_abi == MIPS_ABI_UNKNOWN)
+    mips_abi = MIPS_ABI_O32;
+
+  /* Now that we have found what the ABI for this binary would be,
+     check whether the user is overriding it.  */
+  found_abi = mips_abi;
+  wanted_abi = global_mips_abi ();
+  if (wanted_abi != MIPS_ABI_UNKNOWN)
+    mips_abi = wanted_abi;
+
   if (gdbarch_debug)
     {
       fprintf_unfiltered (gdb_stdlog,
@@ -4338,6 +4380,9 @@ mips_gdbarch_init (struct gdbarch_info i
       fprintf_unfiltered (gdb_stdlog,
 			  "mips_gdbarch_init: mips_abi = %d\n",
 			  mips_abi);
+      fprintf_unfiltered (gdb_stdlog,
+			  "mips_gdbarch_init: found_mips_abi = %d\n",
+			  found_abi);
     }
 
   /* try to find a pre-existing architecture */
@@ -4368,12 +4413,12 @@ mips_gdbarch_init (struct gdbarch_info i
   set_gdbarch_double_bit (gdbarch, 64);
   set_gdbarch_long_double_bit (gdbarch, 64);
   set_gdbarch_register_raw_size (gdbarch, mips_register_raw_size);
+  tdep->found_abi = found_abi;
   tdep->mips_abi = mips_abi;
 
   switch (mips_abi)
     {
     case MIPS_ABI_O32:
-      tdep->mips_abi_string = "o32";
       tdep->mips_default_saved_regsize = 4;
       tdep->mips_default_stack_argsize = 4;
       tdep->mips_fp_register_double = 0;
@@ -4387,7 +4432,6 @@ mips_gdbarch_init (struct gdbarch_info i
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
     case MIPS_ABI_O64:
-      tdep->mips_abi_string = "o64";
       tdep->mips_default_saved_regsize = 8;
       tdep->mips_default_stack_argsize = 8;
       tdep->mips_fp_register_double = 1;
@@ -4401,7 +4445,6 @@ mips_gdbarch_init (struct gdbarch_info i
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
     case MIPS_ABI_EABI32:
-      tdep->mips_abi_string = "eabi32";
       tdep->mips_default_saved_regsize = 4;
       tdep->mips_default_stack_argsize = 4;
       tdep->mips_fp_register_double = 0;
@@ -4415,7 +4458,6 @@ mips_gdbarch_init (struct gdbarch_info i
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
     case MIPS_ABI_EABI64:
-      tdep->mips_abi_string = "eabi64";
       tdep->mips_default_saved_regsize = 8;
       tdep->mips_default_stack_argsize = 8;
       tdep->mips_fp_register_double = 1;
@@ -4429,7 +4471,6 @@ mips_gdbarch_init (struct gdbarch_info i
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
     case MIPS_ABI_N32:
-      tdep->mips_abi_string = "n32";
       tdep->mips_default_saved_regsize = 4;
       tdep->mips_default_stack_argsize = 8;
       tdep->mips_fp_register_double = 1;
@@ -4454,19 +4495,8 @@ mips_gdbarch_init (struct gdbarch_info i
 	tm_print_insn_info.mach = bfd_mach_mips8000;
       break;
     default:
-      tdep->mips_abi_string = "default";
-      tdep->mips_default_saved_regsize = MIPS_REGSIZE;
-      tdep->mips_default_stack_argsize = MIPS_REGSIZE;
-      tdep->mips_fp_register_double = (REGISTER_VIRTUAL_SIZE (FP0_REGNUM) == 8);
-      tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
-      tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
-      tdep->mips_regs_have_home_p = 1;
-      tdep->gdb_target_is_mips64 = 0;
-      tdep->default_mask_address_p = 0;
-      set_gdbarch_long_bit (gdbarch, 32);
-      set_gdbarch_ptr_bit (gdbarch, 32);
-      set_gdbarch_long_long_bit (gdbarch, 64);
-      break;
+      internal_error (__FILE__, __LINE__,
+		      "unknown ABI in switch");
     }
 
   /* FIXME: jlarmour/2000-04-07: There *is* a flag EF_MIPS_32BIT_MODE
@@ -4579,6 +4609,18 @@ mips_gdbarch_init (struct gdbarch_info i
 }
 
 static void
+mips_abi_update (char *ignore_args, int from_tty, 
+		 struct cmd_list_element *c)
+{
+  struct gdbarch_info info;
+
+  /* Force the architecture to update, and (if it's a MIPS architecture)
+     mips_gdbarch_init will take care of the rest.  */
+  gdbarch_info_init (&info);
+  gdbarch_update_p (info);
+}
+
+static void
 mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
@@ -4619,7 +4661,7 @@ mips_dump_tdep (struct gdbarch *current_
       fprintf_unfiltered (file,
 			  "mips_dump_tdep: tdep->mips_abi = %d (%s)\n",
 			  tdep->mips_abi,
-			  tdep->mips_abi_string);
+			  mips_abi_strings[tdep->mips_abi]);
       fprintf_unfiltered (file,
 			  "mips_dump_tdep: mips_mask_address_p() %d (default %d)\n",
 			  mips_mask_address_p (),
@@ -4995,6 +5037,11 @@ _initialize_mips_tdep (void)
   static struct cmd_list_element *mipsfpulist = NULL;
   struct cmd_list_element *c;
 
+  mips_abi_string = mips_abi_strings [MIPS_ABI_UNKNOWN];
+  if (MIPS_ABI_LAST + 1
+      != sizeof (mips_abi_strings) / sizeof (mips_abi_strings[0]))
+    internal_error (__FILE__, __LINE__, "mips_abi_strings out of sync");
+
   gdbarch_register (bfd_arch_mips, mips_gdbarch_init, mips_dump_tdep);
   if (!tm_print_insn)		/* Someone may have already set it */
     tm_print_insn = gdb_print_insn_mips;
@@ -5036,6 +5083,21 @@ This option can be set to one of:\n\
           target and executable (default)",
 				       &setmipscmdlist),
 		     &showmipscmdlist);
+
+  /* Allow the user to override the ABI. */
+  c = add_set_enum_cmd
+    ("abi", class_obscure, mips_abi_strings, &mips_abi_string,
+     "Set the ABI used by this program.\n"
+     "This option can be set to one of:\n"
+     "  auto  - the default ABI associated with the current binary\n"
+     "  o32\n"
+     "  o64\n"
+     "  n32\n"
+     "  eabi32\n"
+     "  eabi64",
+     &setmipscmdlist);
+  add_show_from_set (c, &showmipscmdlist);
+  set_cmd_sfunc (c, mips_abi_update);
 
   /* Let the user turn off floating point and set the fence post for
      heuristic_proc_start.  */


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: RFA: ``set mips abi''
  2002-06-19  9:45 ` Daniel Jacobowitz
@ 2002-06-19 11:43   ` Andrew Cagney
  0 siblings, 0 replies; 8+ messages in thread
From: Andrew Cagney @ 2002-06-19 11:43 UTC (permalink / raw)
  To: Daniel Jacobowitz; +Cc: gdb-patches

> 
> Here's what I checked in.  I compromised; I filed a PR saying we need a
> standard mechanism for matching string->enum in order to postpone the
> discussion, and I added a static check that the size of the two match.

:-)

Andrew



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2002-06-19 18:43 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-06-13 11:51 RFA: ``set mips abi'' Daniel Jacobowitz
2002-06-18 14:22 ` Andrew Cagney
2002-06-18 14:34   ` Daniel Jacobowitz
2002-06-18 15:26     ` Andrew Cagney
2002-06-18 15:34       ` Daniel Jacobowitz
2002-06-19  2:00         ` Andreas Schwab
2002-06-19  9:45 ` Daniel Jacobowitz
2002-06-19 11:43   ` Andrew Cagney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox