/*
ldr pc, _undefined_instruction//位置无关,_undefined_instruction基于PC计算
_undefined_instruction: .word undefined_instruction//位置相关,undefined_instruction编译期间确定
Disassembly of section .text:
80800020 <_undefined_instruction>:
80800020: 808001a0 .word 0x808001a0
808001a0 <undefined_instruction>:
808001a0: e51fd154 ldr sp, [pc, #-340] ; 80800054 <IRQ_STACK_START_IN>
Disassembly of section .rel.dyn
808648dc: 80800020 addhi r0, r0, r0, lsr #32
修复代码重定向之后某些位置相关的代码不能执行问题。
uboot 在ld时,指定 -pie,生成的uboot会包含_rel_dyn段,
_rel_dyn段(808648dc)的作用就是保存“保存函数(text)、常量(rodata)绝对地址(808001a0:undefined_instruction)”的地址(80800020)
下面的代码就是遍历重定位的uboot的_rel_dyn段(还有dynsym段),
将_rel_dyn段(808648dc)中的每一个地址(80800020)所指向的地址(808001a0)加上relocation offset
80800020: 808001a0 .word 0x808001a0
变为
80800020: 808001a0+offset .word 0x808001a0
*/
(uboot.dump1)
ldr r0, _TEXT_BASE /* r0 <- Text base */ //r0=0x80800000
sub r9, r6, r0 /* r9 <- relocation offset */ //r9=0x9FB39000 - 0x80800000=1F339000
ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ //r10=0x6d104(反汇编)
add r10, r10, r0 /* r10 <- sym table in FLASH */ //r10=0x8086D104,_dynsym_start在sdram中的真实地址(未重定位)
ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ //r2=0x64854(反汇编)
add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ //r2=0x80864854,_rel_dyn_start在sdram中的真实地址(未重定位)
ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ //r3=0x6d104(反汇编)
add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ //r3=0x8086D104,_rel_dyn_end在sdram中的真实地址=_dynsym_start(u-boot.lds)
fixloop:
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */
add r0, r0, r9 /* r0 <- location to fix up in RAM */
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:
/* relative fix: increase location by offset */
ldr r1, [r0]
add r1, r1, r9
fixnext:
str r1, [r0]
add r2, r2, #8 /* each rel.dyn entry is 8 bytes */
cmp r2, r3
blo fixloop
b clear_bss
_rel_dyn_start_ofs:
.word __rel_dyn_start - _start
_rel_dyn_end_ofs:
.word __rel_dyn_end - _start
_dynsym_start_ofs:
.word __dynsym_start - _start
/******************************************/
ldr r0, _TEXT_BASE /* r0 <- Text base */ //r0=0x80800000
sub r9, r6, r0 /* r9 <- relocation offset */ //r9=0x9FB39000 - 0x80800000=1F339000
ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ //r10=0x6d104(反汇编)
add r10, r10, r0 /* r10 <- sym table in FLASH */ //r10=0x8086D104,_dynsym_start在sdram中的真实地址(未重定位)
ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ //r2=0x64854(反汇编)
add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ //r2=0x80864854,_rel_dyn_start在sdram中的真实地址(未重定位)
ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ //r3=0x6d104(反汇编)
add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ //r3=0x8086D104,_rel_dyn_end在sdram中的真实地址=_dynsym_start(u-boot.lds)
fixloop:
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ //r0=[80864854]=80800020
add r0, r0, r9 /* r0 <- location to fix up in RAM */ //r0=80800020+1F339000=重定向后的80800020
ldr r1, [r2, #4] //r1=[80864854 + 4] =[80864858] = 0x00000017
and r7, r1, #0xff //r7=0x00000017&&0xff=0x17=23
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:
/* relative fix: increase location by offset */
ldr r1, [r0] //r1=[80800020+1F339000]= 808001a0
add r1, r1, r9 //r1=808001a0+1F339000=重定向后的808001a0 undefined_instruction
fixnext:
str r1, [r0] //[80800020+1F339000]=808001a0+1F339000//把.word中的值加上了relocation offset
add r2, r2, #8 /* each rel.dyn entry is 8 bytes;8字节一个单元 */ //r2= 0x80864854 + 8=0x8086485c
cmp r2, r3
blo fixloop
b clear_bss
/******************************************/
fixloop:
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ //r0=[0x8086485c]=80800024
add r0, r0, r9 /* r0 <- location to fix up in RAM */ //r0=80800024+1F339000=重定向后的80800024
ldr r1, [r2, #4] //r1=[0x8086485c + 4] =[80864860] = 0x00000017
and r7, r1, #0xff //r7=0x00000017&&0xff=0x17=23
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:
/* relative fix: increase location by offset */
ldr r1, [r0] //r1=[80800024+1F339000]= 80800200
add r1, r1, r9 //r1=80800200+1F339000=重定向后的80800200 software_interrupt,位于text
fixnext:
str r1, [r0] //[80800024+1F339000]=80800200+1F339000//把.word中的值加上了relocation offset
add r2, r2, #8 /* each rel.dyn entry is 8 bytes;8字节一个单元 */ r2= 0x8086485c + 8=80864864
cmp r2, r3
blo fixloop
b clear_bss
*
*
*
//循环至r2=808649a4时,(uboot.dump_rel)
fixloop:
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ //r0=[808649a4]=808010ac 保存(test_func打印的字符串常量的地址,位于rodata)的Label
add r0, r0, r9 /* r0 <- location to fix up in RAM */ //r0=808010ac+1F339000=重定向后的808010ac
ldr r1, [r2, #4] //r1=[808649a4 + 4] =[808649a8] = 0x00000017
and r7, r1, #0xff //r7=0x00000017&&0xff=0x17=23
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:
/* relative fix: increase location by offset */
ldr r1, [r0] //r1=[808010ac+1F339000]= 80853f68
add r1, r1, r9 //r1=80853f68+1F339000=重定向后的80853f68 ----74736574 printf的参数:字符串常量,位于rodata
fixnext:
str r1, [r0] //[808010ac+1F339000]=80853f68+1F339000//把.word中的值加上了relocation offset
add r2, r2, #8 /* each rel.dyn entry is 8 bytes;8字节一个单元 */ //r2= 808649a8 + 8=808649b0
cmp r2, r3
blo fixloop
b clear_bss
*
*
*
*
//循环至r2=0x8086D104(__dynsym_start=_rel_dyn_end)时,(uboot.dump1)
*
*
//循环至r2=8086d118(__dynsym)时,(uboot.dump1)
fixloop:
ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ //r0=[8086d118]=80800000 text_base=_start
add r0, r0, r9 /* r0 <- location to fix up in RAM */ //r0=80800000+1F339000=重定向后的80800000
ldr r1, [r2, #4] //r1=[8086d118 + 4] =[8086d11c] = 0x000000
and r7, r1, #0xff //r7=0x000000&&0xff=0x0=0
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 */ //r1=0
add r1, r10, r1 /* r1 <- address of symbol in table */ //r1=0+0x8086D104=0x8086D104
ldr r1, [r1, #4] /* r1 <- symbol value */ //r1=[8086d108]//not found in dump
add r1, r1, r9 /* r1 <- relocated sym addr */
b fixnext
fixrel:
/* relative fix: increase location by offset */
ldr r1, [r0] //r1=[808010ac+1F339000]= 80853f68
add r1, r1, r9 //r1=80853f68+1F339000=重定向后的80853f68 ----74736574 printf的参数:字符串常量,位于rodata
fixnext:
str r1, [r0] //[808010ac+1F339000]=80853f68+1F339000//把.word中的值加上了relocation offset
add r2, r2, #8 /* each rel.dyn entry is 8 bytes;8字节一个单元 */ r2= 808649a8 + 8=808649b0
cmp r2, r3
blo fixloop
b clear_bss
[UBOOT] fix .rel.dyn relocations(u-boot-2011.09)
最新推荐文章于 2023-10-08 23:15:10 发布