mirror of
https://github.com/golang/go
synced 2024-11-11 22:50:22 -07:00
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 <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Jeremy Faller <jeremy@golang.org>
This commit is contained in:
parent
fcf1cb2cf5
commit
20afbe86be
@ -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
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"cmd/oldlink/internal/sym"
|
||||
"debug/elf"
|
||||
"fmt"
|
||||
"log"
|
||||
)
|
||||
|
||||
// Decoding the type.* symbols. This has to be in sync with
|
||||
@ -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
|
||||
}
|
||||
@ -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)
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
@ -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
|
||||
}
|
||||
|
@ -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 }
|
||||
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user