Merge bfd_find_nearest_line variants
[deliverable/binutils-gdb.git] / bfd / elf.c
index a5a24c52997684b1ec8a000cd89f56e5856b7dc0..c884d1d6a930d01d38599b813a24b2a12fb4fcf7 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1,8 +1,6 @@
 /* ELF executable support for BFD.
 
-   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 1993-2014 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -44,6 +42,7 @@ SECTION
 #include "elf-bfd.h"
 #include "libiberty.h"
 #include "safe-ctype.h"
+#include "elf-linux-psinfo.h"
 
 #ifdef CORE_HEADER
 #include CORE_HEADER
@@ -244,23 +243,34 @@ bfd_elf_allocate_object (bfd *abfd,
     return FALSE;
 
   elf_object_id (abfd) = object_id;
-  elf_program_header_size (abfd) = (bfd_size_type) -1;
+  if (abfd->direction != read_direction)
+    {
+      struct output_elf_obj_tdata *o = bfd_zalloc (abfd, sizeof *o);
+      if (o == NULL)
+       return FALSE;
+      elf_tdata (abfd)->o = o;
+      elf_program_header_size (abfd) = (bfd_size_type) -1;
+    }
   return TRUE;
 }
 
 
 bfd_boolean
-bfd_elf_make_generic_object (bfd *abfd)
+bfd_elf_make_object (bfd *abfd)
 {
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   return bfd_elf_allocate_object (abfd, sizeof (struct elf_obj_tdata),
-                                 GENERIC_ELF_DATA);
+                                 bed->target_id);
 }
 
 bfd_boolean
 bfd_elf_mkcorefile (bfd *abfd)
 {
   /* I think this can be done just like an object file.  */
-  return bfd_elf_make_generic_object (abfd);
+  if (!abfd->xvec->_bfd_set_format[(int) bfd_object] (abfd))
+    return FALSE;
+  elf_tdata (abfd)->core = bfd_zalloc (abfd, sizeof (*elf_tdata (abfd)->core));
+  return elf_tdata (abfd)->core != NULL;
 }
 
 static char *
@@ -544,9 +554,9 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
       shnum = elf_numsections (abfd);
       num_group = 0;
 
-#define IS_VALID_GROUP_SECTION_HEADER(shdr)            \
+#define IS_VALID_GROUP_SECTION_HEADER(shdr, minsize)   \
        (   (shdr)->sh_type == SHT_GROUP                \
-        && (shdr)->sh_size >= (2 * GRP_ENTRY_SIZE)     \
+        && (shdr)->sh_size >= minsize                  \
         && (shdr)->sh_entsize == GRP_ENTRY_SIZE        \
         && ((shdr)->sh_size % GRP_ENTRY_SIZE) == 0)
 
@@ -554,7 +564,7 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
        {
          Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
 
-         if (IS_VALID_GROUP_SECTION_HEADER (shdr))
+         if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE))
            num_group += 1;
        }
 
@@ -580,7 +590,7 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
            {
              Elf_Internal_Shdr *shdr = elf_elfsections (abfd)[i];
 
-             if (IS_VALID_GROUP_SECTION_HEADER (shdr))
+             if (IS_VALID_GROUP_SECTION_HEADER (shdr, 2 * GRP_ENTRY_SIZE))
                {
                  unsigned char *src;
                  Elf_Internal_Group *dest;
@@ -821,11 +831,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
   const struct elf_backend_data *bed;
 
   if (hdr->bfd_section != NULL)
-    {
-      BFD_ASSERT (strcmp (name,
-                         bfd_get_section_name (abfd, hdr->bfd_section)) == 0);
-      return TRUE;
-    }
+    return TRUE;
 
   newsect = bfd_make_section_anyway (abfd, name);
   if (newsect == NULL)
@@ -876,50 +882,32 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
       return FALSE;
   if ((hdr->sh_flags & SHF_TLS) != 0)
     flags |= SEC_THREAD_LOCAL;
+  if ((hdr->sh_flags & SHF_EXCLUDE) != 0)
+    flags |= SEC_EXCLUDE;
 
   if ((flags & SEC_ALLOC) == 0)
     {
       /* The debugging sections appear to be recognized only by name,
         not any sort of flag.  Their SEC_ALLOC bits are cleared.  */
-      static const struct
-       {
-         const char *name;
-         int len;
-       } debug_sections [] =
-       {
-         { STRING_COMMA_LEN ("debug") },       /* 'd' */
-         { NULL,                0  },  /* 'e' */
-         { NULL,                0  },  /* 'f' */
-         { STRING_COMMA_LEN ("gnu.linkonce.wi.") },    /* 'g' */
-         { NULL,                0  },  /* 'h' */
-         { NULL,                0  },  /* 'i' */
-         { NULL,                0  },  /* 'j' */
-         { NULL,                0  },  /* 'k' */
-         { STRING_COMMA_LEN ("line") },        /* 'l' */
-         { NULL,                0  },  /* 'm' */
-         { NULL,                0  },  /* 'n' */
-         { NULL,                0  },  /* 'o' */
-         { NULL,                0  },  /* 'p' */
-         { NULL,                0  },  /* 'q' */
-         { NULL,                0  },  /* 'r' */
-         { 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] == '.')
        {
-         int i = name [1] - 'd';
-         if (i >= 0
-             && i < (int) ARRAY_SIZE (debug_sections)
-             && debug_sections [i].name != NULL
-             && strncmp (&name [1], debug_sections [i].name,
-                         debug_sections [i].len) == 0)
+         const char *p;
+         int n;
+         if (name[1] == 'd')
+           p = ".debug", n = 6;
+         else if (name[1] == 'g' && name[2] == 'n')
+           p = ".gnu.linkonce.wi.", n = 17;
+         else if (name[1] == 'g' && name[2] == 'd')
+           p = ".gdb_index", n = 11; /* yes we really do mean 11.  */
+         else if (name[1] == 'l')
+           p = ".line", n = 5;
+         else if (name[1] == 's')
+           p = ".stab", n = 5;
+         else if (name[1] == 'z')
+           p = ".zdebug", n = 7;
+         else
+           p = NULL, n = 0;
+         if (p != NULL && strncmp (name, p, n) == 0)
            flags |= SEC_DEBUGGING;
        }
     }
@@ -977,7 +965,9 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
       phdr = elf_tdata (abfd)->phdr;
       for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
        {
-         if (phdr->p_type == PT_LOAD
+         if (((phdr->p_type == PT_LOAD
+               && (hdr->sh_flags & SHF_TLS) == 0)
+              || phdr->p_type == PT_TLS)
              && ELF_SECTION_IN_SEGMENT (hdr, phdr))
            {
              if ((flags & SEC_LOAD) == 0)
@@ -1006,6 +996,77 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
        }
     }
 
+  /* Compress/decompress DWARF debug sections with names: .debug_* and
+     .zdebug_*, after the section flags is set.  */
+  if ((flags & SEC_DEBUGGING)
+      && ((name[1] == 'd' && name[6] == '_')
+         || (name[1] == 'z' && name[7] == '_')))
+    {
+      enum { nothing, compress, decompress } action = nothing;
+      char *new_name;
+
+      if (bfd_is_section_compressed (abfd, newsect))
+       {
+         /* Compressed section.  Check if we should decompress.  */
+         if ((abfd->flags & BFD_DECOMPRESS))
+           action = decompress;
+       }
+      else
+       {
+         /* Normal section.  Check if we should compress.  */
+         if ((abfd->flags & BFD_COMPRESS) && newsect->size != 0)
+           action = compress;
+       }
+
+      new_name = NULL;
+      switch (action)
+       {
+       case nothing:
+         break;
+       case compress:
+         if (!bfd_init_section_compress_status (abfd, newsect))
+           {
+             (*_bfd_error_handler)
+               (_("%B: unable to initialize compress status for section %s"),
+                abfd, name);
+             return FALSE;
+           }
+         if (name[1] != 'z')
+           {
+             unsigned int len = strlen (name);
+
+             new_name = bfd_alloc (abfd, len + 2);
+             if (new_name == NULL)
+               return FALSE;
+             new_name[0] = '.';
+             new_name[1] = 'z';
+             memcpy (new_name + 2, name + 1, len);
+           }
+         break;
+       case decompress:
+         if (!bfd_init_section_decompress_status (abfd, newsect))
+           {
+             (*_bfd_error_handler)
+               (_("%B: unable to initialize decompress status for section %s"),
+                abfd, name);
+             return FALSE;
+           }
+         if (name[1] == 'z')
+           {
+             unsigned int len = strlen (name);
+
+             new_name = bfd_alloc (abfd, len);
+             if (new_name == NULL)
+               return FALSE;
+             new_name[0] = '.';
+             memcpy (new_name + 1, name + 2, len - 1);
+           }
+         break;
+       }
+      if (new_name != NULL)
+       bfd_rename_section (abfd, newsect, new_name);
+    }
+
   return TRUE;
 }
 
@@ -1056,13 +1117,17 @@ _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return TRUE;
 
-  BFD_ASSERT (!elf_flags_init (obfd)
-             || (elf_elfheader (obfd)->e_flags
-                 == elf_elfheader (ibfd)->e_flags));
+  if (!elf_flags_init (obfd))
+    {
+      elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
+      elf_flags_init (obfd) = TRUE;
+    }
 
   elf_gp (obfd) = elf_gp (ibfd);
-  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
-  elf_flags_init (obfd) = TRUE;
+
+  /* Also copy the EI_OSABI field.  */
+  elf_elfheader (obfd)->e_ident[EI_OSABI] =
+    elf_elfheader (ibfd)->e_ident[EI_OSABI];
 
   /* Copy object attributes.  */
   _bfd_elf_copy_obj_attributes (ibfd, obfd);
@@ -1382,9 +1447,9 @@ bfd_elf_print_symbol (bfd *abfd,
        bfd_fprintf_vma (abfd, file, val);
 
        /* If we have version information, print it.  */
-       if (elf_tdata (abfd)->dynversym_section != 0
-           && (elf_tdata (abfd)->dynverdef_section != 0
-               || elf_tdata (abfd)->dynverref_section != 0))
+       if (elf_dynversym (abfd) != 0
+           && (elf_dynverdef (abfd) != 0
+               || elf_dynverref (abfd) != 0))
          {
            unsigned int vernum;
            const char *version_string;
@@ -1574,7 +1639,15 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
       if (hdr->sh_entsize != bed->s->sizeof_sym)
        return FALSE;
       if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
-       return FALSE;
+       {
+         if (hdr->sh_size != 0)
+           return FALSE;
+         /* Some assemblers erroneously set sh_info to one with a
+            zero sh_size.  ld sees this as a global symbol count
+            of (unsigned) -1.  Fix it here.  */
+         hdr->sh_info = 0;
+         return TRUE;
+       }
       BFD_ASSERT (elf_onesymtab (abfd) == 0);
       elf_onesymtab (abfd) = shindex;
       elf_tdata (abfd)->symtab_hdr = *hdr;
@@ -1627,6 +1700,16 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
 
       if (hdr->sh_entsize != bed->s->sizeof_sym)
        return FALSE;
+      if (hdr->sh_info * hdr->sh_entsize > hdr->sh_size)
+       {
+         if (hdr->sh_size != 0)
+           return FALSE;
+         /* Some linkers erroneously set sh_info to one with a
+            zero sh_size.  ld sees this as a global symbol count
+            of (unsigned) -1.  Fix it here.  */
+         hdr->sh_info = 0;
+         return TRUE;
+       }
       BFD_ASSERT (elf_dynsymtab (abfd) == 0);
       elf_dynsymtab (abfd) = shindex;
       elf_tdata (abfd)->dynsymtab_hdr = *hdr;
@@ -1707,8 +1790,10 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
       /* *These* do a lot of work -- but build no sections!  */
       {
        asection *target_sect;
-       Elf_Internal_Shdr *hdr2;
+       Elf_Internal_Shdr *hdr2, **p_hdr;
        unsigned int num_sec = elf_numsections (abfd);
+       struct bfd_elf_section_data *esdt;
+       bfd_size_type amt;
 
        if (hdr->sh_entsize
            != (bfd_size_type) (hdr->sh_type == SHT_REL
@@ -1787,20 +1872,19 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
        if (target_sect == NULL)
          return FALSE;
 
-       if ((target_sect->flags & SEC_RELOC) == 0
-           || target_sect->reloc_count == 0)
-         hdr2 = &elf_section_data (target_sect)->rel_hdr;
+       esdt = elf_section_data (target_sect);
+       if (hdr->sh_type == SHT_RELA)
+         p_hdr = &esdt->rela.hdr;
        else
-         {
-           bfd_size_type amt;
-           BFD_ASSERT (elf_section_data (target_sect)->rel_hdr2 == NULL);
-           amt = sizeof (*hdr2);
-           hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
-           if (hdr2 == NULL)
-             return FALSE;
-           elf_section_data (target_sect)->rel_hdr2 = hdr2;
-         }
+         p_hdr = &esdt->rel.hdr;
+
+       BFD_ASSERT (*p_hdr == NULL);
+       amt = sizeof (*hdr2);
+       hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, amt);
+       if (hdr2 == NULL)
+         return FALSE;
        *hdr2 = *hdr;
+       *p_hdr = hdr2;
        elf_elfsections (abfd)[shindex] = hdr2;
        target_sect->reloc_count += NUM_SHDR_ENTRIES (hdr);
        target_sect->flags |= SEC_RELOC;
@@ -1809,7 +1893,10 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
        /* In the section to which the relocations apply, mark whether
           its relocations are of the REL or RELA variety.  */
        if (hdr->sh_size != 0)
-         target_sect->use_rela_p = hdr->sh_type == SHT_RELA;
+         {
+           if (hdr->sh_type == SHT_RELA)
+             target_sect->use_rela_p = 1;
+         }
        abfd->flags |= HAS_RELOC;
        return TRUE;
       }
@@ -1835,7 +1922,7 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
       return TRUE;
 
     case SHT_GROUP:
-      if (! IS_VALID_GROUP_SECTION_HEADER (hdr))
+      if (! IS_VALID_GROUP_SECTION_HEADER (hdr, GRP_ENTRY_SIZE))
        return FALSE;
       if (!_bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
        return FALSE;
@@ -1987,6 +2074,9 @@ static const struct bfd_elf_special_section special_sections_d[] =
 {
   { STRING_COMMA_LEN (".data"),         -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".data1"),         0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+  /* There are more DWARF sections than these, but they needn't be added here
+     unless you have to cope with broken compilers that don't emit section
+     attributes or you want to help the user writing assembler.  */
   { STRING_COMMA_LEN (".debug"),         0, SHT_PROGBITS, 0 },
   { STRING_COMMA_LEN (".debug_line"),    0, SHT_PROGBITS, 0 },
   { STRING_COMMA_LEN (".debug_info"),    0, SHT_PROGBITS, 0 },
@@ -2008,6 +2098,7 @@ static const struct bfd_elf_special_section special_sections_f[] =
 static const struct bfd_elf_special_section special_sections_g[] =
 {
   { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS,      SHF_ALLOC + SHF_WRITE },
+  { STRING_COMMA_LEN (".gnu.lto_"),       -1, SHT_PROGBITS,    SHF_EXCLUDE },
   { STRING_COMMA_LEN (".got"),             0, SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".gnu.version"),     0, SHT_GNU_versym,  0 },
   { STRING_COMMA_LEN (".gnu.version_d"),   0, SHT_GNU_verdef,  0 },
@@ -2089,7 +2180,7 @@ static const struct bfd_elf_special_section special_sections_z[] =
   { NULL,                     0,  0, 0,            0 }
 };
 
-static const struct bfd_elf_special_section *special_sections[] =
+static const struct bfd_elf_special_section * const special_sections[] =
 {
   special_sections_b,          /* 'b' */
   special_sections_c,          /* 'c' */
@@ -2229,12 +2320,19 @@ _bfd_elf_new_section_hook (bfd *abfd, asection *sec)
      anyway.  We will set ELF section type and flags for all linker
      created sections.  If user specifies BFD section flags, we will
      set ELF section type and flags based on BFD section flags in
-     elf_fake_sections.  */
-  if ((!sec->flags && abfd->direction != read_direction)
+     elf_fake_sections.  Special handling for .init_array/.fini_array
+     output sections since they may contain .ctors/.dtors input
+     sections.  We don't want _bfd_elf_init_private_section_data to
+     copy ELF section type from .ctors/.dtors input sections.  */
+  if (abfd->direction != read_direction
       || (sec->flags & SEC_LINKER_CREATED) != 0)
     {
       ssect = (*bed->get_sec_type_attr) (abfd, sec);
-      if (ssect != NULL)
+      if (ssect != NULL
+         && (!sec->flags
+             || (sec->flags & SEC_LINKER_CREATED) != 0
+             || ssect->type == SHT_INIT_ARRAY
+             || ssect->type == SHT_FINI_ARRAY))
        {
          elf_section_type (sec) = ssect->type;
          elf_section_flags (sec) = ssect->attr;
@@ -2407,20 +2505,43 @@ bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int hdr_index)
     }
 }
 
-/* Initialize REL_HDR, the section-header for new section, containing
-   relocations against ASECT.  If USE_RELA_P is TRUE, we use RELA
-   relocations; otherwise, we use REL relocations.  */
+/* Return the REL_HDR for SEC, assuming there is only a single one, either
+   REL or RELA.  */
 
-bfd_boolean
+Elf_Internal_Shdr *
+_bfd_elf_single_rel_hdr (asection *sec)
+{
+  if (elf_section_data (sec)->rel.hdr)
+    {
+      BFD_ASSERT (elf_section_data (sec)->rela.hdr == NULL);
+      return elf_section_data (sec)->rel.hdr;
+    }
+  else
+    return elf_section_data (sec)->rela.hdr;
+}
+
+/* Allocate and initialize a section-header for a new reloc section,
+   containing relocations against ASECT.  It is stored in RELDATA.  If
+   USE_RELA_P is TRUE, we use RELA relocations; otherwise, we use REL
+   relocations.  */
+
+static bfd_boolean
 _bfd_elf_init_reloc_shdr (bfd *abfd,
-                         Elf_Internal_Shdr *rel_hdr,
+                         struct bfd_elf_section_reloc_data *reldata,
                          asection *asect,
                          bfd_boolean use_rela_p)
 {
+  Elf_Internal_Shdr *rel_hdr;
   char *name;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-  bfd_size_type amt = sizeof ".rela" + strlen (asect->name);
+  bfd_size_type amt;
+
+  amt = sizeof (Elf_Internal_Shdr);
+  BFD_ASSERT (reldata->hdr == NULL);
+  rel_hdr = bfd_zalloc (abfd, amt);
+  reldata->hdr = rel_hdr;
 
+  amt = sizeof ".rela" + strlen (asect->name);
   name = (char *) bfd_alloc (abfd, amt);
   if (name == NULL)
     return FALSE;
@@ -2449,36 +2570,42 @@ int
 bfd_elf_get_default_section_type (flagword flags)
 {
   if ((flags & SEC_ALLOC) != 0
-      && ((flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0
-         || (flags & SEC_NEVER_LOAD) != 0))
+      && (flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
     return SHT_NOBITS;
   return SHT_PROGBITS;
 }
 
+struct fake_section_arg
+{
+  struct bfd_link_info *link_info;
+  bfd_boolean failed;
+};
+
 /* Set up an ELF internal section header for a section.  */
 
 static void
-elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
+elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
 {
+  struct fake_section_arg *arg = (struct fake_section_arg *)fsarg;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-  bfd_boolean *failedptr = (bfd_boolean *) failedptrarg;
+  struct bfd_elf_section_data *esd = elf_section_data (asect);
   Elf_Internal_Shdr *this_hdr;
   unsigned int sh_type;
 
-  if (*failedptr)
+  if (arg->failed)
     {
       /* We already failed; just get out of the bfd_map_over_sections
         loop.  */
       return;
     }
 
-  this_hdr = &elf_section_data (asect)->this_hdr;
+  this_hdr = &esd->this_hdr;
 
   this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
                                                          asect->name, FALSE);
   if (this_hdr->sh_name == (unsigned int) -1)
     {
-      *failedptr = TRUE;
+      arg->failed = TRUE;
       return;
     }
 
@@ -2627,12 +2754,48 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
            }
        }
     }
+  if ((asect->flags & (SEC_GROUP | SEC_EXCLUDE)) == SEC_EXCLUDE)
+    this_hdr->sh_flags |= SHF_EXCLUDE;
+
+  /* If the section has relocs, set up a section header for the
+     SHT_REL[A] section.  If two relocation sections are required for
+     this section, it is up to the processor-specific back-end to
+     create the other.  */
+  if ((asect->flags & SEC_RELOC) != 0)
+    {
+      /* When doing a relocatable link, create both REL and RELA sections if
+        needed.  */
+      if (arg->link_info
+         /* Do the normal setup if we wouldn't create any sections here.  */
+         && esd->rel.count + esd->rela.count > 0
+         && (arg->link_info->relocatable || arg->link_info->emitrelocations))
+       {
+         if (esd->rel.count && esd->rel.hdr == NULL
+             && !_bfd_elf_init_reloc_shdr (abfd, &esd->rel, asect, FALSE))
+           {
+             arg->failed = TRUE;
+             return;
+           }
+         if (esd->rela.count && esd->rela.hdr == NULL
+             && !_bfd_elf_init_reloc_shdr (abfd, &esd->rela, asect, TRUE))
+           {
+             arg->failed = TRUE;
+             return;
+           }
+       }
+      else if (!_bfd_elf_init_reloc_shdr (abfd,
+                                         (asect->use_rela_p
+                                          ? &esd->rela : &esd->rel),
+                                         asect,
+                                         asect->use_rela_p))
+         arg->failed = TRUE;
+    }
 
   /* Check for processor-specific section types.  */
   sh_type = this_hdr->sh_type;
   if (bed->elf_backend_fake_sections
       && !(*bed->elf_backend_fake_sections) (abfd, this_hdr, asect))
-    *failedptr = TRUE;
+    arg->failed = TRUE;
 
   if (sh_type == SHT_NOBITS && asect->size != 0)
     {
@@ -2640,17 +2803,6 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
         called for objcopy --only-keep-debug.  */
       this_hdr->sh_type = sh_type;
     }
-
-  /* If the section has relocs, set up a section header for the
-     SHT_REL[A] section.  If two relocation sections are required for
-     this section, it is up to the processor-specific back-end to
-     create the other.  */
-  if ((asect->flags & SEC_RELOC) != 0
-      && !_bfd_elf_init_reloc_shdr (abfd,
-                                   &elf_section_data (asect)->rel_hdr,
-                                   asect,
-                                   asect->use_rela_p))
-    *failedptr = TRUE;
 }
 
 /* Fill in the contents of a SHT_GROUP section.  Called from
@@ -2816,26 +2968,26 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
       if (d->this_hdr.sh_type != SHT_GROUP)
        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 (d->rel.hdr)
        {
-         d->rel_idx = section_number++;
-         _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr.sh_name);
+         d->rel.idx = section_number++;
+         _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel.hdr->sh_name);
        }
+      else
+       d->rel.idx = 0;
 
-      if (d->rel_hdr2)
+      if (d->rela.hdr)
        {
-         d->rel_idx2 = section_number++;
-         _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr2->sh_name);
+         d->rela.idx = section_number++;
+         _bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rela.hdr->sh_name);
        }
       else
-       d->rel_idx2 = 0;
+       d->rela.idx = 0;
     }
 
-  t->shstrtab_section = section_number++;
+  elf_shstrtab_sec (abfd) = section_number++;
   _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
-  elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;
+  elf_elfheader (abfd)->e_shstrndx = elf_shstrtab_sec (abfd);
 
   need_symtab = (bfd_get_symcount (abfd) > 0
                || (link_info == NULL
@@ -2843,21 +2995,28 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
                        == HAS_RELOC)));
   if (need_symtab)
     {
-      t->symtab_section = section_number++;
+      elf_onesymtab (abfd) = section_number++;
       _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
       if (section_number > ((SHN_LORESERVE - 2) & 0xFFFF))
        {
-         t->symtab_shndx_section = section_number++;
+         elf_symtab_shndx (abfd) = section_number++;
          t->symtab_shndx_hdr.sh_name
            = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
                                                  ".symtab_shndx", FALSE);
          if (t->symtab_shndx_hdr.sh_name == (unsigned int) -1)
            return FALSE;
        }
-      t->strtab_section = section_number++;
+      elf_strtab_sec (abfd) = section_number++;
       _bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
     }
 
+  if (section_number >= SHN_LORESERVE)
+    {
+      _bfd_error_handler (_("%B: too many sections: %u"),
+                         abfd, section_number);
+      return FALSE;
+    }
+
   _bfd_elf_strtab_finalize (elf_shstrtab (abfd));
   t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
 
@@ -2881,17 +3040,17 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
 
   elf_elfsections (abfd) = i_shdrp;
 
-  i_shdrp[t->shstrtab_section] = &t->shstrtab_hdr;
+  i_shdrp[elf_shstrtab_sec (abfd)] = &t->shstrtab_hdr;
   if (need_symtab)
     {
-      i_shdrp[t->symtab_section] = &t->symtab_hdr;
+      i_shdrp[elf_onesymtab (abfd)] = &t->symtab_hdr;
       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;
+         i_shdrp[elf_symtab_shndx (abfd)] = &t->symtab_shndx_hdr;
+         t->symtab_shndx_hdr.sh_link = elf_onesymtab (abfd);
        }
-      i_shdrp[t->strtab_section] = &t->strtab_hdr;
-      t->symtab_hdr.sh_link = t->strtab_section;
+      i_shdrp[elf_strtab_sec (abfd)] = &t->strtab_hdr;
+      t->symtab_hdr.sh_link = elf_strtab_sec (abfd);
     }
 
   for (sec = abfd->sections; sec; sec = sec->next)
@@ -2902,25 +3061,27 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
       d = elf_section_data (sec);
 
       i_shdrp[d->this_idx] = &d->this_hdr;
-      if (d->rel_idx != 0)
-       i_shdrp[d->rel_idx] = &d->rel_hdr;
-      if (d->rel_idx2 != 0)
-       i_shdrp[d->rel_idx2] = d->rel_hdr2;
+      if (d->rel.idx != 0)
+       i_shdrp[d->rel.idx] = d->rel.hdr;
+      if (d->rela.idx != 0)
+       i_shdrp[d->rela.idx] = d->rela.hdr;
 
       /* Fill in the sh_link and sh_info fields while we're at it.  */
 
       /* sh_link of a reloc section is the section index of the symbol
         table.  sh_info is the section index of the section to which
         the relocation entries apply.  */
-      if (d->rel_idx != 0)
+      if (d->rel.idx != 0)
        {
-         d->rel_hdr.sh_link = t->symtab_section;
-         d->rel_hdr.sh_info = d->this_idx;
+         d->rel.hdr->sh_link = elf_onesymtab (abfd);
+         d->rel.hdr->sh_info = d->this_idx;
+         d->rel.hdr->sh_flags |= SHF_INFO_LINK;
        }
-      if (d->rel_idx2 != 0)
+      if (d->rela.idx != 0)
        {
-         d->rel_hdr2->sh_link = t->symtab_section;
-         d->rel_hdr2->sh_info = d->this_idx;
+         d->rela.hdr->sh_link = elf_onesymtab (abfd);
+         d->rela.hdr->sh_info = d->this_idx;
+         d->rela.hdr->sh_flags |= SHF_INFO_LINK;
        }
 
       /* We need to set up sh_link for SHF_LINK_ORDER.  */
@@ -2933,7 +3094,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
              if (link_info != NULL)
                {
                  /* Check discarded linkonce section.  */
-                 if (elf_discarded_section (s))
+                 if (discarded_section (s))
                    {
                      asection *kept;
                      (*_bfd_error_handler)
@@ -3007,7 +3168,10 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
            name += 5;
          s = bfd_get_section_by_name (abfd, name);
          if (s != NULL)
-           d->this_hdr.sh_info = elf_section_data (s)->this_idx;
+           {
+             d->this_hdr.sh_info = elf_section_data (s)->this_idx;
+             d->this_hdr.sh_flags |= SHF_INFO_LINK;
+           }
          break;
 
        case SHT_STRTAB:
@@ -3074,7 +3238,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
          break;
 
        case SHT_GROUP:
-         d->this_hdr.sh_link = t->symtab_section;
+         d->this_hdr.sh_link = elf_onesymtab (abfd);
        }
     }
 
@@ -3087,9 +3251,6 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
   return TRUE;
 }
 
-/* Map symbol from it's internal number to the external number, moving
-   all local symbols to be at the head of the list.  */
-
 static bfd_boolean
 sym_is_global (bfd *abfd, asymbol *sym)
 {
@@ -3104,19 +3265,31 @@ sym_is_global (bfd *abfd, asymbol *sym)
 }
 
 /* Don't output section symbols for sections that are not going to be
-   output.  */
+   output, that are duplicates or there is no BFD section.  */
 
 static bfd_boolean
 ignore_section_sym (bfd *abfd, asymbol *sym)
 {
-  return ((sym->flags & BSF_SECTION_SYM) != 0
-         && !(sym->section->owner == abfd
+  elf_symbol_type *type_ptr;
+
+  if ((sym->flags & BSF_SECTION_SYM) == 0)
+    return FALSE;
+
+  type_ptr = elf_symbol_from (abfd, sym);
+  return ((type_ptr != NULL
+          && type_ptr->internal_elf_sym.st_shndx != 0
+          && bfd_is_abs_section (sym->section))
+         || !(sym->section->owner == abfd
               || (sym->section->output_section->owner == abfd
-                  && sym->section->output_offset == 0)));
+                  && sym->section->output_offset == 0)
+              || bfd_is_abs_section (sym->section)));
 }
 
+/* Map symbol from it's internal number to the external number, moving
+   all local symbols to be at the head of the list.  */
+
 static bfd_boolean
-elf_map_symbols (bfd *abfd)
+elf_map_symbols (bfd *abfd, unsigned int *pnum_locals)
 {
   unsigned int symcount = bfd_get_symcount (abfd);
   asymbol **syms = bfd_get_outsymbols (abfd);
@@ -3156,7 +3329,8 @@ elf_map_symbols (bfd *abfd)
 
       if ((sym->flags & BSF_SECTION_SYM) != 0
          && sym->value == 0
-         && !ignore_section_sym (abfd, sym))
+         && !ignore_section_sym (abfd, sym)
+         && !bfd_is_abs_section (sym->section))
        {
          asection *sec = sym->section;
 
@@ -3170,12 +3344,10 @@ elf_map_symbols (bfd *abfd)
   /* Classify all of the symbols.  */
   for (idx = 0; idx < symcount; idx++)
     {
-      if (ignore_section_sym (abfd, syms[idx]))
-       continue;
-      if (!sym_is_global (abfd, syms[idx]))
-       num_locals++;
-      else
+      if (sym_is_global (abfd, syms[idx]))
        num_globals++;
+      else if (!ignore_section_sym (abfd, syms[idx]))
+       num_locals++;
     }
 
   /* We will be adding a section symbol for each normal BFD section.  Most
@@ -3205,12 +3377,12 @@ elf_map_symbols (bfd *abfd)
       asymbol *sym = syms[idx];
       unsigned int i;
 
-      if (ignore_section_sym (abfd, sym))
-       continue;
-      if (!sym_is_global (abfd, sym))
+      if (sym_is_global (abfd, sym))
+       i = num_locals + num_globals2++;
+      else if (!ignore_section_sym (abfd, sym))
        i = num_locals2++;
       else
-       i = num_locals + num_globals2++;
+       continue;
       new_syms[i] = sym;
       sym->udata.i = i + 1;
     }
@@ -3233,8 +3405,7 @@ elf_map_symbols (bfd *abfd)
 
   bfd_set_symtab (abfd, new_syms, num_locals + num_globals);
 
-  elf_num_locals (abfd) = num_locals;
-  elf_num_globals (abfd) = num_globals;
+  *pnum_locals = num_locals;
   return TRUE;
 }
 
@@ -3274,6 +3445,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
                                         struct bfd_link_info *link_info)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  struct fake_section_arg fsargs;
   bfd_boolean failed;
   struct bfd_strtab_hash *strtab = NULL;
   Elf_Internal_Shdr *shstrtab_hdr;
@@ -3290,12 +3462,12 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
     return FALSE;
 
   /* Post process the headers if necessary.  */
-  if (bed->elf_backend_post_process_headers)
-    (*bed->elf_backend_post_process_headers) (abfd, link_info);
+  (*bed->elf_backend_post_process_headers) (abfd, link_info);
 
-  failed = FALSE;
-  bfd_map_over_sections (abfd, elf_fake_sections, &failed);
-  if (failed)
+  fsargs.failed = FALSE;
+  fsargs.link_info = link_info;
+  bfd_map_over_sections (abfd, elf_fake_sections, &fsargs);
+  if (fsargs.failed)
     return FALSE;
 
   if (!assign_section_numbers (abfd, link_info))
@@ -3315,6 +3487,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
        return FALSE;
     }
 
+  failed = FALSE;
   if (link_info == NULL)
     {
       bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed);
@@ -3342,7 +3515,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
       file_ptr off;
       Elf_Internal_Shdr *hdr;
 
-      off = elf_tdata (abfd)->next_file_pos;
+      off = elf_next_file_pos (abfd);
 
       hdr = &elf_tdata (abfd)->symtab_hdr;
       off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
@@ -3354,7 +3527,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
       hdr = &elf_tdata (abfd)->strtab_hdr;
       off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
 
-      elf_tdata (abfd)->next_file_pos = off;
+      elf_next_file_pos (abfd) = off;
 
       /* Now that we know where the .strtab section goes, write it
         out.  */
@@ -3405,13 +3578,13 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info)
       ++segs;
     }
 
-  if (elf_tdata (abfd)->eh_frame_hdr)
+  if (elf_eh_frame_hdr (abfd))
     {
       /* We need a PT_GNU_EH_FRAME segment.  */
       ++segs;
     }
 
-  if (elf_tdata (abfd)->stack_flags)
+  if (elf_stack_flags (abfd))
     {
       /* We need a PT_GNU_STACK segment.  */
       ++segs;
@@ -3473,8 +3646,7 @@ _bfd_elf_find_segment_containing_section (bfd * abfd, asection * section)
   struct elf_segment_map *m;
   Elf_Internal_Phdr *p;
 
-  for (m = elf_tdata (abfd)->segment_map,
-        p = elf_tdata (abfd)->phdr;
+  for (m = elf_seg_map (abfd), p = elf_tdata (abfd)->phdr;
        m != NULL;
        m = m->next, p++)
     {
@@ -3558,7 +3730,7 @@ elf_modify_segment_map (bfd *abfd,
      sections from the segment map.  We also remove excluded
      sections.  Finally, any PT_LOAD segment without sections is
      removed.  */
-  m = &elf_tdata (abfd)->segment_map;
+  m = &elf_seg_map (abfd);
   while (*m)
     {
       unsigned int i, new_count;
@@ -3602,7 +3774,11 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   bfd_boolean no_user_phdrs;
 
-  no_user_phdrs = elf_tdata (abfd)->segment_map == NULL;
+  no_user_phdrs = elf_seg_map (abfd) == NULL;
+
+  if (info != NULL)
+    info->user_phdrs = !no_user_phdrs;
+
   if (no_user_phdrs && bfd_count_sections (abfd) != 0)
     {
       asection *s;
@@ -3620,6 +3796,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
       asection *first_tls = NULL;
       asection *dynsec, *eh_frame_hdr;
       bfd_size_type amt;
+      bfd_vma addr_mask, wrap_to = 0;
 
       /* Select the allocated sections, and sort them.  */
 
@@ -3628,6 +3805,12 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
       if (sections == NULL)
        goto error_return;
 
+      /* Calculate top address, avoiding undefined behaviour of shift
+        left operator when shift count is equal to size of type
+        being shifted.  */
+      addr_mask = ((bfd_vma) 1 << (bfd_arch_bits_per_address (abfd) - 1)) - 1;
+      addr_mask = (addr_mask << 1) + 1;
+
       i = 0;
       for (s = abfd->sections; s != NULL; s = s->next)
        {
@@ -3635,6 +3818,9 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
            {
              sections[i] = s;
              ++i;
+             /* A wrapping section potentially clashes with header.  */
+             if (((s->lma + s->size) & addr_mask) < (s->lma & addr_mask))
+               wrap_to = (s->lma + s->size) & addr_mask;
            }
        }
       BFD_ASSERT (i <= bfd_count_sections (abfd));
@@ -3699,13 +3885,16 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
         program headers we will need.  */
       if (count > 0)
        {
-         bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size;
+         bfd_size_type phdr_size = elf_program_header_size (abfd);
 
          if (phdr_size == (bfd_size_type) -1)
            phdr_size = get_program_header_size (abfd, info);
+         phdr_size += bed->s->sizeof_ehdr;
          if ((abfd->flags & D_PAGED) == 0
-             || sections[0]->lma < phdr_size
-             || sections[0]->lma % maxpagesize < phdr_size % maxpagesize)
+             || (sections[0]->lma & addr_mask) < phdr_size
+             || ((sections[0]->lma & addr_mask) % maxpagesize
+                 < phdr_size % maxpagesize)
+             || (sections[0]->lma & addr_mask & -maxpagesize) < wrap_to)
            phdr_in_segment = FALSE;
        }
 
@@ -3732,6 +3921,13 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
                 segment.  */
              new_segment = TRUE;
            }
+         else if (hdr->lma < last_hdr->lma + last_size
+                  || last_hdr->lma + last_size < last_hdr->lma)
+           {
+             /* If this section has a load address that makes it overlap
+                the previous section, then we need a new segment.  */
+             new_segment = TRUE;
+           }
          /* In the next test we have to be careful when last_hdr->lma is close
             to the end of the address space.  If the aligned address wraps
             around to the start of the address space, then there are no more
@@ -3763,9 +3959,8 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
            }
          else if (! writable
                   && (hdr->flags & SEC_READONLY) == 0
-                  && (((last_hdr->lma + last_size - 1)
-                       & ~(maxpagesize - 1))
-                      != (hdr->lma & ~(maxpagesize - 1))))
+                  && (((last_hdr->lma + last_size - 1) & -maxpagesize)
+                      != (hdr->lma & -maxpagesize)))
            {
              /* We don't want to put a writable section in a read only
                 segment, unless they are on the same page in memory
@@ -3830,8 +4025,12 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
          phdr_in_segment = FALSE;
        }
 
-      /* Create a final PT_LOAD program segment.  */
-      if (last_hdr != NULL)
+      /* Create a final PT_LOAD program segment, but not if it's just
+        for .tbss.  */
+      if (last_hdr != NULL
+         && (i - phdr_index != 1
+             || ((last_hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD))
+                 != SEC_THREAD_LOCAL)))
        {
          m = make_mapping (abfd, sections, phdr_index, i, phdr_in_segment);
          if (m == NULL)
@@ -3872,8 +4071,8 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
                    if (s2->next->alignment_power == 2
                        && (s2->next->flags & SEC_LOAD) != 0
                        && CONST_STRNEQ (s2->next->name, ".note")
-                       && align_power (s2->vma + s2->size, 2)
-                          == s2->next->vma)
+                       && align_power (s2->lma + s2->size, 2)
+                          == s2->next->lma)
                      count++;
                    else
                      break;
@@ -3918,11 +4117,31 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
          /* Mandated PF_R.  */
          m->p_flags = PF_R;
          m->p_flags_valid = 1;
+         s = first_tls;
          for (i = 0; i < (unsigned int) tls_count; ++i)
            {
-             BFD_ASSERT (first_tls->flags & SEC_THREAD_LOCAL);
-             m->sections[i] = first_tls;
-             first_tls = first_tls->next;
+             if ((s->flags & SEC_THREAD_LOCAL) == 0)
+               {
+                 _bfd_error_handler
+                   (_("%B: TLS sections are not adjacent:"), abfd);
+                 s = first_tls;
+                 i = 0;
+                 while (i < (unsigned int) tls_count)
+                   {
+                     if ((s->flags & SEC_THREAD_LOCAL) != 0)
+                       {
+                         _bfd_error_handler (_("           TLS: %A"), s);
+                         i++;
+                       }
+                     else
+                       _bfd_error_handler (_(" non-TLS: %A"), s);
+                     s = s->next;
+                   }
+                 bfd_set_error (bfd_error_bad_value);
+                 goto error_return;
+               }
+             m->sections[i] = s;
+             s = s->next;
            }
 
          *pm = m;
@@ -3931,7 +4150,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
 
       /* If there is a .eh_frame_hdr section, throw in a PT_GNU_EH_FRAME
         segment.  */
-      eh_frame_hdr = elf_tdata (abfd)->eh_frame_hdr;
+      eh_frame_hdr = elf_eh_frame_hdr (abfd);
       if (eh_frame_hdr != NULL
          && (eh_frame_hdr->output_section->flags & SEC_LOAD) != 0)
        {
@@ -3948,7 +4167,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
          pm = &m->next;
        }
 
-      if (elf_tdata (abfd)->stack_flags)
+      if (elf_stack_flags (abfd))
        {
          amt = sizeof (struct elf_segment_map);
          m = (struct elf_segment_map *) bfd_zalloc (abfd, amt);
@@ -3956,8 +4175,15 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
            goto error_return;
          m->next = NULL;
          m->p_type = PT_GNU_STACK;
-         m->p_flags = elf_tdata (abfd)->stack_flags;
+         m->p_flags = elf_stack_flags (abfd);
+         m->p_align = bed->stack_align;
          m->p_flags_valid = 1;
+         m->p_align_valid = m->p_align != 0;
+         if (info->stacksize > 0)
+           {
+             m->p_size = info->stacksize;
+             m->p_size_valid = 1;
+           }
 
          *pm = m;
          pm = &m->next;
@@ -3967,18 +4193,21 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
        {
          for (m = mfirst; m != NULL; m = m->next)
            {
-             if (m->p_type == PT_LOAD)
+             if (m->p_type == PT_LOAD
+                 && m->count != 0
+                 && m->sections[0]->vma >= info->relro_start
+                 && m->sections[0]->vma < info->relro_end)
                {
-                 asection *last = m->sections[m->count - 1];
-                 bfd_vma vaddr = m->sections[0]->vma;
-                 bfd_vma filesz = last->vma - vaddr + last->size;
+                 i = m->count;
+                 while (--i != (unsigned) -1)
+                   if ((m->sections[i]->flags & (SEC_LOAD | SEC_HAS_CONTENTS))
+                       == (SEC_LOAD | SEC_HAS_CONTENTS))
+                     break;
 
-                 if (vaddr < info->relro_end
-                     && vaddr >= info->relro_start
-                     && (vaddr + filesz) >= info->relro_end)
+                 if (i != (unsigned) -1)
                    break;
                }
-             }
+           }
 
          /* Make a PT_GNU_RELRO segment only when it isn't empty.  */
          if (m != NULL)
@@ -3998,15 +4227,15 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
        }
 
       free (sections);
-      elf_tdata (abfd)->segment_map = mfirst;
+      elf_seg_map (abfd) = mfirst;
     }
 
   if (!elf_modify_segment_map (abfd, info, no_user_phdrs))
     return FALSE;
 
-  for (count = 0, m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
+  for (count = 0, m = elf_seg_map (abfd); m != NULL; m = m->next)
     ++count;
-  elf_tdata (abfd)->program_header_size = count * bed->s->sizeof_phdr;
+  elf_program_header_size (abfd) = count * bed->s->sizeof_phdr;
 
   return TRUE;
 
@@ -4100,6 +4329,9 @@ elf_sort_sections (const void *arg1, const void *arg2)
 static file_ptr
 vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize)
 {
+  /* PR binutils/16199: Handle an alignment of zero.  */
+  if (maxpagesize == 0)
+    maxpagesize = 1;
   return ((vma - off) % maxpagesize);
 }
 
@@ -4123,10 +4355,12 @@ print_segment_map (const struct elf_segment_map *m)
                  (unsigned int) m->p_type);
       pt = buf;
     }
+  fflush (stdout);
   fprintf (stderr, "%s:", pt);
   for (j = 0; j < m->count; j++)
     fprintf (stderr, " %s", m->sections [j]->name);
   putc ('\n',stderr);
+  fflush (stderr);
 }
 
 static bfd_boolean
@@ -4168,43 +4402,53 @@ assign_file_positions_for_load_sections (bfd *abfd,
     return FALSE;
 
   alloc = 0;
-  for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
+  for (m = elf_seg_map (abfd); m != NULL; m = m->next)
     {
       ++alloc;
       if (m->header_size)
        header_pad = m->header_size;
     }
 
-  elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr;
-  elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr;
+  if (alloc)
+    {
+      elf_elfheader (abfd)->e_phoff = bed->s->sizeof_ehdr;
+      elf_elfheader (abfd)->e_phentsize = bed->s->sizeof_phdr;
+    }
+  else
+    {
+      /* PR binutils/12467.  */
+      elf_elfheader (abfd)->e_phoff = 0;
+      elf_elfheader (abfd)->e_phentsize = 0;
+    }
+
   elf_elfheader (abfd)->e_phnum = alloc;
 
-  if (elf_tdata (abfd)->program_header_size == (bfd_size_type) -1)
-    elf_tdata (abfd)->program_header_size = alloc * bed->s->sizeof_phdr;
+  if (elf_program_header_size (abfd) == (bfd_size_type) -1)
+    elf_program_header_size (abfd) = alloc * bed->s->sizeof_phdr;
   else
-    BFD_ASSERT (elf_tdata (abfd)->program_header_size
+    BFD_ASSERT (elf_program_header_size (abfd)
                >= alloc * bed->s->sizeof_phdr);
 
   if (alloc == 0)
     {
-      elf_tdata (abfd)->next_file_pos = bed->s->sizeof_ehdr;
+      elf_next_file_pos (abfd) = bed->s->sizeof_ehdr;
       return TRUE;
     }
 
-  /* We're writing the size in elf_tdata (abfd)->program_header_size,
+  /* We're writing the size in elf_program_header_size (abfd),
      see assign_file_positions_except_relocs, so make sure we have
      that amount allocated, with trailing space cleared.
-     The variable alloc contains the computed need, while elf_tdata
-     (abfd)->program_header_size contains the size used for the
+     The variable alloc contains the computed need, while
+     elf_program_header_size (abfd) contains the size used for the
      layout.
      See ld/emultempl/elf-generic.em:gld${EMULATION_NAME}_map_segments
      where the layout is forced to according to a larger size in the
      last iterations for the testcase ld-elf/header.  */
-  BFD_ASSERT (elf_tdata (abfd)->program_header_size % bed->s->sizeof_phdr
+  BFD_ASSERT (elf_program_header_size (abfd) % bed->s->sizeof_phdr
              == 0);
   phdrs = (Elf_Internal_Phdr *)
      bfd_zalloc2 (abfd,
-                  (elf_tdata (abfd)->program_header_size / bed->s->sizeof_phdr),
+                  (elf_program_header_size (abfd) / bed->s->sizeof_phdr),
                   sizeof (Elf_Internal_Phdr));
   elf_tdata (abfd)->phdr = phdrs;
   if (phdrs == NULL)
@@ -4222,7 +4466,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
     header_pad -= off;
   off += header_pad;
 
-  for (m = elf_tdata (abfd)->segment_map, p = phdrs, j = 0;
+  for (m = elf_seg_map (abfd), p = phdrs, j = 0;
        m != NULL;
        m = m->next, p++, j++)
     {
@@ -4326,7 +4570,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
                break;
              }
 
-         off_adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align);
+         off_adjust = vma_page_aligned_bias (p->p_vaddr, off, align);
          off += off_adjust;
          if (no_contents)
            {
@@ -4371,8 +4615,6 @@ assign_file_positions_for_load_sections (bfd *abfd,
          p->p_memsz = bed->s->sizeof_ehdr;
          if (m->count > 0)
            {
-             BFD_ASSERT (p->p_type == PT_LOAD);
-
              if (p->p_vaddr < (bfd_vma) off)
                {
                  (*_bfd_error_handler)
@@ -4399,7 +4641,6 @@ assign_file_positions_for_load_sections (bfd *abfd,
 
              if (m->count > 0)
                {
-                 BFD_ASSERT (p->p_type == PT_LOAD);
                  p->p_vaddr -= off - p->p_offset;
                  if (!m->p_paddr_valid)
                    p->p_paddr -= off - p->p_offset;
@@ -4453,15 +4694,20 @@ assign_file_positions_for_load_sections (bfd *abfd,
                      && ((this_hdr->sh_flags & SHF_TLS) == 0
                          || p->p_type == PT_TLS))))
            {
-             bfd_vma adjust = sec->lma - (p->p_paddr + p->p_memsz);
-
-             if (sec->lma < p->p_paddr + p->p_memsz)
+             bfd_vma p_start = p->p_paddr;
+             bfd_vma p_end = p_start + p->p_memsz;
+             bfd_vma s_start = sec->lma;
+             bfd_vma adjust = s_start - p_end;
+
+             if (adjust != 0
+                 && (s_start < p_end
+                     || p_end < p_start))
                {
                  (*_bfd_error_handler)
-                   (_("%B: section %A lma 0x%lx overlaps previous sections"),
-                    abfd, sec, (unsigned long) sec->lma);
+                   (_("%B: section %A lma %#lx adjusted to %#lx"), abfd, sec,
+                    (unsigned long) s_start, (unsigned long) p_end);
                  adjust = 0;
-                 sec->lma = p->p_paddr + p->p_memsz;
+                 sec->lma = p_end;
                }
              p->p_memsz += adjust;
 
@@ -4510,6 +4756,21 @@ assign_file_positions_for_load_sections (bfd *abfd,
                  if (this_hdr->sh_type != SHT_NOBITS)
                    off += this_hdr->sh_size;
                }
+             else if (this_hdr->sh_type == SHT_NOBITS
+                      && (this_hdr->sh_flags & SHF_TLS) != 0
+                      && this_hdr->sh_offset == 0)
+               {
+                 /* This is a .tbss section that didn't get a PT_LOAD.
+                    (See _bfd_elf_map_sections_to_segments "Create a
+                    final PT_LOAD".)  Set sh_offset to the value it
+                    would have if we had created a zero p_filesz and
+                    p_memsz PT_LOAD header for the section.  This
+                    also makes the PT_TLS header have the same
+                    p_offset value.  */
+                 bfd_vma adjust = vma_page_aligned_bias (this_hdr->sh_addr,
+                                                         off, align);
+                 this_hdr->sh_offset = sec->filepos = off + adjust;
+               }
 
              if (this_hdr->sh_type != SHT_NOBITS)
                {
@@ -4547,6 +4808,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
                p->p_flags |= PF_W;
            }
        }
+
       off -= off_adjust;
 
       /* Check that all sections are in a PT_LOAD segment.
@@ -4574,8 +4836,8 @@ assign_file_positions_for_load_sections (bfd *abfd,
 
              sec = m->sections[i];
              this_hdr = &(elf_section_data(sec)->this_hdr);
-             if (this_hdr->sh_size != 0
-                 && !ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma))
+             if (!ELF_SECTION_IN_SEGMENT_1 (this_hdr, p, check_vma, 0)
+                 && !ELF_TBSS_SPECIAL (this_hdr, p))
                {
                  (*_bfd_error_handler)
                    (_("%B: section `%A' can't be allocated in segment %d"),
@@ -4586,7 +4848,7 @@ assign_file_positions_for_load_sections (bfd *abfd,
        }
     }
 
-  elf_tdata (abfd)->next_file_pos = off;
+  elf_next_file_pos (abfd) = off;
   return TRUE;
 }
 
@@ -4602,6 +4864,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
   Elf_Internal_Phdr *phdrs;
   Elf_Internal_Phdr *p;
   struct elf_segment_map *m;
+  struct elf_segment_map *hdrs_segment;
   bfd_vma filehdr_vaddr, filehdr_paddr;
   bfd_vma phdrs_vaddr, phdrs_paddr;
   file_ptr off;
@@ -4611,10 +4874,9 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
 
   i_shdrpp = elf_elfsections (abfd);
   num_sec = elf_numsections (abfd);
-  off = elf_tdata (abfd)->next_file_pos;
+  off = elf_next_file_pos (abfd);
   for (i = 1, hdrpp = i_shdrpp + 1; i < num_sec; i++, hdrpp++)
     {
-      struct elf_obj_tdata *tdata = elf_tdata (abfd);
       Elf_Internal_Shdr *hdr;
 
       hdr = *hdrpp;
@@ -4626,12 +4888,12 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
       else if ((hdr->sh_flags & SHF_ALLOC) != 0)
        {
          if (hdr->sh_size != 0)
-           ((*_bfd_error_handler)
-            (_("%B: warning: allocated section `%s' not in segment"),
-             abfd,
-             (hdr->bfd_section == NULL
-              ? "*unknown*"
-              : hdr->bfd_section->name)));
+           (*_bfd_error_handler)
+             (_("%B: warning: allocated section `%s' not in segment"),
+              abfd,
+              (hdr->bfd_section == NULL
+               ? "*unknown*"
+               : hdr->bfd_section->name));
          /* We don't need to page align empty sections.  */
          if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0)
            off += vma_page_aligned_bias (hdr->sh_addr, off,
@@ -4644,9 +4906,9 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
        }
       else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
                && hdr->bfd_section == NULL)
-              || hdr == i_shdrpp[tdata->symtab_section]
-              || hdr == i_shdrpp[tdata->symtab_shndx_section]
-              || hdr == i_shdrpp[tdata->strtab_section])
+              || hdr == i_shdrpp[elf_onesymtab (abfd)]
+              || hdr == i_shdrpp[elf_symtab_shndx (abfd)]
+              || hdr == i_shdrpp[elf_strtab_sec (abfd)])
        hdr->sh_offset = -1;
       else
        off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
@@ -4659,10 +4921,9 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
   filehdr_paddr = 0;
   phdrs_vaddr = bed->maxpagesize + bed->s->sizeof_ehdr;
   phdrs_paddr = 0;
+  hdrs_segment = NULL;
   phdrs = elf_tdata (abfd)->phdr;
-  for (m = elf_tdata (abfd)->segment_map, p = phdrs;
-       m != NULL;
-       m = m->next, p++)
+  for (m = elf_seg_map (abfd), p = phdrs; m != NULL; m = m->next, p++)
     {
       ++count;
       if (p->p_type != PT_LOAD)
@@ -4679,34 +4940,82 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
          phdrs_paddr = p->p_paddr;
          if (m->includes_filehdr)
            {
+             hdrs_segment = m;
              phdrs_vaddr += bed->s->sizeof_ehdr;
              phdrs_paddr += bed->s->sizeof_ehdr;
            }
        }
     }
 
-  for (m = elf_tdata (abfd)->segment_map, p = phdrs;
-       m != NULL;
-       m = m->next, p++)
+  if (hdrs_segment != NULL && link_info != NULL)
+    {
+      /* There is a segment that contains both the file headers and the
+        program headers, so provide a symbol __ehdr_start pointing there.
+        A program can use this to examine itself robustly.  */
+
+      struct elf_link_hash_entry *hash
+       = elf_link_hash_lookup (elf_hash_table (link_info), "__ehdr_start",
+                               FALSE, FALSE, TRUE);
+      /* If the symbol was referenced and not defined, define it.  */
+      if (hash != NULL
+         && (hash->root.type == bfd_link_hash_new
+             || hash->root.type == bfd_link_hash_undefined
+             || hash->root.type == bfd_link_hash_undefweak
+             || hash->root.type == bfd_link_hash_common))
+       {
+         asection *s = NULL;
+         if (hdrs_segment->count != 0)
+           /* The segment contains sections, so use the first one.  */
+           s = hdrs_segment->sections[0];
+         else
+           /* Use the first (i.e. lowest-addressed) section in any segment.  */
+           for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+             if (m->count != 0)
+               {
+                 s = m->sections[0];
+                 break;
+               }
+
+         if (s != NULL)
+           {
+             hash->root.u.def.value = filehdr_vaddr - s->vma;
+             hash->root.u.def.section = s;
+           }
+         else
+           {
+             hash->root.u.def.value = filehdr_vaddr;
+             hash->root.u.def.section = bfd_abs_section_ptr;
+           }
+
+         hash->root.type = bfd_link_hash_defined;
+         hash->def_regular = 1;
+         hash->non_elf = 0;
+       }
+    }
+
+  for (m = elf_seg_map (abfd), p = phdrs; m != NULL; m = m->next, p++)
     {
       if (p->p_type == PT_GNU_RELRO)
        {
          const Elf_Internal_Phdr *lp;
-
-         BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
+         struct elf_segment_map *lm;
 
          if (link_info != NULL)
            {
              /* During linking the range of the RELRO segment is passed
                 in link_info.  */
-             for (lp = phdrs; lp < phdrs + count; ++lp)
+             for (lm = elf_seg_map (abfd), lp = phdrs;
+                  lm != NULL;
+                  lm = lm->next, lp++)
                {
                  if (lp->p_type == PT_LOAD
-                     && lp->p_vaddr >= link_info->relro_start
                      && lp->p_vaddr < link_info->relro_end
-                     && lp->p_vaddr + lp->p_filesz >= link_info->relro_end)
+                     && lm->count != 0
+                     && lm->sections[0]->vma >= link_info->relro_start)
                    break;
                }
+
+             BFD_ASSERT (lm != NULL);
            }
          else
            {
@@ -4732,8 +5041,15 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
              else
                abort ();
              p->p_memsz = p->p_filesz;
-             p->p_align = 1;
-             p->p_flags = (lp->p_flags & ~PF_W);
+             /* Preserve the alignment and flags if they are valid. The
+                gold linker generates RW/4 for the PT_GNU_RELRO section.
+                It is better for objcopy/strip to honor these attributes
+                otherwise gdb will choke when using separate debug files.
+              */
+             if (!m->p_align_valid)
+               p->p_align = 1;
+             if (!m->p_flags_valid)
+               p->p_flags = (lp->p_flags & ~PF_W);
            }
          else
            {
@@ -4741,23 +5057,32 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
              p->p_type = PT_NULL;
            }
        }
+      else if (p->p_type == PT_GNU_STACK)
+       {
+         if (m->p_size_valid)
+           p->p_memsz = m->p_size;
+       }
       else if (m->count != 0)
        {
          if (p->p_type != PT_LOAD
              && (p->p_type != PT_NOTE
                  || bfd_get_format (abfd) != bfd_core))
            {
-             Elf_Internal_Shdr *hdr;
-             asection *sect;
-
              BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
 
-             sect = m->sections[m->count - 1];
-             hdr = &elf_section_data (sect)->this_hdr;
-             p->p_filesz = sect->filepos - m->sections[0]->filepos;
-             if (hdr->sh_type != SHT_NOBITS)
-               p->p_filesz += hdr->sh_size;
+             p->p_filesz = 0;
              p->p_offset = m->sections[0]->filepos;
+             for (i = m->count; i-- != 0;)
+               {
+                 asection *sect = m->sections[i];
+                 Elf_Internal_Shdr *hdr = &elf_section_data (sect)->this_hdr;
+                 if (hdr->sh_type != SHT_NOBITS)
+                   {
+                     p->p_filesz = (sect->filepos - m->sections[0]->filepos
+                                    + hdr->sh_size);
+                     break;
+                   }
+               }
            }
        }
       else if (m->includes_filehdr)
@@ -4774,7 +5099,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
        }
     }
 
-  elf_tdata (abfd)->next_file_pos = off;
+  elf_next_file_pos (abfd) = off;
 
   return TRUE;
 }
