bfd/
[deliverable/binutils-gdb.git] / bfd / elf.c
index ad8e92109c7cd618861c18ac351c70bba6ad8681..d65c78d963a413792fb4bbd254894e695cc736c9 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -226,17 +226,13 @@ bfd_elf_gnu_hash (const char *namearg)
   return h & 0xffffffff;
 }
 
-/* If ABFD does not already have an allocated tdata field then create
-   one, OBJECT_SIZE bytes is length, zeroed out and with the object_id
-   field of an elf_obj_tdata field set to OBJECT_ID.  */
+/* Create a tdata field OBJECT_SIZE bytes in length, zeroed out and with
+   the object_id field of an elf_obj_tdata field set to OBJECT_ID.  */
 bfd_boolean
-bfd_elf_allocate_object (bfd * abfd,
+bfd_elf_allocate_object (bfd *abfd,
                         size_t object_size,
                         enum elf_object_id object_id)
 {
-  if (abfd->tdata.any != NULL)
-    return TRUE;
-
   BFD_ASSERT (object_size >= sizeof (struct elf_obj_tdata));
   abfd->tdata.any = bfd_zalloc (abfd, object_size);
   if (abfd->tdata.any == NULL)
@@ -285,7 +281,7 @@ bfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
 
       /* Allocate and clear an extra byte at the end, to prevent crashes
         in case the string table is not terminated.  */
-      if (shstrtabsize + 1 == 0
+      if (shstrtabsize + 1 <= 1
          || (shstrtab = bfd_alloc (abfd, shstrtabsize + 1)) == NULL
          || bfd_seek (abfd, offset, SEEK_SET) != 0)
        shstrtab = NULL;
@@ -294,6 +290,10 @@ bfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
          if (bfd_get_error () != bfd_error_system_call)
            bfd_set_error (bfd_error_file_truncated);
          shstrtab = NULL;
+         /* Once we've failed to read it, make sure we don't keep
+            trying.  Otherwise, we'll keep allocating space for
+            the string table over and over.  */
+         i_shdrp[shindex]->sh_size = 0;
        }
       else
        shstrtab[shstrtabsize] = '\0';
@@ -461,8 +461,7 @@ bfd_elf_sym_name (bfd *abfd,
 
   if (iname == 0 && ELF_ST_TYPE (isym->st_info) == STT_SECTION
       /* Check for a bogus st_shndx to avoid crashing.  */
-      && isym->st_shndx < elf_numsections (abfd)
-      && !(isym->st_shndx >= SHN_LORESERVE && isym->st_shndx <= SHN_HIRESERVE))
+      && isym->st_shndx < elf_numsections (abfd))
     {
       iname = elf_elfsections (abfd)[isym->st_shndx]->sh_name;
       shindex = elf_elfheader (abfd)->e_shstrndx;
@@ -499,6 +498,8 @@ group_signature (bfd *abfd, Elf_Internal_Shdr *ghdr)
 
   /* First we need to ensure the symbol table is available.  Make sure
      that it is a symbol table section.  */
+  if (ghdr->sh_link >= elf_numsections (abfd))
+    return NULL;
   hdr = elf_elfsections (abfd) [ghdr->sh_link];
   if (hdr->sh_type != SHT_SYMTAB
       || ! bfd_section_from_shdr (abfd, ghdr->sh_link))
@@ -717,8 +718,7 @@ _bfd_elf_setup_sections (bfd *abfd)
             get the situation where elfsec is 0.  */
          if (elfsec == 0)
            {
-             const struct elf_backend_data *bed
-               = get_elf_backend_data (abfd);
+             const struct elf_backend_data *bed = get_elf_backend_data (abfd);
              if (bed->link_order_error_handler)
                bed->link_order_error_handler
                  (_("%B: warning: sh_link not set for section `%A'"),
@@ -726,14 +726,17 @@ _bfd_elf_setup_sections (bfd *abfd)
            }
          else
            {
-             asection *link;
+             asection *link = NULL;
 
-             this_hdr = elf_elfsections (abfd)[elfsec];
+             if (elfsec < elf_numsections (abfd))
+               {
+                 this_hdr = elf_elfsections (abfd)[elfsec];
+                 link = this_hdr->bfd_section;
+               }
 
              /* PR 1991, 2008:
                 Some strip/objcopy may leave an incorrect value in
                 sh_link.  We don't want to proceed.  */
-             link = this_hdr->bfd_section;
              if (link == NULL)
                {
                  (*_bfd_error_handler)
@@ -829,7 +832,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
   if (! bfd_set_section_vma (abfd, newsect, hdr->sh_addr)
       || ! bfd_set_section_size (abfd, newsect, hdr->sh_size)
       || ! bfd_set_section_alignment (abfd, newsect,
-                                     bfd_log2 ((bfd_vma) hdr->sh_addralign)))
+                                     bfd_log2 (hdr->sh_addralign)))
     return FALSE;
 
   flags = SEC_NO_FLAGS;
@@ -887,7 +890,14 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
          { NULL,                0  },  /* 'p' */
          { NULL,                0  },  /* 'q' */
          { NULL,                0  },  /* 'r' */
-         { STRING_COMMA_LEN ("stab") } /* 's' */
+         { STRING_COMMA_LEN ("stab") },        /* 's' */
+         { NULL,                0  },  /* 't' */
+         { NULL,                0  },  /* 'u' */
+         { NULL,                0  },  /* 'v' */
+         { NULL,                0  },  /* 'w' */
+         { NULL,                0  },  /* 'x' */
+         { NULL,                0  },  /* 'y' */
+         { STRING_COMMA_LEN ("zdebug") }       /* 'z' */
        };
 
       if (name [0] == '.')
@@ -945,65 +955,66 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
   if ((flags & SEC_ALLOC) != 0)
     {
       Elf_Internal_Phdr *phdr;
-      unsigned int i;
+      unsigned int i, nload;
+
+      /* Some ELF linkers produce binaries with all the program header
+        p_paddr fields zero.  If we have such a binary with more than
+        one PT_LOAD header, then leave the section lma equal to vma
+        so that we don't create sections with overlapping lma.  */
+      phdr = elf_tdata (abfd)->phdr;
+      for (nload = 0, i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
+       if (phdr->p_paddr != 0)
+         break;
+       else if (phdr->p_type == PT_LOAD && phdr->p_memsz != 0)
+         ++nload;
+      if (i >= elf_elfheader (abfd)->e_phnum && nload > 1)
+       return TRUE;
 
-      /* Look through the phdrs to see if we need to adjust the lma.
-        If all the p_paddr fields are zero, we ignore them, since
-        some ELF linkers produce such output.  */
       phdr = elf_tdata (abfd)->phdr;
       for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
        {
-         if (phdr->p_paddr != 0)
-           break;
-       }
-      if (i < elf_elfheader (abfd)->e_phnum)
-       {
-         phdr = elf_tdata (abfd)->phdr;
-         for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
+         /* This section is part of this segment if its file
+            offset plus size lies within the segment's memory
+            span and, if the section is loaded, the extent of the
+            loaded data lies within the extent of the segment.
+
+            Note - we used to check the p_paddr field as well, and
+            refuse to set the LMA if it was 0.  This is wrong
+            though, as a perfectly valid initialised segment can
+            have a p_paddr of zero.  Some architectures, eg ARM,
+            place special significance on the address 0 and
+            executables need to be able to have a segment which
+            covers this address.  */
+         if (phdr->p_type == PT_LOAD
+             && (bfd_vma) hdr->sh_offset >= phdr->p_offset
+             && (hdr->sh_offset + hdr->sh_size
+                 <= phdr->p_offset + phdr->p_memsz)
+             && ((flags & SEC_LOAD) == 0
+                 || (hdr->sh_offset + hdr->sh_size
+                     <= phdr->p_offset + phdr->p_filesz)))
            {
-             /* This section is part of this segment if its file
-                offset plus size lies within the segment's memory
-                span and, if the section is loaded, the extent of the
-                loaded data lies within the extent of the segment.
-
-                Note - we used to check the p_paddr field as well, and
-                refuse to set the LMA if it was 0.  This is wrong
-                though, as a perfectly valid initialised segment can
-                have a p_paddr of zero.  Some architectures, eg ARM,
-                place special significance on the address 0 and
-                executables need to be able to have a segment which
-                covers this address.  */
-             if (phdr->p_type == PT_LOAD
-                 && (bfd_vma) hdr->sh_offset >= phdr->p_offset
-                 && (hdr->sh_offset + hdr->sh_size
-                     <= phdr->p_offset + phdr->p_memsz)
-                 && ((flags & SEC_LOAD) == 0
-                     || (hdr->sh_offset + hdr->sh_size
-                         <= phdr->p_offset + phdr->p_filesz)))
-               {
-                 if ((flags & SEC_LOAD) == 0)
-                   newsect->lma = (phdr->p_paddr
-                                   + hdr->sh_addr - phdr->p_vaddr);
-                 else
-                   /* We used to use the same adjustment for SEC_LOAD
-                      sections, but that doesn't work if the segment
-                      is packed with code from multiple VMAs.
-                      Instead we calculate the section LMA based on
-                      the segment LMA.  It is assumed that the
-                      segment will contain sections with contiguous
-                      LMAs, even if the VMAs are not.  */
-                   newsect->lma = (phdr->p_paddr
-                                   + hdr->sh_offset - phdr->p_offset);
-
-                 /* With contiguous segments, we can't tell from file
-                    offsets whether a section with zero size should
-                    be placed at the end of one segment or the
-                    beginning of the next.  Decide based on vaddr.  */
-                 if (hdr->sh_addr >= phdr->p_vaddr
-                     && (hdr->sh_addr + hdr->sh_size
-                         <= phdr->p_vaddr + phdr->p_memsz))
-                   break;
-               }
+             if ((flags & SEC_LOAD) == 0)
+               newsect->lma = (phdr->p_paddr
+                               + hdr->sh_addr - phdr->p_vaddr);
+             else
+               /* We used to use the same adjustment for SEC_LOAD
+                  sections, but that doesn't work if the segment
+                  is packed with code from multiple VMAs.
+                  Instead we calculate the section LMA based on
+                  the segment LMA.  It is assumed that the
+                  segment will contain sections with contiguous
+                  LMAs, even if the VMAs are not.  */
+               newsect->lma = (phdr->p_paddr
+                               + hdr->sh_offset - phdr->p_offset);
+
+             /* With contiguous segments, we can't tell from file
+                offsets whether a section with zero size should
+                be placed at the end of one segment or the
+                beginning of the next.  Decide based on vaddr.  */
+             if (hdr->sh_addr >= phdr->p_vaddr
+                 && (hdr->sh_addr + hdr->sh_size
+                     <= phdr->p_vaddr + phdr->p_memsz))
+               break;
            }
        }
     }
@@ -1184,7 +1195,7 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
   s = bfd_get_section_by_name (abfd, ".dynamic");
   if (s != NULL)
     {
-      int elfsec;
+      unsigned int elfsec;
       unsigned long shlink;
       bfd_byte *extdyn, *extdynend;
       size_t extdynsize;
@@ -1196,7 +1207,7 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
        goto error_return;
 
       elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
-      if (elfsec == -1)
+      if (elfsec == SHN_BAD)
        goto error_return;
       shlink = elf_elfsections (abfd)[elfsec]->sh_link;
 
@@ -1208,9 +1219,10 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
       for (; extdyn < extdynend; extdyn += extdynsize)
        {
          Elf_Internal_Dyn dyn;
-         const char *name;
+         const char *name = "";
          char ab[20];
          bfd_boolean stringp;
+         const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
          (*swap_dyn_in) (abfd, extdyn, &dyn);
 
@@ -1221,8 +1233,14 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
          switch (dyn.d_tag)
            {
            default:
-             sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag);
-             name = ab;
+             if (bed->elf_backend_get_target_dtag)
+               name = (*bed->elf_backend_get_target_dtag) (dyn.d_tag);
+
+             if (!strcmp (name, ""))
+               {
+                 sprintf (ab, "0x%lx", (unsigned long) dyn.d_tag);
+                 name = ab;
+               }
              break;
 
            case DT_NEEDED: name = "NEEDED"; stringp = TRUE; break;
@@ -1285,9 +1303,12 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
            case DT_GNU_HASH: name = "GNU_HASH"; break;
            }
 
-         fprintf (f, "  %-11s ", name);
+         fprintf (f, "  %-20s ", name);
          if (! stringp)
-           fprintf (f, "0x%lx", (unsigned long) dyn.d_un.d_val);
+           {
+             fprintf (f, "0x");
+             bfd_fprintf_vma (abfd, f, dyn.d_un.d_val);
+           }
          else
            {
              const char *string;
@@ -1515,17 +1536,22 @@ _bfd_elf_stringtab_init (void)
 bfd_boolean
 bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
 {
-  Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex];
-  Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd);
-  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  Elf_Internal_Shdr *hdr;
+  Elf_Internal_Ehdr *ehdr;
+  const struct elf_backend_data *bed;
   const char *name;
 
-  name = bfd_elf_string_from_elf_section (abfd,
-                                         elf_elfheader (abfd)->e_shstrndx,
+  if (shindex >= elf_numsections (abfd))
+    return FALSE;
+
+  hdr = elf_elfsections (abfd)[shindex];
+  ehdr = elf_elfheader (abfd);
+  name = bfd_elf_string_from_elf_section (abfd, ehdr->e_shstrndx,
                                          hdr->sh_name);
   if (name == NULL)
     return FALSE;
 
+  bed = get_elf_backend_data (abfd);
   switch (hdr->sh_type)
     {
     case SHT_NULL:
@@ -1726,8 +1752,7 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
          return FALSE;
 
        /* Check for a bogus link to avoid crashing.  */
-       if ((hdr->sh_link >= SHN_LORESERVE && hdr->sh_link <= SHN_HIRESERVE)
-           || hdr->sh_link >= num_sec)
+       if (hdr->sh_link >= num_sec)
          {
            ((*_bfd_error_handler)
             (_("%B: invalid link %lu for reloc section %s (index %u)"),
@@ -1781,7 +1806,6 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
           section, an invalid section, or another reloc section.  */
        if (hdr->sh_link != elf_onesymtab (abfd)
            || hdr->sh_info == SHN_UNDEF
-           || (hdr->sh_info >= SHN_LORESERVE && hdr->sh_info <= SHN_HIRESERVE)
            || hdr->sh_info >= num_sec
            || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_REL
            || elf_elfsections (abfd)[hdr->sh_info]->sh_type == SHT_RELA)
@@ -2102,6 +2126,15 @@ static const struct bfd_elf_special_section special_sections_t[] =
   { NULL,                     0,  0, 0,            0 }
 };
 
+static const struct bfd_elf_special_section special_sections_z[] =
+{
+  { STRING_COMMA_LEN (".zdebug_line"),    0, SHT_PROGBITS, 0 },
+  { STRING_COMMA_LEN (".zdebug_info"),    0, SHT_PROGBITS, 0 },
+  { STRING_COMMA_LEN (".zdebug_abbrev"),  0, SHT_PROGBITS, 0 },
+  { STRING_COMMA_LEN (".zdebug_aranges"), 0, SHT_PROGBITS, 0 },
+  { NULL,                     0,  0, 0,            0 }
+};
+
 static const struct bfd_elf_special_section *special_sections[] =
 {
   special_sections_b,          /* 'b' */
@@ -2123,6 +2156,12 @@ static const struct bfd_elf_special_section *special_sections[] =
   special_sections_r,          /* 'r' */
   special_sections_s,          /* 's' */
   special_sections_t,          /* 't' */
+  NULL,                                /* 'u' */
+  NULL,                                /* 'v' */
+  NULL,                                /* 'w' */
+  NULL,                                /* 'x' */
+  NULL,                                /* 'y' */
+  special_sections_z           /* 'z' */
 };
 
 const struct bfd_elf_special_section *
@@ -2199,7 +2238,7 @@ _bfd_elf_get_sec_type_attr (bfd *abfd, asection *sec)
     return NULL;
 
   i = sec->name[1] - 'b';
-  if (i < 0 || i > 't' - 'b')
+  if (i < 0 || i > 'z' - 'b')
     return NULL;
 
   spec = special_sections[i];
@@ -2440,7 +2479,7 @@ _bfd_elf_init_reloc_shdr (bfd *abfd,
   rel_hdr->sh_entsize = (use_rela_p
                         ? bed->s->sizeof_rela
                         : bed->s->sizeof_rel);
-  rel_hdr->sh_addralign = 1 << bed->s->log_file_align;
+  rel_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
   rel_hdr->sh_flags = 0;
   rel_hdr->sh_addr = 0;
   rel_hdr->sh_size = 0;
@@ -2487,7 +2526,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
   this_hdr->sh_offset = 0;
   this_hdr->sh_size = asect->size;
   this_hdr->sh_link = 0;
-  this_hdr->sh_addralign = 1 << asect->alignment_power;
+  this_hdr->sh_addralign = (bfd_vma) 1 << asect->alignment_power;
   /* The sh_entsize and sh_info fields may have been set already by
      copy_private_section_data.  */
 
@@ -2768,11 +2807,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
                  abfd->section_count--;
                }
              else
-               {
-                 if (section_number == SHN_LORESERVE)
-                   section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
-                 d->this_idx = section_number++;
-               }
+               d->this_idx = section_number++;
            }
        }
     }
@@ -2782,26 +2817,18 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
       d = elf_section_data (sec);
 
       if (d->this_hdr.sh_type != SHT_GROUP)
-       {
-         if (section_number == SHN_LORESERVE)
-           section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
-         d->this_idx = section_number++;
-       }
+       d->this_idx = section_number++;
       _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
       if ((sec->flags & SEC_RELOC) == 0)
        d->rel_idx = 0;
       else
        {
-         if (section_number == SHN_LORESERVE)
-           section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
          d->rel_idx = section_number++;
          _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr.sh_name);
        }
 
       if (d->rel_hdr2)
        {
-         if (section_number == SHN_LORESERVE)
-           section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
          d->rel_idx2 = section_number++;
          _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr2->sh_name);
        }
@@ -2809,22 +2836,16 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
        d->rel_idx2 = 0;
     }
 
-  if (section_number == SHN_LORESERVE)
-    section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
   t->shstrtab_section = section_number++;
   _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
   elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;
 
   if (bfd_get_symcount (abfd) > 0)
     {
-      if (section_number == SHN_LORESERVE)
-       section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
       t->symtab_section = section_number++;
       _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
-      if (section_number > SHN_LORESERVE - 2)
+      if (section_number > ((SHN_LORESERVE - 2) & 0xFFFF))
        {
-         if (section_number == SHN_LORESERVE)
-           section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
          t->symtab_shndx_section = section_number++;
          t->symtab_shndx_hdr.sh_name
            = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
@@ -2832,8 +2853,6 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
          if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1)
            return FALSE;
        }
-      if (section_number == SHN_LORESERVE)
-       section_number += SHN_HIRESERVE + 1 - SHN_LORESERVE;
       t->strtab_section = section_number++;
       _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
     }
@@ -2843,8 +2862,6 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
 
   elf_numsections (abfd) = section_number;
   elf_elfheader (abfd)->e_shnum = section_number;
-  if (section_number > SHN_LORESERVE)
-    elf_elfheader (abfd)->e_shnum -= SHN_HIRESERVE + 1 - SHN_LORESERVE;
 
   /* Set up the list of section header pointers, in agreement with the
      indices.  */
@@ -2865,7 +2882,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
   if (bfd_get_symcount (abfd) > 0)
     {
       i_shdrp[t->symtab_section] = &t->symtab_hdr;
-      if (elf_numsections (abfd) > SHN_LORESERVE)
+      if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF))
        {
          i_shdrp[t->symtab_shndx_section] = &t->symtab_shndx_hdr;
          t->symtab_shndx_hdr.sh_link = t->symtab_section;
@@ -3083,17 +3100,15 @@ sym_is_global (bfd *abfd, asymbol *sym)
 }
 
 /* Don't output section symbols for sections that are not going to be
-   output.  Also, don't output section symbols for reloc and other
-   special sections.  */
+   output.  */
 
 static bfd_boolean
 ignore_section_sym (bfd *abfd, asymbol *sym)
 {
   return ((sym->flags & BSF_SECTION_SYM) != 0
-         && (sym->value != 0
-             || (sym->section->owner != abfd
-                 && (sym->section->output_section->owner != abfd
-                     || sym->section->output_offset != 0))));
+         && !(sym->section->owner == abfd
+              || (sym->section->output_section->owner == abfd
+                  && sym->section->output_offset == 0)));
 }
 
 static bfd_boolean
