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 以来没有改变过。可能不是从更早的时候开始的,但是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 关注
- 121 浏览
添加回答
举报