@@ -4799,7 +5124,6 @@ assign_file_positions_except_relocs (bfd *abfd,
 {
   struct elf_obj_tdata *tdata = elf_tdata (abfd);
   Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
-  file_ptr off;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
@@ -4809,6 +5133,7 @@ assign_file_positions_except_relocs (bfd *abfd,
       unsigned int num_sec = elf_numsections (abfd);
       Elf_Internal_Shdr **hdrpp;
       unsigned int i;
+      file_ptr off;
 
       /* Start after the ELF header.  */
       off = i_ehdrp->e_ehsize;
@@ -4823,15 +5148,17 @@ assign_file_positions_except_relocs (bfd *abfd,
          hdr = *hdrpp;
          if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
               && hdr->bfd_section == NULL)
-             || i == tdata->symtab_section
-             || i == tdata->symtab_shndx_section
-             || i == tdata->strtab_section)
+             || i == elf_onesymtab (abfd)
+             || i == elf_symtab_shndx (abfd)
+             || i == elf_strtab_sec (abfd))
            {
              hdr->sh_offset = -1;
            }
          else
            off = _bfd_elf_assign_file_position_for_section (hdr, off, TRUE);
        }
+
+      elf_next_file_pos (abfd) = off;
     }
   else
     {
@@ -4852,22 +5179,34 @@ assign_file_positions_except_relocs (bfd *abfd,
            return FALSE;
        }
 
+      /* Set e_type in ELF header to ET_EXEC for -pie -Ttext-segment=.  */
+      if (link_info != NULL
+         && link_info->executable
+         && link_info->shared)
+       {
+         unsigned int num_segments = elf_elfheader (abfd)->e_phnum;
+         Elf_Internal_Phdr *segment = elf_tdata (abfd)->phdr;
+         Elf_Internal_Phdr *end_segment = &segment[num_segments];
+
+         /* Find the lowest p_vaddr in PT_LOAD segments.  */
+         bfd_vma p_vaddr = (bfd_vma) -1;
+         for (; segment < end_segment; segment++)
+           if (segment->p_type == PT_LOAD && p_vaddr > segment->p_vaddr)
+             p_vaddr = segment->p_vaddr;
+
+         /* Set e_type to ET_EXEC if the lowest p_vaddr in PT_LOAD
+            segments is non-zero.  */
+         if (p_vaddr)
+           i_ehdrp->e_type = ET_EXEC;
+       }
+
       /* Write out the program headers.  */
-      alloc = tdata->program_header_size / bed->s->sizeof_phdr;
+      alloc = elf_program_header_size (abfd) / bed->s->sizeof_phdr;
       if (bfd_seek (abfd, (bfd_signed_vma) bed->s->sizeof_ehdr, SEEK_SET) != 0
          || bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0)
        return FALSE;
-
-      off = tdata->next_file_pos;
     }
 
