Skip to content

Commit 20afbe8

Browse files
committed
cmd/oldlink: port bug fixes to old linker
This CL ports CL 234105 and CL 240621 to the old linker, which fix critical bugs (runtime crashes). Updates #39049. Updates #39927. Change-Id: I47afc84349119e320d2e60d64b7188a410835d2b Reviewed-on: https://go-review.googlesource.com/c/go/+/241087 Run-TryBot: Cherry Zhang <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Than McIntosh <[email protected]> Reviewed-by: Jeremy Faller <[email protected]>
1 parent fcf1cb2 commit 20afbe8

File tree

6 files changed

+38
-18
lines changed

6 files changed

+38
-18
lines changed

src/cmd/oldlink/internal/arm/asm.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -390,8 +390,12 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
390390
offset := (signext24(r.Add&0xffffff) + 2) * 4
391391
var tramp *sym.Symbol
392392
for i := 0; ; i++ {
393-
name := r.Sym.Name + fmt.Sprintf("%+d-tramp%d", offset, i)
393+
oName := r.Sym.Name
394+
name := oName + fmt.Sprintf("%+d-tramp%d", offset, i)
394395
tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
396+
if oName == "runtime.deferreturn" {
397+
tramp.Attr.Set(sym.AttrDeferReturnTramp, true)
398+
}
395399
if tramp.Type == sym.SDYNIMPORT {
396400
// don't reuse trampoline defined in other module
397401
continue

src/cmd/oldlink/internal/ld/decodesym.go

+19-13
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"cmd/oldlink/internal/sym"
1212
"debug/elf"
1313
"fmt"
14+
"log"
1415
)
1516

1617
// Decoding the type.* symbols. This has to be in sync with
@@ -93,7 +94,7 @@ func decodetypeHasUncommon(arch *sys.Arch, p []byte) bool {
9394
func findShlibSection(ctxt *Link, path string, addr uint64) *elf.Section {
9495
for _, shlib := range ctxt.Shlibs {
9596
if shlib.Path == path {
96-
for _, sect := range shlib.File.Sections {
97+
for _, sect := range shlib.File.Sections[1:] { // skip the NULL section
9798
if sect.Addr <= addr && addr <= sect.Addr+sect.Size {
9899
return sect
99100
}
@@ -112,9 +113,15 @@ func decodetypeGcprog(ctxt *Link, s *sym.Symbol) []byte {
112113
// A gcprog is a 4-byte uint32 indicating length, followed by
113114
// the actual program.
114115
progsize := make([]byte, 4)
115-
sect.ReadAt(progsize, int64(addr-sect.Addr))
116+
_, err := sect.ReadAt(progsize, int64(addr-sect.Addr))
117+
if err != nil {
118+
log.Fatal(err)
119+
}
116120
progbytes := make([]byte, ctxt.Arch.ByteOrder.Uint32(progsize))
117-
sect.ReadAt(progbytes, int64(addr-sect.Addr+4))
121+
_, err = sect.ReadAt(progbytes, int64(addr-sect.Addr+4))
122+
if err != nil {
123+
log.Fatal(err)
124+
}
118125
return append(progsize, progbytes...)
119126
}
120127
Exitf("cannot find gcprog for %s", s.Name)
@@ -124,14 +131,6 @@ func decodetypeGcprog(ctxt *Link, s *sym.Symbol) []byte {
124131
}
125132

126133
func decodetypeGcprogShlib(ctxt *Link, s *sym.Symbol) uint64 {
127-
if ctxt.Arch.Family == sys.ARM64 {
128-
for _, shlib := range ctxt.Shlibs {
129-
if shlib.Path == s.File {
130-
return shlib.gcdataAddresses[s]
131-
}
132-
}
133-
return 0
134-
}
135134
return decodeInuxi(ctxt.Arch, s.P[2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize):], ctxt.Arch.PtrSize)
136135
}
137136

@@ -141,8 +140,15 @@ func decodetypeGcmask(ctxt *Link, s *sym.Symbol) []byte {
141140
ptrdata := decodetypePtrdata(ctxt.Arch, s.P)
142141
sect := findShlibSection(ctxt, s.File, addr)
143142
if sect != nil {
144-
r := make([]byte, ptrdata/int64(ctxt.Arch.PtrSize))
145-
sect.ReadAt(r, int64(addr-sect.Addr))
143+
bits := ptrdata / int64(ctxt.Arch.PtrSize)
144+
r := make([]byte, (bits+7)/8)
145+
// ldshlibsyms avoids closing the ELF file so sect.ReadAt works.
146+
// If we remove this read (and the ones in decodetypeGcprog), we
147+
// can close the file.
148+
_, err := sect.ReadAt(r, int64(addr-sect.Addr))
149+
if err != nil {
150+
log.Fatal(err)
151+
}
146152
return r
147153
}
148154
Exitf("cannot find gcmask for %s", s.Name)

src/cmd/oldlink/internal/ld/lib.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -2010,7 +2010,9 @@ func ldshlibsyms(ctxt *Link, shlib string) {
20102010
Errorf(nil, "cannot open shared library: %s", libpath)
20112011
return
20122012
}
2013-
defer f.Close()
2013+
// Keep the file open as decodetypeGcprog needs to read from it.
2014+
// TODO: fix. Maybe mmap the file.
2015+
//defer f.Close()
20142016

20152017
hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
20162018
if err != nil {

src/cmd/oldlink/internal/ld/pcln.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ func (ctxt *Link) pclntab() {
276276
// set the resumption point to PC_B.
277277
lastWasmAddr = uint32(r.Add)
278278
}
279-
if r.Type.IsDirectCall() && r.Sym != nil && r.Sym.Name == "runtime.deferreturn" {
279+
if r.Type.IsDirectCall() && r.Sym != nil && (r.Sym.Name == "runtime.deferreturn" || r.Sym.Attr.DeferReturnTramp()) {
280280
if ctxt.Arch.Family == sys.Wasm {
281281
deferreturn = lastWasmAddr - 1
282282
} else {

src/cmd/oldlink/internal/ppc64/asm.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,8 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
667667
// target is at some offset within the function. Calls to duff+8 and duff+256 must appear as
668668
// distinct trampolines.
669669

670-
name := r.Sym.Name
670+
oName := r.Sym.Name
671+
name := oName
671672
if r.Add == 0 {
672673
name = name + fmt.Sprintf("-tramp%d", i)
673674
} else {
@@ -677,6 +678,9 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
677678
// Look up the trampoline in case it already exists
678679

679680
tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
681+
if oName == "runtime.deferreturn" {
682+
tramp.Attr.Set(sym.AttrDeferReturnTramp, true)
683+
}
680684
if tramp.Value == 0 {
681685
break
682686
}

src/cmd/oldlink/internal/sym/attribute.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,10 @@ const (
8181
// AttrReadOnly indicates whether the symbol's content (Symbol.P) is backed by
8282
// read-only memory.
8383
AttrReadOnly
84-
// 19 attributes defined so far.
84+
// AttrDeferReturnTramp indicates the symbol is a trampoline of a deferreturn
85+
// call.
86+
AttrDeferReturnTramp
87+
// 20 attributes defined so far.
8588
)
8689

8790
func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 }
@@ -103,6 +106,7 @@ func (a Attribute) SubSymbol() bool { return a&AttrSubSymbol != 0 }
103106
func (a Attribute) Container() bool { return a&AttrContainer != 0 }
104107
func (a Attribute) TopFrame() bool { return a&AttrTopFrame != 0 }
105108
func (a Attribute) ReadOnly() bool { return a&AttrReadOnly != 0 }
109+
func (a Attribute) DeferReturnTramp() bool { return a&AttrDeferReturnTramp != 0 }
106110

107111
func (a Attribute) CgoExport() bool {
108112
return a.CgoExportDynamic() || a.CgoExportStatic()

0 commit comments

Comments
 (0)