bfd/
[deliverable/binutils-gdb.git] / bfd / elf.c
index f97d507dbb97f3ed74073db2cc403459db12dc4f..afde13e8d945f6fcc6d426c914084c6433100cf3 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1,6 +1,7 @@
 /* ELF executable support for BFD.
-   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003 Free Software Foundation, Inc.
+
+   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+   2002, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -41,7 +42,7 @@
 #include "libiberty.h"
 
 static int elf_sort_sections (const void *, const void *);
-static bfd_boolean assign_file_positions_except_relocs (bfd *);
+static bfd_boolean assign_file_positions_except_relocs (bfd *, struct bfd_link_info *);
 static bfd_boolean prep_headers (bfd *);
 static bfd_boolean swap_out_syms (bfd *, struct bfd_strtab_hash **, int) ;
 static bfd_boolean elfcore_read_notes (bfd *, file_ptr, bfd_size_type) ;
@@ -325,7 +326,7 @@ bfd_elf_get_elf_syms (bfd *ibfd,
   Elf_External_Sym_Shndx *shndx;
   Elf_Internal_Sym *isym;
   Elf_Internal_Sym *isymend;
-  struct elf_backend_data *bed;
+  const struct elf_backend_data *bed;
   size_t extsym_size;
   bfd_size_type amt;
   file_ptr pos;
@@ -638,7 +639,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
 {
   asection *newsect;
   flagword flags;
-  struct elf_backend_data *bed;
+  const struct elf_backend_data *bed;
 
   if (hdr->bfd_section != NULL)
     {
@@ -894,7 +895,7 @@ merge_sections_remove_hook (bfd *abfd ATTRIBUTE_UNUSED,
 bfd_boolean
 _bfd_elf_merge_sections (bfd *abfd, struct bfd_link_info *info)
 {
-  if (!is_elf_hash_table (info))
+  if (!is_elf_hash_table (info->hash))
     return FALSE;
   if (elf_hash_table (info)->merge_info)
     _bfd_merge_sections (abfd, elf_hash_table (info)->merge_info,
@@ -907,7 +908,7 @@ _bfd_elf_link_just_syms (asection *sec, struct bfd_link_info *info)
 {
   sec->output_section = bfd_abs_section_ptr;
   sec->output_offset = sec->vma;
-  if (!is_elf_hash_table (info))
+  if (!is_elf_hash_table (info->hash))
     return;
 
   sec->sec_info_type = ELF_INFO_TYPE_JUST_SYMS;
@@ -1193,7 +1194,7 @@ bfd_elf_print_symbol (bfd *abfd,
       {
        const char *section_name;
        const char *name = NULL;
-       struct elf_backend_data *bed;
+       const struct elf_backend_data *bed;
        unsigned char st_other;
        bfd_vma val;
 
@@ -1344,7 +1345,7 @@ _bfd_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
    old indirect symbol.  Also used for copying flags to a weakdef.  */
 
 void
