binutils工具集1

					          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_test
		foo
		/home/null/c-test/addr2line_test.c:4
		--------------------------------------------------------------
		nm 符号显示器
		--------------------------------------------------------------
		null@ubuntu:~/c-test$ nm -n addr2line_test
        ............
		080483e4 T foo
		08048401 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.o
		libtest.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 function
		void foo()
		{
		        printf("This is foo()\n");
		}
		----------------------------------
		#include<stdio.h>
		// bar.c function
		void 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
		  ./main
		This is foo()
		This is bar()
		--------------------------------------------------------------
3.nm,符号显示器
		nm用于列出程序文件的符号
		--------------------------------------------------------------
	先看一个例子: nm -n main 
		函数或变量的开始地址  相应的符号存放在哪一个段中		符号的名字
		080482b0 					T 							_init
		08048320 					T 							_start
		08048350 					t 							__do_global_dtors_aux
		080483b0 					t 							frame_dummy
		080483d4 					T 							main
		080483ec 					T 							foo
		08048400 					T 							bar
		08048420 					T 							__libc_csu_init
		08048490 					T 							__libc_csu_fini
		08048492 					T 							__i686.get_pc_thunk.bx
		080484a0 					t 							__do_global_ctors_aux
		080484cc 					T 							_fini
		080484e8 					R 							_fp_hw
		080484ec 					R 							_IO_stdin_used
		08048650 					r 							__FRAME_END__
		08049f14 					d 							__CTOR_LIST__
		08049f14 					d 							__init_array_end
		08049f14 					d 							__init_array_start
		08049f18 					d 							__CTOR_END__
		08049f1c 					d 							__DTOR_LIST__
		08049f20 					D 							__DTOR_END__
		08049f24 					d 							__JCR_END__
		08049f24 					d 							__JCR_LIST__
		08049f28 					d 							_DYNAMIC
		08049ff4 					d 							_GLOBAL_OFFSET_TABLE_
		0804a00c 					D 							__data_start
		0804a00c 					W 							data_start
		0804a010 					D 							__dso_handle
		0804a014 					A 							__bss_start
		0804a014 					A 							_edata
		0804a014 					b 							completed.6159
		0804a018 					b 							dtor_idx.6161
		0804a01c 					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.c
		nm -n main.o
	//注意输出结果是0地址开始,由于程序没有完成链接,所以是指符号在对应段中的相对偏移位置
			         U time					//没用被定义的符号,原因是在c的标准库中
			00000000 T foo    				//.test
			00000000 D global2				//.data
			00000000 b static_global1		//.bss
			00000004 C global1				//未初始化的公共符号
			00000004 d static_global2		//.data
			00000004 b static_local1.1419	//.bss
			00000008 b static_internal1.1412//.bss
			00000008 d static_local2.1420	//.data
			0000000c d static_internal2.1413//.data
			0000001b T main					//.text
		------------------------------------------------------------
		总结:
		1.静态变量初始话后放在.data,没有被初始话则放在.bss段
		2.非静态的全局变量初始化后放在.data,否则放在.bss
		3.函数无论是静态还是动态都是放在.text段。字母“t”的大小写表示
		  了符号是否为静态函数,小写表示静态
		4.函数内的局部变量由于被分配到了栈上,nm中是看不到他们的
		--------------------------------------------------------------
	链接后看变化:1.地址变化 2.global1变化了
			080483d4 T foo
			080483ef T main
			0804a014 D global2
			0804a018 d static_global2
			0804a01c d static_local2.1420
			0804a020 d static_internal2.1413
			0804a02c b static_global1
			0804a030 b static_local1.1419
			0804a034 b static_internal1.1412
			0804a038 B global1 //这里变化
		--------------------------------------------------------------
		
	

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

byd yes

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值