This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
PATCH: Fix EFI support
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: binutils at sources dot redhat dot com
- Cc: pjones at redhat dot com
- Date: Wed, 15 Apr 2009 14:05:25 -0700
- Subject: PATCH: Fix EFI support
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
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