Apa arahan CFI di Gnu Assembler (GAS) digunakan untuk?

118

Tampaknya ada arahan .CFI setelah setiap baris dan juga ada variasi luas dari contoh. .cfi_startproc,, .cfi_endprocDll .. lebih lanjut di sini .

    .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

Saya tidak mengerti tujuan ini.

cakar
sumber
3
deskripsi cfiinstruksi di GNU AS sini
Paschalis
terkait: Bagaimana cara menghilangkan "noise" dari keluaran perakitan GCC / clang? , jika Anda hanya menginginkan instruksi tanpa arahan. Cara yang bagus adalah dengan meletakkan kode Anda di gcc.godbolt.org untuk melihat keluaran asm yang difilter dari berbagai versi dari berbagai kompiler (termasuk non-x86), dengan penyorotan warna untuk mencocokkan baris sumber dengan blok asm.
Peter Cordes

Jawaban:

70

Saya merasa itu singkatan dari Informasi Bingkai Panggilan dan merupakan ekstensi GNU AS untuk mengelola bingkai panggilan. Dari DeveloperWorks :

Pada beberapa arsitektur, penanganan pengecualian harus dikelola dengan arahan Informasi Bingkai Panggilan. Arahan ini digunakan dalam rakitan untuk mengarahkan penanganan pengecualian. Arahan ini tersedia di Linux pada POWER, jika, karena alasan apa pun (portabilitas basis kode, misalnya), informasi penanganan pengecualian yang dihasilkan GCC tidak cukup.

Sepertinya ini dibuat pada beberapa platform bergantung pada kebutuhan penanganan pengecualian.

Jika Anda ingin menonaktifkan ini, silakan lihat jawaban David .

Komunitas
sumber
5
Anda juga dapat mengatakan sepatah kata pun tentang .LFB0, .LFB1, .LFE0, .LFE1
claws
@claws - Itu adalah label yang dihasilkan kompilator (seperti yang Anda lihat dari :). Lihat stackoverflow.com/a/15285058/4294399
Calculuswhiz
144

Untuk menonaktifkannya, gunakan opsi gcc

-fno-asynchronous-unwind-tables

-fno-dwarf2-cfi-asm mungkin dibutuhkan juga.

David Watson
sumber
12
-fno-dwarf2-cfi-asmmungkin diperlukan juga
technosaurus
Jika Anda menonaktifkannya untuk output asm yang dapat dibaca manusia, lihat Bagaimana cara menghilangkan "noise" dari output perakitan GCC / clang? untuk opsi dan trik berguna lainnya.
Peter Cordes
30

Arahan CFI digunakan untuk debugging. Ini memungkinkan debugger untuk melepas tumpukan. Misalnya: jika prosedur A memanggil prosedur B yang kemudian memanggil prosedur umum C. Prosedur C gagal. Sekarang Anda ingin tahu siapa sebenarnya yang menelepon C dan kemudian Anda mungkin ingin tahu siapa yang menelepon B.

Debugger dapat melepas tumpukan ini dengan menggunakan penunjuk tumpukan (% rsp) dan mendaftarkan% rbp, namun ia perlu mengetahui cara menemukannya. Di situlah arahan CFI masuk.

movq    %rsp, %rbp
.cfi_def_cfa_register 6

jadi baris terakhir di sini mengatakan bahwa "Alamat bingkai panggilan" sekarang ada di register 6 (% rbp)

Graham Stott
sumber
2
Tetapi penanganan pengecualian penggunaan cfi harus lebih sering daripada debugging, saya kira.
osgx
6
Sebenarnya CFA adalah singkatan dari "alamat bingkai kanonik". Lihat disini .
Cameron
1
Arahan CFI memungkinkan pelepasan tumpukan bahkan untuk kode yang dikompilasi -fomit-frame-pointer, sebagai alternatif untuk RBP (yang aktif secara default dengan gcc atau clang -O1dan yang lebih tinggi). Ini digunakan oleh penanganan pengecualian C ++ serta debugger / profiler. Dalam kode dengan penunjuk bingkai RBP tradisional, nilai RBP saat ini selalu menunjuk pada nilai RBP yang disimpan, dan yang menunjuk ke yang sebelumnya membentuk daftar tertaut. Tidak perlu CFI dalam kasus itu. (Meskipun dalam fungsi yang menggunakan penunjuk bingkai, CFI cfa_register menghindari kebutuhan lebih banyak metadata untuk setiap perubahan RSP, seperti yang Anda tunjukkan.)
Peter Cordes
2

Untuk menonaktifkannya, g ++ perlu -fno-exceptionsbersama dengan yang disebutkan sebelumnya -fno-asynchronous-unwind-tables, asalkan Anda tidak menggunakan pengecualian.

iw4h
sumber