if Symaddr(r.Sym) == 0 && r.Sym.Type != sym.SDYNIMPORT {
if r.Sym.File != s.File {
if !isRuntimeDepPkg(s.File) || !isRuntimeDepPkg(r.Sym.File) {
- Errorf(s, "unresolved inter-package jump to %s(%s)", r.Sym, r.Sym.File)
+ ctxt.ErrorUnresolved(s, r)
}
// runtime and its dependent packages may call to each other.
// they are fine, as they will be laid down together.
// resolve relocations in s.
func relocsym(ctxt *Link, s *sym.Symbol) {
- // undefinedSyms contains all undefined symbol names.
- // For successfull builds, it remains nil and does not cause any overhead.
- var undefinedSyms []string
-
for ri := int32(0); ri < int32(len(s.R)); ri++ {
r := &s.R[ri]
if r.Done {
continue
}
} else {
- reported := false
- for _, name := range undefinedSyms {
- if name == r.Sym.Name {
- reported = true
- break
- }
- }
- if !reported {
- // 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 {
- Errorf(s, "relocation target %s not defined", r.Sym.Name)
- }
- undefinedSyms = append(undefinedSyms, r.Sym.Name)
- }
+ ctxt.ErrorUnresolved(s, r)
continue
}
}
PackageShlib map[string]string
tramps []*sym.Symbol // trampolines
+
+ // unresolvedSymSet is a set of erroneous unresolved references.
+ // Used to avoid duplicated error messages.
+ unresolvedSymSet map[unresolvedSymKey]bool
+}
+
+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
+ // 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 {
+ Errorf(s, "relocation target %s not defined", r.Sym.Name)
+ }
+ }
}
// The smallest possible offset from the hardware stack pointer to a local