1.3 GCC 工具

1.3.1 binutils 工具集

工具

描述

addr2line

给出一个可执行文件的内部地址,addr2line 使用文件中的调试信息将地址翻译成源代码文件名和行号。

ar

这是一个程序,可通过从文档中增加、删除和析取文件来维护库文件。通常使用该工具是为了创建和管理连接程序使用的目标库文档。

as

GNU 汇编器。实际上它是一族汇编器,因为它可以被编译或能够在各种不同平台上工作。

c++filt

程序接受被 C++编译程序转换过的名字(不是被重载的) ,而且将该名字翻译成初始形式。

elfedit

更新 ELF 文件的 ELF 头。

gprof

该程序会监督编译程序的执行过程,并报告程序中各个函数的运行时间,可以根据所提供的配置文件来优化程序。

ld

GNU 连接程序。该程序将目标文件的集合组合成可执行程序。

ld.bfd

到 ld 的硬链接。

libbfd

二进制文件描述器库。该程序是 binutils 包的一部分

libiberty

包含多个 GNU 程序会使用的途径,包括 getoptobstackstrerrorstrtol 和 strtoul。

libopcodes

一个库,用于处理 opcodes——处理器指令的 "可读文本" 版本;用于编制 objdump 这样的工具。

nlmconv

将可重定位的目标文件转换成 NetWare 可加载模块(NetWare Loadable Module,NLM) 。

nm

列出目标文件中定义的符号。

objcopy

将目标文件从一种二进制格式复制和翻译到另外一种。

objdump

显示一个或多个目标文件中保存的多种不同信息。

ranlib

创建和添加到 ar 文档的索引。该索引被 ld 使用来定位库中的模块。

readelf

从 ELF 格式的目标文件显示信息

size

列出目标文件中每个部分的名字和尺寸。

strings

浏览所有类型的文件,析取出用于显示的字符串。

strip

从目标文件或文档库中去掉符号表,以及其他调试所需的信息。

windres

Window 资源文件编译程序。

1.3.2 addr2line:地址翻译工具

addr2line用于得到程序指令地址所对应的函数,以及函数所在的源文件名和行号。

参照对应工具的man和info信息,可以查找到详细信息。或者运行相应的工具并指定--help参数,可以获得该工具的简单帮助信息。

用法:addr2line [选项] [地址]

将地址转换成文件名/行号对。

如果没有在命令行中给出地址,就从标准输入中读取它们

选项是:@<file> 读取选项从 <file>

选项

描述

-a

--addresses 显示地址

-b

--target=<bfdname> 设置二进位文件格式

-e

--exe=<executable><name> 设置输入文件名称(默认为 a.out)

-i

--inlines 解开内联函数

-j

--section=<name> 读取相对于段的偏移而非地址

-p

--pretty-print 让输出对人类更可读

-s

--basenames 去除目录名

-f

--functions 显示函数名

-C

--demangle[=style] 解码函数名

-h

--help 显示本帮助

测试代码:main.c

1

2

3

4

5

6

7

8

9

10

11

12

13

#include <stdio.h>

#include <stdlib.h>

void func(void)

{

printf("func() address is %p\n", func);

}

int main(int argc, char *argv[])

{

func();

return 0;

}

编译:gcc -g main.c -o main -Wall

执行:./main

根据地址找到对应的代码位置

1.3.3 ar:创建和管理连接程序使用的目标库文档

ar 命令的语法如下:ar [options] [positionname] [count] archive objectfile [objectfile ...]

  • options:选项标签,选项的字母表示之间没有空格,选项可通过(也可不通过)连字符来表达。
  • 可选的命令行项目 positionname 和 count 只有当用到了某些需要它们的选项时才会出现。
  • ar 命令的选项分为两类:命令行选项告诉 ar 应该采取什么样的操作(有效命令行选项中的一个) ,以及修改子(modifier) 选项指出如何执行该命令操作

指明操作的ar 选项:

选项

描述

d

从文档中删除模块 objectfiles。利用 v 修改子,列出的所有模块都要被删除

m

将模块移入文档内部。默认情况下,列举的所有 objectfiles 成员都会移到文档尾部。利用修改子 a、b 和 i 可将指定模块移到其他位置

p

