Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1729887
  • 博文数量: 782
  • 博客积分: 2455
  • 博客等级: 大尉
  • 技术积分: 4140
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-06 21:37
个人简介

Linux ,c/c++, web,前端,php,js

文章分类

全部博文(782)

文章存档

2015年(8)

2014年(28)

2013年(110)

2012年(307)

2011年(329)

分类:

2012-02-16 09:13:31

原文地址:嵌入式的常用工具链 作者:gongping11

嵌入式开发中的常用工具gcc已经做了一定的总结,但是并不是只有gcc一个有用的工具,其中比较重要的工具有:
1、addr2line用于地址翻译,可以采用该工具判断某一个地址所在的函数,这样便于在出现错误时进行核对,检查函数的基本功能是否正确的实现。但是该工具只对存在调试信息的目标文件有效。通过该命令可以将某一地址确定到具体的函数。
通常被使用的形式为: addr2line 0x080c1000 -f -e objtarget
其中的选项分别表示:-f表示显示函数 -e表示后面对应的可执行文件 
 
该工具在c++中用于确定重载函数的函数原型有一定的效果,众所周知在C++中函数的重载在编译器下的差别主要是通过一定的前缀实现的,采用addr2line可以将前缀去掉得到定义中的函数原型。
基本的实现方法:addr2line address --demangle=gnu-v3 -f -e objtarget,其中选项--demangle=gnu-v3是还原的主要原因。
 
2、ar归档器,用于静态库的生成。
ar csr libname.a objname.o
 
3、nm 符号显示器,用来列出程序中的符号,这个符号显示器的好处可以分析数据的存储区域。由于nm工具列出了程序中符号的类型,可以根据符号类型,了解符号是在数据段,未初始化数据段还是在代码段,同样可以分析静态数据的所在的具体位置,这样也就知道了为什么在函数调用结束以后数据还能被保存,而不是被释放。
  1. /*nmtest.c*/
  2.   1 #include<stdio.h>
  3.   2
  4.   3 int global1;
  5.   4 int global2 = 3;
  6.   5
  7.   6 static int static_global1 = 1;
  8.   7
  9.   8 static int static_global2 = 3;
  10.   9
  11.  10 void foo ()
  12.  11 {
  13.  12 static int internal1;
  14.  13 static int internal2;
  15.  14
  16.  15 time (0);
  17.  16 }
  18.  17
  19.  18 static void bar ()
  20.  19 {
  21.  20
  22.  21 }
  23.  22
  24.  23 int main ()
  25.  24 {
  26.  25 int local1;
  27.  26 int local2 = 3;
  28.  27
  29.  28 foo ();
  30.  29
  31.  30 return 0;
  32.  31 }
  33. ~

上面的代码存在各种数据,全局变量,全局静态变量,局部变量,静态局部变量等,我们可以采用nm找到各个符号的存储位置。

下面是采用nm的实现效果:nm -n objtarget

[gong@Gong-Computer bintools]$ gcc -g nmtest.c -o nmtest
[gong@Gong-Computer bintools]$ nm -n nmtest
         w _Jv_RegisterClasses
         w __gmon_start__
         U
         U
08048290 T _init
08048300 T _start
08048330 t __do_global_dtors_aux
08048390 t frame_dummy
080483b4 T foo
080483c8 t bar
080483cd T main
080483f0 T __libc_csu_init
08048450 T __libc_csu_fini
08048455 T __i686.get_pc_thunk.bx
08048460 t __do_global_ctors_aux
0804848c T _fini
080484a8 R _fp_hw
080484ac R _IO_stdin_used
080484b0 R __dso_handle
08048550 r __FRAME_END__
08049554 d __CTOR_LIST__
08049554 d __init_array_end
08049554 d __init_array_start
08049558 d __CTOR_END__
0804955c d __DTOR_LIST__
08049560 D __DTOR_END__
08049564 d __JCR_END__
08049564 d __JCR_LIST__
08049568 d _DYNAMIC
08049634 d _GLOBAL_OFFSET_TABLE_
0804964c D __data_start
0804964c W data_start
08049650 D global2
08049654 d static_global1
08049658 d static_global2
0804965c A __bss_start
0804965c A _edata
0804965c b completed.5530
08049660 b dtor_idx.5532
08049664 b internal2.1676
08049668 b internal1.1675
0804966c B global1
08049670 A _end
上面的红色部分就是我们的几个变量,其中我们可以发现主要存在三列数据,分别是地址,以及所在段(.text,.data,.bss等),最后是符号名,函数名,全局变量,静态数据都是符号。

其中第二列的字母分别表示对应的段:

A 表示不会改变的,即使在链接过程中

B 表示.bss段

C 表示没有被初始化的公共符号

