Chinaunix首页 | 论坛 | 博客
  • 博客访问: 362140
  • 博文数量: 64
  • 博客积分: 2975
  • 博客等级: 少校
  • 技术积分: 831
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-14 10:59
文章存档

2014年(2)

2012年(7)

2010年(40)

2009年(5)

2008年(8)

2007年(2)

分类: LINUX

2010-03-30 10:26:40

1.什么是binutils

先写一个简单的hello_world.c程序.

#include

int main()
{
printf("Hello World!\n");
return 0;
}

编译它

[root@mail ~]# gcc -v hello_world.c
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared -

-enable-threads=posix --disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
 /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/cc1 -lang-c -v -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=2

-D__GXX_ABI_VERSION=102 -D__ELF__ -Dunix -D__gnu_linux__ -Dlinux -D__ELF__ -D__unix__ -D__gnu_linux__ -D__linux__

-D__unix -D__linux -Asystem=posix -D__NO_INLINE__ -D__STDC_HOSTED__=1 -Acpu=i386 -Amachine=i386 -Di386 -D__i386

-D__i386__ -D__tune_i386__ hello_world.c -quiet -dumpbase hello_world.c -version -o /tmp/ccYjZdgg.s
GNU CPP version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) (cpplib) (i386 Linux/ELF)
GNU C version 3.2.2 20030222 (Red Hat Linux 3.2.2-5) (i386-redhat-linux)
        compiled by GNU C version 3.2.2 20030222 (Red Hat Linux 3.2.2-5).
ignoring nonexistent directory "/usr/i386-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/include
 /usr/include
End of search list.
 as -V -Qy -o /tmp/ccOuEybl.o /tmp/ccYjZdgg.s
GNU assembler version 2.18 (i686-pc-linux-gnu) using BFD version (GNU Binutils) 2.18
 /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2

/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crt1.o /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crti.o

/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/crtbegin.o -L/usr/lib/gcc-lib/i386-redhat-linux/3.2.2

-L/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../.. /tmp/ccOuEybl.o -lgcc -lgcc_eh -lc -lgcc -lgcc_eh

/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/crtend.o /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crtn.o
[root@mail ~]#

从上面的输出可以看出,整个编译过程可分成三步:

第一步,将c语言编译成汇编语言
gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
 /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/cc1 -lang-c -v -D__GNUC__=3 -D__GNUC_MINOR__=2 -D__GNUC_PATCHLEVEL__=2

-D__GXX_ABI_VERSION=102 -D__ELF__ -Dunix -D__gnu_linux__ -Dlinux -D__ELF__ -D__unix__ -D__gnu_linux__ -D__linux__

-D__unix -D__linux -Asystem=posix -D__NO_INLINE__ -D__STDC_HOSTED__=1 -Acpu=i386 -Amachine=i386 -Di386 -D__i386

-D__i386__ -D__tune_i386__ hello_world.c -quiet -dumpbase hello_world.c -version -o /tmp/ccYjZdgg.s

第二步,将汇编语言编译成目标文件
as -V -Qy -o /tmp/ccOuEybl.o /tmp/ccYjZdgg.s

第三步,将目标文件链接成可执行文件
 /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/collect2 --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2

/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crt1.o /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crti.o

/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/crtbegin.o -L/usr/lib/gcc-lib/i386-redhat-linux/3.2.2

-L/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../.. /tmp/ccOuEybl.o -lgcc -lgcc_eh -lc -lgcc -lgcc_eh

/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/crtend.o /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/../../../crtn.o

这里由gcc->as->collect2组成一套环环相扣的编译环境,就像链条一样,因此被称为编译工具链(toolsChain)。

在这三个步骤中,第二步用到的工具程序as就是由binutils工具包提供的。第三步用到的工具程序collect2实际上会调用ld进行实质的

链接工作,collect2只是对ld的包装而已。而ld也是由binutils提供.可见,bintuils在对于我们非常重要,没有它,toolsChain就不存在

2.binutils都包含哪些工具

除了上面提到as,和ld这两个最重要的工具,binutils还提供了许多其他工具,这些工具大家工作中都要经常用到。下面把binutils所

包含的工具都列出来,并给出简要说明。(摘自)

addr2line - Converts addresses into filenames and line numbers.
ar - A utility for creating, modifying and extracting from archives.
c++filt - Filter to demangle encoded C++ symbols.
dlltool - Creates files for building and using DLLs.
gold - A new, faster, ELF only linker, still in beta test.
gprof - Displays profiling information.
nlmconv - Converts object code into an NLM.
nm - Lists symbols from object files.
objcopy - Copys and translates object files.
objdump - Displays information from object files.
ranlib - Generates an index to the contents of an archive.
readelf - Displays information from any ELF format object file.
size - Lists the section sizes of an object or archive file.
strings - Lists printable strings from files.
strip - Discards symbols.
windmc - A Windows compatible message compiler.
windres - A compiler for Windows resource files.

可以发现,ar,gprof,nm,objcopy,objdump,ranlib,readelf,size,strings,strip等经常见到的工具也是由binutils提供。

3.下载编译binutils

本分析基于binutils-2.18版,下载地址是.

将binutils-2.18.tar.gz下载到一台linux机器上.

解压
tar -xzf binutils-2.18.tar.gz.

配置
cd binutils-2.18
./configure CFLAGS=-g

由于默认的编译选项是-g -O2,这将导致在分析调试时达不到最佳效果,通过传CLFAGS=-g修改默认选项。

编译
make

4.源码结构

tree命令显示,下面几个目录比较重要.
.
|-- bfd
|-- binutils
|-- gas
|-- gprof
|-- include
|-- ld
|-- libiberty
|-- opcodes

可以看出,as,ld,gprof都有自己独立的目录,其他工具都放在binutils目录中,libiberty目录存放公共库文件。

bfd目录存放二进制文件描述库(Binary File Descriptor library)文件,该库支持对不同格式文件的各种操作,并为工具提供执行这

些低级操作的接口,例如objdump能够读写elf,pe等各种文件,bfd功不可没。

opcodes目录存放平台机器码相关的文件,各平台一般有两个文件比较重要,xxx-dis.c和xxx-tbl.h.xxx-dis.c提供反汇编接

口,objdump -d的反汇编功能由它完成。xxx-tbl.h提供指令模板,为as翻译机器指令过程服务。我们以后经常打交道的文件是

是i386-dis.c和i386-tbl.h。


5.源码阅读工具

现在源码阅读工具有很多,我倾向于使用source in sight 3.5,这个网上有的下。

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