* elf-hppa.h (elf_hppa_final_link): Use gp val of zero when none
[deliverable/binutils-gdb.git] / bfd / elf32-crx.c
index 79b9c64feac2400b8440956e1f98875eaa02e412..0a49885a76748e29ea107eca199e10c6b9473324 100644 (file)
@@ -16,7 +16,7 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 #include "bfd.h"
 #include "sysdep.h"
@@ -30,7 +30,7 @@ static reloc_howto_type *elf_crx_reloc_type_lookup
 static void elf_crx_info_to_howto
   (bfd *, arelent *, Elf_Internal_Rela *);
 static bfd_boolean elf32_crx_relax_delete_bytes
-  (bfd *, asection *, bfd_vma, int);
+  (struct bfd_link_info *, bfd *, asection *, bfd_vma, int);
 static bfd_reloc_status_type crx_elf_final_link_relocate
   (reloc_howto_type *, bfd *, bfd *, asection *,
    bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
@@ -573,8 +573,8 @@ crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
 /* Delete some bytes from a section while relaxing.  */
 
 static bfd_boolean
-elf32_crx_relax_delete_bytes (bfd *abfd, asection *sec,
-                             bfd_vma addr, int count)
+elf32_crx_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd, 
+                             asection *sec, bfd_vma addr, int count)
 {
   Elf_Internal_Shdr *symtab_hdr;
   unsigned int sec_shndx;
@@ -586,6 +586,7 @@ elf32_crx_relax_delete_bytes (bfd *abfd, asection *sec,
   Elf_Internal_Sym *isymend;
   struct elf_link_hash_entry **sym_hashes;
   struct elf_link_hash_entry **end_hashes;
+  struct elf_link_hash_entry **start_hashes;
   unsigned int symcount;
 
   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
@@ -662,13 +663,38 @@ elf32_crx_relax_delete_bytes (bfd *abfd, asection *sec,
   /* Now adjust the global symbols defined in this section.  */
   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
              - symtab_hdr->sh_info);
-  sym_hashes = elf_sym_hashes (abfd);
+  sym_hashes = start_hashes = elf_sym_hashes (abfd);
   end_hashes = sym_hashes + symcount;
 
   for (; sym_hashes < end_hashes; sym_hashes++)
     {
       struct elf_link_hash_entry *sym_hash = *sym_hashes;
 
+      /* The '--wrap SYMBOL' option is causing a pain when the object file, 
+        containing the definition of __wrap_SYMBOL, includes a direct 
+        call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference 
+        the same symbol (which is __wrap_SYMBOL), but still exist as two 
+        different symbols in 'sym_hashes', we don't want to adjust 
+        the global symbol __wrap_SYMBOL twice.  
+        This check is only relevant when symbols are being wrapped.  */
+      if (link_info->wrap_hash != NULL)
+       {
+         struct elf_link_hash_entry **cur_sym_hashes;
+         
+         /* Loop only over the symbols whom been already checked.  */
+         for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes; 
+              cur_sym_hashes++)
+           {
+             /* If the current symbol is identical to 'sym_hash', that means 
+                the symbol was already adjusted (or at least checked).  */
+             if (*cur_sym_hashes == sym_hash)
+               break;
+           }
+         /* Don't adjust the symbol again.  */
+         if (cur_sym_hashes < sym_hashes)
+           continue;
+       }
+
       if ((sym_hash->root.type == bfd_link_hash_defined
           || sym_hash->root.type == bfd_link_hash_defweak)
          && sym_hash->root.u.def.section == sec
@@ -868,8 +894,9 @@ elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
            {
             case bfd_reloc_overflow:
               if (!((*info->callbacks->reloc_overflow)
-                    (info, name, howto->name, (bfd_vma) 0,
-                     input_bfd, input_section, rel->r_offset)))
+                    (info, (h ? &h->root : NULL), name, howto->name,
+                     (bfd_vma) 0, input_bfd, input_section,
+                     rel->r_offset)))
                 return FALSE;
               break;
 
@@ -1077,7 +1104,7 @@ elf32_crx_relax_section (bfd *abfd, asection *sec,
                                           R_CRX_REL16);
 
              /* Delete two bytes of data.  */
-             if (!elf32_crx_relax_delete_bytes (abfd, sec,
+             if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
                                                   irel->r_offset + 2, 2))
                goto error_return;
 
@@ -1122,7 +1149,7 @@ elf32_crx_relax_section (bfd *abfd, asection *sec,
                                           R_CRX_REL8);
 
              /* Delete two bytes of data.  */
-             if (!elf32_crx_relax_delete_bytes (abfd, sec,
+             if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
                                                   irel->r_offset + 2, 2))
                goto error_return;
 
@@ -1156,7 +1183,9 @@ elf32_crx_relax_section (bfd *abfd, asection *sec,
              /* Verify it's a 'cmp&branch' opcode.  */
              if ((code & 0xfff0) != 0x3180 && (code & 0xfff0) != 0x3190
               && (code & 0xfff0) != 0x31a0 && (code & 0xfff0) != 0x31c0
-              && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0)
+              && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0
+              /* Or a Co-processor branch ('bcop').  */
+              && (code & 0xfff0) != 0x3010 && (code & 0xfff0) != 0x3110)
                continue;
 
              /* Note that we've changed the relocs, section contents, etc.  */
@@ -1172,7 +1201,7 @@ elf32_crx_relax_section (bfd *abfd, asection *sec,
                                           R_CRX_REL8_CMP);
 
              /* Delete two bytes of data.  */
-             if (!elf32_crx_relax_delete_bytes (abfd, sec,
+             if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
                                                   irel->r_offset + 4, 2))
                goto error_return;
 
@@ -1213,7 +1242,7 @@ elf32_crx_relax_section (bfd *abfd, asection *sec,
                                           R_CRX_IMM16);
 
              /* Delete two bytes of data.  */
-             if (!elf32_crx_relax_delete_bytes (abfd, sec,
+             if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
                                                   irel->r_offset + 2, 2))
                goto error_return;
 
This page took 0.024749 seconds and 4 git commands to generate.