-  /* Place the section headers.  */
-  off = align_file_position (off, 1 << bed->s->log_file_align);
-  i_ehdrp->e_shoff = off;
-  off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
-
-  tdata->next_file_pos = off;
-
   return TRUE;
 }
 
@@ -4952,7 +5291,7 @@ prep_headers (bfd *abfd)
   elf_tdata (abfd)->shstrtab_hdr.sh_name =
     (unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", FALSE);
   if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
-      || elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
+      || elf_tdata (abfd)->strtab_hdr.sh_name == (unsigned int) -1
       || elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1)
     return FALSE;
 
@@ -4960,16 +5299,18 @@ prep_headers (bfd *abfd)
 }
 
 /* Assign file positions for all the reloc sections which are not part
-   of the loadable file image.  */
+   of the loadable file image, and the file position of section headers.  */
 
-void
+static void
 _bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
 {
   file_ptr off;
   unsigned int i, num_sec;
   Elf_Internal_Shdr **shdrpp;
+  Elf_Internal_Ehdr *i_ehdrp;
+  const struct elf_backend_data *bed;
 
-  off = elf_tdata (abfd)->next_file_pos;
+  off = elf_next_file_pos (abfd);
 
   num_sec = elf_numsections (abfd);
   for (i = 1, shdrpp = elf_elfsections (abfd) + 1; i < num_sec; i++, shdrpp++)
@@ -4982,7 +5323,13 @@ _bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
        off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE);
     }
 