@@ -3136,6 +3151,7 @@ elf_map_symbols (bfd *abfd)
       asymbol *sym = syms[idx];
 
       if ((sym->flags & BSF_SECTION_SYM) != 0
+         && sym->value == 0
          && !ignore_section_sym (abfd, sym))
        {
          asection *sec = sym->section;
@@ -3234,14 +3250,8 @@ _bfd_elf_assign_file_position_for_section (Elf_Internal_Shdr *i_shdrp,
                                           file_ptr offset,
                                           bfd_boolean align)
 {
-  if (align)
-    {
-      unsigned int al;
-
-      al = i_shdrp->sh_addralign;
-      if (al > 1)
-       offset = BFD_ALIGN (offset, al);
-    }
+  if (align && i_shdrp->sh_addralign > 1)
+    offset = BFD_ALIGN (offset, i_shdrp->sh_addralign);
   i_shdrp->sh_offset = offset;
   if (i_shdrp->bfd_section != NULL)
     i_shdrp->bfd_section->filepos = offset;
@@ -4288,6 +4298,10 @@ assign_file_positions_for_load_sections (bfd *abfd,
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
        }
+      /* Set the note section type to SHT_NOTE.  */
+      else if (p->p_type == PT_NOTE)
+       for (i = 0; i < m->count; i++)
+         elf_section_type (m->sections[i]) = SHT_NOTE;
 
       p->p_offset = 0;
       p->p_filesz = 0;
@@ -4371,30 +4385,28 @@ assign_file_positions_for_load_sections (bfd *abfd,
          this_hdr = &elf_section_data (sec)->this_hdr;
          align = (bfd_size_type) 1 << bfd_get_section_alignment (abfd, sec);
 
-         if (p->p_type == PT_LOAD
-             || p->p_type == PT_TLS)
-           {
-             bfd_signed_vma adjust = sec->lma - (p->p_paddr + p->p_memsz);
-
-             if (this_hdr->sh_type != SHT_NOBITS
+         if ((p->p_type == PT_LOAD
+              || p->p_type == PT_TLS)
+             && (this_hdr->sh_type != SHT_NOBITS
                  || ((this_hdr->sh_flags & SHF_ALLOC) != 0
                      && ((this_hdr->sh_flags & SHF_TLS) == 0
-                         || p->p_type == PT_TLS)))
+                         || p->p_type == PT_TLS))))
+           {
+             bfd_signed_vma adjust = sec->vma - (p->p_vaddr + p->p_memsz);
+
+             if (adjust < 0)
                {
-                 if (adjust < 0)
-                   {
-                     (*_bfd_error_handler)
-                       (_("%B: section %A lma 0x%lx overlaps previous sections"),
-                        abfd, sec, (unsigned long) sec->lma);
-                     adjust = 0;
-                   }
-                 p->p_memsz += adjust;
+                 (*_bfd_error_handler)
+                   (_("%B: section %A vma 0x%lx overlaps previous sections"),
+                    abfd, sec, (unsigned long) sec->lma);
+                 adjust = 0;
+               }
+             p->p_memsz += adjust;
 
-                 if (this_hdr->sh_type != SHT_NOBITS)
-                   {
-                     off += adjust;
-                     p->p_filesz += adjust;
-                   }
+             if (this_hdr->sh_type != SHT_NOBITS)
+               {
+                 off += adjust;
+                 p->p_filesz += adjust;
                }
            }
 
@@ -4553,12 +4565,6 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
        hdr->sh_offset = -1;
       else
        off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
-
-      if (i == SHN_LORESERVE - 1)
-       {
-         i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
-         hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
-       }
     }
 
   /* Now that we have set the section file positions, we can set up
@@ -4755,12 +4761,6 @@ assign_file_positions_except_relocs (bfd *abfd,
            }
          else
            off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
-
-         if (i == SHN_LORESERVE - 1)
-           {
-             i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
-             hdrpp += SHN_HIRESERVE + 1 - SHN_LORESERVE;
-           }
        }
     }
   else
@@ -4806,12 +4806,10 @@ prep_headers (bfd *abfd)
 {
   Elf_Internal_Ehdr *i_ehdrp;  /* Elf file header, internal form */
   Elf_Internal_Phdr *i_phdrp = 0; /* Program header table, internal form */
-  Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */
   struct elf_strtab_hash *shstrtab;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   i_ehdrp = elf_elfheader (abfd);
-  i_shdrp = elf_elfsections (abfd);
 
   shstrtab = _bfd_elf_strtab_init ();
   if (shstrtab == NULL)
@@ -4956,8 +4954,6 @@ _bfd_elf_write_object_contents (bfd *abfd)
              || bfd_bwrite (i_shdrp[count]->contents, amt, abfd) != amt)
            return FALSE;
        }
