[U-Boot] [PATCH 3/4] arm64: Non-manual relocation

Scott Wood scottwood at freescale.com
Fri Oct 4 00:48:30 CEST 2013


This turns off CONFIG_NEEDS_MANUAL_RELOC and turns on -pie.

The bss part of the linker script is changed to be more like arm32,
as the previous arm64 approach was generating bad relocations (even
readelf didn't like them).

relocate_64.S is made to look more like relocate.S, and then changed to
support RELA style relocations rather than REL.

Signed-off-by: Scott Wood <scottwood at freescale.com>
---
 arch/arm/config.mk                |  2 --
 arch/arm/cpu/armv8/config.mk      |  1 -
 arch/arm/cpu/armv8/u-boot.lds     | 32 +++++++++++++++++++++++-------
 arch/arm/include/asm/config.h     |  5 -----
 arch/arm/lib/crt0_64.S            |  7 ++-----
 arch/arm/lib/relocate_64.S        | 41 ++++++++++++++++++++-------------------
 include/configs/vexpress_aemv8a.h |  3 +++
 7 files changed, 51 insertions(+), 40 deletions(-)

diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index 95c07ad..96d2d88 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -74,9 +74,7 @@ endif
 endif
 
 # needed for relocation
-ifndef CONFIG_ARM64
 LDFLAGS_u-boot += -pie
-endif
 
 #
 # FIXME: binutils versions < 2.22 have a bug in the assembler where
diff --git a/arch/arm/cpu/armv8/config.mk b/arch/arm/cpu/armv8/config.mk
index 9f36d59..027a68c 100644
--- a/arch/arm/cpu/armv8/config.mk
+++ b/arch/arm/cpu/armv8/config.mk
@@ -13,4 +13,3 @@ PLATFORM_NO_UNALIGNED := $(PF_NO_UNALIGNED)
 PF_CPPFLAGS_ARMV8 := $(call cc-option, -march=armv8-a)
 PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_ARMV8)
 PLATFORM_CPPFLAGS += $(PF_NO_UNALIGNED)
-PLATFORM_CPPFLAGS += -fpic
diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds
index 328d477..4c12222 100644
--- a/arch/arm/cpu/armv8/u-boot.lds
+++ b/arch/arm/cpu/armv8/u-boot.lds
@@ -41,25 +41,43 @@ SECTIONS
 	}
 
 	. = ALIGN(8);
-	.reloc : {
-		__rel_got_start = .;
-		*(.got)
-		__rel_got_end = .;
-	}
 
 	.image_copy_end :
 	{
 		*(.__image_copy_end)
 	}
 
+	. = ALIGN(8);
+
+	.rel_dyn_start :
+	{
+		*(.__rel_dyn_start)
+	}
+
+	.rela.dyn : {
+		*(.rela*)
+	}
+
+	.rel_dyn_end :
+	{
+		*(.__rel_dyn_end)
+	}
+
 	_end = .;
 
 	. = ALIGN(8);
+
+	.bss_start : {
+		KEEP(*(.__bss_start));
+	}
+
 	.bss : {
-		__bss_start = .;
 		*(.bss*)
 		 . = ALIGN(8);
-		__bss_end = .;
+	}
+
+	.bss_end : {
+		KEEP(*(.__bss_end));
 	}
 
 	/DISCARD/ : { *(.dynsym) }
diff --git a/arch/arm/include/asm/config.h b/arch/arm/include/asm/config.h
index 0ee131d..de4d01e 100644
--- a/arch/arm/include/asm/config.h
+++ b/arch/arm/include/asm/config.h
@@ -11,11 +11,6 @@
 #define CONFIG_SYS_BOOT_RAMDISK_HIGH
 
 #ifdef CONFIG_ARM64
-/*
- * Currently, GOT is used to relocate u-boot and
- * configuration CONFIG_NEEDS_MANUAL_RELOC is needed.
- */
-#define CONFIG_NEEDS_MANUAL_RELOC
 #define CONFIG_PHYS_64BIT
 #endif
 
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S
index ddd46eb..7756396 100644
--- a/arch/arm/lib/crt0_64.S
+++ b/arch/arm/lib/crt0_64.S
@@ -94,11 +94,8 @@ relocation_return:
 /*
  * Clear BSS section
  */
