2017-06-25 116 views
2

如果CPU嘗試執行已使用某些CPU不支持的指令編譯的二進制文件,會發生什麼情況。我特別想知道一些在舊處理器上運行的新AVX指令。執行CPU不支持的指令時會發生什麼?

我假設這可以進行測試,友好的消息理論上可以顯示給用戶。據推測,大多數低級別的圖書館都會代您進行檢查。假設你沒有做這個檢查,你會期望發生什麼?您的流程會收到什麼信號?

+1

[信號'SIGILL'是什麼?](https://stackoverflow.com/q/7901867/608639)和朋友。據我所知,在所有Linux平臺上,包括i386,x86_64,ARM,Aarch32,Aarch64和MIPS都會引發SIGILL。 – jww

+0

*「大概最底層的圖書館會代您檢查。」*呃,我不這麼認爲。大多數使用潛在不受支持指令的低級庫在速度上高於一切。在調用低級代碼之前,高級代碼負責驗證這些指令是否受支持。在執行它們之前,使用'CPUID'指令(在大多數編譯器中作爲內部函數公開)來驗證是否支持所需的指令集,從而避免出現無效指令異常的風險。然後顯示友好的錯誤消息。 –

+1

停止並着火。 –

回答

6

新指令可以設計爲「傳統兼容」或不能。
對於前者類屬於指令像tzcntxacquire有產生老年架構有效指令編碼:tzcnt被編碼爲 rep bsfxacquire只是repne
語義當然不同。

第二類屬於大部分新指令,AVX就是一個流行的例子。
當CPU遇到無效的或保留的編碼它生成#UD(對於未定義)異常 - 這是中斷號6.

的Linux內核entry_64.S設置#UDIDT條目初:

idtentry invalid_op   do_invalid_op   has_error_code=0 

的入口點do_invalid_op,其與宏traps.c生成:

DO_ERROR(X86_TRAP_UD,  SIGILL, "invalid opcode",  invalid_op) 

DO_ERROR生成一個函數,該函數在同一個文件(here)中調用do_error_trap

do_traptraps.c force_sig_info中:

do_error_trap使用fill_trap_info(在同一個文件,here)創建包含Linux的信號的信息的siginfo_t結構:

case X86_TRAP_UD: 
    sicode = ILL_ILLOPN; 
    siaddr = uprobe_get_trap_addr(regs); 
    break; 

從那裏下面的調用發生signal.c specific_send_sig_info in signal.c

最終在調用違規流程的SIGILL的信號處理程序時達到高潮。


下面的程序是一個非常簡單的例子,其產生#UD

BITS 64 

GLOBAL _start 

SECTION .text 

_start: 

ud2 

我們可以使用strace來檢查通過運行程序接收到的信號

--- SIGILL {si_signo=SIGILL, si_code=ILL_ILLOPN, si_addr=0x400080} --- 
+++ killed by SIGILL +++ 

如預期。


作爲Cody Gray commented,圖書館通常不依靠SIGILL,相反,他們使用一個CPU dispatcher或檢查的指令的存在明確。

相關問題