# 汇编文件中的CFI指令
Date: 2019-07-09


这篇文章[CFI directives in assembly file](https://www.imperialviolet.org/2017/01/18/cfi.html) (18 Jan 2017)，   是出自google 工程师[Adam Langley](https://github.com/agl)

* * *

#    问题提出：

- ###      函数调用栈
    

```
:                :
| caller's stack | 
+----------------+ <----$rsp value before CALL
| return address |
+----------------+ <----$rsp at function entry
| caller's rbp   | 
+----------------+ <----$rbp always points here
| callee's stack | 

```

函数调用中 调用call指令时将call指令的下一条指令 return address 入栈， 其中return address存放在RIP寄存器中也就是将 RIP入栈，之后进入子函数后会将父函数的栈基地址入栈，其中父函数的栈基地保存在RBP寄存器中。

- ###      函数栈调用框架：
    

push rbp

mov rbp, rsp

                   .... (子函数处理部分)

mov rsp, rbp

                    pop bp

（leave）

- ###      问题在于
    

1）对于只有少量代码的函数；

         2)  如果使用  -O   -fomit-frame-pointer， 选项 会将省略rbp部分

* * *

# 解决方案：

新增额外的调试表， Call Frame Information (CFI)， 汇编指令以          .cfi\_开头。

CFA， Canonical Frame Address， 它的值为RSP value before CALL

```
:                :
|    whatever    | <--- CFA   caller's stack
+----------------+
| Saved RIP      |   
+----------------+
| caller’s RBP   | <--- %rsp == CFA - 16
+----------------+
|                |
+----------------+            callee's local variables

```

CFI设计上就是存储一个（寄存器，偏移）的键值对。

- ###      CFI函数栈调用框架：
    

 .cfi\_startproc

.cfi\_def\_cfa rsp，8

push rbp

.cfi\_def\_cfa rsp, 16

mov rbp, rsp

.cfi\_def\_cfa rbp, 16

....

pop rbp

.cfi\_def\_cfa rsp, 8

ret

.cfi\_endproc

- ###      CFI的CIE和FDE
    

CIE（Common Information Entry）公共条目信息

FDE（Frame Description Entry）函数中的CFI指令

- ###       CFI指令优化
    

更新偏移量，更新寄存器：

**.cfi\_def\_cfa\_offset，.cfi\_def\_cfa\_register**

使用相对值更新偏移量：

**.cfi\_adjust\_cfa\_offset**

- ###       保存寄存器
    

指示寄存器保存在堆栈中

                   **.cfi\_offset**

- ###       CFI表达式
    

.**cfi\_escape**

允许用户向展开信息添加任意字节。 可以使用它来添加特定于操作系统的CFI操作码，或者GAS尚不支持的通用CFI操作码。

- ###       CFI注册号
    

| Register number | x86-64 | x86 | ARM |
| --- | --- | --- | --- |
| 0 | RAX | EAX | r0 |
| 1 | RDX | ECX | r1 |
| 2 | RCX | EDX | r2 |
| 3 | RBX | EBX | r3 |
| 4 | RSI | ESP | r4 |
| 5 | RDI | EBP | r5 |
| 6 | RBP | ESI | r6 |
| 7 | RSP | EDI | r7 |
| 8 | R8 |  | r8 |
| 9 | R9 |  | r9 |
| 10 | R10 |  | r10 |
| 11 | R11 |  | r11 |
| 12 | R12 |  | r12 |
| 13 | R13 |  | r13 |
| 14 | R14 |  | r14 |
| 15 | R15 |  | r15 |
| 16 | RIP |  |