D 表示.data段

N 表示符号用于调试

P 表示符号位域一个栈中

R 表示在只读数据段中

T和t 表示在代码段中,对于函数名作为符号,若是"T"表示为非静态函数,而"t"表示为静态函数

U 表示没有定义

根据上面的说明分析上面的结果可以知道对于静态变量不是存储在.data段中就是存储在.bss段中,具体的根据是否初始化判断。全局变量的分配也与是否初始化有关,不是存在于.data中就是在.bss中,而局部变量不能通过nm看到。

4、objdump工具,该工具主要用于查看数据,可以查看目标文件的段(sections),可以查看目标文件的信息。通常使用的几个组合为:

   4.1查看目标文件的段信息: objdump -h objtarget

   4.2 查看目标文件的汇编代码: objdump -d objtarget

       源码和汇编代码对照显示: objdump -S -d objtarget

   4.3 查看具体段的信息: objdump -s -j .data(某一个段) objtarget 其中的-s表示显示具体的内容,而-j 表示选择某一个段。

   4.4 查看程序的入口地址: objdump -f objtarget

5、段剪辑工具,可以操作具体的某一个段,可以删除和剪辑以及滤除调试信息等

   5.1剪辑具体的某一段到一个新的目标文件: objcopy -j .data(某一个段) objtarget newtarget

   5.2 删除具体的某一个段:objcopy -R .data(某一个段) objtarget newtarget

   5.3 滤除调试信息 objcopy --strip-debug objtarget

通常是objdump 和objcopy 结合使用,这样就能得到具体的信息。采用上面的nmtest.c进行演示。

[gong@Gong-Computer bintools]$ objcopy -j .data nmtest newtarget
BFD: nmtest: warning: Empty loadable segment detected, is this intentional ?

[gong@Gong-Computer bintools]$ ls -a
.  ..  arm_nmtest  arm_nmtest.txt  arm_test  arm_test_cpp  cppmain  main.c  newtarget  nmtest  nmtest.c  onlytext  string  string.c  target  test
[gong@Gong-Computer bintools]$ objdump -h newtarget

newtarget:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .data         00000010  0804964c  0804964c  0000064c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
[gong@Gong-Computer bintools]$ objcopy -j .data -j .text -j .bss nmtest newtarget
[gong@Gong-Computer bintools]$ objdump -h newtarget

newtarget:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0000018c  08048300  08048300  00000300  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000010  0804964c  0804964c  0000064c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000014  0804965c  0804965c  0000065c  2**2
                  ALLOC
[gong@Gong-Computer bintools]$ objcopy -R .text newtarget
BFD: newtarget: warning: Empty loadable segment detected, is this intentional ?

[gong@Gong-Computer bintools]$ objdump -h newtarget

newtarget:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .data         00000010  0804964c  0804964c  0000064c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  1 .bss          00000014  0804965c  0804965c  0000065c  2**2
                  ALLOC
查看程序与对应的汇编代码:

                  ALLOC
[gong@Gong-Computer bintools]$ objdump -S -d nmtest

nmtest:     file format elf32-i386
Disassembly of section .init:

...

void foo ()
{
 80483b4: 55                    push   %ebp
 80483b5: 89 e5                 mov    %esp,%ebp
 80483b7: 83 ec 18              sub    $0x18,%esp
 static int internal1;
 static int internal2;

 time (0);
 80483ba: c7 04 24 00 00 00 00  movl   $0x0,(%esp)
 80483c1: e8 2a ff ff ff        call   80482f0 <>
}
 80483c6: c9                    leave 
 80483c7: c3                    ret   

080483c8 :

static void bar ()
{
 80483c8: 55                    push   %ebp
 80483c9: 89 e5                 mov    %esp,%ebp
 
}
 80483cb: 5d                    pop    %ebp
 80483cc: c3                    ret   

080483cd

:

int main ()
{
 80483cd: 55                    push   %ebp
 80483ce: 89 e5                 mov    %esp,%ebp
 80483d0: 83 e4 f0              and    $0xfffffff0,%esp
 80483d3: 83 ec 10              sub    $0x10,%esp
 int local1;
 int local2 = 3;
 80483d6: c7 44 24 0c 03 00 00  movl   $0x3,0xc(%esp)
 80483dd: 00

 foo ();
 80483de: e8 d1 ff ff ff        call   80483b4

 return 0;
 80483e3: b8 00 00 00 00        mov    $0x0,%eax
}
...

上面的就是通过objdump的反汇编代码。

滤除的效果如下:

[gong@Gong-Computer bintools]$ objdump -h nmtest