-  elf_tdata (abfd)->next_file_pos = off;
+/* Place the section headers.  */
+  i_ehdrp = elf_elfheader (abfd);
+  bed = get_elf_backend_data (abfd);
+  off = align_file_position (off, 1 << bed->s->log_file_align);
+  i_ehdrp->e_shoff = off;
+  off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
+  elf_next_file_pos (abfd) = off;
 }
 
 bfd_boolean
@@ -4992,6 +5339,7 @@ _bfd_elf_write_object_contents (bfd *abfd)
   Elf_Internal_Shdr **i_shdrp;
   bfd_boolean failed;
   unsigned int count, num_sec;
+  struct elf_obj_tdata *t;
 
   if (! abfd->output_has_begun
       && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
@@ -5023,21 +5371,21 @@ _bfd_elf_write_object_contents (bfd *abfd)
     }
 
   /* Write out the section header names.  */
+  t = elf_tdata (abfd);
   if (elf_shstrtab (abfd) != NULL
-      && (bfd_seek (abfd, elf_tdata (abfd)->shstrtab_hdr.sh_offset, SEEK_SET) != 0
+      && (bfd_seek (abfd, t->shstrtab_hdr.sh_offset, SEEK_SET) != 0
          || !_bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd))))
     return FALSE;
 
   if (bed->elf_backend_final_write_processing)
-    (*bed->elf_backend_final_write_processing) (abfd,
-                                               elf_tdata (abfd)->linker);
+    (*bed->elf_backend_final_write_processing) (abfd, elf_linker (abfd));
 
   if (!bed->s->write_shdrs_and_ehdr (abfd))
     return FALSE;
 
   /* This is last since write_shdrs_and_ehdr can touch i_shdrp[0].  */
-  if (elf_tdata (abfd)->after_write_object_contents)
-    return (*elf_tdata (abfd)->after_write_object_contents) (abfd);
+  if (t->o->build_id.after_write_object_contents != NULL)
+    return (*t->o->build_id.after_write_object_contents) (abfd);
 
   return TRUE;
 }
@@ -5132,9 +5480,8 @@ _bfd_elf_symbol_from_bfd_symbol (bfd *abfd, asymbol **asym_ptr_ptr)
 #if DEBUG & 4
   {
     fprintf (stderr,
-            "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx%s\n",
-            (long) asym_ptr, asym_ptr->name, idx, flags,
-            elf_symbol_flags (flags));
+            "elf_symbol_from_bfd_symbol 0x%.8lx, name = %s, sym num = %d, flags = 0x%.8lx\n",
+            (long) asym_ptr, asym_ptr->name, idx, (long) flags);
     fflush (stderr);
   }
 #endif
@@ -5230,7 +5577,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
        1. It is within the address space of the segment -- we use the LMA
          if that is set for the segment and the VMA otherwise,
        2. It is an allocated section or a NOTE section in a PT_NOTE
-         segment.         
+         segment.
        3. There is an output section associated with it,
        4. The section has not already been allocated to a previous segment.
        5. PT_GNU_STACK segments do not include any sections.
@@ -5747,7 +6094,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
                 and carry on looping.  */
              amt = sizeof (struct elf_segment_map);
              amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
-             map = (struct elf_segment_map *) bfd_alloc (obfd, amt);
+             map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
              if (map == NULL)
                {
                  free (sections);
@@ -5772,7 +6119,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
       free (sections);
     }
 
-  elf_tdata (obfd)->segment_map = map_first;
+  elf_seg_map (obfd) = map_first;
 
   /* If we had to estimate the number of program headers that were
      going to be needed, then check our estimate now and adjust
@@ -5845,7 +6192,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
       bfd_size_type amt;
       Elf_Internal_Shdr *this_hdr;
       asection *first_section = NULL;
-      asection *lowest_section = NULL;
+      asection *lowest_section;
 
       /* Compute how many sections are in this segment.  */
       for (section = ibfd->sections, section_count = 0;
@@ -5853,13 +6200,10 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
           section = section->next)
        {
          this_hdr = &(elf_section_data(section)->this_hdr);
-         if (this_hdr->sh_size != 0
-             && ELF_SECTION_IN_SEGMENT (this_hdr, segment))
+         if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
            {
-             if (!first_section)
-               first_section = lowest_section = section;
-             if (section->lma < lowest_section->lma)
-               lowest_section = section;
+             if (first_section == NULL)
+               first_section = section;
              section_count++;
            }
        }
@@ -5885,12 +6229,15 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
       map->p_align_valid = 1;
       map->p_vaddr_offset = 0;
 
-      if (map->p_type == PT_GNU_RELRO)
+      if (map->p_type == PT_GNU_RELRO
+         || map->p_type == PT_GNU_STACK)
        {
          /* The PT_GNU_RELRO segment may contain the first a few
             bytes in the .got.plt section even if the whole .got.plt
             section isn't in the PT_GNU_RELRO segment.  We won't
-            change the size of the PT_GNU_RELRO segment.  */
+            change the size of the PT_GNU_RELRO segment.
+            Similarly, PT_GNU_STACK size is significant on uclinux
+            systems.    */
          map->p_size = segment->p_memsz;
          map->p_size_valid = 1;
        }
@@ -5913,17 +6260,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
            phdr_included = TRUE;
        }
 
-      if (map->includes_filehdr && first_section)
-       /* We need to keep the space used by the headers fixed.  */
-       map->header_size = first_section->vma - segment->p_vaddr;
-      
-      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);
-
+      lowest_section = NULL;
       if (section_count != 0)
        {
          unsigned int isec = 0;
@@ -5933,22 +6270,52 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
               section = section->next)
            {
              this_hdr = &(elf_section_data(section)->this_hdr);
-             if (this_hdr->sh_size != 0
-                 && ELF_SECTION_IN_SEGMENT (this_hdr, segment))
+             if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
                {
                  map->sections[isec++] = section->output_section;
+                 if ((section->flags & SEC_ALLOC) != 0)
+                   {
+                     bfd_vma seg_off;
+
+                     if (lowest_section == NULL
+                         || section->lma < lowest_section->lma)
+                       lowest_section = section;
+
+                     /* Section lmas are set up from PT_LOAD header
+                        p_paddr in _bfd_elf_make_section_from_shdr.
+                        If this header has a p_paddr that disagrees
+                        with the section lma, flag the p_paddr as
+                        invalid.  */
+                     if ((section->flags & SEC_LOAD) != 0)
+                       seg_off = this_hdr->sh_offset - segment->p_offset;
+                     else
+                       seg_off = this_hdr->sh_addr - segment->p_vaddr;
+                     if (section->lma - segment->p_paddr != seg_off)
+                       map->p_paddr_valid = FALSE;
+                   }
                  if (isec == section_count)
                    break;
                }
            }
        }
 
+      if (map->includes_filehdr && lowest_section != NULL)
+       /* We need to keep the space used by the headers fixed.  */
+       map->header_size = lowest_section->vma - segment->p_vaddr;
+
+      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);
+
       map->count = section_count;
       *pointer_to_map = map;
       pointer_to_map = &map->next;
     }
 
-  elf_tdata (obfd)->segment_map = map_first;
+  elf_seg_map (obfd) = map_first;
   return TRUE;
 }
 
@@ -6011,8 +6378,7 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 
              /* Check if this section is covered by the segment.  */
              this_hdr = &(elf_section_data(section)->this_hdr);
-             if (this_hdr->sh_size != 0
-                 && ELF_SECTION_IN_SEGMENT (this_hdr, segment))
+             if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
                {
                  /* FIXME: Check if its output section is changed or
                     removed.  What else do we need to check?  */
@@ -6043,6 +6409,26 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
     }
 
 rewrite:
+  if (ibfd->xvec == obfd->xvec)
+    {
+      /* When rewriting program header, set the output maxpagesize to
+        the maximum alignment of input PT_LOAD segments.  */
+      Elf_Internal_Phdr *segment;
+      unsigned int i;
+      unsigned int num_segments = elf_elfheader (ibfd)->e_phnum;
+      bfd_vma maxpagesize = 0;
+
+      for (i = 0, segment = elf_tdata (ibfd)->phdr;
+          i < num_segments;
+          i++, segment++)
+       if (segment->p_type == PT_LOAD
+           && maxpagesize < segment->p_align)
+         maxpagesize = segment->p_align;
+
+      if (maxpagesize != get_elf_backend_data (obfd)->maxpagesize)
+       bfd_emul_set_maxpagesize (bfd_get_target (obfd), maxpagesize);
+    }
+
   return rewrite_elf_program_header (ibfd, obfd);
 }
 
