summaryrefslogtreecommitdiff
path: root/gnuefi
diff options
context:
space:
mode:
authorNigel Croxon <nigel.croxon@hp.com>2014-11-25 10:09:50 -0500
committerNigel Croxon <nigel.croxon@hp.com>2014-11-25 10:09:50 -0500
commit530d68ba191850edafc6da22cb2df55bec0c5fa5 (patch)
tree6752986507d3fc8ffc65085deedf11e7887a3d2a /gnuefi
parent00bd66ef46b59a1623a293491a8b2c65a6d61975 (diff)
downloadgnu-efi-530d68ba191850edafc6da22cb2df55bec0c5fa5.tar.gz
The gnu-efi-3.0 toplevel subdirectory is really annoying. Kill it.
Signed-off-by: Peter Jones <pjones@redhat.com> Signed-off-by: Nigel Croxon <nigel.croxon@hp.com>
Diffstat (limited to 'gnuefi')
-rw-r--r--gnuefi/Makefile75
-rw-r--r--gnuefi/crt0-efi-aarch64.S140
-rw-r--r--gnuefi/crt0-efi-arm.S138
-rw-r--r--gnuefi/crt0-efi-ia32.S76
-rw-r--r--gnuefi/crt0-efi-ia64.S87
-rw-r--r--gnuefi/crt0-efi-x86_64.S76
-rw-r--r--gnuefi/elf_aarch64_efi.lds57
-rw-r--r--gnuefi/elf_arm_efi.lds57
-rw-r--r--gnuefi/elf_ia32_efi.lds75
-rw-r--r--gnuefi/elf_ia32_fbsd_efi.lds75
-rw-r--r--gnuefi/elf_ia64_efi.lds70
-rw-r--r--gnuefi/elf_x86_64_efi.lds65
-rw-r--r--gnuefi/elf_x86_64_fbsd_efi.lds59
-rw-r--r--gnuefi/reloc_aarch64.c95
-rw-r--r--gnuefi/reloc_arm.c95
-rw-r--r--gnuefi/reloc_ia32.c97
-rw-r--r--gnuefi/reloc_ia64.S227
-rw-r--r--gnuefi/reloc_x86_64.c96
18 files changed, 1660 insertions, 0 deletions
diff --git a/gnuefi/Makefile b/gnuefi/Makefile
new file mode 100644
index 0000000..d234ac0
--- /dev/null
+++ b/gnuefi/Makefile
@@ -0,0 +1,75 @@
+#
+# Copyright (C) 1999-2001 Hewlett-Packard Co.
+# Contributed by David Mosberger <davidm@hpl.hp.com>
+# Contributed by Stephane Eranian <eranian@hpl.hp.com>
+#
+# All rights reserved.
+#
+# 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.
+# * Neither the name of Hewlett-Packard Co. nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# 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 OWNER OR CONTRIBUTORS
+# BE LIABLE FOR ANYDIRECT, 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.
+#
+
+SRCDIR = .
+
+VPATH = $(SRCDIR)
+
+include $(SRCDIR)/../Make.defaults
+
+TOPDIR = $(SRCDIR)/..
+
+CDIR=$(TOPDIR)/..
+FILES = reloc_$(ARCH)
+
+OBJS = $(FILES:%=%.o)
+
+# on aarch64, avoid jump tables before all relocations have been processed
+reloc_aarch64.o: CFLAGS += -fno-jump-tables
+
+TARGETS = crt0-efi-$(ARCH).o libgnuefi.a
+
+all: $(TARGETS)
+
+libgnuefi.a: $(patsubst %,libgnuefi.a(%),$(OBJS))
+
+clean:
+ rm -f $(TARGETS) *~ *.o $(OBJS)
+
+install:
+ mkdir -p $(INSTALLROOT)/$(LIBDIR)
+ $(INSTALL) -m 644 $(TARGETS) $(INSTALLROOT)/$(LIBDIR)
+ifneq (,$(findstring FreeBSD,$(OS)))
+ ifeq ($(ARCH),x86_64)
+ $(INSTALL) -m 644 elf_$(ARCH)_fbsd_efi.lds $(INSTALLROOT)/$(LIBDIR)
+ else
+ $(INSTALL) -m 644 elf_$(ARCH)_efi.lds $(INSTALLROOT)/$(LIBDIR)
+ endif
+else
+ $(INSTALL) -m 644 elf_$(ARCH)_efi.lds $(INSTALLROOT)/$(LIBDIR)
+endif
+
+include $(SRCDIR)/../Make.rules
diff --git a/gnuefi/crt0-efi-aarch64.S b/gnuefi/crt0-efi-aarch64.S
new file mode 100644
index 0000000..7a9e5c2
--- /dev/null
+++ b/gnuefi/crt0-efi-aarch64.S
@@ -0,0 +1,140 @@
+/*
+ * crt0-efi-aarch64.S - PE/COFF header for AArch64 EFI applications
+ *
+ * Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice and this list of conditions, without modification.
+ * 2. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License as published by the Free Software Foundation;
+ * either version 2 of the License, or (at your option) any later version.
+ */
+
+ .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.
+pe_header:
+ .ascii "PE"
+ .short 0
+coff_header:
+ .short 0xaa64 // AArch64
+ .short 2 // nr_sections
+ .long 0 // TimeDateStamp
+ .long 0 // PointerToSymbolTable
+ .long 1 // NumberOfSymbols
+ .short section_table - optional_header // SizeOfOptionalHeader
+ .short 0x206 // Characteristics.
+ // IMAGE_FILE_DEBUG_STRIPPED |
+ // IMAGE_FILE_EXECUTABLE_IMAGE |
+ // IMAGE_FILE_LINE_NUMS_STRIPPED
+optional_header:
+ .short 0x20b // PE32+ format
+ .byte 0x02 // MajorLinkerVersion
+ .byte 0x14 // MinorLinkerVersion
+ .long _edata - _start // SizeOfCode
+ .long 0 // SizeOfInitializedData
+ .long 0 // SizeOfUninitializedData
+ .long _start - ImageBase // AddressOfEntryPoint
+ .long _start - ImageBase // BaseOfCode
+
+extra_header_fields:
+ .quad 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
+ .quad 0 // SizeOfStackReserve
+ .quad 0 // SizeOfStackCommit
+ .quad 0 // SizeOfHeapReserve
+ .quad 0 // SizeOfHeapCommit
+ .long 0 // LoaderFlags
+ .long 0x6 // NumberOfRvaAndSizes
+
+ .quad 0 // ExportTable
+ .quad 0 // ImportTable
+ .quad 0 // ResourceTable
+ .quad 0 // ExceptionTable
+ .quad 0 // CertificationTable
+ .quad 0 // BaseRelocationTable
+
+ // Section table
+section_table:
+
+ /*
+ * 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
+ .long 0
+ .long 0 // SizeOfRawData
+ .long 0 // PointerToRawData
+ .long 0 // PointerToRelocations
+ .long 0 // PointerToLineNumbers
+ .short 0 // NumberOfRelocations
+ .short 0 // NumberOfLineNumbers
+ .long 0x42100040 // Characteristics (section flags)
+
+
+ .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 0xe0500020 // Characteristics (section flags)
+
+_start:
+ stp x29, x30, [sp, #-32]!
+ mov x29, sp
+
+ stp x0, x1, [sp, #16]
+ mov x2, x0
+ mov x3, x1
+ adr x0, ImageBase
+ adrp x1, _DYNAMIC
+ add x1, x1, #:lo12:_DYNAMIC
+ bl _relocate
+ cbnz x0, 0f
+
+ ldp x0, x1, [sp, #16]
+ bl efi_main
+
+0: ldp x29, x30, [sp], #32
+ ret
diff --git a/gnuefi/crt0-efi-arm.S b/gnuefi/crt0-efi-arm.S
new file mode 100644
index 0000000..3efaf78
--- /dev/null
+++ b/gnuefi/crt0-efi-arm.S
@@ -0,0 +1,138 @@
+/*
+ * crt0-efi-arm.S - PE/COFF header for ARM EFI applications
+ *
+ * Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+ .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.
+pe_header:
+ .ascii "PE"
+ .short 0
+coff_header:
+ .short 0x1c2 // Mixed ARM/Thumb
+ .short 2 // nr_sections
+ .long 0 // TimeDateStamp
+ .long 0 // PointerToSymbolTable
+ .long 1 // NumberOfSymbols
+ .short section_table - optional_header // SizeOfOptionalHeader
+ .short 0x306 // Characteristics.
+ // IMAGE_FILE_32BIT_MACHINE |
+ // IMAGE_FILE_DEBUG_STRIPPED |
+ // IMAGE_FILE_EXECUTABLE_IMAGE |
+ // IMAGE_FILE_LINE_NUMS_STRIPPED
+optional_header:
+ .short 0x10b // PE32+ format
+ .byte 0x02 // MajorLinkerVersion
+ .byte 0x14 // 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 0x6 // NumberOfRvaAndSizes
+
+ .quad 0 // ExportTable
+ .quad 0 // ImportTable
+ .quad 0 // ResourceTable
+ .quad 0 // ExceptionTable
+ .quad 0 // CertificationTable
+ .quad 0 // BaseRelocationTable
+
+ // Section table
+section_table:
+
+ /*
+ * 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
+ .long 0
+ .long 0 // SizeOfRawData
+ .long 0 // PointerToRawData
+ .long 0 // PointerToRelocations
+ .long 0 // PointerToLineNumbers
+ .short 0 // NumberOfRelocations
+ .short 0 // NumberOfLineNumbers
+ .long 0x42100040 // Characteristics (section flags)
+
+
+ .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 0xe0500020 // Characteristics (section flags)
+
+_start:
+ stmfd sp!, {r0-r2, lr}
+
+ mov r2, r0
+ mov r3, r1
+ adr r1, .L_DYNAMIC
+ ldr r0, [r1]
+ add r1, r0, r1
+ adr r0, ImageBase
+ bl _relocate
+ teq r0, #0
+ bne 0f
+
+ ldmfd sp, {r0-r1}
+ bl efi_main
+
+0: add sp, sp, #12
+ ldr pc, [sp], #4
+
+.L_DYNAMIC:
+ .word _DYNAMIC - .
diff --git a/gnuefi/crt0-efi-ia32.S b/gnuefi/crt0-efi-ia32.S
new file mode 100644
index 0000000..f9d5191
--- /dev/null
+++ b/gnuefi/crt0-efi-ia32.S
@@ -0,0 +1,76 @@
+/* crt0-efi-ia32.S - x86 EFI startup code.
+ Copyright (C) 1999 Hewlett-Packard Co.
+ Contributed by David Mosberger <davidm@hpl.hp.com>.
+
+ All rights reserved.
+
+ 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.
+ * Neither the name of Hewlett-Packard Co. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ 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 OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANYDIRECT, 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.
+*/
+
+ .text
+ .align 4
+
+ .globl _start
+_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
+
+ // hand-craft a dummy .reloc section so EFI knows it's a relocatable executable:
+
+ .data
+dummy: .long 0
+
+#define IMAGE_REL_ABSOLUTE 0
+ .section .reloc
+ .long dummy // Page RVA
+ .long 10 // Block Size (2*4+2)
+ .word (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy
diff --git a/gnuefi/crt0-efi-ia64.S b/gnuefi/crt0-efi-ia64.S
new file mode 100644
index 0000000..40c3c83
--- /dev/null
+++ b/gnuefi/crt0-efi-ia64.S
@@ -0,0 +1,87 @@
+/* crt0-efi-ia64.S - IA-64 EFI startup code.
+ Copyright (C) 1999 Hewlett-Packard Co.
+ Contributed by David Mosberger <davidm@hpl.hp.com>.
+
+ All rights reserved.
+
+ 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.
+ * Neither the name of Hewlett-Packard Co. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ 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 OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANYDIRECT, 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.
+*/
+ .text
+ .psr abi64
+ .psr lsb
+ .lsb
+
+ .proc _start
+_start:
+ alloc loc0=ar.pfs,2,2,2,0
+ mov loc1=rp
+ movl out0=@gprel(ImageBase) // out0 <- ImageBase (ldbase)
+ ;;
+ add out0=out0,gp
+ movl out1=@gprel(_DYNAMIC) // out1 <- _DYNAMIC
+ ;; // avoid WAW on CFM
+ add out1=out1,gp
+ br.call.sptk.few rp=_relocate
+.Lret0:
+ cmp.ne p6,p0=r0,r8 // r8 == EFI_SUCCESS?
+(p6) br.cond.sptk.few .exit // no ->
+
+.Lret1:
+
+ mov out0=in0 // image handle
+ mov out1=in1 // systab
+ br.call.sptk.few rp=efi_main
+.Lret2:
+.exit:
+ mov ar.pfs=loc0
+ mov rp=loc1
+ ;;
+ br.ret.sptk.few rp
+
+ .endp _start
+
+
+ // PE32+ wants a PLABEL, not the code address of the entry point:
+
+ .align 16
+ .global _start_plabel
+ .section .plabel, "a"
+_start_plabel:
+ data8 _start
+ data8 __gp
+
+ // hand-craft a .reloc section for the plabel:
+
+#define IMAGE_REL_BASED_DIR64 10
+
+ .section .reloc, "a"
+ data4 _start_plabel // Page RVA
+ data4 12 // Block Size (2*4+2*2)
+ data2 (IMAGE_REL_BASED_DIR64<<12) + 0 // reloc for plabel's entry point
+ data2 (IMAGE_REL_BASED_DIR64<<12) + 8 // reloc for plabel's global pointer
diff --git a/gnuefi/crt0-efi-x86_64.S b/gnuefi/crt0-efi-x86_64.S
new file mode 100644
index 0000000..6839150
--- /dev/null
+++ b/gnuefi/crt0-efi-x86_64.S
@@ -0,0 +1,76 @@
+/* crt0-efi-x86_64.S - x86_64 EFI startup code.
+ Copyright (C) 1999 Hewlett-Packard Co.
+ Contributed by David Mosberger <davidm@hpl.hp.com>.
+ Copyright (C) 2005 Intel Co.
+ Contributed by Fenghua Yu <fenghua.yu@intel.com>.
+
+ All rights reserved.
+
+ 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.
+ * Neither the name of Hewlett-Packard Co. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ 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 OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANYDIRECT, 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.
+*/
+ .text
+ .align 4
+
+ .globl _start
+_start:
+ subq $8, %rsp
+ pushq %rcx
+ pushq %rdx
+
+0:
+ lea ImageBase(%rip), %rdi
+ lea _DYNAMIC(%rip), %rsi
+
+ popq %rcx
+ popq %rdx
+ pushq %rcx
+ pushq %rdx
+ call _relocate
+
+ popq %rdi
+ popq %rsi
+
+ call efi_main
+ addq $8, %rsp
+
+.exit:
+ ret
+
+ // hand-craft a dummy .reloc section so EFI knows it's a relocatable executable:
+
+ .data
+dummy: .long 0
+
+#define IMAGE_REL_ABSOLUTE 0
+ .section .reloc, "a"
+label1:
+ .long dummy-label1 // Page RVA
+ .long 10 // Block Size (2*4+2)
+ .word (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy
+
diff --git a/gnuefi/elf_aarch64_efi.lds b/gnuefi/elf_aarch64_efi.lds
new file mode 100644
index 0000000..0fdb1f6
--- /dev/null
+++ b/gnuefi/elf_aarch64_efi.lds
@@ -0,0 +1,57 @@
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+ .text 0x0 : {
+ *(.text.head)
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t.*)
+ *(.srodata)
+ *(.rodata*)
+ . = ALIGN(16);
+ _etext = .;
+ }
+ .dynamic : { *(.dynamic) }
+ .data :
+ {
+ *(.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 = .;
+ }
+ .rela.dyn : { *(.rela.dyn) }
+ .rela.plt : { *(.rela.plt) }
+ .rela.got : { *(.rela.got) }
+ .rela.data : { *(.rela.data) *(.rela.data*) }
+ _edata = .;
+ _data_size = . - _etext;
+
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+ . = ALIGN(4096);
+ /DISCARD/ :
+ {
+ *(.rel.reloc)
+ *(.eh_frame)
+ *(.note.GNU-stack)
+ }
+ .comment 0 : { *(.comment) }
+}
diff --git a/gnuefi/elf_arm_efi.lds b/gnuefi/elf_arm_efi.lds
new file mode 100644
index 0000000..1bd6b78
--- /dev/null
+++ b/gnuefi/elf_arm_efi.lds
@@ -0,0 +1,57 @@
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ .text 0x0 : {
+ *(.text.head)
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t.*)
+ *(.srodata)
+ *(.rodata*)
+ . = ALIGN(16);
+ _etext = .;
+ }
+ .dynamic : { *(.dynamic) }
+ .data :
+ {
+ *(.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 = .;
+ }
+ .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) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+ . = ALIGN(4096);
+ /DISCARD/ :
+ {
+ *(.rel.reloc)
+ *(.eh_frame)
+ *(.note.GNU-stack)
+ }
+ .comment 0 : { *(.comment) }
+}
diff --git a/gnuefi/elf_ia32_efi.lds b/gnuefi/elf_ia32_efi.lds
new file mode 100644
index 0000000..975e36c
--- /dev/null
+++ b/gnuefi/elf_ia32_efi.lds
@@ -0,0 +1,75 @@
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0;
+ ImageBase = .;
+ .hash : { *(.hash) } /* this MUST come first! */
+ . = ALIGN(4096);
+ .text :
+ {
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t.*)
+ }
+ . = ALIGN(4096);
+ .sdata :
+ {
+ *(.got.plt)
+ *(.got)
+ *(.srodata)
+ *(.sdata)
+ *(.sbss)
+ *(.scommon)
+ }
+ . = ALIGN(4096);
+ .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)
+ }
+ . = 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*)
+ }
+ . = ALIGN(4096);
+ .reloc : /* This is the PECOFF .reloc section! */
+ {
+ *(.reloc)
+ }
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+ . = ALIGN(4096);
+ /DISCARD/ :
+ {
+ *(.rel.reloc)
+ *(.eh_frame)
+ *(.note.GNU-stack)
+ }
+ .comment 0 : { *(.comment) }
+}
diff --git a/gnuefi/elf_ia32_fbsd_efi.lds b/gnuefi/elf_ia32_fbsd_efi.lds
new file mode 100644
index 0000000..bc25b1f
--- /dev/null
+++ b/gnuefi/elf_ia32_fbsd_efi.lds
@@ -0,0 +1,75 @@
+OUTPUT_FORMAT("elf32-i386-freebsd", "elf32-i386-freebsd", "elf32-i386-freebsd")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0;
+ ImageBase = .;
+ .hash : { *(.hash) } /* this MUST come first! */
+ . = ALIGN(4096);
+ .text :
+ {
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t.*)
+ }
+ . = ALIGN(4096);
+ .sdata :
+ {
+ *(.got.plt)
+ *(.got)
+ *(.srodata)
+ *(.sdata)
+ *(.sbss)
+ *(.scommon)
+ }
+ . = ALIGN(4096);
+ .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)
+ }
+ . = 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*)
+ }
+ . = ALIGN(4096);
+ .reloc : /* This is the PECOFF .reloc section! */
+ {
+ *(.reloc)
+ }
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+ . = ALIGN(4096);
+ /DISCARD/ :
+ {
+ *(.rel.reloc)
+ *(.eh_frame)
+ *(.note.GNU-stack)
+ }
+ .comment 0 : { *(.comment) }
+}
diff --git a/gnuefi/elf_ia64_efi.lds b/gnuefi/elf_ia64_efi.lds
new file mode 100644
index 0000000..1d9ffc1
--- /dev/null
+++ b/gnuefi/elf_ia64_efi.lds
@@ -0,0 +1,70 @@
+OUTPUT_FORMAT("elf64-ia64-little")
+OUTPUT_ARCH(ia64)
+ENTRY(_start_plabel)
+SECTIONS
+{
+ . = 0;
+ ImageBase = .;
+ .hash : { *(.hash) } /* this MUST come first! */
+ . = ALIGN(4096);
+ .text :
+ {
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t.*)
+ }
+ . = ALIGN(4096);
+ __gp = ALIGN (8) + 0x200000;
+ .sdata :
+ {
+ *(.got.plt)
+ *(.got)
+ *(.srodata)
+ *(.sdata)
+ *(.sbss)
+ *(.scommon)
+ }
+ . = ALIGN(4096);
+ .data :
+ {
+ *(.rodata*)
+ *(.ctors)
+ *(.data*)
+ *(.gnu.linkonce.d*)
+ *(.plabel) /* data whose relocs we want to ignore */
+ /* the EFI loader doesn't seem to like a .bss section, so we stick
+ it all into .data: */
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ . = ALIGN(4096);
+ .dynamic : { *(.dynamic) }
+ . = ALIGN(4096);
+ .rela :
+ {
+ *(.rela.text)
+ *(.rela.data*)
+ *(.rela.sdata)
+ *(.rela.got)
+ *(.rela.gnu.linkonce.d*)
+ *(.rela.stab)
+ *(.rela.ctors)
+ }
+ . = ALIGN(4096);
+ .reloc : /* This is the PECOFF .reloc section! */
+ {
+ *(.reloc)
+ }
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+ /DISCARD/ :
+ {
+ *(.rela.plabel)
+ *(.rela.reloc)
+ *(.IA_64.unwind*)
+ *(.IA64.unwind*)
+ }
+}
diff --git a/gnuefi/elf_x86_64_efi.lds b/gnuefi/elf_x86_64_efi.lds
new file mode 100644
index 0000000..c4df0a5
--- /dev/null
+++ b/gnuefi/elf_x86_64_efi.lds
@@ -0,0 +1,65 @@
+/* Same as elf_x86_64_fbsd_efi.lds, except for OUTPUT_FORMAT below - KEEP IN SYNC */
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0;
+ ImageBase = .;
+ .hash : { *(.hash) } /* this MUST come first! */
+ . = ALIGN(4096);
+ .eh_frame :
+ {
+ *(.eh_frame)
+ }
+ . = ALIGN(4096);
+ .text :
+ {
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t.*)
+ }
+ . = ALIGN(4096);
+ .reloc :
+ {
+ *(.reloc)
+ }
+ . = ALIGN(4096);
+ .data :
+ {
+ *(.rodata*)
+ *(.got.plt)
+ *(.got)
+ *(.data*)
+ *(.sdata)
+ /* the EFI loader doesn't seem to like a .bss section, so we stick
+ it all into .data: */
+ *(.sbss)
+ *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ *(.rel.local)
+ }
+ . = ALIGN(4096);
+ .dynamic : { *(.dynamic) }
+ . = ALIGN(4096);
+ .rela :
+ {
+ *(.rela.data*)
+ *(.rela.got)
+ *(.rela.stab)
+ }
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+ . = ALIGN(4096);
+ .ignored.reloc :
+ {
+ *(.rela.reloc)
+ *(.eh_frame)
+ *(.note.GNU-stack)
+ }
+ .comment 0 : { *(.comment) }
+}
diff --git a/gnuefi/elf_x86_64_fbsd_efi.lds b/gnuefi/elf_x86_64_fbsd_efi.lds
new file mode 100644
index 0000000..2c64609
--- /dev/null
+++ b/gnuefi/elf_x86_64_fbsd_efi.lds
@@ -0,0 +1,59 @@
+/* Same as elf_x86_64_efi.lds, except for OUTPUT_FORMAT below - KEEP IN SYNC */
+OUTPUT_FORMAT("elf64-x86-64-freebsd", "elf64-x86-64-freebsd", "elf64-x86-64-freebsd")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0;
+ ImageBase = .;
+ .hash : { *(.hash) } /* this MUST come first! */
+ . = ALIGN(4096);
+ .eh_frame :
+ {
+ *(.eh_frame)
+ }
+ . = ALIGN(4096);
+ .text :
+ {
+ *(.text)
+ }
+ .reloc :
+ {
+ *(.reloc)
+ }
+ . = ALIGN(4096);
+ .data :
+ {
+ *(.rodata*)
+ *(.got.plt)
+ *(.got)
+ *(.data*)
+ *(.sdata)
+ /* the EFI loader doesn't seem to like a .bss section, so we stick
+ it all into .data: */
+ *(.sbss)
+ *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ *(.rel.local)
+ }
+ . = ALIGN(4096);
+ .dynamic : { *(.dynamic) }
+ . = ALIGN(4096);
+ .rela :
+ {
+ *(.rela.data*)
+ *(.rela.got)
+ *(.rela.stab)
+ }
+ . = ALIGN(4096);
+ .dynsym : { *(.dynsym) }
+ . = ALIGN(4096);
+ .dynstr : { *(.dynstr) }
+ . = ALIGN(4096);
+ .ignored.reloc :
+ {
+ *(.rela.reloc)
+ }
+}
diff --git a/gnuefi/reloc_aarch64.c b/gnuefi/reloc_aarch64.c
new file mode 100644
index 0000000..ed0249e
--- /dev/null
+++ b/gnuefi/reloc_aarch64.c
@@ -0,0 +1,95 @@
+/* reloc_aarch64.c - position independent x86 ELF shared object relocator
+ Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ Copyright (C) 1999 Hewlett-Packard Co.
+ Contributed by David Mosberger <davidm@hpl.hp.com>.
+
+ All rights reserved.
+
+ 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.
+ * Neither the name of Hewlett-Packard Co. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ 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 OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANYDIRECT, 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.
+*/
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <elf.h>
+
+EFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn, EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
+{
+ long relsz = 0, relent = 0;
+ Elf64_Rela *rel = 0;
+ unsigned long *addr;
+ int i;
+
+ for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
+ switch (dyn[i].d_tag) {
+ case DT_RELA:
+ rel = (Elf64_Rela*)
+ ((unsigned long)dyn[i].d_un.d_ptr
+ + ldbase);
+ break;
+
+ case DT_RELASZ:
+ relsz = dyn[i].d_un.d_val;
+ break;
+
+ case DT_RELAENT:
+ relent = dyn[i].d_un.d_val;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!rel && relent == 0)
+ return EFI_SUCCESS;
+
+ if (!rel || relent == 0)
+ return EFI_LOAD_ERROR;
+
+ while (relsz > 0) {
+ /* apply the relocs */
+ switch (ELF64_R_TYPE (rel->r_info)) {
+ case R_AARCH64_NONE:
+ break;
+
+ case R_AARCH64_RELATIVE:
+ addr = (unsigned long *)
+ (ldbase + rel->r_offset);
+ *addr = ldbase + rel->r_addend;
+ break;
+
+ default:
+ break;
+ }
+ rel = (Elf64_Rela*) ((char *) rel + relent);
+ relsz -= relent;
+ }
+ return EFI_SUCCESS;
+}
diff --git a/gnuefi/reloc_arm.c b/gnuefi/reloc_arm.c
new file mode 100644
index 0000000..d5fa858
--- /dev/null
+++ b/gnuefi/reloc_arm.c
@@ -0,0 +1,95 @@
+/* reloc_arm.c - position independent x86 ELF shared object relocator
+ Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
+ Copyright (C) 1999 Hewlett-Packard Co.
+ Contributed by David Mosberger <davidm@hpl.hp.com>.
+
+ All rights reserved.
+
+ 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.
+ * Neither the name of Hewlett-Packard Co. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ 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 OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANYDIRECT, 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.
+*/
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <elf.h>
+
+EFI_STATUS _relocate (long ldbase, Elf32_Dyn *dyn, EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
+{
+ long relsz = 0, relent = 0;
+ Elf32_Rel *rel = 0;
+ unsigned long *addr;
+ int i;
+
+ for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
+ switch (dyn[i].d_tag) {
+ case DT_REL:
+ rel = (Elf32_Rel*)
+ ((unsigned long)dyn[i].d_un.d_ptr
+ + ldbase);
+ break;
+
+ case DT_RELSZ:
+ relsz = dyn[i].d_un.d_val;
+ break;
+
+ case DT_RELENT:
+ relent = dyn[i].d_un.d_val;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!rel && relent == 0)
+ return EFI_SUCCESS;
+
+ if (!rel || relent == 0)
+ return EFI_LOAD_ERROR;
+
+ while (relsz > 0) {
+ /* apply the relocs */
+ switch (ELF32_R_TYPE (rel->r_info)) {
+ case R_ARM_NONE:
+ break;
+
+ case R_ARM_RELATIVE:
+ addr = (unsigned long *)
+ (ldbase + rel->r_offset);
+ *addr += ldbase;
+ break;
+
+ default:
+ break;
+ }
+ rel = (Elf32_Rel*) ((char *) rel + relent);
+ relsz -= relent;
+ }
+ return EFI_SUCCESS;
+}
diff --git a/gnuefi/reloc_ia32.c b/gnuefi/reloc_ia32.c
new file mode 100644
index 0000000..8d50a75
--- /dev/null
+++ b/gnuefi/reloc_ia32.c
@@ -0,0 +1,97 @@
+/* reloc_ia32.c - position independent x86 ELF shared object relocator
+ Copyright (C) 1999 Hewlett-Packard Co.
+ Contributed by David Mosberger <davidm@hpl.hp.com>.
+
+ All rights reserved.
+
+ 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.
+ * Neither the name of Hewlett-Packard Co. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ 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 OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANYDIRECT, 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.
+*/
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <elf.h>
+
+EFI_STATUS _relocate (long ldbase, Elf32_Dyn *dyn, EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
+{
+ long relsz = 0, relent = 0;
+ Elf32_Rel *rel = 0;
+ unsigned long *addr;
+ int i;
+
+ for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
+ switch (dyn[i].d_tag) {
+ case DT_REL:
+ rel = (Elf32_Rel*)
+ ((unsigned long)dyn[i].d_un.d_ptr
+ + ldbase);
+ break;
+
+ case DT_RELSZ:
+ relsz = dyn[i].d_un.d_val;
+ break;
+
+ case DT_RELENT:
+ relent = dyn[i].d_un.d_val;
+ break;
+
+ case DT_RELA:
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!rel && relent == 0)
+ return EFI_SUCCESS;
+
+ if (!rel || relent == 0)
+ return EFI_LOAD_ERROR;
+
+ while (relsz > 0) {
+ /* apply the relocs */
+ switch (ELF32_R_TYPE (rel->r_info)) {
+ case R_386_NONE:
+ break;
+
+ case R_386_RELATIVE:
+ addr = (unsigned long *)
+ (ldbase + rel->r_offset);
+ *addr += ldbase;
+ break;
+
+ default:
+ break;
+ }
+ rel = (Elf32_Rel*) ((char *) rel + relent);
+ relsz -= relent;
+ }
+ return EFI_SUCCESS;
+}
diff --git a/gnuefi/reloc_ia64.S b/gnuefi/reloc_ia64.S
new file mode 100644
index 0000000..40203bf
--- /dev/null
+++ b/gnuefi/reloc_ia64.S
@@ -0,0 +1,227 @@
+/* reloc_ia64.S - position independent IA-64 ELF shared object relocator
+ Copyright (C) 1999 Hewlett-Packard Co.
+ Contributed by David Mosberger <davidm@hpl.hp.com>.
+
+ All rights reserved.
+
+ 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.
+ * Neither the name of Hewlett-Packard Co. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ 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 OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANYDIRECT, 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.
+*/
+
+/*
+ * This is written in assembly because the entire code needs to be position
+ * independent. Note that the compiler does not generate code that's position
+ * independent by itself because it relies on the global offset table being
+ * relocated.
+ */
+ .text
+ .psr abi64
+ .psr lsb
+ .lsb
+
+/*
+ * This constant determines how many R_IA64_FPTR64LSB relocations we
+ * can deal with. If you get EFI_BUFFER_TOO_SMALL errors, you may
+ * need to increase this number.
+ */
+#define MAX_FUNCTION_DESCRIPTORS 750
+
+#define ST_VALUE_OFF 8 /* offset of st_value in elf sym */
+
+#define EFI_SUCCESS 0
+#define EFI_LOAD_ERROR 1
+#define EFI_BUFFER_TOO_SMALL 5
+
+#define DT_NULL 0 /* Marks end of dynamic section */
+#define DT_RELA 7 /* Address of Rela relocs */
+#define DT_RELASZ 8 /* Total size of Rela relocs */
+#define DT_RELAENT 9 /* Size of one Rela reloc */
+#define DT_SYMTAB 6 /* Address of symbol table */
+#define DT_SYMENT 11 /* Size of one symbol table entry */
+
+#define R_IA64_NONE 0
+#define R_IA64_REL64MSB 0x6e
+#define R_IA64_REL64LSB 0x6f
+#define R_IA64_DIR64MSB 0x26
+#define R_IA64_DIR64LSB 0x27
+#define R_IA64_FPTR64MSB 0x46
+#define R_IA64_FPTR64LSB 0x47
+
+#define ldbase in0 /* load address (address of .text) */
+#define dyn in1 /* address of _DYNAMIC */
+
+#define d_tag r16
+#define d_val r17
+#define rela r18
+#define relasz r19
+#define relaent r20
+#define addr r21
+#define r_info r22
+#define r_offset r23
+#define r_addend r24
+#define r_type r25
+#define r_sym r25 /* alias of r_type ! */
+#define fptr r26
+#define fptr_limit r27
+#define symtab f8
+#define syment f9
+#define ftmp f10
+
+#define target r16
+#define val r17
+
+#define NLOC 0
+
+#define Pnull p6
+#define Prela p7
+#define Prelasz p8
+#define Prelaent p9
+#define Psymtab p10
+#define Psyment p11
+
+#define Pnone p6
+#define Prel p7
+#define Pfptr p8
+
+#define Pmore p6
+
+#define Poom p6 /* out-of-memory */
+
+ .global _relocate
+ .proc _relocate
+_relocate:
+ alloc r2=ar.pfs,2,0,0,0
+ movl fptr = @gprel(fptr_mem_base)
+ ;;
+ add fptr = fptr, gp
+ movl fptr_limit = @gprel(fptr_mem_limit)
+ ;;
+ add fptr_limit = fptr_limit, gp
+
+search_dynamic:
+ ld8 d_tag = [dyn],8
+ ;;
+ ld8 d_val = [dyn],8
+ cmp.eq Pnull,p0 = DT_NULL,d_tag
+(Pnull) br.cond.sptk.few apply_relocs
+ cmp.eq Prela,p0 = DT_RELA,d_tag
+ cmp.eq Prelasz,p0 = DT_RELASZ,d_tag
+ cmp.eq Psymtab,p0 = DT_SYMTAB,d_tag
+ cmp.eq Psyment,p0 = DT_SYMENT,d_tag
+ cmp.eq Prelaent,p0 = DT_RELAENT,d_tag
+ ;;
+(Prela) add rela = d_val, ldbase
+(Prelasz) mov relasz = d_val
+(Prelaent) mov relaent = d_val
+(Psymtab) add val = d_val, ldbase
+ ;;
+(Psyment) setf.sig syment = d_val
+ ;;
+(Psymtab) setf.sig symtab = val
+ br.sptk.few search_dynamic
+
+apply_loop:
+ ld8 r_offset = [rela]
+ add addr = 8,rela
+ sub relasz = relasz,relaent
+ ;;
+
+ ld8 r_info = [addr],8
+ ;;
+ ld8 r_addend = [addr]
+ add target = ldbase, r_offset
+
+ add rela = rela,relaent
+ extr.u r_type = r_info, 0, 32
+ ;;
+ cmp.eq Pnone,p0 = R_IA64_NONE,r_type
+ cmp.eq Prel,p0 = R_IA64_REL64LSB,r_type
+ cmp.eq Pfptr,p0 = R_IA64_FPTR64LSB,r_type
+(Prel) br.cond.sptk.few apply_REL64
+ ;;
+ cmp.eq Prel,p0 = R_IA64_DIR64LSB,r_type // treat DIR64 just like REL64
+
+(Pnone) br.cond.sptk.few apply_relocs
+(Prel) br.cond.sptk.few apply_REL64
+(Pfptr) br.cond.sptk.few apply_FPTR64
+
+ mov r8 = EFI_LOAD_ERROR
+ br.ret.sptk.few rp
+
+apply_relocs:
+ cmp.ltu Pmore,p0=0,relasz
+(Pmore) br.cond.sptk.few apply_loop
+
+ mov r8 = EFI_SUCCESS
+ br.ret.sptk.few rp
+
+apply_REL64:
+ ld8 val = [target]
+ ;;
+ add val = val,ldbase
+ ;;
+ st8 [target] = val
+ br.cond.sptk.few apply_relocs
+
+ // FPTR relocs are a bit more interesting: we need to lookup
+ // the symbol's value in symtab, allocate 16 bytes of memory,
+ // store the value in [target] in the first and the gp in the
+ // second dword.
+apply_FPTR64:
+ st8 [target] = fptr
+ extr.u r_sym = r_info,32,32
+ add target = 8,fptr
+ ;;
+
+ setf.sig ftmp = r_sym
+ mov r8=EFI_BUFFER_TOO_SMALL
+ ;;
+ cmp.geu Poom,p0 = fptr,fptr_limit
+
+ xma.lu ftmp = ftmp,syment,symtab
+(Poom) br.ret.sptk.few rp
+ ;;
+ getf.sig addr = ftmp
+ st8 [target] = gp
+ ;;
+ add addr = ST_VALUE_OFF, addr
+ ;;
+ ld8 val = [addr]
+ ;;
+ add val = val,ldbase
+ ;;
+ st8 [fptr] = val,16
+ br.cond.sptk.few apply_relocs
+
+ .endp _relocate
+
+ .data
+ .align 16
+fptr_mem_base:
+ .space MAX_FUNCTION_DESCRIPTORS*16
+fptr_mem_limit:
diff --git a/gnuefi/reloc_x86_64.c b/gnuefi/reloc_x86_64.c
new file mode 100644
index 0000000..04b4ddb
--- /dev/null
+++ b/gnuefi/reloc_x86_64.c
@@ -0,0 +1,96 @@
+/* reloc_x86_64.c - position independent x86_64 ELF shared object relocator
+ Copyright (C) 1999 Hewlett-Packard Co.
+ Contributed by David Mosberger <davidm@hpl.hp.com>.
+ Copyright (C) 2005 Intel Co.
+ Contributed by Fenghua Yu <fenghua.yu@intel.com>.
+
+ All rights reserved.
+
+ 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.
+ * Neither the name of Hewlett-Packard Co. nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ 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 OWNER OR CONTRIBUTORS
+ BE LIABLE FOR ANYDIRECT, 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.
+*/
+
+#include <efi.h>
+#include <efilib.h>
+
+#include <elf.h>
+
+EFI_STATUS _relocate (long ldbase, Elf64_Dyn *dyn, EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
+{
+ long relsz = 0, relent = 0;
+ Elf64_Rel *rel = 0;
+ unsigned long *addr;
+ int i;
+
+ for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
+ switch (dyn[i].d_tag) {
+ case DT_RELA:
+ rel = (Elf64_Rel*)
+ ((unsigned long)dyn[i].d_un.d_ptr
+ + ldbase);
+ break;
+
+ case DT_RELASZ:
+ relsz = dyn[i].d_un.d_val;
+ break;
+
+ case DT_RELAENT:
+ relent = dyn[i].d_un.d_val;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!rel && relent == 0)
+ return EFI_SUCCESS;
+
+ if (!rel || relent == 0)
+ return EFI_LOAD_ERROR;
+
+ while (relsz > 0) {
+ /* apply the relocs */
+ switch (ELF64_R_TYPE (rel->r_info)) {
+ case R_X86_64_NONE:
+ break;
+
+ case R_X86_64_RELATIVE:
+ addr = (unsigned long *)
+ (ldbase + rel->r_offset);
+ *addr += ldbase;
+ break;
+
+ default:
+ break;
+ }
+ rel = (Elf64_Rel*) ((char *) rel + relent);
+ relsz -= relent;
+ }
+ return EFI_SUCCESS;
+}