Skip to content

Commit

Permalink
cmd/oldlink: port bug fixes to old linker
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
cherrymui committed Jul 6, 2020
1 parent fcf1cb2 commit 20afbe8
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 18 deletions.
6 changes: 5 additions & 1 deletion src/cmd/oldlink/internal/arm/asm.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,12 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
offset := (signext24(r.Add&0xffffff) + 2) * 4
var tramp *sym.Symbol
for i := 0; ; i++ {
name := r.Sym.Name + fmt.Sprintf("%+d-tramp%d", offset, i)
oName := r.Sym.Name
name := oName + fmt.Sprintf("%+d-tramp%d", offset, i)
tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
if oName == "runtime.deferreturn" {
tramp.Attr.Set(sym.AttrDeferReturnTramp, true)
}
if tramp.Type == sym.SDYNIMPORT {
// don't reuse trampoline defined in other module
continue
Expand Down
32 changes: 19 additions & 13 deletions src/cmd/oldlink/internal/ld/decodesym.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"cmd/oldlink/internal/sym"
"debug/elf"
"fmt"
"log"
)

// Decoding the type.* symbols. This has to be in sync with
Expand Down Expand Up @@ -93,7 +94,7 @@ func decodetypeHasUncommon(arch *sys.Arch, p []byte) bool {
func findShlibSection(ctxt *Link, path string, addr uint64) *elf.Section {
for _, shlib := range ctxt.Shlibs {
if shlib.Path == path {
for _, sect := range shlib.File.Sections {
for _, sect := range shlib.File.Sections[1:] { // skip the NULL section
if sect.Addr <= addr && addr <= sect.Addr+sect.Size {
return sect
}
Expand All @@ -112,9 +113,15 @@ func decodetypeGcprog(ctxt *Link, s *sym.Symbol) []byte {
// A gcprog is a 4-byte uint32 indicating length, followed by
// the actual program.
progsize := make([]byte, 4)
sect.ReadAt(progsize, int64(addr-sect.Addr))
_, err := sect.ReadAt(progsize, int64(addr-sect.Addr))
if err != nil {
log.Fatal(err)
}
progbytes := make([]byte, ctxt.Arch.ByteOrder.Uint32(progsize))
sect.ReadAt(progbytes, int64(addr-sect.Addr+4))
_, err = sect.ReadAt(progbytes, int64(addr-sect.Addr+4))
if err != nil {
log.Fatal(err)
}
return append(progsize, progbytes...)
}
Exitf("cannot find gcprog for %s", s.Name)
Expand All @@ -124,14 +131,6 @@ func decodetypeGcprog(ctxt *Link, s *sym.Symbol) []byte {
}

func decodetypeGcprogShlib(ctxt *Link, s *sym.Symbol) uint64 {
if ctxt.Arch.Family == sys.ARM64 {
for _, shlib := range ctxt.Shlibs {
if shlib.Path == s.File {
return shlib.gcdataAddresses[s]
}
}
return 0
}
return decodeInuxi(ctxt.Arch, s.P[2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize):], ctxt.Arch.PtrSize)
}

Expand All @@ -141,8 +140,15 @@ func decodetypeGcmask(ctxt *Link, s *sym.Symbol) []byte {
ptrdata := decodetypePtrdata(ctxt.Arch, s.P)
sect := findShlibSection(ctxt, s.File, addr)
if sect != nil {
r := make([]byte, ptrdata/int64(ctxt.Arch.PtrSize))
sect.ReadAt(r, int64(addr-sect.Addr))
bits := ptrdata / int64(ctxt.Arch.PtrSize)
r := make([]byte, (bits+7)/8)
// ldshlibsyms avoids closing the ELF file so sect.ReadAt works.
// If we remove this read (and the ones in decodetypeGcprog), we
// can close the file.
_, err := sect.ReadAt(r, int64(addr-sect.Addr))
if err != nil {
log.Fatal(err)
}
return r
}
Exitf("cannot find gcmask for %s", s.Name)
Expand Down
4 changes: 3 additions & 1 deletion src/cmd/oldlink/internal/ld/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -2010,7 +2010,9 @@ func ldshlibsyms(ctxt *Link, shlib string) {
Errorf(nil, "cannot open shared library: %s", libpath)
return
}
defer f.Close()
// Keep the file open as decodetypeGcprog needs to read from it.
// TODO: fix. Maybe mmap the file.
//defer f.Close()

hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/oldlink/internal/ld/pcln.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ func (ctxt *Link) pclntab() {
// set the resumption point to PC_B.
lastWasmAddr = uint32(r.Add)
}
if r.Type.IsDirectCall() && r.Sym != nil && r.Sym.Name == "runtime.deferreturn" {
if r.Type.IsDirectCall() && r.Sym != nil && (r.Sym.Name == "runtime.deferreturn" || r.Sym.Attr.DeferReturnTramp()) {
if ctxt.Arch.Family == sys.Wasm {
deferreturn = lastWasmAddr - 1
} else {
Expand Down
6 changes: 5 additions & 1 deletion src/cmd/oldlink/internal/ppc64/asm.go
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,8 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
// target is at some offset within the function. Calls to duff+8 and duff+256 must appear as
// distinct trampolines.

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

tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
if oName == "runtime.deferreturn" {
tramp.Attr.Set(sym.AttrDeferReturnTramp, true)
}
if tramp.Value == 0 {
break
}
Expand Down
6 changes: 5 additions & 1 deletion src/cmd/oldlink/internal/sym/attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ const (
// AttrReadOnly indicates whether the symbol's content (Symbol.P) is backed by
// read-only memory.
AttrReadOnly
// 19 attributes defined so far.
// AttrDeferReturnTramp indicates the symbol is a trampoline of a deferreturn
// call.
AttrDeferReturnTramp
// 20 attributes defined so far.
)

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

func (a Attribute) CgoExport() bool {
return a.CgoExportDynamic() || a.CgoExportStatic()
Expand Down

0 comments on commit 20afbe8

Please sign in to comment.