[U-Boot] [PATCHv3] mpc83xx: Add -fpic relocation support
Joakim Tjernlund
Joakim.Tjernlund at transmode.se
Wed Oct 13 23:11:59 CEST 2010
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 at 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(-)
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_ at local-4
+ mflr r30
+#endif
/* r3: IMMR */
lis r3, CONFIG_SYS_IMMR at 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 at sectoff@l
+ lwz r3,_GOT_TABLE_ at 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) }
--
1.7.2.2
More information about the U-Boot
mailing list