[英]Is there a way to disable inline assembler in GCC?
我正在為LeetCode,Codeforces等編程競賽開發一個在線評判系統。對於大多數編程競賽,在C / C ++中不允許使用內聯匯編程序,所以我想對我的系統添加相同的限制。
我想在編譯包含內聯匯編程序的C / C ++程序時讓GCC和G ++產生錯誤,這樣任何包含內聯匯編程序的代碼都會導致編譯錯誤。
有沒有辦法實現這一目標? 我應該將一些命令行參數傳遞給GCC / G ++嗎?
注意:禁用內聯匯編程序只是為了遵守規則,而不是出於安全考慮。
是的,有幾種方法。
要在編譯階段執行此操作,請使用參數-fno-asm
。 但是,請記住,這只會影響asm
而不會影響__asm__
。
文檔:
-fno-asm
不要將“
asm
”,“inline
”或“typeof
”識別為關鍵字,以便代碼可以將這些單詞用作標識符。 您可以使用關鍵字“__asm__
”,“__inline__
”和“__typeof__
”代替。-ansi
暗示-fno-asm
。在C ++中,此開關僅影響“
typeof
”關鍵字,因為“asm
”和“inline
”是標准關鍵字。 您可能希望使用-fno-gnu-keywords
標志,它具有相同的效果。 在C99模式(-std=c99
或-std=gnu99
)中,此開關僅影響“asm
”和“typeof
”關鍵字,因為“inline
”是ISO C99中的標准關鍵字。
您可以使用參數-Dasm=error -D__asm__=error
請注意,此構造是通用的。 它的作用是創建宏。 它的工作方式非常像#define
。 文件說:
-D name=definition
定義的內容被標記化並處理,就好像它們在#define指令的翻譯階段3中出現一樣。 特別是,定義將被嵌入的換行符截斷。
...
所以它只是將asm
或__asm__
出現更改為error
。 這是在預處理器階段完成的。 您不必使用error
。 只需挑選任何無法編譯的東西。
通過使用宏來編譯階段解決它的方法,如zwol的注釋中所示 ,您可以使用-D'asm(...)=_Static_assert(0,"inline assembly not allowed")'
。 如果存在名為error
的標識符,這也將解決該問題。
注意:此方法需要-std=c11
或更高版本。
另一種可能解決問題的方法是在編譯之前在源樹的根目錄中執行grep
:
grep -nr "asm"
這也會捕獲__asm__
但它可能會給出誤報,例如你有一個包含子串"asm"
的字符串文字,標識符或注釋。 但在您的情況下,您可以通過禁止在源代碼中的任何位置出現該字符串來解決此問題。 只需改變規則。
請注意,禁用程序集可能會導致其他問題。 例如,我無法使用此選項使用stdio.h
。 系統頭文件通常包含內聯匯編代碼。
可以將字符串作為機器代碼執行。 請參閱此答案以獲取示例: https : //stackoverflow.com/a/18477070/6699433
上面鏈接中的一段代碼:
/* our machine code */
char code[] = {0x55,0x48,0x89,0xe5,0x89,0x7d,0xfc,0x48,
0x89,0x75,0xf0,0xb8,0x2a,0x00,0x00,0x00,0xc9,0xc3,0x00};
/* copy code to executable buffer */
void *buf = mmap (0,sizeof(code),PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON,-1,0);
memcpy (buf, code, sizeof(code));
/* run code */
int i = ((int (*) (void))buf)();
上面的代碼只是為了快速了解如何欺騙OP規定的規則。 它並不是一個如何在現實中實際執行它的好例子。 此外,代碼不是我的。 它只是我提供的鏈接的簡短代碼報價。 如果您有關於如何改進它的想法,那么請評論4pie0:s原始帖子。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.