讨论-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相关推荐

  1. 蓝牙连接参数关于IOS的限制

    和iOS设备的连接参数的设置是有要求的 不符合iOS设备连接参数定义的数值是不被接受也就不会变更了,所以首先请您确认一下您的参数定义是否满足以下IOS设备的要求 •Interval Max * (Sl ...

  2. Jdbc访问mysql查询聚合函数_JDBC连接参数设置对Oracle数据库的影响分析

    一次数据库性能问题处理引发的JDBC参数设置思考 近期某环境下系统,出现大面积页面访问缓慢情况,每个页面交易响应时间2-5秒,严重超过平日访问阈值. 经排查分析,问题主要出现在数据库,生成AWR得到3 ...

  3. mysql连接参数配置

    前言 mysql性能优化涉及到很多方面,在上一篇中通过explain打印出sql的执行计划可以作为指导开发人员进行sql优化是一个方面,另外,mysql自身的参数配置也很多,比如连接参数(connec ...

  4. nrf52832 学习笔记(五)蓝牙主从机连接和连接参数更新

    nrf52832 学习笔记(五)蓝牙主从机连接和连接参数更新 主机连接 nrf52832 SDK中主机连接从机需要使用 sd_ble_gap_connect(ble_gap_addr_t const ...

  5. 低功耗蓝牙BLE之连接事件、连接参数和更新方法

    连接事件 在一个连接当中,主设备会在每个连接事件里向从设备发送数据包.一个连接事件是指主设备和从设备之间相互发送数据包的过程.连接事件的进行始终位于一个频率,每个数据包会在上个数据包发完之后等待 15 ...

  6. BLE 协议栈(Master,Slave;Standby,Advertiser,Scanner,Initiator;连接流程,连接参数)

    文章目录 1.BLE 协议栈的结构和配置(应用层,Host 主协议层,Controller 控制层) 2.BLE 物理层(PHY) 3.拓扑结构(星型拓扑) 4.设备状态(Master,Slave:S ...

  7. 低功耗蓝牙BLE之连接事件、连接参数和更新方法(程序解读)

    关注公众号"迈微电子研发社",选择"星标★" 低功耗蓝牙BLE之连接参数de更新方法 0. 蓝牙的状态以及基本连接过程 0.1 蓝牙的状态: 0.3 蓝牙的连接 ...

  8. 低功耗蓝牙设备DA1458x芯片开发之更新连接参数

    今天将详细的讲解下低功耗蓝牙设备和手机连接时的抓包,以此帮助我这样的小白,并积累经验~ 我用的外设芯片是DA14580芯片,协议栈是Dialog的IP蓝牙协议栈,和手机相连,利用sniffer pac ...

  9. 三菱Q系列PLC报错LINK PARA ERROR 链路连接参数异常

    问题描述:PLC报错LINK PARA ERROR 连接参数异常 1.错误监视 2.PLC模块如下所示 1. 2. 原因分析:CCLINK模块未安装,CCLINK–IE模块未安装,软件方面就是CCLI ...

  10. Bluetooth技术学习笔记 ——LE广播、扫描、连接参数设置

    core_v5.0 vol 2. Part E 1. 广播参数设置 (1)广播间隔说明 Advertising_Interval_Min ≤ Advertising_Interval_Max 当Adv ...

最新文章

  1. 机器学习常见的几个误区--逻辑回归的变量之间如果线性相关
  2. Linux-pidstat Monitor and Find Statistics for Linux Procesess
  3. 【大会】声音叫醒耳朵,语音连接网络
  4. python扫描ip的端口打开情况
  5. 计算机学院运动会开幕式稿,运动会开幕式新闻稿 运动会开幕式广播稿原创2019...
  6. HDU1249 三角形【切割平面】
  7. 百度文库文字下载(python原码)
  8. 普通人也可以制作App
  9. Javascript:简易天数计算器
  10. 利用mobi 和 epub 电子书文件建立自己的书库
  11. 蓝桥杯python基础练习
  12. android模拟微信聊天功能,android仿微信聊天界面 语音录制功能
  13. Sketch网页截屏插件设计开发
  14. [11]Debugging in Studio-UiPath ARD Certification Training
  15. 一维数组二维数组对称矩阵三角矩阵三对角矩阵地址的计算
  16. Linux火狐浏览器下载文件时文件名乱码
  17. keyshot怎么批量渲染_如何提高KeyShot的输出渲染速度
  18. 实习生被拒绝的N个理由
  19. C++ 杂谈之去除空格
  20. 国产良心极简版地图软件,地图下载很丝滑,界面简洁无广告

热门文章

  1. [51单片机] 四相五线减速比为1/64步进电机驱动设计
  2. php中include包含文件路径查找过程
  3. POJ 2135 Farm Tour
  4. Asp.net对http request 处理的全过程!
  5. android APN的打开与关闭
  6. 在java中什么管理内存_Java是如何管理内存
  7. stack(栈)数据结构详解
  8. Lucene查询结果高亮
  9. Relay log read failure
  10. delphi 防止程序双开 更好的 Best!