2 回答
TA貢獻1813條經驗 獲得超2個贊
_cgo_topofstack@@Base是一個符號,由于某種原因在剝離的二進制文件中仍然存在。你的調用是一個超出該地址的地址,無論函數位于該地址之外,與實際代碼完全無關。0xe4c0_cgo_topofstack
拆裝者將地址描述為符號+偏移量是正常的。
這種樣式對于數據數組(例如,如果 符號 for 仍然存在,則將類似的東西編譯為 來自 的負載)以及函數內的跳轉是有意義的。對于這種情況,除了讓你看到附近有什么,并且有較小的數字要查看之外,通常沒有幫助。x = global_array[10]global_array+40global_array
與其實現花哨的邏輯來決定是否要打印地址的版本,而不僅僅是數字絕對地址,對于匯編程序來說,總是這樣做要容易得多(并且沒有出錯的風險)。從地址向后搜索,并獲取找到的第一個符號?;蛘撸瑢τ诠澲械谝粋€符號之前的地址,打印為 。這取決于人類使用判斷和經驗來理解輸出,特別是在查看剝離的二進制文件的反匯編時。symbol+offsetfoo - 0x...
(沒有一個反匯編者可以查看的標志來檢測剝離的二進制文件,檢測這將是一個啟發式的問題,就像注意到大多數直接目標是沒有自己符號的地址一樣。call
AFAIK,GNU二進制文件沒有不打印符號版本的地址的選項。 做一些不同的事情。objdump--no-addresses
我不確定這是關于什么的。不過,這似乎并不是Go獨有的。在我的 x86-64 架構 GNU/Linux 系統上,(這是一個剝離的 PIE 可執行文件)顯示了很多地址,例如 .所以這是恰好在程序的大部分代碼之前最后一個符號。@@Baseobjdump -d /bin/ls22d60 <_obstack_memory_used@@Base+0xc2a0>
其他情況包括同一二進制文件中的glibc符號ABI版本控制,例如.這個 Arch Linux 二進制文件是在最新的 Arch Linux 系統上編譯的,實際上并沒有與一個古老的 glibc 2.2.5 相關聯,但我認為這意味著 的類型或自 glibc 2.2.5 以來沒有改變過??赡懿皇菑母绲臅r候開始的,但是2.2.5可能是glibc開始以這種方式命名符號的時候。對這一段持懷疑態度,因為我真的不知道如何安排用這些版本化名稱來代替符號名稱,或者這個的歷史。@@23298 <optarg@@GLIBC_2.2.5>optarglibc.soldstderr@@
TA貢獻1816條經驗 獲得超4個贊
關于它是什么,你可以看到它在Go 1.4中以當前的形式引入,原始名稱cgo_topofstack_cgo_topofstack
(但是,正如彼得·科德斯(Peter Cordes)在評論中指出的那樣,這并不能解釋為什么該符號仍然存在于剝離的二進制文件中。)
// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
// Must obey the gcc calling convention.
TEXT cgo_topofstack(SB),NOSPLIT,$0
get_tls(CX)
MOVL g(CX), AX
MOVL g_m(AX), AX
MOVL m_curg(AX), AX
MOVL (g_stack+stack_hi)(AX), AX
RET
這是為了修復戈蘭/go/問題8771:
cmd/cgo:返回值的 C 函數在調用復制堆棧的 Go 回調時失敗
Cgo 使用調用 C 代碼的包裝器函數,傳遞堆棧幀的地址。
這個包裝函數由GCC編譯,它調用用戶編寫的真實函數。允許用戶的函數調用 Go 回調。
這些 Go 回調將在原始調用方的堆棧上運行。
它們可能會導致堆棧復制。如果在 Go 回調期間復制堆棧,則 GCC 編譯的包裝器的調用方正在其他位置運行。
GCC 編譯的包裝器使用的堆棧幀指針不會更新,因為堆棧復制器當然對 GCC 編譯的代碼一無所知。
我不認為這對函數的參數來說是一個問題;當包裝器調用 real 函數時,它們已經被復制出堆棧幀。但是,對于返回值的 C 函數來說,這是一個問題。
包裝器將獲取 C 函數返回的值,并使用其指向堆棧幀的指針存儲該值。如果發生堆棧復制,則該指針將不會更新。
換句話說,包裝器可以將返回值存儲在舊堆棧上,而不是新堆棧上。
CL 144130043添加:
cgo:調整返回值位置以考慮堆棧副本。
在 cgo 調用期間,可以復制堆棧。
此副本使 cgo 在返回值區域中具有的指針失效。要解決此問題,請傳遞包含堆棧頂部值的位置的地址(位于 G 結構中)。
對于返回值的 cgo 函數,請在 cgo 調用之前和之后讀取 stktop,以計算寫入返回值所需的調整。
它已使用提交e1364a6進行了修訂。
“@@”部分應該是服從選項的結果,--symbols
顯示文件的符號表部分中的條目(如果有)。
如果符號具有與之關聯的版本信息,則也會顯示此信息。版本字符串顯示為符號名稱的后綴,前面帶有一個字符。例如。
@foo@VER_1如果版本是解析對符號的不受版本控制的引用時要使用的默認版本,則它將顯示為以兩個字符開頭的后綴。例如。
@foo@@VER_2
- 2 回答
- 0 關注
- 125 瀏覽
添加回答
舉報
