GCC编译器原理(一)------GCC 工具:addr2line、ar、as、c++filt和elfedit

发布时间:2024-08-26  

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 程序会使用的途径,包括 getopt、obstack、strerror、strtol 和 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 [选项] [地址]

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

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

选项是:@ 读取选项从

选项

描述

-a

--addresses 显示地址

-b

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

-e

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

-i

--inlines 解开内联函数

-j

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

-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

#include

 

void func(void)

{

printf('func() address is %pn', 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

功能节

文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>