* mh-mingw (LDFLAGS): Append to rather than replacing previous
[deliverable/binutils-gdb.git] / bfd / coff-ppc.c
index 55f5f621b7a06281d575f3e7432987d9e28e5834..6f903e84c50c32e1a6d5a4240b48a724d2227774 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD back-end for PowerPC Microsoft Portable Executable files.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 /* BFD back-end for PowerPC Microsoft Portable Executable files.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
    Original version pieced together by Kim Knuttila (krk@cygnus.com)
    Free Software Foundation, Inc.
 
    Original version pieced together by Kim Knuttila (krk@cygnus.com)
@@ -13,7 +13,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -33,9 +33,8 @@
    - dlltool will not produce correct output in some .reloc cases, and will
      not produce the right glue code for dll function calls.  */
 
    - dlltool will not produce correct output in some .reloc cases, and will
      not produce the right glue code for dll function calls.  */
 
-#include "bfd.h"
 #include "sysdep.h"
 #include "sysdep.h"
-
+#include "bfd.h"
 #include "libbfd.h"
 
 #include "coff/powerpc.h"
 #include "libbfd.h"
 
 #include "coff/powerpc.h"
@@ -127,11 +126,6 @@ struct ppc_coff_link_hash_table
 static struct bfd_hash_entry *ppc_coff_link_hash_newfunc
   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
           const char *));
 static struct bfd_hash_entry *ppc_coff_link_hash_newfunc
   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
           const char *));
-static bfd_boolean ppc_coff_link_hash_table_init
-  PARAMS ((struct ppc_coff_link_hash_table *, bfd *,
-          struct bfd_hash_entry *(*) (struct bfd_hash_entry *,
-                                      struct bfd_hash_table *,
-                                      const char *)));
 static struct bfd_link_hash_table *ppc_coff_link_hash_table_create
   PARAMS ((bfd *));
 static bfd_boolean coff_ppc_relocate_section
 static struct bfd_link_hash_table *ppc_coff_link_hash_table_create
   PARAMS ((bfd *));
 static bfd_boolean coff_ppc_relocate_section
@@ -184,14 +178,14 @@ ppc_coff_link_hash_newfunc (entry, table, string)
 /* Initialize a PE linker hash table.  */
 
 static bfd_boolean
 /* Initialize a PE linker hash table.  */
 
 static bfd_boolean
-ppc_coff_link_hash_table_init (table, abfd, newfunc)
-     struct ppc_coff_link_hash_table *table;
-     bfd *abfd;
-     struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
-                                               struct bfd_hash_table *,
-                                               const char *));
+ppc_coff_link_hash_table_init (struct ppc_coff_link_hash_table *table,
+                              bfd *abfd,
+                              struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
+                                                                 struct bfd_hash_table *,
+                                                                 const char *),
+                              unsigned int entsize)
 {
 {
-  return _bfd_coff_link_hash_table_init (&table->root, abfd, newfunc);
+  return _bfd_coff_link_hash_table_init (&table->root, abfd, newfunc, entsize);
 }
 
 /* Create a PE linker hash table.  */
 }
 
 /* Create a PE linker hash table.  */
@@ -206,8 +200,9 @@ ppc_coff_link_hash_table_create (abfd)
   ret = (struct ppc_coff_link_hash_table *) bfd_malloc (amt);
   if (ret == NULL)
     return NULL;
   ret = (struct ppc_coff_link_hash_table *) bfd_malloc (amt);
   if (ret == NULL)
     return NULL;
-  if (! ppc_coff_link_hash_table_init (ret, abfd,
-                                       ppc_coff_link_hash_newfunc))
+  if (!ppc_coff_link_hash_table_init (ret, abfd,
+                                     ppc_coff_link_hash_newfunc,
+                                     sizeof (struct ppc_coff_link_hash_entry)))
     {
       free (ret);
       return (struct bfd_link_hash_table *) NULL;
     {
       free (ret);
       return (struct bfd_link_hash_table *) NULL;
@@ -987,6 +982,18 @@ static bfd_boolean in_reloc_p(abfd, howto)
       && (howto->type != IMAGE_REL_PPC_TOCREL16_DEFN) ;
 }
 
       && (howto->type != IMAGE_REL_PPC_TOCREL16_DEFN) ;
 }
 
+static bfd_boolean
+write_base_file_entry (bfd *obfd, struct bfd_link_info *info, bfd_vma addr)
+{
+  if (coff_data (obfd)->pe)
+     addr -= pe_data (obfd)->pe_opthdr.ImageBase;
+  if (fwrite (&addr, sizeof (addr), 1, (FILE *) info->base_file) == 1)
+    return TRUE;
+
+  bfd_set_error (bfd_error_system_call);
+  return FALSE;
+}
+
 /* The reloc processing routine for the optimized COFF linker.  */
 
 static bfd_boolean
 /* The reloc processing routine for the optimized COFF linker.  */
 
 static bfd_boolean
@@ -1242,10 +1249,8 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
                bfd_vma addr = (toc_section->output_section->vma
                                + toc_section->output_offset + our_toc_offset);
 
                bfd_vma addr = (toc_section->output_section->vma
                                + toc_section->output_offset + our_toc_offset);
 
-               if (coff_data (output_bfd)->pe)
-                 addr -= pe_data(output_bfd)->pe_opthdr.ImageBase;
-
-               fwrite (&addr, 1,4, (FILE *) info->base_file);
+               if (!write_base_file_entry (output_bfd, info, addr))
+                 return FALSE;
              }
 
            /* FIXME: this test is conservative.  */
              }
 
            /* FIXME: this test is conservative.  */
@@ -1336,7 +1341,7 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
 
            DUMP_RELOC2 (howto->name, rel);
 
 
            DUMP_RELOC2 (howto->name, rel);
 
-           if (strncmp(".idata$2",input_section->name,8) == 0 && first_thunk_address == 0)
+           if (CONST_STRNEQ (input_section->name, ".idata$2") && first_thunk_address == 0)
              {
                /* Set magic values.  */
                int idata5offset;
              {
                /* Set magic values.  */
                int idata5offset;
@@ -1458,15 +1463,13 @@ coff_ppc_relocate_section (output_bfd, info, input_bfd, input_section,
              /* Relocation to a symbol in a section which
                 isn't absolute - we output the address here
                 to a file.  */
              /* Relocation to a symbol in a section which
                 isn't absolute - we output the address here
                 to a file.  */
-             bfd_vma addr = rel->r_vaddr
-               - input_section->vma
-               + input_section->output_offset
-                 + input_section->output_section->vma;
-
-             if (coff_data (output_bfd)->pe)
-               addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
+             bfd_vma addr = (rel->r_vaddr
+                             - input_section->vma
+                             + input_section->output_offset
+                             + input_section->output_section->vma);
 
 
-             fwrite (&addr, 1,4, (FILE *) info->base_file);
+             if (!write_base_file_entry (output_bfd, info, addr))
+               return FALSE;
            }
        }
 
            }
        }
 
@@ -1965,8 +1968,23 @@ ppc_coff_reloc_type_lookup (abfd, code)
       return NULL;
     }
 }
       return NULL;
     }
 }
-
 #undef HOW2MAP
 #undef HOW2MAP
+
+static reloc_howto_type *
+ppc_coff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                           const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < sizeof (ppc_coff_howto_table) / sizeof (ppc_coff_howto_table[0]);
+       i++)
+    if (ppc_coff_howto_table[i].name != NULL
+       && strcasecmp (ppc_coff_howto_table[i].name, r_name) == 0)
+      return &ppc_coff_howto_table[i];
+
+  return NULL;
+}
 \f
 /* Tailor coffcode.h -- macro heaven.  */
 
 \f
 /* Tailor coffcode.h -- macro heaven.  */
 
@@ -1975,6 +1993,7 @@ ppc_coff_reloc_type_lookup (abfd, code)
 /* We use the special COFF backend linker, with our own special touch.  */
 
 #define coff_bfd_reloc_type_lookup   ppc_coff_reloc_type_lookup
 /* We use the special COFF backend linker, with our own special touch.  */
 
 #define coff_bfd_reloc_type_lookup   ppc_coff_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup ppc_coff_reloc_name_lookup
 #define coff_rtype_to_howto          coff_ppc_rtype_to_howto
 #define coff_relocate_section        coff_ppc_relocate_section
 #define coff_bfd_final_link          ppc_bfd_coff_final_link
 #define coff_rtype_to_howto          coff_ppc_rtype_to_howto
 #define coff_relocate_section        coff_ppc_relocate_section
 #define coff_bfd_final_link          ppc_bfd_coff_final_link
This page took 0.027188 seconds and 4 git commands to generate.