nmtest:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  08048134  08048134  00000134  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  08048148  08048148  00000148  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .note.gnu.build-id 00000024  08048168  08048168  00000168  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .gnu.hash     00000020  0804818c  0804818c  0000018c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynsym       00000050  080481ac  080481ac  000001ac  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .dynstr       0000004a  080481fc  080481fc  000001fc  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version  0000000a  08048246  08048246  00000246  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .gnu.version_r 00000020  08048250  08048250  00000250  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rel.dyn      00000008  08048270  08048270  00000270  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .rel.plt      00000018  08048278  08048278  00000278  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 10 .init         00000030  08048290  08048290  00000290  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .plt          00000040  080482c0  080482c0  000002c0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .text         0000018c  08048300  08048300  00000300  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .fini         0000001c  0804848c  0804848c  0000048c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 14 .rodata       0000000c  080484a8  080484a8  000004a8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .eh_frame_hdr 00000024  080484b4  080484b4  000004b4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 16 .eh_frame     0000007c  080484d8  080484d8  000004d8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 17 .ctors        00000008  08049554  08049554  00000554  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .dtors        00000008  0804955c  0804955c  0000055c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .jcr          00000004  08049564  08049564  00000564  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 20 .dynamic      000000c8  08049568  08049568  00000568  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 21 .got          00000004  08049630  08049630  00000630  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 22 .got.plt      00000018  08049634  08049634  00000634  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 23 .data         00000010  0804964c  0804964c  0000064c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 24 .bss          00000014  0804965c  0804965c  0000065c  2**2
                  ALLOC
 25 .comment      0000002c  00000000  00000000  0000065c  2**0
                  CONTENTS, READONLY
 26 .debug_aranges 00000020  00000000  00000000  00000688  2**0
                  CONTENTS, READONLY, DEBUGGING
 27 .debug_pubnames 0000003b  00000000  00000000  000006a8  2**0
                  CONTENTS, READONLY, DEBUGGING
 28 .debug_info   00000146  00000000  00000000  000006e3  2**0
                  CONTENTS, READONLY, DEBUGGING
 29 .debug_abbrev 000000aa  00000000  00000000  00000829  2**0
                  CONTENTS, READONLY, DEBUGGING
 30 .debug_line   00000041  00000000  00000000  000008d3  2**0
                  CONTENTS, READONLY, DEBUGGING
 31 .debug_frame  00000074  00000000  00000000  00000914  2**2
                  CONTENTS, READONLY, DEBUGGING
 32 .debug_str    000000eb  00000000  00000000  00000988  2**0
                  CONTENTS, READONLY, DEBUGGING
 33 .debug_pubtypes 00000012  00000000  00000000  00000a73  2**0
                  CONTENTS, READONLY, DEBUGGING
一共33个段

[gong@Gong-Computer bintools]$ objcopy --strip-debug nmtest
[gong@Gong-Computer bintools]$ objdump -h nmtest

nmtest:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .interp       00000013  08048134  08048134  00000134  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  08048148  08048148  00000148  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .note.gnu.build-id 00000024  08048168  08048168  00000168  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .gnu.hash     00000020  0804818c  0804818c  0000018c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynsym       00000050  080481ac  080481ac  000001ac  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .dynstr       0000004a  080481fc  080481fc  000001fc  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version  0000000a  08048246  08048246  00000246  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .gnu.version_r 00000020  08048250  08048250  00000250  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rel.dyn      00000008  08048270  08048270  00000270  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .rel.plt      00000018  08048278  08048278  00000278  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 10 .init         00000030  08048290  08048290  00000290  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .plt          00000040  080482c0  080482c0  000002c0  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .text         0000018c  08048300  08048300  00000300  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .fini         0000001c  0804848c  0804848c  0000048c  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 14 .rodata       0000000c  080484a8  080484a8  000004a8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 15 .eh_frame_hdr 00000024  080484b4  080484b4  000004b4  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 16 .eh_frame     0000007c  080484d8  080484d8  000004d8  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 17 .ctors        00000008  08049554  08049554  00000554  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 18 .dtors        00000008  0804955c  0804955c  0000055c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 19 .jcr          00000004  08049564  08049564  00000564  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 20 .dynamic      000000c8  08049568  08049568  00000568  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 21 .got          00000004  08049630  08049630  00000630  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 22 .got.plt      00000018  08049634  08049634  00000634  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 23 .data         00000010  0804964c  0804964c  0000064c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 24 .bss          00000014  0804965c  0804965c  0000065c  2**2
                  ALLOC
 25 .comment      0000002c  00000000  00000000  0000065c  2**0
                  CONTENTS, READONLY
这次只有25个段。

通过上面的分析可以发现调试信息减少了,这就实现了具体的滤除操作。

上面的这些工具只有在经常的运用才能有很好的效果啊,特别是出现错误时用来分析。

阅读(533) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~