* elf32-mips.c (MIPS_ELF_SRDATA_SECTION_NAME): New macro.
authorMark Mitchell <mark@codesourcery.com>
Sun, 27 Jun 1999 21:23:34 +0000 (21:23 +0000)
committerMark Mitchell <mark@codesourcery.com>
Sun, 27 Jun 1999 21:23:34 +0000 (21:23 +0000)
(MIPS_ELF_OPTIONS_SECTION_NAME): Likewise.
(MIPS_ELF_STUB_SECTION_NAME): Likewise.
(_bfd_mips_elf_section_from_shdr): Use them.
(_bfd_mips_elf_fake_sections): Likewise.  Add .srdata to the list
of GP-relative sections.
(_bfd_mips_elf_set_section_contents): Use them.
(_bfd_mips_elf_section_processing): Share code between .sdata and
.lit4/.lit8 sections.  Set appropriate flags for .srdata.
(mips_elf_additional_program_headers): Add handling for
PT_MIPS_OPTIONS segment on IRIX6.
(mips_elf_modify_segment_map): Likeiwse.
(mips_elf_final_link): Set EF_MIPS_CPIC when required by the ABI.
Include the options sections on IRIX6.  Don't look for GP-relative
sections by name; use SHF_MIPS_GPREL instead.
(ELF_DYNAMIC_INTERPRETER): Adjust to use /usr/lib32/libc.so.1 for
the N32 ABI.
(mips_elf_create_dynamic_sections): Don't muck about with section
alignments and such on IRIX6.
(mips_elf_adjust_dynamic_symbol): Use MIPS_ELF_STUB_SECTION_NAME.
(mips_elf_size_dynamic_sections): Likewise. Adjust to handle the
fact that ELF_DYNAMIC_INTERPRETER is no longer a constant.  Use
bfd_zalloc rather than bfd_alloc and memset.
(mips_elf_finish_dynamic_symbol): Use MIPS_ELF_STUB_SECTION_NAME.
Don't assert the existence of .rld_map on IRIX6.
(mips_elf_finish_dynamic_sections): Use MIPS_ELF_STUB_SECTION_NAME.

bfd/ChangeLog
bfd/elf32-mips.c

index 1b146bfd18a827eeafa966a152c2e3712a266284..eee678f63967e81caa70fbf9f4ec58f3a8f5f7f6 100644 (file)
@@ -1,5 +1,32 @@
 1999-06-27  Mark Mitchell  <mark@codesourcery.com>
 
+       * elf32-mips.c (MIPS_ELF_SRDATA_SECTION_NAME): New macro.
+       (MIPS_ELF_OPTIONS_SECTION_NAME): Likewise.
+       (MIPS_ELF_STUB_SECTION_NAME): Likewise.
+       (_bfd_mips_elf_section_from_shdr): Use them.
+       (_bfd_mips_elf_fake_sections): Likewise.  Add .srdata to the list
+       of GP-relative sections.
+       (_bfd_mips_elf_set_section_contents): Use them.
+       (_bfd_mips_elf_section_processing): Share code between .sdata and
+       .lit4/.lit8 sections.  Set appropriate flags for .srdata.
+       (mips_elf_additional_program_headers): Add handling for
+       PT_MIPS_OPTIONS segment on IRIX6.
+       (mips_elf_modify_segment_map): Likeiwse.
+       (mips_elf_final_link): Set EF_MIPS_CPIC when required by the ABI.
+       Include the options sections on IRIX6.  Don't look for GP-relative
+       sections by name; use SHF_MIPS_GPREL instead.
+       (ELF_DYNAMIC_INTERPRETER): Adjust to use /usr/lib32/libc.so.1 for
+       the N32 ABI.
+       (mips_elf_create_dynamic_sections): Don't muck about with section
+       alignments and such on IRIX6.
+       (mips_elf_adjust_dynamic_symbol): Use MIPS_ELF_STUB_SECTION_NAME.
+       (mips_elf_size_dynamic_sections): Likewise. Adjust to handle the
+       fact that ELF_DYNAMIC_INTERPRETER is no longer a constant.  Use
+       bfd_zalloc rather than bfd_alloc and memset.
+       (mips_elf_finish_dynamic_symbol): Use MIPS_ELF_STUB_SECTION_NAME.
+       Don't assert the existence of .rld_map on IRIX6.
+       (mips_elf_finish_dynamic_sections): Use MIPS_ELF_STUB_SECTION_NAME.
+               
        * elf32-mips.c (mips_elf_adjust_dynindx): Remove.
        (mips_elf_size_dynamic_sections): Use _bfd_elf_link_adjust_dynindx
        instead.
