Skip to contentSkip to conversation

Fix several problems on relocation

PATCH In review Shinya Kuribayashi 2 participants 8 messages Oct 20, 2007 – Oct 21, 2007

lore
Share & tools
lore
#0 lore raw

cover Fix several problems on relocation

I've pushed the following patchset on top of the upstream:

The following changes since commit 5441f61a3d8b7034f19fc1361183e936198e6dbb:
Detlev Zundel (1):
Fix two typos.

are available in the git repository at:

git://www.denx.de/git/u-boot-mips.git testing

Shinya Kuribayashi (5):
[MIPS] u-boot.lds: Remove duplicated .sdata section [MIPS] u-boot.lds: Fix __got_start and __got_end
[MIPS] Fix $gp usage
[MIPS] u-boot.lds: Define _gp in a standard manner
[MIPS] Add PIC-related switches to PLATFORM_{CPP,LD}FLAGS and cleanup

 board/dbau1x00/u-boot.lds |   14 +++++++-------
 board/gth2/u-boot.lds     |   14 +++++++-------
 board/incaip/u-boot.lds   |   14 +++++++-------
 board/pb1x00/u-boot.lds   |   14 +++++++-------
 board/purple/u-boot.lds   |   14 +++++++-------
 board/tb0229/u-boot.lds   |   14 +++++++-------
 cpu/mips/config.mk        |    4 +---
 cpu/mips/start.S          |   19 +++++++++++++------
 examples/mips.lds         |   14 +++++++-------
 mips_config.mk            |   25 +++++++++++++++++++++++++
 10 files changed, 88 insertions(+), 58 deletions(-)

These patches mainly try to fix an outstanding mips bug:

http://article.gmane.org/gmane.comp.boot-loaders.u-boot/25533
http://article.gmane.org/gmane.comp.boot-loaders.u-boot/22160
http://article.gmane.org/gmane.comp.boot-loaders.u-boot/19550
http://article.gmane.org/gmane.comp.boot-loaders.u-boot/18887
http://article.gmane.org/gmane.comp.boot-loaders.u-boot/14935

As already discussed, the cause of this bug is a misalignment between __got_start and _GLOBAL_OFFSET_TABLE_. The __got_start misalignment makes num_got_entries larger than needed. As a result, we update GOT entries too many and corrupt top of the u_boot_cmd data. This will be fixed by __got_{start,end} cleanups in linker scripts.

In addition to fixing above, I've takan $gp usage fix suggested by Vlad, and cleaned up linker scripts, etc. Please review and give it a try.

thanks,

Shinya

#1 lore raw

PATCH 1/5 u-boot.lds: Remove duplicated .sdata section

From: Shinya Kuribayashi <[email protected]>

---

 board/dbau1x00/u-boot.lds |    3 ---
 board/gth2/u-boot.lds     |    3 ---
 board/incaip/u-boot.lds   |    3 ---
 board/pb1x00/u-boot.lds   |    3 ---
 board/purple/u-boot.lds   |    3 ---
 board/tb0229/u-boot.lds   |    3 ---
 examples/mips.lds         |    3 ---
 7 files changed, 0 insertions(+), 21 deletions(-)
board/dbau1x00/u-boot.lds +0 -3
index 10c9917..75a3af6 100644
@@ -43,9 +43,6 @@ SECTIONS
 	. = ALIGN(4);
 	.data  : { *(.data) }
 
-	. = ALIGN(4);
-	.sdata  : { *(.sdata) }
-
 	_gp = ALIGN(16);
 
 	__got_start = .;
board/gth2/u-boot.lds +0 -3
index 8ba0b6d..69c8c9d 100644
@@ -43,9 +43,6 @@ SECTIONS
 	. = ALIGN(4);
 	.data  : { *(.data) }
 
-	. = ALIGN(4);
-	.sdata  : { *(.sdata) }
-
 	_gp = ALIGN(16);
 
 	__got_start = .;
board/incaip/u-boot.lds +0 -3
index 10c9917..75a3af6 100644
@@ -43,9 +43,6 @@ SECTIONS
 	. = ALIGN(4);
 	.data  : { *(.data) }
 
