binutils工具集1

来源:互联网 发布:jdk for mac 下载 编辑:程序博客网 时间:2024/05/01 16:49
          binutils工具集1.addr2line 作用:用于得到程序指令地址所对应的函数,以及函数所在的源文件名和行号。addr2line 例:-------------------------------------------------------------//文件名:addr2line_test.c#include<stdio.h>void foo(){        printf("The address of foo() %#x\n",foo);}int main(void){        foo();        return 0;}-------------------------------------------------------------编译:gcc -g addr2line_test.c -o addr2line_test执行:./addr2line_test 结果:The address of foo() 0x80483e4-------------------------------------------------------------null@ubuntu:~/c-test$ addr2line 0x80483e4 -f -e addr2line_testfoo/home/null/c-test/addr2line_test.c:4--------------------------------------------------------------nm 符号显示器--------------------------------------------------------------null@ubuntu:~/c-test$ nm -n addr2line_test        ............080483e4 T foo08048401 T main............--------------------------------------------------------------对于c++可以使用addr2line的--demangle选项获得函数名addr2line 地址 --demangle=gnu-v3 -f -e 可执行文件--------------------------------------------------------------2.ar,静态库生成器先看下生成一个静态库和解压一个静态库的方法:会在当前目录下生成一个libtest.a静态库文件。-c表示只编译,不链接--------------------------------------------------------------2.1生成一个静态库gcc -c addr2line_test.c //生成一个addr2line_test.o 文件ar cr libtest.a addr2line_test.olibtest.a //生成--------------------------------------------------------------2.2解压一个静态库ar x libtest.a //将libtest.a解压 生成上面的 addr2line_test.o--------------------------------------------------------------2.3静态库的查看和删除ar t xxx.a//查看ar d libxx.a xx.o//删除静态库中的xx.o--------------------------------------------------------------2.4实验:新建两个函数foo.c bar.c----------------------------------#include<stdio.h>// foo.c functionvoid foo(){        printf("This is foo()\n");}----------------------------------#include<stdio.h>// bar.c functionvoid bar(){        printf("This is bar()\n");}----------------------------------然后分别编译这两个文件生成.o文件gcc -c bar.c gcc -c foo.c bar.c  bar.o  foo.c  foo.o//生成的.o文件然后用ar命令来生成libmy.a静态库ar crs libmy.a foo.o bar.o//c参数表示创建一个档案文件,r参数指示将文件增加到创建的库文件中//s参数是为了生成库索引以提高库被链接时的效率库文件已经生成,现在就该怎么使用这个库文件了。新建一个main.c文件-----------------------------------#include<stdio.h>extern void foo();extern void bar();int main(){        foo();        bar();        return 0;}----------------------------------- 编译链接静态库:gcc main.c libmy.a -o main  ./mainThis is foo()This is bar()--------------------------------------------------------------3.nm,符号显示器nm用于列出程序文件的符号--------------------------------------------------------------先看一个例子: nm -n main 函数或变量的开始地址  相应的符号存放在哪一个段中符号的名字080482b0 T _init08048320 T _start08048350 t __do_global_dtors_aux080483b0 t frame_dummy080483d4 T main080483ec T foo08048400 T bar08048420 T __libc_csu_init08048490 T __libc_csu_fini08048492 T __i686.get_pc_thunk.bx080484a0 t __do_global_ctors_aux080484cc T _fini080484e8 R _fp_hw080484ec R _IO_stdin_used08048650 r __FRAME_END__08049f14 d __CTOR_LIST__08049f14 d __init_array_end08049f14 d __init_array_start08049f18 d __CTOR_END__08049f1c d __DTOR_LIST__08049f20 D __DTOR_END__08049f24 d __JCR_END__08049f24 d __JCR_LIST__08049f28 d _DYNAMIC08049ff4 d _GLOBAL_OFFSET_TABLE_0804a00c D __data_start0804a00c W data_start0804a010 D __dso_handle0804a014 A __bss_start0804a014 A _edata0804a014 b completed.61590804a018 b dtor_idx.61610804a01c A _end--------------------------------------------------------------符号的含义字母说明A表示符号所对应的的值是绝对的且在以后的连接过程中也不会改变B或b未初始化的.bss段C表示没有被初始化的公共符号D或d表示位于初始化的.data段N表示符号是调试用的P表示符号位于一个栈回溯段中R或r表示位于只读数据段(.rdata)中T或t表示符号位于代码段(.text)U表示符号没有被定义--------------------------------------------------------------新建一个main.c文件:---------------------------------#include<time.h>int global1;int global2 = 1;static int static_global1;static int static_global2 = 1;void foo(){        int internal1;        int internal2 = 1;        static int static_internal1;        static int static_internal2 = 1;        time(0);}int main(void){        int local1;        int local2 = 1;        static int static_local1;        staitc int static_local2 =1;        foo();        return 0;}---------------------------------gcc -c -g main.cnm -n main.o//注意输出结果是0地址开始,由于程序没有完成链接,所以是指符号在对应段中的相对偏移位置         U time//没用被定义的符号,原因是在c的标准库中00000000 T foo    //.test00000000 D global2//.data00000000 b static_global1//.bss00000004 C global1//未初始化的公共符号00000004 d static_global2//.data00000004 b static_local1.1419//.bss00000008 b static_internal1.1412//.bss00000008 d static_local2.1420//.data0000000c d static_internal2.1413//.data0000001b T main//.text------------------------------------------------------------总结:1.静态变量初始话后放在.data,没有被初始话则放在.bss段2.非静态的全局变量初始化后放在.data,否则放在.bss3.函数无论是静态还是动态都是放在.text段。字母“t”的大小写表示  了符号是否为静态函数,小写表示静态4.函数内的局部变量由于被分配到了栈上,nm中是看不到他们的--------------------------------------------------------------链接后看变化:1.地址变化 2.global1变化了080483d4 T foo080483ef T main0804a014 D global20804a018 d static_global20804a01c d static_local2.14200804a020 d static_internal2.14130804a02c b static_global10804a030 b static_local1.14190804a034 b static_internal1.14120804a038 B global1 //这里变化--------------------------------------------------------------