-      if (count == SHN_LORESERVE - 1)
-       count += SHN_HIRESERVE + 1 - SHN_LORESERVE;
     }
 
   /* Write out the section header names.  */
@@ -4989,11 +4985,11 @@ _bfd_elf_write_corefile_contents (bfd *abfd)
 
 /* Given a section, search the header to find them.  */
 
-int
+unsigned int
 _bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
 {
   const struct elf_backend_data *bed;
-  int index;
+  unsigned int index;
 
   if (elf_section_data (asect) != NULL
       && elf_section_data (asect)->this_idx != 0)
@@ -5006,7 +5002,7 @@ _bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
   else if (bfd_is_und_section (asect))
     index = SHN_UNDEF;
   else
-    index = -1;
+    index = SHN_BAD;
 
   bed = get_elf_backend_data (abfd);
   if (bed->elf_backend_section_from_bfd_section)
@@ -5017,7 +5013,7 @@ _bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
        return retval;
     }
 
-  if (index == -1)
+  if (index == SHN_BAD)
     bfd_set_error (bfd_error_nonrepresentable_section);
 
   return index;
@@ -5094,6 +5090,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
   unsigned int i;
   unsigned int num_segments;
   bfd_boolean phdr_included = FALSE;
+  bfd_boolean p_paddr_valid;
   bfd_vma maxpagesize;
   struct elf_segment_map *phdr_adjust_seg = NULL;
   unsigned int phdr_adjust_num = 0;
