| |
| |
| |
|
|
| package ld |
|
|
| import ( |
| "cmd/internal/obj" |
| "cmd/link/internal/loader" |
| "cmd/link/internal/sym" |
| "sync" |
| ) |
|
|
| type unresolvedSymKey struct { |
| from loader.Sym |
| to loader.Sym |
| } |
|
|
| type symNameFn func(s loader.Sym) string |
|
|
| |
| type ErrorReporter struct { |
| loader.ErrorReporter |
| unresSyms map[unresolvedSymKey]bool |
| unresMutex sync.Mutex |
| SymName symNameFn |
| } |
|
|
| |
| 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) |
|
|
| |
| 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 |
| } |
| } |
| } |
|
|
| |
| 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) |
| } |
| } |
| } |
|
|