当前位置:首页 > 智能硬件 > 智能硬件
[导读]对于c编译器,大家均有所了解。因此对于c编译器的基本知识,本文将不再介绍。本文中,将基于gcc c编译器,为大家讲解程序插装技术,以帮助大家更好理解c编译器的用处,并推动大家对于c编译器的学习进程。

对于c编译器,大家均有所了解。因此对于c编译器的基本知识,本文将不再介绍。本文中,将基于gcc c编译器,为大家讲解程序插装技术,以帮助大家更好理解c编译器的用处,并推动大家对于c编译器的学习进程。

一、引言

程序插装(Program Instrumentation)概念最先是由J.G.Huang教授提出,是借助往被测程序中插入操作(称为“探针”),以便获取程序的控制流和数据流信息,从而实现测试目的的方法。在软件动态测试中,程序插装是一种基本的测试手段,应用广泛,是覆盖率测试、软件故障注入和动态性能分析的基础技术。

GCC(GNU ComPIler Collection)是一个高度优化,高度可移植,广泛使用的编译系统。它能处理多种语言,包括C/C++、Fortran、Java和Pascal等多种语言前端,而且后端支持几乎所有的处理器结构。GCC作为源码开放的软件,人们可以自由修改和使用;加入插装模块后,在GCC所支持的语言中都可插入相应的测试代码(这里只介绍C语言的插装模块)。本文将详细叙述如何修改GCC,使其在编译每个C函数时,分别将各个形式参数连同该函数名传递给一个指定函数。该指定函数的返回值赋予原来的形式参数,从而可以人为控制被插装函数的每个参数实际值,进而完成各种规则下的测试。

二、GCC编译流程分析

编译器的工作是将源代码(通常使用高级语言编写)翻译成目标代码(通常是低级的目标代码或者机器语言)。在现代编译器的实现中,这个工作一般是分为两个阶段来实现的:

第一阶段,编译器的前端接收输入的源代码,经过词法、语法和语义分析等得到源程序的某种中间表示方式。

第二阶段,编译器的后端将前端处理生成的中间表示方式进行一些优化,并最终生成在目标机器上可运行的代码。

GCC编译器以一个函数为单位对经过预处理的输入源文件进行编译处理。根据GNU Bison(一个类似YACC但功能更强大的文法分析工具)生成的语法分析程序,前端完成语法、语义分析,建立语法树,并转换成中间代码。GCC内部使用了一种能对实际的体系结构做一种抽象的,与硬件平台无关的语言,这个中间语言就是RTL(Register Ttansfer Language)。通过修改源程序的RTL,可以改变、删除源程序,包括插入所需要的代码,由GCC后端处理并最终输出对应硬件平台的汇编码,源程序无需手工修改便可实现插装功能。

GCC的入口点main函数在文件main.c中。此函数非常简单,只有一条直接调用toplev_main函数的语句。toplev_main函数是在toplev.c文件中定义的,以下我们只关心与编译有关的源码,其他的暂时忽略。toplev_main中最重要的是调用了do_complile函数,这个函数从名字看就是做编译工作的;而在此之后,toplev_main函数就返回了。dD_compile函数也是在tokv.c中定义的,其中真正进行编译工作的是调用compilte_file函数。compik_file函数最终调用了一个钩子函数来分析(parse)整个输入文件:

(*lang_hooks.parse_file)(set_yydebug);

这里的lang_hooks是一个全局变量,不同语言的前端对此赋以不同的值。对C语言来说,这条语句相当于调用了c-opts.c中的c_common_parse_file函数。c_com-mon_parse_file中调用了c-parse.c中的c_parse_file函数;在此函数中又调用了同文件中的yyparse函数,该函数负责解析C语言源文件,并转化为特殊的语法树结构。该函数是GNU bison将YACC转变为C语言而自动生成的,所以这段代码阅读起来比较困难,但我们并不关心语法分析的细节。在完成函数体的分析后,利用已经建立的tree结构生成RTL,优化后最终输出汇编码;自此C函数的编译就算结束了,这些是由yyparse调用finish_function函数完成的。finish_function函数中最重要的函数是tree_rest_of_compilation(定义在tree_optimize.c中),它是真正实现上述功能的函数。为了说明它所做的具体事情,我们将该函数做了删减,保留了关键的地方。

将函数各个部分展开成RTL形式后,调用函数rest_of_comPIlation将RTL输出为汇编码。至此,得到了一张清晰的GCC编译时的函数调用路线,如表1所列。

以上便是小编此次带来的相关内容,希望大家通过本文可对gcc c编译器程序插装技术有所了解。最后,十分感谢大家的阅读。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

如果你是在Linux下做开发,你就必须知道Makefile是什么东西,如果不知道那就可以说你不是一个合格的Linux开发工程师,因为Makefile是必备的一项技能。那么,Makefile到底有什么作用呢?首先,gcc大...

关键字: Linux Makefile gcc

众所周知,LLVM的Clang C / C ++编译器比GCC提供更快的编译速度。 但是,新版本的GCC中的编译速度有所提高。

关键字: gcc Linux llvm

上篇文章中,小编对Turbo c编译器已做部分介绍。本文中,小编将对Turbo c编译器余下内容加以讲解。如果你对c编译器具有兴趣,不妨继续往下阅读哦。

关键字: c编译器 turbo 指数

为增进大家对c编译器的认识,本文将对Turbo C c编译器予以讲解。如果你对c编译器具有兴趣,不妨继续往下阅读哦。

关键字: c编译器 turbo 指数

本文中,小编将对c编译器和c编辑器的区别予以介绍。如果你对c编译器具有兴趣,不妨继续往下阅读哦。

关键字: c编译器 指数 c编辑器

最近发布的 GCC 10 编译器已对 C++20 的主要功能协程(Co-Routines)进行了初始支持,但是除非显式地开启该选项,否则并不会启用此功能。当 GCC 10 在 C++20 模式(std

关键字: gcc

许多朋友经常混淆c编译器和c编辑器,注意,c编译器的作用在于编译,而c编辑器在于编写代码。对于c编译器,小编曾带来诸多文章。但有网友提问,有没有较为推荐的c编译器。为解决大家的疑问,本文将对6款c编译器予以介绍,大家可以...

关键字: c编译器 指数 编译器

c编译器每天都在被使用,但对c编译器十分了解的人却不多,而对c编译器编译过程有所认知的朋友更是少之又少。在上篇文章中,小编对c编译器的工作过程有所讲解。本文中,为继续增进大家对c编译器的讲解,将对编译器工作过程的余下步骤...

关键字: c编译器 指数 编译器

c编译器的问世是程序界的里程碑之一,没有c编译器,c程序将无法运行。由此可见,c编译器尤为重要。为增进大家对c编译器的了解,本文将带来c编译器的通识篇,以使大家能够了解编译器的运行过程。此外,本文仅为上篇,剩余内容将在后...

关键字: c编译器 指数 编译器

对于c编译器,很多朋友均有所了解。往期文章中,小编为大家带来过诸多c编译器文章。在这篇c编译器相关文章中,小编将介绍如何基于SDCC c编译器开发微控制器。如果你对c编译器的应用同样存在兴趣,不妨继续往下阅读哦。

关键字: c编译器 sdcc 微控制器 指数
关闭