[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC 2/7] xen/x86: Manually build PE header
This is the first step to get: - one binary which can be loaded by the EFI loader, Multiboot and Multiboot2 protocols, - if we wish, in the future we can drop xen/xen.gz and build xen.efi only, - crash dumps generated by the xen.efi loaded from the EFI loader can be analyzed by crash tool, - simpler code, - simpler build, - Xen build will no longer depend on ld i386pep support. Signed-off-by: Daniel Kiper <daniel.kiper@xxxxxxxxxx> --- xen/arch/x86/Rules.mk | 2 + xen/arch/x86/boot/head.S | 145 ++++++++++++++++++++++++++++++++++++++++++++++ xen/arch/x86/xen.lds.S | 16 ++++- 3 files changed, 162 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk index 568657e..b501c88 100644 --- a/xen/arch/x86/Rules.mk +++ b/xen/arch/x86/Rules.mk @@ -7,6 +7,8 @@ CFLAGS += -I$(BASEDIR)/include CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-generic CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-default CFLAGS += -DXEN_IMG_OFFSET=$(XEN_IMG_OFFSET) +CFLAGS += -DXEN_LOAD_ALIGN=XEN_IMG_OFFSET +CFLAGS += -DXEN_FILE_ALIGN=PAGE_SIZE CFLAGS += '-D__OBJECT_LABEL__=$(subst /,$$,$(subst -,_,$(subst $(BASEDIR)/,,$(CURDIR))/$@))' # Prevent floating-point variables from creeping into Xen. diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index fd6fc33..28bbc04 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -1,3 +1,4 @@ +#include <xen/compile.h> #include <xen/multiboot.h> #include <xen/multiboot2.h> #include <public/xen.h> @@ -44,6 +45,150 @@ .Lmb2ht_init_end\@: .endm + .section .efi.pe.header, "a", @progbits + +ENTRY(efi_pe_head) + /* + * Legacy EXE header. + * + * Most of it is copied from binutils package, version 2.28, + * include/coff/pe.h:struct external_PEI_filehdr and + * bfd/peXXigen.c:_bfd_XXi_only_swap_filehdr_out(). + * + * Page is equal 512 bytes here. + * Paragraph is equal 16 bytes here. + */ + .short 0x5a4d /* EXE magic number. */ + .short 0x90 /* Bytes on last page of file. */ + .short 0x3 /* Pages in file. */ + .short 0 /* Relocations. */ + .short 0x4 /* Size of header in paragraphs. */ + .short 0 /* Minimum extra paragraphs needed. */ + .short 0xffff /* Maximum extra paragraphs needed. */ + .short 0 /* Initial (relative) SS value. */ + .short 0xb8 /* Initial SP value. */ + .short 0 /* Checksum. */ + .short 0 /* Initial IP value. */ + .short 0 /* Initial (relative) CS value. */ + .short 0x40 /* File address of relocation table. */ + .short 0 /* Overlay number. */ + .fill 4, 2, 0 /* Reserved words. */ + .short 0 /* OEM identifier. */ + .short 0 /* OEM information. */ + .fill 10, 2, 0 /* Reserved words. */ + .long pe_header - efi_pe_head /* File address of the PE header. */ + + /* + * DOS message. + * + * It is copied from binutils package, version 2.28, + * include/coff/pe.h:struct external_PEI_filehdr and + * bfd/peXXigen.c:_bfd_XXi_only_swap_filehdr_out(). + */ + .long 0x0eba1f0e + .long 0xcd09b400 + .long 0x4c01b821 + .long 0x685421cd + .long 0x70207369 + .long 0x72676f72 + .long 0x63206d61 + .long 0x6f6e6e61 + .long 0x65622074 + .long 0x6e757220 + .long 0x206e6920 + .long 0x20534f44 + .long 0x65646f6d + .long 0x0a0d0d2e + .long 0x24 + .long 0 + + /* + * PE/COFF header. + * + * The PE/COFF format is defined by Microsoft, and is available from + * http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx + * + * Some ideas are taken from Linux kernel and Xen ARM64. + */ + +pe_header: + .ascii "PE\0\0" /* PE signature. */ + .short 0x8664 /* Machine: IMAGE_FILE_MACHINE_AMD64. */ + .short 1 /* NumberOfSections. */ + .long XEN_COMPILE_POSIX_TIME /* TimeDateStamp. */ + .long 0 /* PointerToSymbolTable. */ + .long 0 /* NumberOfSymbols. */ + .short section_table - optional_header /* SizeOfOptionalHeader. */ + .short 0x226 /* Characteristics: + * IMAGE_FILE_EXECUTABLE_IMAGE | + * IMAGE_FILE_LARGE_ADDRESS_AWARE | + * IMAGE_FILE_DEBUG_STRIPPED | + * IMAGE_FILE_LINE_NUMS_STRIPPED + */ + +optional_header: + .short 0x20b /* PE format: PE32+ */ + .byte 0x02 /* MajorLinkerVersion. */ + .byte 0x14 /* MinorLinkerVersion. */ + .long __2M_rwdata_end - efi_pe_head_end /* SizeOfCode. */ + .long 0 /* SizeOfInitializedData. */ + .long 0 /* SizeOfUninitializedData. */ + .long sym_offs(efi_start) /* AddressOfEntryPoint. */ + .long sym_offs(start) /* BaseOfCode. */ + .quad sym_offs(__image_base__) /* ImageBase. */ + .long XEN_LOAD_ALIGN /* SectionAlignment. */ + .long XEN_FILE_ALIGN /* FileAlignment. */ + .short 2 /* MajorOperatingSystemVersion. */ + .short 0 /* MinorOperatingSystemVersion. */ + .short XEN_VERSION /* MajorImageVersion. */ + .short XEN_SUBVERSION /* MinorImageVersion. */ + .short 2 /* MajorSubsystemVersion. */ + .short 0 /* MinorSubsystemVersion. */ + .long 0 /* Win32VersionValue. */ + .long __pe_SizeOfImage /* SizeOfImage. */ + .long efi_pe_head_end - efi_pe_head /* SizeOfHeaders. */ + .long 0 /* CheckSum. */ + .short 0xa /* Subsystem: EFI application. */ + .short 0 /* DllCharacteristics. */ + .quad 0 /* SizeOfStackReserve. */ + .quad 0 /* SizeOfStackCommit. */ + .quad 0 /* SizeOfHeapReserve. */ + .quad 0 /* SizeOfHeapCommit. */ + .long 0 /* LoaderFlags. */ + .long 0x6 /* NumberOfRvaAndSizes. */ + + /* Data Directories. */ + .quad 0 /* Export Table. */ + .quad 0 /* Import Table. */ + .quad 0 /* Resource Table. */ + .quad 0 /* Exception Table. */ + .quad 0 /* Certificate Table. */ + .quad 0 /* Base Relocation Table. */ + +section_table: + .ascii ".text\0\0\0" /* Name. */ + .long __2M_rwdata_end - efi_pe_head_end /* VirtualSize. */ + .long sym_offs(start) /* VirtualAddress. */ + .long __bss_start - efi_pe_head_end /* SizeOfRawData. */ + .long efi_pe_head_end - efi_pe_head /* PointerToRawData. */ + .long 0 /* PointerToRelocations. */ + .long 0 /* PointerToLinenumbers. */ + .short 0 /* NumberOfRelocations. */ + .short 0 /* NumberOfLinenumbers. */ + .long 0xe0500020 /* Characteristics: + * IMAGE_SCN_CNT_CODE | + * IMAGE_SCN_ALIGN_16BYTES | + * IMAGE_SCN_MEM_EXECUTE | + * IMAGE_SCN_MEM_READ | + * IMAGE_SCN_MEM_WRITE + */ + + .align XEN_FILE_ALIGN +ENTRY(efi_pe_head_end) + + .text + .code32 + ENTRY(start) jmp __start diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S index 8289a1b..3c115b9 100644 --- a/xen/arch/x86/xen.lds.S +++ b/xen/arch/x86/xen.lds.S @@ -54,7 +54,12 @@ SECTIONS __2M_text_start = .; /* Start of 2M superpages, mapped RX. */ #endif - . = __XEN_VIRT_START + XEN_IMG_OFFSET; + . = __XEN_VIRT_START + XEN_IMG_OFFSET - efi_pe_head_end + efi_pe_head; + + .efi.pe.header : { + *(.efi.pe.header) + } :NONE + _start = .; .text : { _stext = .; /* Text and read-only data */ @@ -234,6 +239,8 @@ SECTIONS *(.data.rel) *(.data.rel.*) CONSTRUCTORS + /* PE file must end at XEN_FILE_ALIGN boundary. */ + . = ALIGN(XEN_FILE_ALIGN); } :text .bss : { /* BSS */ @@ -259,6 +266,8 @@ SECTIONS #endif __2M_rwdata_end = .; + __pe_SizeOfImage = ALIGN(. - __image_base__, XEN_LOAD_ALIGN); + #ifdef EFI . = ALIGN(4); .reloc : { @@ -337,3 +346,8 @@ ASSERT((trampoline_end - trampoline_start) < TRAMPOLINE_SPACE - MBI_SPACE_MIN, "not enough room for trampoline and mbi data") ASSERT((wakeup_stack - wakeup_stack_start) >= WAKEUP_STACK_MIN, "wakeup stack too small") + +ASSERT(efi_pe_head_end == _start, "PE header does not end at the beginning of .text section") +ASSERT(_start == __XEN_VIRT_START + XEN_IMG_OFFSET, ".text section begins at wrong address") +ASSERT(IS_ALIGNED(_start, XEN_FILE_ALIGN), "_start misaligned") +ASSERT(IS_ALIGNED(__bss_start, XEN_FILE_ALIGN), "__bss_start misaligned") -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |