This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Fix EFI support


This patch:

http://sourceware.org/ml/binutils/2008-02/msg00051.html

breaks EFI. I got

[hjl@gnu-6 HelloWorldUefiGcc4.4]$ file HelloWorld.dll
HelloWorld.dll: PE32+ executable (EFI boot service driver)
[hjl@gnu-6 HelloWorldUefiGcc4.4]$ objdump -p HelloWorld.dll
objdump: HelloWorld.dll: File format not recognized
[hjl@gnu-6 HelloWorldUefiGcc4.4]$ 

The problem is we have 3 EFI targets for each arch. When we scan
all targets on EFI input, we always reach

if (efi)
{
  bfd_set_error (bfd_error_wrong_format);
  return NULL;
}

This patch fixes by checking Subsystem.  This patch also adds
bfd_target_efi_p so that we only needs to check one "efi-" instead of
3 "efi-XXX-".  OK for trunl?

Thanks.


H.J.
----
2009-04-15  H.J. Lu  <hongjiu.lu@intel.com>

	* libpei.h (bfd_target_efi_p): New.
	(bfd_pe_executable_p): Use it.

	* peicode.h (pe_bfd_object_p): Properly check EFI and PE.

--- bfd/libpei.h.efi	2009-04-08 08:46:35.000000000 -0700
+++ bfd/libpei.h	2009-04-15 11:31:48.000000000 -0700
@@ -317,6 +317,10 @@
 #define bfd_target_efi_app_arch(xvec)				\
   ((xvec)->name + sizeof ("efi-app-") - 1)
 
+/* Returns true if the target is an EFI target.  */
+#define bfd_target_efi_p(xvec)					\
+   (CONST_STRNEQ ((xvec)->name, "efi-"))
+
 /* Returns true if the target is an EFI Boot Service driver target.  */
 #define bfd_target_efi_bsdrv_p(xvec)				\
    (CONST_STRNEQ ((xvec)->name, "efi-bsdrv-"))
@@ -336,10 +340,8 @@
 /* Macro: Returns true if the bfd is a PE executable as opposed to a
    PE object file.  */
 #define bfd_pe_executable_p(abfd)			\
-  (   bfd_target_pei_p ((abfd)->xvec)			\
-   || bfd_target_efi_app_p ((abfd)->xvec)		\
-   || bfd_target_efi_bsdrv_p ((abfd)->xvec)		\
-   || bfd_target_efi_rtdrv_p ((abfd)->xvec))
+  (bfd_target_pei_p ((abfd)->xvec)			\
+   || bfd_target_efi_p ((abfd)->xvec))
 
 /* These functions are architecture dependent, and are in peicode.h:
    coff_swap_reloc_in
--- bfd/peicode.h.efi	2008-02-14 09:26:02.000000000 -0800
+++ bfd/peicode.h	2009-04-15 13:51:41.000000000 -0700
@@ -1373,12 +1373,11 @@ pe_bfd_object_p (bfd * abfd)
 	      if (pe_arch (bfd_target_efi_app_arch (*target_ptr)) != arch)
 		continue;
 
-	      if (efi)
+	      if (efi
+		  && i->Subsystem == IMAGE_SUBSYSTEM_EFI_APPLICATION)
 		{
-		  /* TARGET_PTR is an EFI backend.  Don't match
-		     TARGET with a EFI file.  */
-		  bfd_set_error (bfd_error_wrong_format);
-		  return NULL;
+		  /* This is a match.  */
+		  break;
 		}
 	    }
           else if (bfd_target_efi_bsdrv_p (*target_ptr))
@@ -1387,12 +1386,11 @@ pe_bfd_object_p (bfd * abfd)
 	      if (pe_arch (bfd_target_efi_bsdrv_arch (*target_ptr)) != arch)
 		continue;
 
-	      if (efi)
+	      if (efi
+		  && i->Subsystem == IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER)
 		{
-		  /* TARGET_PTR is an EFI backend.  Don't match
-		     TARGET with a EFI file.  */
-		  bfd_set_error (bfd_error_wrong_format);
-		  return NULL;
+		  /* This is a match.  */
+		  break;
 		}
 	    }
           else if (bfd_target_efi_rtdrv_p (*target_ptr))
@@ -1401,14 +1399,11 @@ pe_bfd_object_p (bfd * abfd)
 	      if (pe_arch (bfd_target_efi_rtdrv_arch (*target_ptr)) != arch)
 		continue;
 
-	      if (efi)
+	      if (efi
+		  && i->Subsystem == IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)
 		{
-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;
+		  /* This is a match.  */
+		  break;
 		}
 	    }
 	  else if (bfd_target_pei_p (*target_ptr))
@@ -1419,13 +1414,20 @@ no_match:
 
 	      if (!efi)
 		{
-		  /* TARGET_PTR is a PE backend.  Don't match
-		     TARGET with a PE file.  */
-		  goto no_match;
+		  /* This is a match.  */
+		  break;
 		}
 	    }
 	}
 
+      if (*target_ptr != NULL)
+	{
+	  /* TARGET_PTR is a match.  Don't match TARGET with input.  */
+	  bfd_preserve_restore (abfd, &preserve);
+	  bfd_set_error (bfd_error_wrong_format);
+	  return NULL;
+	}
+
       bfd_preserve_finish (abfd, &preserve);
     }
   else


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]