-	. = ALIGN(4);
-	.sdata  : { *(.sdata) }
-
 	_gp = ALIGN(16);
 
 	__got_start = .;
board/pb1x00/u-boot.lds +0 -3
index a2d19a8..865be77 100644
@@ -43,9 +43,6 @@ SECTIONS
 	. = ALIGN(4);
 	.data  : { *(.data) }
 
-	. = ALIGN(4);
-	.sdata  : { *(.sdata) }
-
 	_gp = ALIGN(16);
 
 	__got_start = .;
board/purple/u-boot.lds +0 -3
index 1bdac1f..6b3783f 100644
@@ -53,9 +53,6 @@ SECTIONS
 	. = ALIGN(4);
 	.data  : { *(.data) }
 
-	. = ALIGN(4);
-	.sdata  : { *(.sdata) }
-
 	_gp = ALIGN(16);
 
 	__got_start = .;
board/tb0229/u-boot.lds +0 -3
index 30a2bc5..26d8c81 100644
@@ -43,9 +43,6 @@ SECTIONS
 	. = ALIGN(4);
 	.data  : { *(.data) }
 
-	. = ALIGN(4);
-	.sdata  : { *(.sdata) }
-
 	_gp = ALIGN(16);
 
 	__got_start = .;
examples/mips.lds +0 -3
index 9d9849b..6f31eb7 100644
@@ -39,9 +39,6 @@ SECTIONS
 	. = ALIGN(4);
 	.data  : { *(.data) }
 
-	. = ALIGN(4);
-	.sdata  : { *(.sdata) }
-
 	_gp = ALIGN(16);
 
 	__got_start = .;
#2 lore raw

PATCH 2/5 u-boot.lds: Fix __got_start and __got_end

From: Shinya Kuribayashi <[email protected]>

Ensure that __got_start points to top of the `.got', and __got_end points to bottom as well, so that we never fail to count num_got_entries.

---

 board/dbau1x00/u-boot.lds |    8 +++++---
 board/gth2/u-boot.lds     |    8 +++++---
 board/incaip/u-boot.lds   |    8 +++++---
 board/pb1x00/u-boot.lds   |    8 +++++---
 board/purple/u-boot.lds   |    8 +++++---
 board/tb0229/u-boot.lds   |    8 +++++---
 examples/mips.lds         |    8 +++++---
 7 files changed, 35 insertions(+), 21 deletions(-)
board/dbau1x00/u-boot.lds +5 -3
index 75a3af6..9c71ef7 100644
@@ -45,9 +45,11 @@ SECTIONS
 
 	_gp = ALIGN(16);
 
-	__got_start = .;
-	.got  : { *(.got) }
-	__got_end = .;
+	.got : {
+	  __got_start = .;
+	  *(.got)
+	  __got_end = .;
+	}
 
 	.sdata  : { *(.sdata) }
 
board/gth2/u-boot.lds +5 -3
index 69c8c9d..0ab42db 100644
@@ -45,9 +45,11 @@ SECTIONS
 
 	_gp = ALIGN(16);
 
-	__got_start = .;
-	.got  : { *(.got) }
-	__got_end = .;
+	.got : {
+	  __got_start = .;
+	  *(.got)
+	  __got_end = .;
+	}
 
 	.sdata  : { *(.sdata) }
 
board/incaip/u-boot.lds +5 -3
index 75a3af6..9c71ef7 100644
@@ -45,9 +45,11 @@ SECTIONS
 
 	_gp = ALIGN(16);
 
-	__got_start = .;
-	.got  : { *(.got) }
-	__got_end = .;
+	.got : {
+	  __got_start = .;
+	  *(.got)
+	  __got_end = .;
+	}
 
 	.sdata  : { *(.sdata) }
 
board/pb1x00/u-boot.lds +5 -3
index 865be77..7329e6a 100644
@@ -45,9 +45,11 @@ SECTIONS
 
 	_gp = ALIGN(16);
 
-	__got_start = .;
-	.got  : { *(.got) }
-	__got_end = .;
+	.got : {
+	  __got_start = .;
+	  *(.got)
+	  __got_end = .;
+	}
 
 	.sdata  : { *(.sdata) }
 
board/purple/u-boot.lds +5 -3
index 6b3783f..aa51cbf 100644
@@ -55,9 +55,11 @@ SECTIONS
 
 	_gp = ALIGN(16);
 
-	__got_start = .;
-	.got  : { *(.got) }
-	__got_end = .;
+	.got : {
+	  __got_start = .;
+	  *(.got)
+	  __got_end = .;
+	}
 
 	.sdata  : { *(.sdata) }
 
board/tb0229/u-boot.lds +5 -3
index 26d8c81..148f5e6 100644
@@ -45,9 +45,11 @@ SECTIONS
 
 	_gp = ALIGN(16);
 
-	__got_start = .;
-	.got  : { *(.got) }
-	__got_end = .;
+	.got : {
+	  __got_start = .;
+	  *(.got)
+	  __got_end = .;
+	}
 
 	.sdata  : { *(.sdata) }
 
examples/mips.lds +5 -3
index 6f31eb7..3bd573c 100644
@@ -41,9 +41,11 @@ SECTIONS
 
 	_gp = ALIGN(16);
 
-	__got_start = .;
-	.got  : { *(.got) }
-	__got_end = .;
+	.got : {
+	  __got_start = .;
+	  *(.got)
+	  __got_end = .;
+	}
 
 	.sdata  : { *(.sdata) }
 
#3 lore raw

PATCH 3/5 Fix $gp usage

From: Shinya Kuribayashi <[email protected]>

Now we load $gp with _GLOBAL_OFFSET_TABLE_, but this is incorrect use. As a general principle, we should use _gp for $gp.

Thanks to linker script's help we fortunately have _gp which equals to _GLOBAL_OFFSET_TABLE_. But once _gp gets out of alignment, we will not be able to access to GOT entires, global variables and procedure entry points. The right thing to do is to use _gp.

This patch also introduce a new symbol `.gpword _GLOBAL_OFFSET_TABLE_' which holds the offset from _gp. When updating GOT entries, we use this offset and _gp to calculate the final _GLOBAL_OFFSET_TABLE_.

