binutils

 

GNU Binutils是交叉编译工具链二进制工具的集合

GNU Binutils是交叉编译工具链二进制工具的集合

主要包括:

  • ld - GNU链接器
  • as - GNU汇编程序

但它还包括以下工具:

工具 功能
addr2line 将地址转换为文件名和行号。
ar 用于创建、修改和从存档中提取的实用程序。
c++filt 过滤器,以demangle编码的c++符号。
dlltool 创建用于构建和使用dll的文件。
gold 一个新的,更快的,只有精灵的链接器,仍然在测试中。
gprof 显示配置信息。
nlmconv 将目标代码转换为NLM。
nm 列出目标文件中的符号。
objcopy 复制和翻译目标文件。
objdump 显示目标文件中的信息。
ranlib 生成存档内容的索引。
readelf 显示来自任何ELF格式对象文件的信息。
size 列出对象或存档文件的节大小。
strings 列出文件中的可打印字符串。
strip 丢弃的象征。
windmc 一个Windows兼容的消息编译器。
windres 用于Windows资源文件的编译器。

这些程序大多使用二进制文件描述符库BFD( Binary File Descriptor library)来进行低级操作。它们中的许多还使用操作码库(opcodes library)来组装和拆卸机器指令。

大多数主要的Unix变体和Wintel系统都移植了binutil,它们存在的主要原因是为GNU系统(和GNU/Linux)提供了编译和链接程序的工具。

获得binutils

当前版本可以从binutils下载,或者通过通用URL http://ftpmirror.gnu.org/binutils 从附近的镜像下载。

工具说明

新目标架构的Binutils移植指南

Binutils 的文件组织结构

大部分binutils源代码位于少数几个目录中。binutils的一些组件是库,可以在内部使用,也可以在其他项目中使用。例如,在GNU GDB调试器中使用了BFD库。这些库有它们自己的顶级目录。主要目录有:

                         binutils
                            |
                            |
    ----------------------------------------------------------
   |       |     |       |      |       |   |     |     |     |
   |       |     |       |      |       |   |     |     |     |
 include  bfd  opcodes  cpu  binutils  gas  ld  gprof  gold  elfcpp

上面目录的一些简要说明:

目录 说明
include 跨主要组件的信息头文件。
例如,模拟器的主接口头文件在这里(remote-sim.h),因为它将GDB(在目录GDB中)链接到模拟器(在目录sim中)。
bfd 二进制文件描述符库。这个库包含处理特定二进制文件格式的代码,如ELF、COFF、SREC等。如果必须识别新的对象文件类型,则应该在这里添加支持它的代码。
opcodes 操作码库。它包含了关于如何汇编和反汇编指令的信息。
cpu 一个名为CGEN的实用程序的源文件。这是一个工具,可以用来为操作码库和GDB使用的SIM模拟器自动生成目标特定的源文件
binutils 忽略它的名字,这不是主要的binutils目录。相反,它是所有没有自己顶级源目录的binutils工具的目录。这包括objcopy、objdump和readelf等工具。
gas GNU汇编器(GNU assembler)。特定目标的汇编代码保存在config子目录中。
ld GNU链接器(GNU linker)。目标特定的链接器文件保存在子目录中。
gprof GNU分析器(GNU profiler)。这个程序没有任何目标特定的代码。
gold 新的GNU链接器。这是一个正在创建的新的连接器,以取代LD,目前仍在开发中。
elfccp Elfcpp是一个用于读取和编写ELF信息的c++库。它目前只被 GOLD 链接器使用。

此外,在一个binutils源版本的顶层还可以找到几个其他目录。它们在binutils构建过程中使用,但它们不是binutils项目的一部分

目录 说明
intl 来自gettext的GNU gettext库。
libiberty 在POSIX和glibc之前,这是一个提供一组标准函数的GNU项目。它存在于binutils中。最有价值的是它的免费存储管理和参数解析函数。

主要功能领域和数据结构

二进制文件描述(BFD)

BFD是一个包,它允许应用程序使用相同的例程对目标文件进行操作,无论目标文件格式是什么。只需创建一个新的BFD后端并将其添加到库中,就可以支持新的目标文件格式。

BFD库后端创建了许多数据结构,用于描述在特定类型的目标文件中保存的数据。

最终会为每个单独的体系结构定义一个惟一的枚举常量(类型为enum bfd_architecture)。然后使用这个常量来访问与特定体系结构相关联的各种数据结构。

在compac - risc的16位实现(可能是COFF或ELF二进制文件)情景中,枚举常数是bfd_cr16_arch。这可以用来访问各种结构,例如:

  const bfd_arch_info_type bfd_cr16_arch =
    {
      16,               /* 16 bits in a word.  */
      32,               /* 32 bits in an address.  */
       8,               /*  8 bits in a byte.  */
      bfd_arch_cr16,    /* enum bfd_architecture arch.  */
      bfd_mach_cr16,    /* Machine value, used to distinguish between cr16 variants.  */
      "cr16",           /* Architecture name (short version).  */
      "cr16",           /* Architecture name (long version).  */
      1,                /* Section alignment power.  */
      TRUE,             /* True if this is the default machine for the architecture.  */
      bfd_default_compatible, /* Function to call to determine if two different architectures are compatible.  */
      bfd_default_scan, /* Function to call to determine if a given string matches this architecture.  */ 
      NULL,             /* Pointer to the next CR16 machine architecture.  */
    };

