[U-Boot] [RFC 3/3] MIPS: add dynamic relocation support

Gabor Juhos juhosg at openwrt.org
Sun Feb 3 10:26:22 CET 2013


The code handles relocation entries with the
following relocation types only:
  mips32: R_MIPS_REL32
  mips64: R_MIPS_REL+R_MIPS_64
  xburst: R_MIPS_REL32

Other relocation entries are skipped without
processing. The code must be extended if other
relocation types must be upported, however my
toolchains uses these types only.

The CONFIG_NEEDS_MANUAL_RELOC is not needed
after the patch, so remove that as well.

Signed-off-by: Gabor Juhos <juhosg at openwrt.org>
Cc: Daniel Schwierzeck <daniel.schwierzeck at googlemail.com>
---
 arch/mips/cpu/mips32/start.S   |   31 +++++++++++++++++++++++++++++--
 arch/mips/cpu/mips64/start.S   |   39 +++++++++++++++++++++++++++++++++++++--
 arch/mips/cpu/xburst/start.S   |   31 +++++++++++++++++++++++++++++--
 arch/mips/include/asm/config.h |    2 --
 4 files changed, 95 insertions(+), 8 deletions(-)

diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S
index 7373d4e..4db06a0 100644
--- a/arch/mips/cpu/mips32/start.S
+++ b/arch/mips/cpu/mips32/start.S
@@ -201,6 +201,8 @@ relocate_code:
 	jr	t0
 	 nop
 
+	.word	__rel_dyn_end
+	.word   __rel_dyn_start
 	.word	_GLOBAL_OFFSET_TABLE_
 	.word	uboot_end_data
 	.word	uboot_end
@@ -228,11 +230,36 @@ in_ram:
 	blt	t2, t3, 1b
 	 addi	t4, 4
 
+	/* Update dynamic relocations. */
+	lw	t1, -20(t0)		# t1 <-- __rel_dyn_start
+	lw	t2, -24(t0)		# t2 <-- __rel_dyn_end
+
+	/* The first relocation entry is reserved, skip it. */
+	b	2f
+	 addi	t1, 8
+
+1:
+	lw	t3, -4(t1)		# t4 <-- relocation info
+
+	sub	t3, 3
+	bnez	t3, 2f			# skip non R_MIPS_REL32 entries
+	 nop
+
+	lw	t3, -8(t1)		# t3 <-- location to fix up in FLASH
+
+	lw	t4, 0(t3)		# t4 <-- original pointer
+	add	t4, s1			# t4 <-- adjusted pointer
+
+	add	t3, s1			# t3 <-- location to fix up in RAM
+	sw	t4, 0(t3)
+
+2:
+	blt	t1, t2, 1b
+	 addi	t1, 8			# each rel.dyn entry is 8 bytes
+
 	/* Clear BSS */
 	lw	t1, -12(t0)		# t1 <-- uboot_end_data
 	lw	t2, -8(t0)		# t2 <-- uboot_end
-	add	t1, s1			# adjust pointers
-	add	t2, s1
 
 	sub	t1, 4
 1:
diff --git a/arch/mips/cpu/mips64/start.S b/arch/mips/cpu/mips64/start.S
index c0ae41a..3479d77 100644
--- a/arch/mips/cpu/mips64/start.S
+++ b/arch/mips/cpu/mips64/start.S
@@ -31,6 +31,14 @@
 #define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
 #endif
 
