]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: move more error handling into loader
authorThan McIntosh <thanm@google.com>
Wed, 22 Apr 2020 19:16:06 +0000 (15:16 -0400)
committerThan McIntosh <thanm@google.com>
Fri, 24 Apr 2020 13:41:49 +0000 (13:41 +0000)
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>
src/cmd/link/internal/ld/errors.go
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/ld/sym.go
src/cmd/link/internal/ld/util.go
src/cmd/link/internal/loader/loader.go
src/cmd/link/internal/loader/loader_test.go

index e66c518b85b276da9f4af00091a0833ba4203fbc..61289b4798a1027cde011368035b8a9376bd06e7 100644 (file)
@@ -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()
-}
index 429c2641fb98f47e45ab55ea9415068f2ed9ceab..675103ee452ba503d8785bea611f130f8de8247c 100644 (file)
@@ -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)
        }
index 6a8b3dbed1447d81021d53ce3018369578f1730d..7a6c4e43e93513ce611804ed80a0b7cc1b9a17fa 100644 (file)
@@ -34,19 +34,22 @@ 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(),
-               outSem:       make(chan int, 2*runtime.GOMAXPROCS(0)),
-               Out:          NewOutBuf(arch),
-               LibraryByPkg: make(map[string]*sym.Library),
-               numelfsym:    1,
+               Target:        Target{Arch: arch},
+               Syms:          sym.NewSymbols(),
+               outSem:        make(chan int, 2*runtime.GOMAXPROCS(0)),
+               Out:           NewOutBuf(arch),
+               LibraryByPkg:  make(map[string]*sym.Library),
+               numelfsym:     1,
+               ErrorReporter: ErrorReporter{ErrorReporter: ler},
        }
 
        if objabi.GOARCH != arch.Name {
index 9f257b8fc0ab03e99610dca575ac865a3f83d61a..b8c9ce28b0ae6ada7c9a7089df148a902d02d094 100644 (file)
@@ -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()
index c0893daeceb34cddcaba9ac76dca4dbe618020a7..458c87a6b60ce646dfcded0d1c223df956e60e5d 100644 (file)
@@ -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")
index b2f823d17e1f63848a43334e9d4a95dff88346a4..60ef69afb994927f2444585ca4b172bec3bfb6d8 100644 (file)
@@ -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