@@ -5222,6 +5219,20 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
   for (section = ibfd->sections; section != NULL; section = section->next)
     section->segment_mark = FALSE;
 
+  /* The Solaris linker creates program headers in which all the
+     p_paddr fields are zero.  When we try to objcopy or strip such a
+     file, we get confused.  Check for this case, and if we find it
+     don't set the p_paddr_valid fields.  */
+  p_paddr_valid = FALSE;
+  for (i = 0, segment = elf_tdata (ibfd)->phdr;
+       i < num_segments;
+       i++, segment++)
+    if (segment->p_paddr != 0)
+      {
+       p_paddr_valid = TRUE;
+       break;
+      }
+
   /* Scan through the segments specified in the program header
      of the input BFD.  For this first scan we look for overlaps
      in the loadable segments.  These can be created by weird
@@ -5357,7 +5368,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
       if (!first_section || first_section->output_section != NULL)
        {
          map->p_paddr = segment->p_paddr;
-         map->p_paddr_valid = 1;
+         map->p_paddr_valid = p_paddr_valid;
        }
 
       /* Determine if this segment contains the ELF file header
@@ -5424,8 +5435,6 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
         pointers that we are interested in.  As these sections get assigned
         to a segment, they are removed from this array.  */
 
-      /* Gcc 2.96 miscompiles this code on mips. Don't do casting here
-        to work around this long long bug.  */
       sections = bfd_malloc2 (section_count, sizeof (asection *));
       if (sections == NULL)
        return FALSE;
