Instead of relying on the builtin linker script of GNU ld, which
may vary based on binutils version (which is not tightly coupled to
the GCC version) and linker command line options, introduce a linker
script for AArch64 to be used by all GCC/binutils versions.

The script is laid out such that both the file and memory layout
are identical between the ELF intermediate file and the final
PE/COFF file. This should prevent problems with debuggers and other
tooling that are ELF based.
It also places the .text section such that, provided that the entire
image is loaded at a 4 KB aligned offset, the build time and runtime
relative alignment with respect to the nearest 4 KB boundary is the
same. This allows the 'small' GCC C model to be used.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
---
 BaseTools/Conf/tools_def.template       | 23 +++++++++++++----------
 BaseTools/Scripts/gcc-aarch64-ld-script | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 10 deletions(-)

diff --git a/BaseTools/Conf/tools_def.template 
b/BaseTools/Conf/tools_def.template
index fd7b4b55e8ba..9ba8d38a1791 100644
--- a/BaseTools/Conf/tools_def.template
+++ b/BaseTools/Conf/tools_def.template
@@ -3821,9 +3821,12 @@ DEFINE GCC_ARM_CC_FLAGS            = 
DEF(GCC_ALL_CC_FLAGS) -mword-relocations -m
 DEFINE GCC_AARCH64_CC_FLAGS        = DEF(GCC_ALL_CC_FLAGS) -mcmodel=large 
-mlittle-endian -fno-short-enums -save-temps -fverbose-asm -fsigned-char  
-ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin 
-Wno-address
 DEFINE GCC_DLINK_FLAGS_COMMON      = -nostdlib --pie
 DEFINE GCC_IA32_X64_DLINK_COMMON   = DEF(GCC_DLINK_FLAGS_COMMON) --gc-sections
-DEFINE GCC_ARM_AARCH64_DLINK_COMMON= -Ttext=0x0 --emit-relocs -nostdlib 
--gc-sections -u $(IMAGE_ENTRY_POINT) -e $(IMAGE_ENTRY_POINT) -Map 
$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+DEFINE GCC_ARM_AARCH64_DLINK_COMMON= --emit-relocs -nostdlib --gc-sections -u 
$(IMAGE_ENTRY_POINT) -e $(IMAGE_ENTRY_POINT) -Map 
$(DEST_DIR_DEBUG)/$(BASE_NAME).map
+DEFINE GCC_ARM_DLINK_FLAGS         = DEF(GCC_ARM_AARCH64_DLINK_COMMON) 
-Ttext=0x0
+DEFINE GCC_AARCH64_DLINK_FLAGS     = DEF(GCC_ARM_AARCH64_DLINK_COMMON) 
--script=$(EDK_TOOLS_PATH)/Scripts/gcc-aarch64-ld-script
 DEFINE GCC_IA32_X64_ASLDLINK_FLAGS = DEF(GCC_IA32_X64_DLINK_COMMON) --entry 
_ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT)
-DEFINE GCC_ARM_AARCH64_ASLDLINK_FLAGS = DEF(GCC_ARM_AARCH64_DLINK_COMMON) 
--entry ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT)
+DEFINE GCC_ARM_ASLDLINK_FLAGS      = DEF(GCC_ARM_DLINK_FLAGS) --entry 
ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT)
+DEFINE GCC_AARCH64_ASLDLINK_FLAGS  = DEF(GCC_AARCH64_DLINK_FLAGS) --entry 
ReferenceAcpiTable -u $(IMAGE_ENTRY_POINT)
 DEFINE GCC_IA32_X64_DLINK_FLAGS    = DEF(GCC_IA32_X64_DLINK_COMMON) --entry 
_$(IMAGE_ENTRY_POINT) --file-alignment 0x20 --section-alignment 0x20 -Map 
$(DEST_DIR_DEBUG)/$(BASE_NAME).map
 DEFINE GCC_IPF_DLINK_FLAGS         = -nostdlib -O2 --gc-sections --dll -static 
--entry $(IMAGE_ENTRY_POINT) --undefined $(IMAGE_ENTRY_POINT) -Map 
$(DEST_DIR_DEBUG)/$(BASE_NAME).map
 DEFINE GCC_IPF_OBJCOPY_FLAGS       = -I elf64-ia64-little -O efi-bsdrv-ia64
