This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix links against /usr/lib/libc.so on IRIX


_bfd_mips_elf_section_from_shdr is quite strict about what sections
it accepts:

     bfd_boolean
     _bfd_mips_elf_section_from_shdr (bfd *abfd,
                                      Elf_Internal_Shdr *hdr,
                                      const char *name,
                                      int shindex)
     {
       flagword flags = 0;

       /* There ought to be a place to keep ELF backend specific flags, but
          at the moment there isn't one.  We just keep track of the
          sections by their name, instead.  Fortunately, the ABI gives
          suggested names for all the MIPS specific sections, so we will
          probably get away with this.  */
       switch (hdr->sh_type)
         {
         case SHT_MIPS_LIBLIST:
           if (strcmp (name, ".liblist") != 0)
             return FALSE;
           break;
         case SHT_MIPS_MSYM:
           if (strcmp (name, ".msym") != 0)
             return FALSE;
           break;
         .....
         default:
           return FALSE;
         }

In other words, it only accepts sections that have a recognised
section/name combination.

In older sources, bfd_section_from_shdr used to ignore the return
value of the function:

    default:
      /* Check for any processor-specific section types.  */
      {
        if (bed->elf_backend_section_from_shdr)
          (*bed->elf_backend_section_from_shdr) (abfd, hdr, name);
      }
      break;

and the (probably unintentional) effect of returning FALSE was to
silently drop sections with unrecognised name/type combinations.
bfd_section_from_shdr now handles a false return correctly:

    default:
      /* Check for any processor-specific section types.  */
      return bed->elf_backend_section_from_shdr (abfd, hdr, name,
						 shindex);

This breaks bootstrap for IRIX because of two unexpected combinations:

  (1) We expect SHT_MIPS_OPTIONS sections to be called ".MIPS.options"
      on NewABI targets and ".options" on o32 targets, but the IRIX o32
      /usr/lib/libc.so has a .MIPS.options section.

  (2) We don't handle section types like SHT_MIPS_XLATE (the ABI doesn't
      list specific section names for it).  This prevents links against
      the system NewABI libraries, which have SHT_MIPS_XLATE sections.

One fix would be to return the old behaviour of silently dropping
unrecognised sections.  It's stood the test of time, but it hardly
seems like the Right Thing.

Another fix would be to accept all section/type combinations.  This is
exactly what the default ELF implementation does.  I'm quite happy to
go this route in principle, but it might cause problems with code that
manipulates the contents of certain sections based on their section type.
SHT_MIPS_REGINFO is the one I'm most worried about.

Instead, I went for the compromise below, which I think should be safe
enough for 2.16.  It deals with (1) by accepting either of the known
SHT_MIPS_OPTIONS names.  We have to recognise them in three places:

  - _bfd_mips_elf_section_from_shdr itself
  - _bfd_mips_elf_fake_sections, which sets the output section type
  - _bfd_mips_elf_set_section_contents, which updates the options' gp value

It deals with (2) by accepting any section with a type that we do not
want to handle specially, just like the generic ELF implementation does.
This should be OK for SHT_MIPS_XLATE sections because we don't normally
link them anyway (even when we don't silently drop them here).  I think
the same goes for the other unhandled SHT_MIPS_* types.

Tested by bootstrapping and regression testing gcc on mips-sgi-irix6.5
with 2.16.  OK for branch and mainline?

Richard


bfd/
	* elfxx-mips.c (MIPS_ELF_OPTIONS_SECTION_NAME_P): New macro.
	(_bfd_mips_elf_section_from_shdr): Use it to check for recognized
	SHT_MIPS_OPTIONS names.  Allow all sections with unrecognised
	section flags.
	(_bfd_mips_elf_fake_sections): Use MIPS_ELF_OPTIONS_SECTION_NAME_P
	to check for SHT_MIPS_OPTIONS sections.
	(_bfd_mips_elf_set_section_contents): Likewise.

Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.129
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.129 elfxx-mips.c
--- bfd/elfxx-mips.c	24 Mar 2005 22:47:51 -0000	1.129
+++ bfd/elfxx-mips.c	3 Apr 2005 18:33:14 -0000
@@ -478,6 +478,11 @@ #define SGI_COMPAT(abfd) \
 #define MIPS_ELF_OPTIONS_SECTION_NAME(abfd) \
   (NEWABI_P (abfd) ? ".MIPS.options" : ".options")
 
+/* True if NAME is the recognized name of any SHT_MIPS_OPTIONS section.
+   Some IRIX system files do not use MIPS_ELF_OPTIONS_SECTION_NAME.  */
+#define MIPS_ELF_OPTIONS_SECTION_NAME_P(NAME) \
+  (strcmp (NAME, ".MIPS.options") == 0 || strcmp (NAME, ".options") == 0)
+
 /* The name of the stub section.  */
 #define MIPS_ELF_STUB_SECTION_NAME(abfd) ".MIPS.stubs"
 
@@ -5122,7 +5127,7 @@ _bfd_mips_elf_section_from_shdr (bfd *ab
 	return FALSE;
       break;
     case SHT_MIPS_OPTIONS:
-      if (strcmp (name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) != 0)
+      if (!MIPS_ELF_OPTIONS_SECTION_NAME_P (name))
 	return FALSE;
       break;
     case SHT_MIPS_DWARF:
@@ -5140,7 +5145,7 @@ _bfd_mips_elf_section_from_shdr (bfd *ab
 	return FALSE;
       break;
     default:
-      return FALSE;
+      break;
     }
 
   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
@@ -5310,7 +5315,7 @@ _bfd_mips_elf_fake_sections (bfd *abfd, 
       hdr->sh_flags |= SHF_MIPS_NOSTRIP;
       /* The sh_info field is set in final_write_processing.  */
     }
-  else if (strcmp (name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0)
+  else if (MIPS_ELF_OPTIONS_SECTION_NAME_P (name))
     {
       hdr->sh_type = SHT_MIPS_OPTIONS;
       hdr->sh_entsize = 1;
@@ -8631,7 +8636,7 @@ _bfd_mips_elf_set_section_contents (bfd 
 				    const void *location,
 				    file_ptr offset, bfd_size_type count)
 {
-  if (strcmp (section->name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0)
+  if (MIPS_ELF_OPTIONS_SECTION_NAME_P (section->name))
     {
       bfd_byte *c;
 


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