Open
Description
原文中描述如下:
int* getGoPtr()
{
__SIZE_TYPE__ _cgo_ctxt = _cgo_wait_runtime_init_done();
struct {
int* r0;
} __attribute__((__packed__)) a;
_cgo_tsan_release();
crosscall2(_cgoexp_95d42b8e6230_getGoPtr, &a, 8, _cgo_ctxt);
_cgo_tsan_acquire();
_cgo_release_context(_cgo_ctxt);
return a.r0;
}
其中 `_cgo_tsan_acquire` 是从 LLVM 项目移植过来的内存指针扫描函数,它会检查 cgo 函数返回的结果是否包含 Go 指针。
函数_cgo_tsan_acquire
应是Go语言对Thread Sanitizer的兼容,而非检查cgo函数返回的结果。
cgochecker检查代码位于cgocall.go中。
具体针对该案例来说,go编译器会生成函数_cgoexp_95d42b8e6230_getGoPtr
。在该函数中,会调用runtime.cgoCheckResult
函数,该函数是真正检查返回结果的指针。
附上反编译代码:
public _cgoexp_d414b5060daa_getGoPtr
_cgoexp_d414b5060daa_getGoPtr proc near
var_8 = qword ptr -8
a = qword ptr 8
cmp rsp, [r14+10h]
jbe short loc_45B538
sub rsp, 18h
mov [rsp+18h+var_8], rbp
lea rbp, [rsp+18h+var_8]
mov [rsp+18h+a], rax
lea rax, unk_4607C0
call runtime_newobject
mov rdi, [rsp+18h+a] ; val
test [rdi], al
cmp dword ptr cs:runtime_writeBarrier.enabled, 0
jnz short loc_45B51A
mov [rdi], rax
jmp short loc_45B51F
loc_45B51A:
call runtime_gcWriteBarrier
loc_45B51F:
mov rbx, rax
lea rax, unk_45EC00
call runtime_cgoCheckResult
mov rbp, [rsp+18h+var_8]
add rsp, 18h
retn
Metadata
Metadata
Assignees
Labels
No labels