嵌入式工具集合使用



工具集合使用


下面我们来看下一个命令级叫nm,nm实际是一个叫做符合列表的概念。这个工具应该说是最精简也是最好用的一个工具,我们经常用它来查看我们可执行程序的符号表,所谓的符合表其实就是说我们可执行程序中有哪些全局的标签,我们通过这个标签也可以打印一些相关的信息。


比如说如下图:


set1.png


如图,我们输入命令“nm build”我们还是看build,build中其实就三列,第一列其实就是地址,但是它是用64bt的方式去显示的有点大,如果你32bt这个值就小一点。中间这一列就是我们的数据段类型,我们一般来说要记住这个,如果你在查nm手册中能查到这些数据段类型。然后给大家简单说一下大体也就是全局的函数标签(T)然后(D)就是全局变量区,如果说是(d)就是在本文件有效然后(t)就是函数的框节。这些都会在C语言中会介绍到。接下来我们还是一样看一下这个简单的例子,如上图T中有个“main”这个main就是我们刚刚说的全局变量,当然有同学说怎么光有main还有些其他乱七八糟的,大家可以想一下因为我们这个程序在操作系统运行当中不光有main,还有其他稀奇古怪的东西比如说图中下方的“400440”是不是我们start,也就是说我们双击这个程序的时候其实就从“start”这个地方跳,跳完之后它走了很多乱七八糟的程序,最后有一个程序跳到main,然后main开始运行起来,所以说整个过程实际上是这样的。


那nm恰好是看这些符号标签的,其中这样符号标签更多的概念就是“400440”这个部分,也就是说这个地方的值是多少,那么这个可以在函数中用百分之t去把我们函数标签打印出来,就可以看到其中的对应关系。


以上就是关于我们nm的理解,我们提一下它然后大家下来可能慢慢去用,随着后面课程中的深入我们会有不断的介绍。然后这个strip要说一下,这个strip我们叫做剔除符号表。


那为什么要有这个东西,这个东西你说它强大它也强大,你说它很弱它也很弱,它其实就是把一些符号表给剔除掉,而什么是符号表就是我们刚才说的那个表。


set2.png


如图就是符号地址之间的对应关系就有一张一一对应的表。那么我们来思考一下如果没有这张表,那么这个程序能不能运行呢?


很显然这个程序真正运行的现象是不是我们代码中那些二进制的信息,而这些信息是不是给人去看的一一对应的关系。所以这个时候大家在输入命令“file build”如下图:


set3.png


如图,前面的ID号或者现在它这个系统的情况我们不用管,其中最后一列有个叫做“not stripped”其中就告诉你build这个文件它没有剔除符号表。也就是说“not stripped”是剔除的意思,也就是说我用nm其实是可以看到这些表的。


而这个表是在build里有,也就是说在我们build这么大的文件中如下图:


set4.png


如图,在8535这个字节中其中就含有了一些我们所说的字段,但是我们strip过后就是把我们整个符号表中的无用信息全部给剔除掉,只保留有效的代码和数据,然后点击回车过后一般来说它没有什么反应。但是输入命令“file build”后它就会告诉你这个地方是strip的,也就是说没有表了,没有表我们在看大小输入命令“ls -l”我们会发现小了一些,然后我们在输入“nm build”会发现无符号也就是看不出来了。


那么也就是说这个工具的好处在于把有些人不想看的表就不要了因为这个表跟我们程序运行是没有任何相关性的,在我们嵌入式开发中像这个工具一般说在我们最后烧写到开发板的时候一般情况下是希望没有符号表的。因为我们嵌入式中本身储存量就够小了,如果还要把那么大的东西全部放进去还是一些无用信息,这是不好的。


所以我们一般来说最终生产出去的那个产品,就是调试部的在生产中一般情况下会把符号表给去掉。也就是说你在我们的目录只一定要把这个文件进行相应的strip,然后在提一下我们现在讲的strip都是在x86的环境,如果是arm的话要输入“arm-linux”这个前缀在加上strip就可以给剔除掉,实际上效果是一样的。



字符串


以上就是我们strip的一个问题,接下来来看下一个关键工具叫“strings”strings其实就是我们说查看可执行程序中一些常量字符串,比如说我们双引号定义的东西它就叫做字符,通过这个字符我们都能看到它里面定义的是哪些字符串。


下面我们来演示一下如下图:


set5.png


如图,这个跟符号表没关系也就是你虽然strip,但是在剔除符号表后我们strings还是能看到,以为你的代码中确确实实有这个双引号。你在把符号表剔除但是双引号的东西还在,比如说我们现在1.c中是不是有个hello world。然后我们输入命令“strings build”回车后你会发现其中有hello world,所以说通过这样一个命令,你至少能知道咱们这个可执行程序中它有哪些字符串可以拿来用,当然有些时候我们通过这些字符串也可以定位这些程序的一些现象和一些表现方式。


当然这个地方你们下来可以自己改,我在这就不改了,也就是说在这个地方你在增加一些双引号的东西然后在用string去看那就会发现还有一些新的字符串去打印出来了。


以上是关于string的介绍。



命令


下面我们两个比较重要的命令一个叫做objdump一个叫做objcopy,那么objcopy我们在学习arm的时候已经说到了它其实就是一个把我们的某些段比如代码段、数据段相应的格式给它拷出来。比如说我们在编译裸机开发的时候我们必须要经过objcopy,因为如果我们不进行objcopy那么我们一上来就直接运行了如下图:


set6.png


如图,这些词很显然不是arm认识的,所以这个地方我们是没有办法处理的,所以说objcopy我们必须要把那些头信息给剔掉。


下面我们简单的说一下objdump,objdump我们称为反汇编,这个工具的用处也是比较大的,其中objdump主要的选项大家可以通过“--help”去看,而“--help”中它有很多很多选项如下图:


set7.png


如图,其中比较重要的选项就是-D、-d都可以,这叫做disassemble也就是反汇编的意思。比如说我们刚才的build就可以输入命令“objdump -d(或者-D) build”这个时候就会看到它每一个汇编语言的关系,包括代码和地址之间的关系,当然这个也是我们在分析或者调试某些比较棘手的底层问题我们可能会用到的一些技巧。


以上就是objdump和objcopy的简单概念。


下面addr2line它实际上是我们在调试中把我们代码中的第几行出错的行号给标出来,但是这个调试工具一般情况下我们用的不多,因为它编译的结果用的比较大,你要用-G选项去把它编译出来,如果想看到时候看一下我们相应的文档然后照着去做一下就可以了。


以上,总的来说这就是我们整个交叉编译集比较常用的选项,但是在这要提一下这些工具集我们现在只是做了一个简略的介绍,以后在我们学校内核的时候我们可能还会用到这些工具,还会作进一步的加深理解。



【本文由麦子学院独家原创,转载请注明出处并保留原文链接】

logo
© 2012-2016 www.maiziedu.com
蜀ICP备13014270号-4 Version 5.0.0 release20160127
有一位课程导师想与你聊聊

免费电话咨询