将指定的目标文件 objectfiles 的二进制内容打印到标准输出上。如果没有指定目标文件objectfiles,就打印所有目标文件。修改子 v 会打印所有列在其内容之前的名字

q

将指定目标文件 objectfiles 快速附加到文档末尾,而不检查是否可以取代而不是一味添加。不会更新索引,因此 ranlib 必须在连接库之前使用

r

将指定目标文件 objectfiles 插入文档。如果指定的所有目标文件都已经在文档中了,就用新的替换老的。如果指定文档不存在,就会创建此文档。默认条件下,新的模块会添加到文件的末尾,但是修改子 a、b 或 i 可用来指定新模块的位置

t

显示一列文档文件的内容。修改子 v 会为该列表加上时间戳、所有者、组、以及每个模块的大小。如果没有指定目标文件 objectfiles,就会列出整个文档

x

将指定目标文件展开成正常的磁盘文件。如果没有指定目标文件,就会展开所有文件

修改子选项:

选项

描述

a

将新文件添加到命令行指定文件位置之后,该文件是作为位置文件的

b

将新文件添加到命令行指定文件位置之前,该文件是作为位置文件的。这和选项 i 一样

c

如果必要就创建文档。只要需要总会创建新的文档,但使用该选项会禁止警告消息

f

截断文档内的文件名。通常 ar 允许任意长度的文件名,可是这样会导致文档的创建过程在某些系统中不能相互兼容

i

立即将所有新文件添加到命令行指定的文件位置之前。这和选项 b 一样

N

当文档中存在多个指定的目标文件时,count 参数可用来当作指定目标文件的选择子(selector)

o

当文件是从文档中展开时,原始日期可以得到保留

s

即使没有改动文档,也会创建新的文档索引。在 ar 中会单独使用修改子,这和使用 ranlib 的结果一样

u

当文件加入文档时,该选项说明只有比文档中现有文件更新的文件才会被添加。该修改子只有和选项 r 在一起才有效

v

按照详细模式运行,在运行处理过程中显示附加信息

V

显示版本信息,然后退出

1.3.4 as:GNU汇编器

它是 GNU 汇编器,主要用来编译 GNU C 编译器 gcc 输出的汇编文件,它将汇编代码转换成二进制代码,并存放到一个 object 文件中,该目标文件将由连接器 ld 连接

  • as的内部预处理主要包括三个方面的工作
    • 调整和去除额外的间隔符,保留每行的关键字前的一个空格或者TAB,其他任意的间隔符都转换为一个空格。
    • 去除所有注释,代之以一个空格,或者新行的合适的数字。
    • 把字符常量转换成相应的数字值。
  • 它不能做宏处理和文件包含处理,如果需要用,可以交给 C 预处理器来处理

语法:as(选项)(参数)

常用选项如下:

选项

描述

-ac

忽略失败条件;

-ad

忽略调试指令;

-ah

包括高级源;

-al

包括装配;

-am

包括宏扩展;

-an

忽略形式处理;

-as

包括符号;

=file

设置列出文件的名字;

--alternate

以交互宏模式开始;

-f

跳过空白和注释预处理;

-g

产生调试信息;

-J

对于有符号溢出不显示警告信息;

-L

在符号表中保留本地符号;

-o

指定要生成的目标文件;

--statistics

打印汇编所用的最大空间和总时间。

例子:as -o main.o main.s –32,编译32位的汇编代码

1.3.5 c++filt:修复 C++ 和 Java 符号

主要是为了防止 C++ 和 Java 中的多个函数名重复产生的重载问题。由于每个重载函数都使用与原函数相同的名称,因此,支持函数重载的语言必须拥有一种机制,以区分同一个函数的许多重载版本。

c++filt 将每个输入的名称看成是改编后的名称,并设法确定用于生成该名称的编译器。

如果这个名称是一个合法的改编名称,那么,c++filt 就输出改编之前的名称; 如果c++filt无法识别一个改编名称,那它就按原样输出该名称。

不关注除 C 语言之外的语言,命令选项查看 man 手册

1.3.6 elfedit:检查或编辑 ELF 文件

elfedit 是一个用于检查或修改现有 ELF 目标文件内容的工具。可以访问目标文件中包含的大多数 ELF 数据,这些数据包括 ELF 头、节头表、程序头表、动态节、硬件和软件功能、字符串表和符号表。

