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

Кажется, что после каждой строки стоит директива .CFI, а также существует множество вариантов таких, например, _ 1_, .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

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


person claws    schedule 27.03.2010    source источник
comment
описание cfi инструкций GNU AS здесь   -  person Paschalis    schedule 26.04.2015
comment
связанные: Как удалить «шум» из вывода сборки GCC / clang ?, если вам нужны инструкции без директив. Хороший способ - поместить свой код на gcc.godbolt.org, чтобы увидеть красивый отфильтрованный вывод asm из различных версий. различных компиляторов (в том числе не x86), с выделением цвета для соответствия исходным строкам с блоками asm.   -  person Peter Cordes    schedule 16.10.2017


Ответы (4)


У меня такое чувство, что он обозначает информацию о кадре вызова и является расширением GNU AS для управлять кадрами вызовов. Из DeveloperWorks:

На некоторых архитектурах обработкой исключений необходимо управлять с помощью директив Call Frame Information. Эти директивы используются в сборке для непосредственной обработки исключений. Эти директивы доступны в Linux на POWER, если по какой-либо причине (например, переносимость базы кода) созданной GCC информации об обработке исключений недостаточно.

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

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

person Community    schedule 27.03.2010
comment
Также можете сказать пару слов о .LFB0, .LFB1, .LFE0, .LFE1 - person claws; 27.03.2010
comment
@claws - это метки, созданные компилятором (как вы можете видеть из :). См. stackoverflow.com/a/15285058/4294399 - person Calculuswhiz; 23.12.2019

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

-fno-asynchronous-unwind-tables

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

person David Watson    schedule 15.04.2013
comment
-fno-dwarf2-cfi-asm может также понадобиться - person technosaurus; 11.03.2016
comment
Если вы отключаете его для удобочитаемого вывода asm, см. Как удалить шум из вывода сборки GCC / clang?, чтобы узнать о других полезных параметрах и трюки. - person Peter Cordes; 11.01.2020

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

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

movq    %rsp, %rbp
.cfi_def_cfa_register 6

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

person Graham Stott    schedule 08.05.2014
comment
Но, я думаю, использование cfi для обработки исключений должно быть более частым, чем отладка. - person osgx; 09.05.2014
comment
Фактически CFA означает канонический адрес кадра. См. здесь. - person Cameron; 03.06.2014
comment
Директивы CFI позволяют раскручивать стек даже для кода, скомпилированного с -fomit-frame-pointer, в качестве альтернативы RBP (которая по умолчанию включена с gcc или clang -O1 и выше). Он используется обработкой исключений C ++, а также отладчиками / профилировщиками. В коде с традиционными указателями кадров RBP текущее значение RBP всегда указывает на сохраненное значение RBP, а это указывает на предыдущее, формируя связанный список. В этом случае нет необходимости в CFI. (Хотя в функциях, использующих указатель кадра, CFI cfa_register позволяет избежать необходимости в дополнительных метаданных для каждого изменения RSP, как вы показываете.) - person Peter Cordes; 11.01.2020

Чтобы отключить их, g ++ требуется -fno-exceptions вместе с ранее упомянутым -fno-asynchronous-unwind-tables, при условии, что вы не используете исключения.

person iw4h    schedule 04.05.2020