This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RFA: Recording MIPS ABI selection in binaries



Hi Guys,

  There is a problem with the MIPS port.  There is no way for GDB to
  tell if a binary has been produced with the -mgp32 option.  This
  means that attempts to debug such binaries will usually fail
  horribly, since GDB has the wrong idea about the size of various
  types and so on.

  This kind of problem used to be solved by setting a flag bit in the
  file header, but in this case the appropriate bit has already been
  taken by the 64 bit binaries, so I have come up with a different
  solution.

  My solution is to have GCC create an empty, uniquely named section
  indicating the ABI in use.  GDB then detects the presence of this
  section and selects the ABI appropriately.  If it does not find the
  section then it goes back to its old method of examining the flags
  in the ELF header.

  I have tested the patch and it reduces the number of GDB testsuite
  failures from 1280 to 450 when the -mgp32 switch is used.

  This patch has the advantage of being simple - no changes are needed
  to the assembler or linker and only mips specific code in GCC and
  GDB are affected - and space efficient - the sections are empty,
  only occupy a small amount of space in the binary, do not get
  loaded into memory, and get merged together when the object files
  are linked.  But perhaps there is a better solution in creating a
  .note section instead, I am not sure.

  The problem as I see it with creating a .note section, is that the
  notes in the section will not be merged together when the object
  files are linked together.  Thus the section could start taking up a
  non-trivial amount of space in the resultant binary.  It is also
  more complex for GDB if it has to read in the .note section's
  contents and then parse them.

  So, I am presenting my patch below for discussion and possible
  approval.  What do people think ?

Cheers
	Nick


gcc ChangeLog:
2000-08-08  Nick Clifton  <nickc@cygnus.com>

	* config/mips/mips.c (mips_asm_file_start): Create a
	.mdebug.XXX section where XXX is the ABI in use.

gdb ChangeLog:
2000-08-08  Nick Clifton  <nickc@cygnus.com>

	* mips-tdep.c (mips_gdbarch_init): Scan for a .mdebug.XXX
	section and initialise the ABI from that, if found.


