Patchwork [U-Boot,PATCHv3] mpc83xx: Add -fpic relocation support

login
register
mail settings
Submitter Joakim Tjernlund
Date Oct. 13, 2010, 9:11 p.m.
Message ID <1287004319-21282-1-git-send-email-Joakim.Tjernlund@transmode.se>
Download mbox | patch
Permalink /patch/71866/
State RFC
Headers show

Comments

Joakim Tjernlund - Oct. 13, 2010, 9:11 p.m.
This adds relocation of .got entries produced
by -fpic. -fpic produces 2-3% smaller code and
is faster. Unfortunately gcc promotes -fpic to
-fPIC when -mrelocatable is used so one need a very
small patch to gcc too(sent upstream).

-fpic puts its GOT entries in .got section(s) and
linker defines the symbol _GLOBAL_OFFSET_TABLE_ to point
to the middle of this table. The entry at _GLOBAL_OFFSET_TABLE_-4
contains a blrl insn which is used to find the table's
real address by branching to _GLOBAL_OFFSET_TABLE_-4.

Here are some size examples for my board:
size with -fPIC
 text    data	    bss	    dec	    hex	filename
 224687  14400	  24228	 263315	  40493	u-boot

size with -mbss-plt -fPIC
 text	   data	    bss	    dec	    hex	filename
 222687  14400	  24228	 261315	  3fcc3	u-boot

size with -mbss-plt -fpic
 text   data	    bss	    dec	    hex	filename
 225179   6580	  24228	 255987	  3e7f3	u-boot

size with -mbss-plt -fpic -msingle-pic-base
 text	  data	    bss	    dec	    hex	filename
 222091   6580	  24228	 252899	  3dbe3	u-boot

Note: -msingle-pic-base is not supported upstream yet.

Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
---

 v3:
 - Make the new -fpic code to have zero impact when
   not compled with -fpic
 - linker __got*_entries sysm needs to be defined
   outside the referenced scope.
   Add linker sym __got_entries for -fpic relocs.
   Very likely more *lds scripts needs fixing but
   that is somebody elses problem :)
 - NAND SPL still don't fit for MPC8315ERDB and SIMPC8313
   but these didn't fit before either. Note that
   my tree isn't current so it migth be fixed in master.

 arch/powerpc/cpu/mpc83xx/start.S                |   26 +++++++++++++++++++++-
 arch/powerpc/cpu/mpc83xx/u-boot.lds             |    3 ++
 nand_spl/board/freescale/mpc8313erdb/u-boot.lds |    7 ++++-
 nand_spl/board/freescale/mpc8315erdb/u-boot.lds |    7 ++++-
 4 files changed, 37 insertions(+), 6 deletions(-)
Joakim Tjernlund - Oct. 20, 2010, 6:32 a.m.
> From: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
> To: u-boot@lists.denx.de, Scott Wood <scottwood@freescale.com>, Kim 
Phillips 
> <kim.phillips@freescale.com>
> Cc: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
> Date: 2010/10/13 23:12
> Subject: [U-Boot] [PATCHv3] mpc83xx: Add -fpic relocation support
> Sent by: u-boot-bounces@lists.denx.de
> 
> This adds relocation of .got entries produced
> by -fpic. -fpic produces 2-3% smaller code and
> is faster. Unfortunately gcc promotes -fpic to
> -fPIC when -mrelocatable is used so one need a very
> small patch to gcc too(sent upstream).
> 
> -fpic puts its GOT entries in .got section(s) and
> linker defines the symbol _GLOBAL_OFFSET_TABLE_ to point
> to the middle of this table. The entry at _GLOBAL_OFFSET_TABLE_-4
> contains a blrl insn which is used to find the table's
> real address by branching to _GLOBAL_OFFSET_TABLE_-4.

Ping?

 Jocke
Joakim Tjernlund - Oct. 28, 2010, 8:46 a.m.
> From: Joakim Tjernlund <joakim.tjernlund@transmode.se>
>
> > From: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
> > To: u-boot@lists.denx.de, Scott Wood <scottwood@freescale.com>, Kim
> Phillips
> > <kim.phillips@freescale.com>
> > Cc: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
> > Date: 2010/10/13 23:12
> > Subject: [U-Boot] [PATCHv3] mpc83xx: Add -fpic relocation support
> > Sent by: u-boot-bounces@lists.denx.de
> >
> > This adds relocation of .got entries produced
> > by -fpic. -fpic produces 2-3% smaller code and
> > is faster. Unfortunately gcc promotes -fpic to
> > -fPIC when -mrelocatable is used so one need a very
> > small patch to gcc too(sent upstream).
> >
> > -fpic puts its GOT entries in .got section(s) and
> > linker defines the symbol _GLOBAL_OFFSET_TABLE_ to point
> > to the middle of this table. The entry at _GLOBAL_OFFSET_TABLE_-4
> > contains a blrl insn which is used to find the table's
> > real address by branching to _GLOBAL_OFFSET_TABLE_-4.
>
> Ping?

