There seem to be a .CFI directive after every line and also there are wide varities of these ex.,.cfi_startproc
, .cfi_endproc
etc.. more here.
.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
I didn't get the purpose of these.
To disable these, use the gcc option
-fno-asynchronous-unwind-tables
-fno-dwarf2-cfi-asm
may be needed also.
I've got a feeling it stands for Call Frame Information and is a GNU AS extension to manage call frames. From DeveloperWorks:
On some architectures, exception handling must be managed with Call Frame Information directives. These directives are used in the assembly to direct exception handling. These directives are available on Linux on POWER, if, for any reason (portability of the code base, for example), the GCC generated exception handling information is not sufficient.
It looks like these are generated on some platforms depending on need for exception handling.
If you are looking to disable these, please see David's answer.
:
). See stackoverflow.com/a/15285058/4294399
The CFI directives are used for debugging. It allows the debugger to unwind a stack. For example: if procedure A calls procedure B which then calls a common procedure C. Procedure C fails. You now want to know who actually called C and then you may want to know who called B.
A debugger can unwind this stack by using the stack pointer (%rsp) and register %rbp, however it needs to know how to find them. That is where the CFI directives come in.
movq %rsp, %rbp
.cfi_def_cfa_register 6
so the last line here tell it that the "Call frame address" is now in register 6 (%rbp)
-fomit-frame-pointer
, as an alternative to RBP (which is on by default with gcc or clang -O1
and higher). It's used by C++ exception handling as well as debuggers / profilers. In code with traditional RBP frame pointers, the current RBP value always points at a saved RBP value, and that points at the previous one forming a linked list. There's no need for CFI in that case. (Although in functions that use a frame pointer, CFI cfa_register avoids needing more metadata for every RSP change, like you're showing.)
To disable these, g++ needs -fno-exceptions
along with the previously mentioned -fno-asynchronous-unwind-tables
, provided that you don't use exceptions.
Well,it just stands for control flow integrity. They are essentially information items passed to debuggers and other tools to describe the intended flow of the program.
endbr
. I don't think any control-flow integrity stuff uses the stack-unwind metadata generated by .cfi_*
directives.
.eh_frame
unwind info these directives create. See also What are CFI directives in Gnu Assembler (GAS) used for? / What do the CFI directives mean? (and some more questions) (Unfortunately the GAS manual section for them doesn't expand the acronym)
Success story sharing
-fno-dwarf2-cfi-asm
may be needed also