Source file src/cmd/link/internal/ld/errors.go

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ld
     6  
     7  import (
     8  	"cmd/internal/obj"
     9  	"cmd/link/internal/loader"
    10  	"cmd/link/internal/sym"
    11  	"sync"
    12  )
    13  
    14  type unresolvedSymKey struct {
    15  	from loader.Sym // Symbol that referenced unresolved "to"
    16  	to   loader.Sym // Unresolved symbol referenced by "from"
    17  }
    18  
    19  type symNameFn func(s loader.Sym) string
    20  
    21  // ErrorReporter is used to make error reporting thread safe.
    22  type ErrorReporter struct {
    23  	loader.ErrorReporter
    24  	unresSyms  map[unresolvedSymKey]bool
    25  	unresMutex sync.Mutex
    26  	SymName    symNameFn
    27  }
    28  
    29  // errorUnresolved prints unresolved symbol error for rs that is referenced from s.
    30  func (reporter *ErrorReporter) errorUnresolved(ldr *loader.Loader, s, rs loader.Sym) {
    31  	reporter.unresMutex.Lock()
    32  	defer reporter.unresMutex.Unlock()
    33  
    34  	if reporter.unresSyms == nil {
    35  		reporter.unresSyms = make(map[unresolvedSymKey]bool)
    36  	}
    37  	k := unresolvedSymKey{from: s, to: rs}
    38  	if !reporter.unresSyms[k] {
    39  		reporter.unresSyms[k] = true
    40  		name := ldr.SymName(rs)
    41  
    42  		// Try to find symbol under another ABI.
    43  		var reqABI, haveABI obj.ABI
    44  		haveABI = ^obj.ABI(0)
    45  		reqABI, ok := sym.VersionToABI(ldr.SymVersion(rs))
    46  		if ok {
    47  			for abi := obj.ABI(0); abi < obj.ABICount; abi++ {
    48  				v := sym.ABIToVersion(abi)
    49  				if v == -1 {
    50  					continue
    51  				}
    52  				if rs1 := ldr.Lookup(name, v); rs1 != 0 && ldr.SymType(rs1) != sym.Sxxx && ldr.SymType(rs1) != sym.SXREF {
    53  					haveABI = abi
    54  				}
    55  			}
    56  		}
    57  
    58  		// Give a special error message for main symbol (see #24809).
    59  		if name == "main.main" {
    60  			reporter.Errorf(s, "function main is undeclared in the main package")
    61  		} else if haveABI != ^obj.ABI(0) {
    62  			reporter.Errorf(s, "relocation target %s not defined for %s (but is defined for %s)", name, reqABI, haveABI)
    63  		} else {
    64  			reporter.Errorf(s, "relocation target %s not defined", name)
    65  		}
    66  	}
    67  }
    68  

View as plain text