-	ldr	x9, [x18, #GD_RELOC_OFF]	/* x9 <- gd->reloc_off */
-	ldr	x0, =__bss_start
-	add	x0, x0, x9			/* x0 <- __bss_start in RAM */
-	ldr	x1, =__bss_end
-	add	x1, x1, x9			/* x1 <- __bss_end in RAM */
+	ldr	x0, =__bss_start		/* this is auto-relocated! */
+	ldr	x1, =__bss_end			/* this is auto-relocated! */
 	mov	x2, #0
 clear_loop:
 	str	x2, [x0]
diff --git a/arch/arm/lib/relocate_64.S b/arch/arm/lib/relocate_64.S
index 29c3239..7fba9e2 100644
--- a/arch/arm/lib/relocate_64.S
+++ b/arch/arm/lib/relocate_64.S
@@ -16,40 +16,41 @@
  * void relocate_code (addr_moni)
  *
  * This function relocates the monitor code.
- *
- * NOTE:
- * GOT is used and configuration CONFIG_NEEDS_MANUAL_RELOC is needed.
+ * x0 holds the destination address.
  */
 ENTRY(relocate_code)
 	/*
 	 * Copy u-boot from flash to RAM
 	 */
-	ldr	x1, =__image_copy_start	/* x1 <- copy source */
-	cmp	x1, x0
+	ldr	x1, =__image_copy_start	/* x1 <- SRC &__image_copy_start */
+	subs	x9, x0, x1		/* x9 <- relocation offset */
 	b.eq	relocate_done		/* skip relocation */
-	mov	x2, x0			/* x2 <- copy destination */
-	ldr	x3, =__image_copy_end	/* x3 <- source end address */
+	ldr	x2, =__image_copy_end	/* x2 <- SRC &__image_copy_end */
 
 copy_loop:
 	ldp	x10, x11, [x1], #16	/* copy from source address [x1] */
-	stp	x10, x11, [x2], #16	/* copy to   target address [x2] */
-	cmp	x1, x3			/* until source end address [x3] */
+	stp	x10, x11, [x0], #16	/* copy to   target address [x0] */
+	cmp	x1, x2			/* until source end address [x2] */
 	b.lo	copy_loop
 
 	/*
-	 * Fix .reloc relocations
+	 * Fix .rela.dyn relocations
 	 */
-	ldr	x9, [x18, #GD_RELOC_OFF]/* x9 <- relocation offset */
-	ldr	x1, =__rel_got_start	/* x1 <- rel got start ofs */
-	add	x1, x1, x9		/* x1 <- rel got start in RAM */
-	ldr	x2, =__rel_got_end	/* x2 <- rel got end ofs */
-	add	x2, x2, x9		/* x2 <- rel got end in RAM */
+	ldr	x2, =__rel_dyn_start	/* x2 <- SRC &__rel_dyn_start */
+	ldr	x3, =__rel_dyn_end	/* x3 <- SRC &__rel_dyn_end */
 fixloop:
-	ldr	x10, [x1]
-	add	x10, x10, x9		/* x10 <- address to be fixed up */
-	str	x10, [x1]
-	add	x1, x1, #8		/* each got entry is 8 bytes */
-	cmp	x1, x2
+	ldp	x0, x1, [x2], #16	/* (x0,x1) <- (SRC location, fixup) */
+	ldr	x4, [x2], #8		/* x4 <- addend */
+	and	x1, x1, #0xffffffff
+	cmp	x1, #1027		/* relative fixup? */
+	bne	fixnext
+
+	/* relative fix: store addend plus offset at dest location */
+	add	x0, x0, x9
+	add	x4, x4, x9
+	str	x4, [x0]
+fixnext:
+	cmp	x2, x3
 	b.lo	fixloop
 
 relocate_done:
diff --git a/include/configs/vexpress_aemv8a.h b/include/configs/vexpress_aemv8a.h
index 01c95f5..3932e00 100644
--- a/include/configs/vexpress_aemv8a.h
+++ b/include/configs/vexpress_aemv8a.h
@@ -10,6 +10,9 @@
 
 #define DEBUG
 
+#define CONFIG_REMAKE_ELF
+#define CONFIG_STATIC_RELA
+
 /*#define CONFIG_BOOTING_EL1*/
 
 /*#define CONFIG_SYS_GENERIC_BOARD*/
-- 
1.8.1.2




More information about the U-Boot mailing list