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

@ -342,7 +342,7 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
}
func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
ld.Thearch.Lput(uint32(sectoff))
ctxt.Out.Write32(uint32(sectoff))
elfsym := r.Xsym.ElfsymForReloc()
switch r.Type {
@ -350,16 +350,16 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
return false
case objabi.R_ADDR:
if r.Siz == 4 {
ld.Thearch.Lput(ld.R_386_32 | uint32(elfsym)<<8)
ctxt.Out.Write32(ld.R_386_32 | uint32(elfsym)<<8)
} else {
return false
}
case objabi.R_GOTPCREL:
if r.Siz == 4 {
ld.Thearch.Lput(ld.R_386_GOTPC)
ctxt.Out.Write32(ld.R_386_GOTPC)
if r.Xsym.Name != "_GLOBAL_OFFSET_TABLE_" {
ld.Thearch.Lput(uint32(sectoff))
ld.Thearch.Lput(ld.R_386_GOT32 | uint32(elfsym)<<8)
ctxt.Out.Write32(uint32(sectoff))
ctxt.Out.Write32(ld.R_386_GOT32 | uint32(elfsym)<<8)
}
} else {
return false
@ -367,30 +367,30 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
case objabi.R_CALL:
if r.Siz == 4 {
if r.Xsym.Type == ld.SDYNIMPORT {
ld.Thearch.Lput(ld.R_386_PLT32 | uint32(elfsym)<<8)
ctxt.Out.Write32(ld.R_386_PLT32 | uint32(elfsym)<<8)
} else {
ld.Thearch.Lput(ld.R_386_PC32 | uint32(elfsym)<<8)
ctxt.Out.Write32(ld.R_386_PC32 | uint32(elfsym)<<8)
}
} else {
return false
}
case objabi.R_PCREL:
if r.Siz == 4 {
ld.Thearch.Lput(ld.R_386_PC32 | uint32(elfsym)<<8)
ctxt.Out.Write32(ld.R_386_PC32 | uint32(elfsym)<<8)
} else {
return false
}
case objabi.R_TLS_LE:
if r.Siz == 4 {
ld.Thearch.Lput(ld.R_386_TLS_LE | uint32(elfsym)<<8)
ctxt.Out.Write32(ld.R_386_TLS_LE | uint32(elfsym)<<8)
} else {
return false
}
case objabi.R_TLS_IE:
if r.Siz == 4 {
ld.Thearch.Lput(ld.R_386_GOTPC)
ld.Thearch.Lput(uint32(sectoff))
ld.Thearch.Lput(ld.R_386_TLS_GOTIE | uint32(elfsym)<<8)
ctxt.Out.Write32(ld.R_386_GOTPC)
ctxt.Out.Write32(uint32(sectoff))
ctxt.Out.Write32(ld.R_386_TLS_GOTIE | uint32(elfsym)<<8)
} else {
return false
}
@ -399,7 +399,7 @@ func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
return true
}
func machoreloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
@ -444,12 +444,12 @@ func machoreloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool
v |= 3 << 25
}
ld.Thearch.Lput(uint32(sectoff))
ld.Thearch.Lput(v)
out.Write32(uint32(sectoff))
out.Write32(v)
return true
}
func pereloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
@ -459,8 +459,8 @@ func pereloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
return false
}
ld.Thearch.Lput(uint32(sectoff))
ld.Thearch.Lput(uint32(rs.Dynid))
out.Write32(uint32(sectoff))
out.Write32(uint32(rs.Dynid))
switch r.Type {
default:
@ -477,7 +477,7 @@ func pereloc1(arch *sys.Arch, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
v = ld.IMAGE_REL_I386_REL32
}
ld.Thearch.Wput(uint16(v))
out.Write16(uint16(v))
return true
}
@ -621,11 +621,11 @@ func asmb(ctxt *ld.Link) {
}
sect := ld.Segtext.Sections[0]
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
// 0xCC is INT $3 - breakpoint instruction
ld.CodeblkPad(ctxt, int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
for _, sect = range ld.Segtext.Sections[1:] {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}
@ -634,14 +634,14 @@ func asmb(ctxt *ld.Link) {
ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
}
ld.Cseek(int64(ld.Segrodata.Fileoff))
ctxt.Out.SeekSet(int64(ld.Segrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
}
if ld.Segrelrodata.Filelen > 0 {
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f relrodatblk\n", ld.Cputime())
}
ld.Cseek(int64(ld.Segrelrodata.Fileoff))
ctxt.Out.SeekSet(int64(ld.Segrelrodata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
}
@ -649,10 +649,10 @@ func asmb(ctxt *ld.Link) {
ctxt.Logf("%5.2f datblk\n", ld.Cputime())
}
ld.Cseek(int64(ld.Segdata.Fileoff))
ctxt.Out.SeekSet(int64(ld.Segdata.Fileoff))
ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
ld.Cseek(int64(ld.Segdwarf.Fileoff))
ctxt.Out.SeekSet(int64(ld.Segdwarf.Fileoff))
ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
machlink := uint32(0)
@ -687,7 +687,7 @@ func asmb(ctxt *ld.Link) {
symo = uint32(ld.Rnd(int64(symo), ld.PEFILEALIGN))
}
ld.Cseek(int64(symo))
ctxt.Out.SeekSet(int64(symo))
switch ld.Headtype {
default:
if ld.Iself {
@ -695,8 +695,8 @@ func asmb(ctxt *ld.Link) {
ctxt.Logf("%5.2f elfsym\n", ld.Cputime())
}
ld.Asmelfsym(ctxt)
ld.Cflush()
ld.Cwrite(ld.Elfstrdat)
ctxt.Out.Flush()
ctxt.Out.Write(ld.Elfstrdat)
if ld.Linkmode == ld.LinkExternal {
ld.Elfemitreloc(ctxt)
@ -705,13 +705,13 @@ func asmb(ctxt *ld.Link) {
case objabi.Hplan9:
ld.Asmplan9sym(ctxt)
ld.Cflush()
ctxt.Out.Flush()
sym := ctxt.Syms.Lookup("pclntab", 0)
if sym != nil {
ld.Lcsize = int32(len(sym.P))
ld.Cwrite(sym.P)
ld.Cflush()
ctxt.Out.Write(sym.P)
ctxt.Out.Flush()
}
case objabi.Hwindows:
@ -729,20 +729,20 @@ func asmb(ctxt *ld.Link) {
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f headr\n", ld.Cputime())
}
ld.Cseek(0)
ctxt.Out.SeekSet(0)
switch ld.Headtype {
default:
case objabi.Hplan9: /* plan9 */
magic := int32(4*11*11 + 7)
ld.Lputb(uint32(magic)) /* magic */
ld.Lputb(uint32(ld.Segtext.Filelen)) /* sizes */
ld.Lputb(uint32(ld.Segdata.Filelen))
ld.Lputb(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
ld.Lputb(uint32(ld.Symsize)) /* nsyms */
ld.Lputb(uint32(ld.Entryvalue(ctxt))) /* va of entry */
ld.Lputb(uint32(ld.Spsize)) /* sp offsets */
ld.Lputb(uint32(ld.Lcsize)) /* line offsets */
ctxt.Out.Write32b(uint32(magic)) /* magic */
ctxt.Out.Write32b(uint32(ld.Segtext.Filelen)) /* sizes */
ctxt.Out.Write32b(uint32(ld.Segdata.Filelen))
ctxt.Out.Write32b(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
ctxt.Out.Write32b(uint32(ld.Symsize)) /* nsyms */
ctxt.Out.Write32b(uint32(ld.Entryvalue(ctxt))) /* va of entry */
ctxt.Out.Write32b(uint32(ld.Spsize)) /* sp offsets */
ctxt.Out.Write32b(uint32(ld.Lcsize)) /* line offsets */
case objabi.Hdarwin:
ld.Asmbmacho(ctxt)
@ -758,5 +758,5 @@ func asmb(ctxt *ld.Link) {
ld.Asmbpe(ctxt)
}
ld.Cflush()
ctxt.Out.Flush()
}