daily update
[deliverable/binutils-gdb.git] / bfd / elflink.c
index b74851698c7ac55460c33766240d36ebf3034629..1fcfce352d8989abc781b6dd48cd0dd40880cdfe 100644 (file)
@@ -852,55 +852,26 @@ _bfd_elf_merge_symbol (bfd *abfd,
   /* NEWDYN and OLDDYN indicate whether the new or old symbol,
      respectively, is from a dynamic object.  */
 
-  if ((abfd->flags & DYNAMIC) != 0)
-    newdyn = TRUE;
-  else
-    newdyn = FALSE;
+  newdyn = (abfd->flags & DYNAMIC) != 0;
 
+  olddyn = FALSE;
   if (oldbfd != NULL)
     olddyn = (oldbfd->flags & DYNAMIC) != 0;
-  else
+  else if (oldsec != NULL)
     {
-      asection *hsec;
-
-      /* This code handles the special SHN_MIPS_{TEXT,DATA} section
+      /* This handles the special SHN_MIPS_{TEXT,DATA} section
         indices used by MIPS ELF.  */
-      switch (h->root.type)
-       {
-       default:
-         hsec = NULL;
-         break;
-
-       case bfd_link_hash_defined:
-       case bfd_link_hash_defweak:
-         hsec = h->root.u.def.section;
-         break;
-
-       case bfd_link_hash_common:
-         hsec = h->root.u.c.p->section;
-         break;
-       }
-
-      if (hsec == NULL)
-       olddyn = FALSE;
-      else
-       olddyn = (hsec->symbol->flags & BSF_DYNAMIC) != 0;
+      olddyn = (oldsec->symbol->flags & BSF_DYNAMIC) != 0;
     }
 
   /* NEWDEF and OLDDEF indicate whether the new or old symbol,
      respectively, appear to be a definition rather than reference.  */
 
-  if (bfd_is_und_section (sec) || bfd_is_com_section (sec))
-    newdef = FALSE;
-  else
-    newdef = TRUE;
+  newdef = !bfd_is_und_section (sec) && !bfd_is_com_section (sec);
 
-  if (h->root.type == bfd_link_hash_undefined
-      || h->root.type == bfd_link_hash_undefweak
-      || h->root.type == bfd_link_hash_common)
-    olddef = FALSE;
-  else
-    olddef = TRUE;
+  olddef = (h->root.type != bfd_link_hash_undefined
+           && h->root.type != bfd_link_hash_undefweak
+           && h->root.type != bfd_link_hash_common);
 
   /* Check TLS symbol.  We don't check undefined symbol introduced by
      "ld -u".  */
@@ -1312,7 +1283,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
       flip->root.type = h->root.type;
       h->root.type = bfd_link_hash_indirect;
       h->root.u.i.link = (struct bfd_link_hash_entry *) flip;
-      (*bed->elf_backend_copy_indirect_symbol) (bed, flip, h);
+      (*bed->elf_backend_copy_indirect_symbol) (info, flip, h);
       flip->root.u.undef.abfd = h->root.u.undef.abfd;
       if (h->def_dynamic)
        {
@@ -1466,7 +1437,7 @@ _bfd_elf_add_default_symbol (bfd *abfd,
       struct elf_link_hash_entry *ht;
 
       ht = (struct elf_link_hash_entry *) hi->root.u.i.link;
-      (*bed->elf_backend_copy_indirect_symbol) (bed, ht, hi);
+      (*bed->elf_backend_copy_indirect_symbol) (info, ht, hi);
 
       /* See if the new flags lead us to realize that the symbol must
         be dynamic.  */
@@ -1535,7 +1506,7 @@ nondefault:
 
       if (hi->root.type == bfd_link_hash_indirect)
        {
-         (*bed->elf_backend_copy_indirect_symbol) (bed, h, hi);
+         (*bed->elf_backend_copy_indirect_symbol) (info, h, hi);
 
          /* See if the new flags lead us to realize that the symbol
             must be dynamic.  */
@@ -2346,7 +2317,7 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h,
          const struct elf_backend_data *bed;
 
          bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
-         (*bed->elf_backend_copy_indirect_symbol) (bed, weakdef, h);
+         (*bed->elf_backend_copy_indirect_symbol) (eif->info, weakdef, h);
        }
     }
 
@@ -3291,11 +3262,10 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
       int ret;
 
       /* ld --just-symbols and dynamic objects don't mix very well.
-        Test for --just-symbols by looking at info set up by
-        _bfd_elf_link_just_syms.  */
+        ld shouldn't allow it.  */
       if ((s = abfd->sections) != NULL
          && s->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
-       goto error_return;
+       abort ();
 
       /* If this dynamic lib was specified on the command line with
         --as-needed in effect, then we don't want to add a DT_NEEDED
@@ -4169,7 +4139,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
              (*bed->elf_backend_hide_symbol) (info, hi, TRUE);
              hi->root.type = bfd_link_hash_indirect;
              hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
-             (*bed->elf_backend_copy_indirect_symbol) (bed, h, hi);
+             (*bed->elf_backend_copy_indirect_symbol) (info, h, hi);
              sym_hash = elf_sym_hashes (abfd);
              if (sym_hash)
                for (symidx = 0; symidx < extsymcount; ++symidx)
@@ -6857,8 +6827,10 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
        isec = bfd_com_section_ptr;
       else
        {
-         /* Who knows?  */
-         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;
        }
 
       *ppsection = isec;
@@ -6889,20 +6861,12 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
        continue;
 
       /* If this symbol is defined in a section which we are
-        discarding, we don't need to keep it, but note that
-        linker_mark is only reliable for sections that have contents.
-        For the benefit of the MIPS ELF linker, we check SEC_EXCLUDE
-        as well as linker_mark.  */
-      if ((isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
+        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
-             || (! isec->linker_mark && (isec->flags & SEC_HAS_CONTENTS) != 0)
-             || (! finfo->info->relocatable
-                 && (isec->flags & SEC_EXCLUDE) != 0)))
-       continue;
-
-      /* If the section is not in the output BFD's section list, it is not
-        being output.  */
-      if (bfd_section_removed_from_list (output_bfd, isec->output_section))
+             || bfd_section_removed_from_list (output_bfd,
+                                               isec->output_section)))
        continue;
 
       /* Get the name of the symbol.  */
