[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