index 17c057b0439489205fceb64ef79d6b1d7b3a86e9..c152e8af5fd89345d71bdf899636ea9bdacfc0bc 100644 (file)
@@ -170,6 +170,17 @@ struct mips_got_info
 /* The name of the msym section.  */
 #define MIPS_ELF_MSYM_SECTION_NAME(abfd) ".msym"
 
+/* The name of the srdata section.  */
+#define MIPS_ELF_SRDATA_SECTION_NAME(abfd) ".srdata"
+
+/* The name of the options section.  */
+#define MIPS_ELF_OPTIONS_SECTION_NAME(abfd) \
+  (IRIX_COMPAT (abfd) == ict_irix6 ? ".MIPS.options" : ".options")
+
+/* The name of the stub section.  */
+#define MIPS_ELF_STUB_SECTION_NAME(abfd) \
+  (IRIX_COMPAT (abfd) == ict_irix6 ? ".MIPS.stubs" : ".stub")
+
 /* The number of local .got entries we reserve.  */
 #define MIPS_RESERVED_GOTNO (2)
 
@@ -2449,8 +2460,7 @@ _bfd_mips_elf_section_from_shdr (abfd, hdr, name)
        return false;
       break;
     case SHT_MIPS_OPTIONS:
-      if (strcmp (name, ".options") != 0
-         && strcmp (name, ".MIPS.options") != 0)
+      if (strcmp (name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) != 0)
        return false;
       break;
     case SHT_MIPS_DWARF:
@@ -2627,6 +2637,7 @@ _bfd_mips_elf_fake_sections (abfd, hdr, sec)
 #endif
     }
   else if (strcmp (name, ".got") == 0
+          || strcmp (name, MIPS_ELF_SRDATA_SECTION_NAME (abfd)) == 0
           || strcmp (name, ".sdata") == 0
           || strcmp (name, ".sbss") == 0
           || strcmp (name, ".lit4") == 0
@@ -2643,8 +2654,7 @@ _bfd_mips_elf_fake_sections (abfd, hdr, sec)
       hdr->sh_flags |= SHF_MIPS_NOSTRIP;
       /* The sh_info field is set in final_write_processing.  */
     }
