Gnu 汇编程序(GAS)中的 CFI 指令用于什么?

似乎有一个。CFI 指令后的每一行,也有这些广泛的品种,如 .cfi_startproc.cfi_endproc等。这里更多.

    .file   "temp.c"
.text
.globl main
.type   main, @function
main:
.LFB0:
.cfi_startproc
pushq   %rbp
.cfi_def_cfa_offset 16
movq    %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl    $0, %eax
leave
ret
.cfi_endproc
.LFE0:
.size   main, .-main
.globl func
.type   func, @function
func:
.LFB1:
.cfi_startproc
pushq   %rbp
.cfi_def_cfa_offset 16
movq    %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl    %edi, -4(%rbp)
movl    %esi, %eax
movb    %al, -8(%rbp)
leave
ret
.cfi_endproc
.LFE1:
.size   func, .-func
.ident  "GCC: (Ubuntu 4.4.1-4ubuntu9) 4.4.1"
.section    .note.GNU-stack,"",@progbits

我不明白这些东西的用途。

59199 次浏览

我有一种感觉,它代表 呼叫帧信息,是一个 GNU AS 扩展,用于管理呼叫帧:

在某些架构上,例外 处理必须与呼叫管理 框架信息指令,这些 指令在程序集中用于 直接异常处理 指令在 Linux 上可用 如果由于任何原因(可移植性) (例如,代码基的)、 GCC 生成的异常处理 资料不足。

看起来这些是根据异常处理的需要在某些平台上生成的。

如果您正在寻找禁用这些,请参阅 David 的回答

要禁用它们,请使用 gcc 选项

-fno-asynchronous-unwind-tables

可能还需要 -fno-dwarf2-cfi-asm

CFI 指令用于调试。它允许调试器释放堆栈。例如: 如果过程 A 调用过程 B,然后过程 B 调用公共过程 C。过程 C 失败。你现在想知道谁真正调用了 C 然后你可能想知道谁调用了 B。

调试器可以通过使用堆栈指针(% rsp)和注册% rbp 来解除此堆栈,但是它需要知道如何找到它们。这就是 CFI 指令的用武之地。

movq    %rsp, %rbp
.cfi_def_cfa_register 6

所以这里的最后一行告诉它“调用帧地址”现在在寄存器6(% rbp)中

要禁用它们,g + + 需要 -fno-exceptions和前面提到的 -fno-asynchronous-unwind-tables,前提是不使用异常。

就是 控制流完整性控制流完整性的缩写。 它们本质上是传递的信息项 调试器和其他工具来描述程序的预期流程。