Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use the go:linkname instruction

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces "how to use go:linkname instructions". In daily operation, I believe many people have doubts about how to use go:linkname instructions. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts about "how to use go:linkname instructions"! Next, please follow the editor to study!

01 format / / go:linkname local remote

Remote may not be available, so remote uses the value of local, and the effect is that local is exported.

02 local and remote are both functions

Local as placeholder and remote as implementer

Examples in the standard library:

/ / from time package / / go:linkname runtimeNano runtime.nanotime func runtimeNano () int64 / / from runtime package / / go:nosplit func nanotime () int64 {return nanotime1 ()}

At this point, there is no runtimeNano in the binary file, which is directly converted to a call to runtime.nanotime.

Local as the implementer and remote as the placeholder

Also from the standard library. There is a function that does not have a function body, but is backreferenced.

/ / in an internal of the standard library / / go:linkname runtime_cmpstring runtime.cmpstring func runtime_cmpstring (a, b string) int {l: = len (a) if len (b)

< l { l = len(b) } for i := 0; i < l; i++ { c1, c2 := a[i], b[i] if c1 < c2 { return -1 } if c1 >

C2 {return + 1}} if len (a)

< len(b) { return -1 } if len(a) >

Len (b) {return + 1} return 0} / / from runtime func cmpstring (string, string) int

At this point, there is no runtime_cmpstring in the binary file, and the corresponding function has been named runtime.cmpstring. That is, the implementation is in the internal package, but is ultimately referenced through runtime.cmpstring.

One placeholder + one assembly function

/ / in an internal of the standard library / / go:linkname abigen_runtime_memequal runtime.memequal func abigen_runtime_memequal (a, b unsafe.Pointer, size uintptr) bool

Note that the implementation of runtime.memequal is not in the runtime package, and it is not required to be in the corresponding package if you use assembly implementation.

# memequal (a, b unsafe.Pointer, size uintptr) bool TEXT runtime ·memequal (SB), NOSPLIT,$0-25 MOVQ aquifer 0 (FP), SI MOVQ SI MOVQ 8 (FP), DI CMPQ SI, DI JEQ eq MOVQ size+16 (FP), BX LEAQ ret+24 (FP), AX JMP memeqbody (SB) eq: MOVB $1, ret+24 (FP) RET03 local and remote are both variables

Two regular variables

/ / go:linkname overflowError runtime.overflowError var overflowError error / / go:linkname divideError runtime.divideError var divideError error / / go:linkname zeroVal runtime.zeroVal var zeroVal [maxZero] byte / / go:linkname _ iscgo runtime.iscgo var _ iscgo bool = true / / go:cgo_import_static x_cgo_setenv / / go:linkname x_cgo_setenv x_cgo_setenv / / go:linkname _ cgo_setenv runtime._cgo_setenv var x_cgo_setenv byte var _ cgo_setenv = & x_cgo _ setenv / / go:cgo_import_static x_cgo_unsetenv / / go:linkname x_cgo_unsetenv x_cgo_unsetenv / / go:linkname _ cgo_unsetenv runtime._cgo_unsetenv var x_cgo_unsetenv byte var _ cgo_unsetenv = & x_cgo_unsetenv

One placeholder + one pseudo symbol

/ / go:linkname runtime_inittask runtime..inittask var runtime_inittask initTask / / go:linkname main_inittask main..inittask var main_inittask initTask

Note that... inittask is not .inittask, and .inittask exists only at compile time, and this variable cannot be declared in any package.

Here's an additional explanation of why.. inittask has two points. The first point is the ordinary runtime. In this way of calling, the second point and inittask together form a symbol (variable). Note that variables in Go are not allowed to. At the beginning, so, this is called a pseudo symbol, and it only exists in the non-compilation phase.

04 an example

The study of / / go:linkname is due to the following background:

There is InheritableThreadLocal,SpringWeb in Java and it is used in ServletActionContext to make it easy to get HttpServletRequest anywhere.

Go does not provide a similar mechanism. Even if you find goroutine id through stack (99% of the articles are described in this way), together with sync.Map, you only implement a rough ThreadLocal, and you still cannot get the content of the parent program in the child program.

G.label is not intended for this scenario, but it has all the requirements of InheritableThreadLocal, as long as we can access the private field of label, we have the full version of InheritableThreadLocal.

The following example is used in the author's real project.

There are two functions in the runtime and runtime/pprof packages: runtime_setProfLabel and runtime_getProfLabel. Among them, the one in the runtime package provides the implementation, while the one in pprof does not. If you create additional functions based on them, as follows:

/ / go:linkname SetPointer runtime/pprof.runtime_setProfLabel func SetPointer (ptr unsafe.Pointer) / / go:linkname GetPointer runtime/pprof.runtime_getProfLabel func GetPointer () unsafe.Pointer

According to the previous analysis, although runtime.runtime_setProfLabel/runtime.runtime_getProfLabel provides a function implementation, it does not appear in the binaries (see code below), and if you want to call it, you have to go through runtime/pprof.runtime_setProfLabel/runtime/pprof.runtime_getProfLabel, which is the root cause of the above linkname to pprof rather than runtime.

/ / from runtime package / / go:linkname runtime_setProfLabel runtime/pprof.runtime_setProfLabel func runtime_setProfLabel (labels unsafe.Pointer) {if raceenabled {racereleasemerge (unsafe.Pointer (& labelSync))} getg (). Labels = labels} / / from runtime/pprof package func runtime_setProfLabel (labels unsafe.Pointer) / from runtime package / / go:linkname runtime_getProfLabel runtime/pprof.runtime_getProfLabel func runtime_getProfLabel () unsafe.Pointer {return getg () .labels} / / from the runtime/pprof package func runtime_getProfLabel () unsafe.Pointer here The study on "how to use go:linkname instructions" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report