1
0
mirror of https://github.com/golang/go synced 2024-11-05 18:36:10 -07:00

cmd/internal/ld: replace Diag;Errorexit with Exitf

I have left the Diag calls in place where I believe Ctxt.Cursym != nil
which means this CL is not the improvement I had hoped for. However
it is now safe to call Exitf whereever you are in the linker, which
makes it easier to reason about some code.

Change-Id: I8261e761ca9719f7d216e2747314adfe464e3337
Reviewed-on: https://go-review.googlesource.com/8668
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
David Crawshaw 2015-04-09 07:37:17 -04:00
parent c5befcf0a7
commit 7816a096d9
19 changed files with 98 additions and 196 deletions

View File

@ -93,9 +93,7 @@ func adddynrel(s *ld.LSym, r *ld.Reloc) {
return return
case 256 + ld.R_ARM_THM_PC22: // R_ARM_THM_CALL case 256 + ld.R_ARM_THM_PC22: // R_ARM_THM_CALL
ld.Diag("R_ARM_THM_CALL, are you using -marm?") ld.Exitf("R_ARM_THM_CALL, are you using -marm?")
ld.Errorexit()
return return
case 256 + ld.R_ARM_GOT32: // R_ARM_GOT_BREL case 256 + ld.R_ARM_GOT32: // R_ARM_GOT_BREL

View File

@ -105,9 +105,7 @@ func archinit() {
switch ld.HEADTYPE { switch ld.HEADTYPE {
default: default:
ld.Diag("unknown -H option") ld.Exitf("unknown -H option: %v", ld.HEADTYPE)
ld.Errorexit()
fallthrough
case ld.Hplan9: /* plan 9 */ case ld.Hplan9: /* plan 9 */
ld.HEADR = 32 ld.HEADR = 32

View File

@ -118,9 +118,7 @@ func archinit() {
switch ld.HEADTYPE { switch ld.HEADTYPE {
default: default:
ld.Diag("unknown -H option") ld.Exitf("unknown -H option: %v", ld.HEADTYPE)
ld.Errorexit()
fallthrough
case ld.Hplan9: /* plan 9 */ case ld.Hplan9: /* plan 9 */
ld.HEADR = 32 + 8 ld.HEADR = 32 + 8

View File

@ -107,9 +107,7 @@ func archinit() {
switch ld.HEADTYPE { switch ld.HEADTYPE {
default: default:
ld.Diag("unknown -H option") ld.Exitf("unknown -H option: %v", ld.HEADTYPE)
ld.Errorexit()
fallthrough
case ld.Hplan9: /* plan 9 */ case ld.Hplan9: /* plan 9 */
ld.HEADR = 32 ld.HEADR = 32

View File

@ -107,9 +107,7 @@ func archinit() {
switch ld.HEADTYPE { switch ld.HEADTYPE {
default: default:
ld.Diag("unknown -H option") ld.Exitf("unknown -H option: %v", ld.HEADTYPE)
ld.Errorexit()
fallthrough
case ld.Hplan9: /* plan 9 */ case ld.Hplan9: /* plan 9 */
ld.HEADR = 32 ld.HEADR = 32

View File

@ -111,9 +111,7 @@ func archinit() {
switch ld.HEADTYPE { switch ld.HEADTYPE {
default: default:
ld.Diag("unknown -H option") ld.Exitf("unknown -H option: %v", ld.HEADTYPE)
ld.Errorexit()
fallthrough
case ld.Hplan9: /* plan 9 */ case ld.Hplan9: /* plan 9 */
ld.HEADR = 32 ld.HEADR = 32

View File

@ -482,7 +482,7 @@ func relocsym(s *LSym) {
// 64-bit architectures so as to be future-proof. // 64-bit architectures so as to be future-proof.
if int32(o) < 0 && Thearch.Ptrsize > 4 && siz == 4 { if int32(o) < 0 && Thearch.Ptrsize > 4 && siz == 4 {
Diag("non-pc-relative relocation address is too big: %#x (%#x + %#x)", uint64(o), Symaddr(r.Sym), r.Add) Diag("non-pc-relative relocation address is too big: %#x (%#x + %#x)", uint64(o), Symaddr(r.Sym), r.Add)
Errorexit() errorexit()
} }
// r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call. // r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call.
@ -713,7 +713,7 @@ func blk(start *LSym, addr int64, size int64) {
Ctxt.Cursym = sym Ctxt.Cursym = sym
if sym.Value < addr { if sym.Value < addr {
Diag("phase error: addr=%#x but sym=%#x type=%d", int64(addr), int64(sym.Value), sym.Type) Diag("phase error: addr=%#x but sym=%#x type=%d", int64(addr), int64(sym.Value), sym.Type)
Errorexit() errorexit()
} }
for ; addr < sym.Value; addr++ { for ; addr < sym.Value; addr++ {
@ -731,7 +731,7 @@ func blk(start *LSym, addr int64, size int64) {
} }
if addr != sym.Value+sym.Size { if addr != sym.Value+sym.Size {
Diag("phase error: addr=%#x value+size=%#x", int64(addr), int64(sym.Value)+sym.Size) Diag("phase error: addr=%#x value+size=%#x", int64(addr), int64(sym.Value)+sym.Size)
Errorexit() errorexit()
} }
if sym.Value+sym.Size >= eaddr { if sym.Value+sym.Size >= eaddr {

View File

@ -35,10 +35,10 @@ func decode_inuxi(p []byte, sz int) uint64 {
return uint64(Ctxt.Arch.ByteOrder.Uint32(p)) return uint64(Ctxt.Arch.ByteOrder.Uint32(p))
case 8: case 8:
return Ctxt.Arch.ByteOrder.Uint64(p) return Ctxt.Arch.ByteOrder.Uint64(p)
default:
Exitf("dwarf: decode inuxi %d", sz)
panic("unreachable")
} }
Diag("dwarf: decode inuxi %d", sz)
Errorexit()
return 0
} }
func commonsize() int { func commonsize() int {

View File

@ -674,13 +674,11 @@ notfound:
return nil return nil
} }
func find_or_diag(die *DWDie, name string) *DWDie { func mustFind(die *DWDie, name string) *DWDie {
r := find(die, name) r := find(die, name)
if r == nil { if r == nil {
Diag("dwarf find: %s %p has no %s", getattr(die, DW_AT_name).data, die, name) Exitf("dwarf find: %s %p has no %s", getattr(die, DW_AT_name).data, die, name)
Errorexit()
} }
return r return r
} }
@ -843,9 +841,7 @@ func putattr(abbrev int, form int, cls int, value int64, data interface{}) {
DW_FORM_indirect: // (see Section 7.5.3) DW_FORM_indirect: // (see Section 7.5.3)
fallthrough fallthrough
default: default:
Diag("dwarf: unsupported attribute form %d / class %d", form, cls) Exitf("dwarf: unsupported attribute form %d / class %d", form, cls)
Errorexit()
} }
} }
@ -924,8 +920,7 @@ func newabslocexprattr(die *DWDie, addr int64, sym *LSym) {
func lookup_or_diag(n string) *LSym { func lookup_or_diag(n string) *LSym {
s := Linkrlookup(Ctxt, n, 0) s := Linkrlookup(Ctxt, n, 0)
if s == nil || s.Size == 0 { if s == nil || s.Size == 0 {
Diag("dwarf: missing type: %s", n) Exitf("dwarf: missing type: %s", n)
Errorexit()
} }
return s return s
@ -961,12 +956,12 @@ func dotypedef(parent *DWDie, name string, def *DWDie) {
// Define gotype, for composite ones recurse into constituents. // Define gotype, for composite ones recurse into constituents.
func defgotype(gotype *LSym) *DWDie { func defgotype(gotype *LSym) *DWDie {
if gotype == nil { if gotype == nil {
return find_or_diag(&dwtypes, "<unspecified>") return mustFind(&dwtypes, "<unspecified>")
} }
if !strings.HasPrefix(gotype.Name, "type.") { if !strings.HasPrefix(gotype.Name, "type.") {
Diag("dwarf: type name doesn't start with \".type\": %s", gotype.Name) Diag("dwarf: type name doesn't start with \".type\": %s", gotype.Name)
return find_or_diag(&dwtypes, "<unspecified>") return mustFind(&dwtypes, "<unspecified>")
} }
name := gotype.Name[5:] // could also decode from Type.string name := gotype.Name[5:] // could also decode from Type.string
@ -1032,7 +1027,7 @@ func defgotype(gotype *LSym) *DWDie {
// use actual length not upper bound; correct for 0-length arrays. // use actual length not upper bound; correct for 0-length arrays.
newattr(fld, DW_AT_count, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0) newattr(fld, DW_AT_count, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0)
newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr")) newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
case obj.KindChan: case obj.KindChan:
die = newdie(&dwtypes, DW_ABRV_CHANTYPE, name) die = newdie(&dwtypes, DW_ABRV_CHANTYPE, name)
@ -1043,7 +1038,7 @@ func defgotype(gotype *LSym) *DWDie {
case obj.KindFunc: case obj.KindFunc:
die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name) die = newdie(&dwtypes, DW_ABRV_FUNCTYPE, name)
dotypedef(&dwtypes, name, die) dotypedef(&dwtypes, name, die)
newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "void")) newrefattr(die, DW_AT_type, mustFind(&dwtypes, "void"))
nfields := decodetype_funcincount(gotype) nfields := decodetype_funcincount(gotype)
var fld *DWDie var fld *DWDie
var s *LSym var s *LSym
@ -1125,7 +1120,7 @@ func defgotype(gotype *LSym) *DWDie {
default: default:
Diag("dwarf: definition of unknown kind %d: %s", kind, gotype.Name) Diag("dwarf: definition of unknown kind %d: %s", kind, gotype.Name)
die = newdie(&dwtypes, DW_ABRV_TYPEDECL, name) die = newdie(&dwtypes, DW_ABRV_TYPEDECL, name)
newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "<unspecified>")) newrefattr(die, DW_AT_type, mustFind(&dwtypes, "<unspecified>"))
} }
newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, int64(kind), 0) newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, int64(kind), 0)
@ -1173,7 +1168,7 @@ func copychildren(dst *DWDie, src *DWDie) {
// Search children (assumed to have DW_TAG_member) for the one named // Search children (assumed to have DW_TAG_member) for the one named
// field and set its DW_AT_type to dwtype // field and set its DW_AT_type to dwtype
func substitutetype(structdie *DWDie, field string, dwtype *DWDie) { func substitutetype(structdie *DWDie, field string, dwtype *DWDie) {
child := find_or_diag(structdie, field) child := mustFind(structdie, field)
if child == nil { if child == nil {
return return
} }
@ -1302,7 +1297,7 @@ func synthesizemaptypes(die *DWDie) {
newrefattr(dwhk, DW_AT_type, t) newrefattr(dwhk, DW_AT_type, t)
fld = newdie(dwhk, DW_ABRV_ARRAYRANGE, "size") fld = newdie(dwhk, DW_ABRV_ARRAYRANGE, "size")
newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0) newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0)
newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr")) newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
// Construct type to represent an array of BucketSize values // Construct type to represent an array of BucketSize values
dwhv = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, mkinternaltypename("[]val", getattr(valtype, DW_AT_name).data.(string), "")) dwhv = newdie(&dwtypes, DW_ABRV_ARRAYTYPE, mkinternaltypename("[]val", getattr(valtype, DW_AT_name).data.(string), ""))
@ -1315,7 +1310,7 @@ func synthesizemaptypes(die *DWDie) {
newrefattr(dwhv, DW_AT_type, t) newrefattr(dwhv, DW_AT_type, t)
fld = newdie(dwhv, DW_ABRV_ARRAYRANGE, "size") fld = newdie(dwhv, DW_ABRV_ARRAYRANGE, "size")
newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0) newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0)
newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr")) newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
// Construct bucket<K,V> // Construct bucket<K,V>
dwhb = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("bucket", getattr(keytype, DW_AT_name).data.(string), getattr(valtype, DW_AT_name).data.(string))) dwhb = newdie(&dwtypes, DW_ABRV_STRUCTTYPE, mkinternaltypename("bucket", getattr(keytype, DW_AT_name).data.(string), getattr(valtype, DW_AT_name).data.(string)))
@ -1335,7 +1330,7 @@ func synthesizemaptypes(die *DWDie) {
newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))) newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize)))
if Thearch.Regsize > Thearch.Ptrsize { if Thearch.Regsize > Thearch.Ptrsize {
fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "pad") fld = newdie(dwhb, DW_ABRV_STRUCTFIELD, "pad")
newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr")) newrefattr(fld, DW_AT_type, mustFind(&dwtypes, "uintptr"))
newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(Thearch.Ptrsize)) newmemberoffsetattr(fld, BucketSize+BucketSize*(int32(keysize)+int32(valsize))+int32(Thearch.Ptrsize))
} }
@ -1804,8 +1799,7 @@ func writeframes() {
pad := CIERESERVE + frameo + 4 - Cpos() pad := CIERESERVE + frameo + 4 - Cpos()
if pad < 0 { if pad < 0 {
Diag("dwarf: CIERESERVE too small by %d bytes.", -pad) Exitf("dwarf: CIERESERVE too small by %d bytes.", -pad)
Errorexit()
} }
strnput("", int(pad)) strnput("", int(pad))
@ -2150,13 +2144,11 @@ func Dwarfemitdebugsections() {
Cseek(infoo) Cseek(infoo)
writeinfo() writeinfo()
if fwdcount > 0 { if fwdcount > 0 {
Diag("dwarf: unresolved references after first dwarf info pass") Exitf("dwarf: unresolved references after first dwarf info pass")
Errorexit()
} }
if infoe != Cpos() { if infoe != Cpos() {
Diag("dwarf: inconsistent second dwarf info pass") Exitf("dwarf: inconsistent second dwarf info pass")
Errorexit()
} }
} }

View File

@ -7,7 +7,6 @@ package ld
import ( import (
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"os"
) )
/* /*
@ -870,7 +869,7 @@ func elfwriteshdrs() uint32 {
func elfsetstring(s string, off int) { func elfsetstring(s string, off int) {
if nelfstr >= len(elfstr) { if nelfstr >= len(elfstr) {
Diag("too many elf strings") Diag("too many elf strings")
Errorexit() errorexit()
} }
elfstr[nelfstr].s = s elfstr[nelfstr].s = s
@ -1133,8 +1132,7 @@ func addbuildinfo(val string) {
var j int var j int
if val[0] != '0' || val[1] != 'x' { if val[0] != '0' || val[1] != 'x' {
fmt.Fprintf(os.Stderr, "%s: -B argument must start with 0x: %s\n", os.Args[0], val) Exitf("-B argument must start with 0x: %s", val)
Exit(2)
} }
ov := val ov := val
@ -1143,8 +1141,7 @@ func addbuildinfo(val string) {
var b int var b int
for val != "" { for val != "" {
if len(val) == 1 { if len(val) == 1 {
fmt.Fprintf(os.Stderr, "%s: -B argument must have even number of digits: %s\n", os.Args[0], ov) Exitf("-B argument must have even number of digits: %s", ov)
Exit(2)
} }
b = 0 b = 0
@ -1157,15 +1154,13 @@ func addbuildinfo(val string) {
} else if val[0] >= 'A' && val[0] <= 'F' { } else if val[0] >= 'A' && val[0] <= 'F' {
b += int(val[0]) - 'A' + 10 b += int(val[0]) - 'A' + 10
} else { } else {
fmt.Fprintf(os.Stderr, "%s: -B argument contains invalid hex digit %c: %s\n", os.Args[0], val[0], ov) Exitf("-B argument contains invalid hex digit %c: %s", val[0], ov)
Exit(2)
} }
} }
const maxLen = 32 const maxLen = 32
if i >= maxLen { if i >= maxLen {
fmt.Fprintf(os.Stderr, "%s: -B option too long (max %d digits): %s\n", os.Args[0], maxLen, ov) Exitf("-B option too long (max %d digits): %s", maxLen, ov)
Exit(2)
} }
buildinfo = append(buildinfo, uint8(b)) buildinfo = append(buildinfo, uint8(b))
@ -1264,21 +1259,7 @@ func elfdynhash() {
need := make([]*Elfaux, nsym) need := make([]*Elfaux, nsym)
chain := make([]uint32, nsym) chain := make([]uint32, nsym)
buckets := make([]uint32, nbucket) buckets := make([]uint32, nbucket)
if need == nil || chain == nil || buckets == nil {
Ctxt.Cursym = nil
Diag("out of memory")
Errorexit()
}
for i := 0; i < nsym; i++ {
need[i] = nil
}
for i := 0; i < nsym; i++ {
chain[i] = 0
}
for i := 0; i < nbucket; i++ {
buckets[i] = 0
}
var b int var b int
var hc uint32 var hc uint32
var name string var name string
@ -1434,7 +1415,7 @@ func elfshname(name string) *ElfShdr {
} }
Diag("cannot find elf name %s", name) Diag("cannot find elf name %s", name)
Errorexit() errorexit()
return nil return nil
} }
@ -1884,22 +1865,15 @@ func Asmbelf(symo int64) {
eh := getElfEhdr() eh := getElfEhdr()
switch Thearch.Thechar { switch Thearch.Thechar {
default: default:
Diag("unknown architecture in asmbelf") Exitf("unknown architecture in asmbelf: %v", Thearch.Thechar)
Errorexit()
fallthrough
case '5': case '5':
eh.machine = EM_ARM eh.machine = EM_ARM
case '6': case '6':
eh.machine = EM_X86_64 eh.machine = EM_X86_64
case '7': case '7':
eh.machine = EM_AARCH64 eh.machine = EM_AARCH64
case '8': case '8':
eh.machine = EM_386 eh.machine = EM_386
case '9': case '9':
eh.machine = EM_PPC64 eh.machine = EM_PPC64
} }

View File

@ -67,7 +67,7 @@ func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
if int64(int(length)) != length { if int64(int(length)) != length {
fmt.Fprintf(os.Stderr, "%s: too much pkg data in %s\n", os.Args[0], filename) fmt.Fprintf(os.Stderr, "%s: too much pkg data in %s\n", os.Args[0], filename)
if Debug['u'] != 0 { if Debug['u'] != 0 {
Errorexit() errorexit()
} }
return return
} }
@ -76,7 +76,7 @@ func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
if int64(Bread(f, bdata)) != length { if int64(Bread(f, bdata)) != length {
fmt.Fprintf(os.Stderr, "%s: short pkg read %s\n", os.Args[0], filename) fmt.Fprintf(os.Stderr, "%s: short pkg read %s\n", os.Args[0], filename)
if Debug['u'] != 0 { if Debug['u'] != 0 {
Errorexit() errorexit()
} }
return return
} }
@ -86,8 +86,7 @@ func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
p0 = strings.Index(data, "\n$$") p0 = strings.Index(data, "\n$$")
if p0 < 0 { if p0 < 0 {
if Debug['u'] != 0 && whence != ArchiveObj { if Debug['u'] != 0 && whence != ArchiveObj {
fmt.Fprintf(os.Stderr, "%s: cannot find export data in %s\n", os.Args[0], filename) Exitf("cannot find export data in %s", filename)
Errorexit()
} }
return return
} }
@ -102,7 +101,7 @@ func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
if p1 < 0 { if p1 < 0 {
fmt.Fprintf(os.Stderr, "%s: cannot find end of exports in %s\n", os.Args[0], filename) fmt.Fprintf(os.Stderr, "%s: cannot find end of exports in %s\n", os.Args[0], filename)
if Debug['u'] != 0 { if Debug['u'] != 0 {
Errorexit() errorexit()
} }
return return
} }
@ -115,7 +114,7 @@ func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
if !strings.HasPrefix(data[p0:], "package ") { if !strings.HasPrefix(data[p0:], "package ") {
fmt.Fprintf(os.Stderr, "%s: bad package section in %s - %.20s\n", os.Args[0], filename, data[p0:]) fmt.Fprintf(os.Stderr, "%s: bad package section in %s - %.20s\n", os.Args[0], filename, data[p0:])
if Debug['u'] != 0 { if Debug['u'] != 0 {
Errorexit() errorexit()
} }
return return
} }
@ -129,9 +128,7 @@ func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
p0++ p0++
} }
if Debug['u'] != 0 && whence != ArchiveObj && (p0+6 > p1 || !strings.HasPrefix(data[p0:], " safe\n")) { if Debug['u'] != 0 && whence != ArchiveObj && (p0+6 > p1 || !strings.HasPrefix(data[p0:], " safe\n")) {
fmt.Fprintf(os.Stderr, "%s: load of unsafe package %s\n", os.Args[0], filename) Exitf("load of unsafe package %s", filename)
nerrors++
Errorexit()
} }
name := data[pname:p0] name := data[pname:p0]
@ -143,9 +140,7 @@ func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
} }
if pkg == "main" && name != "main" { if pkg == "main" && name != "main" {
fmt.Fprintf(os.Stderr, "%s: %s: not package main (package %s)\n", os.Args[0], filename, name) Exitf("%s: not package main (package %s)", filename, name)
nerrors++
Errorexit()
} }
loadpkgdata(filename, pkg, data[p0:p1]) loadpkgdata(filename, pkg, data[p0:p1])
@ -164,7 +159,7 @@ func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
if i < 0 { if i < 0 {
fmt.Fprintf(os.Stderr, "%s: found $$ // cgo but no newline in %s\n", os.Args[0], filename) fmt.Fprintf(os.Stderr, "%s: found $$ // cgo but no newline in %s\n", os.Args[0], filename)
if Debug['u'] != 0 { if Debug['u'] != 0 {
Errorexit() errorexit()
} }
return return
} }
@ -177,7 +172,7 @@ func ldpkg(f *Biobuf, pkg string, length int64, filename string, whence int) {
if p1 < 0 { if p1 < 0 {
fmt.Fprintf(os.Stderr, "%s: cannot find end of // cgo section in %s\n", os.Args[0], filename) fmt.Fprintf(os.Stderr, "%s: cannot find end of // cgo section in %s\n", os.Args[0], filename)
if Debug['u'] != 0 { if Debug['u'] != 0 {
Errorexit() errorexit()
} }
return return
} }
@ -832,7 +827,6 @@ func setlinkmode(arg string) {
} else if arg == "auto" { } else if arg == "auto" {
Linkmode = LinkAuto Linkmode = LinkAuto
} else { } else {
fmt.Fprintf(os.Stderr, "unknown link mode -linkmode %s\n", arg) Exitf("unknown link mode -linkmode %s", arg)
Errorexit()
} }
} }

View File

@ -597,11 +597,6 @@ func ldelf(f *Biobuf, pkg string, length int64, pn string) {
// symbol 0 is the null symbol. // symbol 0 is the null symbol.
symbols = make([]*LSym, elfobj.nsymtab) symbols = make([]*LSym, elfobj.nsymtab)
if symbols == nil {
Diag("out of memory")
Errorexit()
}
for i := 1; i < elfobj.nsymtab; i++ { for i := 1; i < elfobj.nsymtab; i++ {
if err = readelfsym(elfobj, i, &sym, 1); err != nil { if err = readelfsym(elfobj, i, &sym, 1); err != nil {
goto bad goto bad
@ -643,8 +638,7 @@ func ldelf(f *Biobuf, pkg string, length int64, pn string) {
if s.Dupok != 0 { if s.Dupok != 0 {
continue continue
} }
Diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name) Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name)
Errorexit()
} }
s.Sub = sect.sym.Sub s.Sub = sect.sym.Sub

View File

@ -641,8 +641,7 @@ func ldmacho(f *Biobuf, pkg string, length int64, pn string) {
if s.Dupok != 0 { if s.Dupok != 0 {
continue continue
} }
Diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name) Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name)
Errorexit()
} }
s.Type = outer.Type | SSUB s.Type = outer.Type | SSUB

View File

@ -399,8 +399,7 @@ func ldpe(f *Biobuf, pkg string, length int64, pn string) {
if s.Dupok != 0 { if s.Dupok != 0 {
continue continue
} }
Diag("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name) Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name)
Errorexit()
} }
s.Sub = sect.sym.Sub s.Sub = sect.sym.Sub

View File

@ -356,8 +356,7 @@ func libinit() {
mayberemoveoutfile() mayberemoveoutfile()
f, err := os.OpenFile(outfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775) f, err := os.OpenFile(outfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775)
if err != nil { if err != nil {
Diag("cannot create %s: %v", outfile, err) Exitf("cannot create %s: %v", outfile, err)
Errorexit()
} }
cout = f cout = f
@ -381,7 +380,16 @@ func libinit() {
} }
} }
func Errorexit() { func Exitf(format string, a ...interface{}) {
fmt.Fprintf(os.Stderr, os.Args[0]+": "+format+"\n", a...)
if cout != nil {
cout.Close()
mayberemoveoutfile()
}
Exit(2)
}
func errorexit() {
if cout != nil { if cout != nil {
// For rmtemp run at atexit time on Windows. // For rmtemp run at atexit time on Windows.
cout.Close() cout.Close()
@ -621,8 +629,7 @@ func objfile(file string, pkg string) {
var f *Biobuf var f *Biobuf
f, err = Bopenr(file) f, err = Bopenr(file)
if err != nil { if err != nil {
Diag("cannot open file %s: %v", file, err) Exitf("cannot open file %s: %v", file, err)
Errorexit()
} }
magbuf := make([]byte, len(ARMAG)) magbuf := make([]byte, len(ARMAG))
@ -686,9 +693,7 @@ func objfile(file string, pkg string) {
break break
} }
if l < 0 { if l < 0 {
Diag("%s: malformed archive", file) Exitf("%s: malformed archive", file)
Errorexit()
goto out
} }
off += l off += l
@ -767,9 +772,7 @@ func hostobjs() {
var err error var err error
f, err = Bopenr(h.file) f, err = Bopenr(h.file)
if f == nil { if f == nil {
Ctxt.Cursym = nil Exitf("cannot reopen %s: %v", h.pn, err)
Diag("cannot reopen %s: %v", h.pn, err)
Errorexit()
} }
Bseek(f, h.off, 0) Bseek(f, h.off, 0)
@ -806,8 +809,7 @@ func hostlinksetup() {
var err error var err error
cout, err = os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775) cout, err = os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0775)
if err != nil { if err != nil {
Diag("cannot create %s: %v", p, err) Exitf("cannot create %s: %v", p, err)
Errorexit()
} }
coutbuf = *Binitw(cout) coutbuf = *Binitw(cout)
@ -819,33 +821,23 @@ func hostobjCopy() (paths []string) {
for i, h := range hostobj { for i, h := range hostobj {
f, err := os.Open(h.file) f, err := os.Open(h.file)
if err != nil { if err != nil {
Ctxt.Cursym = nil Exitf("cannot reopen %s: %v", h.pn, err)
Diag("cannot reopen %s: %v", h.pn, err)
Errorexit()
} }
if _, err := f.Seek(h.off, 0); err != nil { if _, err := f.Seek(h.off, 0); err != nil {
Ctxt.Cursym = nil Exitf("cannot seek %s: %v", h.pn, err)
Diag("cannot seek %s: %v", h.pn, err)
Errorexit()
} }
p := fmt.Sprintf("%s/%06d.o", tmpdir, i) p := fmt.Sprintf("%s/%06d.o", tmpdir, i)
paths = append(paths, p) paths = append(paths, p)
w, err := os.Create(p) w, err := os.Create(p)
if err != nil { if err != nil {
Ctxt.Cursym = nil Exitf("cannot create %s: %v", p, err)
Diag("cannot create %s: %v", p, err)
Errorexit()
} }
if _, err := io.CopyN(w, f, h.length); err != nil { if _, err := io.CopyN(w, f, h.length); err != nil {
Ctxt.Cursym = nil Exitf("cannot write %s: %v", p, err)
Diag("cannot write %s: %v", p, err)
Errorexit()
} }
if err := w.Close(); err != nil { if err := w.Close(); err != nil {
Ctxt.Cursym = nil Exitf("cannot close %s: %v", p, err)
Diag("cannot close %s: %v", p, err)
Errorexit()
} }
} }
return paths return paths
@ -868,9 +860,7 @@ func archive() {
} }
if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
Ctxt.Cursym = nil Exitf("running %s failed: %v\n%s", argv[0], err, out)
Diag("%s: running %s failed: %v\n%s", os.Args[0], argv[0], err, out)
Errorexit()
} }
} }
@ -1014,9 +1004,7 @@ func hostlink() {
} }
if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil { if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
Ctxt.Cursym = nil Exitf("running %s failed: %v\n%s", argv[0], err, out)
Diag("%s: running %s failed: %v\n%s", os.Args[0], argv[0], err, out)
Errorexit()
} }
} }
@ -1050,39 +1038,32 @@ func ldobj(f *Biobuf, pkg string, length int64, pn string, file string, whence i
/* check the header */ /* check the header */
line := Brdline(f, '\n') line := Brdline(f, '\n')
var import0 int64
var import1 int64
var t string
if line == "" { if line == "" {
if Blinelen(f) > 0 { if Blinelen(f) > 0 {
Diag("%s: not an object file", pn) Diag("%s: not an object file", pn)
return return
} }
Diag("truncated object file: %s", pn)
goto eof return
} }
if !strings.HasPrefix(line, "go object ") { if !strings.HasPrefix(line, "go object ") {
if strings.HasSuffix(pn, ".go") { if strings.HasSuffix(pn, ".go") {
fmt.Printf("%cl: input %s is not .%c file (use %cg to compile .go files)\n", Thearch.Thechar, pn, Thearch.Thechar, Thearch.Thechar) Exitf("%cl: input %s is not .%c file (use %cg to compile .go files)", Thearch.Thechar, pn, Thearch.Thechar, Thearch.Thechar)
Errorexit()
} }
if line == Thestring { if line == Thestring {
// old header format: just $GOOS // old header format: just $GOOS
Diag("%s: stale object file", pn) Diag("%s: stale object file", pn)
return return
} }
Diag("%s: not an object file", pn) Diag("%s: not an object file", pn)
return return
} }
// First, check that the basic goos, goarch, and version match. // First, check that the basic goos, goarch, and version match.
t = fmt.Sprintf("%s %s %s ", goos, obj.Getgoarch(), obj.Getgoversion()) t := fmt.Sprintf("%s %s %s ", goos, obj.Getgoarch(), obj.Getgoversion())
line = strings.TrimRight(line, "\n") line = strings.TrimRight(line, "\n")
if !strings.HasPrefix(line[10:]+" ", t) && Debug['f'] == 0 { if !strings.HasPrefix(line[10:]+" ", t) && Debug['f'] == 0 {
@ -1103,7 +1084,7 @@ func ldobj(f *Biobuf, pkg string, length int64, pn string, file string, whence i
} }
/* skip over exports and other info -- ends with \n!\n */ /* skip over exports and other info -- ends with \n!\n */
import0 = Boffset(f) import0 := Boffset(f)
c1 = '\n' // the last line ended in \n c1 = '\n' // the last line ended in \n
c2 = Bgetc(f) c2 = Bgetc(f)
@ -1113,22 +1094,18 @@ func ldobj(f *Biobuf, pkg string, length int64, pn string, file string, whence i
c2 = c3 c2 = c3
c3 = Bgetc(f) c3 = Bgetc(f)
if c3 == Beof { if c3 == Beof {
goto eof Diag("truncated object file: %s", pn)
return
} }
} }
import1 = Boffset(f) import1 := Boffset(f)
Bseek(f, import0, 0) Bseek(f, import0, 0)
ldpkg(f, pkg, import1-import0-2, pn, whence) // -2 for !\n ldpkg(f, pkg, import1-import0-2, pn, whence) // -2 for !\n
Bseek(f, import1, 0) Bseek(f, import1, 0)
ldobjfile(Ctxt, f, pkg, eof-Boffset(f), pn) ldobjfile(Ctxt, f, pkg, eof-Boffset(f), pn)
return
eof:
Diag("truncated object file: %s", pn)
} }
func ldshlibsyms(shlib string) { func ldshlibsyms(shlib string) {
@ -1553,8 +1530,7 @@ func usage() {
func setheadtype(s string) { func setheadtype(s string) {
h := headtype(s) h := headtype(s)
if h < 0 { if h < 0 {
fmt.Fprintf(os.Stderr, "unknown header type -H %s\n", s) Exitf("unknown header type -H %s", s)
Errorexit()
} }
headstring = s headstring = s
@ -1567,8 +1543,7 @@ func setinterp(s string) {
} }
func doversion() { func doversion() {
fmt.Printf("%cl version %s\n", Thearch.Thechar, obj.Getgoversion()) Exitf("version %s", obj.Getgoversion())
Errorexit()
} }
func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) { func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
@ -1756,7 +1731,7 @@ func undef() {
undefsym(s) undefsym(s)
} }
if nerrors > 0 { if nerrors > 0 {
Errorexit() errorexit()
} }
} }
@ -1791,8 +1766,7 @@ func Diag(format string, args ...interface{}) {
nerrors++ nerrors++
if nerrors > 20 { if nerrors > 20 {
fmt.Printf("too many errors\n") Exitf("too many errors")
Errorexit()
} }
} }

View File

@ -159,8 +159,7 @@ func newMachoLoad(type_ uint32, ndata uint32) *MachoLoad {
func newMachoSeg(name string, msect int) *MachoSeg { func newMachoSeg(name string, msect int) *MachoSeg {
if nseg >= len(seg) { if nseg >= len(seg) {
Diag("too many segs") Exitf("too many segs")
Errorexit()
} }
s := &seg[nseg] s := &seg[nseg]
@ -173,8 +172,7 @@ func newMachoSeg(name string, msect int) *MachoSeg {
func newMachoSect(seg *MachoSeg, name string, segname string) *MachoSect { func newMachoSect(seg *MachoSeg, name string, segname string) *MachoSect {
if seg.nsect >= seg.msect { if seg.nsect >= seg.msect {
Diag("too many sects in segment %s", seg.name) Exitf("too many sects in segment %s", seg.name)
Errorexit()
} }
s := &seg.sect[seg.nsect] s := &seg.sect[seg.nsect]
@ -419,9 +417,7 @@ func Asmbmacho() {
mh := getMachoHdr() mh := getMachoHdr()
switch Thearch.Thechar { switch Thearch.Thechar {
default: default:
Diag("unknown mach architecture") Exitf("unknown macho architecture: %v", Thearch.Thechar)
Errorexit()
fallthrough
case '5': case '5':
mh.cpu = MACHO_CPU_ARM mh.cpu = MACHO_CPU_ARM
@ -491,9 +487,7 @@ func Asmbmacho() {
if Linkmode != LinkExternal { if Linkmode != LinkExternal {
switch Thearch.Thechar { switch Thearch.Thechar {
default: default:
Diag("unknown macho architecture") Exitf("unknown macho architecture: %v", Thearch.Thechar)
Errorexit()
fallthrough
case '5': case '5':
ml := newMachoLoad(5, 17+2) /* unix thread */ ml := newMachoLoad(5, 17+2) /* unix thread */
@ -572,7 +566,7 @@ func Asmbmacho() {
a := machowrite() a := machowrite()
if int32(a) > HEADR { if int32(a) > HEADR {
Diag("HEADR too small: %d > %d", a, HEADR) Exitf("HEADR too small: %d > %d", a, HEADR)
} }
} }

View File

@ -298,7 +298,7 @@ func pclntab() {
for pciterinit(Ctxt, &it, &pcln.Pcfile); it.done == 0; pciternext(&it) { for pciterinit(Ctxt, &it, &pcln.Pcfile); it.done == 0; pciternext(&it) {
if it.value < 1 || it.value > Ctxt.Nhistfile { if it.value < 1 || it.value > Ctxt.Nhistfile {
Diag("bad file number in pcfile: %d not in range [1, %d]\n", it.value, Ctxt.Nhistfile) Diag("bad file number in pcfile: %d not in range [1, %d]\n", it.value, Ctxt.Nhistfile)
Errorexit() errorexit()
} }
} }
} }
@ -337,7 +337,7 @@ func pclntab() {
if off != end { if off != end {
Diag("bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, pcln.Npcdata, pcln.Nfuncdata, Thearch.Ptrsize) Diag("bad math in functab: funcstart=%d off=%d but end=%d (npcdata=%d nfuncdata=%d ptrsize=%d)", funcstart, off, end, pcln.Npcdata, pcln.Nfuncdata, Thearch.Ptrsize)
Errorexit() errorexit()
} }
nfunc++ nfunc++

View File

@ -389,7 +389,7 @@ var ncoffsym int
func addpesection(name string, sectsize int, filesize int) *IMAGE_SECTION_HEADER { func addpesection(name string, sectsize int, filesize int) *IMAGE_SECTION_HEADER {
if pensect == 16 { if pensect == 16 {
Diag("too many sections") Diag("too many sections")
Errorexit() errorexit()
} }
h := &sh[pensect] h := &sh[pensect]
@ -410,19 +410,19 @@ func addpesection(name string, sectsize int, filesize int) *IMAGE_SECTION_HEADER
func chksectoff(h *IMAGE_SECTION_HEADER, off int64) { func chksectoff(h *IMAGE_SECTION_HEADER, off int64) {
if off != int64(h.PointerToRawData) { if off != int64(h.PointerToRawData) {
Diag("%s.PointerToRawData = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.PointerToRawData)), uint64(off)) Diag("%s.PointerToRawData = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.PointerToRawData)), uint64(off))
Errorexit() errorexit()
} }
} }
func chksectseg(h *IMAGE_SECTION_HEADER, s *Segment) { func chksectseg(h *IMAGE_SECTION_HEADER, s *Segment) {
if s.Vaddr-PEBASE != uint64(h.VirtualAddress) { if s.Vaddr-PEBASE != uint64(h.VirtualAddress) {
Diag("%s.VirtualAddress = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.VirtualAddress)), uint64(int64(s.Vaddr-PEBASE))) Diag("%s.VirtualAddress = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.VirtualAddress)), uint64(int64(s.Vaddr-PEBASE)))
Errorexit() errorexit()
} }
if s.Fileoff != uint64(h.PointerToRawData) { if s.Fileoff != uint64(h.PointerToRawData) {
Diag("%s.PointerToRawData = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.PointerToRawData)), uint64(int64(s.Fileoff))) Diag("%s.PointerToRawData = %#x, want %#x", cstring(h.Name[:]), uint64(int64(h.PointerToRawData)), uint64(int64(s.Fileoff)))
Errorexit() errorexit()
} }
} }
@ -711,7 +711,7 @@ func initdynexport() {
} }
if nexport+1 > len(dexport) { if nexport+1 > len(dexport) {
Diag("pe dynexport table is full") Diag("pe dynexport table is full")
Errorexit() errorexit()
} }
dexport[nexport] = s dexport[nexport] = s
@ -1096,13 +1096,9 @@ func addpersrc() {
func Asmbpe() { func Asmbpe() {
switch Thearch.Thechar { switch Thearch.Thechar {
default: default:
Diag("unknown PE architecture") Exitf("unknown PE architecture: %v", Thearch.Thechar)
Errorexit()
fallthrough
case '6': case '6':
fh.Machine = IMAGE_FILE_MACHINE_AMD64 fh.Machine = IMAGE_FILE_MACHINE_AMD64
case '8': case '8':
fh.Machine = IMAGE_FILE_MACHINE_I386 fh.Machine = IMAGE_FILE_MACHINE_I386
} }

View File

@ -148,8 +148,7 @@ func Ldmain() {
if Buildmode == BuildmodeExe { if Buildmode == BuildmodeExe {
Buildmode = BuildmodeCShared Buildmode = BuildmodeCShared
} else if Buildmode != BuildmodeCShared { } else if Buildmode != BuildmodeCShared {
Diag("-shared and -buildmode=%s are incompatible\n", Buildmode.String()) Exitf("-shared and -buildmode=%s are incompatible", Buildmode.String())
Errorexit()
} }
} }
@ -178,8 +177,7 @@ func Ldmain() {
Thearch.Archinit() Thearch.Archinit()
if Linkshared && !Iself { if Linkshared && !Iself {
Diag("-linkshared can only be used on elf systems") Exitf("-linkshared can only be used on elf systems")
Errorexit()
} }
if Debug['v'] != 0 { if Debug['v'] != 0 {
@ -246,5 +244,5 @@ func Ldmain() {
Bflush(&Bso) Bflush(&Bso)
Errorexit() errorexit()
} }