mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.link] cmd/link: move more error handling into loader
Move the guts of ctxt.Errorf into loader.Loader, so that we can make calls to it from functions that have a "*loader.Loader" available but not a "ctxt *Link". This is needed to start converting hooks like "adddynrel" in the arch-specific portions of the linker to use loader APIs. Change-Id: Ieedd4583b66504be0e77d7f3fbadafe0d2307a69 Reviewed-on: https://go-review.googlesource.com/c/go/+/229497 Run-TryBot: Than McIntosh <thanm@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Jeremy Faller <jeremy@golang.org>
This commit is contained in:
parent
442fd182fb
commit
3d1007d28e
6 changed files with 70 additions and 42 deletions
|
|
@ -7,8 +7,6 @@ import (
|
|||
"cmd/internal/obj"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
|
|
@ -22,6 +20,7 @@ type symNameFn func(s loader.Sym) string
|
|||
|
||||
// ErrorReporter is used to make error reporting thread safe.
|
||||
type ErrorReporter struct {
|
||||
loader.ErrorReporter
|
||||
unresOnce sync.Once
|
||||
unresSyms map[unresolvedSymKey]bool
|
||||
unresMutex sync.Mutex
|
||||
|
|
@ -65,23 +64,3 @@ func (reporter *ErrorReporter) errorUnresolved(s *sym.Symbol, r *sym.Reloc) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Errorf method logs an error message.
|
||||
//
|
||||
// If more than 20 errors have been printed, exit with an error.
|
||||
//
|
||||
// Logging an error means that on exit cmd/link will delete any
|
||||
// output file and return a non-zero error code.
|
||||
// TODO: consolidate the various different versions of Errorf (
|
||||
// function, Link method, and ErrorReporter method).
|
||||
func (reporter *ErrorReporter) Errorf(s loader.Sym, format string, args ...interface{}) {
|
||||
if s != 0 && reporter.SymName != nil {
|
||||
sn := reporter.SymName(s)
|
||||
format = sn + ": " + format
|
||||
} else {
|
||||
format = fmt.Sprintf("sym %d: %s", s, format)
|
||||
}
|
||||
format += "\n"
|
||||
fmt.Fprintf(os.Stderr, format, args...)
|
||||
afterErrorAction()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -503,7 +503,7 @@ func (ctxt *Link) loadlib() {
|
|||
default:
|
||||
log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups)
|
||||
}
|
||||
ctxt.loader = loader.NewLoader(flags, elfsetstring)
|
||||
ctxt.loader = loader.NewLoader(flags, elfsetstring, &ctxt.ErrorReporter.ErrorReporter)
|
||||
ctxt.ErrorReporter.SymName = func(s loader.Sym) string {
|
||||
return ctxt.loader.SymName(s)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,12 +34,14 @@ package ld
|
|||
import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"log"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func linknew(arch *sys.Arch) *Link {
|
||||
ler := loader.ErrorReporter{AfterErrorAction: afterErrorAction}
|
||||
ctxt := &Link{
|
||||
Target: Target{Arch: arch},
|
||||
Syms: sym.NewSymbols(),
|
||||
|
|
@ -47,6 +49,7 @@ func linknew(arch *sys.Arch) *Link {
|
|||
Out: NewOutBuf(arch),
|
||||
LibraryByPkg: make(map[string]*sym.Library),
|
||||
numelfsym: 1,
|
||||
ErrorReporter: ErrorReporter{ErrorReporter: ler},
|
||||
}
|
||||
|
||||
if objabi.GOARCH != arch.Name {
|
||||
|
|
|
|||
|
|
@ -73,12 +73,12 @@ func Errorf(s *sym.Symbol, format string, args ...interface{}) {
|
|||
// Logging an error means that on exit cmd/link will delete any
|
||||
// output file and return a non-zero error code.
|
||||
func (ctxt *Link) Errorf(s loader.Sym, format string, args ...interface{}) {
|
||||
if s != 0 && ctxt.loader != nil {
|
||||
sn := ctxt.loader.SymName(s)
|
||||
format = sn + ": " + format
|
||||
} else {
|
||||
format = fmt.Sprintf("sym %d: %s", s, format)
|
||||
if ctxt.loader != nil {
|
||||
ctxt.loader.Errorf(s, format, args)
|
||||
return
|
||||
}
|
||||
// Note: this is not expected to happen very often.
|
||||
format = fmt.Sprintf("sym %d: %s", s, format)
|
||||
format += "\n"
|
||||
fmt.Fprintf(os.Stderr, format, args...)
|
||||
afterErrorAction()
|
||||
|
|
|
|||
|
|
@ -270,6 +270,8 @@ type Loader struct {
|
|||
|
||||
elfsetstring elfsetstringFunc
|
||||
|
||||
errorReporter *ErrorReporter
|
||||
|
||||
SymLookup func(name string, ver int) *sym.Symbol
|
||||
}
|
||||
|
||||
|
|
@ -301,9 +303,9 @@ const (
|
|||
FlagStrictDups = 1 << iota
|
||||
)
|
||||
|
||||
func NewLoader(flags uint32, elfsetstring elfsetstringFunc) *Loader {
|
||||
func NewLoader(flags uint32, elfsetstring elfsetstringFunc, reporter *ErrorReporter) *Loader {
|
||||
nbuiltin := goobj2.NBuiltin()
|
||||
return &Loader{
|
||||
ldr := &Loader{
|
||||
start: make(map[*oReader]Sym),
|
||||
objs: []objIdx{{}}, // reserve index 0 for nil symbol
|
||||
objSyms: []objSym{{}}, // reserve index 0 for nil symbol
|
||||
|
|
@ -332,8 +334,11 @@ func NewLoader(flags uint32, elfsetstring elfsetstringFunc) *Loader {
|
|||
builtinSyms: make([]Sym, nbuiltin),
|
||||
flags: flags,
|
||||
elfsetstring: elfsetstring,
|
||||
errorReporter: reporter,
|
||||
sects: []*sym.Section{nil}, // reserve index 0 for nil section
|
||||
}
|
||||
reporter.ldr = ldr
|
||||
return ldr
|
||||
}
|
||||
|
||||
// Add object file r, return the start index.
|
||||
|
|
@ -2754,6 +2759,42 @@ func (l *Loader) AssignTextSymbolOrder(libs []*sym.Library, intlibs []bool, exts
|
|||
return textp2
|
||||
}
|
||||
|
||||
// ErrorReporter is a helper class for reporting errors.
|
||||
type ErrorReporter struct {
|
||||
ldr *Loader
|
||||
AfterErrorAction func()
|
||||
}
|
||||
|
||||
// Errorf method logs an error message.
|
||||
//
|
||||
// After each error, the error actions function will be invoked; this
|
||||
// will either terminate the link immediately (if -h option given)
|
||||
// or it will keep a count and exit if more than 20 errors have been printed.
|
||||
//
|
||||
// Logging an error means that on exit cmd/link will delete any
|
||||
// output file and return a non-zero error code.
|
||||
//
|
||||
func (reporter *ErrorReporter) Errorf(s Sym, format string, args ...interface{}) {
|
||||
if s != 0 && reporter.ldr.SymName(s) != "" {
|
||||
format = reporter.ldr.SymName(s) + ": " + format
|
||||
} else {
|
||||
format = fmt.Sprintf("sym %d: %s", s, format)
|
||||
}
|
||||
format += "\n"
|
||||
fmt.Fprintf(os.Stderr, format, args...)
|
||||
reporter.AfterErrorAction()
|
||||
}
|
||||
|
||||
// GetErrorReporter returns the loader's associated error reporter.
|
||||
func (l *Loader) GetErrorReporter() *ErrorReporter {
|
||||
return l.errorReporter
|
||||
}
|
||||
|
||||
// Errorf method logs an error message. See ErrorReporter.Errorf for details.
|
||||
func (l *Loader) Errorf(s Sym, format string, args ...interface{}) {
|
||||
l.errorReporter.Errorf(s, format, args)
|
||||
}
|
||||
|
||||
// For debugging.
|
||||
func (l *Loader) Dump() {
|
||||
fmt.Println("objs")
|
||||
|
|
|
|||
|
|
@ -27,9 +27,16 @@ func addDummyObjSym(t *testing.T, ldr *Loader, or *oReader, name string) Sym {
|
|||
return s
|
||||
}
|
||||
|
||||
func TestAddMaterializedSymbol(t *testing.T) {
|
||||
func mkLoader() *Loader {
|
||||
edummy := func(s *sym.Symbol, str string, off int) {}
|
||||
ldr := NewLoader(0, edummy)
|
||||
er := ErrorReporter{}
|
||||
ldr := NewLoader(0, edummy, &er)
|
||||
er.ldr = ldr
|
||||
return ldr
|
||||
}
|
||||
|
||||
func TestAddMaterializedSymbol(t *testing.T) {
|
||||
ldr := mkLoader()
|
||||
dummyOreader := oReader{version: -1, syms: make([]Sym, 100)}
|
||||
or := &dummyOreader
|
||||
|
||||
|
|
@ -229,8 +236,7 @@ func sameRelocSlice(s1 *Relocs, s2 []Reloc) bool {
|
|||
type addFunc func(l *Loader, s Sym, s2 Sym) Sym
|
||||
|
||||
func TestAddDataMethods(t *testing.T) {
|
||||
edummy := func(s *sym.Symbol, str string, off int) {}
|
||||
ldr := NewLoader(0, edummy)
|
||||
ldr := mkLoader()
|
||||
dummyOreader := oReader{version: -1, syms: make([]Sym, 100)}
|
||||
or := &dummyOreader
|
||||
|
||||
|
|
@ -352,8 +358,7 @@ func TestAddDataMethods(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestOuterSub(t *testing.T) {
|
||||
edummy := func(s *sym.Symbol, str string, off int) {}
|
||||
ldr := NewLoader(0, edummy)
|
||||
ldr := mkLoader()
|
||||
dummyOreader := oReader{version: -1, syms: make([]Sym, 100)}
|
||||
or := &dummyOreader
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue