空间和地址分配

仍然采用上一节的代码。看生成的代码段。3个中间目标文件的代码段:

fromelf -v a.o========================================================================** Section #1Name        : i.mainType        : SHT_PROGBITS (0x00000001)Flags       : SHF_ALLOC + SHF_EXECINSTR (0x00000006)Addr        : 0x00000000File Offset : 52 (0x34)Size        : 24 bytes (0x18)Link        : SHN_UNDEFInfo        : 0Alignment   : 4Entry Size  : 0====================================
fromelf -v b.o========================================================================** Section #1Name        : i.swapType        : SHT_PROGBITS (0x00000001)Flags       : SHF_ALLOC + SHF_EXECINSTR (0x00000006)Addr        : 0x00000000File Offset : 52 (0x34)Size        : 22 bytes (0x16)Link        : SHN_UNDEFInfo        : 0Alignment   : 2Entry Size  : 0====================================
fromelf -v startup_stm32f10x_xl.o====================================** Section #3Name        : RESETType        : SHT_PROGBITS (0x00000001)Flags       : SHF_ALLOC (0x00000002)Addr        : 0x00000000File Offset : 52 (0x34)Size        : 304 bytes (0x130)Link        : SHN_UNDEFInfo        : 0Alignment   : 4Entry Size  : 0========================================================================** Section #5Name        : .textType        : SHT_PROGBITS (0x00000001)Flags       : SHF_ALLOC + SHF_EXECINSTR (0x00000006)Addr        : 0x00000000File Offset : 924 (0x39c)Size        : 56 bytes (0x38)Link        : SHN_UNDEFInfo        : 0Alignment   : 4Entry Size  : 0====================================

可以看到,目标文件中的代码段地址都是0。

链接后生成的axf文件:

fromelf -v STM32F103_study.axf========================================================================** Section #1Name        : ER_IROM1Type        : SHT_PROGBITS (0x00000001)Flags       : SHF_ALLOC + SHF_EXECINSTR (0x00000006)Addr        : 0x08000000File Offset : 52 (0x34)Size        : 720 bytes (0x2d0)Link        : SHN_UNDEFInfo        : 0Alignment   : 4Entry Size  : 0====================================

已经分配了实际的地址:0x08000000

重定位表

由于a.c文件中引用了shared全局变量和外部函数swap(),在链接过程中需要对其重定位。

看a.o的重定位表:

在文件偏移0x02F0处,共16个字节。

共2个表项,每个重定位表项占用8个字节:

/* Relocation table entry without addend (in section of type SHT_REL).  */typedef struct
{Elf32_Addr    r_offset;               /* Address */Elf32_Word    r_info;                 /* Relocation type and symbol index */
} Elf32_Rel;

前面4个字节为重定位符号在段中的偏移地址。后面4个字节为信息项。

r_info中包含重定位类型和需要重定位的符号在符号表中的索引值。
举例来说,一个跟函数重定位相关的重定位项中的r_info会给出该函数符号在符号表中的索引值。如果索引值是STN_UNDEF(0),证明符号是未定义的,那么重定位过程中将使用0作为该符号的符号数值(st_value)。
重定位类型是处理器相关的一种属性。
可以使用宏ELF32_R_SYM(或者ELF64_R_SYM)和宏ELF32_R_TYPE(或者ELF64_R_TYPE)分别得到需要重定位的符号的符号表索引值以及重定位类型。

#define ELF32_R_SYM(val)        ((val) >> 8)  //得到符号表的索引
#define ELF32_R_TYPE(val)       ((val) & 0xff)  //得到type
#define ELF32_R_INFO(sym, type)     (((sym) << 8) + ((type) & 0xff))

低8位(1个字节)为类型,高24位为符号索引。

对照a.o文件,第1个重定位表项的地址为0x0000000A,类型为10(0x0A),索引为10(0x0A);

第2个重定位表项的地址为0x00000014,类型为2,索引为9.

fromelf -r a.o** Section #6 '.reli.main' (SHT_REL)Size   : 16 bytes (alignment 4)Symbol table #5 '.symtab'2 relocations applied to section #1 'i.main'#      Offset    Relocation Type               Wrt Symbol                   Defined in========================================================================0  0x0000000a   10 R_ARM_THM_CALL           10 swap                     Ref1  0x00000014    2 R_ARM_ABS32               9 shared                   Ref

对照a.o中的汇编看看这两个位置的内容:

fromelf -c a.o========================================================================** Section #1 'i.main' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]Size   : 24 bytes (alignment 4)Address: 0x00000000$ti.mainmain0x00000000:    b508        ..      PUSH     {r3,lr}0x00000002:    2064        d       MOVS     r0,#0x640x00000004:    9000        ..      STR      r0,[sp,#0]0x00000006:    4903        .I      LDR      r1,[pc,#12] ; [shared = 0x14] = 00x00000008:    4668        hF      MOV      r0,sp0x0000000a:    f7fffffe    ....    BL       swap0x0000000e:    2000        .       MOVS     r0,#00x00000010:    bd08        ..      POP      {r3,pc}$d0x00000012:    0000        ..      DCW    00x00000014:    00000000    ....    DCD    0 ; shared

