summaryrefslogtreecommitdiffstats
path: root/src/cmd/link/internal/ld/errors.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/link/internal/ld/errors.go')
-rw-r--r--src/cmd/link/internal/ld/errors.go67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/cmd/link/internal/ld/errors.go b/src/cmd/link/internal/ld/errors.go
new file mode 100644
index 0000000..b553d68
--- /dev/null
+++ b/src/cmd/link/internal/ld/errors.go
@@ -0,0 +1,67 @@
+// 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/loader"
+ "cmd/link/internal/sym"
+ "sync"
+)
+
+type unresolvedSymKey struct {
+ from loader.Sym // Symbol that referenced unresolved "to"
+ to loader.Sym // Unresolved symbol referenced by "from"
+}
+
+type symNameFn func(s loader.Sym) string
+
+// ErrorReporter is used to make error reporting thread safe.
+type ErrorReporter struct {
+ loader.ErrorReporter
+ unresSyms map[unresolvedSymKey]bool
+ unresMutex sync.Mutex
+ SymName symNameFn
+}
+
+// errorUnresolved prints unresolved symbol error for rs that is referenced from s.
+func (reporter *ErrorReporter) errorUnresolved(ldr *loader.Loader, s, rs loader.Sym) {
+ reporter.unresMutex.Lock()
+ defer reporter.unresMutex.Unlock()
+
+ if reporter.unresSyms == nil {
+ reporter.unresSyms = make(map[unresolvedSymKey]bool)
+ }
+ k := unresolvedSymKey{from: s, to: rs}
+ if !reporter.unresSyms[k] {
+ reporter.unresSyms[k] = true
+ name := ldr.SymName(rs)
+
+ // Try to find symbol under another ABI.
+ var reqABI, haveABI obj.ABI
+ haveABI = ^obj.ABI(0)
+ reqABI, ok := sym.VersionToABI(ldr.SymVersion(rs))
+ if ok {
+ for abi := obj.ABI(0); abi < obj.ABICount; abi++ {
+ v := sym.ABIToVersion(abi)
+ if v == -1 {
+ continue
+ }
+ if rs1 := ldr.Lookup(name, v); rs1 != 0 && ldr.SymType(rs1) != sym.Sxxx && ldr.SymType(rs1) != sym.SXREF {
+ haveABI = abi
+ }
+ }
+ }
+
+ // Give a special error message for main symbol (see #24809).
+ if name == "main.main" {
+ reporter.Errorf(s, "function main is undeclared in the main package")
+ } else if haveABI != ^obj.ABI(0) {
+ reporter.Errorf(s, "relocation target %s not defined for %s (but is defined for %s)", name, reqABI, haveABI)
+ } else {
+ reporter.Errorf(s, "relocation target %s not defined", name)
+ }
+ }
+}