@@ -5460,7 +5469,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
                 We try to catch that case here, and set it to the
                 correct value.  Note - some backends require that
                 p_paddr be left as zero.  */
-             if (segment->p_paddr == 0
+             if (!p_paddr_valid
                  && segment->p_vaddr != 0
                  && !bed->want_p_paddr_set_to_zero
                  && isec == 0
@@ -5518,9 +5527,11 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
          *pointer_to_map = map;
          pointer_to_map = &map->next;
 
-         if (!bed->want_p_paddr_set_to_zero
+         if (p_paddr_valid
+             && !bed->want_p_paddr_set_to_zero
              && matching_lma != map->p_paddr
-             && !map->includes_filehdr && !map->includes_phdrs)
+             && !map->includes_filehdr
+             && !map->includes_phdrs)
            /* There is some padding before the first section in the
               segment.  So, we must account for that in the output
               segment's vma.  */
@@ -5672,7 +5683,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
              map->p_flags = segment->p_flags;
              map->p_flags_valid = 1;
              map->p_paddr = suggested_lma;
-             map->p_paddr_valid = 1;
+             map->p_paddr_valid = p_paddr_valid;
              map->includes_filehdr = 0;
              map->includes_phdrs = 0;
            }
@@ -5682,17 +5693,6 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
       free (sections);
     }
 
