diff --git a/Make.defaults b/Make.defaults index 47ed361..0068e31 100755 --- a/Make.defaults +++ b/Make.defaults @@ -34,7 +34,7 @@ # SUCH DAMAGE. # -TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) +TOPDIR ?= $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) # # Variables below overridable from command-line: @@ -45,10 +45,24 @@ TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) # Where to install the package. GNU-EFI will create and access # lib and include under the root # -INSTALLROOT := / +DESTDIR ?= / +ifeq ($(origin INSTALLROOT),undefined) +INSTALLROOT = $(DESTDIR) +endif + +empty := +space := $(empty) $(empty) +stripped = $(subst $(space),/,$(strip $(subst /,$(space),$(1)))) +unstripped = $(subst $(space),/,$(subst /,$(space),$(1))) +is_absolute = $(subst $(call stripped,$(1)),$(empty),$(call unstripped,$(1))) + +override INSTALLROOT:=$(if $(call is_absolute,$(INSTALLROOT)),,$(TOPDIR)/)$(INSTALLROOT) + PREFIX := /usr/local -LIBDIR := $(PREFIX)/lib -INSTALL := install +EXEC_PREFIX := $(PREFIX) +LIBDIR := $(EXEC_PREFIX)/lib +INCLUDEDIR := $(PREFIX)/include +INSTALL := install # Compilation tools HOSTCC := $(prefix)gcc @@ -75,6 +89,16 @@ ifeq ($(ARCH),amd64) override ARCH := x86_64 endif +GCCVERSION := $(shell $(CC) -dumpversion | cut -f1 -d.) +GCCMINOR := $(shell $(CC) -dumpversion | cut -f2 -d.) +USING_CLANG := $(shell $(CC) -v 2>&1 | grep -q 'clang version' && echo clang) + +# Rely on GCC MS ABI support? +GCCNEWENOUGH := $(shell ( [ $(GCCVERSION) -gt "4" ] \ + || ( [ $(GCCVERSION) -eq "4" ] \ + && [ $(GCCMINOR) -ge "7" ] ) ) \ + && echo 1) + # # Where to build the package # @@ -100,20 +124,15 @@ ifeq ($(ARCH),ia32) endif endif +# Set ISO C mode +CPPFLAGS += -std=c11 + ifeq ($(ARCH),x86_64) - GCCVERSION := $(shell $(CC) -dumpversion | cut -f1 -d.) - GCCMINOR := $(shell $(CC) -dumpversion | cut -f2 -d.) - USING_CLANG := $(shell $(CC) -v 2>&1 | grep -q 'clang version' && echo clang) - - # Rely on GCC MS ABI support? - GCCNEWENOUGH := $(shell ( [ $(GCCVERSION) -gt "4" ] \ - || ( [ $(GCCVERSION) -eq "4" ] \ - && [ $(GCCMINOR) -ge "7" ] ) ) \ - && echo 1) ifeq ($(GCCNEWENOUGH),1) - CPPFLAGS += -DGNU_EFI_USE_MS_ABI -maccumulate-outgoing-args --std=c11 - else ifeq ($(USING_CLANG),clang) - CPPFLAGS += -DGNU_EFI_USE_MS_ABI --std=c11 + CPPFLAGS += -DGNU_EFI_USE_MS_ABI + ifneq ($(USING_CLANG),clang) + CPPFLAGS += -maccumulate-outgoing-args + endif endif CFLAGS += -mno-red-zone @@ -139,7 +158,6 @@ endif # Set HAVE_EFI_OBJCOPY if objcopy understands --target efi-[app|bsdrv|rtdrv], # otherwise we need to compose the PE/COFF header using the assembler # -ifneq ($(ARCH),aarch64) ifneq ($(ARCH),arm) ifneq ($(ARCH),mips64el) ifneq ($(ARCH),riscv64) @@ -147,39 +165,42 @@ export HAVE_EFI_OBJCOPY=y endif endif endif -endif - -ifneq ($(ARCH),arm) -export LIBGCC=$(shell $(CC) $(ARCH3264) -print-libgcc-file-name) -endif ifeq ($(ARCH),arm) CFLAGS += -marm endif +ifneq (,$(filter $(ARCH),aarch64 arm loongarch64)) +LDFLAGS += -z common-page-size=4096 +LDFLAGS += -z max-page-size=4096 +endif + # Generic compilation flags INCDIR += -I$(SRCDIR) -I$(TOPDIR)/inc -I$(TOPDIR)/inc/$(ARCH) \ -I$(TOPDIR)/inc/protocol -# Only enable -fpic for non MinGW compilers (unneeded on MinGW) +# Only enable -fPIE for non MinGW compilers (unneeded on MinGW) GCCMACHINE := $(shell $(CC) -dumpmachine) ifneq (mingw32,$(findstring mingw32, $(GCCMACHINE))) - CFLAGS += -fpic + CFLAGS += -fPIE endif ifeq (FreeBSD, $(findstring FreeBSD, $(OS))) CFLAGS += $(ARCH3264) -g -O2 -Wall -Wextra -Werror \ - -fshort-wchar -fno-strict-aliasing \ + -funsigned-char -fshort-wchar -fno-strict-aliasing \ -ffreestanding -fno-stack-protector else -CFLAGS += $(ARCH3264) -g -O2 -Wall -Wextra -Werror \ - -fshort-wchar -fno-strict-aliasing \ +CFLAGS += $(ARCH3264) -g -O2 -Wall -Wextra -Wno-pointer-sign -Werror \ + -funsigned-char -fshort-wchar -fno-strict-aliasing \ -ffreestanding -fno-stack-protector -fno-stack-check \ - -fno-stack-check \ $(if $(findstring gcc,$(CC)),-fno-merge-all-constants,) endif ARFLAGS := rDv ASFLAGS += $(ARCH3264) LDFLAGS += -nostdlib --warn-common --no-undefined --fatal-warnings \ - --build-id=sha1 + --build-id=sha1 -z nocombreloc + +ifneq ($(ARCH),arm) +export LIBGCC=$(shell $(CC) $(CFLAGS) $(ARCH3264) -print-libgcc-file-name) +endif diff --git a/Make.rules b/Make.rules index 8cb93b0..cdb7aab 100644 --- a/Make.rules +++ b/Make.rules @@ -34,10 +34,12 @@ # SUCH DAMAGE. # +.SECONDARY: + %.efi: %.so - $(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \ + $(OBJCOPY) -j .text -j .sdata -j .data -j .dynamic -j .rodata -j .rel \ -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \ - -j .reloc $(FORMAT) $*.so $@ + -j .areloc -j .reloc $(FORMAT) $*.so $@ %.efi.debug: %.so $(OBJCOPY) -j .debug_info -j .debug_abbrev -j .debug_aranges \ diff --git a/Makefile b/Makefile index 897628b..e0b3062 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ # SUCH DAMAGE. # -VERSION = 3.0.15 +export VERSION = 3.0.18 MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) SRCDIR = $(dir $(MKFILE_PATH)) @@ -44,10 +44,12 @@ VPATH = $(SRCDIR) include $(SRCDIR)/Make.defaults SUBDIRS = lib gnuefi inc apps -gnuefi: lib all: check_gcc $(SUBDIRS) +gnuefi: lib +apps: gnuefi + mkvars: @echo AR=$(AR) @echo ARCH=$(ARCH) @@ -80,15 +82,15 @@ $(SUBDIRS): $(MAKE) -C $(OBJDIR)/$@ -f $(SRCDIR)/$@/Makefile SRCDIR=$(SRCDIR)/$@ ARCH=$(ARCH) clean: - rm -f *~ - @for d in $(SUBDIRS); do \ + @rm -vrf *~ + @set -e ; for d in $(SUBDIRS); do \ if [ -d $(OBJDIR)/$$d ]; then \ $(MAKE) -C $(OBJDIR)/$$d -f $(SRCDIR)/$$d/Makefile SRCDIR=$(SRCDIR)/$$d clean; \ fi; \ done install: - @for d in $(SUBDIRS); do \ + @set -e ; for d in $(SUBDIRS); do \ mkdir -p $(OBJDIR)/$$d; \ $(MAKE) -C $(OBJDIR)/$$d -f $(SRCDIR)/$$d/Makefile SRCDIR=$(SRCDIR)/$$d install; done diff --git a/apps/Makefile b/apps/Makefile index 4e1b69a..18980f1 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -37,22 +37,21 @@ SRCDIR = . VPATH = $(SRCDIR) +TOPDIR = $(SRCDIR)/.. include $(SRCDIR)/../Make.defaults -TOPDIR = $(SRCDIR)/.. - -CDIR=$(TOPDIR)/.. LINUX_HEADERS = /usr/src/sys/build +APPSDIR = $(LIBDIR)/gnuefi/apps CPPFLAGS += -D__KERNEL__ -I$(LINUX_HEADERS)/include -CRTOBJS = ../gnuefi/crt0-efi-$(ARCH).o +CRTOBJS = $(TOPDIR)/$(ARCH)/gnuefi/crt0-efi-$(ARCH).o LDSCRIPT = $(TOPDIR)/gnuefi/elf_$(ARCH)_efi.lds ifneq (,$(findstring FreeBSD,$(OS))) LDSCRIPT = $(TOPDIR)/gnuefi/elf_$(ARCH)_fbsd_efi.lds endif -LDFLAGS += -shared -Bsymbolic -L../lib -L../gnuefi $(CRTOBJS) +LDFLAGS += -shared -Bsymbolic -L$(TOPDIR)/$(ARCH)/lib -L$(TOPDIR)/$(ARCH)/gnuefi $(CRTOBJS) LOADLIBES += -lefi -lgnuefi LOADLIBES += $(LIBGCC) @@ -62,7 +61,8 @@ TARGET_APPS = t.efi t2.efi t3.efi t4.efi t5.efi t6.efi \ printenv.efi t7.efi t8.efi tcc.efi modelist.efi \ route80h.efi drv0_use.efi AllocPages.efi exit.efi \ FreePages.efi setjmp.efi debughook.efi debughook.efi.debug \ - bltgrid.efi lfbgrid.efi setdbg.efi unsetdbg.efi + bltgrid.efi lfbgrid.efi setdbg.efi unsetdbg.efi \ + ctors_test.efi ctors_dtors_priority_test.efi TARGET_BSDRIVERS = drv0.efi TARGET_RTDRIVERS = @@ -87,8 +87,14 @@ TARGETS = $(TARGET_APPS) $(TARGET_BSDRIVERS) $(TARGET_RTDRIVERS) all: $(TARGETS) +ctors_test.so : ctors_fns.o ctors_test.o + clean: - rm -f $(TARGETS) *~ *.o *.so + @rm -vf $(TARGETS) *~ *.o *.so + +install: + mkdir -p $(INSTALLROOT)$(APPSDIR) + $(INSTALL) -m 644 $(TARGETS) $(INSTALLROOT)$(APPSDIR) .PHONY: install diff --git a/apps/bltgrid.c b/apps/bltgrid.c index 4500fbb..ff69753 100644 --- a/apps/bltgrid.c +++ b/apps/bltgrid.c @@ -64,7 +64,8 @@ draw_boxes(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop) if (CompareMem(info, gop->Mode->Info, sizeof (*info))) continue; - NumPixels = info->VerticalResolution * info->HorizontalResolution; + NumPixels = (UINTN)info->VerticalResolution + * (UINTN)info->HorizontalResolution; BufferSize = NumPixels * sizeof(UINT32); PixelBuffer = AllocatePool(BufferSize); diff --git a/apps/ctors_dtors_priority_test.c b/apps/ctors_dtors_priority_test.c new file mode 100644 index 0000000..e8a3990 --- /dev/null +++ b/apps/ctors_dtors_priority_test.c @@ -0,0 +1,29 @@ +#include +#include + +// 101 in init_array, 65434 in ctors +static void __attribute__((constructor(101))) EFI_NO_TAIL_CALL ctors101() { + Print(L"1) ctor with lower numbered priority \r\n"); +} + +// 65434 in init_array, 101 in ctors +static void __attribute__((constructor(65434))) EFI_NO_TAIL_CALL ctors65434() { + Print(L"2) ctor with higher numbered priority \r\n"); +} + +// 101 in fini_array, 65434 in dtors +static void __attribute__((destructor(101))) EFI_NO_TAIL_CALL dtors101() { + Print(L"4) dtor with lower numbered priority \r\n"); +} + +// 65434 in fini_array, 101 in dtors +static void __attribute__((destructor(65434))) EFI_NO_TAIL_CALL dtors65434() { + Print(L"3) dtor with higher numbered priority \r\n"); +} + +EFI_STATUS +efi_main (EFI_HANDLE image EFI_UNUSED, EFI_SYSTEM_TABLE *systab EFI_UNUSED) +{ + Print(L"Main function \r\n"); + return EFI_SUCCESS; +} \ No newline at end of file diff --git a/apps/ctors_fns.c b/apps/ctors_fns.c new file mode 100644 index 0000000..7027447 --- /dev/null +++ b/apps/ctors_fns.c @@ -0,0 +1,26 @@ +/* + * ctors.c + * Copyright 2019 Peter Jones + * + */ + +#include +#include + +int constructed_value = 0; + +static void __attribute__((__constructor__)) EFI_NO_TAIL_CALL ctor(void) +{ + Print(L"%a:%d:%a() constructed_value:%d\n", __FILE__, __LINE__, __func__, constructed_value); + constructed_value = 1; + Print(L"%a:%d:%a() constructed_value:%d\n", __FILE__, __LINE__, __func__, constructed_value); +} + +static void __attribute__((__destructor__)) EFI_NO_TAIL_CALL dtor(void) +{ + Print(L"%a:%d:%a() constructed_value:%d\n", __FILE__, __LINE__, __func__, constructed_value); + constructed_value = 0; + Print(L"%a:%d:%a() constructed_value:%d\n", __FILE__, __LINE__, __func__, constructed_value); +} + +// vim:fenc=utf-8:tw=75:noet diff --git a/apps/ctors_test.c b/apps/ctors_test.c new file mode 100644 index 0000000..7e48da8 --- /dev/null +++ b/apps/ctors_test.c @@ -0,0 +1,20 @@ +/* + * ctors_test.c + * Copyright 2019 Peter Jones + * + */ + +#include +#include + +extern int constructed_value; + +EFI_STATUS +efi_main (EFI_HANDLE image EFI_UNUSED, EFI_SYSTEM_TABLE *systab EFI_UNUSED) +{ + Print(L"%a:%d:%a() constructed_value:%d\n", __FILE__, __LINE__, __func__, constructed_value); + + return EFI_SUCCESS; +} + +// vim:fenc=utf-8:tw=75:noet diff --git a/apps/debughook.c b/apps/debughook.c index 78e4a76..c862f0f 100644 --- a/apps/debughook.c +++ b/apps/debughook.c @@ -37,13 +37,7 @@ GetVariable(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner) EFI_GUID DUMMY_GUID = {0x55aad538, 0x8f82, 0x4e2a, {0xa4,0xf0,0xbe, 0x59, 0x13, 0xb6, 0x5f, 0x1e}}; -#if defined(__clang__) -# define _OPTNONE __attribute__((optnone)) -#else -# define _OPTNONE __attribute__((__optimize__("0"))) -#endif - -static _OPTNONE void +static EFI_OPTNONE void DebugHook(void) { EFI_GUID guid = DUMMY_GUID; diff --git a/apps/lfbgrid.c b/apps/lfbgrid.c index 05977d2..3914313 100644 --- a/apps/lfbgrid.c +++ b/apps/lfbgrid.c @@ -51,10 +51,9 @@ draw_boxes(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop) UINTN NumPixels; UINT32 *PixelBuffer; UINT32 CopySize, BufferSize; -#if defined(__x86_64__) || defined(__aarch64__) || \ - (defined (__riscv) && __riscv_xlen == 64) +#if __SIZEOF_POINTER__ == 8 UINT64 FrameBufferAddr; -#elif defined(__i386__) || defined(__arm__) +#elif __SIZEOF_POINTER__ == 4 UINT32 FrameBufferAddr; #else #error YOUR ARCH HERE @@ -89,7 +88,8 @@ draw_boxes(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop) if (CompareMem(info, gop->Mode->Info, sizeof (*info))) continue; - NumPixels = info->VerticalResolution * info->PixelsPerScanLine; + NumPixels = (UINTN)info->VerticalResolution + * (UINTN)info->PixelsPerScanLine; BufferSize = NumPixels * sizeof(UINT32); if (BufferSize == gop->Mode->FrameBufferSize) { CopySize = BufferSize; @@ -115,10 +115,9 @@ draw_boxes(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop) Print(L"No linear framebuffer on this device.\n"); return; } -#if defined(__x86_64__) || defined(__aarch64__) || \ - (defined (__riscv) && __riscv_xlen == 64) +#if __SIZEOF_POINTER__ == 8 FrameBufferAddr = (UINT64)gop->Mode->FrameBufferBase; -#elif defined(__i386__) || defined(__arm__) +#elif __SIZEOF_POINTER__ == 4 FrameBufferAddr = (UINT32)(UINT64)gop->Mode->FrameBufferBase; #else #error YOUR ARCH HERE diff --git a/debian/changelog b/debian/changelog index da2a37c..e5594f4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +gnu-efi (3.0.18-1) unstable; urgency=medium + + * Strip LDFLAGS before passing to the build + * Add loong64 to arch list (Closes: #1025787) + * Correctly set the PREFIX for the build + * Add myself to uploaders + * Drop unnecessary binutils build dep (Closes: #1032501) + + -- Mario Limonciello Mon, 25 Mar 2024 14:50:29 -0500 + gnu-efi (3.0.15-1) unstable; urgency=medium * New upstream version 3.0.15 diff --git a/debian/control b/debian/control index 546ad24..3690976 100644 --- a/debian/control +++ b/debian/control @@ -2,10 +2,9 @@ Source: gnu-efi Section: devel Priority: optional Maintainer: Debian EFI team -Uploaders: Julian Andres Klode +Uploaders: Julian Andres Klode , Mario Limonciello Build-Depends: debhelper-compat (= 12), - binutils, gcc-multilib [any-amd64 i386], Standards-Version: 4.1.1 Vcs-Git: https://salsa.debian.org/efi-team/gnu-efi.git @@ -13,7 +12,7 @@ Vcs-Browser: https://salsa.debian.org/efi-team/gnu-efi Homepage: http://sourceforge.net/projects/gnu-efi/ Package: gnu-efi -Architecture: any-amd64 any-i386 any-arm64 armhf any-riscv64 any-ia64 +Architecture: any-amd64 any-i386 any-arm64 armhf any-riscv64 any-loong64 any-ia64 Depends: ${misc:Depends} Description: Library for developing EFI applications GNU toolchain for building applications that can run in the environment diff --git a/debian/rules b/debian/rules index 63f8d75..639d694 100755 --- a/debian/rules +++ b/debian/rules @@ -42,9 +42,11 @@ ifneq (,$(COMPAT_ARCH)) endif override_dh_auto_build: - $(MAKE) ARCH=$(HOST_ARCH) + LDFLAGS="${LDFLAGS//-Wl/}" && LDFLAGS="${LDFLAGS//,/ }" && \ + $(MAKE) ARCH=$(HOST_ARCH) PREFIX=/usr ifneq (,$(COMPAT_ARCH)) - $(MAKE) ARCH=$(COMPAT_ARCH) HOSTARCH=$(BUILD_ARCH) + LDFLAGS="${LDFLAGS//-Wl/}" && LDFLAGS="${LDFLAGS//,/ }" && \ + $(MAKE) ARCH=$(COMPAT_ARCH) HOSTARCH=$(BUILD_ARCH) PREFIX=/usr endif # Fixme: This somehow rebuilds some parts diff --git a/gnuefi/Makefile b/gnuefi/Makefile index 10d4e7a..68dfced 100644 --- a/gnuefi/Makefile +++ b/gnuefi/Makefile @@ -37,12 +37,11 @@ SRCDIR = . VPATH = $(SRCDIR) +TOPDIR = $(SRCDIR)/.. include $(SRCDIR)/../Make.defaults -TOPDIR = $(SRCDIR)/.. - -CDIR=$(TOPDIR)/.. +PKGCONFIGDIR ?= $(LIBDIR)/pkgconfig FILES = reloc_$(ARCH) OBJS = $(FILES:%=%.o) @@ -52,14 +51,23 @@ reloc_aarch64.o: CFLAGS += -fno-jump-tables TARGETS = crt0-efi-$(ARCH).o libgnuefi.a -all: $(TARGETS) +all: $(TARGETS) gnu-efi.pc libgnuefi.a: $(OBJS) $(AR) $(ARFLAGS) $@ $^ +gnu-efi.pc: + sed \ + -e 's:@PREFIX@:$(PREFIX):g' \ + -e 's:@EXEC_PREFIX@:$(EXEC_PREFIX):g' \ + -e 's:@INCLUDEDIR@:$(INCLUDEDIR):g' \ + -e 's:@LIBDIR@:$(LIBDIR):g' \ + -e 's:@VERSION@:$(VERSION):g' \ + $(SRCDIR)/gnu-efi.pc.in > gnu-efi.pc + clean: - rm -f $(TARGETS) *~ *.o $(OBJS) + @rm -vf $(TARGETS) *~ *.o $(OBJS) install: mkdir -p $(INSTALLROOT)$(LIBDIR) @@ -73,5 +81,7 @@ ifneq (,$(findstring FreeBSD,$(OS))) else $(INSTALL) -m 644 $(SRCDIR)/elf_$(ARCH)_efi.lds $(INSTALLROOT)$(LIBDIR) endif + $(INSTALL) -d $(INSTALLROOT)$(PKGCONFIGDIR) + $(INSTALL) -m 644 gnu-efi.pc $(INSTALLROOT)$(PKGCONFIGDIR) include $(SRCDIR)/../Make.rules diff --git a/gnuefi/crt0-efi-aarch64.S b/gnuefi/crt0-efi-aarch64.S index a0687b1..236b544 100644 --- a/gnuefi/crt0-efi-aarch64.S +++ b/gnuefi/crt0-efi-aarch64.S @@ -16,100 +16,11 @@ * 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 0 // 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 _data - _start // SizeOfCode - .long _data_size // SizeOfInitializedData - .long 0 // SizeOfUninitializedData - .long _start - ImageBase // AddressOfEntryPoint - .long _start - ImageBase // BaseOfCode - -extra_header_fields: - .quad 0 // ImageBase - .long 0x1000 // SectionAlignment - .long 0x200 // 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: - .ascii ".text\0\0\0" - .long _data - _start // VirtualSize - .long _start - ImageBase // VirtualAddress - .long _data - _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 0x60000020 // Characteristics (section flags) - - .ascii ".data\0\0\0" - .long _data_size // VirtualSize - .long _data - ImageBase // VirtualAddress - .long _data_size // SizeOfRawData - .long _data - 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 0xc0000040 // Characteristics (section flags) - + .text .align 12 + + .globl _start + .type _start,%function _start: stp x29, x30, [sp, #-32]! mov x29, sp @@ -124,11 +35,24 @@ _start: cbnz x0, 0f ldp x0, x1, [sp, #16] - bl efi_main + bl _entry 0: ldp x29, x30, [sp], #32 ret + // 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/crt0-efi-arm.S b/gnuefi/crt0-efi-arm.S index ea3bbc4..d84d43c 100644 --- a/gnuefi/crt0-efi-arm.S +++ b/gnuefi/crt0-efi-arm.S @@ -25,103 +25,132 @@ ImageBase: .ascii "MZ" .skip 58 // 'MZ' + pad + offset == 64 - .long pe_header - ImageBase // Offset to the PE header. + .4byte pe_header - ImageBase // Offset to the PE header. pe_header: .ascii "PE" - .short 0 + .2byte 0 coff_header: - .short 0x1c2 // Mixed ARM/Thumb - .short 2 // nr_sections - .long 0 // TimeDateStamp - .long 0 // PointerToSymbolTable - .long 0 // NumberOfSymbols - .short section_table - optional_header // SizeOfOptionalHeader - .short 0x306 // Characteristics. + .2byte 0x1c2 // Mixed ARM/Thumb + .2byte 4 // nr_sections + .4byte 0 // TimeDateStamp + .4byte 0 // PointerToSymbolTable + .4byte 0 // NumberOfSymbols + .2byte section_table - optional_header // SizeOfOptionalHeader + .2byte 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 + .2byte 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 + .4byte _etext - _start // SizeOfCode + .4byte _alldata_size - ImageBase // SizeOfInitializedData + .4byte 0 // SizeOfUninitializedData + .4byte _start - ImageBase // AddressOfEntryPoint + .4byte _start - ImageBase // BaseOfCode + .4byte _reloc - ImageBase // 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 + .4byte 0 // ImageBase + .4byte 0x1000 // SectionAlignment + .4byte 0x1000 // FileAlignment + .2byte 0 // MajorOperatingSystemVersion + .2byte 0 // MinorOperatingSystemVersion + .2byte 0 // MajorImageVersion + .2byte 0 // MinorImageVersion + .2byte 0 // MajorSubsystemVersion + .2byte 0 // MinorSubsystemVersion + .4byte 0 // Win32VersionValue + + .4byte _image_end - 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 + .4byte _start - ImageBase // SizeOfHeaders + .4byte 0 // CheckSum + .2byte EFI_SUBSYSTEM // Subsystem + .2byte 0 // DllCharacteristics + .4byte 0 // SizeOfStackReserve + .4byte 0 // SizeOfStackCommit + .4byte 0 // SizeOfHeapReserve + .4byte 0 // SizeOfHeapCommit + .4byte 0 // LoaderFlags + .4byte 0x10 // NumberOfRvaAndSizes + + .8byte 0 // ExportTable + .8byte 0 // ImportTable + .8byte 0 // ResourceTable + .8byte 0 // ExceptionTable + .8byte 0 // CertificationTable + .4byte _reloc - ImageBase // BaseRelocationTable (VirtualAddress) + .4byte _reloc_vsize - ImageBase // BaseRelocationTable (Size) + .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: + .ascii ".text\0\0\0" + .4byte _evtext - _start // VirtualSize + .4byte _start - ImageBase // VirtualAddress + .4byte _etext - _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 0x60000020 // 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 - .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) - + .ascii ".reloc\0\0" + .4byte _reloc_vsize - ImageBase // VirtualSize + .4byte _reloc - ImageBase // VirtualAddress + .4byte _reloc_size - ImageBase // SizeOfRawData + .4byte _reloc - ImageBase // PointerToRawData + .4byte 0 // PointerToRelocations + .4byte 0 // PointerToLineNumbers + .2byte 0 // NumberOfRelocations + .2byte 0 // NumberOfLineNumbers + .4byte 0x42000040 // Characteristics (section flags) + + .ascii ".data\0\0\0" + .4byte _data_vsize - ImageBase // VirtualSize + .4byte _data - ImageBase // VirtualAddress + .4byte _data_size - ImageBase // SizeOfRawData + .4byte _data - ImageBase // PointerToRawData + .4byte 0 // PointerToRelocations + .4byte 0 // PointerToLineNumbers + .2byte 0 // NumberOfRelocations + .2byte 0 // NumberOfLineNumbers + .4byte 0xC0000040 // Characteristics (section flags) + + .ascii ".rodata\0" + .4byte _rodata_vsize - ImageBase // VirtualSize + .4byte _rodata - ImageBase // VirtualAddress + .4byte _rodata_size - ImageBase // SizeOfRawData + .4byte _rodata - ImageBase // PointerToRawData + .4byte 0 // PointerToRelocations + .4byte 0 // PointerToLineNumbers + .2byte 0 // NumberOfRelocations + .2byte 0 // NumberOfLineNumbers + .4byte 0x40000040 // Characteristics (section flags) + +.balign 256 +.globl _start +.type _start,%function _start: stmfd sp!, {r0-r2, lr} @@ -136,13 +165,25 @@ _start: bne 0f ldmfd sp, {r0-r1} - bl efi_main + bl _entry 0: add sp, sp, #12 ldr pc, [sp], #4 .L_DYNAMIC: - .word _DYNAMIC - . + .4byte _DYNAMIC - . + +// hand-craft a dummy .reloc section so EFI knows it's a relocatable executable: + + .data +dummy: .4byte 0 + +#define IMAGE_REL_ABSOLUTE 0 + .section .areloc + .4byte dummy // 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 diff --git a/gnuefi/crt0-efi-ia32.S b/gnuefi/crt0-efi-ia32.S index 9e9c865..e7023ab 100644 --- a/gnuefi/crt0-efi-ia32.S +++ b/gnuefi/crt0-efi-ia32.S @@ -37,6 +37,7 @@ .align 4 .globl _start + .type _start,%function _start: pushl %ebp movl %esp,%ebp @@ -56,25 +57,25 @@ _start: call _relocate popl %ebx popl %ebx - testl %eax,%eax - jne .exit + testl %eax,%eax + jne .exit - call efi_main # call app with "image" and "systab" argument + call _entry # call app with "image" and "systab" argument .exit: leave - ret + ret // hand-craft a dummy .reloc section so EFI knows it's a relocatable executable: .data -dummy: .long 0 +dummy: .4byte 0 #define IMAGE_REL_ABSOLUTE 0 .section .reloc - .long dummy // Page RVA - .long 12 // Block Size (2*4+2*2), must be aligned by 32 Bits - .word (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy - .word (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy + .4byte dummy // 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 diff --git a/gnuefi/crt0-efi-ia64.S b/gnuefi/crt0-efi-ia64.S index 38af615..30714d3 100644 --- a/gnuefi/crt0-efi-ia64.S +++ b/gnuefi/crt0-efi-ia64.S @@ -56,7 +56,7 @@ _start: mov out0=in0 // image handle mov out1=in1 // systab - br.call.sptk.few rp=efi_main + br.call.sptk.few rp=_entry .Lret2: .exit: mov ar.pfs=loc0 diff --git a/gnuefi/crt0-efi-loongarch64.S b/gnuefi/crt0-efi-loongarch64.S new file mode 100644 index 0000000..af939ff --- /dev/null +++ b/gnuefi/crt0-efi-loongarch64.S @@ -0,0 +1,60 @@ +/* + * crt0-efi-loongarch64.S - PE/COFF header for LoongArch64 EFI applications + * + * Copyright (C) 2021 Loongson Technology Corporation Limited. + * Copyright (C) 2014 Linaro Ltd. + * + * 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. + */ + + .text + .align 12 + .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 _entry + +0: ld.d $ra, $sp, 0 + addi.d $sp, $sp, 24 + jr $ra + +// 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/crt0-efi-mips64el.S b/gnuefi/crt0-efi-mips64el.S index 4b2c1b2..334c308 100644 --- a/gnuefi/crt0-efi-mips64el.S +++ b/gnuefi/crt0-efi-mips64el.S @@ -26,63 +26,73 @@ ImageBase: .ascii "MZ" .skip 58 // 'MZ' + pad + offset == 64 - .long pe_header - ImageBase // Offset to the PE header. + .4byte pe_header - ImageBase // Offset to the PE header. pe_header: .ascii "PE" - .short 0 + .2byte 0 coff_header: - .short 0x166 // MIPS little endian - .short 2 // nr_sections - .long 0 // TimeDateStamp - .long 0 // PointerToSymbolTable - .long 0 // NumberOfSymbols - .short section_table - optional_header // SizeOfOptionalHeader - .short 0x206 // Characteristics. + .2byte 0x166 // MIPS little endian + .2byte 2 // nr_sections + .4byte 0 // TimeDateStamp + .4byte 0 // PointerToSymbolTable + .4byte 0 // 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: - .short 0x20b // PE32+ format + .2byte 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 + .4byte _edata - _start // SizeOfCode + .4byte 0 // SizeOfInitializedData + .4byte 0 // SizeOfUninitializedData + .4byte _start - ImageBase // AddressOfEntryPoint + .4byte _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 + .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 - .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 + .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: @@ -95,31 +105,31 @@ section_table: .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) + .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 - .long _edata - _start // VirtualSize - .long _start - ImageBase // VirtualAddress - .long _edata - _start // SizeOfRawData - .long _start - ImageBase // PointerToRawData + .4byte _edata - _start // VirtualSize + .4byte _start - ImageBase // VirtualAddress + .4byte _edata - _start // SizeOfRawData + .4byte _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) + .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) .set push .set noreorder @@ -172,8 +182,8 @@ _pc: // a0: ImageHandle ld $a0, 16($sp) - // call efi_main - dla $t9, efi_main + // call _start + dla $t9, _entry jalr $t9 // a1: SystemTable ld $a1, 24($sp) diff --git a/gnuefi/crt0-efi-riscv64.S b/gnuefi/crt0-efi-riscv64.S index 0a5b7fc..712ed03 100644 --- a/gnuefi/crt0-efi-riscv64.S +++ b/gnuefi/crt0-efi-riscv64.S @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause */ /* * Copright (C) 2014 Linaro Ltd. * Copright (C) 2018 Alexander Graf @@ -29,96 +29,130 @@ ImageBase: .ascii "MZ" .skip 58 // 'MZ' + pad + offset == 64 - .long pe_header - ImageBase // Offset to the PE header. + .4byte pe_header - ImageBase // Offset to the PE header. pe_header: .ascii "PE" - .short 0 + .2byte 0 coff_header: - .short 0x5064 // riscv64 - .short 2 // nr_sections - .long 0 // TimeDateStamp - .long 0 // PointerToSymbolTable - .long 0 // NumberOfSymbols - .short section_table - optional_header // SizeOfOptionalHeader - .short 0x206 // Characteristics. + .2byte 0x5064 // riscv64 + .2byte 4 // nr_sections + .4byte 0 // TimeDateStamp + .4byte 0 // PointerToSymbolTable + .4byte 0 // 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: - .short 0x20b // PE32+ format + .2byte 0x20b // PE32+ format .byte 0x02 // MajorLinkerVersion .byte 0x14 // MinorLinkerVersion - .long _data - _start // SizeOfCode - .long _data_size // SizeOfInitializedData - .long 0 // SizeOfUninitializedData - .long _start - ImageBase // AddressOfEntryPoint - .long _start - ImageBase // BaseOfCode + .4byte _text_size - ImageBase // SizeOfCode + .4byte _alldata_size - ImageBase // SizeOfInitializedData + .4byte 0 // SizeOfUninitializedData + .4byte _start - ImageBase // AddressOfEntryPoint + .4byte _text - ImageBase // BaseOfCode extra_header_fields: - .quad 0 // ImageBase - .long 0x1000 // SectionAlignment - .long 0x200 // 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 + .8byte 0 // ImageBase + .4byte 0x1000 // SectionAlignment + .4byte 0x1000 // FileAlignment + .2byte 0 // MajorOperatingSystemVersion + .2byte 0 // MinorOperatingSystemVersion + .2byte 0 // MajorImageVersion + .2byte 0 // MinorImageVersion + .2byte 0 // MajorSubsystemVersion + .2byte 0 // MinorSubsystemVersion + .4byte 0 // Win32VersionValue + + .4byte _image_end - 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 + .4byte _text - 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 + .4byte _reloc - ImageBase // BaseRelocationTable (VirtualAddress) + .4byte _reloc_vsize - ImageBase // BaseRelocationTable (Size) + .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: + + .ascii ".text\0\0\0" + .4byte _text_vsize - ImageBase // VirtualSize + .4byte _text - ImageBase // VirtualAddress + .4byte _text_size - ImageBase // SizeOfRawData + .4byte _text - 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 0x60000020 // 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\0\0" - .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) + .4byte _reloc_vsize - ImageBase // VirtualSize + .4byte _reloc - ImageBase // VirtualAddress + .4byte _reloc_size - ImageBase // SizeOfRawData + .4byte _reloc - ImageBase // PointerToRawData + .4byte 0 // PointerToRelocations + .4byte 0 // PointerToLineNumbers + .2byte 0 // NumberOfRelocations + .2byte 0 // NumberOfLineNumbers + .4byte 0x42000040 // Characteristics (section flags) - .ascii ".text\0\0\0" - .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 12 + .ascii ".data\0\0\0" + .4byte _data_vsize - ImageBase // VirtualSize + .4byte _data - ImageBase // VirtualAddress + .4byte _data_size - ImageBase // SizeOfRawData + .4byte _data - ImageBase // PointerToRawData + .4byte 0 // PointerToRelocations + .4byte 0 // PointerToLineNumbers + .2byte 0 // NumberOfRelocations + .2byte 0 // NumberOfLineNumbers + .4byte 0xC0000040 // Characteristics (section flags) + + .ascii ".rodata\0" + .4byte _rodata_vsize - ImageBase // VirtualSize + .4byte _rodata - ImageBase // VirtualAddress + .4byte _rodata_size - ImageBase // SizeOfRawData + .4byte _rodata - ImageBase // PointerToRawData + .4byte 0 // PointerToRelocations + .4byte 0 // PointerToLineNumbers + .2byte 0 // NumberOfRelocations + .2byte 0 // NumberOfLineNumbers + .4byte 0x40000040 // Characteristics (section flags) + + .text .globl _start + .type _start,%function _start: addi sp, sp, -24 sd a0, 0(sp) @@ -130,11 +164,24 @@ _start: bne a0, zero, 0f ld a1, 8(sp) ld a0, 0(sp) - call efi_main + call _entry ld ra, 16(sp) 0: addi sp, sp, 24 ret +// 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/crt0-efi-x86_64.S b/gnuefi/crt0-efi-x86_64.S index 49f0a0d..b1f599f 100644 --- a/gnuefi/crt0-efi-x86_64.S +++ b/gnuefi/crt0-efi-x86_64.S @@ -38,6 +38,7 @@ .align 4 .globl _start + .type _start,%function _start: subq $8, %rsp pushq %rcx @@ -56,7 +57,7 @@ _start: popq %rdi popq %rsi - call efi_main + call _entry addq $8, %rsp .exit: @@ -65,15 +66,15 @@ _start: // hand-craft a dummy .reloc section so EFI knows it's a relocatable executable: .data -dummy: .long 0 +dummy: .4byte 0 #define IMAGE_REL_ABSOLUTE 0 .section .reloc, "a" label1: - .long dummy-label1 // Page RVA - .long 12 // Block Size (2*4+2*2), must be aligned by 32 Bits - .word (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy - .word (IMAGE_REL_ABSOLUTE<<12) + 0 // reloc for dummy + .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 diff --git a/gnuefi/elf_aarch64_efi.lds b/gnuefi/elf_aarch64_efi.lds index 836d982..d017669 100644 --- a/gnuefi/elf_aarch64_efi.lds +++ b/gnuefi/elf_aarch64_efi.lds @@ -3,20 +3,34 @@ OUTPUT_ARCH(aarch64) 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.*) - *(.srodata) - *(.rodata*) + *(.plt) . = ALIGN(16); } _etext = .; - _text_size = . - _text; + _text_size = _etext - _text; + . = ALIGN(65536); + .reloc : + { + KEEP (*(.reloc)) + } + . = ALIGN(4096); .dynamic : { *(.dynamic) } - .data : ALIGN(4096) + . = ALIGN(4096); + .data : { _data = .; *(.sdata) @@ -26,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); @@ -33,19 +74,35 @@ 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); _edata = .; - _data_size = . - _data; + _data_size = _edata - _data; . = ALIGN(4096); .dynsym : { *(.dynsym) } @@ -53,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) } diff --git a/gnuefi/elf_arm_efi.lds b/gnuefi/elf_arm_efi.lds index 665bbdb..cae55ea 100644 --- a/gnuefi/elf_arm_efi.lds +++ b/gnuefi/elf_arm_efi.lds @@ -3,22 +3,36 @@ OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { - .text 0x0 : { - _text = .; + .text 0 : { *(.text.head) + _text = .; *(.text) *(.text.*) *(.gnu.linkonce.t.*) - *(.srodata) - *(.rodata*) + *(.plt) . = ALIGN(16); - } - _etext = .; - _text_size = . - _text; + _evtext = .; + . = ALIGN(4096); + _etext = .; + } =0 + _text_vsize = _evtext - _text; + _text_size = _etext - _text; + . = ALIGN(4096); + _reloc = .; + .areloc : { + *(.areloc) + _evreloc = .; + . = ALIGN(4096); + _ereloc = .; + } =0 + _reloc_vsize = _evreloc - _reloc; + _reloc_size = _ereloc - _reloc; + . = ALIGN(4096); + _data = .; .dynamic : { *(.dynamic) } + . = ALIGN(4096); .data : { - _data = .; *(.sdata) *(.data) *(.data1) @@ -26,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); @@ -38,14 +79,41 @@ SECTIONS *(COMMON) . = ALIGN(16); _bss_end = .; - } + _evdata = .; + . = ALIGN(4096); + _edata = .; + } =0 + _data_vsize = _evdata - _data; + _data_size = _edata - _data; - .rel.dyn : { *(.rel.dyn) } + . = ALIGN(4096); + _rodata = .; + .rel : + { + *(.rel.text*) + *(.rel.data*) + *(.rel.got) + *(.rel.dyn) + *(.rel.stab) + *(.rel.init_array*) + *(.rel.fini_array*) + *(.rel.ctors*) + *(.rel.dtors*) + + } + . = ALIGN(4096); .rel.plt : { *(.rel.plt) } - .rel.got : { *(.rel.got) } - .rel.data : { *(.rel.data) *(.rel.data*) } - _edata = .; - _data_size = . - _etext; + . = ALIGN(4096); + .rodata : { + *(.rodata*) + _evrodata = .; + . = ALIGN(4096); + _erodata = .; + } =0 + _rodata_vsize = _evrodata - _rodata; + _rodata_size = _erodata - _rodata; + _image_end = .; + _alldata_size = _image_end - _reloc; . = ALIGN(4096); .dynsym : { *(.dynsym) } @@ -53,10 +121,16 @@ SECTIONS .dynstr : { *(.dynstr) } . = ALIGN(4096); .note.gnu.build-id : { *(.note.gnu.build-id) } + . = ALIGN(4096); + .hash : { *(.hash) } + . = ALIGN(4096); + .gnu.hash : { *(.gnu.hash) } + . = ALIGN(4096); + .ARM.exidx : { *(.ARM.exidx*) } + .ARM.extab : { *(.ARM.extab*) } /DISCARD/ : { - *(.rel.reloc) - *(.eh_frame) + *(.rel.areloc) *(.note.GNU-stack) } .comment 0 : { *(.comment) } diff --git a/gnuefi/elf_ia32_efi.lds b/gnuefi/elf_ia32_efi.lds index f27fe5f..1361454 100644 --- a/gnuefi/elf_ia32_efi.lds +++ b/gnuefi/elf_ia32_efi.lds @@ -8,6 +8,8 @@ SECTIONS /* .hash and/or .gnu.hash MUST come first! */ .hash : { *(.hash) } .gnu.hash : { *(.gnu.hash) } + .eh_frame : { *(.eh_frame) } + .gcc_except_table : { *(.gcc_except_table*) } . = ALIGN(4096); .text : { @@ -15,37 +17,52 @@ SECTIONS *(.text) *(.text.*) *(.gnu.linkonce.t.*) + *(.plt) . = ALIGN(16); } _etext = .; - _text_size = . - _text; - . = ALIGN(4096); - .sdata : + _text_size = _etext - _text; + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); + .data : { _data = .; *(.got.plt) *(.got) - *(.srodata) - *(.sdata) - *(.sbss) - *(.scommon) - } - . = ALIGN(4096); - .data : - { - *(.rodata*) *(.data) *(.data1) *(.data.*) - *(.sdata) - *(.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: */ - *(.sbss) - *(.scommon) *(.dynbss) - *(.bss) + *(.bss*) *(COMMON) } .note.gnu.build-id : { *(.note.gnu.build-id) } @@ -55,31 +72,40 @@ SECTIONS . = ALIGN(4096); .rel : { - *(.rel.data) - *(.rel.data.*) + *(.rel.text*) + *(.rel.data*) *(.rel.got) + *(.rel.dyn) *(.rel.stab) + *(.rel.init_array*) + *(.rel.fini_array*) + *(.rel.ctors*) + *(.rel.dtors*) *(.data.rel.ro.local) *(.data.rel.local) *(.data.rel.ro) *(.data.rel*) } + . = ALIGN(4096); + .rel.plt : { *(.rel.plt) } + . = ALIGN(4096); + .rodata : { *(.rodata*) } _edata = .; - _data_size = . - _etext; + _data_size = _edata - _etext; . = ALIGN(4096); .reloc : /* This is the PECOFF .reloc section! */ { - *(.reloc) + KEEP (*(.reloc)) } . = ALIGN(4096); .dynsym : { *(.dynsym) } . = ALIGN(4096); .dynstr : { *(.dynstr) } . = ALIGN(4096); + . = DATA_SEGMENT_END (.); /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 index cd309e2..650000c 100644 --- a/gnuefi/elf_ia32_fbsd_efi.lds +++ b/gnuefi/elf_ia32_fbsd_efi.lds @@ -18,7 +18,7 @@ SECTIONS . = ALIGN(16); } _etext = .; - _text_size = . - _text; + _text_size = _etext - _text; . = ALIGN(4096); .sdata : { @@ -40,6 +40,34 @@ SECTIONS *(.sdata) *(.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: */ *(.sbss) @@ -59,13 +87,17 @@ SECTIONS *(.rel.data.*) *(.rel.got) *(.rel.stab) + *(.rel.init_array*) + *(.rel.fini_array*) + *(.rel.ctors*) + *(.rel.dtors*) *(.data.rel.ro.local) *(.data.rel.local) *(.data.rel.ro) *(.data.rel*) } _edata = .; - _data_size = . - _etext; + _data_size = _edata - _etext; . = ALIGN(4096); .reloc : /* This is the PECOFF .reloc section! */ { diff --git a/gnuefi/elf_ia64_efi.lds b/gnuefi/elf_ia64_efi.lds index 190792a..eb8a7ad 100644 --- a/gnuefi/elf_ia64_efi.lds +++ b/gnuefi/elf_ia64_efi.lds @@ -8,6 +8,8 @@ SECTIONS /* .hash and/or .gnu.hash MUST come first! */ .hash : { *(.hash) } .gnu.hash : { *(.gnu.hash) } + .eh_frame : { *(.eh_frame) } + .gcc_except_table : { *(.gcc_except_table*) } . = ALIGN(4096); .text : { @@ -15,11 +17,12 @@ SECTIONS *(.text) *(.text.*) *(.gnu.linkonce.t.*) + *(.plt) . = ALIGN(16); } _etext = .; - _text_size = . - _text; - . = ALIGN(4096); + _text_size = _etext - _text; + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); __gp = ALIGN (8) + 0x200000; .sdata : { @@ -39,10 +42,38 @@ SECTIONS *(.data*) *(.gnu.linkonce.d*) *(.plabel) /* data whose relocs we want to ignore */ + + /* + * 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: */ *(.dynbss) - *(.bss) + *(.bss*) *(COMMON) } .note.gnu.build-id : { *(.note.gnu.build-id) } @@ -52,25 +83,32 @@ SECTIONS . = ALIGN(4096); .rela : { - *(.rela.text) + *(.rela.text*) + *(.rela.sdata*) *(.rela.data*) - *(.rela.sdata) *(.rela.got) + *(.rela.dyn) *(.rela.gnu.linkonce.d*) *(.rela.stab) - *(.rela.ctors) + *(.rela.init_array*) + *(.rela.fini_array*) + *(.rela.ctors*) + *(.rela.dtors*) } + . = ALIGN(4096); + .rela.plt : { *(.rela.plt) } _edata = .; - _data_size = . - _etext; + _data_size = _edata - _etext; . = ALIGN(4096); .reloc : /* This is the PECOFF .reloc section! */ { - *(.reloc) + KEEP (*(.reloc)) } . = ALIGN(4096); .dynsym : { *(.dynsym) } . = ALIGN(4096); .dynstr : { *(.dynstr) } + . = DATA_SEGMENT_END (.); /DISCARD/ : { *(.rela.plabel) diff --git a/gnuefi/elf_loongarch64_efi.lds b/gnuefi/elf_loongarch64_efi.lds new file mode 100644 index 0000000..57d046d --- /dev/null +++ b/gnuefi/elf_loongarch64_efi.lds @@ -0,0 +1,119 @@ +OUTPUT_FORMAT("elf64-loongarch", "elf64-loongarch", "elf64-loongarch") +OUTPUT_ARCH(loongarch) +ENTRY(_start) +SECTIONS +{ + . = 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) + *(.text.*) + *(.gnu.linkonce.t.*) + *(.plt) + . = ALIGN(16); + } + _etext = .; + _text_size = _etext - _text; + . = ALIGN(4096); + .reloc : + { + KEEP (*(.reloc)) + } + . = ALIGN(65536); + .dynamic : { *(.dynamic) } + . = ALIGN(4096); + .data : + { + _data = .; + *(.sdata) + *(.data) + *(.data1) + *(.data.*) + *(.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); + _bss = .; + *(.sbss) + *(.scommon) + *(.dynbss) + *(.bss*) + *(COMMON) + *(.rel.local) + . = ALIGN(16); + + _bss_end = .; + } + + . = 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) } + . = ALIGN(4096); + .rodata : { *(.rodata*) } + . = ALIGN(512); + _edata = .; + _data_size = _edata - _data; + + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } + . = ALIGN(4096); + .note.gnu.build-id : { *(.note.gnu.build-id) } + .ignored.reloc : + { + *(.rela.reloc) + *(.note.GNU-stack) + } + .comment 0 : { *(.comment) } +} diff --git a/gnuefi/elf_mips64el_efi.lds b/gnuefi/elf_mips64el_efi.lds index 4d1a077..a0d1a5b 100644 --- a/gnuefi/elf_mips64el_efi.lds +++ b/gnuefi/elf_mips64el_efi.lds @@ -9,13 +9,14 @@ SECTIONS *(.text) *(.text.*) *(.gnu.linkonce.t.*) - *(.srodata) - *(.rodata*) + *(.plt) . = ALIGN(16); } _etext = .; - _text_size = . - _text; + _text_size = _etext - _text; + . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); .dynamic : { *(.dynamic) } + . = ALIGN(4096); .data : { _data = .; @@ -27,6 +28,33 @@ SECTIONS HIDDEN (_gp = ALIGN (16) + 0x7ff0); *(.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); @@ -34,18 +62,31 @@ SECTIONS *(.sbss) *(.scommon) *(.dynbss) - *(.bss) + *(.bss*) *(COMMON) . = ALIGN(16); _bss_end = .; } - .rel.dyn : { *(.rel.dyn) } + . = ALIGN(4096); + .rel : + { + *(.rel.text*) + *(.rel.data*) + *(.rel.got) + *(.rel.dyn) + *(.rel.stab) + *(.rel.init_array*) + *(.rel.fini_array*) + *(.rel.ctors*) + *(.rel.dtors*) + } + . = ALIGN(4096); .rel.plt : { *(.rel.plt) } - .rel.got : { *(.rel.got) } - .rel.data : { *(.rel.data) *(.rel.data*) } + . = ALIGN(4096); + .rodata : { *(.rodata*) } _edata = .; - _data_size = . - _etext; + _data_size = _edata - _etext; . = ALIGN(4096); .dynsym : { *(.dynsym) } @@ -53,6 +94,7 @@ SECTIONS .dynstr : { *(.dynstr) } . = ALIGN(4096); .note.gnu.build-id : { *(.note.gnu.build-id) } + . = DATA_SEGMENT_END (.); /DISCARD/ : { *(.rel.reloc) diff --git a/gnuefi/elf_riscv64_efi.lds b/gnuefi/elf_riscv64_efi.lds index bb64d81..ac7055a 100644 --- a/gnuefi/elf_riscv64_efi.lds +++ b/gnuefi/elf_riscv64_efi.lds @@ -1,77 +1,142 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause */ OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv") OUTPUT_ARCH(riscv) 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) +SECTIONS +{ + .text 0 : { + *(.text.head) + . = ALIGN(4096); + _text = .; + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + *(.plt) + . = ALIGN(16); + _evtext = .; + . = ALIGN(4096); + _etext = .; + } =0 + _text_vsize = _evtext - _text; + _text_size = _etext - _text; + . = ALIGN(4096); + _reloc = .; + .reloc : { + *(.reloc) + _evreloc = .; + . = ALIGN(4096); + _ereloc = .; + } =0 + _reloc_vsize = _evreloc - _reloc; + _reloc_size = _ereloc - _reloc; + . = ALIGN(4096); + _data = .; + .dynamic : { *(.dynamic) } + . = 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 = .; - } + /* + * 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 = .; -.rela.text : - { *(.rela.text) *(.rela.text*) } -.rela.dyn : - { *(.rela.dyn) } -.rela.plt : - { *(.rela.plt) } -.rela.got : - { *(.rela.got) } -.rela.data : - { *(.rela.data) *(.rela.data*) } - . = ALIGN(512); - _edata = .; - _data_size = . - _data; + /* 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) + *(.bss.*) + *(COMMON) + . = ALIGN(16); + _bss_end = .; + _evdata = .; + . = ALIGN(4096); + _edata = .; + } =0 + _data_vsize = _evdata - _data; + _data_size = _edata - _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) } + . = ALIGN(4096); + _rodata = .; + .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) } + . = ALIGN(4096); + .rodata : { + *(.rodata*) + _evrodata = .; + . = ALIGN(4096); + _erodata = .; + } =0 + _rodata_vsize = _evrodata - _rodata; + _rodata_size = _erodata - _rodata; + _image_end = .; + _alldata_size = _image_end - _reloc; + + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } + . = ALIGN(4096); + .note.gnu.build-id : { *(.note.gnu.build-id) } + . = ALIGN(4096); + .hash : { *(.hash) } + . = ALIGN(4096); + .gnu.hash : { *(.gnu.hash) } + . = ALIGN(4096); + .eh_frame : { *(.eh_frame) } + . = ALIGN(4096); + .gcc_except_table : { *(.gcc_except_table*) } + /DISCARD/ : + { + *(.rela.reloc) + *(.note.GNU-stack) + } + .comment 0 : { *(.comment) } } + diff --git a/gnuefi/elf_x86_64_efi.lds b/gnuefi/elf_x86_64_efi.lds index 7be5902..e9f395e 100644 --- a/gnuefi/elf_x86_64_efi.lds +++ b/gnuefi/elf_x86_64_efi.lds @@ -10,10 +10,8 @@ SECTIONS .hash : { *(.hash) } .gnu.hash : { *(.gnu.hash) } . = ALIGN(4096); - .eh_frame : - { - *(.eh_frame) - } + .eh_frame : { *(.eh_frame) } + .gcc_except_table : { *(.gcc_except_table*) } . = ALIGN(4096); .text : { @@ -21,47 +19,86 @@ SECTIONS *(.text) *(.text.*) *(.gnu.linkonce.t.*) + *(.plt) . = ALIGN(16); } _etext = .; - _text_size = . - _text; + _text_size = _etext - _text; . = ALIGN(4096); .reloc : { - *(.reloc) + KEEP (*(.reloc)) } + . = ALIGN(4096); .data : { _data = .; - *(.rodata*) *(.got.plt) *(.got) *(.data*) *(.sdata) + + /* + * 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: */ *(.sbss) *(.scommon) *(.dynbss) - *(.bss) + *(.bss*) *(COMMON) *(.rel.local) } .note.gnu.build-id : { *(.note.gnu.build-id) } _edata = .; - _data_size = . - _etext; + _data_size = _edata - _etext; . = ALIGN(4096); .dynamic : { *(.dynamic) } . = 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) } + . = ALIGN(4096); + .rodata : { *(.rodata*) } + . = ALIGN(4096); .dynsym : { *(.dynsym) } . = ALIGN(4096); .dynstr : { *(.dynstr) } @@ -69,7 +106,6 @@ SECTIONS .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 index fe1f334..a0dc6c0 100644 --- a/gnuefi/elf_x86_64_fbsd_efi.lds +++ b/gnuefi/elf_x86_64_fbsd_efi.lds @@ -22,7 +22,7 @@ SECTIONS . = ALIGN(16); } _etext = .; - _text_size = . - _text; + _text_size = _etext - _text; .reloc : { *(.reloc) @@ -31,11 +31,38 @@ SECTIONS .data : { _data = .; - *(.rodata*) *(.got.plt) *(.got) *(.data*) *(.sdata) + + /* + * 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: */ *(.sbss) @@ -55,9 +82,15 @@ SECTIONS *(.rela.data*) *(.rela.got) *(.rela.stab) + *(.rela.init_array*) + *(.rela.fini_array*) + *(.rela.ctors*) + *(.rela.dtors*) } + . = ALIGN(4096); + .rodata : { *(.rodata*) } _edata = .; - _data_size = . - _etext; + _data_size = _edata - _etext; . = ALIGN(4096); .dynsym : { *(.dynsym) } . = ALIGN(4096); diff --git a/gnuefi/gnu-efi.pc.in b/gnuefi/gnu-efi.pc.in new file mode 100644 index 0000000..9280bc0 --- /dev/null +++ b/gnuefi/gnu-efi.pc.in @@ -0,0 +1,10 @@ +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +includedir=@INCLUDEDIR@ +libdir=@LIBDIR@ + +Name: gnu-efi +Description: EFI development toolkit +Version: @VERSION@ +Cflags: -I${includedir}/efi +Libs: -lefi 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. + Copyright (C) 2014 Linaro Ltd. + Copyright (C) 1999 Hewlett-Packard Co. + Contributed by David Mosberger . + + 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 +#include + +#include + +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; +} diff --git a/gnuefi/reloc_riscv64.c b/gnuefi/reloc_riscv64.c index 73e8d13..e429602 100644 --- a/gnuefi/reloc_riscv64.c +++ b/gnuefi/reloc_riscv64.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause /* reloc_riscv.c - position independent ELF shared object relocator Copyright (C) 2018 Alexander Graf Copyright (C) 2014 Linaro Ltd. @@ -81,8 +81,7 @@ EFI_STATUS EFIAPI _relocate(long ldbase, Elf_Dyn *dyn) *addr = ldbase + rel->r_addend; break; default: - /* Panic */ - while (1) ; + break; } rel = (Elf_Rela *)((char *)rel + relent); relsz -= relent; diff --git a/inc/Makefile b/inc/Makefile index 273d303..b5de1fa 100644 --- a/inc/Makefile +++ b/inc/Makefile @@ -1,27 +1,24 @@ SRCDIR = . VPATH = $(SRCDIR) - -include $(SRCDIR)/../Make.defaults - TOPDIR = $(SRCDIR)/.. -CDIR=$(TOPDIR)/.. +include $(SRCDIR)/../Make.defaults all: clean: install: - mkdir -p $(INSTALLROOT)$(PREFIX)/include/efi - mkdir -p $(INSTALLROOT)$(PREFIX)/include/efi/protocol - mkdir -p $(INSTALLROOT)$(PREFIX)/include/efi/$(ARCH) - $(INSTALL) -m 644 $(SRCDIR)/*.h $(INSTALLROOT)$(PREFIX)/include/efi - $(INSTALL) -m 644 $(SRCDIR)/protocol/*.h $(INSTALLROOT)$(PREFIX)/include/efi/protocol - $(INSTALL) -m 644 $(SRCDIR)/$(ARCH)/*.h $(INSTALLROOT)$(PREFIX)/include/efi/$(ARCH) + mkdir -p $(INSTALLROOT)$(INCLUDEDIR)/efi + mkdir -p $(INSTALLROOT)$(INCLUDEDIR)/efi/protocol + mkdir -p $(INSTALLROOT)$(INCLUDEDIR)/efi/$(ARCH) + $(INSTALL) -m 644 $(SRCDIR)/*.h $(INSTALLROOT)$(INCLUDEDIR)/efi + $(INSTALL) -m 644 $(SRCDIR)/protocol/*.h $(INSTALLROOT)$(INCLUDEDIR)/efi/protocol + $(INSTALL) -m 644 $(SRCDIR)/$(ARCH)/*.h $(INSTALLROOT)$(INCLUDEDIR)/efi/$(ARCH) ifeq ($(ARCH),ia64) - mkdir -p $(INSTALLROOT)$(PREFIX)/include/efi/protocol/ia64 - $(INSTALL) -m 644 $(SRCDIR)/protocol/ia64/*.h $(INSTALLROOT)$(PREFIX)/include/efi/protocol/ia64 + mkdir -p $(INSTALLROOT)$(INCLUDEDIR)/efi/protocol/ia64 + $(INSTALL) -m 644 $(SRCDIR)/protocol/ia64/*.h $(INSTALLROOT)$(INCLUDEDIR)/efi/protocol/ia64 endif include $(SRCDIR)/../Make.rules diff --git a/inc/aarch64/efibind.h b/inc/aarch64/efibind.h index c2c546b..d6b5d0f 100644 --- a/inc/aarch64/efibind.h +++ b/inc/aarch64/efibind.h @@ -38,9 +38,10 @@ typedef int64_t intptr_t; // Basic EFI types of various widths // -#ifndef __WCHAR_TYPE__ -# define __WCHAR_TYPE__ short -#endif +#include + +typedef wchar_t CHAR16; +#define WCHAR CHAR16 typedef uint64_t UINT64; typedef int64_t INT64; @@ -50,12 +51,13 @@ typedef int32_t INT32; typedef uint16_t UINT16; typedef int16_t INT16; + typedef uint8_t UINT8; +typedef char CHAR8; typedef int8_t INT8; -typedef __WCHAR_TYPE__ WCHAR; #undef VOID -#define VOID void +typedef void VOID; typedef int64_t INTN; typedef uint64_t UINTN; diff --git a/inc/aarch64/efisetjmp_arch.h b/inc/aarch64/efisetjmp_arch.h index 8dbce07..74e1f87 100644 --- a/inc/aarch64/efisetjmp_arch.h +++ b/inc/aarch64/efisetjmp_arch.h @@ -18,6 +18,7 @@ typedef struct { UINT64 FP; UINT64 LR; UINT64 IP0; + UINT64 _pad1; /* FP regs */ UINT64 D8; @@ -28,6 +29,6 @@ typedef struct { UINT64 D13; UINT64 D14; UINT64 D15; -} ALIGN(JMPBUF_ALIGN) jmp_buf[1]; +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; #endif /* GNU_EFI_AARCH64_SETJMP_H */ diff --git a/inc/arm/efibind.h b/inc/arm/efibind.h index 9e2cb10..8c578df 100644 --- a/inc/arm/efibind.h +++ b/inc/arm/efibind.h @@ -46,9 +46,10 @@ typedef int32_t intptr_t; // Basic EFI types of various widths // -#ifndef __WCHAR_TYPE__ -# define __WCHAR_TYPE__ short -#endif +#include + +typedef wchar_t CHAR16; +#define WCHAR CHAR16 typedef uint64_t UINT64; typedef int64_t INT64; @@ -58,12 +59,13 @@ typedef int32_t INT32; typedef uint16_t UINT16; typedef int16_t INT16; + typedef uint8_t UINT8; +typedef char CHAR8; typedef int8_t INT8; -typedef __WCHAR_TYPE__ WCHAR; #undef VOID -#define VOID void +typedef void VOID; typedef int32_t INTN; typedef uint32_t UINTN; diff --git a/inc/arm/efisetjmp_arch.h b/inc/arm/efisetjmp_arch.h index 17f5dc0..b809453 100644 --- a/inc/arm/efisetjmp_arch.h +++ b/inc/arm/efisetjmp_arch.h @@ -16,6 +16,6 @@ typedef struct { UINT32 R12; UINT32 R13; UINT32 R14; -} ALIGN(JMPBUF_ALIGN) jmp_buf[1]; +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; #endif /* GNU_EFI_ARM_SETJMP_H */ diff --git a/inc/efi.h b/inc/efi.h index b193932..6d83374 100644 --- a/inc/efi.h +++ b/inc/efi.h @@ -33,6 +33,10 @@ Revision History #ifndef _EFI_INCLUDE_ #define _EFI_INCLUDE_ +#ifdef __cplusplus +extern "C" { +#endif + #define EFI_FIRMWARE_VENDOR L"INTEL" #define EFI_FIRMWARE_MAJOR_REVISION 12 #define EFI_FIRMWARE_MINOR_REVISION 33 @@ -52,6 +56,8 @@ Revision History #include "mips64el/efibind.h" #elif defined (__riscv) && __riscv_xlen == 64 #include "riscv64/efibind.h" +#elif defined (__loongarch64) +#include "loongarch64/efibind.h" #else #error Usupported architecture #endif @@ -77,4 +83,8 @@ Revision History #include "efipoint.h" #include "efishell.h" +#ifdef __cplusplus +} +#endif + #endif diff --git a/inc/efiapi.h b/inc/efiapi.h index 7dbedc4..778d513 100644 --- a/inc/efiapi.h +++ b/inc/efiapi.h @@ -24,8 +24,10 @@ Revision History // EFI Specification Revision // +#define EFI_SPECIFICATION_REVISION_MAJORMINOR(major, minor) ((major<<16) | (minor)) #define EFI_SPECIFICATION_MAJOR_REVISION 1 #define EFI_SPECIFICATION_MINOR_REVISION 02 +#define EFI_SPECIFICATION_VERSION EFI_SPECIFICATION_REVISION_MAJORMINOR(EFI_SPECIFICATION_MAJOR_REVISION, EFI_SPECIFICATION_MINOR_REVISION) // // Declare forward referenced data structures @@ -229,6 +231,7 @@ VOID #define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010 #define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS 0x00000020 #define EFI_VARIABLE_APPEND_WRITE 0x00000040 +#define EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS 0x00000080 // Variable size limitation #define EFI_MAXIMUM_VARIABLE_SIZE 1024 @@ -354,6 +357,14 @@ EFI_STATUS #define EFI_IMAGE_MACHINE_RISCV128 0x5128 #endif +#if !defined(EFI_IMAGE_MACHINE_LOONGARCH32) +#define EFI_IMAGE_MACHINE_LOONGARCH32 0x6232 +#endif + +#if !defined(EFI_IMAGE_MACHINE_LOONGARCH64) +#define EFI_IMAGE_MACHINE_LOONGARCH64 0x6264 +#endif + // Image Entry prototype typedef @@ -762,8 +773,22 @@ typedef struct _EFI_TABLE_HEADER { // EFI Runtime Serivces Table // -#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552 -#define EFI_RUNTIME_SERVICES_REVISION (EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION) +#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552 +#define EFI_1_02_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(1, 02) +#define EFI_1_10_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(1, 10) +#define EFI_2_00_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 00) +#define EFI_2_10_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 10) +#define EFI_2_20_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 20) +#define EFI_2_30_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 30) +#define EFI_2_31_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 31) +#define EFI_2_40_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 40) +#define EFI_2_50_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 50) +#define EFI_2_60_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 60) +#define EFI_2_70_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 70) +#define EFI_2_80_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 80) +#define EFI_2_90_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 90) +#define EFI_2_100_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 100) +#define EFI_RUNTIME_SERVICES_REVISION EFI_SPECIFICATION_VERSION typedef struct { EFI_TABLE_HEADER Hdr; @@ -809,8 +834,22 @@ typedef struct { // EFI Boot Services Table // -#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42 -#define EFI_BOOT_SERVICES_REVISION (EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION) +#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42 +#define EFI_1_02_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(1, 02) +#define EFI_1_10_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(1, 10) +#define EFI_2_00_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 00) +#define EFI_2_10_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 10) +#define EFI_2_20_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 20) +#define EFI_2_30_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 30) +#define EFI_2_31_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 31) +#define EFI_2_40_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 40) +#define EFI_2_50_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 50) +#define EFI_2_60_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 60) +#define EFI_2_70_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 70) +#define EFI_2_80_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 80) +#define EFI_2_90_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 90) +#define EFI_2_100_BOOT_SERVICES_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 100) +#define EFI_BOOT_SERVICES_REVISION EFI_SPECIFICATION_VERSION typedef struct _EFI_BOOT_SERVICES { @@ -952,7 +991,21 @@ typedef struct _EFI_CONFIGURATION_TABLE { #define EFI_SYSTEM_TABLE_SIGNATURE 0x5453595320494249 -#define EFI_SYSTEM_TABLE_REVISION (EFI_SPECIFICATION_MAJOR_REVISION<<16) | (EFI_SPECIFICATION_MINOR_REVISION) +#define EFI_1_02_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(1, 02) +#define EFI_1_10_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(1, 10) +#define EFI_2_00_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 00) +#define EFI_2_10_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 10) +#define EFI_2_20_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 20) +#define EFI_2_30_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 30) +#define EFI_2_31_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 31) +#define EFI_2_40_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 40) +#define EFI_2_50_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 50) +#define EFI_2_60_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 60) +#define EFI_2_70_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 70) +#define EFI_2_80_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 80) +#define EFI_2_90_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 90) +#define EFI_2_100_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_REVISION_MAJORMINOR(2, 100) +#define EFI_SYSTEM_TABLE_REVISION EFI_SPECIFICATION_VERSION typedef struct _EFI_SYSTEM_TABLE { EFI_TABLE_HEADER Hdr; diff --git a/inc/eficompiler.h b/inc/eficompiler.h index 26636c7..6f6ff7d 100644 --- a/inc/eficompiler.h +++ b/inc/eficompiler.h @@ -19,9 +19,39 @@ Abstract: #endif #ifdef _MSC_EXTENSIONS -#define ALIGN(x) __declspec(align(x)) +#define EFI_NO_TAIL_CALL #else -#define ALIGN(x) __attribute__((__aligned__(x))) +#ifdef __clang__ +#define EFI_NO_TAIL_CALL __attribute__((disable_tail_calls)) +#else +#define EFI_NO_TAIL_CALL __attribute__((optimize("no-optimize-sibling-calls"))) +#endif +#endif + +#ifdef _MSC_EXTENSIONS +#define EFI_OPTNONE +#else +#ifdef __clang__ +#define EFI_OPTNONE __attribute__((optnone)) +#else +#define EFI_OPTNONE __attribute__((__optimize__("0"))) +#endif +#endif + +#ifdef _MSC_EXTENSIONS +#define EFI_ALIGN(x) __declspec(align(x)) +#else +#define EFI_ALIGN(x) __attribute__((__aligned__(x))) +#endif + +#ifndef ALIGN +#define ALIGN(x) EFI_ALIGN(x) +#endif + +#ifdef _MSC_EXTENSIONS +#define EFI_NORETURN __declspec(noreturn) +#else +#define EFI_NORETURN __attribute__((noreturn)) #endif /* Also add a catch-all on __attribute__() for MS compilers */ diff --git a/inc/efidef.h b/inc/efidef.h index 8b70051..2934b11 100644 --- a/inc/efidef.h +++ b/inc/efidef.h @@ -20,19 +20,39 @@ Revision History --*/ -typedef UINT16 CHAR16; -typedef UINT8 CHAR8; -typedef UINT8 BOOLEAN; +#if !defined(__cplusplus) +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +typedef _Bool BOOLEAN; +#else +typedef unsigned char BOOLEAN; +#endif +#else +typedef bool BOOLEAN; +#endif + #ifndef CONST #define CONST const #endif #ifndef TRUE +#if defined(__cplusplus) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) + #define TRUE true + #define FALSE false +#else #define TRUE ((BOOLEAN) 1) #define FALSE ((BOOLEAN) 0) #endif +#endif #ifndef NULL +#if (defined(__cplusplus) && __cplusplus >= 201103L) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L) + #define NULL nullptr +#else +#if !defined(__cplusplus) #define NULL ((VOID *) 0) +#else + #define NULL 0 +#endif +#endif #endif typedef UINTN EFI_STATUS; @@ -162,23 +182,36 @@ typedef enum { EfiMemoryMappedIO, EfiMemoryMappedIOPortSpace, EfiPalCode, + EfiPersistentMemory, + EfiUnacceptedMemoryType, EfiMaxMemoryType } EFI_MEMORY_TYPE; -// possible caching types for the memory range -#define EFI_MEMORY_UC 0x0000000000000001 -#define EFI_MEMORY_WC 0x0000000000000002 -#define EFI_MEMORY_WT 0x0000000000000004 -#define EFI_MEMORY_WB 0x0000000000000008 -#define EFI_MEMORY_UCE 0x0000000000000010 -// physical memory protection on range -#define EFI_MEMORY_WP 0x0000000000001000 -#define EFI_MEMORY_RP 0x0000000000002000 -#define EFI_MEMORY_XP 0x0000000000004000 +// Memory cacheability attribute +#define EFI_MEMORY_UC 0x0000000000000001 +#define EFI_MEMORY_WC 0x0000000000000002 +#define EFI_MEMORY_WT 0x0000000000000004 +#define EFI_MEMORY_WB 0x0000000000000008 +#define EFI_MEMORY_UCE 0x0000000000000010 + +// Physical memory protection attribute +#define EFI_MEMORY_WP 0x0000000000001000 +#define EFI_MEMORY_RP 0x0000000000002000 +#define EFI_MEMORY_XP 0x0000000000004000 +#define EFI_MEMORY_RO 0x0000000000020000 + +// Runtime memory attribute +#define EFI_MEMORY_NV 0x0000000000008000 +#define EFI_MEMORY_RUNTIME 0x8000000000000000 + +// Other memory attribute +#define EFI_MEMORY_MORE_RELIABLE 0x0000000000010000 +#define EFI_MEMORY_SP 0x0000000000040000 +#define EFI_MEMORY_CPU_CRYPTO 0x0000000000080000 +#define EFI_MEMORY_ISA_VALID 0x4000000000000000 +#define EFI_MEMORY_ISA_MASK 0x0FFFF00000000000 -// range requires a runtime mapping -#define EFI_MEMORY_RUNTIME 0x8000000000000000 #define EFI_MEMORY_DESCRIPTOR_VERSION 1 typedef struct { @@ -194,7 +227,7 @@ typedef struct { // International Language // -typedef UINT8 ISO_639_2; +typedef CHAR8 ISO_639_2; #define ISO_639_2_ENTRY_SIZE 3 // @@ -216,5 +249,10 @@ typedef UINT8 ISO_639_2; 0x0000000000000008 #define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED \ 0x0000000000000010 +#define EFI_OS_INDICATIONS_START_OS_RECOVERY 0x0000000000000020 +#define EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY \ + 0x0000000000000040 +#define EFI_OS_INDICATIONS_JSON_CONFIG_DATA_REFRESH \ + 0x0000000000000080 #endif diff --git a/inc/efierr.h b/inc/efierr.h index 5a66e1a..ac9ef7b 100644 --- a/inc/efierr.h +++ b/inc/efierr.h @@ -57,12 +57,17 @@ Revision History #define EFI_END_OF_FILE EFIERR(31) #define EFI_INVALID_LANGUAGE EFIERR(32) #define EFI_COMPROMISED_DATA EFIERR(33) +#define EFI_IP_ADDRESS_CONFLICT EFIERR(34) +#define EFI_HTTP_ERROR EFIERR(35) #define EFI_WARN_UNKOWN_GLYPH EFIWARN(1) #define EFI_WARN_UNKNOWN_GLYPH EFIWARN(1) #define EFI_WARN_DELETE_FAILURE EFIWARN(2) #define EFI_WARN_WRITE_FAILURE EFIWARN(3) #define EFI_WARN_BUFFER_TOO_SMALL EFIWARN(4) +#define EFI_WARN_STALE_DATA EFIWARN(5) +#define EFI_WARN_FILE_SYSTEM EFIWARN(6) +#define EFI_WARN_RESET_REQUIRED EFIWARN(7) #endif diff --git a/inc/efilib.h b/inc/efilib.h index a2b39b2..f35d2ed 100644 --- a/inc/efilib.h +++ b/inc/efilib.h @@ -19,6 +19,10 @@ Revision History --*/ +#ifdef __cplusplus +extern "C" { +#endif + #include "efidebug.h" #include "efipart.h" #if defined(_M_X64) || defined(__x86_64__) || defined(__amd64__) @@ -35,6 +39,8 @@ Revision History #include "mips64el/efilibplat.h" #elif defined (__riscv) && __riscv_xlen == 64 #include "riscv64/efilibplat.h" +#elif defined (__loongarch64) +#include "loongarch64/efilibplat.h" #endif #include "efilink.h" #include "efirtlib.h" @@ -281,17 +287,17 @@ ZeroMem ( IN UINTN Size ); -VOID +VOID EFIAPI SetMem ( IN VOID *Buffer, IN UINTN Size, IN UINT8 Value ); -VOID +VOID EFIAPI CopyMem ( IN VOID *Dest, - IN CONST VOID *Src, + IN VOID *Src, IN UINTN len ); @@ -1076,4 +1082,8 @@ extern EFI_DEVICE_IO_INTERFACE *GlobalIoFncs; #define Port80(_PostCode) GlobalIoFncs->Io.Write (GlobalIoFncs, IO_UINT16, (UINT64)0x80, 1, &(_PostCode)) +#ifdef __cplusplus +} +#endif + #endif diff --git a/inc/efiprot.h b/inc/efiprot.h index 3e4d60b..c4457de 100644 --- a/inc/efiprot.h +++ b/inc/efiprot.h @@ -1428,4 +1428,39 @@ typedef struct _EFI_EBC_PROTOCOL { EFI_EBC_GET_VERSION GetVersion; } EFI_EBC_PROTOCOL; +INTERFACE_DECL(_EFI_MEMORY_ATTRIBUTE_PROTOCOL); + +typedef +EFI_STATUS +(EFIAPI *EFI_GET_MEMORY_ATTRIBUTES)( + IN struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + OUT UINT64 *Attributes + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_SET_MEMORY_ATTRIBUTES)( + IN struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +typedef +EFI_STATUS +(EFIAPI *EFI_CLEAR_MEMORY_ATTRIBUTES)( + IN struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL *This, + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +typedef struct _EFI_MEMORY_ATTRIBUTE_PROTOCOL { + EFI_GET_MEMORY_ATTRIBUTES GetMemoryAttributes; + EFI_SET_MEMORY_ATTRIBUTES SetMemoryAttributes; + EFI_CLEAR_MEMORY_ATTRIBUTES ClearMemoryAttributes; +} EFI_MEMORY_ATTRIBUTE_PROTOCOL; + #endif diff --git a/inc/efisetjmp.h b/inc/efisetjmp.h index de69194..4037688 100644 --- a/inc/efisetjmp.h +++ b/inc/efisetjmp.h @@ -5,6 +5,6 @@ #include "efisetjmp_arch.h" extern UINTN setjmp(jmp_buf env) __attribute__((returns_twice)); -extern VOID longjmp(jmp_buf env, UINTN value) __attribute__((noreturn)); +extern VOID longjmp(jmp_buf env, UINTN value) EFI_NORETURN; #endif /* GNU_EFI_SETJMP_H */ diff --git a/inc/ia32/efibind.h b/inc/ia32/efibind.h index 27459e4..718e8d1 100644 --- a/inc/ia32/efibind.h +++ b/inc/ia32/efibind.h @@ -85,9 +85,11 @@ Revision History // Basic EFI types of various widths // -#ifndef __WCHAR_TYPE__ -# define __WCHAR_TYPE__ short -#endif +#include + +typedef wchar_t CHAR16; +#define WCHAR CHAR16 + typedef uint64_t UINT64; typedef int64_t INT64; @@ -99,12 +101,13 @@ typedef int64_t INT64; typedef uint16_t UINT16; typedef int16_t INT16; + typedef uint8_t UINT8; +typedef char CHAR8; typedef int8_t INT8; -typedef __WCHAR_TYPE__ WCHAR; #undef VOID -#define VOID void +typedef void VOID; typedef int32_t INTN; diff --git a/inc/ia32/efisetjmp_arch.h b/inc/ia32/efisetjmp_arch.h index a5c1a81..f65432e 100644 --- a/inc/ia32/efisetjmp_arch.h +++ b/inc/ia32/efisetjmp_arch.h @@ -10,6 +10,6 @@ typedef struct { UINT32 Ebp; UINT32 Esp; UINT32 Eip; -} ALIGN(JMPBUF_ALIGN) jmp_buf[1]; +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; #endif /* GNU_EFI_IA32_SETJMP_H */ diff --git a/inc/ia64/efibind.h b/inc/ia64/efibind.h index 3ace8d5..1d2745b 100644 --- a/inc/ia64/efibind.h +++ b/inc/ia64/efibind.h @@ -71,24 +71,27 @@ Revision History // // Basic EFI types of various widths // -#ifndef __WCHAR_TYPE__ -# define __WCHAR_TYPE__ short -#endif +#include + +typedef wchar_t CHAR16; +#define WCHAR CHAR16 typedef uint64_t UINT64; typedef int64_t INT64; + typedef uint32_t UINT32; typedef int32_t INT32; + typedef uint16_t UINT16; typedef int16_t INT16; + typedef uint8_t UINT8; +typedef char CHAR8; typedef int8_t INT8; -typedef __WCHAR_TYPE__ WCHAR; - #undef VOID -#define VOID void +typedef void VOID; typedef int64_t INTN; diff --git a/inc/ia64/efisetjmp_arch.h b/inc/ia64/efisetjmp_arch.h index ceda448..7b674f6 100644 --- a/inc/ia64/efisetjmp_arch.h +++ b/inc/ia64/efisetjmp_arch.h @@ -42,6 +42,6 @@ typedef struct { UINT64 Predicates; UINT64 LoopCount; UINT64 FPSR; -} ALIGN(JMPBUF_ALIGN) jmp_buf[1]; +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; #endif /* GNU_EFI_IA64_SETJMP_H */ diff --git a/inc/loongarch64/efibind.h b/inc/loongarch64/efibind.h new file mode 100644 index 0000000..8ed83a5 --- /dev/null +++ b/inc/loongarch64/efibind.h @@ -0,0 +1,159 @@ +/* + * Copright (C) 2014 - 2015 Linaro Ltd. + * Author: Ard Biesheuvel + * Copright (C) 2017 Lemote Co. + * Author: Heiher + * Copright (C) 2021 Loongson Technology Corporation Limited. + * Author: zhoumingtao + * + * 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. + */ + +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L ) && !defined(__cplusplus) + +// ANSI C 1999/2000 stdint.h integer width declarations + +typedef unsigned long uint64_t; +typedef long int64_t; +typedef unsigned int uint32_t; +typedef int int32_t; +typedef unsigned short uint16_t; +typedef short int16_t; +typedef unsigned char uint8_t; +typedef signed char int8_t; +typedef uint64_t uintptr_t; +typedef int64_t intptr_t; + +#else +#include +#endif + +// +// Basic EFI types of various widths +// + +#include + +typedef wchar_t CHAR16; +#define WCHAR CHAR16 + +typedef uint64_t UINT64; +typedef int64_t INT64; + +typedef uint32_t UINT32; +typedef int32_t INT32; + +typedef uint16_t UINT16; +typedef int16_t INT16; + +typedef uint8_t UINT8; +typedef char CHAR8; +typedef int8_t INT8; + +#undef VOID +typedef void VOID; + +typedef int64_t INTN; +typedef uint64_t UINTN; + +#define EFIERR(a) (0x8000000000000000 | a) +#define EFI_ERROR_MASK 0x8000000000000000 +#define EFIERR_OEM(a) (0xc000000000000000 | a) + +#define BAD_POINTER 0xFBFBFBFBFBFBFBFB +#define MAX_ADDRESS 0xFFFFFFFFFFFFFFFF + +#define BREAKPOINT() while (TRUE); // Make it hang on Bios[Dbg]32 + +// +// Pointers must be aligned to these address to function +// + +#define MIN_ALIGNMENT_SIZE 8 + +#define ALIGN_VARIABLE(Value ,Adjustment) \ + (UINTN)Adjustment = 0; \ + if((UINTN)Value % MIN_ALIGNMENT_SIZE) \ + (UINTN)Adjustment = MIN_ALIGNMENT_SIZE - ((UINTN)Value % MIN_ALIGNMENT_SIZE); \ + Value = (UINTN)Value + (UINTN)Adjustment + + +// +// Define macros to build data structure signatures from characters. +// + +#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8)) +#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16)) +#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32)) + +// +// EFIAPI - prototype calling convention for EFI function pointers +// BOOTSERVICE - prototype for implementation of a boot service interface +// RUNTIMESERVICE - prototype for implementation of a runtime service interface +// RUNTIMEFUNCTION - prototype for implementation of a runtime function that is not a service +// RUNTIME_CODE - pragma macro for declaring runtime code +// + +#ifndef EFIAPI // Forces EFI calling conventions reguardless of compiler options +#define EFIAPI // Substitute expresion to force C calling convention +#endif + +#define BOOTSERVICE +#define RUNTIMESERVICE +#define RUNTIMEFUNCTION + + +#define RUNTIME_CODE(a) alloc_text("rtcode", a) +#define BEGIN_RUNTIME_DATA() data_seg("rtdata") +#define END_RUNTIME_DATA() data_seg("") + +#define VOLATILE volatile + +#define MEMORY_FENCE __sync_synchronize + +// +// When build similiar to FW, then link everything together as +// one big module. +// + +#define EFI_DRIVER_ENTRY_POINT(InitFunction) \ + UINTN \ + InitializeDriver ( \ + VOID *ImageHandle, \ + VOID *SystemTable \ + ) \ + { \ + return InitFunction(ImageHandle, \ + SystemTable); \ + } \ + \ + EFI_STATUS efi_main( \ + EFI_HANDLE image, \ + EFI_SYSTEM_TABLE *systab \ + ) __attribute__((weak, \ + alias ("InitializeDriver"))); + +#define LOAD_INTERNAL_DRIVER(_if, type, name, entry) \ + (_if)->LoadInternal(type, name, entry) + + +// +// Some compilers don't support the forward reference construct: +// typedef struct XXXXX +// +// The following macro provide a workaround for such cases. + +#define INTERFACE_DECL(x) struct x + +#define uefi_call_wrapper(func, va_num, ...) func(__VA_ARGS__) +#define EFI_FUNCTION diff --git a/inc/loongarch64/efilibplat.h b/inc/loongarch64/efilibplat.h new file mode 100644 index 0000000..eda7c83 --- /dev/null +++ b/inc/loongarch64/efilibplat.h @@ -0,0 +1,24 @@ +/*++ + +Copyright (c) 1998 Intel Corporation + +Module Name: + + efilibplat.h + +Abstract: + + EFI to compile bindings + + + + +Revision History + +--*/ + +VOID +InitializeLibPlatform ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); diff --git a/inc/loongarch64/efisetjmp_arch.h b/inc/loongarch64/efisetjmp_arch.h new file mode 100644 index 0000000..41ff410 --- /dev/null +++ b/inc/loongarch64/efisetjmp_arch.h @@ -0,0 +1,23 @@ +#ifndef GNU_EFI_LOONGARCH64_SETJMP_H +#define GNU_EFI_LOONGARCH64_SETJMP_H + +#define JMPBUF_ALIGN 8 + +typedef struct { + /* GP regs */ + UINT64 RA; + UINT64 SP; + UINT64 FP; + + UINT64 S0; + UINT64 S1; + UINT64 S2; + UINT64 S3; + UINT64 S4; + UINT64 S5; + UINT64 S6; + UINT64 S7; + UINT64 S8; +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; + +#endif /* GNU_EFI_LOONGARCH64_SETJMP_H */ diff --git a/inc/mips64el/efibind.h b/inc/mips64el/efibind.h index 1f08cd3..cf77ddc 100644 --- a/inc/mips64el/efibind.h +++ b/inc/mips64el/efibind.h @@ -40,9 +40,10 @@ typedef int64_t intptr_t; // Basic EFI types of various widths // -#ifndef __WCHAR_TYPE__ -# define __WCHAR_TYPE__ short -#endif +#include + +typedef wchar_t CHAR16; +#define WCHAR CHAR16 typedef uint64_t UINT64; typedef int64_t INT64; @@ -52,12 +53,13 @@ typedef int32_t INT32; typedef uint16_t UINT16; typedef int16_t INT16; + typedef uint8_t UINT8; +typedef char CHAR8; typedef int8_t INT8; -typedef __WCHAR_TYPE__ WCHAR; #undef VOID -#define VOID void +typedef void VOID; typedef int64_t INTN; typedef uint64_t UINTN; diff --git a/inc/mips64el/efisetjmp_arch.h b/inc/mips64el/efisetjmp_arch.h index 2b8f756..e241284 100644 --- a/inc/mips64el/efisetjmp_arch.h +++ b/inc/mips64el/efisetjmp_arch.h @@ -29,6 +29,6 @@ typedef struct { UINT64 F30; UINT64 F31; #endif -} ALIGN(JMPBUF_ALIGN) jmp_buf[1]; +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; #endif /* GNU_EFI_MIPS64EL_SETJMP_H */ diff --git a/inc/riscv64/efibind.h b/inc/riscv64/efibind.h index 0a818ae..d8b4f39 100644 --- a/inc/riscv64/efibind.h +++ b/inc/riscv64/efibind.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause */ /* * Copright (C) 2014 - 2015 Linaro Ltd. * Author: Ard Biesheuvel @@ -21,7 +22,7 @@ // Basic EFI types of various widths // - +#include typedef uint64_t UINT64; typedef int64_t INT64; @@ -31,15 +32,11 @@ typedef uint16_t UINT16; typedef int16_t INT16; typedef uint8_t UINT8; typedef int8_t INT8; -#ifndef __WCHAR_TYPE__ -#define __WCHAR_TYPE__ short -#endif -typedef __WCHAR_TYPE__ WCHAR; -#ifndef BOOLEAN -typedef uint8_t BOOLEAN; -#endif +typedef char CHAR8; +typedef wchar_t CHAR16; +#define WCHAR CHAR16 #undef VOID -#define VOID void +typedef void VOID; typedef int64_t INTN; typedef uint64_t UINTN; diff --git a/inc/riscv64/efilibplat.h b/inc/riscv64/efilibplat.h index 0a61b24..9b15163 100644 --- a/inc/riscv64/efilibplat.h +++ b/inc/riscv64/efilibplat.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause */ VOID InitializeLibPlatform ( diff --git a/inc/riscv64/efisetjmp_arch.h b/inc/riscv64/efisetjmp_arch.h index 2bb4efd..bb6f467 100644 --- a/inc/riscv64/efisetjmp_arch.h +++ b/inc/riscv64/efisetjmp_arch.h @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause */ + #ifndef GNU_EFI_RISCV64_SETJMP_H #define GNU_EFI_RISCV64_SETJMP_H @@ -33,6 +35,6 @@ typedef struct { UINT64 fs9; UINT64 fs10; UINT64 fs11; -} ALIGN(JMPBUF_ALIGN) jmp_buf[1]; +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; #endif /* GNU_EFI_RISCV64_SETJMP_H */ diff --git a/inc/x86_64/efibind.h b/inc/x86_64/efibind.h index b8c32c3..e454ed2 100644 --- a/inc/x86_64/efibind.h +++ b/inc/x86_64/efibind.h @@ -96,9 +96,10 @@ Revision History // Basic EFI types of various widths // -#ifndef __WCHAR_TYPE__ -# define __WCHAR_TYPE__ short -#endif +#include + +typedef wchar_t CHAR16; +#define WCHAR CHAR16 typedef uint64_t UINT64; typedef int64_t INT64; @@ -110,12 +111,13 @@ typedef int64_t INT64; typedef uint16_t UINT16; typedef int16_t INT16; + typedef uint8_t UINT8; +typedef char CHAR8; typedef int8_t INT8; -typedef __WCHAR_TYPE__ WCHAR; #undef VOID -#define VOID void +typedef void VOID; typedef int64_t INTN; diff --git a/inc/x86_64/efisetjmp_arch.h b/inc/x86_64/efisetjmp_arch.h index b1ad1fe..8d100ae 100644 --- a/inc/x86_64/efisetjmp_arch.h +++ b/inc/x86_64/efisetjmp_arch.h @@ -17,6 +17,6 @@ typedef struct { UINT64 Rip; UINT64 MxCsr; UINT8 XmmBuffer[160]; // XMM6 - XMM15 -} ALIGN(JMPBUF_ALIGN) jmp_buf[1]; +} EFI_ALIGN(JMPBUF_ALIGN) jmp_buf[1]; #endif /* GNU_EFI_X86_64_SETJMP_H */ diff --git a/lib/Makefile b/lib/Makefile index 1fc6a47..ec1f9e3 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -37,14 +37,12 @@ SRCDIR = . VPATH = $(SRCDIR) +TOPDIR = $(SRCDIR)/.. include $(SRCDIR)/../Make.defaults -TOPDIR = $(SRCDIR)/.. - -CDIR = $(TOPDIR)/.. -FILES = boxdraw smbios console crc data debug dpath \ - error event exit guid hand hw init lock \ +FILES = boxdraw smbios console crc data debug dpath \ + entry error event exit guid hand hw init lock \ misc pause print sread str cmdline\ runtime/rtlock runtime/efirtlib runtime/rtstr runtime/vm runtime/rtdata \ $(ARCH)/initplat $(ARCH)/math $(ARCH)/setjmp @@ -62,9 +60,9 @@ FILES += $(ARCH)/uldiv $(ARCH)/ldivmod $(ARCH)/div $(ARCH)/llsl $(ARCH)/llsr \ $(ARCH)/mullu endif -OBJS = $(FILES:%=%.o) +OBJS = $(FILES:%=%.o) ctors.o -SUBDIRS = ia32 x86_64 ia64 aarch64 arm mips64el riscv64 runtime +SUBDIRS = ia32 x86_64 ia64 aarch64 arm mips64el riscv64 loongarch64 runtime LIBDIRINSTALL = $(INSTALLROOT)$(LIBDIR) @@ -72,7 +70,7 @@ all: libsubdirs libefi.a .PHONY: libsubdirs libsubdirs: - for sdir in $(SUBDIRS); do mkdir -p $$sdir; done + @set -e ; for sdir in $(SUBDIRS); do mkdir -p $$sdir; done $(OBJS): libsubdirs @@ -80,7 +78,7 @@ libefi.a: $(OBJS) $(AR) $(ARFLAGS) $@ $^ clean: - rm -f libefi.a *~ $(OBJS) */*.o + @rm -vf libefi.a *~ $(OBJS) */*.o $(LIBDIRINSTALL): mkdir -p $@ diff --git a/lib/Makefile.orig b/lib/Makefile.orig deleted file mode 100644 index 65aa8ca..0000000 --- a/lib/Makefile.orig +++ /dev/null @@ -1,91 +0,0 @@ -# -# Copyright (C) 1999-2001 Hewlett-Packard Co. -# Contributed by David Mosberger -# Contributed by Stephane Eranian -# -# 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 = boxdraw smbios console crc data debug dpath \ - error event guid hand hw init lock \ - misc print sread str cmdline \ - runtime/rtlock runtime/efirtlib runtime/rtstr runtime/vm runtime/rtdata \ - $(ARCH)/initplat $(ARCH)/math - -ifeq ($(ARCH),ia64) -FILES += $(ARCH)/salpal $(ARCH)/palproc -endif - -ifeq ($(ARCH),x86_64) -FILES += $(ARCH)/callwrap $(ARCH)/efi_stub -endif - -ifeq ($(ARCH),arm) -FILES += $(ARCH)/lib1funcs $(ARCH)/div64 -endif - -OBJS = $(FILES:%=%.o) - -SUBDIRS = ia32 x86_64 ia64 aarch64 arm runtime - -LIBDIRINSTALL = $(INSTALLROOT)$(LIBDIR) - -all: libsubdirs libefi.a - -.PHONY: libsubdirs -libsubdirs: - for sdir in $(SUBDIRS); do mkdir -p $$sdir; done - -libefi.a: $(patsubst %,libefi.a(%),$(OBJS)) - -clean: - rm -f libefi.a *~ $(OBJS) */*.o - -$(LIBDIRINSTALL): - mkdir -p $@ - -$(LIBDIRINSTALL)/libefi.a: libefi.a | $(LIBDIRINSTALL) - $(INSTALL) -m 644 $< $(dir $@) - -install: $(LIBDIRINSTALL)/libefi.a - -include $(SRCDIR)/../Make.rules - -.PHONY: libsubdirs diff --git a/lib/ctors.S b/lib/ctors.S new file mode 100644 index 0000000..4a66a4e --- /dev/null +++ b/lib/ctors.S @@ -0,0 +1,39 @@ +/* + * Try to define the minimal empty init/ctor/dtor/fini_arrays so building with + * older or out-of-tree linker scripts will still work. + */ +/* + * 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. + */ + .section .init_array,"aw",%init_array + .p2align 4, 0 + .globl __init_array_start +__init_array_start: + .globl __init_array_end +__init_array_end: + .section .ctors,"aw",%progbits + .p2align 4, 0 + .globl __CTOR_LIST__ +__CTOR_LIST__: + .globl __CTOR_END__ +__CTOR_END__: + .section .dtors,"aw",%progbits + .p2align 4, 0 + .globl __DTOR_LIST__ +__DTOR_LIST__: + .globl __DTOR_END__ +__DTOR_END__: + .section .fini_array,"aw",%fini_array + .p2align 4, 0 + .globl __fini_array_start +__fini_array_start: + .globl __fini_array_end +__fini_array_end: + +#if defined(__ELF__) && defined(__linux__) + .section .note.GNU-stack,"",%progbits +#endif + diff --git a/lib/dpath.c b/lib/dpath.c index 5e079d6..63e4e70 100644 --- a/lib/dpath.c +++ b/lib/dpath.c @@ -1083,11 +1083,12 @@ _DevPathNodeUnknown ( * Entries hold "Type" and "SubType" for know values. * Special "SubType" 0 is used as default for known type with unknown subtype. */ -struct { +typedef struct { UINT8 Type; UINT8 SubType; VOID (*Function)(POOL_PRINT *, VOID *); -} DevPathTable[] = { +} DevPathTable_Type; +DevPathTable_Type DevPathTable[] = { { HARDWARE_DEVICE_PATH, HW_PCI_DP, _DevPathPci}, { HARDWARE_DEVICE_PATH, HW_PCCARD_DP, _DevPathPccard}, { HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, _DevPathMemMap}, diff --git a/lib/entry.c b/lib/entry.c new file mode 100644 index 0000000..3baa91d --- /dev/null +++ b/lib/entry.c @@ -0,0 +1,73 @@ +/* + * ctors.c + * Copyright 2019 Peter Jones + * + */ + +#include +#include + +typedef void (*funcp)(void); + +/* + * 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. + */ +extern funcp __init_array_start[], __init_array_end[]; +extern funcp __CTOR_LIST__[], __CTOR_END__[]; +extern funcp __fini_array_start[], __fini_array_end[]; +extern funcp __DTOR_LIST__[], __DTOR_END__[]; + +static void ctors(void) +{ + size_t __init_array_length = __init_array_end - __init_array_start; + for (size_t i = 0; i < __init_array_length; i++) { + funcp func = __init_array_start[i]; + if (func != NULL) + func(); + } + + size_t __CTOR_length = __CTOR_END__ - __CTOR_LIST__; + for (size_t i = 0; i < __CTOR_length; i++) { + size_t current = __CTOR_length - i - 1; + funcp func = __CTOR_LIST__[current]; + if (func != NULL) + func(); + } +} + +static void dtors(void) +{ + size_t __DTOR_length = __DTOR_END__ - __DTOR_LIST__; + for (size_t i = 0; i < __DTOR_length; i++) { + funcp func = __DTOR_LIST__[i]; + if (func != NULL) + func(); + } + + size_t __fini_array_length = __fini_array_end - __fini_array_start; + for (size_t i = 0; i < __fini_array_length; i++) { + size_t current = __fini_array_length - i - 1; + funcp func = __fini_array_start[current]; + if (func != NULL) + func(); + } +} + +extern EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab); + +EFI_STATUS _entry(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) +{ + EFI_STATUS status; + InitializeLib(image, systab); + + ctors(); + status = efi_main(image, systab); + dtors(); + + return status; +} + +// vim:fenc=utf-8:tw=75:noet diff --git a/lib/error.c b/lib/error.c index 2399a06..38e03e8 100644 --- a/lib/error.c +++ b/lib/error.c @@ -18,10 +18,11 @@ Revision History #include "lib.h" -struct { - EFI_STATUS Code; - WCHAR *Desc; -} ErrorCodeTable[] = { +typedef struct { + EFI_STATUS Code; + WCHAR *Desc; +} ErrorCodeTable_Type; +ErrorCodeTable_Type ErrorCodeTable[] = { { EFI_SUCCESS, L"Success"}, { EFI_LOAD_ERROR, L"Load Error"}, { EFI_INVALID_PARAMETER, L"Invalid Parameter"}, @@ -54,12 +55,17 @@ struct { { EFI_END_OF_FILE, L"End of File"}, { EFI_INVALID_LANGUAGE, L"Invalid Languages"}, { EFI_COMPROMISED_DATA, L"Compromised Data"}, + { EFI_IP_ADDRESS_CONFLICT, L"IP Address Conflict"}, + { EFI_HTTP_ERROR, L"HTTP Error"}, // warnings { EFI_WARN_UNKNOWN_GLYPH, L"Warning Unknown Glyph"}, { EFI_WARN_DELETE_FAILURE, L"Warning Delete Failure"}, { EFI_WARN_WRITE_FAILURE, L"Warning Write Failure"}, { EFI_WARN_BUFFER_TOO_SMALL, L"Warning Buffer Too Small"}, + { EFI_WARN_STALE_DATA, L"Warning Stale Data"}, + { EFI_WARN_FILE_SYSTEM, L"Warning File System"}, + { EFI_WARN_RESET_REQUIRED, L"Warning Reset Required"}, { 0, NULL} } ; diff --git a/lib/ia32/math.c b/lib/ia32/math.c index fce7a8d..2ef7588 100644 --- a/lib/ia32/math.c +++ b/lib/ia32/math.c @@ -158,7 +158,7 @@ DivU64x32 ( Rem = 0; for (bit=0; bit < 64; bit++) { #if defined(__GNUC__) || defined(__MINGW32__) - asm ( + __asm__ ( "shll $1, %0\n\t" "rcll $1, 4%0\n\t" "rcll $1, %2\n\t" diff --git a/lib/init.c b/lib/init.c index 4f238c0..726e493 100644 --- a/lib/init.c +++ b/lib/init.c @@ -46,57 +46,52 @@ Returns: EFI_STATUS Status; CHAR8 *LangCode; - if (!LibInitialized) { - LibInitialized = TRUE; - LibFwInstance = FALSE; - LibImageHandle = ImageHandle; + if (LibInitialized) + return; + LibInitialized = TRUE; + LibFwInstance = FALSE; + LibImageHandle = ImageHandle; - // - // Set up global pointer to the system table, boot services table, - // and runtime services table - // - - ST = SystemTable; - BS = SystemTable->BootServices; - RT = SystemTable->RuntimeServices; -// ASSERT (CheckCrc(0, &ST->Hdr)); -// ASSERT (CheckCrc(0, &BS->Hdr)); -// ASSERT (CheckCrc(0, &RT->Hdr)); - - - // - // Initialize pool allocation type - // - - if (ImageHandle) { - Status = uefi_call_wrapper( - BS->HandleProtocol, - 3, - ImageHandle, - &LoadedImageProtocol, - (VOID*)&LoadedImage - ); - - if (!EFI_ERROR(Status)) { - PoolAllocationType = LoadedImage->ImageDataType; - } - EFIDebugVariable (); - } + // + // Set up global pointer to the system table, boot services table, + // and runtime services table + // - // - // Initialize Guid table - // + ST = SystemTable; + BS = SystemTable->BootServices; + RT = SystemTable->RuntimeServices; + // ASSERT (CheckCrc(0, &ST->Hdr)); + // ASSERT (CheckCrc(0, &BS->Hdr)); + // ASSERT (CheckCrc(0, &RT->Hdr)); - InitializeGuid(); + // + // Initialize pool allocation type + // - InitializeLibPlatform(ImageHandle,SystemTable); + if (ImageHandle) { + Status = uefi_call_wrapper( + BS->HandleProtocol, + 3, + ImageHandle, + &LoadedImageProtocol, + (VOID*)&LoadedImage + ); + + if (!EFI_ERROR(Status)) { + PoolAllocationType = LoadedImage->ImageDataType; + } + EFIDebugVariable (); } // - // + // Initialize Guid table // + InitializeGuid(); + + InitializeLibPlatform(ImageHandle,SystemTable); + if (ImageHandle && UnicodeInterface == &LibStubUnicodeInterface) { LangCode = LibGetVariable (VarLanguage, &EfiGlobalVariable); InitializeUnicodeSupport (LangCode); diff --git a/lib/loongarch64/efi_stub.S b/lib/loongarch64/efi_stub.S new file mode 100644 index 0000000..b3fba1d --- /dev/null +++ b/lib/loongarch64/efi_stub.S @@ -0,0 +1,4 @@ +/* This stub is a stub to make the build happy */ +#if defined(__ELF__) && defined(__linux__) + .section .note.GNU-stack,"",%progbits +#endif diff --git a/lib/loongarch64/initplat.c b/lib/loongarch64/initplat.c new file mode 100644 index 0000000..6c5e1fa --- /dev/null +++ b/lib/loongarch64/initplat.c @@ -0,0 +1,26 @@ +/* + * Copright (C) 2014 Linaro Ltd. + * Author: Ard Biesheuvel + * + * 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. + */ + +#include "lib.h" + +VOID +InitializeLibPlatform ( + IN EFI_HANDLE ImageHandle EFI_UNUSED, + IN EFI_SYSTEM_TABLE *SystemTable EFI_UNUSED + ) +{ +} diff --git a/lib/loongarch64/math.c b/lib/loongarch64/math.c new file mode 100644 index 0000000..8c16444 --- /dev/null +++ b/lib/loongarch64/math.c @@ -0,0 +1,63 @@ +/* + * Copright (C) 2014 Linaro Ltd. + * Author: Ard Biesheuvel + * + * 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. + */ + +#include "lib.h" + +UINT64 +LShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +// Left shift 64bit by 32bit and get a 64bit result +{ + return Operand << Count; +} + +UINT64 +RShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +// Right shift 64bit by 32bit and get a 64bit result +{ + return Operand >> Count; +} + + +UINT64 +MultU64x32 ( + IN UINT64 Multiplicand, + IN UINTN Multiplier + ) +// Multiple 64bit by 32bit and get a 64bit result +{ + return Multiplicand * Multiplier; +} + +UINT64 +DivU64x32 ( + IN UINT64 Dividend, + IN UINTN Divisor, + OUT UINTN *Remainder OPTIONAL + ) +// divide 64bit by 32bit and get a 64bit result +// N.B. only works for 31bit divisors!! +{ + if (Remainder) + *Remainder = Dividend % Divisor; + return Dividend / Divisor; +} diff --git a/lib/loongarch64/setjmp.S b/lib/loongarch64/setjmp.S new file mode 100644 index 0000000..6821af3 --- /dev/null +++ b/lib/loongarch64/setjmp.S @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved. + * Copyright (c) 2021 Loongson Technology Corporation Limited.All rights + * reserved. + * Author: zhoumingtao + * + * This program and the accompanying materials are licensed and made + * available + * under the terms and conditions of the BSD License which accompanies + * this + * distribution. The full text of the license may be found at + * http://opensource.org/licenses/bsd-license.php. + * + * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" + * BASIS, + * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR + * IMPLIED. + */ + + .text + .p2align 3 + +/* + int setjmp(jmp_buf env); +*/ + .globl setjmp + .type setjmp, @function +setjmp: + st.d $ra, $a0, 0x0 + st.d $sp, $a0, 0x8 + st.d $fp, $a0, 0x10 + st.d $s0, $a0, 0x18 + st.d $s1, $a0, 0x20 + st.d $s2, $a0, 0x28 + st.d $s3, $a0, 0x30 + st.d $s4, $a0, 0x38 + st.d $s5, $a0, 0x40 + st.d $s6, $a0, 0x48 + st.d $s7, $a0, 0x50 + st.d $s8, $a0, 0x58 + + move $a0, $zero + jr $ra + +/* + void longjmp(jmp_buf env, int val); +*/ + .globl longjmp + .type longjmp, @function +longjmp: + ld.d $ra, $a0, 0x0 + ld.d $sp, $a0, 0x8 + ld.d $fp, $a0, 0x10 + ld.d $s0, $a0, 0x18 + ld.d $s1, $a0, 0x20 + ld.d $s2, $a0, 0x28 + ld.d $s3, $a0, 0x30 + ld.d $s4, $a0, 0x38 + ld.d $s5, $a0, 0x40 + ld.d $s6, $a0, 0x48 + ld.d $s7, $a0, 0x50 + ld.d $s8, $a0, 0x58 + + addi.d $a0, $zero, 1 # a0 = 1 + beqz $a1, .L0 # if (a1 == 0); goto L0 + move $a0, $a1 # a0 = a1 +.L0: + jr $ra diff --git a/lib/misc.c b/lib/misc.c index 78d61fc..1d2e241 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -98,7 +98,7 @@ ZeroMem ( RtZeroMem (Buffer, Size); } -VOID +VOID EFIAPI SetMem ( IN VOID *Buffer, IN UINTN Size, @@ -108,10 +108,10 @@ SetMem ( RtSetMem (Buffer, Size, Value); } -VOID +VOID EFIAPI CopyMem ( IN VOID *Dest, - IN CONST VOID *Src, + IN VOID *Src, IN UINTN len ) { diff --git a/lib/print.c b/lib/print.c index 8a7466c..a43dc8c 100644 --- a/lib/print.c +++ b/lib/print.c @@ -1125,24 +1125,24 @@ Returns: Item.Item.pw = Item.Scratch; break; - case '0': - Item.Pad = '0'; + case ',': + Item.Comma = TRUE; break; case '-': Item.PadBefore = FALSE; break; - case ',': - Item.Comma = TRUE; + case '*': + *Item.WidthParse = va_arg(ps->args, UINTN); break; case '.': Item.WidthParse = &Item.FieldWidth; break; - case '*': - *Item.WidthParse = va_arg(ps->args, UINTN); + case '0': + Item.Pad = '0'; break; case '1': @@ -1170,52 +1170,23 @@ Returns: } break; - case 's': - Item.Item.pw = va_arg(ps->args, CHAR16 *); - if (!Item.Item.pw) { - Item.Item.pw = L"(null)"; - } - break; - case 'c': Item.Scratch[0] = (CHAR16) va_arg(ps->args, UINTN); Item.Scratch[1] = 0; Item.Item.pw = Item.Scratch; break; - case 'l': - Item.Long = TRUE; - break; - - case 'X': - Item.Width = Item.Long ? 16 : 8; - Item.Pad = '0'; -#if __GNUC__ >= 7 - __attribute__ ((fallthrough)); -#endif - case 'x': - ValueToHex ( - Item.Scratch, - Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32) - ); - Item.Item.pw = Item.Scratch; - - break; - + case 'D': + { + EFI_DEVICE_PATH *dp = va_arg(ps->args, EFI_DEVICE_PATH *); + CHAR16 *dpstr = DevicePathToStr(dp); + StrnCpy(Item.Scratch, dpstr, PRINT_ITEM_BUFFER_LEN); + Item.Scratch[PRINT_ITEM_BUFFER_LEN-1] = L'\0'; + FreePool(dpstr); - case 'g': - GuidToString (Item.Scratch, va_arg(ps->args, EFI_GUID *)); - Item.Item.pw = Item.Scratch; - break; - - case 'u': - ValueToString ( - Item.Scratch, - Item.Comma, - Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32) - ); Item.Item.pw = Item.Scratch; break; + } case 'd': ValueToString ( @@ -1226,17 +1197,13 @@ Returns: Item.Item.pw = Item.Scratch; break; - case 'D': - { - EFI_DEVICE_PATH *dp = va_arg(ps->args, EFI_DEVICE_PATH *); - CHAR16 *dpstr = DevicePathToStr(dp); - StrnCpy(Item.Scratch, dpstr, PRINT_ITEM_BUFFER_LEN); - Item.Scratch[PRINT_ITEM_BUFFER_LEN-1] = L'\0'; - FreePool(dpstr); + case 'E': + Attr = ps->AttrError; + break; - Item.Item.pw = Item.Scratch; + case 'e': + PSETATTR(ps, ps->AttrError); break; - } case 'f': FloatToString ( @@ -1247,38 +1214,83 @@ Returns: Item.Item.pw = Item.Scratch; break; - case 't': - TimeToString (Item.Scratch, va_arg(ps->args, EFI_TIME *)); - Item.Item.pw = Item.Scratch; - break; - - case 'r': - StatusToString (Item.Scratch, va_arg(ps->args, EFI_STATUS)); + case 'g': + GuidToString (Item.Scratch, va_arg(ps->args, EFI_GUID *)); Item.Item.pw = Item.Scratch; break; - case 'n': - PSETATTR(ps, ps->AttrNorm); + case 'H': + Attr = ps->AttrHighlight; break; case 'h': PSETATTR(ps, ps->AttrHighlight); break; - case 'e': - PSETATTR(ps, ps->AttrError); + case 'l': + Item.Long = TRUE; break; case 'N': Attr = ps->AttrNorm; break; - case 'H': - Attr = ps->AttrHighlight; + case 'n': + PSETATTR(ps, ps->AttrNorm); break; - case 'E': - Attr = ps->AttrError; + case 'p': + Item.Width = sizeof(void *) == (8 ? 16 : 8) + 2; + Item.Pad = '0'; + Item.Scratch[0] = ' '; + Item.Scratch[1] = ' '; + ValueToHex ( + Item.Scratch+2, + Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32) + ); + Item.Scratch[0] = '0'; + Item.Scratch[1] = 'x'; + Item.Item.pw = Item.Scratch; + break; + + case 'r': + StatusToString (Item.Scratch, va_arg(ps->args, EFI_STATUS)); + Item.Item.pw = Item.Scratch; + break; + + case 's': + Item.Item.pw = va_arg(ps->args, CHAR16 *); + if (!Item.Item.pw) { + Item.Item.pw = L"(null)"; + } + break; + + case 't': + TimeToString (Item.Scratch, va_arg(ps->args, EFI_TIME *)); + Item.Item.pw = Item.Scratch; + break; + + case 'u': + ValueToString ( + Item.Scratch, + Item.Comma, + Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32) + ); + Item.Item.pw = Item.Scratch; + break; + + case 'X': + Item.Width = Item.Long ? 16 : 8; + Item.Pad = '0'; +#if __GNUC__ >= 7 + __attribute__ ((fallthrough)); +#endif + case 'x': + ValueToHex ( + Item.Scratch, + Item.Long ? va_arg(ps->args, UINT64) : va_arg(ps->args, UINT32) + ); + Item.Item.pw = Item.Scratch; break; default: diff --git a/lib/riscv64/initplat.c b/lib/riscv64/initplat.c index ed42037..895353a 100644 --- a/lib/riscv64/initplat.c +++ b/lib/riscv64/initplat.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause #include "lib.h" diff --git a/lib/riscv64/setjmp.S b/lib/riscv64/setjmp.S index f7928e5..275a715 100644 --- a/lib/riscv64/setjmp.S +++ b/lib/riscv64/setjmp.S @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +// SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause /* * Copyright Heinrich Schuchardt */ diff --git a/lib/str.c b/lib/str.c index b9b156b..a2f8750 100644 --- a/lib/str.c +++ b/lib/str.c @@ -205,7 +205,7 @@ StrDuplicate ( Size = StrSize(Src); Dest = AllocatePool (Size); if (Dest) { - CopyMem (Dest, Src, Size); + CopyMem (Dest, (void *)Src, Size); } return Dest; }