-  else if (strcmp (name, ".options") == 0
-          || strcmp (name, ".MIPS.options") == 0)
+  else if (strcmp (name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0)
     {
       hdr->sh_type = SHT_MIPS_OPTIONS;
       hdr->sh_entsize = 1;
@@ -2714,8 +2724,7 @@ _bfd_mips_elf_set_section_contents (abfd, section, location, offset, count)
      file_ptr offset;
      bfd_size_type count;
 {
-  if (strcmp (section->name, ".options") == 0
-      || strcmp (section->name, ".MIPS.options") == 0)
+  if (strcmp (section->name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0)
     {
       bfd_byte *c;
 
@@ -2762,7 +2771,9 @@ _bfd_mips_elf_section_processing (abfd, hdr)
     {
       const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
 
-      if (strcmp (name, ".sdata") == 0)
+      if (strcmp (name, ".sdata") == 0
+         || strcmp (name, ".lit8") == 0
+         || strcmp (name, ".lit4") == 0)
        {
          hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
          hdr->sh_type = SHT_PROGBITS;
@@ -2772,10 +2783,9 @@ _bfd_mips_elf_section_processing (abfd, hdr)
          hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
          hdr->sh_type = SHT_NOBITS;
        }
-      else if (strcmp (name, ".lit8") == 0
-              || strcmp (name, ".lit4") == 0)
+      else if (strcmp (name, MIPS_ELF_SRDATA_SECTION_NAME (abfd)) == 0)
        {
-         hdr->sh_flags |= SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL;
+         hdr->sh_flags |= SHF_ALLOC | SHF_MIPS_GPREL;
          hdr->sh_type = SHT_PROGBITS;
        }
       else if (strcmp (name, ".compact_rel") == 0)
@@ -2981,26 +2991,27 @@ mips_elf_additional_program_headers (abfd)
      bfd *abfd;
 {
   asection *s;
-  int ret;
-
-  ret = 0;
+  int ret = 0;
 
-  if (! SGI_COMPAT (abfd))
-    return ret;
+  if (!SGI_COMPAT (abfd))
+    return 0;
 
+  /* See if we need a PT_MIPS_REGINFO segment.  */
   s = bfd_get_section_by_name (abfd, ".reginfo");
-  if (s != NULL && (s->flags & SEC_LOAD) != 0)
-    {
-      /* We need a PT_MIPS_REGINFO segment.  */
-      ++ret;
-    }
+  if (s && (s->flags & SEC_LOAD))
+    ++ret;
 
-  if (bfd_get_section_by_name (abfd, ".dynamic") != NULL
-      && bfd_get_section_by_name (abfd, ".mdebug") != NULL)
-    {
-      /* We need a PT_MIPS_RTPROC segment.  */
-      ++ret;
-    }
+  /* See if we need a PT_MIPS_OPTIONS segment.  */
+  if (IRIX_COMPAT (abfd) == ict_irix6
+      && bfd_get_section_by_name (abfd, 
+                                 MIPS_ELF_OPTIONS_SECTION_NAME (abfd)))
+    ++ret;
+
+  /* See if we need a PT_MIPS_RTPROC segment.  */
+  if (IRIX_COMPAT (abfd) == ict_irix5
+      && bfd_get_section_by_name (abfd, ".dynamic")
+      && bfd_get_section_by_name (abfd, ".mdebug"))
+    ++ret;
 
   return ret;
 }
@@ -3047,114 +3058,154 @@ mips_elf_modify_segment_map (abfd)
        }
     }
 
-  /* If there are .dynamic and .mdebug sections, we make a room for
-     the RTPROC header.  FIXME: Rewrite without section names.  */
-  if (bfd_get_section_by_name (abfd, ".interp") == NULL
-      && bfd_get_section_by_name (abfd, ".dynamic") != NULL
-      && bfd_get_section_by_name (abfd, ".mdebug") != NULL)
+  /* For IRIX 6, we don't have .mdebug sections, nor does anything but
+     .dynamic end up in PT_DYNAMIC.  However, we do have to insert a
+     PT_OPTIONS segement immediately following the program header
+     table.  */
+  if (IRIX_COMPAT (abfd) == ict_irix6)
     {
-      for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
-       if (m->p_type == PT_MIPS_RTPROC)
+      asection *s;
+
+      for (s = abfd->sections; s; s = s->next)
+       if (elf_section_data (s)->this_hdr.sh_type == SHT_MIPS_OPTIONS)
          break;
-      if (m == NULL)
+
+      if (s)
        {
-         m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
+         struct elf_segment_map *options_segment;
+
+         for (m = elf_tdata (abfd)->segment_map; m; m = m->next)
+           if (m->p_type == PT_PHDR)
+             break;
+
+         /* There should always be a program header table.  */
          if (m == NULL)
            return false;
 
-         m->p_type = PT_MIPS_RTPROC;
-
-         s = bfd_get_section_by_name (abfd, ".rtproc");
-         if (s == NULL)
-           {
-             m->count = 0;
-             m->p_flags = 0;
-             m->p_flags_valid = 1;
-           }
-         else
+         options_segment = bfd_zalloc (abfd, 
+                                       sizeof (struct elf_segment_map));
+         options_segment->next = m->next;
+         options_segment->p_type = PT_MIPS_OPTIONS;
+         options_segment->p_flags = PF_R;
+         options_segment->p_flags_valid = true;
+         options_segment->count = 1;
+         options_segment->sections[0] = s;
+         m->next = options_segment;
+       }
+    }
+  else
+    {
+      /* If there are .dynamic and .mdebug sections, we make a room
+        for the RTPROC header.  FIXME: Rewrite without section names.  */
+      if (bfd_get_section_by_name (abfd, ".interp") == NULL
+         && bfd_get_section_by_name (abfd, ".dynamic") != NULL
+         && bfd_get_section_by_name (abfd, ".mdebug") != NULL)
+       {
+         for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
+           if (m->p_type == PT_MIPS_RTPROC)
+             break;
+         if (m == NULL)
            {
-             m->count = 1;
-             m->sections[0] = s;
-           }
+             m = (struct elf_segment_map *) bfd_zalloc (abfd, sizeof *m);
+             if (m == NULL)
+               return false;
 
-         /* We want to put it after the DYNAMIC segment.  */
-         pm = &elf_tdata (abfd)->segment_map;
-         while (*pm != NULL && (*pm)->p_type != PT_DYNAMIC)
-           pm = &(*pm)->next;
-         if (*pm != NULL)
-           pm = &(*pm)->next;
+             m->p_type = PT_MIPS_RTPROC;
 
-         m->next = *pm;
-         *pm = m;
+             s = bfd_get_section_by_name (abfd, ".rtproc");
+             if (s == NULL)
+               {
+                 m->count = 0;
+                 m->p_flags = 0;
+                 m->p_flags_valid = 1;
+               }
+             else
+               {
+                 m->count = 1;
+                 m->sections[0] = s;
+               }
+
+             /* We want to put it after the DYNAMIC segment.  */
+             pm = &elf_tdata (abfd)->segment_map;
+             while (*pm != NULL && (*pm)->p_type != PT_DYNAMIC)
+               pm = &(*pm)->next;
+             if (*pm != NULL)
+               pm = &(*pm)->next;
+
+             m->next = *pm;
+             *pm = m;
+           }
        }
-    }
 
-  /* On Irix 5, the PT_DYNAMIC segment includes the .dynamic, .dynstr,
-     .dynsym, and .hash sections, and everything in between.  */
-  for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL; pm = &(*pm)->next)
-    if ((*pm)->p_type == PT_DYNAMIC)
-      break;
-  m = *pm;
-  if (m != NULL
-      && m->count == 1
-      && strcmp (m->sections[0]->name, ".dynamic") == 0)
-    {
-      static const char *sec_names[] =
-       { ".dynamic", ".dynstr", ".dynsym", ".hash" };
-      bfd_vma low, high;
-      unsigned int i, c;
-      struct elf_segment_map *n;
-
-      low = 0xffffffff;
-      high = 0;
-      for (i = 0; i < sizeof sec_names / sizeof sec_names[0]; i++)
+      /* On Irix 5, the PT_DYNAMIC segment includes the .dynamic,
+        .dynstr, .dynsym, and .hash sections, and everything in
+        between.  */
+      for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL; pm = &(*pm)->next)
+       if ((*pm)->p_type == PT_DYNAMIC)
+         break;
+      m = *pm;
+      if (m != NULL
+         && m->count == 1
+         && strcmp (m->sections[0]->name, ".dynamic") == 0)
        {
-         s = bfd_get_section_by_name (abfd, sec_names[i]);
-         if (s != NULL && (s->flags & SEC_LOAD) != 0)
+         static const char *sec_names[] =
+         { ".dynamic", ".dynstr", ".dynsym", ".hash" };
+         bfd_vma low, high;
+         unsigned int i, c;
+         struct elf_segment_map *n;
+
+         low = 0xffffffff;
+         high = 0;
+         for (i = 0; i < sizeof sec_names / sizeof sec_names[0]; i++)
            {
-             bfd_size_type sz;
-
-             if (low > s->vma)
-               low = s->vma;
-             sz = s->_cooked_size;
-             if (sz == 0)
-               sz = s->_raw_size;
-             if (high < s->vma + sz)
-               high = s->vma + sz;
+             s = bfd_get_section_by_name (abfd, sec_names[i]);
+             if (s != NULL && (s->flags & SEC_LOAD) != 0)
+               {
+                 bfd_size_type sz;
+
+                 if (low > s->vma)
+                   low = s->vma;
+                 sz = s->_cooked_size;
+                 if (sz == 0)
+                   sz = s->_raw_size;
+                 if (high < s->vma + sz)
+                   high = s->vma + sz;
+               }
            }
-       }
 
-      c = 0;
-      for (s = abfd->sections; s != NULL; s = s->next)
-       if ((s->flags & SEC_LOAD) != 0
-           && s->vma >= low
-           && ((s->vma
-                + (s->_cooked_size != 0 ? s->_cooked_size : s->_raw_size))
-               <= high))
-         ++c;
-
-      n = ((struct elf_segment_map *)
-          bfd_zalloc (abfd, sizeof *n + (c - 1) * sizeof (asection *)));
-      if (n == NULL)
-       return false;
-      *n = *m;
-      n->count = c;
+         c = 0;
+         for (s = abfd->sections; s != NULL; s = s->next)
+           if ((s->flags & SEC_LOAD) != 0
+               && s->vma >= low
+               && ((s->vma
+                    + (s->_cooked_size != 0 ? s->_cooked_size : s->_raw_size))
+                   <= high))
+             ++c;
+
+         n = ((struct elf_segment_map *)
+              bfd_zalloc (abfd, sizeof *n + (c - 1) * sizeof (asection *)));
+         if (n == NULL)
+           return false;
+         *n = *m;
+         n->count = c;
 
-      i = 0;
-      for (s = abfd->sections; s != NULL; s = s->next)
-       {
-         if ((s->flags & SEC_LOAD) != 0
-             && s->vma >= low
-             && ((s->vma
-                  + (s->_cooked_size != 0 ? s->_cooked_size : s->_raw_size))
-                 <= high))
+         i = 0;
+         for (s = abfd->sections; s != NULL; s = s->next)
            {
-             n->sections[i] = s;
-             ++i;
+             if ((s->flags & SEC_LOAD) != 0
+                 && s->vma >= low
+                 && ((s->vma
+                      + (s->_cooked_size != 0 ?
+                         s->_cooked_size : s->_raw_size))
+                     <= high))
+               {
+                 n->sections[i] = s;
+                 ++i;
+               }
            }
-       }
 
-      *pm = n;
+         *pm = n;
+       }
     }
 
   return true;
