|
@@ -223,12 +223,9 @@ ENTRY(relocate_code)
|
|
|
PTR_LI t0, CONFIG_SYS_MONITOR_BASE
|
|
|
PTR_SUB s1, s2, t0 # s1 <-- relocation offset
|
|
|
|
|
|
- PTR_LA t3, in_ram
|
|
|
- PTR_L t2, -(3 * PTRSIZE)(t3) # t2 <-- __image_copy_end
|
|
|
+ PTR_LA t2, __image_copy_end
|
|
|
move t1, a2
|
|
|
|
|
|
- PTR_ADD gp, s1 # adjust gp
|
|
|
-
|
|
|
/*
|
|
|
* t0 = source address
|
|
|
* t1 = target address
|
|
@@ -241,32 +238,14 @@ ENTRY(relocate_code)
|
|
|
blt t0, t2, 1b
|
|
|
PTR_ADDU t1, PTRSIZE
|
|
|
|
|
|
- /* If caches were enabled, we would have to flush them here. */
|
|
|
- PTR_SUB a1, t1, s2 # a1 <-- size
|
|
|
- PTR_LA t9, flush_cache
|
|
|
- jalr t9
|
|
|
- move a0, s2 # a0 <-- destination address
|
|
|
-
|
|
|
- /* Jump to where we've relocated ourselves */
|
|
|
- PTR_ADDIU t0, s2, in_ram - _start
|
|
|
- jr t0
|
|
|
- nop
|
|
|
-
|
|
|
- PTR __rel_dyn_end
|
|
|
- PTR __rel_dyn_start
|
|
|
- PTR __image_copy_end
|
|
|
- PTR _GLOBAL_OFFSET_TABLE_
|
|
|
- PTR num_got_entries
|
|
|
-
|
|
|
-in_ram:
|
|
|
/*
|
|
|
* 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.
|
|
|
*/
|
|
|
- PTR_L t3, -(1 * PTRSIZE)(t0) # t3 <-- num_got_entries
|
|
|
- PTR_L t8, -(2 * PTRSIZE)(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_
|
|
|
+ PTR_LA t3, num_got_entries
|
|
|
+ PTR_LA t8, _GLOBAL_OFFSET_TABLE_
|
|
|
PTR_ADD t8, s1 # t8 now holds relocated _G_O_T_
|
|
|
PTR_ADDIU t8, t8, 2 * PTRSIZE # skipping first two entries
|
|
|
PTR_LI t2, 2
|
|
@@ -281,8 +260,8 @@ in_ram:
|
|
|
PTR_ADDIU t8, PTRSIZE
|
|
|
|
|
|
/* Update dynamic relocations */
|
|
|
- PTR_L t1, -(4 * PTRSIZE)(t0) # t1 <-- __rel_dyn_start
|
|
|
- PTR_L t2, -(5 * PTRSIZE)(t0) # t2 <-- __rel_dyn_end
|
|
|
+ PTR_LA t1, __rel_dyn_start
|
|
|
+ PTR_LA t2, __rel_dyn_end
|
|
|
|
|
|
b 2f # skip first reserved entry
|
|
|
PTR_ADDIU t1, 2 * PTRSIZE
|
|
@@ -306,6 +285,20 @@ in_ram:
|
|
|
blt t1, t2, 1b
|
|
|
PTR_ADDIU t1, 2 * PTRSIZE # each rel.dyn entry is 2*PTRSIZE bytes
|
|
|
|
|
|
+ /*
|
|
|
+ * Flush caches to ensure our newly modified instructions are visible
|
|
|
+ * to the instruction cache. We're still running with the old GOT, so
|
|
|
+ * apply the reloc offset to the start address.
|
|
|
+ */
|
|
|
+ PTR_LA a0, __text_start
|
|
|
+ PTR_LA a1, __text_end
|
|
|
+ PTR_SUB a1, a1, a0
|
|
|
+ PTR_LA t9, flush_cache
|
|
|
+ jalr t9
|
|
|
+ PTR_ADD a0, s1
|
|
|
+
|
|
|
+ PTR_ADD gp, s1 # adjust gp
|
|
|
+
|
|
|
/*
|
|
|
* Clear BSS
|
|
|
*
|