Index: gcc/config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mips/mips.c,v
retrieving revision 1.96
diff -p -r1.96 mips.c
*** mips.c	2000/08/08 01:17:06	1.96
- --- mips.c	2000/08/08 20:55:35
*************** void
*** 5907,5912 ****
- --- 5907,5914 ----
  mips_asm_file_start (stream)
       FILE *stream;
  {
+   const char * abi_string = NULL;
+   
    ASM_OUTPUT_SOURCE_FILENAME (stream, main_input_filename);
  
    /* Versions of the MIPS assembler before 2.20 generate errors if a branch
*************** mips_asm_file_start (stream)
*** 5916,5921 ****
- --- 5918,5943 ----
  
    if (TARGET_MIPS_AS && optimize && flag_delayed_branch)
      fprintf (stream, "\t.set\tnobopt\n");
+ 
+   /* Generate a special section to describe the ABI switches used to produce
+      the resultant binary.  This used to be done by the assembler setting bits
+      in the ELF header's flags field, but we have run out of bits.  GDB needs
+      this information in order to be able to correctly debug these binaries.
+      See the function mips_gdbarch_init() in gdb/mips-tdep.c.  */
+   switch (mips_abi)
+     {
+     case ABI_32:   abi_string = "abi32"; break;
+     case ABI_N32:  abi_string = "abiN32"; break;
+     case ABI_64:   abi_string = "abi64"; break;
+     case ABI_O64:  abi_string = "abiO64"; break;
+     case ABI_EABI: abi_string = TARGET_64BIT ? "eabi64" : "eabi32"; break;
+     default:
+       abort ();
+     }
+   fprintf (stream, "\t.section .mdebug.%s\n", abi_string);
+ 
+   /* Restore the default section.  */
+   fprintf (stream, "\t.section .text\n");
  
    /* Generate the pseudo ops that System V.4 wants.  */
  #ifndef ABICALLS_ASM_OP

Index: gdb/mips-tdep.c
===================================================================
RCS file: /cvs/src//src/gdb/mips-tdep.c,v
retrieving revision 1.29
diff -p -w -r1.29 mips-tdep.c
*** mips-tdep.c	2000/07/30 01:48:26	1.29
- --- mips-tdep.c	2000/08/08 20:57:40
*************** mips_gdbarch_init (struct gdbarch_info i
*** 3813,3828 ****
    {0};
    struct gdbarch *gdbarch;
    struct gdbarch_tdep *tdep;
!   int elf_flags;
!   enum mips_abi mips_abi;
  
!   /* Extract the elf_flags if available */
    if (info.abfd != NULL
        && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
      elf_flags = elf_elfheader (info.abfd)->e_flags;
    else
!     elf_flags = 0;
  
    /* Check ELF_FLAGS to see if it specifies the ABI being used. */
    switch ((elf_flags & EF_MIPS_ABI))
      {
- --- 3813,3873 ----
    {0};
    struct gdbarch *gdbarch;
    struct gdbarch_tdep *tdep;
!   int elf_flags = 0;
!   enum mips_abi mips_abi = MIPS_ABI_UNKNOWN;
  
!   /* Extract the elf_flags if available.  */
    if (info.abfd != NULL
        && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
+     {
+       asection * note;
+       const char * abi_sec = ".mdebug.";
+       
        elf_flags = elf_elfheader (info.abfd)->e_flags;
+       
+       /* See if there is a .mdebug.XXX section.  If there is, treat its
+ 	 name as ABI information.  GCC may have produced this section for
+          us.  See the function mips_asm_file_start() in gcc/config/mips/mips.c.  */
+       for (note = info.abfd->sections; note != NULL; note = note->next)
+ 	{
+ 	  if (strncmp (note->name, abi_sec, strlen (abi_sec)) == 0)
+ 	    {
+ 	      struct
+ 	      {
+ 		const char *  abi_name;
+ 		enum mips_abi mips_abi;
+ 	      }
+ 	      names [] =
+ 	      {
+ 		{ "abi32",  MIPS_ABI_O32 },
+ 		{ "abiN32", MIPS_ABI_N32 },
+ 		{ "abi64",  MIPS_ABI_O64 },
+ 		{ "abiO64", MIPS_ABI_O64 },
+ 		{ "eabi32", MIPS_ABI_EABI32 },
+ 		{ "eabi64", MIPS_ABI_EABI64 },
+ 		{ NULL,     MIPS_ABI_UNKNOWN }
+ 	      };
+ 	      int i;
+ 
+ 	      for (i = 0; names[i].abi_name != NULL; i++)
+ 		if (strcmp (note->name + strlen (abi_sec), names[i].abi_name) == 0)
+ 		  break;
+ 
+ 	      if (names[i].abi_name == NULL)
+ 		printf_filtered ("Warning: Unrecognised MIPS ABI section '%s'\n",
+ 				 note->name);
+ 	      else
+ 		if (   mips_abi != MIPS_ABI_UNKNOWN
+ 		    && mips_abi != names[i].mips_abi)
+ 		  printf_filtered ("Warning: Multiple differing MIPS ABI sections\n");
  	      else
! 		mips_abi = names[i].mips_abi;
! 	    }
! 	}
!     }
  
+   if (mips_abi == MIPS_ABI_UNKNOWN)
+     {
        /* Check ELF_FLAGS to see if it specifies the ABI being used. */
        switch ((elf_flags & EF_MIPS_ABI))
  	{
*************** mips_gdbarch_init (struct gdbarch_info i
*** 3845,3850 ****
- --- 3889,3895 ----
  	    mips_abi = MIPS_ABI_UNKNOWN;
  	  break;
  	}
+     }
  
    /* Try the architecture for any hint of the corect ABI */
    if (mips_abi == MIPS_ABI_UNKNOWN
*************** mips_gdbarch_init (struct gdbarch_info i
*** 4010,4016 ****
       and not all gcc targets support that currently. Therefore using
       this flag to detect 32-bit mode would do the wrong thing given
       the current gcc - it would make GDB treat these 64-bit programs
!      as 32-bit programs by default. */
  
    /* enable/disable the MIPS FPU */
    if (!mips_fpu_type_auto)
- --- 4055,4066 ----
       and not all gcc targets support that currently. Therefore using
       this flag to detect 32-bit mode would do the wrong thing given
       the current gcc - it would make GDB treat these 64-bit programs
!      as 32-bit programs by default.
! 
!      FIXED: nickc/2000-08-08: GCC now creates a special, empty section
!      whoes name indicates the ABI that is in used.  There is now code
!      at the start of this funciton to detect this section and set up the
!      ABI selection appropriately.  */
  
    /* enable/disable the MIPS FPU */
    if (!mips_fpu_type_auto)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]