Ping ping :)

I should mention that this work tougher with -msingle-pic-base paves
the way for true PIC with minimal changes to C source code.

Patch

diff --git a/arch/powerpc/cpu/mpc83xx/start.S b/arch/powerpc/cpu/mpc83xx/start.S
index c7d85a8..c9bb0ea 100644
--- a/arch/powerpc/cpu/mpc83xx/start.S
+++ b/arch/powerpc/cpu/mpc83xx/start.S
@@ -296,7 +296,11 @@  in_flash:
 	/*------------------------------------------------------*/
 
 	GET_GOT			/* initialize GOT access	*/
-
+#if defined(__pic__) && __pic__ == 1
+	/* Needed for upcoming -msingle-pic-base */
+	bl	_GLOBAL_OFFSET_TABLE_@local-4
+	mflr	r30
+#endif
 	/* r3: IMMR */
 	lis	r3, CONFIG_SYS_IMMR@h
 	/* run low-level CPU init code (in Flash)*/
@@ -950,7 +954,25 @@  in_ram:
 	add	r0,r0,r11
 	stw	r0,0(r3)
 2:	bdnz	1b
-
+#if defined(__pic__) && __pic__ == 1
+	/*
+	 * Relocation of *.got(-fpic)
+	 *
+	 * Adjust got pointers, no need to check for 0, this code
+	 * already puts one entry in the table.
+	 */
+	li	r0,__got_entries@sectoff@l
+	lwz	r3,_GOT_TABLE_@got(r30)
+	add	r3,r3,r11
+	mtctr	r0
+	addi	r3,r3,-4
+1:	lwzu	r0,4(r3)
+	cmpwi	r0,0
+	beq-	2f
+	add	r0,r0,r11
+	stw	r0,0(r3)
+2:	bdnz	1b
+#endif
 #ifndef CONFIG_NAND_SPL
 	/*
 	 * Now adjust the fixups and the pointers to the fixups
diff --git a/arch/powerpc/cpu/mpc83xx/u-boot.lds b/arch/powerpc/cpu/mpc83xx/u-boot.lds
index 0b74a13..8b189d9 100644
--- a/arch/powerpc/cpu/mpc83xx/u-boot.lds
+++ b/arch/powerpc/cpu/mpc83xx/u-boot.lds
@@ -67,12 +67,15 @@  SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
+    _GOT_TABLE_ = .;
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     *(.got)
     _GOT2_TABLE_ = .;
     *(.got2)
     _FIXUP_TABLE_ = .;
     *(.fixup)
   }
+  __got_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT_TABLE_) >> 2)-1;
   __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
   __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
 
diff --git a/nand_spl/board/freescale/mpc8313erdb/u-boot.lds b/nand_spl/board/freescale/mpc8313erdb/u-boot.lds
index ad82589..a3cacf6 100644
--- a/nand_spl/board/freescale/mpc8313erdb/u-boot.lds
+++ b/nand_spl/board/freescale/mpc8313erdb/u-boot.lds
@@ -38,11 +38,14 @@  SECTIONS
 	.data : {
 		*(.data*)
 		*(.sdata*)
+		_GOT_TABLE_ = .;
+		PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
+		*(.got)
 		_GOT2_TABLE_ = .;
 		*(.got2)
-		__got2_entries = (. - _GOT2_TABLE_) >> 2;
 	}
-
+	__got_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT_TABLE_) >> 2)-1;
+	__got2_entries = (. - _GOT2_TABLE_) >> 2;
 	. = ALIGN(8);
 	__bss_start = .;
 	.bss (NOLOAD) : { *(.*bss) }
diff --git a/nand_spl/board/freescale/mpc8315erdb/u-boot.lds b/nand_spl/board/freescale/mpc8315erdb/u-boot.lds
index ad82589..a3cacf6 100644
--- a/nand_spl/board/freescale/mpc8315erdb/u-boot.lds
+++ b/nand_spl/board/freescale/mpc8315erdb/u-boot.lds
@@ -38,11 +38,14 @@  SECTIONS
 	.data : {
 		*(.data*)
 		*(.sdata*)
+		_GOT_TABLE_ = .;
+		PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
+		*(.got)
 		_GOT2_TABLE_ = .;
 		*(.got2)
-		__got2_entries = (. - _GOT2_TABLE_) >> 2;
 	}
-
+	__got_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT_TABLE_) >> 2)-1;
+	__got2_entries = (. - _GOT2_TABLE_) >> 2;
 	. = ALIGN(8);
 	__bss_start = .;
 	.bss (NOLOAD) : { *(.*bss) }