Các chỉ thị CFI trong Gnu Assembler (GAS) được sử dụng để làm gì?


118

Dường như có một lệnh .CFI sau mỗi dòng và cũng có nhiều biến thể của các ví dụ này .cfi_startproc, .cfi_endprocv.v. ở đây .

    .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

Tôi đã không có được mục đích của những điều này.


3
mô tả các cfihướng dẫn GNU AS ở đây
Paschalis

liên quan: Làm thế nào để loại bỏ tiếng ồn Tiếng Việt từ đầu ra lắp ráp GCC / clang? , nếu bạn chỉ muốn các hướng dẫn mà không có chỉ thị. Một cách hay là đặt mã của bạn lên gcc.godbolt.org để xem đầu ra asm được lọc đẹp từ các phiên bản khác nhau của các trình biên dịch khác nhau (bao gồm cả không phải x86), với tô sáng màu để khớp các dòng nguồn với các khối asm.
Peter Cordes

Câu trả lời:


70

Tôi có cảm giác nó là viết tắt của Thông tin khung cuộc gọi và là phần mở rộng GNU AS để quản lý các khung gọi. Từ DeveloperWorks :

Trên một số kiến ​​trúc, việc xử lý ngoại lệ phải được quản lý bằng các chỉ thị Thông tin khung gọi. Những chỉ thị này được sử dụng trong hội đồng để xử lý ngoại lệ trực tiếp. Các chỉ thị này có sẵn trên Linux trên POWER, nếu, vì bất kỳ lý do nào (ví dụ tính di động của cơ sở mã), thông tin xử lý ngoại lệ do GCC tạo ra là không đủ.

Có vẻ như những thứ này được tạo ra trên một số nền tảng tùy thuộc vào nhu cầu xử lý ngoại lệ.

Nếu bạn đang tìm cách vô hiệu hóa những điều này, xin vui lòng xem câu trả lời của David .


5
Ngoài ra, bạn có thể nói một từ về .LFB0, .LFB1, .LFE0, .LFE1
vuốt

@claws - Đó là những nhãn do trình biên dịch tạo ra (như bạn có thể thấy từ :). Xem stackoverflow.com/a/15285058/4294399
Tính toán

144

Để tắt những thứ này, hãy sử dụng tùy chọn gcc

-fno-asynchronous-unwind-tables

-fno-dwarf2-cfi-asm cũng có thể cần thiết


12
-fno-dwarf2-cfi-asmcó thể cần thiết cũng
technosaurus

Nếu bạn đang vô hiệu hóa nó cho đầu ra asm có thể đọc được của con người, hãy xem Làm thế nào để loại bỏ "tiếng ồn" khỏi đầu ra lắp ráp GCC / clang? cho các tùy chọn và thủ thuật hữu ích khác.
Peter Cordes

30

Các chỉ thị CFI được sử dụng để gỡ lỗi. Nó cho phép trình gỡ lỗi để thư giãn một ngăn xếp. Ví dụ: nếu thủ tục A gọi thủ tục B mà sau đó gọi một thủ tục chung C. Quy trình C thất bại. Bây giờ bạn muốn biết ai thực sự đã gọi C và sau đó bạn có thể muốn biết ai đã gọi B.

Trình gỡ lỗi có thể giải phóng ngăn xếp này bằng cách sử dụng con trỏ ngăn xếp (% rsp) và đăng ký% rbp, tuy nhiên nó cần biết cách tìm ra chúng. Đó là nơi các chỉ thị CFI ra đời.

movq    %rsp, %rbp
.cfi_def_cfa_register 6

vì vậy dòng cuối cùng ở đây nói với nó rằng "Địa chỉ khung cuộc gọi" hiện đang ở trong thanh ghi 6 (% rbp)


2
Nhưng việc xử lý ngoại lệ sử dụng cfi nên thường xuyên hơn là gỡ lỗi, tôi nghĩ vậy.
osgx

6
Trên thực tế CFA là viết tắt của "địa chỉ khung chính tắc". Xem ở đây .
Cameron


1
Các lệnh CFI cho phép giải nén ngăn xếp ngay cả đối với mã được biên dịch -fomit-frame-pointer, như là một thay thế cho RBP (được bật theo mặc định với gcc hoặc clang -O1và cao hơn). Nó được sử dụng bởi xử lý ngoại lệ C ++ cũng như trình gỡ lỗi / trình lược tả. Trong mã với các con trỏ khung RBP truyền thống, giá trị RBP hiện tại luôn trỏ đến một giá trị RBP đã lưu và chỉ vào điểm trước đó tạo thành một danh sách được liên kết. Không cần CFI trong trường hợp đó. (Mặc dù trong các chức năng sử dụng con trỏ khung, CFI cfa_register tránh cần thêm siêu dữ liệu cho mỗi thay đổi RSP, như bạn đang hiển thị.)
Peter Cordes

2

Để vô hiệu hóa những điều này, g ++ cần -fno-exceptionscùng với các đề cập trước đó -fno-asynchronous-unwind-tables, miễn là bạn không sử dụng ngoại lệ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.