@@ -4121,22 +4172,36 @@ mips_elf_final_link (abfd, info)
   HDRR *symhdr = &debug.symbolic_header;
   PTR mdebug_handle = NULL;
 
-  /* Drop the .options section, since it has special semantics which I
-     haven't bothered to figure out.  */
-  for (secpp = &abfd->sections; *secpp != NULL; secpp = &(*secpp)->next)
+  /* If all the things we linked together were PIC, but we're
+     producing an executable (rather than a shared object), then the
+     resulting file is CPIC (i.e., it calls PIC code.)  */
+  if (!info->shared && elf_elfheader (abfd)->e_flags & EF_MIPS_PIC)
     {
-      if (strcmp ((*secpp)->name, ".options") == 0)
-       {
-         for (p = (*secpp)->link_order_head; p != NULL; p = p->next)
-           if (p->type == bfd_indirect_link_order)
-             p->u.indirect.section->flags &=~ SEC_HAS_CONTENTS;
-         (*secpp)->link_order_head = NULL;
-         *secpp = (*secpp)->next;
-         --abfd->section_count;
-         break;
-       }
+      elf_elfheader (abfd)->e_flags &= ~EF_MIPS_PIC;
+      elf_elfheader (abfd)->e_flags |= EF_MIPS_CPIC;
+      
     }
 
