* output.h (Output_section::Input_section): Initialize p2align_ to
[deliverable/binutils-gdb.git] / bfd / elflink.c
index ab19be255a6518f66a96dedb75224d7522b2b685..de1939ac7c8b2a6aa7c1291023becfcce3d96827 100644 (file)
@@ -618,8 +618,7 @@ bfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *info,
     }
 
   if (entry->isym.st_shndx != SHN_UNDEF
-      && (entry->isym.st_shndx < SHN_LORESERVE
-         || entry->isym.st_shndx > SHN_HIRESERVE))
+      && entry->isym.st_shndx < SHN_LORESERVE)
     {
       asection *s;
 
@@ -2789,6 +2788,11 @@ _bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h,
   if (h == NULL)
     return TRUE;
 
+  /* STV_HIDDEN or STV_INTERNAL ones must be local.  */
+  if (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
+      || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL)
+    return TRUE;
+
   /* Common symbols that become definitions don't get the DEF_REGULAR
      flag set, so test it first, and don't bail out.  */
   if (ELF_COMMON_DEF_P (h))
@@ -2817,10 +2821,6 @@ _bfd_elf_symbol_refs_local_p (struct elf_link_hash_entry *h,
   if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
     return FALSE;
 
-  /* However, STV_HIDDEN or STV_INTERNAL ones must be local.  */
-  if (ELF_ST_VISIBILITY (h->other) != STV_PROTECTED)
-    return TRUE;
-
   hash_table = elf_hash_table (info);
   if (!is_elf_hash_table (hash_table))
     return TRUE;
@@ -3471,14 +3471,14 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
        {
          bfd_byte *dynbuf;
          bfd_byte *extdyn;
-         int elfsec;
+         unsigned int elfsec;
          unsigned long shlink;
 
          if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
            goto error_free_dyn;
 
          elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
-         if (elfsec == -1)
+         if (elfsec == SHN_BAD)
            goto error_free_dyn;
          shlink = elf_elfsections (abfd)[elfsec]->sh_link;
 
@@ -3819,8 +3819,16 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
 
       if (isym->st_shndx == SHN_UNDEF)
        sec = bfd_und_section_ptr;
-      else if (isym->st_shndx < SHN_LORESERVE
-              || isym->st_shndx > SHN_HIRESERVE)
+      else if (isym->st_shndx == SHN_ABS)
+       sec = bfd_abs_section_ptr;
+      else if (isym->st_shndx == SHN_COMMON)
+       {
+         sec = bfd_com_section_ptr;
+         /* What ELF calls the size we call the value.  What ELF
+            calls the value we call the alignment.  */
+         value = isym->st_size;
+       }
+      else
        {
          sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
          if (sec == NULL)
@@ -3835,19 +3843,6 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
          else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
            value -= sec->vma;
        }
-      else if (isym->st_shndx == SHN_ABS)
-       sec = bfd_abs_section_ptr;
-      else if (isym->st_shndx == SHN_COMMON)
-       {
-         sec = bfd_com_section_ptr;
-         /* What ELF calls the size we call the value.  What ELF
-            calls the value we call the alignment.  */
-         value = isym->st_size;
-       }
-      else
-       {
-         /* Leave it up to the processor backend.  */
-       }
 
       name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
                                              isym->st_name);
@@ -5408,7 +5403,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
        {
          asection *s;
 
-         if (inputobj->flags & (DYNAMIC | BFD_LINKER_CREATED))
+         if (inputobj->flags & (DYNAMIC | EXEC_P | BFD_LINKER_CREATED))
            continue;
          s = bfd_get_section_by_name (inputobj, ".note.GNU-stack");
          if (s)
@@ -6136,20 +6131,22 @@ _bfd_elf_init_2_index_sections (bfd *output_bfd, struct bfd_link_info *info)
 {
   asection *s;
 
+  /* Data first, since setting text_index_section changes
+     _bfd_elf_link_omit_section_dynsym.  */
   for (s = output_bfd->sections; s != NULL; s = s->next)
-    if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY))
-        == (SEC_ALLOC | SEC_READONLY))
+    if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY)) == SEC_ALLOC)
        && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s))
       {
-       elf_hash_table (info)->text_index_section = s;
+       elf_hash_table (info)->data_index_section = s;
        break;
       }
 
   for (s = output_bfd->sections; s != NULL; s = s->next)
