diff --git a/util/cbfstool/cbfs-mkpayload.c b/util/cbfstool/cbfs-mkpayload.c index 99142f4fae..e207b3e40f 100644 --- a/util/cbfstool/cbfs-mkpayload.c +++ b/util/cbfstool/cbfs-mkpayload.c @@ -261,11 +261,10 @@ int parse_fv_to_payload(const struct buffer *input, common_section_header_t *cs; dos_header_t *dh; coff_header_t *ch; - pe_opt_header_t *ph; int dh_offset; - uint32_t loadaddress; - uint32_t entrypoint; + uint32_t loadaddress = 0; + uint32_t entrypoint = 0; compress = compression_function(algo); if (!compress) @@ -282,18 +281,21 @@ int parse_fv_to_payload(const struct buffer *input, fh = (ffs_file_header_t *)(input->data + fv->header_length); if (fh->file_type != FILETYPE_SEC) { ERROR("Not a usable UEFI firmware volume.\n"); + INFO("First file in first FV not a SEC core.\n"); return -1; } cs = (common_section_header_t *)&fh[1]; if (cs->section_type != SECTION_PE32) { ERROR("Not a usable UEFI firmware volume.\n"); + INFO("Section type not PE32.\n"); return -1; } dh = (dos_header_t *)&cs[1]; - if (dh->signature != 0x5a4d) { + if (dh->signature != DOS_MAGIC) { ERROR("Not a usable UEFI firmware volume.\n"); + INFO("DOS header signature wrong.\n"); return -1; } @@ -301,23 +303,36 @@ int parse_fv_to_payload(const struct buffer *input, DEBUG("dos header offset = %x\n", dh_offset); ch = (coff_header_t *)(((void *)dh)+dh->e_lfanew); - if (ch->machine != 0x14c) { - ERROR("Not a usable UEFI firmware volume.\n"); + + if (ch->machine == MACHINE_TYPE_X86) { + pe_opt_header_32_t *ph; + ph = (pe_opt_header_32_t *)&ch[1]; + if (ph->signature != PE_HDR_32_MAGIC) { + WARN("PE header signature incorrect.\n"); + return -1; + } + DEBUG("image base %x\n", ph->image_addr); + DEBUG("entry point %x\n", ph->entry_point); + + loadaddress = ph->image_addr - dh_offset; + entrypoint = ph->image_addr + ph->entry_point; + } else if (ch->machine == MACHINE_TYPE_X64) { + pe_opt_header_64_t *ph; + ph = (pe_opt_header_64_t *)&ch[1]; + if (ph->signature != PE_HDR_64_MAGIC) { + WARN("PE header signature incorrect.\n"); + return -1; + } + DEBUG("image base %lx\n", (unsigned long)ph->image_addr); + DEBUG("entry point %x\n", ph->entry_point); + + loadaddress = ph->image_addr - dh_offset; + entrypoint = ph->image_addr + ph->entry_point; + } else { + ERROR("Machine type not x86 or x64.\n"); return -1; } - ph = (pe_opt_header_t *)&ch[1]; - if (ph->signature != 267) { - ERROR("Not a usable UEFI firmware volume.\n"); - return -1; - } - - DEBUG("image base %x\n", ph->image_addr); - DEBUG("entry point %x\n", ph->entry_point); - - loadaddress = ph->image_addr - dh_offset; - entrypoint = ph->image_addr + ph->entry_point; - if (buffer_create(output, (2 * sizeof(*segs) + input->size), input->name) != 0) return -1; diff --git a/util/cbfstool/coff.h b/util/cbfstool/coff.h index ebe45389f3..0720c15ac0 100644 --- a/util/cbfstool/coff.h +++ b/util/cbfstool/coff.h @@ -17,6 +17,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#define DOS_MAGIC 0x5a4d typedef struct { uint16_t signature; uint16_t lastsize; @@ -39,6 +40,8 @@ typedef struct { uint32_t e_lfanew; } dos_header_t; +#define MACHINE_TYPE_X86 0x014c +#define MACHINE_TYPE_X64 0x8664 typedef struct { uint8_t signature[4]; uint16_t machine; @@ -50,6 +53,7 @@ typedef struct { uint16_t characteristics; } coff_header_t; +#define PE_HDR_32_MAGIC 0x10b typedef struct { uint16_t signature; uint8_t major_linker_version; @@ -82,5 +86,39 @@ typedef struct { uint32_t loader_flags; uint32_t number_of_va_and_sizes; /* data directory not needed */ -} pe_opt_header_t; +} pe_opt_header_32_t; + +#define PE_HDR_64_MAGIC 0x20b +typedef struct { + uint16_t signature; + uint8_t major_linker_version; + uint8_t minor_linker_version; + uint32_t code_size; + uint32_t data_size; + uint32_t bss_size; + uint32_t entry_point; + uint32_t code_offset; + uint64_t image_addr; + uint32_t section_alignment; + uint32_t file_alignment; + uint16_t major_os_version; + uint16_t minor_os_version; + uint16_t major_image_version; + uint16_t minor_image_version; + uint16_t major_subsystem_version; + uint16_t minor_subsystem_version; + uint32_t reserved; + uint32_t image_size; + uint32_t header_size; + uint32_t checksum; + uint16_t subsystem; + uint16_t characteristics; + uint64_t stack_reserve_size; + uint64_t stack_commit_size; + uint64_t heap_reserve_size; + uint64_t heap_commit_size; + uint32_t loader_flags; + uint32_t number_of_va_and_sizes; + /* data directory not needed */ +} pe_opt_header_64_t;