2012-07-04 19 views
19

我一直在試圖找到OCaml調用約定,以便我可以手動解釋gdb無法解析的堆棧跟蹤。不幸的是,除了一般的觀察外,似乎從來沒有人用英文寫下過。例如,人們會評論OCaml在寄存器中傳遞許多參數的博客。 (如果有英文文檔,鏈接將不勝感激。)OCaml調用約定:這是一個精確的總結嗎?

所以我一直試圖從ocamlopt源頭中解開它。任何人都可以確認這些猜測的準確性嗎?

而且,如果我對正在傳入寄存器的前十個參數是正確的,那麼通常不可能將參數恢復到函數調用?在C中,參數仍然會被推到堆棧的某個地方,如果只是我回到正確的框架。在OCaml中,被調用者似乎可以自由地摧毀他們的調用者的論點。


寄存器分配(從/asmcomp/amd64/proc.ml

對於調用到OCaml的功能,

  • 第一10個整數和指針參數被在寄存器RAX,RBX,RDI,RSI傳遞,rdx,rcx,r8,r9,r10和r11
  • 前10個浮點參數傳遞到寄存器xmm0 - xmm9
  • 將其他參數壓入堆棧(最左邊的第一個?),魚漂和整數和指針混合
  • 陷阱指針(見下文例外)中R14
  • 的分配指針(據推測爲如本blog post描述的次要堆被傳遞)中R15
  • 的被傳遞如果返回值是一個整數或指針,則返回rax;如果是浮點數,返回值返回xmm0
  • 所有寄存器都是調用者保存的?

對於調用到C函數,標準AMD64 C約定用於:

  • 前六個整數和指針參數在RDI,RSI,RDX,RCS,R8和R9
  • 傳遞
  • 前八個浮動參數在XMM0通過 - XMM7
  • 附加參數被壓入堆棧
  • 返回值是在RAX傳遞迴或XMM0
  • 寄存器RBX,RBP,和R 12 - R 15是被調用者保存

返回地址(從/asmcomp/amd64/emit.mlp

返回地址被第一指針與推入呼叫幀中,根據amd64 C約定。 (我猜ret指令假設這個佈局。)

例外(從/asmcomp/linearize.ml

代碼try (...body...) with (...handler...); (...rest...)被線性化這樣的:

Lsetuptrap .body 
(...handler...) 
Lbranch .join 
Llabel .body 
Lpushtrap 
(...body...) 
Lpoptrap 
Llabel .join 
(...rest...) 

和然後被髮射作爲這樣裝配在右側(目的地):

call .body 
(...handler...) 
jmp .join 
.body: 
pushq %r14 
movq %rsp, %r14 
(...body...) 
popq %r14 
addq %rsp, 8 
.join: 
(...rest...) 

身體某處,有一個線性化的操作碼Lraise這是精確組裝發出:

movq %r14, %rsp 
popq %r14 
ret 

這真的很整潔!我們不是創建setjmp/longjmp業務,而是創建一個虛擬框架,其返回地址是異常處理程序,其唯一本地是前一個虛擬框架。 /asmcomp/amd64/proc.ml有一個註釋,稱$ r14爲「陷阱指針」,所以我將這個僞幀稱爲陷阱幀。當我們想要引發異常時,我們將堆棧指針設置爲最近的陷阱幀,在此之前將陷阱指針設置爲陷阱幀,然後「返回」到異常處理程序中。我敢打賭,如果異常處理程序不能處理這個異常,它只是重新評估它。

異常在%eax中。

回答

6

這是一個比問題更多的答案!關於這個話題我知道的一點是,我通過查看源代碼來學習,就像你一樣,所以不要指望進一步的精確度比你的帖子更具權威性。

是的,我認爲OCaml只使用調用者保存寄存器的專用調用約定。這種選擇的好處是它簡化了尾部呼叫:當您跳過尾部呼叫¹時,您不必溢出或重新加載任何寄存器。

¹:對於非自尾調用,這隻適用於沒有太多參數的情況,因此我們不需要泄漏。如果需要堆棧分配,則該呼叫將變成非尾部呼叫。

請注意,調用約定仍然強烈依賴於目標體系結構。例如,在x86上,當寄存器耗盡時以及溢出之前使用少量全局變量來保留尾部調用。

我還同意「最左邊先在」:參數,以便通過在calling_conventions遍歷proc.ml,存儲在偏置以便通過slot_offsetemit.mlp;他們從右到左計算,但按順序返回,在selectgen.ml

4

是的,你不能從調用中恢復參數,因爲OCaml試圖儘可能重用寄存器,並且如果它在剩餘的函數中不再有用,就會銷燬它們的內容。調試器無法打印參數,它們只能在函數的給定位置打印仍然存在的變量,但爲此,您需要修改ocamlopt以轉儲DWARF代碼以恢復值。

相關問題