elfedit 可以处理来自命令行(–e 选项)或标准输入的命令。如果标准输入是一个终端,elfedit 可提供终端编辑功能以及涵盖大量命令的命令补齐功能。ELF 对特殊整数值和位掩码使用许多标准符号名称。elfedit 可识别此类名称的最有可能的完整形式。在输入 elfedit 命令时,可以随时按 TAB 键,令 elfedit 显示用法消息以及当前光标处文本的任意已知完整形式。

elfedit 功能以模块形式组织。每个模块提供一组命令,这些命令针对相关功能。通过使用冒号 (:) 分隔符将模块和命令名称组合到一起(中间无空格)来指定命令。例如,dyn:runpath 指的是由 dyn 模块提供的 runpath 命令。模块名称必须是唯一的。给定模块中的命令名称在该模块中必须唯一,但可在多个模块中使用相同的命令名称。

某些模块将模块内的某个命令指定为该模块的缺省命令。用户只需指定模块名称,就可运行此命令。大多数 elfedit 模块均提供一个名为 dump 的命令,它针对模块涵盖的 ELF 文件部分生成的信息与 elfdump 实用程序所显示的信息相同。通常,模块会将 dump 指定为其缺省命令。

用于执行 elfedit 命令的语法在设计上采用类似 UNIX 命令行实用程序的语法,这样任何会使用 UNIX 命令行实用程序的人都可以方便地使用 elfedit 命令。该语法由空格分隔的标记组成:第一个标记是命令名称。选项(即以连字符 (-) 开头的参数)跟在命令后面。纯参数(操作数)跟在选项后面。一个给定的命令可以有 0 个或多个选项和操作数,但是如果它们同时存在,选项始终位于纯参数前面。可使用特殊选项 --(两个连字符)来限定选项的结尾。如果遇到此选项,其余所有参数均被视为纯参数,即使它们以 - 开头。

elfedit 标记中的字符的解释取决于所用的引用格式:

引用格式

描述

非引用

