]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: remove some dependence on *Link
authorJeremy Faller <jeremy@golang.org>
Tue, 25 Feb 2020 02:03:54 +0000 (21:03 -0500)
committerJeremy Faller <jeremy@golang.org>
Fri, 28 Feb 2020 21:24:32 +0000 (21:24 +0000)
In an effort to make relocation application thread-safe remove another
dependence on context.

Change-Id: Ic53ea122cce72117fcebe56e386b710755f6eb68
Reviewed-on: https://go-review.googlesource.com/c/go/+/220838
Run-TryBot: Jeremy Faller <jeremy@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/errors.go [new file with mode: 0644]
src/cmd/link/internal/ld/link.go
src/cmd/link/internal/ld/xcoff.go
src/cmd/link/internal/ppc64/asm.go

index 0e34f3667f84152f5b304dca3c8d9c4c377ef585..e4d081c564dcf3264b8dd5d5377b53010afcf6d8 100644 (file)
@@ -100,7 +100,7 @@ func trampoline(ctxt *Link, s *sym.Symbol) {
                if Symaddr(r.Sym) == 0 && (r.Sym.Type != sym.SDYNIMPORT && r.Sym.Type != sym.SUNDEFEXT) {
                        if r.Sym.File != s.File {
                                if !isRuntimeDepPkg(s.File) || !isRuntimeDepPkg(r.Sym.File) {
-                                       ctxt.ErrorUnresolved(s, r)
+                                       ctxt.errorUnresolved(ctxt.Syms.ROLookup, s, r)
                                }
                                // runtime and its dependent packages may call to each other.
                                // they are fine, as they will be laid down together.
@@ -167,7 +167,7 @@ func relocsym(ctxt *Link, target *Target, s *sym.Symbol) {
                                        continue
                                }
                        } else {
-                               ctxt.ErrorUnresolved(s, r)
+                               ctxt.errorUnresolved(ctxt.Syms.ROLookup, s, r)
                                continue
                        }
                }
@@ -335,7 +335,7 @@ func relocsym(ctxt *Link, target *Target, s *sym.Symbol) {
                                // symbol which isn't in .data. However, as .text has the
                                // same address once loaded, this is possible.
                                if s.Sect.Seg == &Segdata {
-                                       Xcoffadddynrel(ctxt, s, r)
+                                       Xcoffadddynrel(target, s, r)
                                }
                        }
 
diff --git a/src/cmd/link/internal/ld/errors.go b/src/cmd/link/internal/ld/errors.go
new file mode 100644 (file)
index 0000000..0cbef03
--- /dev/null
@@ -0,0 +1,61 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+package ld
+
+import (
+       "cmd/internal/obj"
+       "cmd/link/internal/sym"
+       "sync"
+)
+
+type unresolvedSymKey struct {
+       from *sym.Symbol // Symbol that referenced unresolved "to"
+       to   *sym.Symbol // Unresolved symbol referenced by "from"
+}
+
+// ErrorReporter is used to make error reporting thread safe.
+type ErrorReporter struct {
+       unresOnce  sync.Once
+       unresSyms  map[unresolvedSymKey]bool
+       unresMutex sync.Mutex
+}
+
+type roLookup func(name string, v int) *sym.Symbol
+
+// errorUnresolved prints unresolved symbol error for r.Sym that is referenced from s.
+func (reporter *ErrorReporter) errorUnresolved(lookup roLookup, s *sym.Symbol, r *sym.Reloc) {
+       reporter.unresOnce.Do(func() { reporter.unresSyms = make(map[unresolvedSymKey]bool) })
+
+       k := unresolvedSymKey{from: s, to: r.Sym}
+       reporter.unresMutex.Lock()
+       defer reporter.unresMutex.Unlock()
+       if !reporter.unresSyms[k] {
+               reporter.unresSyms[k] = true
+
+               // Try to find symbol under another ABI.
+               var reqABI, haveABI obj.ABI
+               haveABI = ^obj.ABI(0)
+               reqABI, ok := sym.VersionToABI(int(r.Sym.Version))
+               if ok {
+                       for abi := obj.ABI(0); abi < obj.ABICount; abi++ {
+                               v := sym.ABIToVersion(abi)
+                               if v == -1 {
+                                       continue
+                               }
+                               if rs := lookup(r.Sym.Name, v); rs != nil && rs.Type != sym.Sxxx {
+                                       haveABI = abi
+                               }
+                       }
+               }
+
+               // Give a special error message for main symbol (see #24809).
+               if r.Sym.Name == "main.main" {
+                       Errorf(s, "function main is undeclared in the main package")
+               } else if haveABI != ^obj.ABI(0) {
+                       Errorf(s, "relocation target %s not defined for %s (but is defined for %s)", r.Sym.Name, reqABI, haveABI)
+               } else {
+                       Errorf(s, "relocation target %s not defined", r.Sym.Name)
+               }
+       }
+}
index fdc0b04aac7853856be98af224bac5c40ab2d7fb..677bc57d343fb4e26aab6833fd6cf9ed0867a5d4 100644 (file)
@@ -32,7 +32,6 @@ package ld
 
 import (
        "bufio"
-       "cmd/internal/obj"
        "cmd/internal/objabi"
        "cmd/internal/sys"
        "cmd/link/internal/loader"
@@ -52,6 +51,7 @@ type Shlib struct {
 // or for reading that input into the linker.
 type Link struct {
        Target
+       ErrorReporter
        Out *OutBuf
 
        Syms *sym.Symbols
@@ -81,10 +81,6 @@ type Link struct {
 
        tramps []*sym.Symbol // trampolines
 
-       // unresolvedSymSet is a set of erroneous unresolved references.
-       // Used to avoid duplicated error messages.
-       unresolvedSymSet map[unresolvedSymKey]bool
-
        // Used to implement field tracking.
        Reachparent map[*sym.Symbol]*sym.Symbol
 
@@ -104,48 +100,6 @@ type cgodata struct {
        directives [][]string
 }
 
-type unresolvedSymKey struct {
-       from *sym.Symbol // Symbol that referenced unresolved "to"
-       to   *sym.Symbol // Unresolved symbol referenced by "from"
-}
-
-// ErrorUnresolved prints unresolved symbol error for r.Sym that is referenced from s.
-func (ctxt *Link) ErrorUnresolved(s *sym.Symbol, r *sym.Reloc) {
-       if ctxt.unresolvedSymSet == nil {
-               ctxt.unresolvedSymSet = make(map[unresolvedSymKey]bool)
-       }
-
-       k := unresolvedSymKey{from: s, to: r.Sym}
-       if !ctxt.unresolvedSymSet[k] {
-               ctxt.unresolvedSymSet[k] = true
-
-               // Try to find symbol under another ABI.
-               var reqABI, haveABI obj.ABI
-               haveABI = ^obj.ABI(0)
-               reqABI, ok := sym.VersionToABI(int(r.Sym.Version))
-               if ok {
-                       for abi := obj.ABI(0); abi < obj.ABICount; abi++ {
-                               v := sym.ABIToVersion(abi)
-                               if v == -1 {
-                                       continue
-                               }
-                               if rs := ctxt.Syms.ROLookup(r.Sym.Name, v); rs != nil && rs.Type != sym.Sxxx {
-                                       haveABI = abi
-                               }
-                       }
-               }
-
-               // Give a special error message for main symbol (see #24809).
-               if r.Sym.Name == "main.main" {
-                       Errorf(s, "function main is undeclared in the main package")
-               } else if haveABI != ^obj.ABI(0) {
-                       Errorf(s, "relocation target %s not defined for %s (but is defined for %s)", r.Sym.Name, reqABI, haveABI)
-               } else {
-                       Errorf(s, "relocation target %s not defined", r.Sym.Name)
-               }
-       }
-}
-
 // The smallest possible offset from the hardware stack pointer to a local
 // variable on the stack. Architectures that use a link register save its value
 // on the stack in the function prologue and so always have a pointer between
index 5b48e3c650c9dbafe2aba67a8844a5816058e874..55a404cfb0071dbc10943cbd8f24d0872ad1d475 100644 (file)
@@ -1096,8 +1096,8 @@ func (f *xcoffFile) adddynimpsym(ctxt *Link, s *sym.Symbol) {
 
 // Xcoffadddynrel adds a dynamic relocation in a XCOFF file.
 // This relocation will be made by the loader.
-func Xcoffadddynrel(ctxt *Link, s *sym.Symbol, r *sym.Reloc) bool {
-       if ctxt.LinkMode == LinkExternal {
+func Xcoffadddynrel(target *Target, s *sym.Symbol, r *sym.Reloc) bool {
+       if target.IsExternal() {
                return true
        }
        if s.Type <= sym.SPCLNTAB {
index 9fbcff551a997432e9e34844ee1dfa08d5ee8105..99173a5b9cacb308485e918fe9fd79870bc6fd81 100644 (file)
@@ -266,7 +266,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
        if ctxt.IsELF {
                return addelfdynrel(ctxt, s, r)
        } else if ctxt.HeadType == objabi.Haix {
-               return ld.Xcoffadddynrel(ctxt, s, r)
+               return ld.Xcoffadddynrel(&ctxt.Target, s, r)
        }
        return false
 }