亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

_cgo_topofstack@@Base剝離的二進制文件中

_cgo_topofstack@@Base剝離的二進制文件中

Go
慕慕森 2022-09-12 17:08:49
在來自 Go 的剝離二進制文件中,這意味著什么?_cgo_topofstack@@Base$ cat simple.gopackage mainimport(    "net"    "time"    "strconv")func main() {    tcpAddr, _ := net.ResolveTCPAddr("tcp4", ":7777")    listener, _ := net.ListenTCP("tcp", tcpAddr)    conn, _ := listener.Accept()    daytime := time.Now().String()+strconv.Itoa(0xdeadface)    conn.Write([]byte(daytime))}代碼應該被剝離 - 這是什么意思?_cgo_topofstack@@Base$ go build -gcflags=-l -ldflags "-s -w" -o simple_wo_symbols simple.go$ objdump -D -S simple_wo_symbols > simple_wo_symbols.human$ sed -n "198899,198904p" simple_wo_symbols.human  4b9860:   e8 db c1 fb ff          callq  475a40 <_cgo_topofstack@@Base+0xe4c0>  4b9865:   48 8b 44 24 18          mov    0x18(%rsp),%rax  4b986a:   48 89 44 24 70          mov    %rax,0x70(%rsp)  4b986f:   48 8b 4c 24 20          mov    0x20(%rsp),%rcx  4b9874:   48 89 4c 24 40          mov    %rcx,0x40(%rsp)  4b9879:   ba ce fa ad de          mov    $0xdeadface,%edx編輯(更好的問題規范):為什么這個符號存在于一個剝離的二進制文件中?批準 peter-cordes 聲明:被調用的函數與 處的函數完全無關,添加此(不相關和多余的)信息是一件(奇怪的?)事情_cgo_topofstack@@Baseobjdump也許與此有關(?):有沒有一種脫衣的慣用語?!
查看完整描述

2 回答

?
慕姐8265434

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@@


查看完整回答
反對 回復 2022-09-12
?
繁華開滿天機

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


查看完整回答
反對 回復 2022-09-12
  • 2 回答
  • 0 關注
  • 125 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號