单引号 (') 或双引号 (") 外面的反斜杠 (\) 充当转义符。elfedit 发现反斜杠字符时会将其忽略,并按字面意思处理反斜杠后面的字符(即使它后面的字符为反斜杠)。此功能可用于在命令的字符串参数中插入一个空白字符,从而无需将一个字符串分为两个单独的标记。同样,它可用于插入一个引号或反斜杠作为文本字符。

单引号

在单引号 (') 中,空白字符不用于分隔标记,且会被解释为标记内部的文本字符。双引号 (") 和反斜杠 (\) 字符会被解释为文本字符,无特殊意义。

双引号

在双引号 (") 中,空白字符不用于分隔标记。单引号字符会被解释为文本,不具有引用功能。反斜杠 (\) 是一个转义字符,在字符串文本中,其作用与 C 编程语言中反斜杠的作用类似:

\a        警报(响铃)

\b        退格键

\f        换页符

\n        换行符

\r        回车

\t        水平制表符

\v        垂直制表符

\\        反斜杠

\'        单引号

\"        双引号

\ooo    八进制常量,其中 ooo 是 1 到 3 个八进制位 (0...7)

在反斜杠后面跟有任何其他字符,均会出错。

核心命令均属于一个名为 sys 的内部模块。所有其他模块均打包为可动态装入的可共享目标文件。当执行需要某个模块的命令时或者当执行 sys:load 命令时,elfedit 会按需装入模块。由于 sys 模块特殊的内置状态,而且其命令使用频繁,所以 elfedit 命令允许在不加 sys: 前缀的情况下指定 sys 模块中的命令,例如,使用 load 而非 sys:load。要访问任何其他模块中的命令,必须采用 module:cmd 完整格式指定。

elfedit 随以下标准模块一起提供:

模块

描述

cap

功能节

dyn

动态节

ehdr

ELF 头

reloc

重定位节

phdr

程序头数组

shdr

节头数组

str

字符串表节

sym

符号表节

syminfo

Syminfo 节

sys

内置的核心 elfedit 命令

命令用法:elfedit [-adr] [-e cmd] [-L path] [-o default | simple | num] [infile] [outfile]

选项

描述

–a

启用 autoprint 模式。启用 autoprint 后,elfedit 将输出修改 ELF 文件后所生成的修改值。此输出以当前输出样式显示,可使用 –o 选项更改此样式。缺省输出样式是 elfdump(1) 实用程序使用的样式。以交互方式使用 elfedit 时,autoprint 模式为缺省模式(当 stdin 和 stdout 为终端时)。因此,仅当在非交互式上下文中使用 elfedit 时,–a 选项才有意义。要在交互式会话中禁用 autoprint,请使用 elfedit 命令:> set a off

–d

如果已设置,此选项可使 elfedit 发布信息性消息,说明其内部操作和要处理的 ELF 目标文件的详细信息。这在需要深入了解所执行的操作时非常有用。

–e cmd

指定一个编辑命令。可以指定多个 –e 选项。如果在命令行上指定了多个编辑命令,elfedit 将在批处理模式下运行。打开文件后,elfedit 按给定的顺序执行每个命令,然后保存修改的文件,最后 elfedit 退出。从 shell 脚本和 makefile 执行简单操作时,批处理模式非常有用。

–L path

设置用于定位 elfedit 模块的缺省路径。本手册页的"模块搜索路径"部分介绍了各个模块。

–o default | simple | num

用于显示 ELF 数据的样式。此选项用于确立会话的当前样式。可在 elfedit 会话中更改此样式,方法是使用 set (sys:set) 命令或向会话中执行的各个命令提供 –o 选项。

default

缺省样式是以适合用户查看的格式显示输出。此样式与 elfdump 实用程序使用的样式类似。

num

整数值始终以整数格式显示。字符串显示为在内含的字符串表中定位所用的整数偏移量。

simple

显示 ELF 文件中的字符串时,仅显示字符串。如果可能,整数值显示为符号常量,否则以整数格式显示。不显示任何标题、头或其他补充输出。

–r

只读模式。输入文件以只读访问模式打开,编辑会话的结果不会保存。指定了 –r 时,elfedit 不允许使用 outfile 参数。如果不打算修改文件,强烈建议使用只读模式。除了提供额外保护以防止意外修改外,该选项还允许检查用户没有写入权限的文件。

操作数支持:

操作数

描述

infile

包含要处理的 ELF 目标文件的输入文件。

此文件可以为可执行文件 (ET_EXEC)、共享目标文件 (ET_DYN) 或可重定位目标文件 (ET_REL)。不直接支持归档文件。要编辑归档中的目标文件,必须提取目标文件,编辑副本,然后将其重新插入到该归档文件。

如果未提供 infile,elfedit 将在限定模式下运行,此模式仅允许执行 sys: 模块中的命令。此模式主要用于访问 help (sys:help) 命令提供的命令文档。

如果提供了 infile,但未给定任何 outfile,elfedit 将就地编辑文件并将结果写入同一文件,这会导致原始文件内容被覆盖。通常,不建议以此模式使用 elfedit,建议指定输出文件。生成的文件经过测试和验证后,可将其移动到原始文件所在的位置。

–r 选项可用于以只读访问模式打开 infile。在检查不希望修改的现有文件时,此选项非常有用。

outfile

输出文件。如果同时提供了 infile 和 outfile,infile 将以只读访问模式打开,修改的目标文件内容会写入到 outfile 中。

GCC编译器原理(一)------GCC 工具:addr2line、ar、as、c++filt和elfedit的更多相关文章

  1. GCC编译器原理(一)------交叉编译器制作和GCC组件及命令

    1.1 交叉编译器制作 默认安装的 GCC 编译系统所产生的代码适用于本机,即运行 GCC 的机器,但也可将 GCC 安装成能够生成其他的机器代码.安装一些必须的模块,就可产生多种目标机器代码,而且可 ...

  2. GCC编译器原理(一)04------GCC 工具:nlmconv、nm、objcopy、objdump和 ranlib

    1.3.13 nlmconv nlmconv 将可重定位的对象文件(Infile)转换为 NetWare 可加载模块(outfile),并可选择读取头文件信息获取 NLM 头信息. 选项,描述 -I ...

  3. GCC编译器原理(一)03------GCC 工具:gprof、ld、libbfd、libiberty 和libopcodes

    1.3.7 gprof:性能分析工具 参考文档:https://www.cnblogs.com/andashu/p/6378000.html gprof是GNU profile工具,可以运行于linu ...

  4. GCC编译器原理(一)05------GCC 工具:readelf、size、strings、strip和 windres

    1.3.18 readelf:elf 文件格式分析工具 这个工具和 objdump 命令提供的功能类似,但是它显示的信息更为具体,并且它不依赖 BFD 库( BFD 库是一个 GNU 项目,它的目标就 ...

  5. GCC编译器原理(三)------编译原理三:编译过程(3)---编译之汇编以及静态链接【2】

    4.1.2 符号解析与重定位 (1)重定位 在完成空间和地址的分配步骤之后,链接器就进入了符号解析和重定位的步骤,这是静态链接的核心部分. 先看看 a.o 的反汇编文件: objdump -d a.o ...

  6. GCC编译器原理(三)------编译原理三:编译过程(2-1)---编译之词法分析

    二.编译 引用文档:https://blog.csdn.net/chdhust/article/details/9040647 编译过程就是把预处理完的文件进行一系列词法分析.语法分析.语义分析及优化 ...

  7. GCC编译器原理(三)------编译原理三:编译过程---预处理

    Gcc的编译流程分为了四个步骤: 预处理,生成预编译文件(.文件):gcc –E hello.c –o hello.i 编译,生成汇编代码(.s文件):gcc –S hello.i –o hello. ...

  8. GCC编译器原理(二)------编译原理一:目标文件

    一.目标文件 在 UNIX® 和 Linux® 中,任何事物都是文件.UNIX 和 Linux 编程实际上是编写处理各种文件的代码.系统由许多类型的文件组成,但目标文件具有一种特殊的设计,提供了灵活和 ...

  9. GCC编译器原理(二)------编译原理一:ELF文件(3)

    4.5 String Table:字符串表 字符串表节区包含以 NULL( ASCII 码 0) 结尾的字符序列, 通常称为字符串. ELF 目标文件通常使用字符串来表示符号和节区名称. 对字符串的引 ...

随机推荐

  1. [ZJOI2016]小星星&[SHOI2016]黑暗前的幻想乡(容斥)

    这两道题思路比较像,所以把他们放到一块. [ZJOI2016]小星星 题目描述 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细线连着两颗小星星. ...

  2. centos7使用yum安装zabbix3.4

     应用环境: 关于ZABBIX: zabbix一开强大的开源监控工具,同类型还有nagios,ganglia,cacti等监控工具,通过过去一年Google趋势就知道zabbix全球的相对热度:   ...

  3. Codeforces 1051E. Vasya and Big Integers

    题意:给你N个点M条边,M-N<=20,有1e5个询问,询问两点的最短距离.保证没有自环和重边. 题解:连题目都在提示你这个20很有用,所以如果是颗树的话那任意两点的最短距离就是求一下lca搞一 ...

  4. Jupyter Notebook 编辑器美化

    汇总系列:https://www.cnblogs.com/dunitian/p/4822808.html#ai 2018-10-10新增Linux样式路径: Logo: ~/anaconda3/lib ...

  5. pycharm安装TensorFlow

    一.首先说下我在安装TensorFlow的过程中遇到的坑: 1.python的版本是3.5的版本,因为TensorFlow好像只支持到3.5现在.然后python需要安装64位的安装包,如果安装的是3 ...

  6. 浅析 @PathVariable 和 @RequestParam(转发,非原创)

    首先 上两个地址:地址①http://localhost:8989/SSSP/emps?pageNo=2地址②http://localhost:8989/SSSP/emp/7如果想获取地址①中的 pa ...

  7. 一张图看懂JVM

    https://mp.weixin.qq.com/s?__biz=MzAxNjk4ODE4OQ==&mid=2247484432&idx=1&sn=381c98c49ffb81 ...

  8. 区块链使用Java,以太坊 Ethereum, web3j, Spring Boot

    Blockchain is one of the buzzwords in IT world during some last months. This term is related to cryp ...

  9. java 子类强转父类 父类强转子类

    Java 继承 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为. Java 子类强转父类 父类引用指向子类对象: jav ...

  10. Vim在图形环境下全屏产生黑边

    在终端中运行Vim或运行GVim都会遇到这个问题,当窗口全屏时,左右和底部可能会出现边框,这个边框在终端中的Vim表现为Terminal的背景颜色.下图为SpaceVim+Neovim+Termina ...