Blob Blame History Raw
From 6744a7ef8eca44948565c3d1244ec931ed3f6fee Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Sun, 21 Sep 2014 13:11:11 -0400
Subject: [PATCH 61/74] Do the same for ia32...

Once again, on ia32 this time, we see:

00000120  47 84 00 00 0a 00 00 00  00 00 00 00 00 00 00 00 |G...............|

Which is where the pointer on ia32 for the Base Relocation Table should
be.  It points to 0x8447, which isn't a particularly reasonable address as
numbers go, and happens to have this data there:

00008440  6f 00 6e 00 66 00 69 00  67 00 75 00 72 00 65 00 |o.n.f.i.g.u.r.e.|
00008450  00 00 49 00 50 00 76 00  36 00 28 00 00 00 2c 00 |..I.P.v.6.(...,.|
00008460  25 00 73 00 2c 00 00 00  29 00 00 00 25 00 64 00 |%.s.,...)...%.d.|
00008470  2e 00 25 00 64 00 2e 00  25 00 64 00 2e 00 25 00 |..%.d...%.d...%.|
00008480  64 00 00 00 44 00 48 00  43 00 50 00 00 00 49 00 |d...D.H.C.P...I.|
00008490  50 00 76 00 34 00 28 00  00 00 2c 00 25 00 73 00 |P.v.4.(...,.%.s.|

And so that table is, in theory, this part:

00008447                       00  67 00 75 00 72 00 65 00 |       .g.u.r.e.|
00008450  00                                               |.               |

Which is pretty clearly not a pointer table of any kind.

So give ia32 the same treatment as x86_64, and now all arches work basically
the same.

Signed-off-by: Peter Jones <pjones@redhat.com>
---
 Makefile         |  22 +++++--
 crt0-efi-ia32.S  | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 elf_ia32_efi.lds |  83 ++++++++++++-------------
 3 files changed, 236 insertions(+), 49 deletions(-)
 create mode 100644 crt0-efi-ia32.S

diff --git a/Makefile b/Makefile
index d5fd55b..a52984f 100644
--- a/Makefile
+++ b/Makefile
@@ -6,19 +6,25 @@ ARCH		= $(shell $(CC) -dumpmachine | cut -f1 -d- | sed s,i[3456789]86,ia32,)
 
 SUBDIRS		= Cryptlib lib
 
-LIB_PATH	= /usr/lib64
-
 EFI_INCLUDE	:= /usr/include/efi
 EFI_INCLUDES	= -nostdinc -ICryptlib -ICryptlib/Include -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol -Iinclude
-EFI_PATH	:= /usr/lib64/gnuefi
+ifeq ($(ARCH),ia32)
+LIB_PATH	:= /usr/lib
+EFI_PATH	:= /usr/lib/gnuefi
+endif
+LIB_PATH	?= /usr/lib64
+EFI_PATH	?= /usr/lib64/gnuefi
 
 LIB_GCC		= $(shell $(CC) -print-libgcc-file-name)
 EFI_LIBS	= -lefi -lgnuefi --start-group Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a --end-group $(LIB_GCC) 
 
 ifeq ($(ARCH),x86_64)
 EFI_CRT_OBJS	:= crt0-efi-$(ARCH).o
-endif
+else ifeq ($(ARCH),ia32)
+EFI_CRT_OBJS	:= crt0-efi-$(ARCH).o
+else
 EFI_CRT_OBJS 	?= $(EFI_PATH)/crt0-efi-$(ARCH).o
+endif
 EFI_LDS		= elf_$(ARCH)_efi.lds
 
 DEFAULT_LOADER	:= \\\\grub.efi
@@ -137,9 +143,15 @@ SUBSYSTEM	:= 0xa
 LDFLAGS		+= --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
 endif
 
+ifeq ($(ARCH),ia32)
+FORMAT		:= -O binary
+SUBSYSTEM	:= 0xa
+LDFLAGS		+= --defsym=EFI_SUBSYSTEM=$(SUBSYSTEM)
+endif
+
 FORMAT		?= --target efi-app-$(ARCH)
 
-crt0-efi-x86_64.o : crt0-efi-x86_64.S
+crt0-efi-$(ARCH).o : crt0-efi-$(ARCH).S
 	$(CC) $(CFLAGS) -DEFI_SUBSYSTEM=$(SUBSYSTEM) -c -o $@ $<
 
 %.efi: %.so
diff --git a/crt0-efi-ia32.S b/crt0-efi-ia32.S
new file mode 100644
index 0000000..70b5b44
--- /dev/null
+++ b/crt0-efi-ia32.S
@@ -0,0 +1,180 @@
+/* crt0-efi-x86_64.S - x86_64 EFI startup code.
+ *
+ * Copyright 2014 Red Hat, Inc. <pjones@redhat.com>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+	.section	.text.head
+
+	/*
+	 * Magic "MZ" signature for PE/COFF
+	 */
+	.globl	ImageBase
+ImageBase:
+	.ascii	"MZ"
+	.skip	58				// 'MZ' + pad + offset == 64
+	.long	pe_header - ImageBase		// Offset to the PE header.
+	.long	0x0eba1f0e			/* terrifying code */
+	.long	0xcd09b400			/* terrifying code */
+	.long	0x4c01b821			/* terrifying code */
+	.short	0x21cd				/* terrfiying code */
+	.ascii	"The only winning move is not to play.\r\r\n$" /* DOS text */
+	.skip	9
+pe_header:
+	.ascii	"PE"
+	.short 	0
+coff_header:
+	.short	0x014c				// i386
+	.short	1				// nr_sections
+	.long	0 				// TimeDateStamp
+	.long	0				// PointerToSymbolTable
+	.long	0				// NumberOfSymbols
+	.short	section_table - optional_header	// SizeOfOptionalHeader
+	.short	0x306				// Characteristics.
+						// IMAGE_FILE_DEBUG_STRIPPED |
+						// IMAGE_FILE_EXECUTABLE_IMAGE |
+						// IMAGE_FILE_LINE_NUMS_STRIPPED
+						// | IMAGE_FILE_32BIT_MACHINE
+optional_header:
+	.short	0x10b				// PE32+ format
+	.byte	0x02				// MajorLinkerVersion
+	.byte	0x18				// MinorLinkerVersion
+	.long	_edata - _start			// SizeOfCode
+	.long	0				// SizeOfInitializedData
+	.long	0				// SizeOfUninitializedData
+	.long	_start - ImageBase		// AddressOfEntryPoint
+	.long	_start - ImageBase		// BaseOfCode
+	.long	0				// BaseOfData
+
+extra_header_fields:
+	.long	0				// ImageBase
+	.long	0x20				// SectionAlignment
+	.long	0x8				// FileAlignment
+	.short	0				// MajorOperatingSystemVersion
+	.short	0				// MinorOperatingSystemVersion
+	.short	0				// MajorImageVersion
+	.short	0				// MinorImageVersion
+	.short	0				// MajorSubsystemVersion
+	.short	0				// MinorSubsystemVersion
+	.long	0				// Win32VersionValue
+
+	.long	_edata - ImageBase		// SizeOfImage
+
+	// Everything before the kernel image is considered part of the header
+	.long	_start - ImageBase		// SizeOfHeaders
+	.long	0				// CheckSum
+	.short	EFI_SUBSYSTEM			// Subsystem
+	.short	0				// DllCharacteristics
+	.long	0				// SizeOfStackReserve
+	.long	0				// SizeOfStackCommit
+	.long	0				// SizeOfHeapReserve
+	.long	0				// SizeOfHeapCommit
+	.long	0				// LoaderFlags
+	.long	0x10				// NumberOfRvaAndSizes
+
+	.quad	0				// ExportTable
+	.quad	0				// ImportTable
+	.quad	0				// ResourceTable
+	.quad	0				// ExceptionTable
+	.quad	0				// CertificationTable
+	.quad	0				// BaseRelocationTable
+	.quad	0				// DebugTable
+	.quad	0				// ArchTable
+	.quad	0				// GlobalPointerTable
+	.quad	0				// .tls
+	.quad	0				// LoadConfigTable
+	.quad	0				// BoundImportsTable
+	.quad	0				// ImportAddressTable
+	.quad	0				// DelayLoadImportTable
+	.quad	0				// ClrRuntimeHeader (.cor)
+	.quad	0				// Reserved
+
+	// Section table
+section_table:
+	.ascii	".text"
+	.byte	0
+	.byte	0
+	.byte	0			// end of 0 padding of section name
+
+	.long	_edata - _start		// VirtualSize
+	.long	_start - ImageBase	// VirtualAddress
+	.long	_edata - _start		// SizeOfRawData
+	.long	_start - ImageBase	// PointerToRawData
+	.long	0		// PointerToRelocations (0 for executables)
+	.long	0		// PointerToLineNumbers (0 for executables)
+	.short	0		// NumberOfRelocations  (0 for executables)
+	.short	0		// NumberOfLineNumbers  (0 for executables)
+	.long	0x60500020	// Characteristics (section flags)
+
+	/*
+	 * The EFI application loader requires a relocation section
+	 * because EFI applications must be relocatable.  This is a
+	 * dummy section as far as we are concerned.
+	 */
+	.ascii	".reloc"
+	.byte	0
+	.byte	0			// end of 0 padding of section name
+
+	.long	0			// VirtualSize
+	.long	0			// VirtualAddress
+	.long	0			// SizeOfRawData
+	.long	0			// PointerToRawData
+	.long	0			// PointerToRelocations
+	.long	0			// PointerToLineNumbers
+	.short	0			// NumberOfRelocations
+	.short	0			// NumberOfLineNumbers
+	.long	0x42100040		// Characteristics (section flags)
+
+	/* most if not all ia32 binaries binutils makes seem to have .text
+	 * starting at 0x400; no reason to assume that's a bad idea. */
+	.align 1024
+
+_start:
+	pushl %ebp
+	movl %esp,%ebp
+
+	pushl 12(%ebp)			# copy "image" argument
+	pushl  8(%ebp)			# copy "systab" argument
+
+	call 0f
+0:	popl %eax
+	movl %eax,%ebx
+
+	addl $ImageBase-0b,%eax		# %eax = ldbase
+	addl $_DYNAMIC-0b,%ebx		# %ebx = _DYNAMIC
+
+	pushl %ebx			# pass _DYNAMIC as second argument
+	pushl %eax			# pass ldbase as first argument
+	call _relocate
+	popl %ebx
+	popl %ebx
+ 	testl %eax,%eax
+ 	jne .exit
+  
+  	call efi_main			# call app with "image" and "systab" argument
+
+.exit:
+	leave
+  	ret
diff --git a/elf_ia32_efi.lds b/elf_ia32_efi.lds
index 12d4085..b649e15 100644
--- a/elf_ia32_efi.lds
+++ b/elf_ia32_efi.lds
@@ -3,61 +3,56 @@ OUTPUT_ARCH(i386)
 ENTRY(_start)
 SECTIONS
 {
-  . = 0;
-  ImageBase = .;
-  .hash : { *(.hash) }	/* this MUST come first! */
-  . = ALIGN(4096);
-  .text :
-  {
-   *(.text)
-   *(.text.*)
-   *(.gnu.linkonce.t.*)
-  }
-  .reloc :
-  {
-   *(.reloc)
+  .text 0x0 : {
+    *(.text.head)
+    *(.text)
+    *(.text.*)
+    *(.gnu.linkonce.t.*)
+    *(.srodata)
+    *(.rodata*)
+    . = ALIGN(16);
+    _etext = .;
   }
-  . = ALIGN(4096);
+  .dynamic : { *(.dynamic) }
   .data :
   {
-   *(.rodata*)
-   *(.data)
-   *(.data1)
-   *(.data.*)
-   *(.sdata)
-   *(.got.plt)
-   *(.got)
-   /* the EFI loader doesn't seem to like a .bss section, so we stick
-      it all into .data: */
-   *(.sbss)
-   *(.scommon)
-   *(.dynbss)
-   *(.bss)
-   *(COMMON)
+    *(.sdata)
+    *(.data)
+    *(.data1)
+    *(.data.*)
+    *(.got.plt)
+    *(.got)
+
+    /* the EFI loader doesn't seem to like a .bss section, so we stick
+     * it all into .data: */
+    . = ALIGN(16);
+    _bss = .;
+    *(.sbss)
+    *(.scommon)
+    *(.dynbss)
+    *(.bss)
+    *(COMMON)
+    . = ALIGN(16);
+    _bss_end = .;
   }
   . = ALIGN(4096);
   .vendor_cert :
   {
-   *(.vendor_cert)
+    *(.vendor_cert)
   }
+
   . = ALIGN(4096);
-  .dynamic  : { *(.dynamic) }
-  . = ALIGN(4096);
-  .rel :
-  {
-    *(.rel.data)
-    *(.rel.data.*)
-    *(.rel.got)
-    *(.rel.stab)
-    *(.data.rel.ro.local)
-    *(.data.rel.local)
-    *(.data.rel.ro)
-    *(.data.rel*)
-  }
+  .rel.dyn : { *(.rel.dyn) }
+  .rel.plt : { *(.rel.plt) }
+  .rel.got : { *(.rel.got) }
+  .rel.data : { *(.rel.data) *(.rel.data*) }
+  _edata = .;
+  _data_size = . - _etext;
+
   . = ALIGN(4096);
-  .dynsym   : { *(.dynsym) }
+  .dynsym : { *(.dynsym) }
   . = ALIGN(4096);
-  .dynstr   : { *(.dynstr) }
+  .dynstr : { *(.dynstr) }
   . = ALIGN(4096);
   /DISCARD/ :
   {
-- 
1.9.3