They're only used in a single place.
Instead of calculating the end every time,
calculate it in the linker.
It'd be nice to recalculate baseaddr-vaddr,
but that generates relocations that are too large.
While we're here, remove some pointless uintptr -> uintptr conversions.
Change-Id: I91758f9bff11b365bc3a63fee172dbdc3d90b966
Reviewed-on: https://go-review.googlesource.com/c/go/+/354089
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
if sect.Name != ".text" {
break
}
- off = t.SetUint(ctxt.Arch, off, sect.Vaddr-textbase)
- off = t.SetUint(ctxt.Arch, off, sect.Length)
- if n == 0 {
- s := ldr.Lookup("runtime.text", 0)
- if s == 0 {
- ctxt.Errorf(s, "Unable to find symbol runtime.text\n")
- }
- off = t.SetAddr(ctxt.Arch, off, s)
-
- } else {
- s := ldr.Lookup(fmt.Sprintf("runtime.text.%d", n), 0)
- if s == 0 {
- ctxt.Errorf(s, "Unable to find symbol runtime.text.%d\n", n)
- }
- off = t.SetAddr(ctxt.Arch, off, s)
+ // The fields written should match runtime/symtab.go:textsect.
+ // They are designed to minimize runtime calculations.
+ vaddr := sect.Vaddr - textbase
+ off = t.SetUint(ctxt.Arch, off, vaddr) // field vaddr
+ end := vaddr + sect.Length
+ off = t.SetUint(ctxt.Arch, off, end) // field end
+ name := "runtime.text"
+ if n != 0 {
+ name = fmt.Sprintf("runtime.text.%d", n)
+ }
+ s := ldr.Lookup(name, 0)
+ if s == 0 {
+ ctxt.Errorf(s, "Unable to find symbol %s\n", name)
}
+ off = t.SetAddr(ctxt.Arch, off, s) // field baseaddr
n++
}
return t.Sym(), uint32(n)
type textsect struct {
vaddr uintptr // prelinked section vaddr
- length uintptr // section length
+ end uintptr // vaddr + section length
baseaddr uintptr // relocated section address
}
// 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.
+// Each function's offset is compared against the section vaddrs and ends to determine the containing section.
// Then the section relative offset is added to the section's
-// relocated baseaddr to compute the function addess.
+// relocated baseaddr to compute the function address.
//
// It is nosplit because it is part of the findfunc implementation.
//go:nosplit
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)
+ if off >= md.textsectmap[i].vaddr && off < md.textsectmap[i].end {
+ res = md.textsectmap[i].baseaddr + off - md.textsectmap[i].vaddr
break
}
}
} else {
// single text section
- res = md.text + uintptr(off)
+ res = md.text + 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))