@@ -6063,6 +6449,8 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
       || obfd->xvec->flavour != bfd_target_elf_flavour)
     return TRUE;
 
+  BFD_ASSERT (elf_section_data (osec) != NULL);
+
   /* For objcopy and relocatable link, don't copy the output ELF
      section type from input if the output BFD section flags have been
      set to something different.  For a final link allow some flags
@@ -6071,7 +6459,7 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
       && (osec->flags == isec->flags
          || (final_link
              && ((osec->flags ^ isec->flags)
-                 & ~ (SEC_LINK_ONCE | SEC_LINK_DUPLICATES)) == 0)))
+                 & ~(SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_RELOC)) == 0)))
     elf_section_type (osec) = elf_section_type (isec);
 
   /* FIXME: Is this correct for all OS/PROC specific flags?  */
@@ -6218,7 +6606,7 @@ _bfd_elf_copy_private_header_data (bfd *ibfd, bfd *obfd)
      entry point, because the latter is called after the section
      contents have been set, which means that the program headers have
      already been worked out.  */
-  if (elf_tdata (obfd)->segment_map == NULL && elf_tdata (ibfd)->phdr != NULL)
+  if (elf_seg_map (obfd) == NULL && elf_tdata (ibfd)->phdr != NULL)
     {
       if (! copy_private_bfd_data (ibfd, obfd))
        return FALSE;
@@ -6266,11 +6654,11 @@ _bfd_elf_copy_private_symbol_data (bfd *ibfd,
        shndx = MAP_ONESYMTAB;
       else if (shndx == elf_dynsymtab (ibfd))
        shndx = MAP_DYNSYMTAB;
-      else if (shndx == elf_tdata (ibfd)->strtab_section)
+      else if (shndx == elf_strtab_sec (ibfd))
        shndx = MAP_STRTAB;
-      else if (shndx == elf_tdata (ibfd)->shstrtab_section)
+      else if (shndx == elf_shstrtab_sec (ibfd))
        shndx = MAP_SHSTRTAB;
-      else if (shndx == elf_tdata (ibfd)->symtab_shndx_section)
+      else if (shndx == elf_symtab_shndx (ibfd))
        shndx = MAP_SYM_SHNDX;
       osym->internal_elf_sym.st_shndx = shndx;
     }
@@ -6295,10 +6683,11 @@ swap_out_syms (bfd *abfd,
   bfd_byte *outbound_syms;
   bfd_byte *outbound_shndx;
   int idx;
+  unsigned int num_locals;
   bfd_size_type amt;
   bfd_boolean name_local_sections;
 
-  if (!elf_map_symbols (abfd))
+  if (!elf_map_symbols (abfd, &num_locals))
     return FALSE;
 
   /* Dump out the symtabs.  */
@@ -6312,7 +6701,7 @@ swap_out_syms (bfd *abfd,
   symtab_hdr->sh_type = SHT_SYMTAB;
   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_info = num_locals + 1;
   symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
 
   symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr;
@@ -6357,6 +6746,7 @@ swap_out_syms (bfd *abfd,
     sym.st_info = 0;
     sym.st_other = 0;
     sym.st_shndx = SHN_UNDEF;
+    sym.st_target_internal = 0;
     bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
     outbound_syms += bed->s->sizeof_sym;
     if (outbound_shndx != NULL)
@@ -6445,15 +6835,16 @@ swap_out_syms (bfd *abfd,
                  shndx = elf_dynsymtab (abfd);
                  break;
                case MAP_STRTAB:
-                 shndx = elf_tdata (abfd)->strtab_section;
+                 shndx = elf_strtab_sec (abfd);
                  break;
                case MAP_SHSTRTAB:
-                 shndx = elf_tdata (abfd)->shstrtab_section;
+                 shndx = elf_shstrtab_sec (abfd);
                  break;
                case MAP_SYM_SHNDX:
-                 shndx = elf_tdata (abfd)->symtab_shndx_section;
+                 shndx = elf_symtab_shndx (abfd);
                  break;
                default:
+                 shndx = SHN_ABS;
                  break;
                }
            }
@@ -6556,9 +6947,16 @@ Unable to find equivalent output section for symbol '%s' from section '%s'"),
        }
 
       if (type_ptr != NULL)
-       sym.st_other = type_ptr->internal_elf_sym.st_other;
+       {
+         sym.st_other = type_ptr->internal_elf_sym.st_other;
+         sym.st_target_internal
+           = type_ptr->internal_elf_sym.st_target_internal;
+       }
       else
-       sym.st_other = 0;
+       {
+         sym.st_other = 0;
+         sym.st_target_internal = 0;
+       }
 
       bed->s->swap_symbol_out (abfd, &sym, outbound_syms, outbound_shndx);
       outbound_syms += bed->s->sizeof_sym;
@@ -7039,7 +7437,7 @@ error_return_verdef:
       Elf_Internal_Verdef *iverdef;
       Elf_Internal_Verdaux *iverdaux;
 
-      iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];;
+      iverdef = &elf_tdata (abfd)->verdef[freeidx - 1];
 
       iverdef->vd_version = VER_DEF_CURRENT;
       iverdef->vd_flags = 0;
@@ -7151,77 +7549,100 @@ _bfd_elf_set_arch_mach (bfd *abfd,
 
 static bfd_boolean
 elf_find_function (bfd *abfd,
-                  asection *section,
                   asymbol **symbols,
+                  asection *section,
                   bfd_vma offset,
                   const char **filename_ptr,
                   const char **functionname_ptr)
 {
-  const char *filename;
-  asymbol *func, *file;
-  bfd_vma low_func;
-  asymbol **p;
-  /* ??? Given multiple file symbols, it is impossible to reliably
-     choose the right file name for global symbols.  File symbols are
-     local symbols, and thus all file symbols must sort before any
-     global symbols.  The ELF spec may be interpreted to say that a
-     file symbol must sort before other local symbols, but currently
-     ld -r doesn't do this.  So, for ld -r output, it is possible to
-     make a better choice of file name for local symbols by ignoring
-     file symbols appearing after a given local symbol.  */
-  enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
-  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  struct elf_find_function_cache
+  {
+    asection *last_section;
+    asymbol *func;
+    const char *filename;
+    bfd_size_type func_size;
+  } *cache;
 
-  filename = NULL;
-  func = NULL;
-  file = NULL;
-  low_func = 0;
-  state = nothing_seen;
+  if (symbols == NULL)
+    return FALSE;
 
-  for (p = symbols; *p != NULL; p++)
+  cache = elf_tdata (abfd)->elf_find_function_cache;
+  if (cache == NULL)
     {
-      elf_symbol_type *q;
-      unsigned int type;
+      cache = bfd_zalloc (abfd, sizeof (*cache));
+      elf_tdata (abfd)->elf_find_function_cache = cache;
+      if (cache == NULL)
+       return FALSE;
+    }
+  if (cache->last_section != section
+      || cache->func == NULL
+      || offset < cache->func->value
+      || offset >= cache->func->value + cache->func_size)
+    {
+      asymbol *file;
+      bfd_vma low_func;
+      asymbol **p;
+      /* ??? Given multiple file symbols, it is impossible to reliably
+        choose the right file name for global symbols.  File symbols are
+        local symbols, and thus all file symbols must sort before any
+        global symbols.  The ELF spec may be interpreted to say that a
+        file symbol must sort before other local symbols, but currently
+        ld -r doesn't do this.  So, for ld -r output, it is possible to
+        make a better choice of file name for local symbols by ignoring
+        file symbols appearing after a given local symbol.  */
+      enum { nothing_seen, symbol_seen, file_after_symbol_seen } state;
+      const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+
+      file = NULL;
+      low_func = 0;
+      state = nothing_seen;
+      cache->filename = NULL;
+      cache->func = NULL;
+      cache->func_size = 0;
+      cache->last_section = section;
+
+      for (p = symbols; *p != NULL; p++)
+       {
+         asymbol *sym = *p;
+         bfd_vma code_off;
+         bfd_size_type size;
 
-      q = (elf_symbol_type *) *p;
+         if ((sym->flags & BSF_FILE) != 0)
+           {
+             file = sym;
+             if (state == symbol_seen)
+               state = file_after_symbol_seen;
+             continue;
+           }
 
-      type = ELF_ST_TYPE (q->internal_elf_sym.st_info);
-      switch (type)
-       {
-       case STT_FILE:
-         file = &q->symbol;
-         if (state == symbol_seen)
-           state = file_after_symbol_seen;
-         continue;
-       default:
-         if (!bed->is_function_type (type))
-           break;
-       case STT_NOTYPE:
-         if (bfd_get_section (&q->symbol) == section
-             && q->symbol.value >= low_func
-             && q->symbol.value <= offset)
+         size = bed->maybe_function_sym (sym, section, &code_off);
+         if (size != 0
+             && code_off <= offset
+             && (code_off > low_func
+                 || (code_off == low_func
+                     && size > cache->func_size)))
            {
-             func = (asymbol *) q;
-             low_func = q->symbol.value;
-             filename = NULL;
+             cache->func = sym;
+             cache->func_size = size;
+             cache->filename = NULL;
+             low_func = code_off;
              if (file != NULL
-                 && (ELF_ST_BIND (q->internal_elf_sym.st_info) == STB_LOCAL
+                 && ((sym->flags & BSF_LOCAL) != 0
                      || state != file_after_symbol_seen))
-               filename = bfd_asymbol_name (file);
+               cache->filename = bfd_asymbol_name (file);
            }
-         break;
+         if (state == nothing_seen)
+           state = symbol_seen;
        }
-      if (state == nothing_seen)
-       state = symbol_seen;
     }
 
-  if (func == NULL)
+  if (cache->func == NULL)
     return FALSE;
 
   if (filename_ptr)
-    *filename_ptr = filename;
+    *filename_ptr = cache->filename;
   if (functionname_ptr)
-    *functionname_ptr = bfd_asymbol_name (func);
+    *functionname_ptr = bfd_asymbol_name (cache->func);
 
   return TRUE;
 }
@@ -7231,34 +7652,35 @@ elf_find_function (bfd *abfd,
 
 bfd_boolean
 _bfd_elf_find_nearest_line (bfd *abfd,
-                           asection *section,
                            asymbol **symbols,
+                           asection *section,
                            bfd_vma offset,
                            const char **filename_ptr,
                            const char **functionname_ptr,
-                           unsigned int *line_ptr)
+                           unsigned int *line_ptr,
+                           unsigned int *discriminator_ptr)
 {
   bfd_boolean found;
 
-  if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset,
+  if (_bfd_dwarf2_find_nearest_line (abfd, symbols, NULL, section, offset,
                                     filename_ptr, functionname_ptr,
-                                    line_ptr))
+                                    line_ptr, discriminator_ptr,
+                                    dwarf_debug_sections, 0,
+                                    &elf_tdata (abfd)->dwarf2_find_line_info))
     {
       if (!*functionname_ptr)
-       elf_find_function (abfd, section, symbols, offset,
+       elf_find_function (abfd, symbols, section, offset,
                           *filename_ptr ? NULL : filename_ptr,
                           functionname_ptr);
 
       return TRUE;
     }
 
-  if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
-                                    filename_ptr, functionname_ptr,
-                                    line_ptr, 0,
-                                    &elf_tdata (abfd)->dwarf2_find_line_info))
+  if (_bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
+                                    filename_ptr, functionname_ptr, line_ptr))
     {
       if (!*functionname_ptr)
-       elf_find_function (abfd, section, symbols, offset,
+       elf_find_function (abfd, symbols, section, offset,
                           *filename_ptr ? NULL : filename_ptr,
                           functionname_ptr);
 
@@ -7276,7 +7698,7 @@ _bfd_elf_find_nearest_line (bfd *abfd,
   if (symbols == NULL)
     return FALSE;
 
-  if (! elf_find_function (abfd, section, symbols, offset,
+  if (! elf_find_function (abfd, symbols, section, offset,
                           filename_ptr, functionname_ptr))
     return FALSE;
 
@@ -7290,9 +7712,10 @@ bfd_boolean
 _bfd_elf_find_line (bfd *abfd, asymbol **symbols, asymbol *symbol,
                    const char **filename_ptr, unsigned int *line_ptr)
 {
-  return _bfd_dwarf2_find_line (abfd, symbols, symbol,
-                               filename_ptr, line_ptr, 0,
-                               &elf_tdata (abfd)->dwarf2_find_line_info);
+  return _bfd_dwarf2_find_nearest_line (abfd, symbols, symbol, NULL, 0,
+                                       filename_ptr, NULL, line_ptr, NULL,
+                                       dwarf_debug_sections, 0,
+                                       &elf_tdata (abfd)->dwarf2_find_line_info);
 }
 
 /* After a call to bfd_find_nearest_line, successive calls to
@@ -7322,21 +7745,21 @@ _bfd_elf_sizeof_headers (bfd *abfd, struct bfd_link_info *info)
 
   if (!info->relocatable)
     {
-      bfd_size_type phdr_size = elf_tdata (abfd)->program_header_size;
+      bfd_size_type phdr_size = elf_program_header_size (abfd);
 
       if (phdr_size == (bfd_size_type) -1)
        {
          struct elf_segment_map *m;
 
          phdr_size = 0;
-         for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
+         for (m = elf_seg_map (abfd); m != NULL; m = m->next)
            phdr_size += bed->s->sizeof_phdr;
 
          if (phdr_size == 0)
            phdr_size = get_program_header_size (abfd, info);
        }
 
-      elf_tdata (abfd)->program_header_size = phdr_size;
+      elf_program_header_size (abfd) = phdr_size;
       ret += phdr_size;
     }
 
@@ -7351,7 +7774,7 @@ _bfd_elf_set_section_contents (bfd *abfd,
                               bfd_size_type count)
 {
   Elf_Internal_Shdr *hdr;
-  bfd_signed_vma pos;
+  file_ptr pos;
 
   if (! abfd->output_has_begun
       && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
@@ -7473,11 +7896,12 @@ _bfd_elf_validate_reloc (bfd *abfd, arelent *areloc)
 bfd_boolean
 _bfd_elf_close_and_cleanup (bfd *abfd)
 {
-  if (bfd_get_format (abfd) == bfd_object)
+  struct elf_obj_tdata *tdata = elf_tdata (abfd);
+  if (bfd_get_format (abfd) == bfd_object && tdata != NULL)
     {
-      if (elf_tdata (abfd) != NULL && elf_shstrtab (abfd) != NULL)
+      if (elf_tdata (abfd)->o != NULL && elf_shstrtab (abfd) != NULL)
        _bfd_elf_strtab_free (elf_shstrtab (abfd));
-      _bfd_dwarf2_cleanup_debug_info (abfd);
+      _bfd_dwarf2_cleanup_debug_info (abfd, &tdata->dwarf2_find_line_info);
     }
 
   return _bfd_generic_close_and_cleanup (abfd);
@@ -7509,13 +7933,19 @@ _bfd_elf_rel_vtable_reloc_fn
 # include <sys/procfs.h>
 #endif
 
-/* FIXME: this is kinda wrong, but it's what gdb wants.  */
+/* Return a PID that identifies a "thread" for threaded cores, or the
+   PID of the main process for non-threaded cores.  */
 
 static int
 elfcore_make_pid (bfd *abfd)
 {
-  return ((elf_tdata (abfd)->core_lwpid << 16)
-         + (elf_tdata (abfd)->core_pid));
+  int pid;
+
+  pid = elf_tdata (abfd)->core->lwpid;
+  if (pid == 0)
+    pid = elf_tdata (abfd)->core->pid;
+
+  return pid;
 }
 
 /* If there isn't a section called NAME, make one, using
@@ -7603,9 +8033,10 @@ elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
 
       /* Do not overwrite the core signal if it
         has already been set by another thread.  */
-      if (elf_tdata (abfd)->core_signal == 0)
-       elf_tdata (abfd)->core_signal = prstat.pr_cursig;
-      elf_tdata (abfd)->core_pid = prstat.pr_pid;
+      if (elf_tdata (abfd)->core->signal == 0)
+       elf_tdata (abfd)->core->signal = prstat.pr_cursig;
+      if (elf_tdata (abfd)->core->pid == 0)
+       elf_tdata (abfd)->core->pid = prstat.pr_pid;
 
       /* pr_who exists on:
         solaris 2.5+
@@ -7614,7 +8045,9 @@ elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
         linux 2.[01]
         */
 #if defined (HAVE_PRSTATUS_T_PR_WHO)
-      elf_tdata (abfd)->core_lwpid = prstat.pr_who;
+      elf_tdata (abfd)->core->lwpid = prstat.pr_who;
+#else
+      elf_tdata (abfd)->core->lwpid = prstat.pr_pid;
 #endif
     }
 #if defined (HAVE_PRSTATUS32_T)
@@ -7629,9 +8062,10 @@ elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
 
       /* Do not overwrite the core signal if it
         has already been set by another thread.  */
-      if (elf_tdata (abfd)->core_signal == 0)
-       elf_tdata (abfd)->core_signal = prstat.pr_cursig;
-      elf_tdata (abfd)->core_pid = prstat.pr_pid;
+      if (elf_tdata (abfd)->core->signal == 0)
+       elf_tdata (abfd)->core->signal = prstat.pr_cursig;
+      if (elf_tdata (abfd)->core->pid == 0)
+       elf_tdata (abfd)->core->pid = prstat.pr_pid;
 
       /* pr_who exists on:
         solaris 2.5+
@@ -7640,7 +8074,9 @@ elfcore_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
         linux 2.[01]
         */
 #if defined (HAVE_PRSTATUS32_T_PR_WHO)
-      elf_tdata (abfd)->core_lwpid = prstat.pr_who;
+      elf_tdata (abfd)->core->lwpid = prstat.pr_who;
+#else
+      elf_tdata (abfd)->core->lwpid = prstat.pr_pid;
 #endif
     }
 #endif /* HAVE_PRSTATUS32_T */
@@ -7745,6 +8181,48 @@ elfcore_grok_s390_prefix (bfd *abfd, Elf_Internal_Note *note)
   return elfcore_make_note_pseudosection (abfd, ".reg-s390-prefix", note);
 }
 
+static bfd_boolean
+elfcore_grok_s390_last_break (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-s390-last-break", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_system_call (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-s390-system-call", note);
+}
+
+static bfd_boolean
+elfcore_grok_s390_tdb (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-s390-tdb", note);
+}
+
+static bfd_boolean
+elfcore_grok_arm_vfp (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-arm-vfp", note);
+}
+
+static bfd_boolean
+elfcore_grok_aarch_tls (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-aarch-tls", note);
+}
+
+static bfd_boolean
+elfcore_grok_aarch_hw_break (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-break", note);
+}
+
+static bfd_boolean
+elfcore_grok_aarch_hw_watch (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-aarch-hw-watch", note);
+}
+
 #if defined (HAVE_PRPSINFO_T)
 typedef prpsinfo_t   elfcore_psinfo_t;
 #if defined (HAVE_PRPSINFO32_T)                /* Sparc64 cross Sparc32 */
@@ -7795,11 +8273,14 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 
       memcpy (&psinfo, note->descdata, sizeof (psinfo));
 
-      elf_tdata (abfd)->core_program
+#if defined (HAVE_PSINFO_T_PR_PID) || defined (HAVE_PRPSINFO_T_PR_PID)
+      elf_tdata (abfd)->core->pid = psinfo.pr_pid;
+#endif
+      elf_tdata (abfd)->core->program
        = _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
                                sizeof (psinfo.pr_fname));
 
-      elf_tdata (abfd)->core_command
+      elf_tdata (abfd)->core->command
        = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
                                sizeof (psinfo.pr_psargs));
     }
