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