这个特殊的结构是在bfd目录中的一个名为cpu-<target>.c的文件中定义的。

文件<file_format>-<target>.c(例如:elf32-cr16.c)用于为给定的文件格式和体系结构提供特定的目标支持。它至少提供了以下信息:

  1. 一个reloc_map数组,它将BFD重定位枚举映射为特定于目标的重定位类型

  2. 具有目标特定重定位细节的reloc_howto_type数组。

  3. 定义下面对应于特定目标的设置宏:

    #define TARGET_LITTLE_SYM 
    #define TARGET_LITTLE_NAME
       
    #define ELF_ARCH         
    #define ELF_MACHINE_CODE 
    #define ELF_MAXPAGESIZE  
    #define elf_symbol_leading_char 
    // .... 省略
    
  4. 此外,bfd目录中的archures.c, config.bfd, Makefile.am 和 target.c对于特定的修改也应更新。

操作码

opcodes目录至少应该有两个目标特定文件。

一个用于装配(assembling)目标指令,另一个用于拆卸(dis-assembling)目标指令。文件名称为:

  1. <target>-opc.c<target>-opc.h (header files are optional)

  2. <target>-dis.c<target>-dis.h (header files are optional)

<target>-dis.c文件包括用于打印反汇编指令的代码,以及用于适当匹配操作码和操作数的代码。

在opcodes目录中的configure.in, disassemble.c 和 Makefile,am文件也需要对它们进行特定的更改。

Include

include目录包含目标特定的头文件,通常位于文件格式特定的子目录中。操作码信息通常保存在操作码子目录中的目标特定文件中。

例如:

  include/elf/cr16.h
  include/opcode/cr16.h

Binutils

此目录不需要任何新的目标特定文件。但是configure.tgt, Makefile.am 和 readelf.c文件应更新所需的任何目标具体信息。

Gas

gas/config子目录包含汇编程序的目标特定文件。文件名称为:

tc-<target>.c
tc-<target>.h

上述文件应包括:

  • size of (即宏定义):
    • 寄存器
    • 指令(即最大 size)
    • 操作数
  • 操作数错误类型
  • 汇编代码中使用的注释字符
  • 汇编代码行中使用的行注释字符
  • 行分隔符
  • 其他省略,可参看binutils-porting-guide

在gas目录本身中configure.tgt 和 Makefile.am文件需要修改,以引用新的文件,并添加对新目标的支持。

ld

scripttempl/<format><target>.sc中为架构定义了默认的链接器脚本文件

emulparams/<format><target>.em 定义默认的模拟脚本文件。它包含定制链接器行为所需的任何函数。

emulparams/<format><target>.sh 中定义可用于修改默认链接器脚本文件的任何参数

在ld目录本身中config.tgt 文件需要更新以添加新的目标信息以及新的目标信息构建规则的Makefile.am文件。

Build and test

构建binutils工具

建立binutils工具需要以下步骤:

  1. 配置

    • 运行带有目标和前缀选项的配置脚本为例:

      src/configure --target=cr16-elf --prefix=/local/cr16-bintuils
      
      • target:想要构建binutils工具。
      • prefiex:构建binutils工具的安装位置/目录
  2. 构建

    • 运行“make”来为上述配置的目标构建binutils工具

      make all
      make install
      

测试binutils工具

使用binutils测试套件(如gas、binutls和ld测试套件)测试以上构建的工具。运行binutils测试套件需要DejaGNU包和DejaGNU环境变量。然后可以使用以下命令运行测试:

make check

上面的命令运行binutils、gas和链接器测试套件

通过下面的命令,用户可以分别运行binutils、gas和链接器测试套件:

make check-binutils
make check-gas
make check-ld
  • 在完成binutils测试运行后,结果的摘要将出现在binutils目录中的bintils.sum文件中。更详细的信息也可以在binutils/binutils.log文件中找到。

  • 对于gas测试套件,结果在gas/testsuite/gas.sum和gas/testsuite/gas.log文件中。

  • 对于链接器testsuite,它们位于ld/ld.sum和ld/ld.log文件中。

对于在主机和目标不同的环境中进行的最全面的测试,DejaGNU需要一些额外的配置。这可以通过设置DEJAGNU环境变量来引用合适的配置文件,并在目录~/boards中定义一个定制的board配置文件来实现。这些配置文件可用于指定合适的模拟器以及在运行测试时如何连接它。

文档

一些binutils子目录又有doc子目录。文档是用texinfo编写的,可以生成PDF、PostScript、HTML或info文件。文档不是用make all或make doc自动生成的。要创建文档,改变到个人文档目录需要使用make HTML, make PDF, make ps或make info。主要的文档是:

  • bfd/doc/bfd.texinfo:BFD手册
  • binutils/doc/binutils.texinfo:主要的binutils用户手册
  • ld/ld.texinfo:链接器用户手册
  • gas/doc/as.texinfo:汇编器用户手册

自动构建的例外是使用make install。这将为binutils/doc目录中的所有文档构建信息文件,并将它们安装在安装目录的info子目录中。