* linker.c (link_action): Ignore duplicate warning syms.
[deliverable/binutils-gdb.git] / bfd / elf32-i386.c
index 6e79199e0999364444170adf397d6ade248c57e7..d74f6eef1a66c418826b2549037684aa8eb6affb 100644 (file)
@@ -1,5 +1,5 @@
 /* Intel 80386/80486-specific support for 32-bit ELF
-   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -847,11 +847,10 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
                {
                  const char *name;
                  bfd *dynobj;
+                 unsigned int strndx = elf_elfheader (abfd)->e_shstrndx;
+                 unsigned int shnam = elf_section_data (sec)->rel_hdr.sh_name;
 
-                 name = (bfd_elf_string_from_elf_section
-                         (abfd,
-                          elf_elfheader (abfd)->e_shstrndx,
-                          elf_section_data (sec)->rel_hdr.sh_name));
+                 name = bfd_elf_string_from_elf_section (abfd, strndx, shnam);
                  if (name == NULL)
                    return false;
 
@@ -1251,10 +1250,15 @@ allocate_dynrelocs (h, inf)
   struct elf_i386_link_hash_entry *eh;
   struct elf_i386_dyn_relocs *p;
 
-  if (h->root.type == bfd_link_hash_indirect
-      || h->root.type == bfd_link_hash_warning)
+  if (h->root.type == bfd_link_hash_indirect)
     return true;
 
+  if (h->root.type == bfd_link_hash_warning)
+    /* When warning symbols are created, they **replace** the "real"
+       entry in the hash table, thus we never get to see the real
+       symbol in a hash traversal.  So look at it now.  */
+    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
   info = (struct bfd_link_info *) inf;
   htab = elf_i386_hash_table (info);
 
@@ -1421,6 +1425,9 @@ readonly_dynrelocs (h, inf)
   struct elf_i386_link_hash_entry *eh;
   struct elf_i386_dyn_relocs *p;
 
+  if (h->root.type == bfd_link_hash_warning)
+    h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
   eh = (struct elf_i386_link_hash_entry *) h;
   for (p = eh->dyn_relocs; p != NULL; p = p->next)
     {
@@ -1500,10 +1507,12 @@ elf_i386_size_dynamic_sections (output_bfd, info)
                     linker script /DISCARD/, so we'll be discarding
                     the relocs too.  */
                }
-             else
+             else if (p->count != 0)
                {
                  srel = elf_section_data (p->sec)->sreloc;
                  srel->_raw_size += p->count * sizeof (Elf32_External_Rel);
+                 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
+                   info->flags |= DF_TEXTREL;
                }
            }
        }
@@ -1625,7 +1634,9 @@ elf_i386_size_dynamic_sections (output_bfd, info)
 
          /* If any dynamic relocs apply to a read-only section,
             then we need a DT_TEXTREL entry.  */
-         elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, (PTR) info);
+         if ((info->flags & DF_TEXTREL) == 0)
+           elf_link_hash_traverse (&htab->elf, readonly_dynrelocs,
+                                   (PTR) info);
 
          if ((info->flags & DF_TEXTREL) != 0)
            {
@@ -2002,20 +2013,20 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
                 time.  */
 
              skip = false;
+             relocate = false;
 
              outrel.r_offset =
                _bfd_elf_section_offset (output_bfd, info, input_section,
                                         rel->r_offset);
              if (outrel.r_offset == (bfd_vma) -1)
                skip = true;
+             else if (outrel.r_offset == (bfd_vma) -2)
+               skip = true, relocate = true;
              outrel.r_offset += (input_section->output_section->vma
                                  + input_section->output_offset);
 
              if (skip)
-               {
-                 memset (&outrel, 0, sizeof outrel);
-                 relocate = false;
-               }
+               memset (&outrel, 0, sizeof outrel);
              else if (h != NULL
                       && h->dynindx != -1
                       && (r_type == R_386_PC32
@@ -2023,11 +2034,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
                           || !info->symbolic
                           || (h->elf_link_hash_flags
                               & ELF_LINK_HASH_DEF_REGULAR) == 0))
-
-               {
-                 relocate = false;
-                 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
-               }
+               outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
              else
                {
                  /* This symbol is local, or marked to become local.  */
This page took 0.025239 seconds and 4 git commands to generate.