github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/cmd/link/ld/errors.go (about)

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