diff options
Diffstat (limited to 'arch/arm/lib/relocate.S')
-rw-r--r-- | arch/arm/lib/relocate.S | 61 |
1 files changed, 15 insertions, 46 deletions
diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S index 4446da9..949b9e8 100644 --- a/arch/arm/lib/relocate.S +++ b/arch/arm/lib/relocate.S @@ -37,56 +37,34 @@ */ ENTRY(relocate_code) - mov r6, r0 /* save addr of destination */ - - ldr r0, =_start /* r0 <- SRC &_start */ - subs r9, r6, r0 /* r9 <- relocation offset */ + ldr r1, =__image_copy_start /* r1 <- SRC &__image_copy_start */ + subs r9, r0, r1 /* r9 <- relocation offset */ beq relocate_done /* skip relocation */ - mov r1, r6 /* r1 <- scratch for copy loop */ - adr r7, relocate_code /* r7 <- SRC &relocate_code */ - ldr r3, _image_copy_end_ofs /* r3 <- __image_copy_end local ofs */ - add r2, r7, r3 /* r2 <- SRC &__image_copy_end */ + ldr r2, =__image_copy_end /* r2 <- SRC &__image_copy_end */ copy_loop: - ldmia r0!, {r10-r11} /* copy from source address [r0] */ - stmia r1!, {r10-r11} /* copy to target address [r1] */ - cmp r0, r2 /* until source end address [r2] */ + ldmia r1!, {r10-r11} /* copy from source address [r1] */ + stmia r0!, {r10-r11} /* copy to target address [r0] */ + cmp r1, r2 /* until source end address [r2] */ blo copy_loop /* * fix .rel.dyn relocations */ - ldr r10, _dynsym_start_ofs /* r10 <- __dynsym_start local ofs */ - add r10, r10, r7 /* r10 <- SRC &__dynsym_start */ - ldr r2, _rel_dyn_start_ofs /* r2 <- __rel_dyn_start local ofs */ - add r2, r2, r7 /* r2 <- SRC &__rel_dyn_start */ - ldr r3, _rel_dyn_end_ofs /* r3 <- __rel_dyn_end local ofs */ - add r3, r3, r7 /* r3 <- SRC &__rel_dyn_end */ + ldr r2, =__rel_dyn_start /* r2 <- SRC &__rel_dyn_start */ + ldr r3, =__rel_dyn_end /* r3 <- SRC &__rel_dyn_end */ fixloop: - ldr r0, [r2] /* r0 <- SRC location to fix up */ - add r0, r0, r9 /* r0 <- DST location to fix up */ - ldr r1, [r2, #4] - and r7, r1, #0xff - cmp r7, #23 /* relative fixup? */ - beq fixrel - cmp r7, #2 /* absolute fixup? */ - beq fixabs - /* ignore unknown type of fixup */ - b fixnext -fixabs: - /* absolute fix: set location to (offset) symbol value */ - mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ - add r1, r10, r1 /* r1 <- address of symbol in table */ - ldr r1, [r1, #4] /* r1 <- symbol value */ - add r1, r1, r9 /* r1 <- relocated sym addr */ - b fixnext -fixrel: + ldmia r2!, {r0-r1} /* (r0,r1) <- (SRC location,fixup) */ + and r1, r1, #0xff + cmp r1, #23 /* relative fixup? */ + bne fixnext + /* relative fix: increase location by offset */ + add r0, r0, r9 ldr r1, [r0] add r1, r1, r9 -fixnext: str r1, [r0] - add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ +fixnext: cmp r2, r3 blo fixloop @@ -100,13 +78,4 @@ relocate_done: bx lr #endif -_image_copy_end_ofs: - .word __image_copy_end - relocate_code -_rel_dyn_start_ofs: - .word __rel_dyn_start - relocate_code -_rel_dyn_end_ofs: - .word __rel_dyn_end - relocate_code -_dynsym_start_ofs: - .word __dynsym_start - relocate_code - ENDPROC(relocate_code) |