-    if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY)) == SEC_ALLOC)
+    if (((s->flags & (SEC_EXCLUDE | SEC_ALLOC | SEC_READONLY))
+        == (SEC_ALLOC | SEC_READONLY))
        && !_bfd_elf_link_omit_section_dynsym (output_bfd, info, s))
       {
-       elf_hash_table (info)->data_index_section = s;
+       elf_hash_table (info)->text_index_section = s;
        break;
       }
 
@@ -6749,7 +6746,7 @@ bfd_elf_get_bfd_needed_list (bfd *abfd,
 {
   asection *s;
   bfd_byte *dynbuf = NULL;
-  int elfsec;
+  unsigned int elfsec;
   unsigned long shlink;
   bfd_byte *extdyn, *extdynend;
   size_t extdynsize;
@@ -6769,7 +6766,7 @@ bfd_elf_get_bfd_needed_list (bfd *abfd,
     goto error_return;
 
   elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
-  if (elfsec == -1)
+  if (elfsec == SHN_BAD)
     goto error_return;
 
   shlink = elf_elfsections (abfd)[elfsec]->sh_link;
@@ -6870,7 +6867,7 @@ elf_create_symbuf (bfd_size_type symcount, Elf_Internal_Sym *isymbuf)
   Elf_Internal_Sym **ind, **indbufend, **indbuf;
   struct elf_symbuf_symbol *ssym;
   struct elf_symbuf_head *ssymbuf, *ssymhead;
-  bfd_size_type i, shndx_count;
+  bfd_size_type i, shndx_count, total_size;
 
   indbuf = bfd_malloc2 (symcount, sizeof (*indbuf));
   if (indbuf == NULL)
@@ -6890,15 +6887,16 @@ elf_create_symbuf (bfd_size_type symcount, Elf_Internal_Sym *isymbuf)
       if (ind[0]->st_shndx != ind[1]->st_shndx)
        shndx_count++;
 
-  ssymbuf = bfd_malloc ((shndx_count + 1) * sizeof (*ssymbuf)
-                       + (indbufend - indbuf) * sizeof (*ssymbuf));
+  total_size = ((shndx_count + 1) * sizeof (*ssymbuf)
+               + (indbufend - indbuf) * sizeof (*ssym));
+  ssymbuf = bfd_malloc (total_size);
   if (ssymbuf == NULL)
     {
       free (indbuf);
       return NULL;
     }
 
-  ssym = (struct elf_symbuf_symbol *) (ssymbuf + shndx_count);
+  ssym = (struct elf_symbuf_symbol *) (ssymbuf + shndx_count + 1);
   ssymbuf->ssym = NULL;
   ssymbuf->count = shndx_count;
   ssymbuf->st_shndx = 0;
@@ -6916,7 +6914,9 @@ elf_create_symbuf (bfd_size_type symcount, Elf_Internal_Sym *isymbuf)
       ssym->st_other = (*ind)->st_other;
       ssymhead->count++;
     }
-  BFD_ASSERT ((bfd_size_type) (ssymhead - ssymbuf) == shndx_count);
+  BFD_ASSERT ((bfd_size_type) (ssymhead - ssymbuf) == shndx_count
+             && (((bfd_hostptr_t) ssym - (bfd_hostptr_t) ssymbuf)
+                 == total_size));
 
   free (indbuf);
   return ssymbuf;
@@ -6938,7 +6938,7 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
   Elf_Internal_Sym *isym, *isymend;
   struct elf_symbol *symtable1 = NULL, *symtable2 = NULL;
   bfd_size_type count1, count2, i;
-  int shndx1, shndx2;
+  unsigned int shndx1, shndx2;
   bfd_boolean result;
 
   bfd1 = sec1->owner;
@@ -6954,7 +6954,7 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
 
   shndx1 = _bfd_elf_section_from_bfd_section (bfd1, sec1);
   shndx2 = _bfd_elf_section_from_bfd_section (bfd2, sec2);
-  if (shndx1 == -1 || shndx2 == -1)
+  if (shndx1 == SHN_BAD || shndx2 == SHN_BAD)
     return FALSE;
 
   bed1 = get_elf_backend_data (bfd1);
@@ -7011,9 +7011,9 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
       while (lo < hi)
        {
          mid = (lo + hi) / 2;
-         if ((unsigned int) shndx1 < ssymbuf1[mid].st_shndx)
+         if (shndx1 < ssymbuf1[mid].st_shndx)
            hi = mid;
-         else if ((unsigned int) shndx1 > ssymbuf1[mid].st_shndx)
+         else if (shndx1 > ssymbuf1[mid].st_shndx)
            lo = mid + 1;
          else
            {
@@ -7030,9 +7030,9 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
       while (lo < hi)
        {
          mid = (lo + hi) / 2;
-         if ((unsigned int) shndx2 < ssymbuf2[mid].st_shndx)
+         if (shndx2 < ssymbuf2[mid].st_shndx)
            hi = mid;
-         else if ((unsigned int) shndx2 > ssymbuf2[mid].st_shndx)
+         else if (shndx2 > ssymbuf2[mid].st_shndx)
            lo = mid + 1;
          else
            {
@@ -7095,12 +7095,12 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2,
   /* Count definitions in the section.  */
   count1 = 0;
   for (isym = isymbuf1, isymend = isym + symcount1; isym < isymend; isym++)
-    if (isym->st_shndx == (unsigned int) shndx1)
+    if (isym->st_shndx == shndx1)
       symtable1[count1++].u.isym = isym;
 
   count2 = 0;
   for (isym = isymbuf2, isymend = isym + symcount2; isym < isymend; isym++)
-    if (isym->st_shndx == (unsigned int) shndx2)
+    if (isym->st_shndx == shndx2)
       symtable2[count2++].u.isym = isym;
 
   if (count1 == 0 || count2 == 0 || count1 != count2)
@@ -8202,13 +8202,14 @@ elf_link_output_sym (struct elf_final_link_info *finfo,
 static bfd_boolean
 check_dynsym (bfd *abfd, Elf_Internal_Sym *sym)
 {
-  if (sym->st_shndx > SHN_HIRESERVE)
+  if (sym->st_shndx >= (SHN_LORESERVE & 0xffff)
+      && sym->st_shndx < SHN_LORESERVE)
     {
       /* The gABI doesn't support dynamic symbols in output sections
         beyond 64k.  */
       (*_bfd_error_handler)
        (_("%B: Too many sections: %d (>= %d)"),
-        abfd, bfd_count_sections (abfd), SHN_LORESERVE);
+        abfd, bfd_count_sections (abfd), SHN_LORESERVE & 0xffff);
       bfd_set_error (bfd_error_nonrepresentable_section);
       return FALSE;
     }
@@ -8900,28 +8901,26 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
 
       if (isym->st_shndx == SHN_UNDEF)
        isec = bfd_und_section_ptr;
-      else if (isym->st_shndx < SHN_LORESERVE
-              || isym->st_shndx > SHN_HIRESERVE)
-       {
-         isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
-         if (isec
-             && isec->sec_info_type == ELF_INFO_TYPE_MERGE
-             && ELF_ST_TYPE (isym->st_info) != STT_SECTION)
-           isym->st_value =
-             _bfd_merged_section_offset (output_bfd, &isec,
-                                         elf_section_data (isec)->sec_info,
-                                         isym->st_value);
-       }
       else if (isym->st_shndx == SHN_ABS)
        isec = bfd_abs_section_ptr;
       else if (isym->st_shndx == SHN_COMMON)
        isec = bfd_com_section_ptr;
       else
        {
-         /* Don't attempt to output symbols with st_shnx in the
-            reserved range other than SHN_ABS and SHN_COMMON.  */
-         *ppsection = NULL;
-         continue;
+         isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
+         if (isec == NULL)
+           {
+             /* Don't attempt to output symbols with st_shnx in the
+                reserved range other than SHN_ABS and SHN_COMMON.  */
+             *ppsection = NULL;
+             continue;
+           }
+         else if (isec->sec_info_type == ELF_INFO_TYPE_MERGE
+                  && ELF_ST_TYPE (isym->st_info) != STT_SECTION)
+           isym->st_value =
+             _bfd_merged_section_offset (output_bfd, &isec,
+                                         elf_section_data (isec)->sec_info,
+                                         isym->st_value);
        }
 
       *ppsection = isec;
@@ -8954,10 +8953,9 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
       /* If this symbol is defined in a section which we are
         discarding, we don't need to keep it.  */
       if (isym->st_shndx != SHN_UNDEF
-         && (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
-         && (isec == NULL
-             || bfd_section_removed_from_list (output_bfd,
-                                               isec->output_section)))
+         && isym->st_shndx < SHN_LORESERVE
+         && bfd_section_removed_from_list (output_bfd,
+                                           isec->output_section))
        continue;
 
       /* Get the name of the symbol.  */
@@ -9781,7 +9779,8 @@ elf_fixup_link_order (bfd *abfd, asection *o)
              && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass
              && (elfsec = _bfd_elf_section_from_bfd_section (sub, s))
              && elfsec < elf_numsections (sub)
-             && elf_elfsections (sub)[elfsec]->sh_flags & SHF_LINK_ORDER)
+             && elf_elfsections (sub)[elfsec]->sh_flags & SHF_LINK_ORDER
+             && elf_elfsections (sub)[elfsec]->sh_link < elf_numsections (sub))
            {
              seen_linkorder++;
              linkorder_sec = s;
@@ -10169,7 +10168,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
   /* sh_link is set in assign_section_numbers.  */
   /* sh_info is set below.  */
   /* sh_offset is set just below.  */
-  symtab_hdr->sh_addralign = 1 << bed->s->log_file_align;
+  symtab_hdr->sh_addralign = (bfd_vma) 1 << bed->s->log_file_align;
 
   off = elf_tdata (abfd)->next_file_pos;
   off = _bfd_elf_assign_file_position_for_section (symtab_hdr, off, TRUE);
@@ -10189,7 +10188,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
   finfo.symbuf = bfd_malloc (amt);
   if (finfo.symbuf == NULL)
     goto error_return;
-  if (elf_numsections (abfd) > SHN_LORESERVE)
+  if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF))
     {
       /* Wild guess at number of output symbols.  realloc'd as needed.  */
       amt = 2 * max_sym_count + elf_numsections (abfd) + 1000;
@@ -10239,8 +10238,6 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
              if (!elf_link_output_sym (&finfo, NULL, &elfsym, o, NULL))
                goto error_return;
            }
-         if (i == SHN_LORESERVE - 1)
-           i += SHN_HIRESERVE + 1 - SHN_LORESERVE;
        }
     }
 
@@ -10487,13 +10484,10 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
                 the original st_name with the dynstr_index.  */
              sym = e->isym;
 
-             if (e->isym.st_shndx != SHN_UNDEF
-                 && (e->isym.st_shndx < SHN_LORESERVE
-                     || e->isym.st_shndx > SHN_HIRESERVE))
+             s = bfd_section_from_elf_index (e->input_bfd,
+                                             e->isym.st_shndx);
+             if (s != NULL)
                {
-                 s = bfd_section_from_elf_index (e->input_bfd,
-                                                 e->isym.st_shndx);
-
                  sym.st_shndx =
                    elf_section_data (s->output_section)->this_idx;
                  if (! check_dynsym (abfd, &sym))
@@ -11860,12 +11854,9 @@ bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie)
 
          /* Need to: get the symbol; get the section.  */
          isym = &rcookie->locsyms[r_symndx];
-         if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
-           {
-             isec = bfd_section_from_elf_index (rcookie->abfd, isym->st_shndx);
-             if (isec != NULL && elf_discarded_section (isec))
-               return TRUE;
-           }
+         isec = bfd_section_from_elf_index (rcookie->abfd, isym->st_shndx);
+         if (isec != NULL && elf_discarded_section (isec))
+           return TRUE;
        }
       return FALSE;
     }
This page took 0.030215 seconds and 4 git commands to generate.