gcc源代码分析的方法【总结】

看gcc-1.40有段时间了,14年左右看了一段时间,15年左右看了一段时间。

现在可以说基本上明白了gcc的大部分代码。

如果说能快速的明白其中的原理,总结我看代码的方法捷径我列举以下几条。

第一,gcc版本低,这是成功的前提,也是一条捷径。

第二,分析最基本的hello.c文件,就一条函数调用,但是已经足够。

第三,发现了debug_rtx ()函数和debug_tree ()函数。这两个函数可以说是看懂gcc的唯一的两把钥匙!

第四,思路正确,expand_call()如何产生各种rtx的?这个思路借助debug_rtx ()函数。

expand_call ()函数的参数也就是用到的tree如何得到的?

expand_expr_stmt()函数的参数是如何得到的?

形象的可以说tree的形成可以看成套娃模型,

最基本的小的套娃最先形成,然后各种操作tree的函数一层层的套上去,

我们debug_tree ()函数的print_node ()函数的作用则是把套娃分开!

大体的思路就是:就是如何从源代码到tree的,上面的可以说如何从tree到rtx的!

关注的是和printf相关的tree如何形成的?和"Hello,world!\n"相关的tree如何形成的?

第五,对语法分析bison的原理很熟悉。

判断一个人是否懂gcc可以分3个层次:

初级的:hello.c到hello.i到hello.s到hello.o到a.out

中级的:gcc前端,从源代码到rtl中间语言,后端从rtl到汇编语言。

高级的:c文件源代码到tree,tree到rtx,rtx到汇编语言。

时间: 2024-08-13 02:08:43

gcc源代码分析的方法【总结】的相关文章

gcc源代码分析,debug_tree()函数,又一利器啊

gcc源代码分析,debug_rtx()函数,利器啊 print-tree.c #include "config.h" #include "tree.h" #include <stdio.h> /* Names of tree components. Used for printing out the tree and error messages.  */ #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,

gcc源代码分析,build_pointer_type ()函数分析

function = build (ADDR_EXPR, build_pointer_type (TREE_TYPE (function)), function); 继续分析上篇文章的这句. /* Constructors for pointer, array and function types. (RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are constructed by language-dependent code, not he

gcc源代码分析,expand_call()函数和printf(&quot;Hello, world!\n&quot;);的关系

expand_call()函数在expr.c文件中. 下面是expand_call()函数的主要调试结果,记录之. 主要是加入了debug_tree()函数和debug_rtx()函数. debug_tree()函数加入到了expand_expr()函数的开始. debug_rtx()函数加入到了gen_rtx()函数的结束处. emit_call_1()函数是何时调用的也能看出.emit_call_insn()是何时调用的也能看出. 主要的调试目的是expand_call()函数是如何生成rt

gcc 源代码分析-前端篇3

3. GCC怎样函表示一个函数 对c语言来说.函数是其核心,全部的东西都在环绕着函数在转.对于一个函数来说.它基本的一些特性例如以下: 1. 有一个返回值,在这里我们没有把返回值的函数觉得它的返回值是void; 2. 它有传入的參数.而这个參数个数不确定.可多可少,也能够没有: 3. 它有一个函数名称,这个名称具有唯一性,也就是同一个project,不能有名称一样的多个函数. 4. 它有函数运行体: 对于函数来说,还是通过struct tree_decl结构来表示: filename:函数所在文

gcc源代码分析,expand_call ()函数分析第五部分,store_one_arg ()函数

本文主要是分析store_one_arg ()函数和expand_expr ()的关系来说明如何处理 函数的参数.printf("Hello, world!\n");中的"Hello, world!\n"这个字符串常量的! expand_call () 函数中的相关代码: if (args[i].reg == 0 && TYPE_SIZE (TREE_TYPE (args[i].tree_value)) != 0) { fprintf(stderr,

gcc源代码分析,finish_decl ()函数和push_parm_decl ()函数分析

parms: parm { push_parm_decl ($1); } /* This is what appears inside the parens in a function declarator. Is value is represented in the format that grokdeclarator expects.  */ parmlist_2:  /* empty */ { $$ = get_parm_info (0); } | parms { $$ = get_pa

gcc源代码分析,在expand_call ()函数 和expand_expr_stmt ()函数的开始处加入debug_tree ()函数

对于expand_call函数来说最主要的参数就是exp这个tree树, 打印出来之后我们终于看到了printf和Hello,world! expand_call <call_expr 840f0 type <integer_type 824d0 int permanent SI size <integer_cst 8254c literal permanent 4 align 32 size_unit 8 sep_unit 32 symtab 0 sep <integer_cst

gcc源代码分析,debug_tree()函数的利用

tree.def 中第0x3d个元素是 DEFTREECODE (CALL_EXPR, "call_expr", "e", 3) 下面是debug_tree()函数的结果,可以看出expand_expr()函数到gen_rtx()函数的调用过程! expand_expr code = 3d <call_expr 840f0 type <integer_type 824d0 int permanent SI size <integer_cst 825

gcc源代码分析gen_push_operand ()函数和emit_move_insn ()函数

如何生成下面红色的3个指令? 和gen_push_operand ()函数和emit_move_insn ()函数有关,他们都在expand_call()函数中被调用. 具体位置: rtx addr; #ifdef PUSH_ROUNDING if (args_addr == 0) addr = gen_push_operand (); else #endif if (GET_CODE (args_so_far) == CONST_INT) addr = memory_address (mode