@@ -3866,8 +3869,8 @@ DEFINE GCC46_X64_DLINK_FLAGS         = 
DEF(GCC45_X64_DLINK_FLAGS)
 DEFINE GCC46_ASM_FLAGS               = DEF(GCC45_ASM_FLAGS)
 DEFINE GCC46_ARM_ASM_FLAGS           = $(ARCHASM_FLAGS) $(PLATFORM_FLAGS) 
DEF(GCC_ASM_FLAGS) -mlittle-endian
 DEFINE GCC46_ARM_CC_FLAGS            = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) 
DEF(GCC44_ALL_CC_FLAGS) DEF(GCC_ARM_CC_FLAGS) -fstack-protector
-DEFINE GCC46_ARM_DLINK_FLAGS         = DEF(GCC_ARM_AARCH64_DLINK_COMMON) 
--oformat=elf32-littlearm
-DEFINE GCC46_ARM_ASLDLINK_FLAGS      = DEF(GCC_ARM_AARCH64_ASLDLINK_FLAGS) 
--oformat=elf32-littlearm
+DEFINE GCC46_ARM_DLINK_FLAGS         = DEF(GCC_ARM_DLINK_FLAGS) 
--oformat=elf32-littlearm
+DEFINE GCC46_ARM_ASLDLINK_FLAGS      = DEF(GCC_ARM_ASLDLINK_FLAGS) 
--oformat=elf32-littlearm
 
 DEFINE GCC47_IA32_CC_FLAGS           = DEF(GCC46_IA32_CC_FLAGS)
 DEFINE GCC47_X64_CC_FLAGS            = DEF(GCC46_X64_CC_FLAGS)
@@ -3881,9 +3884,9 @@ DEFINE GCC47_AARCH64_ASM_FLAGS       = $(ARCHASM_FLAGS) 
$(PLATFORM_FLAGS) DEF(GC
 DEFINE GCC47_ARM_CC_FLAGS            = DEF(GCC46_ARM_CC_FLAGS) 
-mno-unaligned-access
 DEFINE GCC47_AARCH64_CC_FLAGS        = $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) 
DEF(GCC44_ALL_CC_FLAGS) DEF(GCC_AARCH64_CC_FLAGS)
 DEFINE GCC47_ARM_DLINK_FLAGS         = DEF(GCC46_ARM_DLINK_FLAGS)
-DEFINE GCC47_AARCH64_DLINK_FLAGS     = DEF(GCC_ARM_AARCH64_DLINK_COMMON)
+DEFINE GCC47_AARCH64_DLINK_FLAGS     = DEF(GCC_AARCH64_DLINK_FLAGS)
 DEFINE GCC47_ARM_ASLDLINK_FLAGS      = DEF(GCC46_ARM_ASLDLINK_FLAGS)
-DEFINE GCC47_AARCH64_ASLDLINK_FLAGS  = DEF(GCC_ARM_AARCH64_ASLDLINK_FLAGS)
+DEFINE GCC47_AARCH64_ASLDLINK_FLAGS  = DEF(GCC_AARCH64_ASLDLINK_FLAGS)
 
 DEFINE GCC48_IA32_CC_FLAGS           = DEF(GCC47_IA32_CC_FLAGS)
 DEFINE GCC48_X64_CC_FLAGS            = DEF(GCC47_X64_CC_FLAGS)
@@ -3897,9 +3900,9 @@ DEFINE GCC48_AARCH64_ASM_FLAGS       = 
DEF(GCC47_AARCH64_ASM_FLAGS)
 DEFINE GCC48_ARM_CC_FLAGS            = DEF(GCC47_ARM_CC_FLAGS)
 DEFINE GCC48_AARCH64_CC_FLAGS        = DEF(GCC47_AARCH64_CC_FLAGS)
 DEFINE GCC48_ARM_DLINK_FLAGS         = DEF(GCC47_ARM_DLINK_FLAGS)