-_bfd_elf_link_hash_copy_indirect (struct elf_backend_data *bed,
+_bfd_elf_link_hash_copy_indirect (const struct elf_backend_data *bed,
                                  struct elf_link_hash_entry *dir,
                                  struct elf_link_hash_entry *ind)
 {
@@ -1354,12 +1355,13 @@ _bfd_elf_link_hash_copy_indirect (struct elf_backend_data *bed,
   /* Copy down any references that we may have already seen to the
      symbol which just became indirect.  */
 
-  dir->elf_link_hash_flags |=
-    (ind->elf_link_hash_flags
-     & (ELF_LINK_HASH_REF_DYNAMIC
-       | ELF_LINK_HASH_REF_REGULAR
-       | ELF_LINK_HASH_REF_REGULAR_NONWEAK
-       | ELF_LINK_NON_GOT_REF));
+  dir->elf_link_hash_flags
+    |= ind->elf_link_hash_flags & (ELF_LINK_HASH_REF_DYNAMIC
+                                  | ELF_LINK_HASH_REF_REGULAR
+                                  | ELF_LINK_HASH_REF_REGULAR_NONWEAK
+                                  | ELF_LINK_NON_GOT_REF
+                                  | ELF_LINK_HASH_NEEDS_PLT
+                                  | ELF_LINK_POINTER_EQUALITY_NEEDED);
 
   if (ind->root.type != bfd_link_hash_indirect)
     return;
@@ -1444,7 +1446,8 @@ _bfd_elf_link_hash_table_init
   memset (&table->eh_info, 0, sizeof (table->eh_info));
   table->dynlocal = NULL;
   table->runpath = NULL;
-  table->tls_segment = NULL;
+  table->tls_sec = NULL;
+  table->tls_size = 0;
   table->loaded = NULL;
 
   ret = _bfd_link_hash_table_init (&table->root, abfd, newfunc);
@@ -1476,8 +1479,7 @@ _bfd_elf_link_hash_table_create (bfd *abfd)
 
 /* This is a hook for the ELF emulation code in the generic linker to
    tell the backend linker what file name to use for the DT_NEEDED
-   entry for a dynamic object.  The generic linker passes name as an
-   empty string to indicate that no DT_NEEDED entry should be made.  */
+   entry for a dynamic object.  */
 
 void
 bfd_elf_set_dt_needed_name (bfd *abfd, const char *name)
@@ -1488,11 +1490,11 @@ bfd_elf_set_dt_needed_name (bfd *abfd, const char *name)
 }
 
 void
-bfd_elf_set_dt_needed_soname (bfd *abfd, const char *name)
+bfd_elf_set_dyn_lib_class (bfd *abfd, int lib_class)
 {
   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
       && bfd_get_format (abfd) == bfd_object)
-    elf_dt_soname (abfd) = name;
+    elf_dyn_lib_class (abfd) = lib_class;
 }
 
 /* Get the list of DT_NEEDED entries for a link.  This is a hook for
@@ -1502,7 +1504,7 @@ struct bfd_link_needed_list *
 bfd_elf_get_needed_list (bfd *abfd ATTRIBUTE_UNUSED,
                         struct bfd_link_info *info)
 {
-  if (! is_elf_hash_table (info))
+  if (! is_elf_hash_table (info->hash))
     return NULL;
   return elf_hash_table (info)->needed;
 }
@@ -1514,7 +1516,7 @@ struct bfd_link_needed_list *
 bfd_elf_get_runpath_list (bfd *abfd ATTRIBUTE_UNUSED,
                          struct bfd_link_info *info)
 {
-  if (! is_elf_hash_table (info))
+  if (! is_elf_hash_table (info->hash))
     return NULL;
   return elf_hash_table (info)->runpath;
 }
@@ -1649,7 +1651,7 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
 {
   Elf_Internal_Shdr *hdr = elf_elfsections (abfd)[shindex];
   Elf_Internal_Ehdr *ehdr = elf_elfheader (abfd);
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   const char *name;
 
   name = elf_string_from_elf_strtab (abfd, hdr->sh_name);
@@ -2019,82 +2021,44 @@ bfd_section_from_elf_index (bfd *abfd, unsigned int index)
 
 static struct bfd_elf_special_section const special_sections[] =
 {
-  { ".bss",            0,      NULL,   0,
-    SHT_NOBITS,                SHF_ALLOC + SHF_WRITE },
-  { ".comment",                0,      NULL,   0,
-    SHT_PROGBITS,      0 },
-  { ".data",           0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC + SHF_WRITE },
-  { ".data1",          0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC + SHF_WRITE },
-  { ".debug",          0,      NULL,   0,
-    SHT_PROGBITS,      0 },
-  { ".fini",           0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC + SHF_EXECINSTR },
-  { ".init",           0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC + SHF_EXECINSTR },
-  { ".line",           0,      NULL,   0,
-    SHT_PROGBITS,      0 },
-  { ".rodata",         0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC },
-  { ".rodata1",                0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC },
-  { ".tbss",           0,      NULL,   0,
-    SHT_NOBITS,                SHF_ALLOC + SHF_WRITE + SHF_TLS },
-  { ".tdata",          0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC + SHF_WRITE + SHF_TLS },
-  { ".text",           0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC + SHF_EXECINSTR },
-  { ".init_array",     0,      NULL,   0,
-    SHT_INIT_ARRAY,    SHF_ALLOC + SHF_WRITE },
-  { ".fini_array",     0,      NULL,   0,
-    SHT_FINI_ARRAY,    SHF_ALLOC + SHF_WRITE },
-  { ".preinit_array",  0,      NULL,   0,
-    SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
-  { ".debug_line",     0,      NULL,   0,
-    SHT_PROGBITS,      0 },
-  { ".debug_info",     0,      NULL,   0,
-    SHT_PROGBITS,      0 },
-  { ".debug_abbrev",   0,      NULL,   0,
-    SHT_PROGBITS,      0 },
-  { ".debug_aranges",  0,      NULL,   0,
-    SHT_PROGBITS,      0 },
-  { ".dynamic",                0,      NULL,   0,
-    SHT_DYNAMIC,       SHF_ALLOC },
-  { ".dynstr",         0,      NULL,   0,
-    SHT_STRTAB,                SHF_ALLOC },
-  { ".dynsym",         0,      NULL,   0,
-    SHT_DYNSYM,                SHF_ALLOC },
-  { ".got",            0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC + SHF_WRITE },
-  { ".hash",           0,      NULL,   0,
-    SHT_HASH,          SHF_ALLOC },
-  { ".interp",         0,      NULL,   0,
-    SHT_PROGBITS,      0 },
-  { ".plt",            0,      NULL,   0,
-    SHT_PROGBITS,      SHF_ALLOC + SHF_EXECINSTR },
-  { ".shstrtab",       0,      NULL,   0,
-    SHT_STRTAB,                0 },
-  { ".strtab",         0,      NULL,   0,
-    SHT_STRTAB,                0 },
-  { ".symtab",         0,      NULL,   0,
-    SHT_SYMTAB,                0 },
-  { ".gnu.version",    0,      NULL,   0,
-    SHT_GNU_versym,    0 },
-  { ".gnu.version_d",  0,      NULL,   0,
-    SHT_GNU_verdef,    0 },
-  { ".gnu.version_r",  0,      NULL,   0,
-    SHT_GNU_verneed,   0 },
-  { ".note",           5,      NULL,   0,
-    SHT_NOTE,          0 },
-  { ".rela",           5,      NULL,   0,
-    SHT_RELA,          0 },
-  { ".rel",            4,      NULL,   0,
-    SHT_REL,           0 },
-  { ".stab",           5,      "str",  3,
-    SHT_STRTAB,                0 },
-  { NULL,              0,      NULL,   0,
-    0,          0 }
+  { ".bss",            4, -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
+  { ".comment",        8,  0, SHT_PROGBITS, 0 },
+  { ".data",           5, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+  { ".data1",          6,  0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+  { ".debug",          6,  0, SHT_PROGBITS, 0 },
+  { ".fini",           5,  0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+  { ".init",           5,  0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+  { ".line",           5,  0, SHT_PROGBITS, 0 },
+  { ".rodata",         7, -2, SHT_PROGBITS, SHF_ALLOC },
+  { ".rodata1",        8,  0, SHT_PROGBITS, SHF_ALLOC },
+  { ".tbss",           5, -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_TLS },
+  { ".tdata",          6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_TLS },
+  { ".text",           5, -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+  { ".init_array",    11,  0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_WRITE },
+  { ".fini_array",    11,  0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_WRITE },
+  { ".preinit_array", 14,  0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
+  { ".debug_line",    11,  0, SHT_PROGBITS, 0 },
+  { ".debug_info",    11,  0, SHT_PROGBITS, 0 },
+  { ".debug_abbrev",  13,  0, SHT_PROGBITS, 0 },
+  { ".debug_aranges", 14,  0, SHT_PROGBITS, 0 },
+  { ".dynamic",        8,  0, SHT_DYNAMIC,  SHF_ALLOC },
+  { ".dynstr",         7,  0, SHT_STRTAB,   SHF_ALLOC },
+  { ".dynsym",         7,  0, SHT_DYNSYM,   SHF_ALLOC },
+  { ".got",            4,  0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+  { ".hash",           5,  0, SHT_HASH,     SHF_ALLOC },
+  { ".interp",         7,  0, SHT_PROGBITS, 0 },
+  { ".plt",            4,  0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
+  { ".shstrtab",       9,  0, SHT_STRTAB,   0 },
+  { ".strtab",         7,  0, SHT_STRTAB,   0 },
+  { ".symtab",         7,  0, SHT_SYMTAB,   0 },
+  { ".gnu.version",   12,  0, SHT_GNU_versym, 0 },
+  { ".gnu.version_d", 14,  0, SHT_GNU_verdef, 0 },
+  { ".gnu.version_r", 14,  0, SHT_GNU_verneed, 0 },
+  { ".note",           5, -1, SHT_NOTE,     0 },
+  { ".rela",           5, -1, SHT_RELA,     0 },
+  { ".rel",            4, -1, SHT_REL,      0 },
+  { ".stabstr",        5,  3, SHT_STRTAB,   0 },
+  { NULL,              0,  0, 0,            0 }
 };
 
 static const struct bfd_elf_special_section *
@@ -2103,56 +2067,72 @@ get_special_section (const char *name,
                     unsigned int rela)
 {
   int i;
+  int len = strlen (name);
 
   for (i = 0; special_sections[i].prefix != NULL; i++)
-    if (((special_sections[i].prefix_length
-         && strncmp (name, special_sections[i].prefix,
-                     special_sections[i].prefix_length) == 0
-         && (! special_sections[i].suffix_length
-             || strcmp ((name + strlen (name)
-                         - special_sections[i].suffix_length),
-                        special_sections[i].suffix) == 0))
-        || strcmp (name, special_sections[i].prefix) == 0)
-       && (rela || special_sections[i].type != SHT_RELA))
+    {
+      int suffix_len;
+      int prefix_len = special_sections[i].prefix_length;
+
+      if (len < prefix_len)
+       continue;
+      if (memcmp (name, special_sections[i].prefix, prefix_len) != 0)
+       continue;
+
+      suffix_len = special_sections[i].suffix_length;
+      if (suffix_len <= 0)
+       {
+         if (name[prefix_len] != 0)
+           {
+             if (suffix_len == 0)
+               continue;
+             if (name[prefix_len] != '.'
+                 && (suffix_len == -2
+                     || (rela && special_sections[i].type == SHT_REL)))
+               continue;
+           }
+       }
+      else
+       {
+         if (len < prefix_len + suffix_len)
+           continue;
+         if (memcmp (name + len - suffix_len,
+                     special_sections[i].prefix + prefix_len,
+                     suffix_len) != 0)
+           continue;
+       }
       return &special_sections[i];
+    }
 
   return NULL;
 }
 
-bfd_boolean
-_bfd_elf_get_sec_type_attr (bfd *abfd, const char *name, int *type, int *attr)
+const struct bfd_elf_special_section *
+_bfd_elf_get_sec_type_attr (bfd *abfd, const char *name)
 {
-  bfd_boolean found = FALSE;
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct bfd_elf_special_section *ssect = NULL;
 
   /* See if this is one of the special sections.  */
   if (name)
     {
-      const struct bfd_elf_special_section *ssect = NULL;
-      unsigned int rela = get_elf_backend_data (abfd)->default_use_rela_p;
+      unsigned int rela = bed->default_use_rela_p;
 
       if (bed->special_sections)
        ssect = get_special_section (name, bed->special_sections, rela);
 
       if (! ssect)
        ssect = get_special_section (name, special_sections, rela);
-
-      if (ssect)
-       {
-         *type = ssect->type;
-         *attr = ssect->attributes;
-         found = TRUE;
-       }
     }
 
-  return found;
+  return ssect;
 }
 
 bfd_boolean
 _bfd_elf_new_section_hook (bfd *abfd, asection *sec)
 {
   struct bfd_elf_section_data *sdata;
-  int type, attr;
+  const struct bfd_elf_special_section *ssect;
 
   sdata = (struct bfd_elf_section_data *) sec->used_by_bfd;
   if (sdata == NULL)
@@ -2164,11 +2144,11 @@ _bfd_elf_new_section_hook (bfd *abfd, asection *sec)
     }
 
   elf_section_type (sec) = SHT_NULL;