-  /* The Solaris linker creates program headers in which all the
-     p_paddr fields are zero.  When we try to objcopy or strip such a
-     file, we get confused.  Check for this case, and if we find it
-     reset the p_paddr_valid fields.  */
-  for (map = map_first; map != NULL; map = map->next)
-    if (map->p_paddr != 0)
-      break;
-  if (map == NULL)
-    for (map = map_first; map != NULL; map = map->next)
-      map->p_paddr_valid = 0;
-
   elf_tdata (obfd)->segment_map = map_first;
 
   /* If we had to estimate the number of program headers that were
@@ -5737,13 +5737,26 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
   unsigned int i;
   unsigned int num_segments;
   bfd_boolean phdr_included = FALSE;
+  bfd_boolean p_paddr_valid;
 
   iehdr = elf_elfheader (ibfd);
 
   map_first = NULL;
   pointer_to_map = &map_first;
 
+  /* If all the segment p_paddr fields are zero, don't set
+     map->p_paddr_valid.  */
+  p_paddr_valid = FALSE;
   num_segments = elf_elfheader (ibfd)->e_phnum;
+  for (i = 0, segment = elf_tdata (ibfd)->phdr;
+       i < num_segments;
+       i++, segment++)
+    if (segment->p_paddr != 0)
+      {
+       p_paddr_valid = TRUE;
+       break;
+      }
+
   for (i = 0, segment = elf_tdata (ibfd)->phdr;
        i < num_segments;
        i++, segment++)
