xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Daniel Kiper <daniel.kiper@oracle.com>
To: xen-devel@lists.xenproject.org
Cc: andrew.cooper3@citrix.com, jbeulich@suse.com
Subject: [PATCH RFC 2/7] xen/x86: Manually build PE header
Date: Sat,  8 Jul 2017 23:53:17 +0200	[thread overview]
Message-ID: <1499550803-25664-3-git-send-email-daniel.kiper@oracle.com> (raw)
In-Reply-To: <1499550803-25664-1-git-send-email-daniel.kiper@oracle.com>

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@oracle.com>
---
 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@lists.xen.org
https://lists.xen.org/xen-devel

  parent reply	other threads:[~2017-07-08 21:53 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-08 21:53 [PATCH RFC 0/7] Change xen.efi build and add SHIM_LOCK verification into efi_multiboot2() Daniel Kiper
2017-07-08 21:53 ` [PATCH RFC 1/7] xen: Introduce XEN_COMPILE_POSIX_TIME Daniel Kiper
2018-04-30 15:56   ` Jan Beulich
2018-05-08 12:18     ` Daniel Kiper
2018-05-14 10:30       ` Jan Beulich
2018-05-14 16:25         ` Daniel Kiper
2018-05-15  7:47           ` Jan Beulich
2017-07-08 21:53 ` Daniel Kiper [this message]
2018-05-04 15:38   ` [PATCH RFC 2/7] xen/x86: Manually build PE header Jan Beulich
2018-05-08 12:47     ` Daniel Kiper
2018-05-14 10:40       ` Jan Beulich
2018-05-14 16:52         ` Daniel Kiper
2018-05-15  8:01           ` Jan Beulich
2017-07-08 21:53 ` [PATCH RFC 3/7] xen/x86: Add some addresses to the Multiboot header Daniel Kiper
2018-05-04 15:40   ` Jan Beulich
2018-05-08 13:01     ` Daniel Kiper
2017-07-08 21:53 ` [PATCH RFC 4/7] xen/x86: Add some addresses to the Multiboot2 header Daniel Kiper
2017-07-08 21:53 ` [PATCH RFC 5/7] efi: split out efi_shim_lock() Daniel Kiper
2017-07-08 21:53 ` [PATCH RFC 6/7] xen/x86/efi: Verify dom0 kernel with SHIM_LOCK protocol in efi_multiboot2() Daniel Kiper
2018-05-04 15:46   ` Jan Beulich
2018-05-08 13:09     ` Daniel Kiper
2018-05-14 10:43       ` Jan Beulich
2018-05-14 16:56         ` Daniel Kiper
2018-05-15  8:06           ` Jan Beulich
2017-07-08 21:53 ` [PATCH RFC 7/7] xen/x86: Build xen.mb.efi directly from xen-syms Daniel Kiper

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1499550803-25664-3-git-send-email-daniel.kiper@oracle.com \
    --to=daniel.kiper@oracle.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).