* elf-hppa.h (elf_hppa_reloc_final_type): Handle R_PARISC_GPREL64,
[deliverable/binutils-gdb.git] / bfd / peicode.h
index a6140d7bbe92d8052b219c5b462df8a6a9da9b3d..357d1c881efefb166e4caa53db6ba986fd992600 100644 (file)
@@ -1,6 +1,6 @@
 /* Support for the generic parts of PE/PEI, for BFD.
    Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005, 2006, 2007 Free Software Foundation, Inc.
+   2005, 2006, 2007, 2008  Free Software Foundation, Inc.
    Written by Cygnus Solutions.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -237,7 +237,7 @@ coff_swap_scnhdr_in (bfd * abfd, void * ext, void * in)
   if (scnhdr_int->s_paddr > 0
       && (((scnhdr_int->s_flags & IMAGE_SCN_CNT_UNINITIALIZED_DATA) != 0
           && (! bfd_pe_executable_p (abfd) || scnhdr_int->s_size == 0))
-          || (bfd_pe_executable_p (abfd) && scnhdr_int->s_size > scnhdr_int->s_paddr)))
+          || (bfd_pe_executable_p (abfd) && (scnhdr_int->s_size > scnhdr_int->s_paddr))))
   /* This code used to set scnhdr_int->s_paddr to 0.  However,
      coff_set_alignment_hook stores s_paddr in virt_size, which
      only works if it correctly holds the virtual size of the
@@ -567,7 +567,7 @@ pe_ILF_make_a_symbol (pe_ILF_vars *  vars,
   /* Initialise the internal symbol structure.  */
   ent->u.syment.n_sclass          = sclass;
   ent->u.syment.n_scnum           = section->target_index;
-  ent->u.syment._n._n_n._n_offset = (long) sym;
+  ent->u.syment._n._n_n._n_offset = (bfd_hostptr_t) sym;
 
   sym->symbol.the_bfd = vars->abfd;
   sym->symbol.name    = vars->string_ptr;
@@ -1263,6 +1263,7 @@ pe_bfd_object_p (bfd * abfd)
   struct external_PEI_IMAGE_hdr image_hdr;
   file_ptr offset;
   const bfd_target *target;
+  struct bfd_preserve preserve;
 
   /* Detect if this a Microsoft Import Library Format element.  */
   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
@@ -1327,21 +1328,38 @@ pe_bfd_object_p (bfd * abfd)
       return NULL;
     }
 
+  preserve.marker = NULL;
+  if (! bfd_preserve_save (abfd, &preserve))
+    return NULL;
+
   target = coff_object_p (abfd);
   if (target)
     {
       pe_data_type *pe = pe_data (abfd);
       struct internal_extra_pe_aouthdr *i = &pe->pe_opthdr;
-      bfd_boolean efi = i->Subsystem == IMAGE_SUBSYSTEM_EFI_APPLICATION;
+      bfd_boolean efi = i->Subsystem == IMAGE_SUBSYSTEM_EFI_APPLICATION
+                     || i->Subsystem == IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
+                     || i->Subsystem == IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER;
       enum arch_type arch;
       const bfd_target * const *target_ptr;
 
       /* Get the machine.  */
-      if (bfd_target_efi_p (abfd->xvec))
-       arch = pe_arch (bfd_target_efi_arch (abfd->xvec));
+      if (bfd_target_efi_app_p (abfd->xvec))
+       arch = pe_arch (bfd_target_efi_app_arch (abfd->xvec));
+      else if (bfd_target_efi_bsdrv_p (abfd->xvec))
+        arch = pe_arch (bfd_target_efi_bsdrv_arch (abfd->xvec));
+      else if (bfd_target_efi_rtdrv_p (abfd->xvec))
+        arch = pe_arch (bfd_target_efi_rtdrv_arch (abfd->xvec));
       else
        arch = pe_arch (bfd_target_pei_arch (abfd->xvec));
 
+      /* Don't check PE vs. EFI if arch is unknown.  */
+      if (arch == arch_type_unknown)
+       {
+         bfd_preserve_finish (abfd, &preserve);
+         return target;
+       }
+
       for (target_ptr = bfd_target_vector; *target_ptr != NULL;
           target_ptr++)
        {
@@ -1349,19 +1367,49 @@ pe_bfd_object_p (bfd * abfd)
              || (*target_ptr)->flavour != bfd_target_coff_flavour)
            continue;
 
-         if (bfd_target_efi_p (*target_ptr))
+         if (bfd_target_efi_app_p (*target_ptr))
            {
              /* Skip incompatible arch.  */
-             if (pe_arch (bfd_target_efi_arch (*target_ptr)) != arch)
+             if (pe_arch (bfd_target_efi_app_arch (*target_ptr)) != arch)
                continue;
 
-               if (efi)
-                 {
-                   /* TARGET_PTR is an EFI backend.  Don't match
-                      TARGET with a EFI file.  */
-                   bfd_set_error (bfd_error_wrong_format);
-                   return NULL;
-                 }
+             if (efi)
+               {
+                 /* TARGET_PTR is an EFI backend.  Don't match
+                    TARGET with a EFI file.  */
+                 bfd_set_error (bfd_error_wrong_format);
+                 return NULL;
+               }
+           }
+          else if (bfd_target_efi_bsdrv_p (*target_ptr))
+           {
+             /* Skip incompatible arch.  */
+             if (pe_arch (bfd_target_efi_bsdrv_arch (*target_ptr)) != arch)
+               continue;
+
+             if (efi)
+               {
+                 /* TARGET_PTR is an EFI backend.  Don't match
+                    TARGET with a EFI file.  */
+                 bfd_set_error (bfd_error_wrong_format);
+                 return NULL;
+               }
+           }
+          else if (bfd_target_efi_rtdrv_p (*target_ptr))
+           {
+             /* Skip incompatible arch.  */
+             if (pe_arch (bfd_target_efi_rtdrv_arch (*target_ptr)) != arch)
+               continue;
+
+             if (efi)
+               {
+no_match:
+                 /* TARGET_PTR is an EFI backend.  Don't match
+                    TARGET with a EFI file.  */
+                 bfd_preserve_restore (abfd, &preserve);
+                 bfd_set_error (bfd_error_wrong_format);
+                 return NULL;
+               }
            }
          else if (bfd_target_pei_p (*target_ptr))
            {
@@ -1369,16 +1417,19 @@ pe_bfd_object_p (bfd * abfd)
              if (pe_arch (bfd_target_pei_arch (*target_ptr)) != arch)
                continue;
 
-               if (!efi)
-                 {
-                   /* TARGET_PTR is a PE backend.  Don't match
-                      TARGET with a PE file.  */
-                   bfd_set_error (bfd_error_wrong_format);
-                   return NULL;
-                 }
+             if (!efi)
+               {
+                 /* TARGET_PTR is a PE backend.  Don't match
+                    TARGET with a PE file.  */
+                 goto no_match;
+               }
            }
        }
+
+      bfd_preserve_finish (abfd, &preserve);
     }
+  else
+    bfd_preserve_restore (abfd, &preserve);
 
   return target;
 }
This page took 0.024798 seconds and 4 git commands to generate.