@@ -7811,11 +8292,14 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 
       memcpy (&psinfo, note->descdata, sizeof (psinfo));
 
-      elf_tdata (abfd)->core_program
+#if defined (HAVE_PSINFO32_T_PR_PID) || defined (HAVE_PRPSINFO32_T_PR_PID)
+      elf_tdata (abfd)->core->pid = psinfo.pr_pid;
+#endif
+      elf_tdata (abfd)->core->program
        = _bfd_elfcore_strndup (abfd, psinfo.pr_fname,
                                sizeof (psinfo.pr_fname));
 
-      elf_tdata (abfd)->core_command
+      elf_tdata (abfd)->core->command
        = _bfd_elfcore_strndup (abfd, psinfo.pr_psargs,
                                sizeof (psinfo.pr_psargs));
     }
@@ -7833,7 +8317,7 @@ elfcore_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
      implementations, so strip it off if it exists.  */
 
   {
-    char *command = elf_tdata (abfd)->core_command;
+    char *command = elf_tdata (abfd)->core->command;
     int n = strlen (command);
 
     if (0 < n && command[n - 1] == ' ')
@@ -7858,7 +8342,7 @@ elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note)
 
       memcpy (&pstat, note->descdata, sizeof (pstat));
 
-      elf_tdata (abfd)->core_pid = pstat.pr_pid;
+      elf_tdata (abfd)->core->pid = pstat.pr_pid;
     }
 #if defined (HAVE_PSTATUS32_T)
   else if (note->descsz == sizeof (pstatus32_t))
@@ -7868,7 +8352,7 @@ elfcore_grok_pstatus (bfd *abfd, Elf_Internal_Note *note)
 
       memcpy (&pstat, note->descdata, sizeof (pstat));
 
-      elf_tdata (abfd)->core_pid = pstat.pr_pid;
+      elf_tdata (abfd)->core->pid = pstat.pr_pid;
     }
 #endif
   /* Could grab some more details from the "representative"
@@ -7898,11 +8382,11 @@ elfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note)
 
   memcpy (&lwpstat, note->descdata, sizeof (lwpstat));
 
-  elf_tdata (abfd)->core_lwpid = lwpstat.pr_lwpid;
+  elf_tdata (abfd)->core->lwpid = lwpstat.pr_lwpid;
   /* Do not overwrite the core signal if it has already been set by
      another thread.  */
-  if (elf_tdata (abfd)->core_signal == 0)
-    elf_tdata (abfd)->core_signal = lwpstat.pr_cursig;
+  if (elf_tdata (abfd)->core->signal == 0)
+    elf_tdata (abfd)->core->signal = lwpstat.pr_cursig;
 
   /* Make a ".reg/999" section.  */
 
@@ -7985,11 +8469,11 @@ elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note)
   switch (type)
     {
     case 1 /* NOTE_INFO_PROCESS */:
-      /* FIXME: need to add ->core_command.  */
+      /* FIXME: need to add ->core->command.  */
       /* process_info.pid */
-      elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 8);
+      elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, note->descdata + 8);
       /* process_info.signal */
-      elf_tdata (abfd)->core_signal = bfd_get_32 (abfd, note->descdata + 12);
+      elf_tdata (abfd)->core->signal = bfd_get_32 (abfd, note->descdata + 12);
       break;
 
     case 2 /* NOTE_INFO_THREAD */:
@@ -8158,6 +8642,55 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
       else
         return TRUE;
 
+    case NT_S390_LAST_BREAK:
+      if (note->namesz == 6
+          && strcmp (note->namedata, "LINUX") == 0)
+        return elfcore_grok_s390_last_break (abfd, note);
+      else
+        return TRUE;
+
+    case NT_S390_SYSTEM_CALL:
+      if (note->namesz == 6
+          && strcmp (note->namedata, "LINUX") == 0)
+        return elfcore_grok_s390_system_call (abfd, note);
+      else
+        return TRUE;
+
+    case NT_S390_TDB:
+      if (note->namesz == 6
+          && strcmp (note->namedata, "LINUX") == 0)
+        return elfcore_grok_s390_tdb (abfd, note);
+      else
+        return TRUE;
+
+    case NT_ARM_VFP:
+      if (note->namesz == 6
+         && strcmp (note->namedata, "LINUX") == 0)
+       return elfcore_grok_arm_vfp (abfd, note);
+      else
+       return TRUE;
+
+    case NT_ARM_TLS:
+      if (note->namesz == 6
+         && strcmp (note->namedata, "LINUX") == 0)
+       return elfcore_grok_aarch_tls (abfd, note);
+      else
+       return TRUE;
+
+    case NT_ARM_HW_BREAK:
+      if (note->namesz == 6
+         && strcmp (note->namedata, "LINUX") == 0)
+       return elfcore_grok_aarch_hw_break (abfd, note);
+      else
+       return TRUE;
+
+    case NT_ARM_HW_WATCH:
+      if (note->namesz == 6
+         && strcmp (note->namedata, "LINUX") == 0)
+       return elfcore_grok_aarch_hw_watch (abfd, note);
+      else
+       return TRUE;
+
     case NT_PRPSINFO:
     case NT_PSINFO:
       if (bed->elf_backend_grok_psinfo)
@@ -8182,18 +8715,32 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
 
        return TRUE;
       }
+
+    case NT_FILE:
+      return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.file",
+                                             note);
+
+    case NT_SIGINFO:
+      return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo",
+                                             note);
     }
 }
 
 static bfd_boolean
 elfobj_grok_gnu_build_id (bfd *abfd, Elf_Internal_Note *note)
 {
-  elf_tdata (abfd)->build_id_size = note->descsz;
-  elf_tdata (abfd)->build_id = (bfd_byte *) bfd_alloc (abfd, note->descsz);
-  if (elf_tdata (abfd)->build_id == NULL)
+  struct elf_obj_tdata *t;
+
+  if (note->descsz == 0)
     return FALSE;
 
-  memcpy (elf_tdata (abfd)->build_id, note->descdata, note->descsz);
+  t = elf_tdata (abfd);
+  t->build_id = bfd_alloc (abfd, sizeof (*t->build_id) - 1 + note->descsz);
+  if (t->build_id == NULL)
+    return FALSE;
+
+  t->build_id->size = note->descsz;
+  memcpy (t->build_id->data, note->descdata, note->descsz);
 
   return TRUE;
 }
@@ -8211,6 +8758,35 @@ elfobj_grok_gnu_note (bfd *abfd, Elf_Internal_Note *note)
     }
 }
 
+static bfd_boolean
+elfobj_grok_stapsdt_note_1 (bfd *abfd, Elf_Internal_Note *note)
+{
+  struct sdt_note *cur =
+    (struct sdt_note *) bfd_alloc (abfd, sizeof (struct sdt_note)
+                                  + note->descsz);
+
+  cur->next = (struct sdt_note *) (elf_tdata (abfd))->sdt_note_head;
+  cur->size = (bfd_size_type) note->descsz;
+  memcpy (cur->data, note->descdata, note->descsz);
+
+  elf_tdata (abfd)->sdt_note_head = cur;
+
+  return TRUE;
+}
+
+static bfd_boolean
+elfobj_grok_stapsdt_note (bfd *abfd, Elf_Internal_Note *note)
+{
+  switch (note->type)
+    {
+    case NT_STAPSDT:
+      return elfobj_grok_stapsdt_note_1 (abfd, note);
+
+    default:
+      return TRUE;
+    }
+}
+
 static bfd_boolean
 elfcore_netbsd_get_lwpid (Elf_Internal_Note *note, int *lwpidp)
 {
@@ -8229,15 +8805,15 @@ static bfd_boolean
 elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
 {
   /* Signal number at offset 0x08. */
-  elf_tdata (abfd)->core_signal
+  elf_tdata (abfd)->core->signal
     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
 
   /* Process ID at offset 0x50. */
-  elf_tdata (abfd)->core_pid
+  elf_tdata (abfd)->core->pid
     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x50);
 
   /* Command name at 0x7c (max 32 bytes, including nul). */
-  elf_tdata (abfd)->core_command
+  elf_tdata (abfd)->core->command
     = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31);
 
   return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo",
@@ -8250,7 +8826,7 @@ elfcore_grok_netbsd_note (bfd *abfd, Elf_Internal_Note *note)
   int lwp;
 
   if (elfcore_netbsd_get_lwpid (note, &lwp))
-    elf_tdata (abfd)->core_lwpid = lwp;
+    elf_tdata (abfd)->core->lwpid = lwp;
 
   if (note->type == NT_NETBSDCORE_PROCINFO)
     {
@@ -8313,15 +8889,15 @@ static bfd_boolean
 elfcore_grok_openbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
 {
   /* Signal number at offset 0x08. */
-  elf_tdata (abfd)->core_signal
+  elf_tdata (abfd)->core->signal
     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x08);
 
   /* Process ID at offset 0x20. */
-  elf_tdata (abfd)->core_pid
+  elf_tdata (abfd)->core->pid
     = bfd_h_get_32 (abfd, (bfd_byte *) note->descdata + 0x20);
 
   /* Command name at 0x48 (max 32 bytes, including nul). */
-  elf_tdata (abfd)->core_command
+  elf_tdata (abfd)->core->command
     = _bfd_elfcore_strndup (abfd, note->descdata + 0x48, 31);
 
   return TRUE;
@@ -8384,7 +8960,7 @@ elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid)
   unsigned flags;
 
   /* nto_procfs_status 'pid' field is at offset 0.  */
