cmd/link: remove coutbuf global variable

Begin passing coutbuf by as a parameter. To make the initial plumbing
pass easier, it is also a field in the standard ctxt parameter.

Consolidate the byte writing functions into the OutBuf object.
The result is less architecture-dependent initialization.

To avoid plumbing out everywhere we want to report an error, move
handling of out file deletion to an AtExit function.

For #22095

Change-Id: I0863695241562e0662ae3669666c7922b8c846f9
Reviewed-on: https://go-review.googlesource.com/67318
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
David Crawshaw 2017-10-01 02:37:20 +00:00
parent 5d95de2072
commit 5fe9bbcf63
27 changed files with 794 additions and 874 deletions

View file

@ -105,14 +105,8 @@ type Arch struct {
Elfreloc1 func(*Link, *Reloc, int64) bool
Elfsetupplt func(*Link)
Gentext func(*Link)
Machoreloc1 func(*sys.Arch, *Symbol, *Reloc, int64) bool
PEreloc1 func(*sys.Arch, *Symbol, *Reloc, int64) bool
Wput func(uint16)
Lput func(uint32)
Vput func(uint64)
Append16 func(b []byte, v uint16) []byte
Append32 func(b []byte, v uint32) []byte
Append64 func(b []byte, v uint64) []byte
Machoreloc1 func(*sys.Arch, *OutBuf, *Symbol, *Reloc, int64) bool
PEreloc1 func(*sys.Arch, *OutBuf, *Symbol, *Reloc, int64) bool
// TLSIEtoLE converts a TLS Initial Executable relocation to
// a TLS Local Executable relocation.
@ -220,31 +214,6 @@ const (
Pkgdef
)
// TODO(dfc) outBuf duplicates bio.Writer
type outBuf struct {
w *bufio.Writer
f *os.File
off int64
}
func (w *outBuf) Write(p []byte) (n int, err error) {
n, err = w.w.Write(p)
w.off += int64(n)
return n, err
}
func (w *outBuf) WriteString(s string) (n int, err error) {
n, err = coutbuf.w.WriteString(s)
w.off += int64(n)
return n, err
}
func (w *outBuf) Offset() int64 {
return w.off
}
var coutbuf outBuf
const pkgdef = "__.PKGDEF"
var (
@ -297,8 +266,8 @@ func libinit(ctxt *Link) {
Exitf("cannot create %s: %v", *flagOutfile, err)
}
coutbuf.w = bufio.NewWriter(f)
coutbuf.f = f
ctxt.Out.w = bufio.NewWriter(f)
ctxt.Out.f = f
if *flagEntrySymbol == "" {
switch Buildmode {
@ -315,23 +284,9 @@ func libinit(ctxt *Link) {
}
func errorexit() {
if coutbuf.f != nil {
if nerrors != 0 {
Cflush()
}
// For rmtemp run at atexit time on Windows.
if err := coutbuf.f.Close(); err != nil {
Exitf("close: %v", err)
}
}
if nerrors != 0 {
if coutbuf.f != nil {
mayberemoveoutfile()
}
Exit(2)
}
Exit(0)
}
@ -606,7 +561,7 @@ func (ctxt *Link) loadlib() {
}
}
} else {
hostlinksetup()
hostlinksetup(ctxt)
}
// We've loaded all the code now.
@ -934,7 +889,7 @@ func rmtemp() {
os.RemoveAll(*flagTmpdir)
}
func hostlinksetup() {
func hostlinksetup(ctxt *Link) {
if Linkmode != LinkExternal {
return
}
@ -956,7 +911,7 @@ func hostlinksetup() {
}
// change our output to temporary object file
coutbuf.f.Close()
ctxt.Out.f.Close()
mayberemoveoutfile()
p := filepath.Join(*flagTmpdir, "go.o")
@ -966,8 +921,9 @@ func hostlinksetup() {
Exitf("cannot create %s: %v", p, err)
}
coutbuf.w = bufio.NewWriter(f)
coutbuf.f = f
ctxt.Out.w = bufio.NewWriter(f)
ctxt.Out.f = f
ctxt.Out.off = 0
}
// hostobjCopy creates a copy of the object files in hostobj in a
@ -1048,11 +1004,11 @@ func (ctxt *Link) archive() {
// Force the buffer to flush here so that external
// tools will see a complete file.
Cflush()
if err := coutbuf.f.Close(); err != nil {
ctxt.Out.Flush()
if err := ctxt.Out.f.Close(); err != nil {
Exitf("close: %v", err)
}
coutbuf.f = nil
ctxt.Out.f = nil
argv := []string{*flagExtar, "-q", "-c", "-s", *flagOutfile}
argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
@ -1907,36 +1863,6 @@ func stkprint(ctxt *Link, ch *chain, limit int) {
}
}
func Cflush() {
if err := coutbuf.w.Flush(); err != nil {
Exitf("flushing %s: %v", coutbuf.f.Name(), err)
}
}
func Cseek(p int64) {
if p == coutbuf.off {
return
}
Cflush()
if _, err := coutbuf.f.Seek(p, 0); err != nil {
Exitf("seeking in output [0, 1]: %v", err)
}
coutbuf.off = p
}
func Cwritestring(s string) {
coutbuf.WriteString(s)
}
func Cwrite(p []byte) {
coutbuf.Write(p)
}
func Cput(c uint8) {
coutbuf.w.WriteByte(c)
coutbuf.off++
}
func usage() {
fmt.Fprintf(os.Stderr, "usage: link [options] main.o\n")
objabi.Flagprint(2)