-  if (sec->name && _bfd_elf_get_sec_type_attr (abfd, sec->name,
-                                              &type, &attr))
+  ssect = _bfd_elf_get_sec_type_attr (abfd, sec->name);
+  if (ssect != NULL)
     {
-      elf_section_type (sec) = type;
-      elf_section_flags (sec) = attr;
+      elf_section_type (sec) = ssect->type;
+      elf_section_flags (sec) = ssect->attr;
     }
 
   /* Indicate whether or not this section should use RELA relocations.  */
@@ -2228,6 +2208,7 @@ _bfd_elf_make_section_from_phdr (bfd *abfd,
   newsect->_raw_size = hdr->p_filesz;
   newsect->filepos = hdr->p_offset;
   newsect->flags |= SEC_HAS_CONTENTS;
+  newsect->alignment_power = bfd_log2 (hdr->p_align);
   if (hdr->p_type == PT_LOAD)
     {
       newsect->flags |= SEC_ALLOC;
@@ -2274,7 +2255,7 @@ _bfd_elf_make_section_from_phdr (bfd *abfd,
 bfd_boolean
 bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int index)
 {
-  struct elf_backend_data *bed;
+  const struct elf_backend_data *bed;
 
   switch (hdr->p_type)
     {
@@ -2332,7 +2313,7 @@ _bfd_elf_init_reloc_shdr (bfd *abfd,
                          bfd_boolean use_rela_p)
 {
   char *name;
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   bfd_size_type amt = sizeof ".rela" + strlen (asect->name);
 
   name = bfd_alloc (abfd, amt);
@@ -2362,7 +2343,7 @@ _bfd_elf_init_reloc_shdr (bfd *abfd,
 static void
 elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
 {
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   bfd_boolean *failedptr = failedptrarg;
   Elf_Internal_Shdr *this_hdr;
 
@@ -2430,7 +2411,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
     case SHT_HASH:
       this_hdr->sh_entsize = bed->s->sizeof_hash_entry;
       break;
-  
+
     case SHT_DYNSYM:
       this_hdr->sh_entsize = bed->s->sizeof_sym;
       break;
@@ -2868,11 +2849,11 @@ assign_section_numbers (bfd *abfd)
 /* Map symbol from it's internal number to the external number, moving
    all local symbols to be at the head of the list.  */
 
-static INLINE int
+static int
 sym_is_global (bfd *abfd, asymbol *sym)
 {
   /* If the backend has a special mapping, use it.  */
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   if (bed->elf_backend_sym_is_global)
     return (*bed->elf_backend_sym_is_global) (abfd, sym);
 
@@ -3028,7 +3009,7 @@ elf_map_symbols (bfd *abfd)
 /* Align to the maximum file alignment that could be required for any
    ELF data structure.  */
 
-static INLINE file_ptr
+static inline file_ptr
 align_file_position (file_ptr off, int align)
 {
   return (off + align - 1) & ~(align - 1);
@@ -3066,7 +3047,7 @@ bfd_boolean
 _bfd_elf_compute_section_file_positions (bfd *abfd,
                                         struct bfd_link_info *link_info)
 {
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   bfd_boolean failed;
   struct bfd_strtab_hash *strtab;
   Elf_Internal_Shdr *shstrtab_hdr;
@@ -3122,7 +3103,7 @@ _bfd_elf_compute_section_file_positions (bfd *abfd,
   /* sh_offset is set in assign_file_positions_except_relocs.  */
   shstrtab_hdr->sh_addralign = 1;
 
-  if (!assign_file_positions_except_relocs (abfd))
+  if (!assign_file_positions_except_relocs (abfd, link_info))
     return FALSE;
 
   if (link_info == NULL && bfd_get_symcount (abfd) > 0)
@@ -3378,7 +3359,9 @@ map_sections_to_segments (bfd *abfd)
        {
          if ((hdr->flags & SEC_READONLY) == 0)
            writable = TRUE;
-         last_hdr = hdr;
+         /* Ignore .tbss section for segment layout purposes.  */
+         if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL)
+           last_hdr = hdr;
          continue;
        }
 
@@ -3590,12 +3573,41 @@ elf_sort_sections (const void *arg1, const void *arg2)
   return sec1->target_index - sec2->target_index;
 }
 
+/* Ian Lance Taylor writes:
+
+   We shouldn't be using % with a negative signed number.  That's just
+   not good.  We have to make sure either that the number is not
+   negative, or that the number has an unsigned type.  When the types
+   are all the same size they wind up as unsigned.  When file_ptr is a
+   larger signed type, the arithmetic winds up as signed long long,
+   which is wrong.
+
+   What we're trying to say here is something like ``increase OFF by
+   the least amount that will cause it to be equal to the VMA modulo
+   the page size.''  */
+/* In other words, something like:
+
+   vma_offset = m->sections[0]->vma % bed->maxpagesize;
+   off_offset = off % bed->maxpagesize;
+   if (vma_offset < off_offset)
+     adjustment = vma_offset + bed->maxpagesize - off_offset;
+   else
+     adjustment = vma_offset - off_offset;
+     
+   which can can be collapsed into the expression below.  */
+
+static file_ptr
+vma_page_aligned_bias (bfd_vma vma, ufile_ptr off, bfd_vma maxpagesize)
+{
+  return ((vma - off) % maxpagesize);
+}
+
 /* Assign file positions to the sections based on the mapping from
    sections to segments.  This function also sets up some fields in
    the file header, and writes out the program headers.  */
 
 static bfd_boolean
-assign_file_positions_for_segments (bfd *abfd)
+assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info)
 {
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   unsigned int count;
@@ -3647,7 +3659,7 @@ assign_file_positions_for_segments (bfd *abfd)
 
   if (bed->elf_backend_modify_segment_map)
     {
-      if (! (*bed->elf_backend_modify_segment_map) (abfd))
+      if (! (*bed->elf_backend_modify_segment_map) (abfd, link_info))
        return FALSE;
     }
 
@@ -3717,7 +3729,8 @@ assign_file_positions_for_segments (bfd *abfd)
          && (m->sections[0]->flags & SEC_ALLOC) != 0)
        {
          if ((abfd->flags & D_PAGED) != 0)
-           off += (m->sections[0]->vma - off) % bed->maxpagesize;
+           off += vma_page_aligned_bias (m->sections[0]->vma, off,
+                                         bed->maxpagesize);
          else
            {
              bfd_size_type align;
@@ -3732,7 +3745,8 @@ assign_file_positions_for_segments (bfd *abfd)
                    align = secalign;
                }
 
-             off += (m->sections[0]->vma - off) % (1 << align);
+             off += vma_page_aligned_bias (m->sections[0]->vma, off,
+                                           1 << align);
            }
        }
 
@@ -3894,9 +3908,11 @@ assign_file_positions_for_segments (bfd *abfd)
                     not have the SEC_LOAD case just above, and then
                     this was necessary, but now I'm not sure.  */
                  if ((abfd->flags & D_PAGED) != 0)
-                   adjust = (sec->vma - voff) % bed->maxpagesize;
+                   adjust = vma_page_aligned_bias (sec->vma, voff,
+                                                   bed->maxpagesize);
                  else
-                   adjust = (sec->vma - voff) % align;
+                   adjust = vma_page_aligned_bias (sec->vma, voff,
+                                                   align);
                }
              else
                adjust = 0;
@@ -4059,7 +4075,7 @@ get_program_header_size (bfd *abfd)
 {
   size_t segs;
   asection *s;
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   /* We can't return a different result each time we're called.  */
   if (elf_tdata (abfd)->program_header_size != 0)
@@ -4155,14 +4171,15 @@ get_program_header_size (bfd *abfd)
    We also don't set the positions of the .symtab and .strtab here.  */
 
 static bfd_boolean
-assign_file_positions_except_relocs (bfd *abfd)
+assign_file_positions_except_relocs (bfd *abfd,
+                                    struct bfd_link_info *link_info)
 {
   struct elf_obj_tdata * const tdata = elf_tdata (abfd);
   Elf_Internal_Ehdr * const i_ehdrp = elf_elfheader (abfd);
   Elf_Internal_Shdr ** const i_shdrpp = elf_elfsections (abfd);
   unsigned int num_sec = elf_numsections (abfd);
   file_ptr off;
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
       && bfd_get_format (abfd) != bfd_core)
@@ -4206,7 +4223,7 @@ assign_file_positions_except_relocs (bfd *abfd)
 
       /* Assign file positions for the loaded sections based on the
          assignment of sections to segments.  */
-      if (! assign_file_positions_for_segments (abfd))
+      if (! assign_file_positions_for_segments (abfd, link_info))
        return FALSE;
 
       /* Assign file positions for the other sections.  */
@@ -4229,9 +4246,11 @@ assign_file_positions_except_relocs (bfd *abfd)
                 ? "*unknown*"
                 : hdr->bfd_section->name)));
              if ((abfd->flags & D_PAGED) != 0)
-               off += (hdr->sh_addr - off) % bed->maxpagesize;
+               off += vma_page_aligned_bias (hdr->sh_addr, off,
+                                             bed->maxpagesize);
              else
-               off += (hdr->sh_addr - off) % hdr->sh_addralign;
+               off += vma_page_aligned_bias (hdr->sh_addr, off,
+                                             hdr->sh_addralign);
              off = _bfd_elf_assign_file_position_for_section (hdr, off,
                                                               FALSE);
            }
@@ -4269,7 +4288,7 @@ prep_headers (bfd *abfd)
   Elf_Internal_Phdr *i_phdrp = 0; /* Program header table, internal form */
   Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */
   struct elf_strtab_hash *shstrtab;
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   i_ehdrp = elf_elfheader (abfd);
   i_shdrp = elf_elfsections (abfd);
@@ -4314,11 +4333,8 @@ prep_headers (bfd *abfd)
         Such need can generally be supplied by replacing the tests for
         e_machine with the conditions used to determine it.  */
     default:
-      if (get_elf_backend_data (abfd) != NULL)
-       i_ehdrp->e_machine = get_elf_backend_data (abfd)->elf_machine_code;
-      else
-       i_ehdrp->e_machine = EM_NONE;
-      }
+      i_ehdrp->e_machine = bed->elf_machine_code;
+    }
 
   i_ehdrp->e_version = bed->s->ev_current;
   i_ehdrp->e_ehsize = bed->s->sizeof_ehdr;
@@ -4396,7 +4412,7 @@ _bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
 bfd_boolean
 _bfd_elf_write_object_contents (bfd *abfd)
 {
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   Elf_Internal_Ehdr *i_ehdrp;
   Elf_Internal_Shdr **i_shdrp;
   bfd_boolean failed;
@@ -4456,9 +4472,9 @@ _bfd_elf_write_corefile_contents (bfd *abfd)
 /* Given a section, search the header to find them.  */
 
 int
-_bfd_elf_section_from_bfd_section (bfd *abfd, struct sec *asect)
+_bfd_elf_section_from_bfd_section (bfd *abfd, struct bfd_section *asect)
 {
-  struct elf_backend_data *bed;
+  const struct elf_backend_data *bed;
   int index;
 
   if (elf_section_data (asect) != NULL
@@ -4574,7 +4590,7 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
   bfd_vma maxpagesize;
   struct elf_segment_map *phdr_adjust_seg = NULL;
   unsigned int phdr_adjust_num = 0;
-  struct elf_backend_data *bed;
+  const struct elf_backend_data *bed;
 
   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
@@ -4646,8 +4662,9 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
        2. It is an allocated segment,
        3. There is an output section associated with it,
        4. The section has not already been allocated to a previous segment.
-       5. PT_TLS segment includes only SHF_TLS sections.
-       6. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.  */
+       5. PT_GNU_STACK segments do not include any sections.
+       6. PT_TLS segment includes only SHF_TLS sections.
+       7. SHF_TLS sections are only in PT_TLS or PT_LOAD segments.  */
 #define INCLUDE_SECTION_IN_SEGMENT(section, segment, bed)              \
   ((((segment->p_paddr                                                 \
       ? IS_CONTAINED_BY_LMA (section, segment, segment->p_paddr)       \
@@ -4655,6 +4672,7 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
      && (section->flags & SEC_ALLOC) != 0)                             \
     || IS_COREFILE_NOTE (segment, section))                            \
    && section->output_section != NULL                                  \
+   && segment->p_type != PT_GNU_STACK                                  \
    && (segment->p_type != PT_TLS                                       \
        || (section->flags & SEC_THREAD_LOCAL))                         \
    && (segment->p_type == PT_LOAD                                      \
@@ -4698,7 +4716,7 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
          if (IS_SOLARIS_PT_INTERP (segment, section))
            {
              /* Mininal change so that the normal section to segment
-                assigment code will work.  */
+                assignment code will work.  */
              segment->p_vaddr = section->vma;
              break;
            }
@@ -5269,7 +5287,7 @@ swap_out_syms (bfd *abfd,
               struct bfd_strtab_hash **sttp,
               int relocatable_p)
 {
-  struct elf_backend_data *bed;
+  const struct elf_backend_data *bed;
   int symcount;
   asymbol **syms;
   struct bfd_strtab_hash *stt;
@@ -5280,6 +5298,7 @@ swap_out_syms (bfd *abfd,
   char *outbound_shndx;
   int idx;
   bfd_size_type amt;
+  bfd_boolean name_local_sections;
 
   if (!elf_map_symbols (abfd))
     return FALSE;
@@ -5345,6 +5364,10 @@ swap_out_syms (bfd *abfd,
       outbound_shndx += sizeof (Elf_External_Sym_Shndx);
   }
 
+  name_local_sections
+    = (bed->elf_backend_name_local_section_symbols
+       && bed->elf_backend_name_local_section_symbols (abfd));
+
   syms = bfd_get_outsymbols (abfd);
   for (idx = 0; idx < symcount; idx++)
     {
@@ -5354,7 +5377,8 @@ swap_out_syms (bfd *abfd,
       flagword flags = syms[idx]->flags;
       int type;
 
-      if ((flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM)
+      if (!name_local_sections
+         && (flags & (BSF_SECTION_SYM | BSF_GLOBAL)) == BSF_SECTION_SYM)
        {
          /* Local section symbols have no name.  */
          sym.st_name = 0;
@@ -5601,7 +5625,7 @@ _bfd_elf_canonicalize_reloc (bfd *abfd,
 {
   arelent *tblptr;
   unsigned int i;
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   if (! bed->s->slurp_reloc_table (abfd, section, symbols, FALSE))
     return -1;
@@ -5616,9 +5640,9 @@ _bfd_elf_canonicalize_reloc (bfd *abfd,
 }
 
 long
-_bfd_elf_get_symtab (bfd *abfd, asymbol **allocation)
+_bfd_elf_canonicalize_symtab (bfd *abfd, asymbol **allocation)
 {
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   long symcount = bed->s->slurp_symbol_table (abfd, allocation, FALSE);
 
   if (symcount >= 0)
@@ -5630,7 +5654,7 @@ long
 _bfd_elf_canonicalize_dynamic_symtab (bfd *abfd,
                                      asymbol **allocation)
 {
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   long symcount = bed->s->slurp_symbol_table (abfd, allocation, TRUE);
 
   if (symcount >= 0)
@@ -6119,7 +6143,7 @@ _bfd_elf_sizeof_headers (bfd *abfd, bfd_boolean reloc)
 bfd_boolean
 _bfd_elf_set_section_contents (bfd *abfd,
                               sec_ptr section,
-                              void *location,
+                              const void *location,
                               file_ptr offset,
                               bfd_size_type count)
 {
@@ -6263,7 +6287,7 @@ _bfd_elf_close_and_cleanup (bfd *abfd)
 bfd_reloc_status_type
 _bfd_elf_rel_vtable_reloc_fn
   (bfd *abfd ATTRIBUTE_UNUSED, arelent *re ATTRIBUTE_UNUSED,
-   struct symbol_cache_entry *symbol ATTRIBUTE_UNUSED,
+   struct bfd_symbol *symbol ATTRIBUTE_UNUSED,
    void *data ATTRIBUTE_UNUSED, asection *is ATTRIBUTE_UNUSED,
    bfd *obfd ATTRIBUTE_UNUSED, char **errmsg ATTRIBUTE_UNUSED)
 {
@@ -6339,7 +6363,7 @@ _bfd_elfcore_make_pseudosection (bfd *abfd,
     return FALSE;
   memcpy (threaded_name, buf, len);
 
-  sect = bfd_make_section (abfd, threaded_name);
+  sect = bfd_make_section_anyway (abfd, threaded_name);
   if (sect == NULL)
     return FALSE;
   sect->_raw_size = size;
@@ -6623,7 +6647,7 @@ elfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note)
     return FALSE;
   memcpy (name, buf, len);
 
-  sect = bfd_make_section (abfd, name);
+  sect = bfd_make_section_anyway (abfd, name);
   if (sect == NULL)
     return FALSE;
 
@@ -6653,7 +6677,7 @@ elfcore_grok_lwpstatus (bfd *abfd, Elf_Internal_Note *note)
     return FALSE;
   memcpy (name, buf, len);
 
-  sect = bfd_make_section (abfd, name);
+  sect = bfd_make_section_anyway (abfd, name);
   if (sect == NULL)
     return FALSE;
 
@@ -6709,7 +6733,7 @@ elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note)
 
       memcpy (name, buf, len);
 
-      sect = bfd_make_section (abfd, name);
+      sect = bfd_make_section_anyway (abfd, name);
       if (sect == NULL)
        return FALSE;
 
@@ -6736,7 +6760,7 @@ elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note)
 
       memcpy (name, buf, len);
 
-      sect = bfd_make_section (abfd, name);
+      sect = bfd_make_section_anyway (abfd, name);
 
       if (sect == NULL)
        return FALSE;
@@ -6758,7 +6782,7 @@ elfcore_grok_win32pstatus (bfd *abfd, Elf_Internal_Note *note)
 static bfd_boolean
 elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
 {
-  struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   switch (note->type)
     {
@@ -6813,7 +6837,7 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
 
     case NT_AUXV:
       {
-       asection *sect = bfd_make_section (abfd, ".auxv");
+       asection *sect = bfd_make_section_anyway (abfd, ".auxv");
 
        if (sect == NULL)
          return FALSE;
@@ -6857,7 +6881,8 @@ elfcore_grok_netbsd_procinfo (bfd *abfd, Elf_Internal_Note *note)
   elf_tdata (abfd)->core_command
     = _bfd_elfcore_strndup (abfd, note->descdata + 0x7c, 31);
 
-  return TRUE;
+  return elfcore_make_note_pseudosection (abfd, ".note.netbsdcore.procinfo",
+                                         note);
 }
 
 static bfd_boolean
@@ -6965,7 +6990,7 @@ elfcore_grok_nto_status (bfd *abfd, Elf_Internal_Note *note, pid_t *tid)
     return FALSE;
   strcpy (name, buf);
 
-  sect = bfd_make_section (abfd, name);
+  sect = bfd_make_section_anyway (abfd, name);
   if (sect == NULL)
     return FALSE;
 
@@ -6992,7 +7017,7 @@ elfcore_grok_nto_gregs (bfd *abfd, Elf_Internal_Note *note, pid_t tid)
     return FALSE;
   strcpy (name, buf);
 
-  sect = bfd_make_section (abfd, name);
+  sect = bfd_make_section_anyway (abfd, name);
   if (sect == NULL)
     return FALSE;
 
@@ -7062,14 +7087,14 @@ elfcore_write_note (bfd  *abfd,
   pad = 0;
   if (name != NULL)
     {
-      struct elf_backend_data *bed;
+      const struct elf_backend_data *bed;
 
       namesz = strlen (name) + 1;
       bed = get_elf_backend_data (abfd);
       pad = -namesz & ((1 << bed->s->log_file_align) - 1);
     }
 
-  newspace = sizeof (Elf_External_Note) - 1 + namesz + pad + size;
+  newspace = 12 + namesz + pad + size;
 
   p = realloc (buf, *bufsiz + newspace);
   dest = p + *bufsiz;
@@ -7391,9 +7416,10 @@ _bfd_elf_reloc_type_class (const Elf_Internal_Rela *rela ATTRIBUTE_UNUSED)
 bfd_vma
 _bfd_elf_rela_local_sym (bfd *abfd,
                         Elf_Internal_Sym *sym,
-                        asection *sec,
+                        asection **psec,
                         Elf_Internal_Rela *rel)
 {
+  asection *sec = *psec;
   bfd_vma relocation;
 
   relocation = (sec->output_section->vma
@@ -7403,16 +7429,14 @@ _bfd_elf_rela_local_sym (bfd *abfd,
       && ELF_ST_TYPE (sym->st_info) == STT_SECTION
       && sec->sec_info_type == ELF_INFO_TYPE_MERGE)
     {
-      asection *msec;
-
-      msec = sec;
       rel->r_addend =
-       _bfd_merged_section_offset (abfd, &msec,
+       _bfd_merged_section_offset (abfd, psec,
                                    elf_section_data (sec)->sec_info,
                                    sym->st_value + rel->r_addend,
-                                   0)
-       - relocation;
-      rel->r_addend += msec->output_section->vma + msec->output_offset;
+                                   0);
+      sec = *psec;
+      rel->r_addend -= relocation;
+      rel->r_addend += sec->output_section->vma + sec->output_offset;
     }
   return relocation;
 }
This page took 0.036915 seconds and 4 git commands to generate.