-DEFINE GCC48_AARCH64_DLINK_FLAGS     = DEF(GCC_ARM_AARCH64_DLINK_COMMON)
+DEFINE GCC48_AARCH64_DLINK_FLAGS     = DEF(GCC47_AARCH64_DLINK_FLAGS)
 DEFINE GCC48_ARM_ASLDLINK_FLAGS      = DEF(GCC47_ARM_ASLDLINK_FLAGS)
-DEFINE GCC48_AARCH64_ASLDLINK_FLAGS  = DEF(GCC_ARM_AARCH64_ASLDLINK_FLAGS)
+DEFINE GCC48_AARCH64_ASLDLINK_FLAGS  = DEF(GCC47_AARCH64_ASLDLINK_FLAGS)
 
 DEFINE GCC49_IA32_CC_FLAGS           = DEF(GCC48_IA32_CC_FLAGS)
 DEFINE GCC49_X64_CC_FLAGS            = DEF(GCC48_X64_CC_FLAGS)
@@ -3913,9 +3916,9 @@ DEFINE GCC49_AARCH64_ASM_FLAGS       = 
DEF(GCC48_AARCH64_ASM_FLAGS)
 DEFINE GCC49_ARM_CC_FLAGS            = DEF(GCC48_ARM_CC_FLAGS)
 DEFINE GCC49_AARCH64_CC_FLAGS        = DEF(GCC48_AARCH64_CC_FLAGS)
 DEFINE GCC49_ARM_DLINK_FLAGS         = DEF(GCC48_ARM_DLINK_FLAGS)
-DEFINE GCC49_AARCH64_DLINK_FLAGS     = DEF(GCC_ARM_AARCH64_DLINK_COMMON)
+DEFINE GCC49_AARCH64_DLINK_FLAGS     = DEF(GCC48_AARCH64_DLINK_FLAGS)
 DEFINE GCC49_ARM_ASLDLINK_FLAGS      = DEF(GCC48_ARM_ASLDLINK_FLAGS)
-DEFINE GCC49_AARCH64_ASLDLINK_FLAGS  = DEF(GCC_ARM_AARCH64_ASLDLINK_FLAGS)
+DEFINE GCC49_AARCH64_ASLDLINK_FLAGS  = DEF(GCC48_AARCH64_ASLDLINK_FLAGS)
 
 
####################################################################################
 #
diff --git a/BaseTools/Scripts/gcc-aarch64-ld-script 
b/BaseTools/Scripts/gcc-aarch64-ld-script
new file mode 100644
index 000000000000..cf09b63d916f
--- /dev/null
+++ b/BaseTools/Scripts/gcc-aarch64-ld-script
@@ -0,0 +1,33 @@
+SECTIONS {
+
+  /*
+   * By positioning the .text section at 0x800, and aligning it at 0x800, it
+   * is guaranteed to end up at 0x800 offset in the resulting PE/COFF image as
+   * well. This allows us to use GCC's 'small' C model, which uses PC relative
+   * ADRP/ADD and ADRP/LDR pairs to reference global symbols, instead of 64-bit
+   * absolute addresses.
+   * Since some AArch64 code is aligned to 0x800 (i.e., the vector table), we
+   * need to use at least this alignment for .text. The actual PE/COFF headers
+   * are only around 0x260 bytes in size, so we are wasting around 1.5 KB here.
+   */
+  .text 0x800 : ALIGN(0x800) {
+    *(.text .text.* .rodata .rodata.*)
+  }
+  .data : ALIGN(0x40) {
+    *(.data .data.*)
+    *(.bss .bss.* *COM*)
+  }
+  .rela ALIGN(0x20) : {
+    *(.rela .rela.*)
+  }
+
+  /DISCARD/ : {
+    *(.note.GNU-stack)
+    *(.interp)
+    *(.dynsym)
+    *(.dynstr)
+    *(.dynamic)
+    *(.hash)
+    *(.comment)
+  }
+}
-- 
1.9.1


------------------------------------------------------------------------------
Monitor 25 network devices or servers for free with OpManager!
OpManager is web-based network management software that monitors 
network devices and physical & virtual servers, alerts via email & sms 
for fault. Monitor 25 devices for free with no restriction. Download now
http://ad.doubleclick.net/ddm/clk/292181274;119417398;o
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to