@@ -5787,7 +5800,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
       map->p_flags = segment->p_flags;
       map->p_flags_valid = 1;
       map->p_paddr = segment->p_paddr;
-      map->p_paddr_valid = 1;
+      map->p_paddr_valid = p_paddr_valid;
       map->p_align = segment->p_align;
       map->p_align_valid = 1;
       map->p_vaddr_offset = 0;
@@ -5821,7 +5834,9 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
            phdr_included = TRUE;
        }
 
-      if (!map->includes_phdrs && !map->includes_filehdr)
+      if (!map->includes_phdrs
+         && !map->includes_filehdr
+         && map->p_paddr_valid)
        /* There is some other padding before the first section.  */
        map->p_vaddr_offset = ((lowest_section ? lowest_section->lma : 0)
                               - segment->p_paddr);
@@ -6170,7 +6185,7 @@ swap_out_syms (bfd *abfd,
   symtab_hdr->sh_entsize = bed->s->sizeof_sym;
   symtab_hdr->sh_size = symtab_hdr->sh_entsize * (symcount + 1);
   symtab_hdr->sh_info = elf_num_locals (abfd) + 1;
-  symtab_hdr->sh_addralign = 1 << bed->s->log_file_align;
+  symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
 
   symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
   symstrtab_hdr->sh_type = SHT_STRTAB;
@@ -6270,7 +6285,7 @@ swap_out_syms (bfd *abfd,
       else
        {
          asection *sec = syms[idx]->section;
-         int shndx;
+         unsigned int shndx;
 
          if (sec->output_section)
            {
@@ -6317,7 +6332,7 @@ swap_out_syms (bfd *abfd,
            {
              shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
 
-             if (shndx == -1)
+             if (shndx == SHN_BAD)
                {
                  asection *sec2;
 
@@ -6341,7 +6356,7 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"),
                    }
 
                  shndx = _bfd_elf_section_from_bfd_section (abfd, sec2);
-                 BFD_ASSERT (shndx != -1);
+                 BFD_ASSERT (shndx != SHN_BAD);
                }
            }
 
@@ -6378,11 +6393,15 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"),
            sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION);
        }
       else if (bfd_is_com_section (syms[idx]->section))
-       sym.st_info = ELF_ST_INFO (STB_GLOBAL,
+       {
 #ifdef USE_STT_COMMON
-                                  type == STT_OBJECT ? STT_COMMON :
+         if (type == STT_OBJECT)
+           sym.st_info = ELF_ST_INFO (STB_GLOBAL, STT_COMMON);
+         else
+#else
+           sym.st_info = ELF_ST_INFO (STB_GLOBAL, type);
 #endif
-                                  type);
+       }
       else if (bfd_is_und_section (syms[idx]->section))
        sym.st_info = ELF_ST_INFO (((flags & BSF_WEAK)
                                    ? STB_WEAK
@@ -6544,8 +6563,7 @@ _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
 
   ret = sizeof (arelent *);
   for (s = abfd->sections; s != NULL; s = s->next)
-    if ((s->flags & SEC_LOAD) != 0
-       && elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
+    if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
        && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
            || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
       ret += ((s->size / elf_section_data (s)->this_hdr.sh_entsize)
@@ -6581,8 +6599,7 @@ _bfd_elf_canonicalize_dynamic_reloc (bfd *abfd,
   ret = 0;
   for (s = abfd->sections; s != NULL; s = s->next)
     {
-      if ((s->flags & SEC_LOAD) != 0
-         && elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
+      if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
          && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
              || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
        {
@@ -8457,6 +8474,23 @@ elfcore_write_ppc_vmx (bfd *abfd,
                             note_name, NT_PPC_VMX, ppc_vmx, size);
 }
 
+char *
+elfcore_write_register_note (bfd *abfd,
+                            char *buf,
+                            int *bufsiz,
+                            const char *section,
+                            const void *data,
+                            int size)
+{
+  if (strcmp (section, ".reg2") == 0)
+    return elfcore_write_prfpreg (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-xfp") == 0)
+    return elfcore_write_prxfpreg (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-ppc-vmx") == 0)
+    return elfcore_write_ppc_vmx (abfd, buf, bufsiz, data, size);
+  return NULL;
+}
+
 static bfd_boolean
 elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
 {
@@ -8749,7 +8783,7 @@ _bfd_elf_get_synthetic_symtab (bfd *abfd,
   count = relplt->size / hdr->sh_entsize;
   size = count * sizeof (asymbol);
   p = relplt->relocation;
-  for (i = 0; i < count; i++, p++)
+  for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
     size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
 
   s = *ret = bfd_malloc (size);
@@ -8759,7 +8793,7 @@ _bfd_elf_get_synthetic_symtab (bfd *abfd,
   names = (char *) (s + count);
   p = relplt->relocation;
   n = 0;
-  for (i = 0; i < count; i++, p++)
+  for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
     {
       size_t len;
       bfd_vma addr;
@@ -8773,6 +8807,7 @@ _bfd_elf_get_synthetic_symtab (bfd *abfd,
         we are defining a symbol, ensure one of them is set.  */
       if ((s->flags & BSF_LOCAL) == 0)
        s->flags |= BSF_GLOBAL;
+      s->flags |= BSF_SYNTHETIC;
       s->section = plt;
       s->value = addr - plt->vma;
       s->name = names;
This page took 0.0381 seconds and 4 git commands to generate.