]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/oldlink: port bug fixes to old linker
authorCherry Zhang <cherryyz@google.com>
Mon, 6 Jul 2020 18:22:38 +0000 (14:22 -0400)
committerCherry Zhang <cherryyz@google.com>
Mon, 6 Jul 2020 20:17:51 +0000 (20:17 +0000)
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>
src/cmd/oldlink/internal/arm/asm.go
src/cmd/oldlink/internal/ld/decodesym.go
src/cmd/oldlink/internal/ld/lib.go
src/cmd/oldlink/internal/ld/pcln.go
src/cmd/oldlink/internal/ppc64/asm.go
src/cmd/oldlink/internal/sym/attribute.go

index 9dc4ca0f2a9379eaa1ab42405bd286c27e0fb62d..77338e467292ca816e0cdd14b8fbf98bd328e63f 100644 (file)
@@ -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
index 0676e94e2c0b27a06aa0897642818472820aeb81..6c596ec78e1b09ab0d688056e29aa096235652bf 100644 (file)
@@ -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)
index cc42901cb60418269c2e479adeecdb1cfcd6aefa..499602f9be03b85e11b45870518a47f055d2060a 100644 (file)
@@ -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 {
index 7d53ab8ad4aa670aa5d19a716123e1056612e579..ed2e8f9e2b77d573954f082696eb085c25a4e8a3 100644 (file)
@@ -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 {
index 6b57abf5643e313c42b38b7ec7c16d0f36db8906..612f9aa8d27db58e36471e148986dd40c506d620 100644 (file)
@@ -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
                                }
index 4b69bf32d07f15fbcb288b91c7e60c68c015f2af..773b6a4ee703727dc789434cc80185764c9a3c34 100644 (file)
@@ -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()