ARM Architecture C 语言寻址解析—— 从U-Boot relocation所展开的探索(三)

ARM  Architecture C 语言寻址解析——
从U-Boot relocation所展开的探索(三)
by LazyCatDesign
www.lazycatdesign.com

ARM Architecture C语言PIC寻址方式解析(续)
继续讨论上一篇文章的问题,GOT所记录的是C的对象地址,但一个工程中往往还存在汇编代码定义的变量(事实上汇编语言中并不存在“变量”这一说法,这些所谓的“变量”更准确的讲是一个"Lable",C语言的指针变量名,比如main.c中定义的global_str,对汇编来说也是一个Lable,在接下来的文章里我们统一用Lable称呼这两者),如何对汇编的Lable进行relocate呢?如何得到需要relocate的Lable信息呢?命令行进入arm_pic目录,运行命令arm-none-eabi-readelf -r arm_pic,得到以下输出:

ARM <wbr> <wbr>Architecture <wbr>C <wbr>语言寻址解析鈥斺 <wbr>从U-Boot <wbr>relocation所展开的探索(三)

“arm-none-eabi-readelf”是一个分析elf文件的工具,使用“-r”选项可以列出所有需要relocate的Lable信息。观察上图“offset”列的数据,配合arm_pic.dump,我想读者应该发现,0x40200020是Lable “_undefined_instruction” 的地址,0x40200024是Lable "_software_interrupt"的地址(这两个Lable是在汇编文件start.S中定义的),没错,所有在汇编语言中定义的Lable,都可以在这个输出中查看到它们的地址,更甚者,C语言GOT entry的地址也都被列出。那么上面输出的这些数据保存在elf文件中的哪个section呢?——它们被保存在.rel.dyn section(.rel.dyn section由连接时为ld指定-pie选项产生),如下图所示:

ARM <wbr> <wbr>Architecture <wbr>C <wbr>语言寻址解析鈥斺 <wbr>从U-Boot <wbr>relocation所展开的探索(三)

.rel.dyn section由若干.rel.dyn entry组成,一个entry记录了一个Lable的信息(ELF standard定义.rel.dyn entry 为ELF32_Rel结构体,具体内容请参考 ELF standardELF for the ARM Architecture),如上图所示,第一个entry记录了Lable "_undefined_instruction"的信息,其地址为0x40200020,relocate type为R_ARM_RELATIVE。 无论汇编语言定义的Lable或是C语言定义的Lable,只要得到该Lable的.rel.dyn entry,就可以对其进行relocation。
如上一篇文章所讲,arm_pic被整体copy到0x80000000地址后,将GOT中每一个entry的内容累加上偏移量0x3fe00000,这样还不能让其正常地从新地址中运行(修改GOT entry只解决了C变量的relocation),完美的做法是—— 遍历.rel.dyn section,将每一个entry所指地址中的值加上偏移量,这样无论汇编定义的Lable,还是C定义的Lable,所有的Lable都被relocation,U-Boot relocation使用的就是这种方法。

U-Boot 2011.12 relocation分析
事实上u-boot 2011.12并没有使用到“ -fpic”或“-fpie”编译选项,只用到“-pie”连接选项,指定了“-pie”连接选项所产生的elf文件包含了.rel.dyn section,U-Boot 2011.12 relocation只需借助.rel.dyn提供的信息就足够了。

ARM <wbr> <wbr>Architecture <wbr>C <wbr>语言寻址解析鈥斺 <wbr>从U-Boot <wbr>relocation所展开的探索(三)

上图的代码可在 /u-boot-2011-12/arch/arm/cpu/armv7/start.S 中找到,这段代码用于完成U-Boot 2011.12 relocation。“fixloop”循环遍历.rel.dyn section,“fixabs”和"fixrel"分别relocate "R_ARM_ABS32"和“R_ARM_RELATIVE”两种类型的Lable,其中,“R_ARM_ABS32”类型的Lable在relocate的时候还需要引用到.dynsym section的数据,而“R_ARM_RELATIVE”的处理则简单许多,只需在原地址值的基础上加上offset即可。

现在还有以下这3个问题:

  1. .dynsym section包含什么数据?
  2. "R_ARM_ABS32"和“R_ARM_RELATIVE”的区别是什么?
  3. "R_ARM_ABS32"和“R_ARM_RELATIVE” relocate的具体细节是什么?


我想这3个问题就留给读者自己去研究吧:)


全文完



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段代码是关于系统启动时的一些信息,具体解析如下: 1. emmc boot table board switch:0x00000007:表示系统选择的引导设备为emmc。 2. boot table version:V0.3:表示引导表的版本号为V0.3。 3. boot table build time:2023/05/12 15:58:27:表示引导表的构建时间为2023年5月12日15点58分27秒。 4. boot table file name:Hi3519DV500-DMEB_6L_T_DDR4_2666M-2GB_16bitx2-A55_1G.xlsm:表示引导表的文件名为Hi3519DV500-DMEB_6L_T_DDR4_2666M-2GB_16bitx2-A55_1G.xlsm。 5. System startup Uncompress Ok!:表示系统启动,并且解压缩成功。 6. U-Boot 2022.07 (May 12 2023 - 15:58:35 +0800)hi3519dv500:表示使用的启动加载器版本号为U-Boot 2022.07,启动时间为2023年5月12日15点58分35秒,使用的处理器型号为hi3519dv500。 7. DRAM: Relocation Offset is: 17745000 Relocating to 5ff45000, new gd at 5fb04de0, sp at 5fb04dd0:表示系统正在进行DRAM的重定位操作,新的地址为5ff45000,新的全局数据指针为5fb04de0,新的栈指针为5fb04dd0。 8. Core: 1 devices, 1 uclasses:表示系统核心有1个设备和1个类别。 9. MMC: mmc->ocr_from_bootrom 0x00000000:表示MMC设备OCR寄存器值为0x00000000。 10. MMC/SD Card: MID: 0x90 Read Block: 512 Bytes Write Block: 512 Bytes Chip Size: 7456M Bytes (High Capacity) Name: "H8G4a" Chip Type: MMC Version: 5.1 Speed: 150000000Hz Bus Width: 8bit Mode: HS400ES Boot Mode: normal(), 86 ms bsp-sdhci: 0 (eMMC):表示MMC/SD卡的详细信息,包括厂商ID、读写块大小、芯片容量、芯片类型、版本号、速度、总线宽度、模式和引导模式等。 11. Loading Environment from MMC... OK:表示从MMC设备中加载环境变量成功。 12. In: serial Out: serial Err: serial:表示标准输入输出错误都使用串口进行传输。 13. Net: gmac0 Error: gmac0 address not set.:表示网络设备gmac0的地址未设置,可能需要在系统中进行配置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值