Для чего используются директивы CFI в GNU Assembler (GAS)?

кажется, есть .Директива CFI после каждой строки, а также существуют широкие вариации этих ex.,.cfi_startproc , .cfi_endproc etc.. здесь.

    .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    , %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

Я не понял цель этих.

3 ответов


У меня такое чувство, что это означает Информация О Кадре Вызова и является расширением GNU для управления фреймами вызовов. От DeveloperWorks:

на некоторых архитектурах, исключение обработка должна управляться с помощью Call Сформулируйте информационные директивы. Эти директивы используются в сборке прямая обработка исключений. Эти директивы доступны в Linux on Мощность, если по какой-либо причине (переносимость базы кода, например), Обработка исключений, генерируемых GCC информации недостаточно.

похоже, они создаются на некоторых платформах в зависимости от необходимости обработки исключений.

Если вы хотите отключить их, см. Дэвид.


чтобы отключить их, используйте опцию gcc

-fno-asynchronous-unwind-tables

примечание, Я знаю, что это действительно старый поток, но это лучший результат в google для cfi_startproc, поэтому многие люди, вероятно, приходят сюда, чтобы отключить этот вывод.


-fno-dwarf2-cfi-asm может понадобиться также.


директивы CFI используются для отладки. Это позволяет отладчику разматывать стек. Например: если процедура A вызывает процедуру B, которая затем вызывает общую процедуру C. процедура C терпит неудачу. Теперь вы хотите знать, кто на самом деле вызвал C, а затем вы можете узнать, кто вызвал B.

отладчик может размотать этот стек с помощью указателя стека (%rsp) и зарегистрировать %rbp, однако он должен знать, как их найти. Вот где вступают директивы CFI.

movq    %rsp, %rbp
.cfi_def_cfa_register 6

Итак, последняя строка здесь говорит ему, что" адрес кадра вызова " теперь находится в регистре 6 (%rbp)