cmd/link: detect trampoline of deferreturn call

The runtime needs to find the PC of the deferreturn call in a few
places. So for functions that have defer, we record the PC of
deferreturn call in its funcdata.

For very large binaries, the deferreturn call could be made
through a trampoline. The current code of finding deferreturn PC
fails in this case. This CL handles the trampoline as well.

Fixes #39049.

Change-Id: I929be54d6ae436f5294013793217dc2a35f080d4
Reviewed-on: https://go-review.googlesource.com/c/go/+/234105
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
Cherry Zhang 2020-05-14 19:22:59 -04:00
parent 881d540540
commit 2b70ffe930
5 changed files with 42 additions and 9 deletions

View file

@ -236,7 +236,8 @@ type Loader struct {
outdata [][]byte // symbol's data in the output buffer
extRelocs [][]ExtReloc // symbol's external relocations
itablink map[Sym]struct{} // itablink[j] defined if j is go.itablink.*
itablink map[Sym]struct{} // itablink[j] defined if j is go.itablink.*
deferReturnTramp map[Sym]bool // whether the symbol is a trampoline of a deferreturn call
objByPkg map[string]*oReader // map package path to its Go object reader
@ -362,6 +363,7 @@ func NewLoader(flags uint32, elfsetstring elfsetstringFunc, reporter *ErrorRepor
attrCgoExportDynamic: make(map[Sym]struct{}),
attrCgoExportStatic: make(map[Sym]struct{}),
itablink: make(map[Sym]struct{}),
deferReturnTramp: make(map[Sym]bool),
extStaticSyms: make(map[nameVer]Sym),
builtinSyms: make([]Sym, nbuiltin),
flags: flags,
@ -1062,6 +1064,16 @@ func (l *Loader) IsItabLink(i Sym) bool {
return false
}
// Return whether this is a trampoline of a deferreturn call.
func (l *Loader) IsDeferReturnTramp(i Sym) bool {
return l.deferReturnTramp[i]
}
// Set that i is a trampoline of a deferreturn call.
func (l *Loader) SetIsDeferReturnTramp(i Sym, v bool) {
l.deferReturnTramp[i] = v
}
// growValues grows the slice used to store symbol values.
func (l *Loader) growValues(reqLen int) {
curLen := len(l.values)