bfd/
[deliverable/binutils-gdb.git] / bfd / elflink.c
index 0bb49ea1c8df4b0b88f4dddf8785b75dc70bec19..cd9131ef3805d301d0afc7c0e954fe502e26e3eb 100644 (file)
@@ -2935,8 +2935,11 @@ elf_smash_syms (struct elf_link_hash_entry *h, void *data)
   if (h->ref_regular)
     abort ();
 
-  /* Set sym back to newly created state, but keep undefs list pointer.  */
+  /* Set sym back to newly created state, but keep undef.next if it is
+     being used as a list pointer.  */
   bh = h->root.u.undef.next;
+  if (bh == &h->root)
+    bh = NULL;
   if (bh != NULL || inf->htab->root.undefs_tail == &h->root)
     inf->twiddled = TRUE;
   (*inf->htab->root.table.newfunc) (&h->root.root,
@@ -3240,6 +3243,10 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
                  /* Clobber the section size so that the warning does
                     not get copied into the output file.  */
                  s->size = 0;
+
+                 /* Also set SEC_EXCLUDE, so that symbols defined in
+                    the warning section don't get copied to the output.  */
+                 s->flags |= SEC_EXCLUDE;
                }
            }
        }
@@ -6696,6 +6703,26 @@ match_group_member (asection *sec, asection *group)
   return NULL;
 }
 
+/* Check if the kept section of a discarded section SEC can be used
+   to replace it. Return the replacement if it is OK. Otherwise return
+   NULL. */
+
+asection *
+_bfd_elf_check_kept_section (asection *sec)
+{
+  asection *kept;
+
+  kept = sec->kept_section;
+  if (kept != NULL)
+    {
+      if (elf_sec_group (sec) != NULL)
+       kept = match_group_member (sec, kept);
+      if (kept != NULL && sec->size != kept->size)
+       kept = NULL;
+    }
+  return kept;
+}
+
 /* Link an input file into the linker output file.  This function
    handles all the sections and relocations of the input file at once.
    This is so that we only have to read the local symbols once, and
@@ -6845,6 +6872,11 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                  && (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))
+       continue;
+
       /* Get the name of the symbol.  */
       name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link,
                                              isym->st_name);
@@ -7009,15 +7041,15 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                     discarded section.  */
                  if ((sec = *ps) != NULL && elf_discarded_section (sec))
                    {
-                     asection *kept;
-
                      BFD_ASSERT (r_symndx != 0);
                      if (action & COMPLAIN)
                        {
                          (*_bfd_error_handler)
                            (_("`%s' referenced in section `%A' of %B: "
-                              "defined in discarded section `%A' of %B\n"),
+                              "defined in discarded section `%A' of %B"),
                             o, input_bfd, sec, sec->owner, sym_name);
+                         bfd_set_error (bfd_error_bad_value);
+                         return FALSE;
                        }
 
                      /* Try to do the best we can to support buggy old
@@ -7031,13 +7063,12 @@ elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd)
                         is that we warn in non-debug sections, and
                         debug sections tend to come after other
                         sections.  */
-                     kept = sec->kept_section;
-                     if (kept != NULL && (action & PRETEND))
+                     if (action & PRETEND)
                        {
-                         if (elf_sec_group (sec) != NULL)
-                           kept = match_group_member (sec, kept);
-                         if (kept != NULL
-                             && sec->size == kept->size)
+                         asection *kept;
+
+                         kept = _bfd_elf_check_kept_section (sec);
+                         if (kept != NULL)
                            {
                              *ps = kept;
                              continue;
@@ -9012,7 +9043,7 @@ elf_mark_used_section (struct elf_link_hash_entry *h,
       || h->root.type == bfd_link_hash_defweak)
     {
       asection *s = h->root.u.def.section;
-      if (s != NULL && s->output_section != NULL && s->output_section != s)
+      if (s != NULL && s->output_section != NULL)
        s->output_section->flags |= SEC_KEEP;
     }
 
@@ -9636,21 +9667,21 @@ _bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
 
            case SEC_LINK_DUPLICATES_ONE_ONLY:
              (*_bfd_error_handler)
-               (_("%B: ignoring duplicate section `%A'\n"),
+               (_("%B: ignoring duplicate section `%A'"),
                 abfd, sec);
              break;
 
            case SEC_LINK_DUPLICATES_SAME_SIZE:
              if (sec->size != l->sec->size)
                (*_bfd_error_handler)
-                 (_("%B: duplicate section `%A' has different size\n"),
+                 (_("%B: duplicate section `%A' has different size"),
                   abfd, sec);
              break;
 
            case SEC_LINK_DUPLICATES_SAME_CONTENTS:
              if (sec->size != l->sec->size)
                (*_bfd_error_handler)
-                 (_("%B: duplicate section `%A' has different size\n"),
+                 (_("%B: duplicate section `%A' has different size"),
                   abfd, sec);
              else if (sec->size != 0)
                {
@@ -9658,16 +9689,16 @@ _bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
 
                  if (!bfd_malloc_and_get_section (abfd, sec, &sec_contents))
                    (*_bfd_error_handler)
-                     (_("%B: warning: could not read contents of section `%A'\n"),
+                     (_("%B: warning: could not read contents of section `%A'"),
                       abfd, sec);
                  else if (!bfd_malloc_and_get_section (l->sec->owner, l->sec,
                                                        &l_sec_contents))
                    (*_bfd_error_handler)
-                     (_("%B: warning: could not read contents of section `%A'\n"),
+                     (_("%B: warning: could not read contents of section `%A'"),
                       l->sec->owner, l->sec);
                  else if (memcmp (sec_contents, l_sec_contents, sec->size) != 0)
                    (*_bfd_error_handler)
-                     (_("%B: warning: duplicate section `%A' has different contents\n"),
+                     (_("%B: warning: duplicate section `%A' has different contents"),
                       abfd, sec);
 
                  if (sec_contents)
@@ -9750,3 +9781,24 @@ _bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
   /* This is the first section with this name.  Record it.  */
   bfd_section_already_linked_table_insert (already_linked_list, sec);
 }
+
+/* Set NAME to VAL if the symbol exists and is undefined.  */
+
+void
+_bfd_elf_provide_symbol (struct bfd_link_info *info, const char *name,
+                        bfd_vma val)
+{
+  struct elf_link_hash_entry *h;
+  h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE,
+                           FALSE);
+  if (h != NULL && h->root.type == bfd_link_hash_undefined)
+    {
+      h->root.type = bfd_link_hash_defined;
+      h->root.u.def.section = bfd_abs_section_ptr;
+      h->root.u.def.value = val;
+      h->def_regular = 1;
+      h->type = STT_OBJECT;
+      h->other = STV_HIDDEN | (h->other & ~ ELF_ST_VISIBILITY (-1));
+      h->forced_local = 1;
+    }
+}
This page took 0.028995 seconds and 4 git commands to generate.