自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(54)
  • 收藏
  • 关注

原创 AArch64中va_list/va_start/va_arg/...的实现

一、背景[3]1. 可变参函数可变参函数指的是一个可以接受可变个参数的函数, 调用此函数时只有caller知道为此函数传入了多少个参数, 可变参函数callee只知道caller最少传入了多少个参数:callee中可以确定的参数称为命名参数(Named arguments) callee中不确定的参数称为匿名参数(Anonymous arguments) 对于可变参函数(callee), 其需要:在其函数栈中预留空间存储所有可能的匿名寄存器参数(否则由于不确定传入了多少个寄存器参数,不.

2022-04-04 23:03:39 3131 1

原创 AArch64函数栈的分配,指令生成与GCC实现(下)

上一篇AArch64函数栈的分配,指令生成与GCC实现(上)_ashimida@的博客-CSDN博客主要说明原理,本篇主要介绍gcc中的实现.一、函数栈中的位置标记 gcc编译过程中会为当前函数布局函数栈,函数栈中的每一个元素位置最终都会对应当基于硬件寄存器sp或fp的偏移,但在编译过程中这些偏移不是一次性确定的。gcc在编译过程中内部会使用一些虚拟寄存器/伪寄存器作为标记位来代表函数栈中的各个位置,这些标记位最终被转换为sp/fp + offset并在最终输出的汇编代码中不可见,但这些标记...

2022-04-04 22:42:59 3238

原创 AArch64函数栈的分配,指令生成与GCC实现(上)

一、术语定义 为便于理解,本文中后续术语含义解释如下:首地址: 一个变量/内存的首地址指的是此变量/内存最低位的地址 尾地址: 一个变量/内存的尾地址指的是此变量/内存最高地址(+1), 如变量存储空间为[0x0, 0x10), 则此变量首地址为0x0, 尾地址为0x10 GPR/FPR: AArch64中的通用寄存器(R0-R30)后面称为GPR(General Purpose Register); 浮点寄存器称为FPR(Floating Point Register)二、AArch64函.

2022-04-04 22:20:12 4984

原创 LKDTM 内核测试框架初探

lkdtm(Linux Kernel Dump Test Module)[1] 是一个测试内核功能的内核模块, 其在用户态提供几个接口以方便用户测试系统中如RODATA,CFI等功能是否正常运行; 其在用户态同时还有一个测试框架支持,此框架可以自动从dmesg中获取测试结果(日志)并比对测试是否通过。注: 后续内容基于 linux 5.15一、内核部分 lkdtm的内核部分主要包含各个内核功能的测试用例以及用户态接口的定义, 内核部分的所有代码都在 ./drivers/misc/lkdtm...

2022-03-08 20:03:00 6205 1

原创 GCC源码分析—shrink-wrapping

一、shrink-wrapping基本概念 pro/epilogue是函数开始/结束时编译器为其插入的指令序列, shrink-warpping是针对pro/epilogue插入位置的优化,包括两个步骤:1. 将pro/epilogue收缩到其实际需要的当前函数最小cfg子集中(此过程是在try_shrink_wrapping函数中完成的,后续称之为shrink-wrapping): pro/epilogue未必总是要发送到函数的开始和结束的,比如函数的某个流程中可能没有使用pro/ep...

2022-02-15 23:06:39 1566

原创 linux中的信号处理与SROP

一、基本概念 信号是事件发生时对进程的通知机制,其与中断类似,在到达时都会打断程序的正常执行流程。一个进程(若具有权限则)可以向另一个进程或向自身发送信号,其可以作为一种同步技术或进程间通信的原始形式。发往进程的诸多信号通常都源于内核,引发内核为进程产生信号的事件包括:硬件异常: 如用户态的访问异常/除零异常等,其首先都是由硬件捕获并通知内核的,再由内核通过信号传递给用户态。 用户输入的中断字符: 如ctrl-c, ctrl-z。 软件事件的发生: 如针对文件描述符的输出变为有效,终端大小调整.

2022-01-17 21:02:48 3759

原创 C++异常处理源码与安全性分析

C++异常处理需要DWARF的支持,其业界实际标准是 IA-64 C++ABI[1],本文主要描述整个异常处理的流程以及在libgcc中的实现.关于基于DWARF的栈回溯可参考 [2], 关于C++异常处理其他分析可参考[3-8]。一、异常处理代码举例 先以一个简单的C++程序为例:1 #include <stdio.h>2 #include <stdlib.h>34 class x {5 public:6 x(voi...

2021-12-10 21:56:22 4868 3

原创 AARCH64平台的栈回溯

一、术语解释:1.栈顶/栈底[1]: 栈中最后一个push,第一个被pop的位置是栈顶;栈中最后一个被pop,且pop后当前栈为空的位置是栈底;2.Current Function Frame Address[2]: 当前函数栈帧,在aarch64中是当前函数执行完prologue后的栈顶地址, 其可以通过__builtin_frame_address(0)函数获取.3.Canonical Frame Address(CFA)[3]:标准/规范栈帧地址,在aarch64中是当前...

2021-12-08 23:02:17 3971 1

原创 linux 内核安全增强(一)— stack canary

一、背景知识 ——aarch64的函数栈1. 栈生长方向与push/pop操作 栈是一种运算受限的线性表,入栈的一端为栈顶,另一端则为栈底,其生长方向和操作顺序理论上没有限定.而在aarch64平台上:栈是向低地址方向增长的(STACK_GROWS_DOWNWARD) 栈的PUSH/POP通常要先移动SP: PUSH操作为PRE_DEC,即 PUSH操作为 sp = sp -4; store; POP操作为 POST_INC,即POP操作为 read; sp=sp+4; ...

2021-09-15 23:11:35 5687

原创 GCC源码分析(十七) — rtl expand之后

ps: 这是源码分析系列最后一篇文章, 从<GCC源码分析(一) — 输入参数解析>到本文只是大体介绍了整个cc1编译的基本流程, 而实际上其中的细节十分复杂,尤其各个优化的pass更是gcc的精髓,因笔者了解有限,故这些内容在此系列中尚未涉及,后续有机会再加以补充. 由前可知,函数expand过程中执行了all_passes链表中的所有pass,其中pass_expand负责将gimple指令序列expand为rtl指令序列, pass_expand是一级pass中的倒数第二个,...

2021-08-31 23:39:37 1203 5

原创 GCC源码分析(十六) — gimple转RTL(pass_expand)(下)

上接 <GCC源码分析(十五) — gimple转RTL(pass_expand)(上)>一、pass_expand的基本流程二、pass_expand-局部,临时变量的展开与空间分配三、pass_expand-caller的参数传入和callee的参数接收四、pass_expand-gimple指令序列的展开五、pass_expand-init_block和exit_block的展开六、pass_expand-边指令的插入和硬件寄存器初值的保存四、pass_expa

2021-08-31 22:18:57 762

原创 GCC源码分析(十五) — gimple转RTL(pass_expand)(上)

由前可知,函数的expand(cgraph_node::expand)过程实际上是执行了all_passes中的所有passes,这些pass中:首先执行了一系列的GIMPLE_PASS(如优化) 然后通过pass "expand"将gimple指令序列转化为rtl指令序列 之后执行了一系列RTL_PASS 最终通过RTL_PASS "final"将函数的RTX指令序列输出为汇编代码而本文主要记录在pass "expand"中是如何将gimple指令序列转化为rtl指令序列的....

2021-08-31 22:08:25 1274 1

原创 GCC源码分析(十四) — rtx结构体,指令与栈分配

一、rtx表达式 RTL(Register Transfer Language)全称叫寄存器传输语言,其采用类似LISP语言的列表形式描述了每一条指令的语义动作.RTL语言中最基础的数据结构体就是RTX(struct rtx_def),类似于树节点(tree)在AST中的作用,RTX(rtx_def)表达式节点是RTL语言中最基本的数据类型(RTX 是 RTLeXpression). 在gcc中,rtx结构体实际上是一个指向rtx_def结构体的指针,其类似AST中树节点(tree)是用来...

2021-08-30 23:54:06 1931

原创 GCC源码分析(十三) — 机器描述文件

在gcc中,各个平台都有自己的机器描述文件,机器描述文件主要包括两种:${target}.[md]:在aarch64平台为 ./config/aarch64/aarch64.md文件,此文件中主要记录的是aarch64平台的指令模板,此模板用来决定最终RTL是如何生成汇编代码的. ${target}.[ch]:在aarch64平台中为 ./config/aarch64/aarch64.h, ./config/aarch64/aarch64.c 两个文件.除了RTL=>汇编代码的指令...

2021-08-30 23:18:00 2982

原创 GCC源码分析(十二) — gimplify之后的基本流程

一、gimplify之后 gimplify之后的所有流程主要都是在函数 symbol_table::compile中完成的,此过程中除了IPA_PASS的执行外,还完成了:gimple=>rtl的转换,以及最终rtl=>汇编代码的输出:void symbol_table::finalize_compilation_unit (void){ ...... current_function_decl = NULL; /* 全局的 cfun, current_functi..

2021-08-29 23:40:41 804

原创 GCC源码分析(十一) — 函数节点的gimple低端化

一、gimple低端化 在gimple高端化时已经说过,整个编译单元所有外部声明的AST树节点生成完毕后会遍历符号表中的所有符号节点进行分析,而对于函数节点最终会执行到 cgraph_node::analyze对其进行gimple高端化和gimple低端化分析,gimple高端化的分析是通过函数gimplify_function_tree(decl)来完成的,而同样是在此流程中,gimple低端化则是通过一系列pass的执行完成的,代码如下:void cgraph_node::analyze (.

2021-08-29 23:26:25 895

原创 GCC源码分析(十) — 函数节点的gimple高端化

一、gimple高端化 前面提到整个编译单元所有外部声明的AST树节点生成完毕后会遍历符号表中的所有符号节点进行分析,对于函数节点最终会执行到 cgraph_node::analyze对其进行gimple高端化和低端化分析,其中gimple高端化是通过函数gimplify_function_tree(decl)来完成的,此函数用来分析一个具体的函数声明节点,其代码大体如下:/* 此函数负责整个gimple高端化,其创建了一个gbind节点,其中: .body记录当前函数形参和函.

2021-08-29 22:38:45 1240

原创 GCC源码分析(九) — gcc全局符号表与符号的分析(gimplify)

一、全局符号表 在gcc中有一个全局变量symbol_table *symtab; 此变量是用来记录整个编译过程中产生的所有函数和符号的, symbol_table类的关键元素记录如下:class symbol_table{public: friend class symtab_node; friend class cgraph_node; friend class cgraph_edge; int cgraph_count; /* 记录当前全局符号表中的函数...

2021-08-29 13:22:56 2975

原创 GCC源码分析(八) — 语法/语义分析之声明与函数定义的解析

一、概述 由前可知, c_parser_declaration_or_fndef负责对声明和函数定义的解析, 对于声明的解析其整体流程是:解析声明说明符(c_parser_declspecs) 解析出第一个声明符(c_parser_declarator) 根据声明说明符 +声明符为声明构建声明节点(XXX_DECL),并将新创建的声明绑定到当前scope(start_decl) 若下一个符号是等号(=)则解析此声明符的初值(c_parser_initializer); 不论是否有=,当前声..

2021-08-29 13:11:04 1183 1

原创 GCC源码分析(七) — 语法/语义分析之声明符解析(下)

在<GCC源码分析(五) — 语法/语义分析之声明符解析(上)>中已经大体介绍了声明符的解析流程,其中没有完成的一部分就是参数列表的解析,也就是下面产生式中的 parameter-type-list的解析: declarator: pointer[opt] direct-declarator direct-declarator: identifier T4 (attributes[opt] ...

2021-08-28 23:24:20 645 1

原创 GCC源码分析(六) — 符号绑定,作用域与block树节点

gcc中的符号绑定(c_binding)作用于(scope)和block树节点,根据c语言语法可知在不同的作用于中是可以对标识符重新声明的:int x;void fun(){int x;} 如上的定义中函数func内部的x和全局变量x是两个不同的声明,但在gcc中二者的标识符实际上都是x. 在gcc源码中相同字符串的标识符节点是全局唯一的(只有一个), 因为仅仅在词法和语法层面是没法区分出相同字符串的不同含义的. 而在解析到源码不同位置时则需要区分出一个标识符到...

2021-08-28 22:59:12 895

原创 GCC源码分析(五) — 语法/语义分析之声明符解析(上)

c_parser_declaration_or_fndef在解析完声明说明符之后接着要解析的就是声明符,对于函数和声明来说,虽然产生式不一样但这一步基本是一样的(除了断言在之前已经处理过了),函数定义和声明的组成都是 "声明说明符声明符 ... "开头的,所以在声明说明符解析完毕后不论是函数还是声明的解析,下一步都是要解析声明符,而声明符的解析函数是:c_parser_declaration_or_fndef => c_parser_declarator 声明符实际上指的是如具体...

2021-08-28 22:23:37 712 3

原创 GCC源码分析(四) — 语法/语义分析之声明说明符的解析

一、GCC中的语法/语义分析 在gcc中词法分析是作为接口函数供语法分析调用的, 每当语法分析需要一个新的语法符号时其内部则会调用词法分析接口来获取一个新的token. 语法分析 = >语义分析后会将源代码转换成一个一个AST树节点, 之后此AST树节点即可代表整个源码中的所有内容了, 在gcc中函数c_common_parse_file则负责语法分析直到AST树结点的生成:/*toplev::main=> do_compile => compile...

2021-08-28 11:22:17 2366

原创 GCC源码分析(三) — 词法符号转语法符号

语法分析要解决的主要问题是对词法分析得到的词法符号序列进行语法的推导,如果推到成功则源代码就是满足语法规范的源代码。 常见的语法分析工具包括Yacc, Bison等,早期的GCC中使用Yacc及Bison进行C语言的语法分析,而在较高的版本中不再使用二者,而是使用gcc/c-parser.c中定义的专门函数完成c语言语法分析。 C语言发展至今,其语法经历了多次修订,包含多个版本,gcc中均予以支持, 总体来讲GCC对C语言的语法分析采用一种【自顶向下】的语法推导过程,由于部分推导...

2021-08-27 00:18:12 897

原创 GCC源码分析(二) — 词法分析

GCC的词法分析是在伴随语法分析完成的,当语法分析过程中找不到下一个token时,就会调用词法分析来解析后续的token。词法分析的代码在./gcc/c-family目录;而C语言语法分析的目录在./gcc/c目录下,词法分析是给所有C家族的语言共用的。GCC的词法分析的主要代码是从cc1(如./gcc/c-family/c-lex.c) => libcpp(如./gcc/libcpp/lex.c)中的,对于cc1来说这些代码都编译进其二进制了。 lex是LEXical compi...

2021-08-27 00:06:44 3012 2

原创 GCC源码分析(一) — 输入参数解析

只以编译阶段为例的话,gcc的参数解析分为两部分: 一部分是参数从命令行到gcc 一部分是参数从gcc到最终的编译程序cc1 1.从命令行到gcc 编译出来的gcc二进制程序实际上只是起到一个桩代码的作用,或者说只是一个编译的驱动,其内部实际上是要分别调用cc1,as,collect来进行编译,汇编与连接。gcc的基本流程如下图: gcc在解析了输入参数后,会为每一个输入文件启动一次cc1来做具体的编译,而cc1一次只能处理一个源码的编译,如果输入多...

2021-08-26 23:48:02 4904 10

原创 ELF文件中的各个节区

ELF节区信息概述: 节区名 节区说明 备注 .rodata1 和rodata类似,只存放只读数据 .comment 存放编译器版本信息,如字符串 "GCC:(GNU)4.2.0" .debug 存放调试信息 .shstrtab ..

2021-08-25 00:40:06 6406 1

原创 OP-TEE 编译流程

一、概述:1. OPTEE中的编译目标: OPTEE中需要被编译的目标分为3类:optee core:这里是optee的内核代码(运行在Secure EL1,对应目标为core) optee SDK:分为32/64位, 用来编译用户态TA的开发环境(对应目标为ta_arm32/ta_arm64) optee DTA: DTA(动态TA)也就是optee的用户态TA,其是借助opteeSDK编译的,与前两者编译是分开的(DTA运行在Secure EL0)2. DTA与PTA: ...

2021-08-23 23:26:05 2953 2

原创 再谈内核模块加载(三)—模块加载流程(下)

上接<再谈内核模块加载(二)—模块加载流程(上)>9.检查是否有同名模块已加载或正在加载err = add_unformed_module(mod);if (err)goto free_module;unformed是指加载到一半(也就是执行完当前函数),但还没有完全加载好的模块,此函数根据this_module.name检测当前系统里是否有同名模块:如果有同名模块但状态是正在执行module_init或unformed...

2021-08-19 23:56:06 1087 3

原创 再谈内核模块加载(二)—模块加载流程(上)

内核模块加载一共有两个syscall入口,分别为: * sys_init_module: 用户态传入包含模块代码的内存地址 * sys_finit_module: 用户态传入模块二进制的文件句柄fd 除了以上区别外,sys_fini_module接口相对更加灵活,其可以传入额外的flag来忽略模块版本信息和CRC以强制加载。二者最终都直接 return load_module函数,真正的模块加载是在load_module函数中完成的,其声明如下:static int load_mod...

2021-08-19 23:39:46 3450

原创 再谈内核模块加载(一)—背景知识

注: 之前的分析可参考 <内核模块的加载>在内核模块代码分析前,先简单介绍一下相关背景知识:1.内核模块的编译分为两个阶段,可分别称为stage1和stage2:stage1主要负责将模块源码(*.c)编译为对应的目标(x.o)文件 stage2主要负责对每个模块生成一个.mod.c文件,其中记录了ko所需要的其他信息,将其编译为.mod.o,最终同模块的x.o共同链接(ld -r)为一个目标文件,这个目标文件即为最终的可加载模块(x.ko) 其中stage2是个批.....

2021-08-19 23:15:31 2566

原创 Kbuild系统源码分析(五)—模块的编译流程

模块的编译流程在<Kbuild系统源码分析(二)—./Makefile>等文章中已有提及,这里主要梳理思路并记录之前分析中没有记录的一些细节,这里仅以arm64平台内部模块的编译,目标为modules(编译所有模块),CONFIG_MODULES=y,且CONFIG_MODVERSIONS=y的情况为例,后面提及的模块默认指的是这种情况下的模块. 模块的编译规则如下:modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) mo...

2021-08-18 23:09:05 3608 1

原创 Kbuild系统源码分析(三)—./scripts/Makefile.lib

./scripts/Makefile.lib是被include使用的,在Kbuild系统中只在两个脚本中包含了此文件,分别是:./scripts/Makefile.build./scripts/Makefile.modpost 在使用此文件之前通常会先include某个源码目录下的Makefile(见Makefile.build/Makefile.modpos代码),而Kbuild子目录中的Makefile中通常会指定如obj-m/obj-y等一些编译目标,此库函数首先会处理这些目标...

2021-08-17 23:39:16 919

原创 Kbuild系统源码分析(四)—./scripts/Makefile.build

./scripts/Makefile.build是通过make -f 而不是在Makefile中include使用的,其本身就是一个make的起始脚本 ./scripts/Makefile.build在内核主要通过一个变量定义的方式使用,此变量定义在Kbuild.include中,所有include此文件的make脚本均可以使用此变量:./scripts/Kbuild.includebuild := -f $(srctree)/scripts/Makefile.build obj 此脚...

2021-08-17 23:28:28 1873

原创 Kbuild系统源码分析(二)—./Makefile

上接 <Kbuild系统源码分析(一)—./Makefile>5.对非xxx_config目标的编译5.1:设置./Makefile的默认目标 ./Makefile的开头可知,其默认的编译目标是_all,之前的处理流程中处理了对混合目标,xxx_config等编译的情况,而大部分情况都是走到这里,这里要先设置make的默认目标,在整个./Makefile中,_all的编译仅在这里唯一设置了一次,根据当前是否是编译外部模块,_all中的默认目标有所区别: * 如果编译的是外部模块,那么..

2021-08-16 23:40:25 1806

原创 Kbuild系统源码分析(一)—./Makefile

linux内核的Kbuid系统实际上就是make & makefile的一种应用,其起始于内核根目录的./Makefile; 文档记录在内核./Documentation/Kbuild目录下,代码解析如下:1. ./Makefile文件入口1.1:内核版本定义VERSION = 5PATCHLEVEL = 2SUBLEVEL = 5EXTRAVERSION =NAME = Bobtail Squid1.2:默认目标定义## _all是个伪目标,每次运行make ...

2021-08-16 23:09:31 2331

翻译 Android平台安全模型(The Android Platform Security Model)

摘要 Android是部署最广泛的终端用户操作系统,其覆盖的用例包括: 通信,导航,媒体消费,娱乐,财务,健康以及传感器,执行器,摄像头或麦克风,其基础安全模型需要在各种情况下解决许多实际的威胁。 Android的安全模型模型需要在终端用户的安全性,隐私性,可用性,及在资源紧张的硬件配置下保证应用开发和系统性能之间取得平衡。 虽然很多设计原则都隐含在了整个系统架构,访问控制机制和漏洞缓解技术中,但Android的安全模型之前从未正式发布过,本文的目的就是为了讨论此抽象模型。 基于威胁模型的定...

2021-08-10 22:32:07 2233 1

翻译 Safe and Efficient Implementation of a Security System on ARM using Intra-level Privilege Separation

内容摘要: 此文中作者介绍了ARM64中一种同特权级下(EL1/2/3)下系统自隔离的方法——Hilps, 此方法和之前学术界的SKEE[5]效果类似,但实现方法不同. Hilps是针对AARCH64平台的,可以实现同特权级(EL1/2/3)系统自保护的安全特性,其将同特权级(如kernel在EL1)分为Inner/Outer mode两个模式,其中:Outer mode是正常系统(内核)运行的环境 Innermode则相对具有更高的特权, Innermode会保护系统中所有的页表...

2021-08-05 00:09:20 424

原创 静态单赋值(二)—gcc中的SSA化算法

一、基本概念[1] 许多数据流分析需要寻找表达式中每个定值变量的使用点,或者每个使用变量的定值点. 定值-使用链表(def-use chain)是一种能够高效获取这些信息的数据结构: 对于流图中的每条语句,编译器能够保存两个由指针组成的列表: * 其中一个列表中的指针指向在该语句中定值的变量的所有使用点 * 另一个列表中的指针指向该语句中所使用变量的所有定值点 通过这个方法编译器能够快速地从使用跳到定值, 从定值跳到使用. 对定值-使用链思想的一种改进是静态...

2021-08-02 23:40:59 1447

原创 静态单赋值(一)—gcc中的支配树

一、需要了解的基本概念在gcc优化的过程中,不论是循环的优化还是数据流分析,支配树在其中都起到至关重要的作用: *对于循环来说,支配树对找出代码中的循环非常有用 *对数据流分析来说,支配树对计算SSA_NAME中的phi函数插入点十分重要支配树中的主要概念包括: 1)必经结点(Dominator,又称支配结点):如果从(如函数的)起始节点S0到结点n的所有有效路径都经过结点d,那么结点d则成为结点n的必经结点,同时每一个结点都是自己的必经结点简单的说,必经...

2021-08-02 23:25:39 1360 1

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除