2017-04-25 53 views
4

我正在編寫一個LLVM通道,它需要將傳遞給聲明函數的值傳出並打印出來。請注意聲明的函數正在LLVM IR中調用。LLVM在運行時獲取聲明函數的參數值

我寫了一個模塊傳遞來遍歷程序中的所有指令。一個片段來獲得被調用函數的參數的指令如下:

for (auto &B: F){ 
       for (auto &I: B){ 
        if (auto *InvokeI = dyn_cast <InvokeInst>(&I)) { 
         if (InvokeI->getCalledFunction()->getName().str() == "function_name") { 
          errs() << "===\n"; 
          errs() << *(InvokeI->getOperand(0)) <<"\n"; 
          errs() << *(InvokeI->getOperand(1)) <<"\n"; 
          errs() << *(InvokeI->getOperand(2)) <<"\n"; 
         } 
        } 
       } 

} 

但是,如果LLVM IR爲獲取調用的函數看起來是這樣的:

invoke void @function_name(i8* %4, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #5 
      to label %36 unwind label %6 

然後我上面的代碼片段輸出:

%4 = call i8* @__cxa_allocate_exception(i64 4) #2 
i8* bitcast (i8** @_ZTIi to i8*) 
i8* null 

而不是輸出函數調用期間傳遞的實際值。

我的問題是我們如何獲得運行期間傳遞的值。有沒有辦法可以將函數體添加到不返回任何內容的聲明函數?

任何幫助表示讚賞,感謝

+0

這就是產生異常的'C++ abi'調用。你能提供一個原始源代碼的最小片段,它能在pastebin或類似的地方產生IR(如果它在這裏太大)? – compor

+0

其實函數名是'__cxa_throw',產生這個IR的代碼行基本上就是'thow 1',我試圖去捕捉那個1或者其他任何會拋出的東西 – Nik391

+0

它有點迷失方向,因爲你已經留下了指向C++ [ABI](https://itanium-cxx-abi.github.io/cxx-abi/)的東西。 – compor

回答

1

異常變化,以便在程序執行過程中提供自己的設備程序的控制流。作爲一個運行時構造,它操縱程序堆棧,執行清理等,它依靠runtime system支持來履行其職責。出於這個原因,存在一個ABI standard,它規定了如何在實現中實施這些操作的各個方面。說了這麼多,如果你深入瞭解這個規範,你會發現__cxa_throw的參數是它是什麼引發的。看看here。以上片段包含指向分配的異常位置的指針以及類型信息。事實上,如果您在_ZTIi上應用c++filt,則會得到typeinfo for int

換句話說,由語句throw 1引發的整數1被包裝到要在運行時期間訪問的異常對象(即存儲器位置)中。關於這些值的存儲位置和方式的更多具體細節在前述規範中。我沒有看到靜態訪問特定值的直接方式,因爲哪些異常可能是活動的,並且確切的內容依賴於執行期間程序的狀態(例如調用堆棧等)。

+0

不錯,感謝輸入,是的,如果我在編譯時試圖捕獲異常(這顯然我現在正在執行),實際上它會變得複雜,但是使用JIT會使運行時grep throw參數變得更有意義,這再次我不太確定如何使用它:) – Nik391