2 回答

TA貢獻(xiàn)1813條經(jīng)驗(yàn) 獲得超2個(gè)贊
_cgo_topofstack@@Base是一個(gè)符號(hào),由于某種原因在剝離的二進(jìn)制文件中仍然存在。你的調(diào)用是一個(gè)超出該地址的地址,無論函數(shù)位于該地址之外,與實(shí)際代碼完全無關(guān)。0xe4c0_cgo_topofstack
拆裝者將地址描述為符號(hào)+偏移量是正常的。
這種樣式對(duì)于數(shù)據(jù)數(shù)組(例如,如果 符號(hào) for 仍然存在,則將類似的東西編譯為 來自 的負(fù)載)以及函數(shù)內(nèi)的跳轉(zhuǎn)是有意義的。對(duì)于這種情況,除了讓你看到附近有什么,并且有較小的數(shù)字要查看之外,通常沒有幫助。x = global_array[10]global_array+40global_array
與其實(shí)現(xiàn)花哨的邏輯來決定是否要打印地址的版本,而不僅僅是數(shù)字絕對(duì)地址,對(duì)于匯編程序來說,總是這樣做要容易得多(并且沒有出錯(cuò)的風(fēng)險(xiǎn))。從地址向后搜索,并獲取找到的第一個(gè)符號(hào)?;蛘?,對(duì)于節(jié)中第一個(gè)符號(hào)之前的地址,打印為 。這取決于人類使用判斷和經(jīng)驗(yàn)來理解輸出,特別是在查看剝離的二進(jìn)制文件的反匯編時(shí)。symbol+offsetfoo - 0x...
(沒有一個(gè)反匯編者可以查看的標(biāo)志來檢測(cè)剝離的二進(jìn)制文件,檢測(cè)這將是一個(gè)啟發(fā)式的問題,就像注意到大多數(shù)直接目標(biāo)是沒有自己符號(hào)的地址一樣。call
AFAIK,GNU二進(jìn)制文件沒有不打印符號(hào)版本的地址的選項(xiàng)。 做一些不同的事情。objdump--no-addresses
我不確定這是關(guān)于什么的。不過,這似乎并不是Go獨(dú)有的。在我的 x86-64 架構(gòu) GNU/Linux 系統(tǒng)上,(這是一個(gè)剝離的 PIE 可執(zhí)行文件)顯示了很多地址,例如 .所以這是恰好在程序的大部分代碼之前最后一個(gè)符號(hào)。@@Baseobjdump -d /bin/ls22d60 <_obstack_memory_used@@Base+0xc2a0>
其他情況包括同一二進(jìn)制文件中的glibc符號(hào)ABI版本控制,例如.這個(gè) Arch Linux 二進(jìn)制文件是在最新的 Arch Linux 系統(tǒng)上編譯的,實(shí)際上并沒有與一個(gè)古老的 glibc 2.2.5 相關(guān)聯(lián),但我認(rèn)為這意味著 的類型或自 glibc 2.2.5 以來沒有改變過。可能不是從更早的時(shí)候開始的,但是2.2.5可能是glibc開始以這種方式命名符號(hào)的時(shí)候。對(duì)這一段持懷疑態(tài)度,因?yàn)槲艺娴牟恢廊绾伟才庞眠@些版本化名稱來代替符號(hào)名稱,或者這個(gè)的歷史。@@23298 <optarg@@GLIBC_2.2.5>optarglibc.soldstderr@@

TA貢獻(xiàn)1816條經(jīng)驗(yàn) 獲得超4個(gè)贊
關(guān)于它是什么,你可以看到它在Go 1.4中以當(dāng)前的形式引入,原始名稱cgo_topofstack
_cgo_topofstack
(但是,正如彼得·科德斯(Peter Cordes)在評(píng)論中指出的那樣,這并不能解釋為什么該符號(hào)仍然存在于剝離的二進(jìn)制文件中。)
// 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
這是為了修復(fù)戈蘭/go/問題8771:
cmd/cgo
:返回值的 C 函數(shù)在調(diào)用復(fù)制堆棧的 Go 回調(diào)時(shí)失敗
Cgo 使用調(diào)用 C 代碼的包裝器函數(shù),傳遞堆棧幀的地址。
這個(gè)包裝函數(shù)由GCC編譯,它調(diào)用用戶編寫的真實(shí)函數(shù)。允許用戶的函數(shù)調(diào)用 Go 回調(diào)。
這些 Go 回調(diào)將在原始調(diào)用方的堆棧上運(yùn)行。
它們可能會(huì)導(dǎo)致堆棧復(fù)制。如果在 Go 回調(diào)期間復(fù)制堆棧,則 GCC 編譯的包裝器的調(diào)用方正在其他位置運(yùn)行。
GCC 編譯的包裝器使用的堆棧幀指針不會(huì)更新,因?yàn)槎褩?fù)制器當(dāng)然對(duì) GCC 編譯的代碼一無所知。
我不認(rèn)為這對(duì)函數(shù)的參數(shù)來說是一個(gè)問題;當(dāng)包裝器調(diào)用 real 函數(shù)時(shí),它們已經(jīng)被復(fù)制出堆棧幀。但是,對(duì)于返回值的 C 函數(shù)來說,這是一個(gè)問題。
包裝器將獲取 C 函數(shù)返回的值,并使用其指向堆棧幀的指針存儲(chǔ)該值。如果發(fā)生堆棧復(fù)制,則該指針將不會(huì)更新。
換句話說,包裝器可以將返回值存儲(chǔ)在舊堆棧上,而不是新堆棧上。
CL 144130043添加:
cgo:調(diào)整返回值位置以考慮堆棧副本。
在 cgo 調(diào)用期間,可以復(fù)制堆棧。
此副本使 cgo 在返回值區(qū)域中具有的指針失效。要解決此問題,請(qǐng)傳遞包含堆棧頂部值的位置的地址(位于 G 結(jié)構(gòu)中)。
對(duì)于返回值的 cgo 函數(shù),請(qǐng)?jiān)?cgo 調(diào)用之前和之后讀取 stktop,以計(jì)算寫入返回值所需的調(diào)整。
它已使用提交e1364a6進(jìn)行了修訂。
“@@”部分應(yīng)該是服從
選項(xiàng)的結(jié)果,--symbols
顯示文件的符號(hào)表部分中的條目(如果有)。
如果符號(hào)具有與之關(guān)聯(lián)的版本信息,則也會(huì)顯示此信息。版本字符串顯示為符號(hào)名稱的后綴,前面帶有一個(gè)字符。例如。
@
foo@VER_1
如果版本是解析對(duì)符號(hào)的不受版本控制的引用時(shí)要使用的默認(rèn)版本,則它將顯示為以兩個(gè)字符開頭的后綴。例如。
@
foo@@VER_2
- 2 回答
- 0 關(guān)注
- 94 瀏覽
添加回答
舉報(bào)