mirror of
https://github.com/golang/go
synced 2024-11-17 05:44:52 -07:00
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>
This commit is contained in:
parent
ed57d7bb15
commit
88ea8a5fe0
@ -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
|
// FuncForPC returns a *Func describing the function that contains the
|
||||||
// given program counter address, or else nil.
|
// given program counter address, or else nil.
|
||||||
//
|
//
|
||||||
|
@ -288,34 +288,7 @@ func (t *_type) textOff(off textOff) unsafe.Pointer {
|
|||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
res := uintptr(0)
|
res := md.textAddr(uintptr(off))
|
||||||
|
|
||||||
// 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")
|
|
||||||
}
|
|
||||||
return unsafe.Pointer(res)
|
return unsafe.Pointer(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user