@@ -7430,7 +7394,7 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
 }
 
 /* Generate a reloc when linking an ELF file.  This is a reloc
-   requested by the linker, and does come from any input file.  This
+   requested by the linker, and does not come from any input file.  This
    is used to build constructor and destructor tables when linking
    with -Ur.  */
 
@@ -7612,7 +7576,7 @@ elf_get_linked_section_vma (struct bfd_link_order *p)
   elfsec = elf_shdrp[elfsec]->sh_link;
   /* PR 290:
      The Intel C compiler generates SHT_IA_64_UNWIND with
-     SHF_LINK_ORDER.  But it doesn't set theh sh_link or
+     SHF_LINK_ORDER.  But it doesn't set the sh_link or
      sh_info fields.  Hence we could get the situation
      where elfsec is 0.  */
   if (elfsec == 0)
@@ -7665,41 +7629,54 @@ elf_fixup_link_order (bfd *abfd, asection *o)
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   int elfsec;
   struct bfd_link_order **sections;
-  asection *s;
+  asection *s, *other_sec, *linkorder_sec;
   bfd_vma offset;
 
+  other_sec = NULL;
+  linkorder_sec = NULL;
   seen_other = 0;
   seen_linkorder = 0;
   for (p = o->map_head.link_order; p != NULL; p = p->next)
     {
-      if (p->type == bfd_indirect_link_order
-         && (bfd_get_flavour ((sub = p->u.indirect.section->owner))
-             == bfd_target_elf_flavour)
-         && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass)
+      if (p->type == bfd_indirect_link_order)
        {
          s = p->u.indirect.section;
-         elfsec = _bfd_elf_section_from_bfd_section (sub, s);
-         if (elfsec != -1
+         sub = s->owner;
+         if (bfd_get_flavour (sub) == bfd_target_elf_flavour
+             && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass
+             && (elfsec = _bfd_elf_section_from_bfd_section (sub, s)) != -1
              && elf_elfsections (sub)[elfsec]->sh_flags & SHF_LINK_ORDER)
-           seen_linkorder++;
+           {
+             seen_linkorder++;
+             linkorder_sec = s;
+           }
          else
-           seen_other++;
+           {
+             seen_other++;
+             other_sec = s;
+           }
        }
       else
        seen_other++;
+
+      if (seen_other && seen_linkorder)
+       {
+         if (other_sec && linkorder_sec)
+           (*_bfd_error_handler) (_("%A has both ordered [`%A' in %B] and unordered [`%A' in %B] sections"),
+                                  o, linkorder_sec,
+                                  linkorder_sec->owner, other_sec,
+                                  other_sec->owner);
+         else
+           (*_bfd_error_handler) (_("%A has both ordered and unordered sections"),
+                                  o);
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
     }
 
   if (!seen_linkorder)
     return TRUE;
 
-  if (seen_other && seen_linkorder)
-    {
-      (*_bfd_error_handler) (_("%A has both ordered and unordered sections"),
-                            o);
-      bfd_set_error (bfd_error_bad_value);
-      return FALSE;
-    }
-
   sections = (struct bfd_link_order **)
     xmalloc (seen_linkorder * sizeof (struct bfd_link_order *));
   seen_linkorder = 0;
@@ -8152,15 +8129,14 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
           sec && (sec->flags & SEC_THREAD_LOCAL);
           sec = sec->next)
        {
-         bfd_vma size = sec->size;
+         bfd_size_type size = sec->size;
 
-         if (size == 0 && (sec->flags & SEC_HAS_CONTENTS) == 0)
+         if (size == 0
+             && (sec->flags & SEC_HAS_CONTENTS) == 0)
            {
-             struct bfd_link_order *o;
-
-             for (o = sec->map_head.link_order; o != NULL; o = o->next)
-               if (size < o->offset + o->size)
-                 size = o->offset + o->size;
+             struct bfd_link_order *o = sec->map_tail.link_order;
+             if (o != NULL)
+               size = o->offset + o->size;
            }
          end = sec->vma + size;
        }
This page took 0.027334 seconds and 4 git commands to generate.