]> git.sur5r.net Git - u-boot/blobdiff - cpu/mips/start.S
[MIPS] Fix $gp usage
[u-boot] / cpu / mips / start.S
index e91e2137d704f7eb8c0fe7ab6b1907673c1f2716..074d01d2dde203e88f0a07e54040f39b0c2324ba 100644 (file)
@@ -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)