[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2] x86/efi: Use generic PE/COFF structures
Hello everyone, Any comments on v2 patch? Just checking if you missed this email or didn't have time for review. BR, Milan On Tue, Aug 27, 2024 at 3:43 PM Milan Djokic <milandjokic1995@xxxxxxxxx> wrote: > > From: Nikola Jelic <nikola.jelic@xxxxxxxxx> > > Adapted x86 efi parser and mkreloc utility to use generic PE header > (efi/pe.h), instead of locally defined structures for each component. > > Signed-off-by: Nikola Jelic <nikola.jelic@xxxxxxxxx> > Signed-off-by: Milan Djokic <milan.djokic@xxxxxxxxx> > --- > Changes in V2: > - Using pe header constants instead of hardcoded values (magic, > machine) > --- > xen/arch/x86/efi/mkreloc.c | 134 +++++++++++-------------------------- > xen/common/efi/pe.c | 96 ++++++-------------------- > 2 files changed, 61 insertions(+), 169 deletions(-) > > diff --git a/xen/arch/x86/efi/mkreloc.c b/xen/arch/x86/efi/mkreloc.c > index 083740ab8a..89c525d81e 100644 > --- a/xen/arch/x86/efi/mkreloc.c > +++ b/xen/arch/x86/efi/mkreloc.c > @@ -9,45 +9,7 @@ > #include <sys/mman.h> > #include <unistd.h> > > -struct mz_hdr { > - uint16_t signature; > -#define MZ_SIGNATURE 0x5a4d > - uint16_t last_page_size; > - uint16_t page_count; > - uint16_t relocation_count; > - uint16_t header_paras; > - uint16_t min_paras; > - uint16_t max_paras; > - uint16_t entry_ss; > - uint16_t entry_sp; > - uint16_t checksum; > - uint16_t entry_ip; > - uint16_t entry_cs; > - uint16_t relocations; > - uint16_t overlay; > - uint8_t reserved[32]; > - uint32_t extended_header_base; > -}; > - > -struct pe_hdr { > - uint32_t signature; > -#define PE_SIGNATURE 0x00004550 > - uint16_t cpu; > - uint16_t section_count; > - int32_t timestamp; > - uint32_t symbols_file_offset; > - uint32_t symbol_count; > - uint16_t opt_hdr_size; > - uint16_t flags; > - struct { > - uint16_t magic; > -#define PE_MAGIC_EXE32 0x010b > -#define PE_MAGIC_EXE32PLUS 0x020b > - uint8_t linker_major, linker_minor; > - uint32_t code_size, data_size, bss_size; > - uint32_t entry_rva, code_rva, data_rva; > - } opt_hdr; > -}; > +#include "../../../include/efi/pe.h" > > #define PE_PAGE_SIZE 0x1000 > > @@ -55,22 +17,6 @@ struct pe_hdr { > #define PE_BASE_RELOC_HIGHLOW 3 > #define PE_BASE_RELOC_DIR64 10 > > -struct coff_section { > - char name[8]; > - uint32_t size; > - uint32_t rva; > - uint32_t file_size; > - uint32_t file_offset; > - uint32_t relocation_file_offset; > - uint32_t line_number_file_offset; > - uint16_t relocation_count; > - uint16_t line_number_count; > - uint32_t flags; > -#define COFF_SECTION_BSS 0x00000080U > -#define COFF_SECTION_DISCARDABLE 0x02000000U > -#define COFF_SECTION_WRITEABLE 0x80000000U > -}; > - > static void usage(const char *cmd, int rc) > { > fprintf(rc ? stderr : stdout, > @@ -80,7 +26,7 @@ static void usage(const char *cmd, int rc) > } > > static unsigned int load(const char *name, int *handle, > - struct coff_section **sections, > + struct section_header **sections, > uint_fast64_t *image_base, > uint32_t *image_size, > unsigned int *width) > @@ -88,6 +34,7 @@ static unsigned int load(const char *name, int *handle, > int in = open(name, O_RDONLY); > struct mz_hdr mz_hdr; > struct pe_hdr pe_hdr; > + struct pe32_opt_hdr pe32_opt_hdr; > uint32_t base; > > if ( in < 0 || > @@ -96,16 +43,17 @@ static unsigned int load(const char *name, int *handle, > perror(name); > exit(2); > } > - if ( mz_hdr.signature != MZ_SIGNATURE || > - mz_hdr.relocations < sizeof(mz_hdr) || > - !mz_hdr.extended_header_base ) > + if ( mz_hdr.magic != MZ_MAGIC || > + mz_hdr.reloc_table_offset < sizeof(mz_hdr) || > + !mz_hdr.peaddr ) > { > fprintf(stderr, "%s: Wrong DOS file format\n", name); > exit(2); > } > > - if ( lseek(in, mz_hdr.extended_header_base, SEEK_SET) < 0 || > + if ( lseek(in, mz_hdr.peaddr, SEEK_SET) < 0 || > read(in, &pe_hdr, sizeof(pe_hdr)) != sizeof(pe_hdr) || > + read(in, &pe32_opt_hdr, sizeof(pe32_opt_hdr)) != > sizeof(pe32_opt_hdr) || > read(in, &base, sizeof(base)) != sizeof(base) || > /* > * Luckily the image size field lives at the > @@ -117,35 +65,33 @@ static unsigned int load(const char *name, int *handle, > perror(name); > exit(3); > } > - switch ( (pe_hdr.signature == PE_SIGNATURE && > - pe_hdr.opt_hdr_size > sizeof(pe_hdr.opt_hdr)) * > - pe_hdr.opt_hdr.magic ) > + switch ( (pe_hdr.magic == PE_MAGIC && > + pe_hdr.opt_hdr_size > sizeof(pe32_opt_hdr)) * > + pe32_opt_hdr.magic ) > { > - case PE_MAGIC_EXE32: > + case PE_OPT_MAGIC_PE32: > *width = 32; > *image_base = base; > break; > - case PE_MAGIC_EXE32PLUS: > + case PE_OPT_MAGIC_PE32PLUS: > *width = 64; > - *image_base = ((uint64_t)base << 32) | pe_hdr.opt_hdr.data_rva; > + *image_base = ((uint64_t)base << 32) | pe32_opt_hdr.data_base; > break; > default: > fprintf(stderr, "%s: Wrong PE file format\n", name); > exit(3); > } > > - *sections = malloc(pe_hdr.section_count * sizeof(**sections)); > + *sections = malloc(pe_hdr.sections * sizeof(**sections)); > if ( !*sections ) > { > perror(NULL); > exit(4); > } > - if ( lseek(in, > - mz_hdr.extended_header_base + offsetof(struct pe_hdr, > opt_hdr) + > - pe_hdr.opt_hdr_size, > + if ( lseek(in, mz_hdr.peaddr + sizeof(pe_hdr) + pe_hdr.opt_hdr_size, > SEEK_SET) < 0 || > - read(in, *sections, pe_hdr.section_count * sizeof(**sections)) != > - pe_hdr.section_count * sizeof(**sections) ) > + read(in, *sections, pe_hdr.sections * sizeof(**sections)) != > + pe_hdr.sections * sizeof(**sections) ) > { > perror(name); > exit(4); > @@ -153,12 +99,12 @@ static unsigned int load(const char *name, int *handle, > > *handle = in; > > - return pe_hdr.section_count; > + return pe_hdr.sections; > } > > static long page_size; > > -static const void *map_section(const struct coff_section *sec, int in, > +static const void *map_section(const struct section_header *sec, int in, > const char *name) > { > const char *ptr; > @@ -166,10 +112,10 @@ static const void *map_section(const struct > coff_section *sec, int in, > > if ( !page_size ) > page_size = sysconf(_SC_PAGESIZE); > - offs = sec->file_offset & (page_size - 1); > + offs = sec->data_addr & (page_size - 1); > > - ptr = mmap(0, offs + sec->file_size, PROT_READ, MAP_PRIVATE, in, > - sec->file_offset - offs); > + ptr = mmap(0, offs + sec->raw_data_size, PROT_READ, MAP_PRIVATE, in, > + sec->data_addr - offs); > if ( ptr == MAP_FAILED ) > { > perror(name); > @@ -179,15 +125,15 @@ static const void *map_section(const struct > coff_section *sec, int in, > return ptr + offs; > } > > -static void unmap_section(const void *ptr, const struct coff_section *sec) > +static void unmap_section(const void *ptr, const struct section_header *sec) > { > - unsigned long offs = sec->file_offset & (page_size - 1); > + unsigned long offs = sec->data_addr & (page_size - 1); > > - munmap((char *)ptr - offs, offs + sec->file_size); > + munmap((char *)ptr - offs, offs + sec->raw_data_size); > } > > static void diff_sections(const unsigned char *ptr1, const unsigned char > *ptr2, > - const struct coff_section *sec, > + const struct section_header *sec, > int_fast64_t diff, unsigned int width, > uint_fast64_t base, uint_fast64_t end) > { > @@ -208,7 +154,7 @@ static void diff_sections(const unsigned char *ptr1, > const unsigned char *ptr2, > while ( !(diff & (((int_fast64_t)1 << ((disp + 1) * CHAR_BIT)) - 1)) ) > ++disp; > > - for ( i = 0; i < sec->file_size; ++i ) > + for ( i = 0; i < sec->raw_data_size; ++i ) > { > uint_fast32_t rva; > union { > @@ -222,7 +168,7 @@ static void diff_sections(const unsigned char *ptr1, > const unsigned char *ptr2, > if ( ptr1[i] == ptr2[i] ) > continue; > > - if ( i < disp || i + width - disp > sec->file_size ) > + if ( i < disp || i + width - disp > sec->raw_data_size ) > { > fprintf(stderr, > "Bogus difference at %.8s:%08" PRIxFAST32 "\n", > @@ -250,11 +196,11 @@ static void diff_sections(const unsigned char *ptr1, > const unsigned char *ptr2, > reloc_size += reloc_size & 2; > if ( reloc_size ) > printf("\t.equ rva_%08" PRIxFAST32 "_relocs," > - " %#08" PRIxFAST32 "\n", > + " %#08" PRIxFAST32 "\n", > cur_rva, reloc_size); > printf("\t.balign 4\n" > "\t.long %#08" PRIxFAST32 "," > - " rva_%08" PRIxFAST32 "_relocs\n", > + " rva_%08" PRIxFAST32 "_relocs\n", > rva, rva); > cur_rva = rva; > reloc_size = 8; > @@ -267,7 +213,7 @@ static void diff_sections(const unsigned char *ptr1, > const unsigned char *ptr2, > exit(3); > } > > - if ( !(sec->flags & COFF_SECTION_WRITEABLE) ) > + if ( !(sec->flags & IMAGE_SCN_MEM_WRITE) ) > fprintf(stderr, > "Warning: relocation to r/o section %.8s:%08" PRIxFAST32 > "\n", > sec->name, i - disp); > @@ -285,7 +231,7 @@ int main(int argc, char *argv[]) > unsigned int i, nsec, width1, width2; > uint_fast64_t base1, base2; > uint32_t size1, size2; > - struct coff_section *sec1, *sec2; > + struct section_header *sec1, *sec2; > > if ( argc == 1 || > !strcmp(argv[1], "-?") || > @@ -328,16 +274,16 @@ int main(int argc, char *argv[]) > > if ( memcmp(sec1[i].name, sec2[i].name, sizeof(sec1[i].name)) || > sec1[i].rva != sec2[i].rva || > - sec1[i].size != sec2[i].size || > - sec1[i].file_size != sec2[i].file_size || > + sec1[i].virtual_size != sec2[i].virtual_size || > + sec1[i].raw_data_size != sec2[i].raw_data_size || > sec1[i].flags != sec2[i].flags ) > { > fprintf(stderr, "Mismatched section %u parameters\n", i); > return 5; > } > > - if ( !sec1[i].size || > - (sec1[i].flags & (COFF_SECTION_DISCARDABLE|COFF_SECTION_BSS)) ) > + if ( !sec1[i].virtual_size || > + (sec1[i].flags & (IMAGE_SCN_MEM_DISCARDABLE | > IMAGE_SCN_CNT_UNINITIALIZED_DATA)) ) > continue; > > /* > @@ -354,10 +300,10 @@ int main(int argc, char *argv[]) > return 3; > } > > - if ( sec1[i].file_size > sec1[i].size ) > + if ( sec1[i].raw_data_size > sec1[i].virtual_size ) > { > - sec1[i].file_size = sec1[i].size; > - sec2[i].file_size = sec2[i].size; > + sec1[i].raw_data_size = sec1[i].virtual_size; > + sec2[i].raw_data_size = sec2[i].virtual_size; > } > ptr1 = map_section(sec1 + i, in1, argv[1]); > ptr2 = map_section(sec2 + i, in2, argv[2]); > diff --git a/xen/common/efi/pe.c b/xen/common/efi/pe.c > index ef8a2543e0..560f35188d 100644 > --- a/xen/common/efi/pe.c > +++ b/xen/common/efi/pe.c > @@ -20,78 +20,28 @@ > * Lesser General Public License for more details. > */ > > - > #include "efi.h" > +#include "efi/pe.h" > > -struct DosFileHeader { > - UINT8 Magic[2]; > - UINT16 LastSize; > - UINT16 nBlocks; > - UINT16 nReloc; > - UINT16 HdrSize; > - UINT16 MinAlloc; > - UINT16 MaxAlloc; > - UINT16 ss; > - UINT16 sp; > - UINT16 Checksum; > - UINT16 ip; > - UINT16 cs; > - UINT16 RelocPos; > - UINT16 nOverlay; > - UINT16 reserved[4]; > - UINT16 OEMId; > - UINT16 OEMInfo; > - UINT16 reserved2[10]; > - UINT32 ExeHeader; > -}; > - > -#if defined(__arm__) || defined (__aarch64__) > -#define PE_HEADER_MACHINE 0xaa64 > +#if defined(__arm__) || defined(__aarch64__) > +#define PE_HEADER_MACHINE IMAGE_FILE_MACHINE_ARM64 > #elif defined(__x86_64__) > -#define PE_HEADER_MACHINE 0x8664 > +#define PE_HEADER_MACHINE IMAGE_FILE_MACHINE_AMD64 > #else > #error "Unknown architecture" > #endif > > -struct PeFileHeader { > - UINT16 Machine; > - UINT16 NumberOfSections; > - UINT32 TimeDateStamp; > - UINT32 PointerToSymbolTable; > - UINT32 NumberOfSymbols; > - UINT16 SizeOfOptionalHeader; > - UINT16 Characteristics; > -}; > - > -struct PeHeader { > - UINT8 Magic[4]; > - struct PeFileHeader FileHeader; > -}; > - > -struct PeSectionHeader { > - CHAR8 Name[8]; > - UINT32 VirtualSize; > - UINT32 VirtualAddress; > - UINT32 SizeOfRawData; > - UINT32 PointerToRawData; > - UINT32 PointerToRelocations; > - UINT32 PointerToLinenumbers; > - UINT16 NumberOfRelocations; > - UINT16 NumberOfLinenumbers; > - UINT32 Characteristics; > -}; > - > -static bool __init pe_name_compare(const struct PeSectionHeader *sect, > +static bool __init pe_name_compare(const struct section_header *sect, > const CHAR16 *name) > { > size_t i; > > - if ( sect->Name[0] != '.' ) > + if ( sect->name[0] != '.' ) > return false; > > - for ( i = 1; i < sizeof(sect->Name); i++ ) > + for ( i = 1; i < sizeof(sect->name); i++ ) > { > - const char c = sect->Name[i]; > + const char c = sect->name[i]; > > if ( c != name[i - 1] ) > return false; > @@ -105,33 +55,29 @@ static bool __init pe_name_compare(const struct > PeSectionHeader *sect, > const void *__init pe_find_section(const void *image, const UINTN image_size, > const CHAR16 *section_name, UINTN > *size_out) > { > - const struct DosFileHeader *dos = image; > - const struct PeHeader *pe; > - const struct PeSectionHeader *sect; > + const struct mz_hdr *mz = image; > + const struct pe_hdr *pe; > + const struct section_header *sect; > UINTN offset, i; > > - if ( image_size < sizeof(*dos) || > - dos->Magic[0] != 'M' || > - dos->Magic[1] != 'Z' ) > + if ( image_size < sizeof(*mz) || > + mz->magic != MZ_MAGIC ) > return NULL; > > - offset = dos->ExeHeader; > + offset = mz->peaddr; > pe = image + offset; > > offset += sizeof(*pe); > if ( image_size < offset || > - pe->Magic[0] != 'P' || > - pe->Magic[1] != 'E' || > - pe->Magic[2] != '\0' || > - pe->Magic[3] != '\0' ) > + pe->magic != PE_MAGIC ) > return NULL; > > - if ( pe->FileHeader.Machine != PE_HEADER_MACHINE ) > + if ( pe->machine != PE_HEADER_MACHINE ) > return NULL; > > - offset += pe->FileHeader.SizeOfOptionalHeader; > + offset += pe->opt_hdr_size; > > - for ( i = 0; i < pe->FileHeader.NumberOfSections; i++ ) > + for ( i = 0; i < pe->sections; i++ ) > { > sect = image + offset; > if ( image_size < offset + sizeof(*sect) ) > @@ -143,13 +89,13 @@ const void *__init pe_find_section(const void *image, > const UINTN image_size, > continue; > } > > - if ( image_size < sect->VirtualSize + sect->VirtualAddress ) > + if ( image_size < sect->virtual_size + sect->rva ) > blexit(L"PE invalid section size + address"); > > if ( size_out ) > - *size_out = sect->VirtualSize; > + *size_out = sect->virtual_size; > > - return image + sect->VirtualAddress; > + return image + sect->rva; > } > > return NULL; > -- > 2.25.1 >
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |