aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--util/cbfstool/cbfs-mkpayload.c49
-rw-r--r--util/cbfstool/coff.h40
2 files changed, 71 insertions, 18 deletions
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");
- return -1;
- }
- ph = (pe_opt_header_t *)&ch[1];
- if (ph->signature != 267) {
- 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;
}
- 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;