From feedeaa339e68c4e24304af2226345d4b7b85635 Mon Sep 17 00:00:00 2001 From: Xiaotian Wu Date: Thu, 18 May 2023 19:49:32 +0800 Subject: [PATCH] Make loongarch64 use efi-app-loongarch64 Binutils 2.41 now supports efi-app-loongarch64, so to use this we must add a dummy reloc section and remove the PE header definition from crt0 as this will conflict with the version added by objcopy Signed-off-by: Xiaotian Wu --- Make.defaults | 4 +- gnuefi/crt0-efi-loongarch64.S | 141 +++++---------------------------- gnuefi/elf_loongarch64_efi.lds | 75 +++++++++++++++--- 3 files changed, 86 insertions(+), 134 deletions(-) diff --git a/Make.defaults b/Make.defaults index 30ba06d..f0ae245 100755 --- a/Make.defaults +++ b/Make.defaults @@ -161,18 +161,16 @@ endif ifneq ($(ARCH),arm) ifneq ($(ARCH),mips64el) ifneq ($(ARCH),riscv64) -ifneq ($(ARCH),loongarch64) export HAVE_EFI_OBJCOPY=y endif endif endif -endif ifeq ($(ARCH),arm) CFLAGS += -marm endif -ifneq (,$(filter $(ARCH),aarch64 arm)) +ifneq (,$(filter $(ARCH),aarch64 arm loongarch64)) LDFLAGS += -z common-page-size=4096 LDFLAGS += -z max-page-size=4096 endif diff --git a/gnuefi/crt0-efi-loongarch64.S b/gnuefi/crt0-efi-loongarch64.S index 97e3265..af939ff 100644 --- a/gnuefi/crt0-efi-loongarch64.S +++ b/gnuefi/crt0-efi-loongarch64.S @@ -17,125 +17,8 @@ * 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 - .4byte pe_header - ImageBase // Offset to the PE header. -pe_header: - .ascii "PE" - .2byte 0 -coff_header: - .2byte 0x6264 // loongarch64 little endian - .2byte 2 // nr_sections - .4byte 0 // TimeDateStamp - .4byte 0 // PointerToSymbolTable - .4byte 1 // NumberOfSymbols - .2byte section_table - optional_header // SizeOfOptionalHeader - .2byte 0x206 // Characteristics. - // IMAGE_FILE_DEBUG_STRIPPED | - // IMAGE_FILE_EXECUTABLE_IMAGE | - // IMAGE_FILE_LINE_NUMS_STRIPPED -optional_header: - .2byte 0x20b // PE32+ format - .byte 0x02 // MajorLinkerVersion - .byte 0x14 // MinorLinkerVersion - .4byte _edata - _start // SizeOfCode - .4byte 0 // SizeOfInitializedData - .4byte 0 // SizeOfUninitializedData - .4byte _start - ImageBase // AddressOfEntryPoint - .4byte _start - ImageBase // BaseOfCode - -extra_header_fields: - .8byte 0 // ImageBase - .4byte 0x20 // SectionAlignment - .4byte 0x8 // FileAlignment - .2byte 0 // MajorOperatingSystemVersion - .2byte 0 // MinorOperatingSystemVersion - .2byte 0 // MajorImageVersion - .2byte 0 // MinorImageVersion - .2byte 0 // MajorSubsystemVersion - .2byte 0 // MinorSubsystemVersion - .4byte 0 // Win32VersionValue - - .4byte _edata - ImageBase // SizeOfImage - - // Everything before the kernel image is considered part of the header - .4byte _start - ImageBase // SizeOfHeaders - .4byte 0 // CheckSum - .2byte EFI_SUBSYSTEM // Subsystem - .2byte 0 // DllCharacteristics - .8byte 0 // SizeOfStackReserve - .8byte 0 // SizeOfStackCommit - .8byte 0 // SizeOfHeapReserve - .8byte 0 // SizeOfHeapCommit - .4byte 0 // LoaderFlags - .4byte 0x10 // NumberOfRvaAndSizes - - .8byte 0 // ExportTable - .8byte 0 // ImportTable - .8byte 0 // ResourceTable - .8byte 0 // ExceptionTable - .8byte 0 // CertificationTable - .8byte 0 // BaseRelocationTable - .8byte 0 // Debug - .8byte 0 // Architecture - .8byte 0 // Global Ptr - .8byte 0 // TLS Table - .8byte 0 // Load Config Table - .8byte 0 // Bound Import - .8byte 0 // IAT - .8byte 0 // Delay Import Descriptor - .8byte 0 // CLR Runtime Header - .8byte 0 // Reserved, must be zero - - // 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 - .4byte 0 - .4byte 0 - .4byte 0 // SizeOfRawData - .4byte 0 // PointerToRawData - .4byte 0 // PointerToRelocations - .4byte 0 // PointerToLineNumbers - .2byte 0 // NumberOfRelocations - .2byte 0 // NumberOfLineNumbers - .4byte 0x42100040 // Characteristics (section flags) - - - .ascii ".text" - .byte 0 - .byte 0 - .byte 0 // end of 0 padding of section name - .4byte _edata - _start // VirtualSize - .4byte _start - ImageBase // VirtualAddress - .4byte _edata - _start // SizeOfRawData - .4byte _start - ImageBase // PointerToRawData - - .4byte 0 // PointerToRelocations (0 for executables) - .4byte 0 // PointerToLineNumbers (0 for executables) - .2byte 0 // NumberOfRelocations (0 for executables) - .2byte 0 // NumberOfLineNumbers (0 for executables) - .4byte 0xe0500020 // Characteristics (section flags) - - .align 4 - + .text + .align 12 .globl _start .type _start, @function _start: @@ -153,9 +36,25 @@ _start: ld.d $a0, $sp, 8 ld.d $a1, $sp, 16 - bl efi_main + bl _entry 0: ld.d $ra, $sp, 0 addi.d $sp, $sp, 24 jr $ra - .end _start + +// hand-craft a dummy .reloc section so EFI knows it's a relocatable executable: + + .data +dummy: .4byte 0 + +#define IMAGE_REL_ABSOLUTE 0 + .section .reloc, "a" +label1: + .4byte dummy-label1 // Page RVA + .4byte 12 // Block Size (2*4+2*2), must be aligned by 32 Bits + .2byte (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy + .2byte (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy + +#if defined(__ELF__) && defined(__linux__) + .section .note.GNU-stack,"",%progbits +#endif diff --git a/gnuefi/elf_loongarch64_efi.lds b/gnuefi/elf_loongarch64_efi.lds index d9de3bd..57d046d 100644 --- a/gnuefi/elf_loongarch64_efi.lds +++ b/gnuefi/elf_loongarch64_efi.lds @@ -3,9 +3,17 @@ OUTPUT_ARCH(loongarch) ENTRY(_start) SECTIONS { - .text 0x0 : { + . = 0; + ImageBase = .; + /* .hash and/or .gnu.hash MUST come first! */ + .hash : { *(.hash) } + .gnu.hash : { *(.gnu.hash) } + . = ALIGN(4096); + .eh_frame : { *(.eh_frame) } + .gcc_except_table : { *(.gcc_except_table*) } + . = ALIGN(4096); + .text : { _text = .; - *(.text.head) *(.text) *(.text.*) *(.gnu.linkonce.t.*) @@ -14,8 +22,15 @@ SECTIONS } _etext = .; _text_size = _etext - _text; + . = ALIGN(4096); + .reloc : + { + KEEP (*(.reloc)) + } + . = ALIGN(65536); .dynamic : { *(.dynamic) } - .data : ALIGN(4096) + . = ALIGN(4096); + .data : { _data = .; *(.sdata) @@ -25,6 +40,33 @@ SECTIONS *(.got.plt) *(.got) + /* + * Note that these aren't the using the GNU "CONSTRUCTOR" output section + * command, so they don't start with a size. Because of p2align and the + * end/END definitions, and the fact that they're mergeable, they can also + * have NULLs which aren't guaranteed to be at the end. + */ + . = ALIGN(16); + __init_array_start = .; + *(SORT(.init_array.*)) + *(.init_array) + __init_array_end = .; + . = ALIGN(16); + __CTOR_LIST__ = .; + *(SORT(.ctors.*)) + *(.ctors) + __CTOR_END__ = .; + . = ALIGN(16); + __DTOR_LIST__ = .; + *(SORT(.dtors.*)) + *(.dtors) + __DTOR_END__ = .; + . = ALIGN(16); + __fini_array_start = .; + *(SORT(.fini_array.*)) + *(.fini_array) + __fini_array_end = .; + /* the EFI loader doesn't seem to like a .bss section, so we stick it all into .data: */ . = ALIGN(16); @@ -32,16 +74,30 @@ SECTIONS *(.sbss) *(.scommon) *(.dynbss) - *(.bss) + *(.bss*) *(COMMON) + *(.rel.local) . = ALIGN(16); + _bss_end = .; } - .rela.dyn : { *(.rela.dyn) } + . = ALIGN(4096); + .rela : + { + *(.rela.text*) + *(.rela.data*) + *(.rela.got) + *(.rela.dyn) + *(.rela.stab) + *(.rela.init_array*) + *(.rela.fini_array*) + *(.rela.ctors*) + *(.rela.dtors*) + + } + . = ALIGN(4096); .rela.plt : { *(.rela.plt) } - .rela.got : { *(.rela.got) } - .rela.data : { *(.rela.data) *(.rela.data*) } . = ALIGN(4096); .rodata : { *(.rodata*) } . = ALIGN(512); @@ -54,10 +110,9 @@ SECTIONS .dynstr : { *(.dynstr) } . = ALIGN(4096); .note.gnu.build-id : { *(.note.gnu.build-id) } - /DISCARD/ : + .ignored.reloc : { - *(.rel.reloc) - *(.eh_frame) + *(.rela.reloc) *(.note.GNU-stack) } .comment 0 : { *(.comment) }