+  /* On IRIX5, we omit the .options section.  On IRIX6, however, we
+     include it, even though we don't process it quite right.  (Some
+     entries are supposed to be merged.)  Empirically, we seem to be
+     better off including it then not.  */
+  if (IRIX_COMPAT (abfd) == ict_irix5)
+    for (secpp = &abfd->sections; *secpp != NULL; secpp = &(*secpp)->next)
+      {
+       if (strcmp ((*secpp)->name, MIPS_ELF_OPTIONS_SECTION_NAME (abfd)) == 0)
+         {
+           for (p = (*secpp)->link_order_head; p != NULL; p = p->next)
+             if (p->type == bfd_indirect_link_order)
+               p->u.indirect.section->flags &=~ SEC_HAS_CONTENTS;
+           (*secpp)->link_order_head = NULL;
+           *secpp = (*secpp)->next;
+           --abfd->section_count;
+           
+           break;
+         }
+      }
+
   /* Get a value for the GP register.  */
   if (elf_gp (abfd) == 0)
     {
@@ -4152,17 +4217,14 @@ mips_elf_final_link (abfd, info)
        {
          bfd_vma lo;
 
-         /* Make up a value.  */
+         /* Find the GP-relative section with the lowest offset.  */
          lo = (bfd_vma) -1;
          for (o = abfd->sections; o != (asection *) NULL; o = o->next)
-           {
-             if (o->vma < lo
-                 && (strcmp (o->name, ".sbss") == 0
-                     || strcmp (o->name, ".sdata") == 0
-                     || strcmp (o->name, ".lit4") == 0
-                     || strcmp (o->name, ".lit8") == 0))
-               lo = o->vma;
-           }
+           if (o->vma < lo 
+               && (elf_section_data (o)->this_hdr.sh_flags & SHF_MIPS_GPREL))
+             lo = o->vma;
+
+         /* And calculate GP relative to that.  */
          elf_gp (abfd) = lo + ELF_MIPS_GP_OFFSET (abfd);
        }
       else
@@ -5815,7 +5877,8 @@ mips_elf_link_output_symbol_hook (abfd, info, name, sym, input_sec)
 /* The name of the dynamic interpreter.  This is put in the .interp
    section.  */
 
-#define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
+#define ELF_DYNAMIC_INTERPRETER(abfd) \
+   (ABI_N32_P (abfd) ? "/usr/lib32/libc.so.1" : "/usr/lib/libc.so.1")
 
 /* Create dynamic sections when linking against a dynamic object.  */
 
@@ -5872,7 +5935,11 @@ mips_elf_create_dynamic_sections (abfd, info)
        return false;
     }
 