从中可以看出,0x0000000A为调用swap函数,函数地址偏移量暂时为-1。0x00000014处为shared的地址,暂时为0.

地址更新与代码修正

和链接后的axf文件对比一下,BL swap的二进制代码由F7FFFFFE变成了F805F000;shared变量的地址也由00000000变成了0x20000000。

如果在b.c文件中,shared变量前面再加一个变量,比如:int x = 2,则变量x会占用0x20000000的位置,shared变量的地址会变成0x20000004.再来看看axf文件,确实变了:

《程序员的自我修养》读书笔记3——使用KEIL研究ELF文件的重定位相关推荐

  1. 程序员的自我修养读书笔记-1

    前序:作为一个马上就要工作的非科班本科生,前段时间为了找工作,有针对性的学习了一些编程语言,数据结构,网络方面的知识,学的非常浅,非常杂乱,存粹是为了应对找工作.现在空下来了,想着以后应该就是走程序员 ...

  2. 程序员的自我修养 - 读书笔记文字版

    第1部分 简介 第1章 温故而知新 程序在运行的时候先通过分段(segmentation)的方式将虚拟地址空间与真实的物理内存地址空间进行一一的映射,但是这种方式每次换入换出的是整个程序,导致IO变大 ...

  3. 程序员的自我修养——读书笔记

    第一部分:温故而知新 第一章:介绍基本的背景知识--操作系统.线程.硬件 1.关于C语言中的hello world这些问题你都清楚吗? 2.计算机硬件设备的三个核心部件: 1>中央处理器CPU ...

  4. 程序员的自我修养阅读笔记

    编译和链接 将编译和链接合并到一起的过程称为构建(Build). 从源文件生成最终可执行目标文件共有4个步骤: 预处理(Prepressing) 编译(Compilation) 汇编(Assembly ...

  5. 程序员的自我修养——学习笔记1

    文章目录 计算机硬件 早期计算机 发展 SMP和多核 计算机软件 操作系统和设备驱动的作用 文件系统 存储设备 未使用内存管理时 解决思路:地址空间 分段 分页 线程进程 参考资料 计算机硬件 计算机 ...

  6. 程序员的自我修养学习笔记——第五章

    PE: Portable Executable COFF: Common Object File Format 跟ELF一样,PE中也允许程序员将变量后函数放到自定义段.在GCC中使用"__ ...

  7. 《程序员的自我修养》笔记

    第1章 引言 说明:①本书中将计算机的范围限定于PC机,更具体的讲是采用x86指令集的32位CPU的个人计算机. 1.1 CPU与外围部件的连接方式 计算机最核心的三个硬件设备是:CPU.内存.I/O ...

  8. 【读书笔记】程序员的自我修养总结(七)

    [读书笔记]程序员的自我修养总结(七) 标签: [编程开发] 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:这是程序员的自我修养一书的读书总结,随着阅 ...

  9. 【读书笔记】程序员的自我修养总结(一)

    程序员的自我修养总结(一) 声明:引用请注明出处http://blog.csdn.net/lg1259156776/ 说明:这是程序员的自我修养一书的读书总结,随着阅读的推进,逐步增加内容. 1. 关 ...

最新文章

  1. Nature官方劝退读博:全球七成博士对前途迷茫,36%自认有过心理疾病
  2. 服务器硬件及RAID配置
  3. 你在使用Gmail,Wallop,MSN Spaces,Three Degrees吗?
  4. sharepoint 弹出框
  5. 燕山大学数字通信计算机仿真代码,燕山大学数字通信计算机仿真课程设计模板.doc...
  6. 【Flink】kafka INVALID_PRODUCER_EPO send data to Kafka old epoch newer producer same transactionalId
  7. poj2431java_POJ 2431 Expedition
  8. 语音 识别_语音识别_qq语音识别 - 云+社区 - 腾讯云
  9. 洛谷OJ:P3811 【模板】乘法逆元(线性递推求逆元)
  10. Linux在线词典项目,实现注册,登陆,查询单词以及查询历史记录,退出查询等功能,(涉及网络编程,进程线程,文件io,sqlite)
  11. 40位40岁以下投资人
  12. c语言地铁系统设计,城市地铁报站系统设计.doc
  13. Qt的简单应用:五子棋游戏
  14. Ubuntu安装Nixnote,解决印象笔记(国服/中国区)登录不能显示输入密码的问题
  15. BASE64Encoded() 方法报错说方法未定义
  16. HFDS 内部工作机制
  17. R6034问题的解决
  18. 时间复杂度简述及例题
  19. Python就业行情和前景分析之一
  20. Typescript 笔记

热门文章

  1. 算法概论-作业1-席景科老师 问题 A: algorithm-锯木棒
  2. python(moviepy ) mp4视频拼接截取
  3. TypeScript基础-数组结构和对象解构
  4. 在Word中利用EndNote导入参考文献
  5. Worthington胶原蛋白酶原料
  6. 21- JavaScript 事件简介
  7. 2023年全国DAMA-CDGP数据治理专家认证线上班招生简章
  8. SWD WAIT reponse 处理
  9. element-ui的textarea设置大小
  10. 3面直接拿到offer,java面试刷题网站分享