This patch is originally submitted by Vlad Lungu <[email protected]>, then I made some change to leave over num_got_entries.

---

 cpu/mips/start.S |   19 +++++++++++++------
 1 files changed, 13 insertions(+), 6 deletions(-)
cpu/mips/start.S +13 -6
index e91e213..074d01d 100644
@@ -234,11 +234,11 @@ reset:
 	li	t0, CONF_CM_UNCACHED
 	mtc0	t0, CP0_CONFIG
 
-	/* Initialize GOT pointer.
+	/* Initialize $gp.
 	*/
 	bal     1f
 	nop
-	.word   _GLOBAL_OFFSET_TABLE_
+	.word	_gp
 	1:
 	move    gp, ra
 	lw      t1, 0(ra)
@@ -306,9 +306,9 @@ relocate_code:
 	move	t1, a2
 
 	/*
-	 * Fix GOT pointer:
+	 * Fix $gp:
 	 *
-	 * New GOT-PTR = (old GOT-PTR - CFG_MONITOR_BASE) + Destination Address
+	 * New $gp = (Old $gp - CFG_MONITOR_BASE) + Destination Address
 	 */
 	move	t6, gp
 	sub	gp, CFG_MONITOR_BASE
@@ -341,15 +341,22 @@ relocate_code:
 	j	t0
 	nop
 
+	.gpword	_GLOBAL_OFFSET_TABLE_	/* _GLOBAL_OFFSET_TABLE_ - _gp	*/
 	.word	uboot_end_data
 	.word	uboot_end
 	.word	num_got_entries
 
 in_ram:
-	/* Now we want to update GOT.
+	/*
+	 * Now we want to update GOT.
+	 *
+	 * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
+	 * generated by GNU ld. Skip these reserved entries from relocation.
 	 */
 	lw	t3, -4(t0)	/* t3 <-- num_got_entries	*/
-	addi	t4, gp, 8	/* Skipping first two entries.	*/
+	lw	t4, -16(t0)	/* t4 <-- (_GLOBAL_OFFSET_TABLE_ - _gp)	*/
+	add	t4, t4, gp	/* t4 now holds _GLOBAL_OFFSET_TABLE_	*/
+	addi	t4, t4, 8	/* Skipping first two entries.	*/
 	li	t2, 2
 1:
 	lw	t1, 0(t4)
