关于连接参数-Ttext
讨论-Ttext之前,先简单介绍一下工具:
readelf -h 读取ELF可执行文件头
readelf -S 查看ELF文件Section 信息
objdump -d 看目标文件汇编代码
以典型的bootloader为例,我们分析-Ttext的实际作用。
首先来看具体的两条命令
编译 $(CC) $(CFLAGS) -DKERNEL_START=$(TEXT_START) -c mbr_start.S -o $(OBJDIR)/mbr_start.o
链接 $(LD) -Ttext=0x7c00 -o $(OBJDIR)/mbr $(OBJDIR)/mbr_start.o $(OBJDIR)/mbr.o
第一行编译mbr_start.S并传入参数KERNEL_START,生成目标文件mbr_start.o;第二行,连接mbr_start.o和mbr.o生成mbr,并将程序重定向到0x7c00处。
即,-Ttext是连接时将初始地址重定向为0x7c00(若不注明此,则程序的起始地址为0)。比如,在mbr_start.S文件中函数inb()的编译完成后在mbr_start.o中的偏移地址是0x006b,则在连接时指定-Ttext=0x7c00,连接之后其地址为0x7c6b, 其他函数调用此函数时,也就会调用地址0x7c6b,而不会是0x006b。
那这个编译连接参数的意义是什么?比如bootloader, x86平台上,BIOS加载bootloader到0x7c00, 然后从0x7c00开始执行,那么你的bootloader则就需要在编译的时候指明-Ttext=0x7c00使得bootloader程序在以0x7c00为起始的地址空间内,否则程序运行时将因为地址空间紊乱无法正常运行。举例说明如下。
比如编译完,mbr_start.o, mbr.o
mbr_start.o: file format elf32-i386
Disassembly of section .text:
00000000 <_start>:
0: 31 c0 xor %eax,%eax
2: 8e d8 mov %eax,%ds
4: 31 db xor %ebx,%ebx
6: 31 c9 xor %ecx,%ecx
8: 31 d2 xor %edx,%edx
a: b8 01 e8 cd 15 mov $0x15cde801,%eax
f: 66 81 e3 ff ff and $0xffff,%bx
14: 00 00 add %al,(%eax)
...(省略)
0000005a <pm32>:
5a: bc 00 7c 00 00 mov $0x7c00,%esp
5f: 68 00 00 10 00 push $0x100000
64: e8 fc ff ff ff call 65 <pm32+0xb>
69: ff e0 jmp *%eax
0000006b <inb>:
6b: 29 c0 sub %eax,%eax
6d: 66 8b 54 24 04 mov 0x4(%esp),%dx
72: ec in (%dx),%al
73: c3 ret
...(省略)
000000b0 <gdtdscr>:
b0: 27 daa
b1: 00 88 00 00 00 00 add %cl,0x0(%eax)
...
mbr.o: file format elf32-i386
Disassembly of section .text:
00000000 <read_mbr>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 57 push %edi
4: 56 push %esi
5: 53 push %ebx
6: 83 ec 2c sub $0x2c,%esp
9: 8b 5d 08 mov 0x8(%ebp),%ebx
c: 89 5d e0 mov %ebx,-0x20(%ebp)
f: c7 45 dc 00 80 00 00 movl $0x8000,-0x24(%ebp)
16: bf 00 00 00 00 mov $0x0,%edi
1b: 85 ff test %edi,%edi
1d: 74 08 je 27 <read_mbr+0x27>
1f: 81 ff ff ff 01 00 cmp $0x1ffff,%edi
...(省略)
d8: 89 5c 24 04 mov %ebx,0x4(%esp)
dc: c7 04 24 f0 01 00 00 movl $0x1f0,(%esp)
e3: e8 fc ff ff ff call e4 <read_mbr+0xe4>
e8: 81 7d dc 00 80 00 00 cmpl $0x8000,-0x24(%ebp)
ef: 75 03 jne f4 <read_mbr+0xf4>
f1: 8b 7b 28 mov 0x28(%ebx),%edi
f4: 81 45 dc 00 02 00 00 addl $0x200,-0x24(%ebp)
fb: 81 c3 00 02 00 00 add $0x200,%ebx
101: 81 ef 00 02 00 00 sub $0x200,%edi
107: 89 f0 mov %esi,%eax
109: 4e dec %esi
10a: 85 c0 test %eax,%eax
10c: 7f b2 jg c0 <read_mbr+0xc0>
...(省略)
13c: 5f pop %edi
13d: 5d pop %ebp
13e: c3 ret
显然单独编译的时候,这个mbr_start.o是以0为基址的。但在连接之后呢?
mbr: file format elf32-i386
Disassembly of section .text:
00007c00 <_start>:
7c00: 31 c0 xor %eax,%eax
7c02: 8e d8 mov %eax,%ds
7c04: 31 db xor %ebx,%ebx
7c06: 31 c9 xor %ecx,%ecx
7c08: 31 d2 xor %edx,%edx
7c0a: b8 01 e8 cd 15 mov $0x15cde801,%eax
...(省略)
00007c5a <pm32>:
7c5a: bc 00 7c 00 00 mov $0x7c00,%esp
7c5f: 68 00 00 10 00 push $0x100000
7c64: e8 4f 00 00 00 call 7cb8 <read_mbr >
7c69: ff e0 jmp *%eax
00007c6b <inb>:
7c6b: 29 c0 sub %eax,%eax
7c6d: 66 8b 54 24 04 mov 0x4(%esp),%dx
7c72: ec in (%dx),%al
7c73: c3 ret
...(省略)
00007cb0 <gdtdscr>:
7cb0: 27 daa
7cb1: 00 88 7c 00 00 00 add %cl,0x7c(%eax)
...
00007cb8 <read_mbr >:
7cb8: 55 push %ebp
7cb9: 89 e5 mov %esp,%ebp
7cbb: 57 push %edi
7cbc: 56 push %esi
7cbd: 53 push %ebx
7cbe: 83 ec 2c sub $0x2c,%esp
7cc1: 8b 5d 08 mov 0x8(%ebp),%ebx
7cc4: 89 5d e0 mov %ebx,-0x20(%ebp)
7cc7: c7 45 dc 00 80 00 00 movl $0x8000,-0x24(%ebp)
7cce: bf 00 00 00 00 mov $0x0,%edi
7cd3: 85 ff test %edi,%edi
7cd5: 74 08 je 7cdf <read_mbr+0x27>
7cd7: 81 ff ff ff 01 00 cmp $0x1ffff,%edi
7cdd: 7e 07 jle 7ce6 <read_mbr+0x2e>
7cdf: be 00 01 00 00 mov $0x100,%esi
7ce4: eb 14 jmp 7cfa <read_mbr+0x42>
7ce6 : 89 f8 mov %edi,%eax
7ce8: 05 ff 01 00 00 add $0x1ff,%eax
7ced: 79 06 jns 7cf5 <read_mbr+0x3d>
7cef: 8d 87 fe 03 00 00 lea 0x3fe(%edi),%eax
7cf5 : 89 c6 mov %eax,%esi
7cf7: c1 fe 09 sar $0x9,%esi
7cfa: 8b 45 dc mov -0x24(%ebp),%eax
7cfd: 85 c0 test %eax,%eax
7cff: 79 05 jns 7d06 <read_mbr+0x4e>
7d01: 05 ff 01 00 00 add $0x1ff,%eax
7d06 : 89 c2 mov %eax,%edx
7d08: c1 fa 09 sar $0x9,%edx
7d0b: 0f b6 c2 movzbl %dl,%eax
...(省略)
7d71: 89 f0 mov %esi,%eax
7d73: 4e dec %esi
7d74: 85 c0 test %eax,%eax
7d76: 7e 4e jle 7dc6 <read_mbr+0x10e>
7d78 : c7 04 24 f7 01 00 00 movl $0x1f7,(%esp)
7d7f: e8 e7 fe ff ff call 7c6b <inb>
7d84: a8 08 test $0x8,%al
7d86: 74 f0 je 7d78 <read_mbr+0xc0>
7d88: c7 44 24 08 80 00 00 movl $0x80,0x8(%esp)
7d8f: 00
7d90: 89 5c 24 04 mov %ebx,0x4(%esp)
7d94: c7 04 24 f0 01 00 00 movl $0x1f0,(%esp)
7d9b: e8 d4 fe ff ff call 7c74 <linl>
7da0: 81 7d dc 00 80 00 00 cmpl $0x8000,-0x24(%ebp)
7da7: 75 03 jne 7dac <read_mbr+0xf4>
7da9: 8b 7b 28 mov 0x28(%ebx),%edi
7dac : 81 45 dc 00 02 00 00 addl $0x200,-0x24(%ebp)
7db3: 81 c3 00 02 00 00 add $0x200,%ebx
7db9: 81 ef 00 02 00 00 sub $0x200,%edi
7dbf: 89 f0 mov %esi,%eax
7dc1: 4e dec %esi
7dc2: 85 c0 test %eax,%eax
7dc4: 7f b2 jg 7d78 <read_mbr+0xc0>
7dc6 : 85 ff test %edi,%edi
7dc8: 0f 8f 05 ff ff ff jg 7cd3 <read_mbr+0x1b>
7dce: 8b 55 e0 mov -0x20(%ebp),%edx
7dd1: 8b 42 2c mov 0x2c(%edx),%eax
7dd4: a3 00 10 00 00 mov %eax,0x1000
...(省略)
7df4: 5f pop %edi
7df5: 5d pop %ebp
7df6: c3 ret
注意上面加粗部分,在bootloader被加载到内存0x7c00之后,这些地址是能准确的被访问。
但假设我们不加-Ttext=0x7c00,那么连接完后,将是如下程序段(objdump -d mbr):
mbr: file format elf32-i386
Disassembly of section .text:
00000000 <_start>:
0: 31 c0 xor %eax,%eax
2: 8e d8 mov %eax,%ds
4: 31 db xor %ebx,%ebx
6: 31 c9 xor %ecx,%ecx
8: 31 d2 xor %edx,%edx
a: b8 01 e8 cd 15 mov $0x15cde801,%eax
f: 66 81 e3 ff ff and $0xffff,%bx
14: 00 00 add %al,(%eax)
16: 66 c1 e3 10 shl $0x10,%bx
1a: 66 25 ff ff and $0xffff,%ax
1e: 00 00 add %al,(%eax)
20: 66 c1 e0 0a shl $0xa,%ax
...(省略)
0000005a <pm32>:
5a: bc 00 7c 00 00 mov $0x7c00,%esp
5f: 68 00 00 10 00 push $0x100000
64: e8 4f 00 00 00 call b8 <read_mbr>
69: ff e0 jmp *%eax
0000006b <inb>:
6b: 29 c0 sub %eax,%eax
6d: 66 8b 54 24 04 mov 0x4(%esp),%dx
72: ec in (%dx),%al
73: c3 ret
...(省略)
000000b0 <gdtdscr>:
b0: 27 daa
b1: 00 88 00 00 00 00 add %cl,0x0(%eax)
...
000000b8 <read_mbr>:
b8: 55 push %ebp
b9: 89 e5 mov %esp,%ebp
bb: 57 push %edi
bc: 56 push %esi
bd: 53 push %ebx
be: 83 ec 2c sub $0x2c,%esp
c1: 8b 5d 08 mov 0x8(%ebp),%ebx
c4: 89 5d e0 mov %ebx,-0x20(%ebp)
c7: c7 45 dc 00 80 00 00 movl $0x8000,-0x24(%ebp)
ce: bf 00 00 00 00 mov $0x0,%edi
d3: 85 ff test %edi,%edi
d5: 74 08 je df <read_mbr+0x27>
d7: 81 ff ff ff 01 00 cmp $0x1ffff,%edi
dd: 7e 07 jle e6 <read_mbr+0x2e>
df: be 00 01 00 00 mov $0x100,%esi
e4: eb 14 jmp fa <read_mbr+0x42>
e6: 89 f8 mov %edi,%eax
e8: 05 ff 01 00 00 add $0x1ff,%eax
ed: 79 06 jns f5 <read_mbr+0x3d>
ef: 8d 87 fe 03 00 00 lea 0x3fe(%edi),%eax
f5: 89 c6 mov %eax,%esi
f7: c1 fe 09 sar $0x9,%esi
...(省略)
1ea: be ef be
1ed: 89 d0 mov %edx,%eax
1ef: 83 c4 2c add $0x2c,%esp
1f2: 5b pop %ebx
1f3: 5e pop %esi
1f4: 5f pop %edi
1f5: 5d pop %ebp
1f6: c3 ret
如果这段bootloader代码还是被BIOS加载到0x7c00处,那么将无法运行。以加粗一小段为例,假设程序可以运行到0xd5这里,但CPU试图访问readmbr+0x27时(本来是应在本程序段的函数体read_mbr内偏移0x27,也就是下属第三行0xdf处),但是代码:je df是如果为零跳至df处,而地址0xdf是并非是bootloader的代码所在地址,跳转未知区域执行很可能引起系统死机。当然,倘若这段代码是被加载到了内存0开始的起始地址处,那么地址空间正好和程序的相符,程序仍可以正常访问所有自身的函数和变量地址。
简而言之,程序连接后的地址空间要与其运行环境的地址空间相匹配,而-Ttext的功能就是指定程度段的起始地址。
关于连接参数-Ttext相关推荐
- 蓝牙连接参数关于IOS的限制
和iOS设备的连接参数的设置是有要求的 不符合iOS设备连接参数定义的数值是不被接受也就不会变更了,所以首先请您确认一下您的参数定义是否满足以下IOS设备的要求 •Interval Max * (Sl ...
- Jdbc访问mysql查询聚合函数_JDBC连接参数设置对Oracle数据库的影响分析
一次数据库性能问题处理引发的JDBC参数设置思考 近期某环境下系统,出现大面积页面访问缓慢情况,每个页面交易响应时间2-5秒,严重超过平日访问阈值. 经排查分析,问题主要出现在数据库,生成AWR得到3 ...
- mysql连接参数配置
前言 mysql性能优化涉及到很多方面,在上一篇中通过explain打印出sql的执行计划可以作为指导开发人员进行sql优化是一个方面,另外,mysql自身的参数配置也很多,比如连接参数(connec ...
- nrf52832 学习笔记(五)蓝牙主从机连接和连接参数更新
nrf52832 学习笔记(五)蓝牙主从机连接和连接参数更新 主机连接 nrf52832 SDK中主机连接从机需要使用 sd_ble_gap_connect(ble_gap_addr_t const ...
- 低功耗蓝牙BLE之连接事件、连接参数和更新方法
连接事件 在一个连接当中,主设备会在每个连接事件里向从设备发送数据包.一个连接事件是指主设备和从设备之间相互发送数据包的过程.连接事件的进行始终位于一个频率,每个数据包会在上个数据包发完之后等待 15 ...
- BLE 协议栈(Master,Slave;Standby,Advertiser,Scanner,Initiator;连接流程,连接参数)
文章目录 1.BLE 协议栈的结构和配置(应用层,Host 主协议层,Controller 控制层) 2.BLE 物理层(PHY) 3.拓扑结构(星型拓扑) 4.设备状态(Master,Slave:S ...
- 低功耗蓝牙BLE之连接事件、连接参数和更新方法(程序解读)
关注公众号"迈微电子研发社",选择"星标★" 低功耗蓝牙BLE之连接参数de更新方法 0. 蓝牙的状态以及基本连接过程 0.1 蓝牙的状态: 0.3 蓝牙的连接 ...
- 低功耗蓝牙设备DA1458x芯片开发之更新连接参数
今天将详细的讲解下低功耗蓝牙设备和手机连接时的抓包,以此帮助我这样的小白,并积累经验~ 我用的外设芯片是DA14580芯片,协议栈是Dialog的IP蓝牙协议栈,和手机相连,利用sniffer pac ...
- 三菱Q系列PLC报错LINK PARA ERROR 链路连接参数异常
问题描述:PLC报错LINK PARA ERROR 连接参数异常 1.错误监视 2.PLC模块如下所示 1. 2. 原因分析:CCLINK模块未安装,CCLINK–IE模块未安装,软件方面就是CCLI ...
- Bluetooth技术学习笔记 ——LE广播、扫描、连接参数设置
core_v5.0 vol 2. Part E 1. 广播参数设置 (1)广播间隔说明 Advertising_Interval_Min ≤ Advertising_Interval_Max 当Adv ...
最新文章
- 机器学习常见的几个误区--逻辑回归的变量之间如果线性相关
- Linux-pidstat Monitor and Find Statistics for Linux Procesess
- 【大会】声音叫醒耳朵,语音连接网络
- python扫描ip的端口打开情况
- 计算机学院运动会开幕式稿,运动会开幕式新闻稿 运动会开幕式广播稿原创2019...
- HDU1249 三角形【切割平面】
- 百度文库文字下载(python原码)
- 普通人也可以制作App
- Javascript:简易天数计算器
- 利用mobi 和 epub 电子书文件建立自己的书库
- 蓝桥杯python基础练习
- android模拟微信聊天功能,android仿微信聊天界面 语音录制功能
- Sketch网页截屏插件设计开发
- [11]Debugging in Studio-UiPath ARD Certification Training
- 一维数组二维数组对称矩阵三角矩阵三对角矩阵地址的计算
- Linux火狐浏览器下载文件时文件名乱码
- keyshot怎么批量渲染_如何提高KeyShot的输出渲染速度
- 实习生被拒绝的N个理由
- C++ 杂谈之去除空格
- 国产良心极简版地图软件,地图下载很丝滑,界面简洁无广告