diff options
Diffstat (limited to 'gnuefi')
-rw-r--r-- | gnuefi/crt0-efi-loongarch64.S | 151 | ||||
-rw-r--r-- | gnuefi/elf_aarch64_efi.lds | 3 | ||||
-rw-r--r-- | gnuefi/elf_arm_efi.lds | 3 | ||||
-rw-r--r-- | gnuefi/elf_loongarch64_efi.lds | 63 | ||||
-rw-r--r-- | gnuefi/elf_x86_64_efi.lds | 3 | ||||
-rw-r--r-- | gnuefi/reloc_loongarch64.c | 104 |
6 files changed, 321 insertions, 6 deletions
diff --git a/gnuefi/crt0-efi-loongarch64.S b/gnuefi/crt0-efi-loongarch64.S new file mode 100644 index 0000000..af45d46 --- /dev/null +++ b/gnuefi/crt0-efi-loongarch64.S @@ -0,0 +1,151 @@ +/* + * crt0-efi-loongarch64.S - PE/COFF header for LoongArch64 EFI applications + * + * Copyright (C) 2021 Loongson Technology Corporation Limited. <zhoumingtao@loongson.cn> + * Copyright (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. + */ + +#ifndef EFI_SUBSYSTEM +#define EFI_SUBSYSTEM 0xa +#endif + .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 0x6264 // loongarch64 little endian + .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) + + .align 4 + + .globl _start + .type _start, @function +_start: + addi.d $sp, $sp, -24 + st.d $ra, $sp, 0 + st.d $a0, $sp, 8 + st.d $a1, $sp, 16 + + move $a2, $a0 // a2: ImageHandle + move $a3, $a1 // a3: SystemTable + la.local $a0, ImageBase // a0: ImageBase + la.local $a1, _DYNAMIC // a1: DynamicSection + bl _relocate + bnez $a0, 0f + + ld.d $a0, $sp, 8 + ld.d $a1, $sp, 16 + bl efi_main + +0: ld.d $ra, $sp, 0 + addi.d $sp, $sp, 24 + jr $ra + .end _start diff --git a/gnuefi/elf_aarch64_efi.lds b/gnuefi/elf_aarch64_efi.lds index 8c0fad0..6ceab19 100644 --- a/gnuefi/elf_aarch64_efi.lds +++ b/gnuefi/elf_aarch64_efi.lds @@ -29,7 +29,7 @@ SECTIONS { *(.reloc) } - . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + . = ALIGN(65536); .dynamic : { *(.dynamic) } .data : { @@ -73,7 +73,6 @@ SECTIONS .dynstr : { *(.dynstr) } . = ALIGN(4096); .note.gnu.build-id : { *(.note.gnu.build-id) } - . = DATA_SEGMENT_END (.); .ignored.reloc : { *(.rela.reloc) diff --git a/gnuefi/elf_arm_efi.lds b/gnuefi/elf_arm_efi.lds index dc2f459..f9087db 100644 --- a/gnuefi/elf_arm_efi.lds +++ b/gnuefi/elf_arm_efi.lds @@ -15,7 +15,7 @@ SECTIONS } _etext = .; _text_size = . - _text; - . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + . = ALIGN(4096); .dynamic : { *(.dynamic) } .data : { @@ -58,7 +58,6 @@ SECTIONS .dynstr : { *(.dynstr) } . = ALIGN(4096); .note.gnu.build-id : { *(.note.gnu.build-id) } - . = DATA_SEGMENT_END (.); /DISCARD/ : { *(.rel.reloc) diff --git a/gnuefi/elf_loongarch64_efi.lds b/gnuefi/elf_loongarch64_efi.lds new file mode 100644 index 0000000..e7b4d6b --- /dev/null +++ b/gnuefi/elf_loongarch64_efi.lds @@ -0,0 +1,63 @@ +OUTPUT_FORMAT("elf64-loongarch", "elf64-loongarch", "elf64-loongarch") +OUTPUT_ARCH(loongarch) +ENTRY(_start) +SECTIONS +{ + .text 0x0 : { + _text = .; + *(.text.head) + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + *(.srodata) + *(.rodata*) + . = ALIGN(16); + } + _etext = .; + _text_size = . - _text; + .dynamic : { *(.dynamic) } + .data : ALIGN(4096) + { + _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*) } + . = ALIGN(512); + _edata = .; + _data_size = . - _data; + + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } + . = ALIGN(4096); + .note.gnu.build-id : { *(.note.gnu.build-id) } + /DISCARD/ : + { + *(.rel.reloc) + *(.eh_frame) + *(.note.GNU-stack) + } + .comment 0 : { *(.comment) } +} diff --git a/gnuefi/elf_x86_64_efi.lds b/gnuefi/elf_x86_64_efi.lds index b1379ee..01979ea 100644 --- a/gnuefi/elf_x86_64_efi.lds +++ b/gnuefi/elf_x86_64_efi.lds @@ -30,7 +30,7 @@ SECTIONS { *(.reloc) } - . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + . = ALIGN(4096); .data : { _data = .; @@ -68,7 +68,6 @@ SECTIONS . = ALIGN(4096); .dynstr : { *(.dynstr) } . = ALIGN(4096); - . = DATA_SEGMENT_END (.); .ignored.reloc : { *(.rela.reloc) diff --git a/gnuefi/reloc_loongarch64.c b/gnuefi/reloc_loongarch64.c new file mode 100644 index 0000000..7860f9d --- /dev/null +++ b/gnuefi/reloc_loongarch64.c @@ -0,0 +1,104 @@ +/* reloc_loongarch64.c - position independent loongarch64 ELF shared object relocator + Copyright (C) 2021 Loongson Technology Corporation Limited. <zhoumingtao@loongson.cn> + 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_UNUSED, + EFI_SYSTEM_TABLE *systab EFI_UNUSED) +{ + 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; + + case DT_PLTGOT: + addr = (unsigned long *) + ((unsigned long)dyn[i].d_un.d_ptr + + ldbase); + 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_LARCH_NONE: + break; + + case R_LARCH_RELATIVE: + addr = (unsigned long *) + (ldbase + rel->r_offset); + *addr += ldbase; + break; + + default: + break; + } + rel = (Elf64_Rela*) ((char *) rel + relent); + relsz -= relent; + } + return EFI_SUCCESS; +} |