cmd/link: replace ld.Link.Diag with ld.Errorf

Instead of using ctxt.Cursym, Errorf takes an explicit *Symbol
parameter. This removes most uses of Cursym and means the *Link
context object is needed in fewer parts of the linker.

All transformations done manually, as wiring Cursym is tricky.

Change-Id: Ief88b00b73904224675c0035684c3a84c19249d7
Reviewed-on: https://go-review.googlesource.com/29369
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Michael Hudson-Doyle <michael.hudson@canonical.com>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
David Crawshaw 2016-09-17 09:39:33 -04:00
parent bd3d00e310
commit 5a597e2d29
21 changed files with 410 additions and 404 deletions

View file

@ -103,8 +103,8 @@ type Arch struct {
Elfreloc1 func(*Link, *Reloc, int64) int
Elfsetupplt func(*Link)
Gentext func(*Link)
Machoreloc1 func(*Link, *Reloc, int64) int
PEreloc1 func(*Link, *Reloc, int64) bool
Machoreloc1 func(*Symbol, *Reloc, int64) int
PEreloc1 func(*Symbol, *Reloc, int64) bool
Wput func(uint16)
Lput func(uint32)
Vput func(uint64)
@ -305,20 +305,11 @@ func libinit(ctxt *Link) {
case BuildmodeShared, BuildmodePlugin:
// No *flagEntrySymbol for -buildmode=shared and plugin
default:
ctxt.Diag("unknown *flagEntrySymbol for buildmode %v", Buildmode)
Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", Buildmode)
}
}
}
func Exitf(format string, a ...interface{}) {
fmt.Fprintf(os.Stderr, os.Args[0]+": "+format+"\n", a...)
if coutbuf.f != nil {
coutbuf.f.Close()
mayberemoveoutfile()
}
Exit(2)
}
func errorexit() {
if coutbuf.f != nil {
if nerrors != 0 {
@ -493,7 +484,7 @@ func (ctxt *Link) loadlib() {
tlsg.Type = obj.STLSBSS
tlsg.Size = int64(SysArch.PtrSize)
} else if tlsg.Type != obj.SDYNIMPORT {
ctxt.Diag("internal error: runtime declared tlsg variable %d", tlsg.Type)
Errorf(nil, "runtime declared tlsg variable %v", tlsg.Type)
}
tlsg.Attr |= AttrReachable
ctxt.Tlsg = tlsg
@ -693,12 +684,12 @@ func objfile(ctxt *Link, lib *Library) {
l := nextar(f, off, &arhdr)
var pname string
if l <= 0 {
ctxt.Diag("%s: short read on archive file symbol header", lib.File)
Errorf(nil, "%s: short read on archive file symbol header", lib.File)
goto out
}
if !strings.HasPrefix(arhdr.name, pkgname) {
ctxt.Diag("%s: cannot find package header", lib.File)
Errorf(nil, "%s: cannot find package header", lib.File)
goto out
}
@ -706,7 +697,7 @@ func objfile(ctxt *Link, lib *Library) {
before := f.Offset()
pkgdefBytes := make([]byte, atolwhex(arhdr.size))
if _, err := io.ReadFull(f, pkgdefBytes); err != nil {
ctxt.Diag("%s: short read on archive file symbol header: %v", lib.File, err)
Errorf(nil, "%s: short read on archive file symbol header: %v", lib.File, err)
}
hash := sha1.Sum(pkgdefBytes)
lib.hash = hash[:]
@ -1119,7 +1110,7 @@ func (l *Link) hostlink() {
// new and we test for its support first.
src := filepath.Join(*flagTmpdir, "trivial.c")
if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
l.Diag("WriteFile trivial.c failed: %v", err)
Errorf(nil, "WriteFile trivial.c failed: %v", err)
}
cmd := exec.Command(argv[0], "-c", "-no-pie", "trivial.c")
cmd.Dir = *flagTmpdir
@ -1174,7 +1165,6 @@ func (l *Link) hostlink() {
if !SysArch.InFamily(sys.ARM, sys.ARM64) {
dsym := filepath.Join(*flagTmpdir, "go.dwarf")
if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
l.Cursym = nil
Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
}
// Skip combining if `dsymutil` didn't generate a file. See #11994.
@ -1184,12 +1174,10 @@ func (l *Link) hostlink() {
// For os.Rename to work reliably, must be in same directory as outfile.
combinedOutput := *flagOutfile + "~"
if err := machoCombineDwarf(*flagOutfile, dsym, combinedOutput); err != nil {
l.Cursym = nil
Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
}
os.Remove(*flagOutfile)
if err := os.Rename(combinedOutput, *flagOutfile); err != nil {
l.Cursym = nil
Exitf("%s: %v", os.Args[0], err)
}
}
@ -1243,7 +1231,7 @@ func ldobj(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string, file
/* check the header */
line, err := f.ReadString('\n')
if err != nil {
ctxt.Diag("truncated object file: %s: %v", pn, err)
Errorf(nil, "truncated object file: %s: %v", pn, err)
return nil
}
@ -1255,11 +1243,11 @@ func ldobj(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string, file
if line == SysArch.Name {
// old header format: just $GOOS
ctxt.Diag("%s: stale object file", pn)
Errorf(nil, "%s: stale object file", pn)
return nil
}
ctxt.Diag("%s: not an object file", pn)
Errorf(nil, "%s: not an object file", pn)
return nil
}
@ -1268,7 +1256,7 @@ func ldobj(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string, file
line = strings.TrimRight(line, "\n")
if !strings.HasPrefix(line[10:]+" ", t) && !*flagF {
ctxt.Diag("%s: object is [%s] expected [%s]", pn, line[10:], t)
Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], t)
return nil
}
@ -1279,7 +1267,7 @@ func ldobj(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string, file
if theline == "" {
theline = line[10:]
} else if theline != line[10:] {
ctxt.Diag("%s: object is [%s] expected [%s]", pn, line[10:], theline)
Errorf(nil, "%s: object is [%s] expected [%s]", pn, line[10:], theline)
return nil
}
}
@ -1295,7 +1283,7 @@ func ldobj(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string, file
c2 = c3
c3 = bgetc(f)
if c3 == -1 {
ctxt.Diag("truncated object file: %s", pn)
Errorf(nil, "truncated object file: %s", pn)
return nil
}
}
@ -1314,11 +1302,11 @@ func readelfsymboldata(ctxt *Link, f *elf.File, sym *elf.Symbol) []byte {
data := make([]byte, sym.Size)
sect := f.Sections[sym.Section]
if sect.Type != elf.SHT_PROGBITS && sect.Type != elf.SHT_NOTE {
ctxt.Diag("reading %s from non-data section", sym.Name)
Errorf(nil, "reading %s from non-data section", sym.Name)
}
n, err := sect.ReadAt(data, int64(sym.Value-sect.Addr))
if uint64(n) != sym.Size {
ctxt.Diag("reading contents of %s: %v", sym.Name, err)
Errorf(nil, "reading contents of %s: %v", sym.Name, err)
}
return data
}
@ -1379,7 +1367,7 @@ func findshlib(ctxt *Link, shlib string) string {
return libpath
}
}
ctxt.Diag("cannot find shared library: %s", shlib)
Errorf(nil, "cannot find shared library: %s", shlib)
return ""
}
@ -1399,26 +1387,26 @@ func ldshlibsyms(ctxt *Link, shlib string) {
f, err := elf.Open(libpath)
if err != nil {
ctxt.Diag("cannot open shared library: %s", libpath)
Errorf(nil, "cannot open shared library: %s", libpath)
return
}
hash, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GOABIHASH_TAG)
if err != nil {
ctxt.Diag("cannot read ABI hash from shared library %s: %v", libpath, err)
Errorf(nil, "cannot read ABI hash from shared library %s: %v", libpath, err)
return
}
depsbytes, err := readnote(f, ELF_NOTE_GO_NAME, ELF_NOTE_GODEPS_TAG)
if err != nil {
ctxt.Diag("cannot read dep list from shared library %s: %v", libpath, err)
Errorf(nil, "cannot read dep list from shared library %s: %v", libpath, err)
return
}
deps := strings.Split(string(depsbytes), "\n")
syms, err := f.DynamicSymbols()
if err != nil {
ctxt.Diag("cannot read symbols from shared library: %s", libpath)
Errorf(nil, "cannot read symbols from shared library: %s", libpath)
return
}
gcdataLocations := make(map[uint64]*Symbol)
@ -1459,7 +1447,7 @@ func ldshlibsyms(ctxt *Link, shlib string) {
if err == io.EOF {
break
} else if err != nil {
ctxt.Diag("reading relocation failed %v", err)
Errorf(nil, "reading relocation failed %v", err)
return
}
t := elf.R_AARCH64(rela.Info & 0xffff)
@ -1600,7 +1588,6 @@ func (ctxt *Link) dostkcheck() {
}
if s.Attr.NoSplit() {
ctxt.Cursym = s
ch.sym = s
stkcheck(ctxt, &ch, 0)
}
@ -1608,7 +1595,6 @@ func (ctxt *Link) dostkcheck() {
for _, s := range ctxt.Textp {
if !s.Attr.NoSplit() {
ctxt.Cursym = s
ch.sym = s
stkcheck(ctxt, &ch, 0)
}
@ -1630,7 +1616,7 @@ func stkcheck(ctxt *Link, up *chain, depth int) int {
}
if depth > 100 {
ctxt.Diag("nosplit stack check too deep")
Errorf(s, "nosplit stack check too deep")
stkbroke(ctxt, up, 0)
return -1
}
@ -1642,7 +1628,8 @@ func stkcheck(ctxt *Link, up *chain, depth int) int {
// TODO(mwhudson): actually think about this.
if depth == 1 && s.Type != obj.SXREF && !ctxt.DynlinkingGo() &&
Buildmode != BuildmodeCArchive && Buildmode != BuildmodePIE && Buildmode != BuildmodeCShared && Buildmode != BuildmodePlugin {
ctxt.Diag("call to external function %s", s.Name)
Errorf(s, "call to external function")
}
return -1
}
@ -1729,7 +1716,7 @@ func stkcheck(ctxt *Link, up *chain, depth int) int {
}
func stkbroke(ctxt *Link, ch *chain, limit int) {
ctxt.Diag("nosplit stack overflow")
Errorf(ch.sym, "nosplit stack overflow")
stkprint(ctxt, ch, limit)
}
@ -1866,16 +1853,16 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *
if !s.Attr.Reachable() {
continue
}
put(ctxt, s, s.Name, DataSym, Symaddr(ctxt, s), s.Gotype)
put(ctxt, s, s.Name, DataSym, Symaddr(s), s.Gotype)
case obj.SBSS, obj.SNOPTRBSS:
if !s.Attr.Reachable() {
continue
}
if len(s.P) > 0 {
ctxt.Diag("%s should not be bss (size=%d type=%d special=%v)", s.Name, len(s.P), s.Type, s.Attr.Special())
Errorf(s, "should not be bss (size=%d type=%d special=%v)", len(s.P), s.Type, s.Attr.Special())
}
put(ctxt, s, s.Name, BSSSym, Symaddr(ctxt, s), s.Gotype)
put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype)
case obj.SFILE:
put(ctxt, nil, s.Name, FileSym, s.Value, nil)
@ -1893,7 +1880,7 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *
case obj.STLSBSS:
if Linkmode == LinkExternal && Headtype != obj.Hopenbsd {
put(ctxt, s, s.Name, TLSSym, Symaddr(ctxt, s), s.Gotype)
put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype)
}
}
}
@ -1947,9 +1934,9 @@ func genasmsym(ctxt *Link, put func(*Link, *Symbol, string, SymbolType, int64, *
}
}
func Symaddr(ctxt *Link, s *Symbol) int64 {
func Symaddr(s *Symbol) int64 {
if !s.Attr.Reachable() {
ctxt.Diag("unreachable symbol in symaddr - %s", s.Name)
Errorf(s, "unreachable symbol in symaddr")
}
return s.Value
}
@ -1963,14 +1950,14 @@ func (ctxt *Link) xdefine(p string, t obj.SymKind, v int64) {
s.Attr |= AttrLocal
}
func datoff(ctxt *Link, addr int64) int64 {
func datoff(s *Symbol, addr int64) int64 {
if uint64(addr) >= Segdata.Vaddr {
return int64(uint64(addr) - Segdata.Vaddr + Segdata.Fileoff)
}
if uint64(addr) >= Segtext.Vaddr {
return int64(uint64(addr) - Segtext.Vaddr + Segtext.Fileoff)
}
ctxt.Diag("datoff %#x", addr)
Errorf(s, "invalid datoff %#x", addr)
return 0
}
@ -1984,7 +1971,7 @@ func Entryvalue(ctxt *Link) int64 {
return *FlagTextAddr
}
if s.Type != obj.STEXT {
ctxt.Diag("entry not text: %s", s.Name)
Errorf(s, "entry not text")
}
return s.Value
}
@ -1992,17 +1979,16 @@ func Entryvalue(ctxt *Link) int64 {
func undefsym(ctxt *Link, s *Symbol) {
var r *Reloc
ctxt.Cursym = s
for i := 0; i < len(s.R); i++ {
r = &s.R[i]
if r.Sym == nil { // happens for some external ARM relocs
continue
}
if r.Sym.Type == obj.Sxxx || r.Sym.Type == obj.SXREF {
ctxt.Diag("undefined: %s", r.Sym.Name)
Errorf(s, "undefined: %q", r.Sym.Name)
}
if !r.Sym.Attr.Reachable() {
ctxt.Diag("use of unreachable symbol: %s", r.Sym.Name)
Errorf(s, "relocation target %q", r.Sym.Name)
}
}
}
@ -2039,23 +2025,6 @@ func (ctxt *Link) callgraph() {
}
}
func (ctxt *Link) Diag(format string, args ...interface{}) {
tn := ""
sep := ""
if ctxt.Cursym != nil {
tn = ctxt.Cursym.Name
sep = ": "
}
fmt.Printf("%s%s%s\n", tn, sep, fmt.Sprintf(format, args...))
nerrors++
if *flagH {
panic("error")
}
if nerrors > 20 {
Exitf("too many errors")
}
}
func Rnd(v int64, r int64) int64 {
if r <= 0 {
return v