GDB 源码分析 03:函数前导代码分析(下)

在上一次分析中,我们基本上通读了对前导代码分析实现通用的支持的代码,在这里,我们将针对多种不同架构的代码进行分析。

这篇文章将不可避免地要求对一些架构中汇编指令有一定的熟悉程度,但基本上只需要了解汇编指令的含义即可,可以参考相关的开发者指南。我们将首先从相对简单的 RISC-V 架构的分析开始。

阅读更多

GDB 源码分析 01:函数前导代码分析(上)

代码:gdb/prologue-value.hgdb/prologue-value.c

函数前导代码其实很简单也很固定,它主要就是进入一个函数时进行的代码操作,用来建立栈帧,并为临时变量开好空间。这里展示一个 x86 汇编的最简单情形:

1
2
3
push ebp
mov ebp, esp
sub esp, N

很简单,很友好,不是吗?

那么为什么要对这块代码进行重点分析呢?一方面,这是一个函数开头的部分,可以用来分析这个函数调用栈的情况,并分析这个函数所使用的临时变量地址;另一方面,虽然看起来这段代码很可爱,但是随着编译器的复杂化和在调度指令时日益激进的策略,它往往会变得面目全非。但无论如何,这段代码总归是相对简单的部分。

事实上,在现代的 gcc 编译器中往往会给出调用栈信息(call frame information, CFI),其中描述了如何寻找栈的基地址和存储的寄存器等信息,但是这些信息并不总是存在。如果它们不存在,我们就必须采用一些策略来试图解读这些信息。为了解读这些信息,我们就采用一种对指令“抽象解读”的策略,也就是下面将介绍的模糊计算策略。

阅读更多