+#ifdef CONFIG_SYS_LITTLE_ENDIAN
+#define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
+	(((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym))
+#else
+#define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
+	((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24)
+#endif
+
 	/*
 	 * For the moment disable interrupts, mark the kernel mode and
 	 * set ST0_KX so that the CPU does not spit fire when using
@@ -193,6 +201,8 @@ relocate_code:
 	jr	t0
 	 nop
 
+	.dword	__rel_dyn_end
+	.dword	__rel_dyn_start
 	.dword	_GLOBAL_OFFSET_TABLE_
 	.dword	uboot_end_data
 	.dword	uboot_end
@@ -220,11 +230,36 @@ in_ram:
 	blt	t2, t3, 1b
 	 daddi	t8, 8
 
+	/* update dynamic relocation entries */
+	ld	t1, -40(t0)		# t1 <-- __rel_dyn_start
+	ld	t2, -48(t0)		# t2 <-- __rel_dyn_end
+
+	/* The first relocation entry is reserved, skip it. */
+	b	2f
+	 daddi	t1, 16
+
+1:
+	lw	t8, -4(t1)		# t8 <-- r_info
+
+	dli	t3, MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03)
+	bne	t8, t3, 2f		# skip non R_MIPS_REL32 entries
+	 nop
+
+	ld	t3, -16(t1)		# t3 <-- location to fix up in FLASH
+
+	ld	t8, 0(t3)		# t8 <-- original pointer
+	dadd	t8, s1			# t8 <-- adjusted pointer
+
+	dadd	t3, s1			# t3 <-- location to fix up in RAM
+	sd	t8, 0(t3)
+
+2:
+	blt	t1, t2, 1b
+	 daddi	t1, 16			# each rel.dyn entry is 16 bytes
+
 	/* Clear BSS */
 	ld	t1, -24(t0)		# t1 <-- uboot_end_data
 	ld	t2, -16(t0)		# t2 <-- uboot_end
-	dadd	t1, s1			# adjust pointers
-	dadd	t2, s1
 
 	dsub	t1, 8
 1:
diff --git a/arch/mips/cpu/xburst/start.S b/arch/mips/cpu/xburst/start.S
index 50b7fb1..e669061 100644
--- a/arch/mips/cpu/xburst/start.S
+++ b/arch/mips/cpu/xburst/start.S
@@ -116,6 +116,8 @@ relocate_code:
 	jr	t0
 	 nop
 
+	.word	__rel_dyn_end
+	.word   __rel_dyn_start
 	.word	_GLOBAL_OFFSET_TABLE_
 	.word	uboot_end_data
 	.word	uboot_end
@@ -143,11 +145,36 @@ in_ram:
 	blt	t2, t3, 1b
 	 addi	t4, 4
 
+	/* Update dynamic relocations. */
+	lw	t1, -20(t0)		# t1 <-- __rel_dyn_start
+	lw	t2, -24(t0)		# t2 <-- __rel_dyn_end
+
+	/* The first relocation entry is reserved, skip it. */
+	b	2f
+	 addi	t1, 8
+
+1:
+	lw	t3, -4(t1)		# t4 <-- relocation info
+
+	sub	t3, 3
+	bnez	t3, 2f			# skip non R_MIPS_REL32 entries
+	 nop
+
+	lw	t3, -8(t1)		# t3 <-- location to fix up in FLASH
+
+	lw	t4, 0(t3)		# t4 <-- original pointer
+	add	t4, t6			# t4 <-- adjusted pointer
+
+	add	t3, t6			# t3 <-- location to fix up in RAM
+	sw	t4, 0(t3)
+
+2:
+	blt	t1, t2, 1b
+	 addi	t1, 8			# each rel.dyn entry is 8 bytes
+
 	/* Clear BSS */
 	lw	t1, -12(t0)		# t1 <-- uboot_end_data
 	lw	t2, -8(t0)		# t2 <-- uboot_end
-	add	t1, t6			# adjust pointers
-	add	t2, t6
 
 	sub	t1, 4
 1:	addi	t1, 4
diff --git a/arch/mips/include/asm/config.h b/arch/mips/include/asm/config.h
index 02fbfb3..049c44e 100644
--- a/arch/mips/include/asm/config.h
+++ b/arch/mips/include/asm/config.h
@@ -21,6 +21,4 @@
 #ifndef _ASM_CONFIG_H_
 #define _ASM_CONFIG_H_
 
-#define CONFIG_NEEDS_MANUAL_RELOC
-
 #endif
-- 
1.7.10



More information about the U-Boot mailing list