解析基于ELF的嵌入式软件源码级交叉调试技术
开发任何一个软件都不可避免地存在各种错误,要修正错误必须找出其错误原因。通常程序员利用调试器来跟踪程序执行情况,快速有效地定位错误产生的位置从而找到引起错误的原因,并改正错误。
调试器为用户提供的主要功能包括:在目标程序中设置、删除断点;以单步执行或连续执行等方式控制目标程序运行;浏览程序中的变量或表达式的值;查看、修改目标机寄存器的内容;查看、修改目标机内存的内容。源码级调试器是面向高级语言的符号调试工具,它基于源代码的语句和符号跟踪观察目标程序,同时提供基于汇编级的程序跟踪功能以满足用户底层的调试需要。通用计算机软件一般在同一台机器上进行编辑、编译、调试;而嵌入式软件的目标系统多为特殊的专用系统,通常采用宿主机/目标机开发环境,借助通用计算机作为编辑源文件的宿主机,利用交叉编译器在宿主机上编译生成目标机的可执行代码,调试时通过通讯介质(串线或网络)将目标代码下载到目标系统上运行,利用交叉调试器进行跟踪调试。
一、源码级交叉调试器的实现途径
程序运行过程中目标程序的指令代码和数据都映射到目标机上相应的内存内容,为了实现源码级调试,利用目标文件中在程序编译链接时生成的调试信息来实现目标程序与源程序之间的映射,从而在源码级实现对程序执行情况的控制和观察。其关键在于找到调试控制点和数据在源程序与目标程序之间的映射关系。
任何数据都有名和值两个侧面,数据名与数据值之间的映射关系为:根据数据名得到存放该数据值的内存地址,再从目标机的内存地址取出其内容即为数据值:
调试中的程序控制点通常为源程序中的函数、语句行等,它们对应于装载到目标内存中的相应目标代码,要实现程序的运行控制关键在于得到源代码与目标代码之间的映射关系:由源码定位信息得到相应的目标码信息;由目标码地址得到相应的源码定位信息。源码定位信息为源文件名+行号或函数名;目标码信息为目标指令在目标机内存中的起始和终止地址。
嵌入式软件以宿主机/目标机模式开发,其交叉调试器分为宿主机部分和目标机部分,两者以统一的通讯协议进行通信,宿主机向目标机发送命令,目标机接收、执行命令并将结果返回宿主机,从而实现两机之间的交互控制。免费软件基金会FSF提供的调试工具gdb具有一套比较成熟的通讯协议----remote通讯协议,该协议作为开放软件被广为采用,在此我们选择了rmote协议作为交叉调试器的远程通讯协议。
二、ELF格式目标文件
目标文件是实现源码级调试的基础,需要详细分析文件的格式及内容以从中获取有用的调试信息。在设计调试器时采用可执行连接格式DDELF格式目标文件作为开发基础,ELF(Executable and Linking Format)是UNIX系统实验室(USL)作为应用程序二进制接口(Application Binary Interface(ABI))而开发和发布的,已被软件业广泛采用,在Linux系统中ELF格式是其默认的目标文件格式,许多嵌入式软件都采用ELF格式作为目标文件格式。
ELF目标文件主要有三种类型:可重定位文件,可执行文件,共享的目标文件,我们以可执行文件为分析对象。
ELF头固定在文件的起始位置,其它各部分的位置由ELF头及其它相关信息获得。
1、ELF头
ELF头是整个文件的入口,具有固定的长度,52个字节,包含14个值。包括ELF文件标识,程序头表和节头表的位置、长度,文件中段的数目和节的数目等信息。
2、程序头表与段
程序头表中有多个表项,每个表项是一个程序段的信息,固定长度为32个字节,包含8个值,包括段在文件中的位置,段在内存中的起始虚拟地址,段的长度及其它属性等。调试器根据程序头表中的信息来确定需要下载到目标机上的目标文件内容(指令与数据)及其在目标机中的内存地址。
3、节头表与节
节头表中也有多个表项,每个表项是一个节的信息,固定长度为40个字节,包含10个值,包括节名、节的类型、该节在文件中的位置、该节在内存中的起始地址(如果该节出现在内存映象中)、节的长度等信息。某些节是程序段的组成部分,如包含程序二进制指令代码的正文节.text和数据节.rodata,.hash等,某些节不作为段的组成部分,只提供其它的额外信息。为源码调试服务的有 .debug,.line,.symtab,.debug_ pubname,.debug_range等节,其中.debug, .line节包含了源码调试信息的基本内容。
.debug节中有多种类型的记录,可分为几大类:
(1)、编译模块信息:包含组成该文件的各个模块的源文件名,路径,及该模块的代码地址范围等。
(2)、子程序信息:包含程序名,程序类型,起始终止地址,程序返回结果存放地址等。
(3)、
交叉 调试 技术 源码 软件 基于 ELF 嵌入式 解析 相关文章:
- 建立针对arm-linux的交叉编译环境(02-07)
- 基于AD9516的高速四通道时间交叉采样时钟的设计(09-22)
- 嵌入式Linux开发环境的搭建之:嵌入式开发环境的搭建(08-13)
- 基于FPGA的共享总线开关网络实现多CPU共享内存(06-05)
- RS-485及RS-422的自动交叉连接(12-20)
- 直连串口线和交叉串口线的区别(12-13)