-  elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, (bfd_byte *) ddata);
+  elf_tdata (abfd)->core->pid = bfd_get_32 (abfd, (bfd_byte *) ddata);
 
   /* nto_procfs_status 'tid' field is at offset 4.  Pass it back.  */
   *tid = bfd_get_32 (abfd, (bfd_byte *) ddata + 4);
@@ -8395,15 +8971,15 @@ elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, long *tid)
   /* nto_procfs_status 'what' field is at offset 14.  */
   if ((sig = bfd_get_16 (abfd, (bfd_byte *) ddata + 14)) > 0)
     {
-      elf_tdata (abfd)->core_signal = sig;
-      elf_tdata (abfd)->core_lwpid = *tid;
+      elf_tdata (abfd)->core->signal = sig;
+      elf_tdata (abfd)->core->lwpid = *tid;
     }
 
   /* _DEBUG_FLAG_CURTID (current thread) is 0x80.  Some cores
      do not come from signals so we make sure we set the current
      thread just in case.  */
   if (flags & 0x00000080)
-    elf_tdata (abfd)->core_lwpid = *tid;
+    elf_tdata (abfd)->core->lwpid = *tid;
 
   /* Make a ".qnx_core_status/%d" section.  */
   sprintf (buf, ".qnx_core_status/%ld", *tid);
@@ -8451,7 +9027,7 @@ elfcore_grok_nto_regs (bfd *abfd,
   sect->alignment_power = 2;
 
   /* This is the current thread.  */
-  if (elf_tdata (abfd)->core_lwpid == tid)
+  if (elf_tdata (abfd)->core->lwpid == tid)
     return elfcore_maybe_make_sect (abfd, base, sect);
 
   return TRUE;
@@ -8578,7 +9154,6 @@ elfcore_write_note (bfd *abfd,
   return buf;
 }
 
-#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
 char *
 elfcore_write_prpsinfo (bfd  *abfd,
                        char *buf,
@@ -8586,7 +9161,6 @@ elfcore_write_prpsinfo (bfd  *abfd,
                        const char *fname,
                        const char *psargs)
 {
-  const char *note_name = "CORE";
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   if (bed->elf_backend_write_core_note != NULL)
@@ -8598,6 +9172,7 @@ elfcore_write_prpsinfo (bfd  *abfd,
        return ret;
     }
 
+#if defined (HAVE_PRPSINFO_T) || defined (HAVE_PSINFO_T)
 #if defined (HAVE_PRPSINFO32_T) || defined (HAVE_PSINFO32_T)
   if (bed->s->elfclass == ELFCLASS32)
     {
@@ -8613,7 +9188,7 @@ elfcore_write_prpsinfo (bfd  *abfd,
       strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
       strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
-                                note_name, note_type, &data, sizeof (data));
+                                "CORE", note_type, &data, sizeof (data));
     }
   else
 #endif
@@ -8630,12 +9205,42 @@ elfcore_write_prpsinfo (bfd  *abfd,
       strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
       strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
       return elfcore_write_note (abfd, buf, bufsiz,
-                                note_name, note_type, &data, sizeof (data));
+                                "CORE", note_type, &data, sizeof (data));
     }
-}
 #endif /* PSINFO_T or PRPSINFO_T */
 
-#if defined (HAVE_PRSTATUS_T)
+  free (buf);
+  return NULL;
+}
+
+char *
+elfcore_write_linux_prpsinfo32
+  (bfd *abfd, char *buf, int *bufsiz,
+   const struct elf_internal_linux_prpsinfo *prpsinfo)
+{
+  struct elf_external_linux_prpsinfo32 data;
+
+  memset (&data, 0, sizeof (data));
+  LINUX_PRPSINFO32_SWAP_FIELDS (abfd, prpsinfo, data);
+
+  return elfcore_write_note (abfd, buf, bufsiz, "CORE", NT_PRPSINFO,
+                            &data, sizeof (data));
+}
+
+char *
+elfcore_write_linux_prpsinfo64
+  (bfd *abfd, char *buf, int *bufsiz,
+   const struct elf_internal_linux_prpsinfo *prpsinfo)
+{
+  struct elf_external_linux_prpsinfo64 data;
+
+  memset (&data, 0, sizeof (data));
+  LINUX_PRPSINFO64_SWAP_FIELDS (abfd, prpsinfo, data);
+
+  return elfcore_write_note (abfd, buf, bufsiz,
+                            "CORE", NT_PRPSINFO, &data, sizeof (data));
+}
+
 char *
 elfcore_write_prstatus (bfd *abfd,
                        char *buf,
@@ -8644,7 +9249,6 @@ elfcore_write_prstatus (bfd *abfd,
                        int cursig,
                        const void *gregs)
 {
-  const char *note_name = "CORE";
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   if (bed->elf_backend_write_core_note != NULL)
@@ -8657,6 +9261,7 @@ elfcore_write_prstatus (bfd *abfd,
        return ret;
     }
 
+#if defined (HAVE_PRSTATUS_T)
 #if defined (HAVE_PRSTATUS32_T)
   if (bed->s->elfclass == ELFCLASS32)
     {
@@ -8666,7 +9271,7 @@ elfcore_write_prstatus (bfd *abfd,
       prstat.pr_pid = pid;
       prstat.pr_cursig = cursig;
       memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
-      return elfcore_write_note (abfd, buf, bufsiz, note_name,
+      return elfcore_write_note (abfd, buf, bufsiz, "CORE",
                                 NT_PRSTATUS, &prstat, sizeof (prstat));
     }
   else
@@ -8678,12 +9283,15 @@ elfcore_write_prstatus (bfd *abfd,
       prstat.pr_pid = pid;
       prstat.pr_cursig = cursig;
       memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
-      return elfcore_write_note (abfd, buf, bufsiz, note_name,
+      return elfcore_write_note (abfd, buf, bufsiz, "CORE",
                                 NT_PRSTATUS, &prstat, sizeof (prstat));
     }
-}
 #endif /* HAVE_PRSTATUS_T */
 
+  free (buf);
+  return NULL;
+}
+
 #if defined (HAVE_LWPSTATUS_T)
 char *
 elfcore_write_lwpstatus (bfd *abfd,
@@ -8882,6 +9490,92 @@ elfcore_write_s390_prefix (bfd *abfd,
                              note_name, NT_S390_PREFIX, s390_prefix, size);
 }
 
+char *
+elfcore_write_s390_last_break (bfd *abfd,
+                              char *buf,
+                              int *bufsiz,
+                              const void *s390_last_break,
+                              int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                             note_name, NT_S390_LAST_BREAK,
+                            s390_last_break, size);
+}
+
+char *
+elfcore_write_s390_system_call (bfd *abfd,
+                               char *buf,
+                               int *bufsiz,
+                               const void *s390_system_call,
+                               int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                             note_name, NT_S390_SYSTEM_CALL,
+                            s390_system_call, size);
+}
+
+char *
+elfcore_write_s390_tdb (bfd *abfd,
+                       char *buf,
+                       int *bufsiz,
+                       const void *s390_tdb,
+                       int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                             note_name, NT_S390_TDB, s390_tdb, size);
+}
+
+char *
+elfcore_write_arm_vfp (bfd *abfd,
+                      char *buf,
+                      int *bufsiz,
+                      const void *arm_vfp,
+                      int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                            note_name, NT_ARM_VFP, arm_vfp, size);
+}
+
+char *
+elfcore_write_aarch_tls (bfd *abfd,
+                      char *buf,
+                      int *bufsiz,
+                      const void *aarch_tls,
+                      int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                            note_name, NT_ARM_TLS, aarch_tls, size);
+}
+
+char *
+elfcore_write_aarch_hw_break (bfd *abfd,
+                           char *buf,
+                           int *bufsiz,
+                           const void *aarch_hw_break,
+                           int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                            note_name, NT_ARM_HW_BREAK, aarch_hw_break, size);
+}
+
+char *
+elfcore_write_aarch_hw_watch (bfd *abfd,
+                           char *buf,
+                           int *bufsiz,
+                           const void *aarch_hw_watch,
+                           int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                            note_name, NT_ARM_HW_WATCH, aarch_hw_watch, size);
+}
+
 char *
 elfcore_write_register_note (bfd *abfd,
                             char *buf,
@@ -8912,6 +9606,20 @@ elfcore_write_register_note (bfd *abfd,
     return elfcore_write_s390_ctrs (abfd, buf, bufsiz, data, size);
   if (strcmp (section, ".reg-s390-prefix") == 0)
     return elfcore_write_s390_prefix (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-s390-last-break") == 0)
+    return elfcore_write_s390_last_break (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-s390-system-call") == 0)
+    return elfcore_write_s390_system_call (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-s390-tdb") == 0)
+    return elfcore_write_s390_tdb (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-arm-vfp") == 0)
+    return elfcore_write_arm_vfp (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-aarch-tls") == 0)
+    return elfcore_write_aarch_tls (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-aarch-hw-break") == 0)
+    return elfcore_write_aarch_hw_break (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-aarch-hw-watch") == 0)
+    return elfcore_write_aarch_hw_watch (abfd, buf, bufsiz, data, size);
   return NULL;
 }
 
@@ -8984,6 +9692,12 @@ elf_parse_notes (bfd *abfd, char *buf, size_t size, file_ptr offset)
              if (! elfobj_grok_gnu_note (abfd, &in))
                return FALSE;
            }
+         else if (in.namesz == sizeof "stapsdt"
+                  && strcmp (in.namedata, "stapsdt") == 0)
+           {
+             if (! elfobj_grok_stapsdt_note (abfd, &in))
+               return FALSE;
+           }
          break;
        }
 
@@ -9064,7 +9778,9 @@ bfd_get_elf_phdrs (bfd *abfd, void *phdrs)
 }
 
 enum elf_reloc_type_class
-_bfd_elf_reloc_type_class (const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
+_bfd_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                          const asection *rel_sec ATTRIBUTE_UNUSED,
+                          const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
 {
   return reloc_class_normal;
 }
@@ -9086,7 +9802,7 @@ _bfd_elf_rela_local_sym (bfd *abfd,
                + sym->st_value);
   if ((sec->flags & SEC_MERGE)
       && ELF_ST_TYPE (sym->st_info) == STT_SECTION
-      && sec->sec_info_type == ELF_INFO_TYPE_MERGE)
+      && sec->sec_info_type == SEC_INFO_TYPE_MERGE)
     {
       rel->r_addend =
        _bfd_merged_section_offset (abfd, psec,
@@ -9117,7 +9833,7 @@ _bfd_elf_rel_local_sym (bfd *abfd,
 {
   asection *sec = *psec;
 
-  if (sec->sec_info_type != ELF_INFO_TYPE_MERGE)
+  if (sec->sec_info_type != SEC_INFO_TYPE_MERGE)
     return sym->st_value + addend;
 
   return _bfd_merged_section_offset (abfd, psec,
@@ -9133,12 +9849,18 @@ _bfd_elf_section_offset (bfd *abfd,
 {
   switch (sec->sec_info_type)
     {
-    case ELF_INFO_TYPE_STABS:
+    case SEC_INFO_TYPE_STABS:
       return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info,
                                       offset);
-    case ELF_INFO_TYPE_EH_FRAME:
+    case SEC_INFO_TYPE_EH_FRAME:
       return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset);
     default:
+      if ((sec->flags & SEC_ELF_REVERSE_COPY) != 0)
+       {
+         const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+         bfd_size_type address_size = bed->s->arch_size / 8;
+         offset = sec->size - offset - address_size;
+       }
       return offset;
     }
 }
@@ -9160,11 +9882,12 @@ bfd *
 bfd_elf_bfd_from_remote_memory
   (bfd *templ,
    bfd_vma ehdr_vma,
+   bfd_size_type size,
    bfd_vma *loadbasep,
-   int (*target_read_memory) (bfd_vma, bfd_byte *, int))
+   int (*target_read_memory) (bfd_vma, bfd_byte *, bfd_size_type))
 {
   return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory)
-    (templ, ehdr_vma, loadbasep, target_read_memory);
+    (templ, ehdr_vma, size, loadbasep, target_read_memory);
 }
 \f
 long
@@ -9266,7 +9989,7 @@ _bfd_elf_get_synthetic_symtab (bfd *abfd,
       if (p->addend != 0)
        {
          char buf[30], *a;
-         
+
          memcpy (names, "+0x", sizeof ("+0x") - 1);
          names += sizeof ("+0x") - 1;
          bfd_sprintf_vma (abfd, buf, p->addend);
@@ -9290,8 +10013,8 @@ asection _bfd_elf_large_com_section
                      SEC_IS_COMMON, NULL, "LARGE_COMMON", 0);
 
 void
-_bfd_elf_set_osabi (bfd * abfd,
-                   struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
+_bfd_elf_post_process_headers (bfd * abfd,
+                              struct bfd_link_info * link_info ATTRIBUTE_UNUSED)
 {
   Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form.  */
 
@@ -9300,11 +10023,11 @@ _bfd_elf_set_osabi (bfd * abfd,
   i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
 
   /* To make things simpler for the loader on Linux systems we set the
-     osabi field to ELFOSABI_LINUX if the binary contains symbols of
-     the STT_GNU_IFUNC type.  */
+     osabi field to ELFOSABI_GNU if the binary contains symbols of
+     the STT_GNU_IFUNC type or STB_GNU_UNIQUE binding.  */
   if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE
-      && elf_tdata (abfd)->has_ifunc_symbols)
-    i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_LINUX;
+      && elf_tdata (abfd)->has_gnu_symbols)
+    i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_GNU;
 }
 
 
@@ -9318,3 +10041,27 @@ _bfd_elf_is_function_type (unsigned int type)
   return (type == STT_FUNC
          || type == STT_GNU_IFUNC);
 }
+
+/* If the ELF symbol SYM might be a function in SEC, return the
+   function size and set *CODE_OFF to the function's entry point,
+   otherwise return zero.  */
+
+bfd_size_type
+_bfd_elf_maybe_function_sym (const asymbol *sym, asection *sec,
+                            bfd_vma *code_off)
+{
+  bfd_size_type size;
+
+  if ((sym->flags & (BSF_SECTION_SYM | BSF_FILE | BSF_OBJECT
+                    | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC)) != 0
+      || sym->section != sec)
+    return 0;
+
+  *code_off = sym->value;
+  size = 0;
+  if (!(sym->flags & BSF_SYNTHETIC))
+    size = ((elf_symbol_type *) sym)->internal_elf_sym.st_size;
+  if (size == 0)
+    size = 1;
+  return size;
+}
This page took 0.087426 seconds and 4 git commands to generate.