diff options
| author | Josh Bleecher Snyder <josharian@gmail.com> | 2021-09-29 09:49:54 -0700 |
|---|---|---|
| committer | Josh Bleecher Snyder <josharian@gmail.com> | 2021-09-29 22:12:05 +0000 |
| commit | 88ea8a5fe0526bc53e944420c42cf75fc7b11c4f (patch) | |
| tree | d47c39014de37fb53921efd290d6976a13ca0ca0 /src | |
| parent | ed57d7bb15992bf7ffbbe643401b03f0a418663c (diff) | |
| download | go-88ea8a5fe0526bc53e944420c42cf75fc7b11c4f.tar.xz | |
runtime: extract text address calculation into a separate method
Pure code movement.
Change-Id: I7216e50fe14afa3d19c5047c92e515c90838f834
Reviewed-on: https://go-review.googlesource.com/c/go/+/353129
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Trust: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/runtime/symtab.go | 36 | ||||
| -rw-r--r-- | src/runtime/type.go | 29 |
2 files changed, 37 insertions, 28 deletions
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go index 0d0fe8055b..f65e16ff1d 100644 --- a/src/runtime/symtab.go +++ b/src/runtime/symtab.go @@ -628,6 +628,42 @@ func moduledataverify1(datap *moduledata) { } } +// textAddr returns md.text + off, with special handling for multiple text sections. +// off is a (virtual) offset computed at internal linking time, +// before the external linker adjusts the sections' base addresses. +// +// The text, or instruction stream is generated as one large buffer. +// The off (offset) for a function is its offset within this buffer. +// If the total text size gets too large, there can be issues on platforms like ppc64 +// if the target of calls are too far for the call instruction. +// To resolve the large text issue, the text is split into multiple text sections +// to allow the linker to generate long calls when necessary. +// When this happens, the vaddr for each text section is set to its offset within the text. +// Each function's offset is compared against the section vaddrs and sizes to determine the containing section. +// Then the section relative offset is added to the section's +// relocated baseaddr to compute the function addess. +func (md *moduledata) textAddr(off uintptr) uintptr { + var res uintptr + if len(md.textsectmap) > 1 { + for i := range md.textsectmap { + sectaddr := md.textsectmap[i].vaddr + sectlen := md.textsectmap[i].length + if uintptr(off) >= sectaddr && uintptr(off) < sectaddr+sectlen { + res = md.textsectmap[i].baseaddr + uintptr(off) - uintptr(md.textsectmap[i].vaddr) + break + } + } + } else { + // single text section + res = md.text + uintptr(off) + } + if res > md.etext && GOARCH != "wasm" { // on wasm, functions do not live in the same address space as the linear memory + println("runtime: textOff", hex(off), "out of range", hex(md.text), "-", hex(md.etext)) + throw("runtime: text offset out of range") + } + return res +} + // FuncForPC returns a *Func describing the function that contains the // given program counter address, or else nil. // diff --git a/src/runtime/type.go b/src/runtime/type.go index ad01d5095e..e609acbc1e 100644 --- a/src/runtime/type.go +++ b/src/runtime/type.go @@ -288,34 +288,7 @@ func (t *_type) textOff(off textOff) unsafe.Pointer { } return res } - res := uintptr(0) - - // The text, or instruction stream is generated as one large buffer. The off (offset) for a method is - // its offset within this buffer. If the total text size gets too large, there can be issues on platforms like ppc64 if - // the target of calls are too far for the call instruction. To resolve the large text issue, the text is split - // into multiple text sections to allow the linker to generate long calls when necessary. When this happens, the vaddr - // for each text section is set to its offset within the text. Each method's offset is compared against the section - // vaddrs and sizes to determine the containing section. Then the section relative offset is added to the section's - // relocated baseaddr to compute the method addess. - - if len(md.textsectmap) > 1 { - for i := range md.textsectmap { - sectaddr := md.textsectmap[i].vaddr - sectlen := md.textsectmap[i].length - if uintptr(off) >= sectaddr && uintptr(off) < sectaddr+sectlen { - res = md.textsectmap[i].baseaddr + uintptr(off) - uintptr(md.textsectmap[i].vaddr) - break - } - } - } else { - // single text section - res = md.text + uintptr(off) - } - - if res > md.etext && GOARCH != "wasm" { // on wasm, functions do not live in the same address space as the linear memory - println("runtime: textOff", hex(off), "out of range", hex(md.text), "-", hex(md.etext)) - throw("runtime: text offset out of range") - } + res := md.textAddr(uintptr(off)) return unsafe.Pointer(res) } |
