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.tjernl...@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_tab...@local-4
+       mflr    r30
+#endif
        /* r3: IMMR */
        lis     r3, config_sys_i...@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_entr...@sectoff@l
+       lwz     r3,_got_tab...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to