#4 lore raw

PATCH 4/5 u-boot.lds: Define _gp in a standard manner

From: Shinya Kuribayashi <[email protected]>

---

 board/dbau1x00/u-boot.lds |    3 ++-
 board/gth2/u-boot.lds     |    3 ++-
 board/incaip/u-boot.lds   |    3 ++-
 board/pb1x00/u-boot.lds   |    3 ++-
 board/purple/u-boot.lds   |    3 ++-
 board/tb0229/u-boot.lds   |    3 ++-
 examples/mips.lds         |    3 ++-
 7 files changed, 14 insertions(+), 7 deletions(-)
board/dbau1x00/u-boot.lds +2 -1
index 9c71ef7..9639b81 100644
@@ -43,7 +43,8 @@ SECTIONS
 	. = ALIGN(4);
 	.data  : { *(.data) }
 
-	_gp = ALIGN(16);
+	. = .;
+	_gp = ALIGN(16) + 0x7ff0;
 
 	.got : {
 	  __got_start = .;
board/gth2/u-boot.lds +2 -1
index 0ab42db..90432cb 100644
@@ -43,7 +43,8 @@ SECTIONS
 	. = ALIGN(4);
 	.data  : { *(.data) }
 
-	_gp = ALIGN(16);
+	. = .;
+	_gp = ALIGN(16) + 0x7ff0;
 
 	.got : {
 	  __got_start = .;
board/incaip/u-boot.lds +2 -1
index 9c71ef7..9639b81 100644
@@ -43,7 +43,8 @@ SECTIONS
 	. = ALIGN(4);
 	.data  : { *(.data) }
 
-	_gp = ALIGN(16);
+	. = .;
+	_gp = ALIGN(16) + 0x7ff0;
 
 	.got : {
 	  __got_start = .;
board/pb1x00/u-boot.lds +2 -1
index 7329e6a..363d974 100644
@@ -43,7 +43,8 @@ SECTIONS
 	. = ALIGN(4);
 	.data  : { *(.data) }
 
-	_gp = ALIGN(16);
+	. = .;
+	_gp = ALIGN(16) + 0x7ff0;
 
 	.got : {
 	  __got_start = .;
board/purple/u-boot.lds +2 -1
index aa51cbf..e7ec012 100644
@@ -53,7 +53,8 @@ SECTIONS
 	. = ALIGN(4);
 	.data  : { *(.data) }
 
-	_gp = ALIGN(16);
+	. = .;
+	_gp = ALIGN(16) + 0x7ff0;
 
 	.got : {
 	  __got_start = .;
board/tb0229/u-boot.lds +2 -1
index 148f5e6..b2fa9f2 100644
@@ -43,7 +43,8 @@ SECTIONS
 	. = ALIGN(4);
 	.data  : { *(.data) }
 
-	_gp = ALIGN(16);
+	. = .;
+	_gp = ALIGN(16) + 0x7ff0;
 
 	.got : {
 	  __got_start = .;
examples/mips.lds +2 -1
index 3bd573c..a770728 100644
@@ -39,7 +39,8 @@ SECTIONS
 	. = ALIGN(4);
 	.data  : { *(.data) }
 
-	_gp = ALIGN(16);
+	. = .;
+	_gp = ALIGN(16) + 0x7ff0;
 
 	.got : {
 	  __got_start = .;
#5 lore raw

[U-Boot-Users] [MIPS] Add PIC-related switches to PLATFORM_{CPP, LD}FLAGS and cleanup

From: Shinya Kuribayashi <[email protected]>

---

 cpu/mips/config.mk |    4 +---
 mips_config.mk     |   25 +++++++++++++++++++++++++
 2 files changed, 26 insertions(+), 3 deletions(-)
cpu/mips/config.mk +1 -3
index b29986e..1f2860e 100644
@@ -35,6 +35,4 @@ else
 ENDIANNESS = -EB
 endif
 
-MIPSFLAGS += $(ENDIANNESS) -mabicalls
-
-PLATFORM_CPPFLAGS += $(MIPSFLAGS)
+PLATFORM_CPPFLAGS += $(ENDIANNESS)
mips_config.mk +25 -0
index d8aa5fa..67fb67d 100644
@@ -22,3 +22,28 @@
 #
 
 PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__
+
+#
+# From Linux arch/mips/Makefile
+#
+# GCC uses -G 0 -mabicalls -fpic as default.  We don't want PIC in the kernel
+# code since it only slows down the whole thing.  At some point we might make
+# use of global pointer optimizations but their use of $28 conflicts with
+# the current pointer optimization.
+#
+# The DECStation requires an ECOFF kernel for remote booting, other MIPS
+# machines may also.  Since BFD is incredibly buggy with respect to
+# crossformat linking we rely on the elf2ecoff tool for format conversion.
+#
+# cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe
+# cflags-y			+= -msoft-float
+# LDFLAGS_vmlinux		+= -G 0 -static -n -nostdlib
+# MODFLAGS			+= -mlong-calls
+#
+
+#
+# Meanwhile, U-Boot rely on PIC. We add proper switches explicitly.
+#
+PLATFORM_CPPFLAGS		+= -G 0 -mabicalls -fpic -pipe
+PLATFORM_CPPFLAGS		+= -msoft-float
+PLATFORM_LDFLAGS		+= -G 0 -static -n -nostdlib
#6 lore raw

[U-Boot-Users] [MIPS] Add PIC-related switches to PLATFORM_{CPP, LD}FLAGS and cleanup

Quoted 4 lines · In message <[email protected]> you wrote:

From: Shinya Kuribayashi <[email protected]>

---

Re this and your other MIPS patches: I would like to relesase U-Boot 1.3.0 soon. Will you send a pull request for all these patches soon? Then I would wait...

Best regards,

Wolfgang Denk

Signature · 7 lines
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
After a heated argument on some trivial matter Nancy [Astor]  .  .  .
shouted,  ``If  I were your wife I would put poison in your coffee!''
Whereupon Winston Churchill with equal heat and  sincerity  answered,
``And if I were your husband I would drink it.''
#7 lore raw

[U-Boot-Users] [MIPS] Add PIC-related switches to PLATFORM_{CPP, LD}FLAGS and cleanup

In reply to Shinya Kuribayashi

cpu/mips/config.mk else · line 38

Quoted 12 lines · Shinya Kuribayashi
cpu/mips/config.mk +1 -3
index b29986e..1f2860e 100644
@@ -35,6 +35,4 @@ else
 ENDIANNESS = -EB
 endif
 
-MIPSFLAGS += $(ENDIANNESS) -mabicalls
-
-PLATFORM_CPPFLAGS += $(MIPSFLAGS)
+PLATFORM_CPPFLAGS += $(ENDIANNESS)

Err, I should have fixed like this:

-MIPSFLAGS += $(ENDIANNESS) -mabicalls
+MIPSFLAGS += $(ENDIANNESS)

already fixed.

Shinya

Quoted 33 lines
mips_config.mk +25 -0
index d8aa5fa..67fb67d 100644
@@ -22,3 +22,28 @@
 #
 
 PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__
+
+#
+# From Linux arch/mips/Makefile
+#
+# GCC uses -G 0 -mabicalls -fpic as default.  We don't want PIC in the kernel
+# code since it only slows down the whole thing.  At some point we might make
+# use of global pointer optimizations but their use of $28 conflicts with
+# the current pointer optimization.
+#
+# The DECStation requires an ECOFF kernel for remote booting, other MIPS
+# machines may also.  Since BFD is incredibly buggy with respect to
+# crossformat linking we rely on the elf2ecoff tool for format conversion.
+#
+# cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe
+# cflags-y			+= -msoft-float
+# LDFLAGS_vmlinux		+= -G 0 -static -n -nostdlib
+# MODFLAGS			+= -mlong-calls
+#
+
+#
+# Meanwhile, U-Boot rely on PIC. We add proper switches explicitly.
+#
+PLATFORM_CPPFLAGS		+= -G 0 -mabicalls -fpic -pipe
+PLATFORM_CPPFLAGS		+= -msoft-float
+PLATFORM_LDFLAGS		+= -G 0 -static -n -nostdlib