aboutsummaryrefslogtreecommitdiff
path: root/src/debug
diff options
context:
space:
mode:
authorJosh Bleecher Snyder <josharian@gmail.com>2021-09-28 17:06:56 -0700
committerJosh Bleecher Snyder <josharian@gmail.com>2021-09-29 22:14:22 +0000
commitd3ad216f8e7ea7699fe44990c65213c26aba907d (patch)
tree69306ed4253d70afae6a448dc2d953a6724a0de4 /src/debug
parent88ea8a5fe0526bc53e944420c42cf75fc7b11c4f (diff)
downloadgo-d3ad216f8e7ea7699fe44990c65213c26aba907d.tar.gz
go-d3ad216f8e7ea7699fe44990c65213c26aba907d.zip
cmd/link, runtime: use offset for _func.entry
The first field of the func data stored by the linker is the entry PC for the function. Prior to this change, this was stored as a relocation to the function. Change this to be an offset relative to runtime.text. This reduces the number of relocations on darwin/arm64 by about 10%. It also slightly shrinks binaries: file before after Δ % addr2line 3803058 3791298 -11760 -0.309% api 5140114 5104242 -35872 -0.698% asm 4886850 4840626 -46224 -0.946% buildid 2512466 2503042 -9424 -0.375% cgo 4374770 4342274 -32496 -0.743% compile 22920530 22769202 -151328 -0.660% cover 4624626 4588242 -36384 -0.787% dist 3217570 3205522 -12048 -0.374% doc 3715026 3684498 -30528 -0.822% fix 3148226 3119266 -28960 -0.920% link 6350226 6313362 -36864 -0.581% nm 3768850 3757106 -11744 -0.312% objdump 4140594 4127618 -12976 -0.313% pack 2227474 2218818 -8656 -0.389% pprof 13598706 13506786 -91920 -0.676% test2json 2497234 2487426 -9808 -0.393% trace 10198066 10118498 -79568 -0.780% vet 6930658 6889074 -41584 -0.600% total 108055044 107366900 -688144 -0.637% It should also incrementally speed up binary launching. This is the first step towards removing enough relocations that pages that were previously dirtied by the loader may remain clean, which will offer memory savings useful in constrained environments. Change-Id: Icfba55e696ba2f9c99c4f179125ba5a3ba4369c9 Reviewed-on: https://go-review.googlesource.com/c/go/+/351463 Trust: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/debug')
-rw-r--r--src/debug/gosym/pclntab.go43
1 files changed, 38 insertions, 5 deletions
diff --git a/src/debug/gosym/pclntab.go b/src/debug/gosym/pclntab.go
index bf97976b3c..fdaa47a917 100644
--- a/src/debug/gosym/pclntab.go
+++ b/src/debug/gosym/pclntab.go
@@ -22,6 +22,7 @@ const (
ver11
ver12
ver116
+ ver118
)
// A LineTable is a data structure mapping program counters to line numbers.
@@ -48,10 +49,11 @@ type LineTable struct {
// Contains the version of the pclntab section.
version version
- // Go 1.2/1.16 state
+ // Go 1.2/1.16/1.18 state
binary binary.ByteOrder
quantum uint32
ptrsize uint32
+ textStart uintptr // address of runtime.text symbol (1.18+)
funcnametab []byte
cutab []byte
funcdata []byte
@@ -166,8 +168,11 @@ func (t *LineTable) isGo12() bool {
return t.version >= ver12
}
-const go12magic = 0xfffffffb
-const go116magic = 0xfffffffa
+const (
+ go12magic = 0xfffffffb
+ go116magic = 0xfffffffa
+ go118magic = 0xfffffff0
+)
// uintptr returns the pointer-sized value encoded at b.
// The pointer size is dictated by the table being read.
@@ -219,11 +224,15 @@ func (t *LineTable) parsePclnTab() {
t.binary, possibleVersion = binary.LittleEndian, ver116
case beMagic == go116magic:
t.binary, possibleVersion = binary.BigEndian, ver116
+ case leMagic == go118magic:
+ t.binary, possibleVersion = binary.LittleEndian, ver118
+ case beMagic == go118magic:
+ t.binary, possibleVersion = binary.BigEndian, ver118
default:
return
}
- // quantum and ptrSize are the same between 1.2 and 1.16
+ // quantum and ptrSize are the same between 1.2, 1.16, and 1.18
t.quantum = uint32(t.Data[6])
t.ptrsize = uint32(t.Data[7])
@@ -235,6 +244,18 @@ func (t *LineTable) parsePclnTab() {
}
switch possibleVersion {
+ case ver118:
+ t.nfunctab = uint32(offset(0))
+ t.nfiletab = uint32(offset(1))
+ t.textStart = uintptr(offset(2))
+ t.funcnametab = data(3)
+ t.cutab = data(4)
+ t.filetab = data(5)
+ t.pctab = data(6)
+ t.funcdata = data(7)
+ t.functab = data(7)
+ functabsize := t.nfunctab*2*t.ptrsize + t.ptrsize
+ t.functab = t.functab[:functabsize]
case ver116:
t.nfunctab = uint32(offset(0))
t.nfiletab = uint32(offset(1))
@@ -380,7 +401,14 @@ func (f funcData) IsZero() bool {
}
// entryPC returns the func's entry PC.
-func (f funcData) entryPC() uint64 {
+func (f *funcData) entryPC() uint64 {
+ // In Go 1.18, the first field of _func changed
+ // from a uintptr entry PC to a uint32 entry offset.
+ if f.t.version >= ver118 {
+ // TODO: support multiple text sections.
+ // See runtime/symtab.go:(*moduledata).textAddr.
+ return uint64(f.t.binary.Uint32(f.data)) + uint64(f.t.textStart)
+ }
return f.t.uintptr(f.data)
}
@@ -397,7 +425,12 @@ func (f funcData) field(n uint32) uint32 {
if n == 0 || n > 9 {
panic("bad funcdata field")
}
+ // In Go 1.18, the first field of _func changed
+ // from a uintptr entry PC to a uint32 entry offset.
sz0 := f.t.ptrsize
+ if f.t.version >= ver118 {
+ sz0 = 4
+ }
off := sz0 + (n-1)*4 // subsequent fields are 4 bytes each
data := f.data[off:]
return f.t.binary.Uint32(data)