> +   * Since some AArch64 code is aligned to 0x800 (i.e., the vector table), we
> +   * need to use at least this alignment for .text.

>From what I can see the vector table code uses .align directives to increase 
>the alignment size which is propagated into the resulting ELF.  The PE-COFF 
>conversion respects this so I don't believe it is necessary to impose this 
>alignment requirement.

We are very sensitive to code size in SEC and PEI which are typically 
uncompressed and XIP so I would ask that we keep the alignment padding to a 
minimum (see Andrew's email about this topic).

-----Original Message-----
From: Ard Biesheuvel [mailto:ard.biesheu...@linaro.org] 
Sent: Tuesday, June 23, 2015 9:31 AM
To: edk2-devel@lists.sourceforge.net; olivier.mar...@arm.com; 
leif.lindh...@linaro.org
Subject: [edk2] [RFC PATCH 2/4] BaseTools: AArch64: use an explicit linker 
script

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

------------------------------------------------------------------------------
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