-  if (SGI_COMPAT (abfd))
+  /* On IRIX5, we adjust add some additional symbols and change the
+     alignments of several sections.  There is no ABI documentation
+     indicating that this is necessary on IRIX6, nor any evidence that
+     the linker takes such action.  */
+  if (IRIX_COMPAT (abfd) == ict_irix5)
     {
       for (namep = mips_elf_dynsym_rtproc_names; *namep != NULL; namep++)
        {
@@ -6679,7 +6746,8 @@ mips_elf_adjust_dynamic_symbol (info, h)
       if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
        {
          /* We need .stub section.  */
-         s = bfd_get_section_by_name (dynobj, ".stub");
+         s = bfd_get_section_by_name (dynobj, 
+                                      MIPS_ELF_STUB_SECTION_NAME (dynobj));
          BFD_ASSERT (s != NULL);
 
          h->root.u.def.section = s;
@@ -6819,8 +6887,10 @@ mips_elf_size_dynamic_sections (output_bfd, info)
        {
          s = bfd_get_section_by_name (dynobj, ".interp");
          BFD_ASSERT (s != NULL);
-         s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;
-         s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
+         s->_raw_size 
+           = strlen (ELF_DYNAMIC_INTERPRETER (output_bfd)) + 1;
+         s->contents 
+           = (unsigned char *) ELF_DYNAMIC_INTERPRETER (output_bfd);
        }
     }
 
@@ -6929,7 +6999,7 @@ mips_elf_size_dynamic_sections (output_bfd, info)
          i = elf_hash_table (info)->dynsymcount - g->global_gotsym;
          s->_raw_size += i * 4;
        }
-      else if (strncmp (name, ".stub", 5) == 0)
+      else if (strcmp (name, MIPS_ELF_STUB_SECTION_NAME (output_bfd)) == 0)
        {
          /* Irix rld assumes that the function stub isn't at the end
             of .text section. So put a dummy. XXX  */
@@ -6964,13 +7034,12 @@ mips_elf_size_dynamic_sections (output_bfd, info)
        }
 
       /* Allocate memory for the section contents.  */
-      s->contents = (bfd_byte *) bfd_alloc (dynobj, s->_raw_size);
+      s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);
       if (s->contents == NULL && s->_raw_size != 0)
        {
          bfd_set_error (bfd_error_no_memory);
          return false;
        }
-      memset (s->contents, 0, s->_raw_size);
     }
 
   if (elf_hash_table (info)->dynamic_sections_created)
@@ -7203,7 +7272,8 @@ mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
 
       BFD_ASSERT (h->dynindx != -1);
 
-      s = bfd_get_section_by_name (dynobj, ".stub");
+      s = bfd_get_section_by_name (dynobj, 
+                                  MIPS_ELF_STUB_SECTION_NAME (dynobj));
       BFD_ASSERT (s != NULL);
 
       /* Fill the stub.  */
@@ -7333,8 +7403,10 @@ mips_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
       else if (mips_elf_hash_table (info)->use_rld_obj_head
               && strcmp (name, "__rld_obj_head") == 0)
        {
-         asection *s = bfd_get_section_by_name (dynobj, ".rld_map");
-         BFD_ASSERT (s != NULL);
+         /* IRIX6 does not use a .rld_map section.  */
+         if (IRIX_COMPAT (output_bfd) == ict_irix5)
+           BFD_ASSERT (bfd_get_section_by_name (dynobj, ".rld_map") 
+                       != NULL);
          mips_elf_hash_table (info)->rld_value = sym->st_value;
        }
     }
@@ -7673,7 +7745,8 @@ mips_elf_finish_dynamic_sections (output_bfd, info)
                                             s->contents));
 
            /* Clean up a dummy stub function entry in .text.  */
-           s = bfd_get_section_by_name (dynobj, ".stub");
+           s = bfd_get_section_by_name (dynobj, 
+                                        MIPS_ELF_STUB_SECTION_NAME (dynobj));
            if (s != NULL)
              {
                file_ptr dummy_offset;