}
func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
- ld.Thearch.Vput(uint64(sectoff))
+ ctxt.Out.Write64(uint64(sectoff))
elfsym := r.Xsym.ElfsymForReloc()
switch r.Type {
return false
case objabi.R_ADDR:
if r.Siz == 4 {
- ld.Thearch.Vput(ld.R_X86_64_32 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_X86_64_32 | uint64(elfsym)<<32)
} else if r.Siz == 8 {
- ld.Thearch.Vput(ld.R_X86_64_64 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_X86_64_64 | uint64(elfsym)<<32)
} else {
return false
}
case objabi.R_TLS_LE:
if r.Siz == 4 {
- ld.Thearch.Vput(ld.R_X86_64_TPOFF32 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_X86_64_TPOFF32 | uint64(elfsym)<<32)
} else {
return false
}
case objabi.R_TLS_IE:
if r.Siz == 4 {
- ld.Thearch.Vput(ld.R_X86_64_GOTTPOFF | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_X86_64_GOTTPOFF | uint64(elfsym)<<32)
} else {
return false
}
if r.Siz == 4 {
if r.Xsym.Type == ld.SDYNIMPORT {
if ctxt.DynlinkingGo() {
- ld.Thearch.Vput(ld.R_X86_64_PLT32 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_X86_64_PLT32 | uint64(elfsym)<<32)
} else {
- ld.Thearch.Vput(ld.R_X86_64_GOTPCREL | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_X86_64_GOTPCREL | uint64(elfsym)<<32)
}
} else {
- ld.Thearch.Vput(ld.R_X86_64_PC32 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_X86_64_PC32 | uint64(elfsym)<<32)
}
} else {
return false
case objabi.R_PCREL:
if r.Siz == 4 {
if r.Xsym.Type == ld.SDYNIMPORT && r.Xsym.ElfType == elf.STT_FUNC {
- ld.Thearch.Vput(ld.R_X86_64_PLT32 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_X86_64_PLT32 | uint64(elfsym)<<32)
} else {
- ld.Thearch.Vput(ld.R_X86_64_PC32 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_X86_64_PC32 | uint64(elfsym)<<32)
}
} else {
return false
}
case objabi.R_GOTPCREL:
if r.Siz == 4 {
- ld.Thearch.Vput(ld.R_X86_64_GOTPCREL | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_X86_64_GOTPCREL | uint64(elfsym)<<32)
} else {
return false
}
}
- ld.Thearch.Vput(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(r.Xadd))
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
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
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:
v = ld.IMAGE_REL_AMD64_REL32
}
- ld.Thearch.Wput(uint16(v))
+ out.Write16(uint16(v))
return true
}
}
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))
}
if ctxt.Debugvlog != 0 {
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))
}
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 := int64(0)
symo = ld.Rnd(symo, ld.PEFILEALIGN)
}
- ld.Cseek(symo)
+ ctxt.Out.SeekSet(symo)
switch ld.Headtype {
default:
if ld.Iself {
- ld.Cseek(symo)
+ ctxt.Out.SeekSet(symo)
ld.Asmelfsym(ctxt)
- ld.Cflush()
- ld.Cwrite(ld.Elfstrdat)
+ ctxt.Out.Flush()
+ ctxt.Out.Write(ld.Elfstrdat)
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
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:
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*26*26 + 7)
- magic |= 0x00008000 /* fat header */
- 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 */
+ magic |= 0x00008000 /* fat header */
+ 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 */
vl := ld.Entryvalue(ctxt)
- ld.Lputb(PADDR(uint32(vl))) /* va of entry */
- ld.Lputb(uint32(ld.Spsize)) /* sp offsets */
- ld.Lputb(uint32(ld.Lcsize)) /* line offsets */
- ld.Vputb(uint64(vl)) /* va of entry */
+ ctxt.Out.Write32b(PADDR(uint32(vl))) /* va of entry */
+ ctxt.Out.Write32b(uint32(ld.Spsize)) /* sp offsets */
+ ctxt.Out.Write32b(uint32(ld.Lcsize)) /* line offsets */
+ ctxt.Out.Write64b(uint64(vl)) /* va of entry */
case objabi.Hdarwin:
ld.Asmbmacho(ctxt)
ld.Asmbpe(ctxt)
}
- ld.Cflush()
+ ctxt.Out.Flush()
}
func tlsIEtoLE(s *ld.Symbol, off, size int) {
Gentext: gentext,
Machoreloc1: machoreloc1,
PEreloc1: pereloc1,
- Lput: ld.Lputl,
- Wput: ld.Wputl,
- Vput: ld.Vputl,
- Append16: ld.Append16l,
- Append32: ld.Append32l,
- Append64: ld.Append64l,
TLSIEtoLE: tlsIEtoLE,
Linuxdynld: "/lib64/ld-linux-x86-64.so.2",
}
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 {
return false
case objabi.R_ADDR:
if r.Siz == 4 {
- ld.Thearch.Lput(ld.R_ARM_ABS32 | uint32(elfsym)<<8)
+ ctxt.Out.Write32(ld.R_ARM_ABS32 | uint32(elfsym)<<8)
} else {
return false
}
case objabi.R_PCREL:
if r.Siz == 4 {
- ld.Thearch.Lput(ld.R_ARM_REL32 | uint32(elfsym)<<8)
+ ctxt.Out.Write32(ld.R_ARM_REL32 | uint32(elfsym)<<8)
} else {
return false
}
case objabi.R_CALLARM:
if r.Siz == 4 {
if r.Add&0xff000000 == 0xeb000000 { // BL
- ld.Thearch.Lput(ld.R_ARM_CALL | uint32(elfsym)<<8)
+ ctxt.Out.Write32(ld.R_ARM_CALL | uint32(elfsym)<<8)
} else {
- ld.Thearch.Lput(ld.R_ARM_JUMP24 | uint32(elfsym)<<8)
+ ctxt.Out.Write32(ld.R_ARM_JUMP24 | uint32(elfsym)<<8)
}
} else {
return false
}
case objabi.R_TLS_LE:
- ld.Thearch.Lput(ld.R_ARM_TLS_LE32 | uint32(elfsym)<<8)
+ ctxt.Out.Write32(ld.R_ARM_TLS_LE32 | uint32(elfsym)<<8)
case objabi.R_TLS_IE:
- ld.Thearch.Lput(ld.R_ARM_TLS_IE32 | uint32(elfsym)<<8)
+ ctxt.Out.Write32(ld.R_ARM_TLS_IE32 | uint32(elfsym)<<8)
case objabi.R_GOTPCREL:
if r.Siz == 4 {
- ld.Thearch.Lput(ld.R_ARM_GOT_PREL | uint32(elfsym)<<8)
+ ctxt.Out.Write32(ld.R_ARM_GOT_PREL | uint32(elfsym)<<8)
} else {
return false
}
}
}
-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
o2 |= ld.MACHO_ARM_RELOC_PAIR << 24
o2 |= 2 << 28 // size = 4
- ld.Thearch.Lput(o1)
- ld.Thearch.Lput(uint32(ld.Symaddr(rs)))
- ld.Thearch.Lput(o2)
- ld.Thearch.Lput(uint32(s.Value + int64(r.Off)))
+ out.Write32(o1)
+ out.Write32(uint32(ld.Symaddr(rs)))
+ out.Write32(o2)
+ out.Write32(uint32(s.Value + int64(r.Off)))
return true
}
v |= 3 << 25
}
- ld.Thearch.Lput(uint32(sectoff))
- ld.Thearch.Lput(v)
+ out.Write32(uint32(sectoff))
+ out.Write32(v)
return true
}
}
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))
ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
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))
}
if ctxt.Debugvlog != 0 {
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))
}
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)
symo = uint32(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(*ld.FlagRound))) + uint64(machlink))
}
- ld.Cseek(int64(symo))
+ ctxt.Out.SeekSet(int64(symo))
switch ld.Headtype {
default:
if ld.Iself {
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)
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.Hdarwin:
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f header\n", ld.Cputime())
}
- ld.Cseek(0)
+ ctxt.Out.SeekSet(0)
switch ld.Headtype {
default:
case objabi.Hplan9: /* plan 9 */
- ld.Lputb(0x647) /* 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(0)
- ld.Lputb(uint32(ld.Lcsize))
+ ctxt.Out.Write32b(0x647) /* 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(0)
+ ctxt.Out.Write32b(uint32(ld.Lcsize))
case objabi.Hlinux,
objabi.Hfreebsd,
ld.Asmbmacho(ctxt)
}
- ld.Cflush()
+ ctxt.Out.Flush()
if *ld.FlagC {
fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
Elfsetupplt: elfsetupplt,
Gentext: gentext,
Machoreloc1: machoreloc1,
- Lput: ld.Lputl,
- Wput: ld.Wputl,
- Vput: ld.Vputl,
- Append16: ld.Append16l,
- Append32: ld.Append32l,
- Append64: ld.Append64l,
Linuxdynld: "/lib/ld-linux.so.3", // 2 for OABI, 3 for EABI
Freebsddynld: "/usr/libexec/ld-elf.so.1",
}
func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
- ld.Thearch.Vput(uint64(sectoff))
+ ctxt.Out.Write64(uint64(sectoff))
elfsym := r.Xsym.ElfsymForReloc()
switch r.Type {
case objabi.R_ADDR:
switch r.Siz {
case 4:
- ld.Thearch.Vput(ld.R_AARCH64_ABS32 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_AARCH64_ABS32 | uint64(elfsym)<<32)
case 8:
- ld.Thearch.Vput(ld.R_AARCH64_ABS64 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_AARCH64_ABS64 | uint64(elfsym)<<32)
default:
return false
}
case objabi.R_ADDRARM64:
// two relocations: R_AARCH64_ADR_PREL_PG_HI21 and R_AARCH64_ADD_ABS_LO12_NC
- ld.Thearch.Vput(ld.R_AARCH64_ADR_PREL_PG_HI21 | uint64(elfsym)<<32)
- ld.Thearch.Vput(uint64(r.Xadd))
- ld.Thearch.Vput(uint64(sectoff + 4))
- ld.Thearch.Vput(ld.R_AARCH64_ADD_ABS_LO12_NC | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_AARCH64_ADR_PREL_PG_HI21 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(sectoff + 4))
+ ctxt.Out.Write64(ld.R_AARCH64_ADD_ABS_LO12_NC | uint64(elfsym)<<32)
case objabi.R_ARM64_TLS_LE:
- ld.Thearch.Vput(ld.R_AARCH64_TLSLE_MOVW_TPREL_G0 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_AARCH64_TLSLE_MOVW_TPREL_G0 | uint64(elfsym)<<32)
case objabi.R_ARM64_TLS_IE:
- ld.Thearch.Vput(ld.R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 | uint64(elfsym)<<32)
- ld.Thearch.Vput(uint64(r.Xadd))
- ld.Thearch.Vput(uint64(sectoff + 4))
- ld.Thearch.Vput(ld.R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(sectoff + 4))
+ ctxt.Out.Write64(ld.R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC | uint64(elfsym)<<32)
case objabi.R_ARM64_GOTPCREL:
- ld.Thearch.Vput(ld.R_AARCH64_ADR_GOT_PAGE | uint64(elfsym)<<32)
- ld.Thearch.Vput(uint64(r.Xadd))
- ld.Thearch.Vput(uint64(sectoff + 4))
- ld.Thearch.Vput(ld.R_AARCH64_LD64_GOT_LO12_NC | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_AARCH64_ADR_GOT_PAGE | uint64(elfsym)<<32)
+ ctxt.Out.Write64(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(sectoff + 4))
+ ctxt.Out.Write64(ld.R_AARCH64_LD64_GOT_LO12_NC | uint64(elfsym)<<32)
case objabi.R_CALLARM64:
if r.Siz != 4 {
return false
}
- ld.Thearch.Vput(ld.R_AARCH64_CALL26 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_AARCH64_CALL26 | uint64(elfsym)<<32)
}
- ld.Thearch.Vput(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(r.Xadd))
return true
}
return
}
-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
// Two relocation entries: MACHO_ARM64_RELOC_PAGEOFF12 MACHO_ARM64_RELOC_PAGE21
// if r.Xadd is non-zero, add two MACHO_ARM64_RELOC_ADDEND.
if r.Xadd != 0 {
- ld.Thearch.Lput(uint32(sectoff + 4))
- ld.Thearch.Lput((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
+ out.Write32(uint32(sectoff + 4))
+ out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
}
- ld.Thearch.Lput(uint32(sectoff + 4))
- ld.Thearch.Lput(v | (ld.MACHO_ARM64_RELOC_PAGEOFF12 << 28) | (2 << 25))
+ out.Write32(uint32(sectoff + 4))
+ out.Write32(v | (ld.MACHO_ARM64_RELOC_PAGEOFF12 << 28) | (2 << 25))
if r.Xadd != 0 {
- ld.Thearch.Lput(uint32(sectoff))
- ld.Thearch.Lput((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
+ out.Write32(uint32(sectoff))
+ out.Write32((ld.MACHO_ARM64_RELOC_ADDEND << 28) | (2 << 25) | uint32(r.Xadd&0xffffff))
}
v |= 1 << 24 // pc-relative bit
v |= ld.MACHO_ARM64_RELOC_PAGE21 << 28
v |= 3 << 25
}
- ld.Thearch.Lput(uint32(sectoff))
- ld.Thearch.Lput(v)
+ out.Write32(uint32(sectoff))
+ out.Write32(v)
return true
}
}
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))
ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
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))
}
if ctxt.Debugvlog != 0 {
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))
}
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)
symo = uint32(ld.Segdwarf.Fileoff + uint64(ld.Rnd(int64(ld.Segdwarf.Filelen), int64(*ld.FlagRound))) + uint64(machlink))
}
- ld.Cseek(int64(symo))
+ ctxt.Out.SeekSet(int64(symo))
switch ld.Headtype {
default:
if ld.Iself {
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)
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.Hdarwin:
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f header\n", ld.Cputime())
}
- ld.Cseek(0)
+ ctxt.Out.SeekSet(0)
switch ld.Headtype {
default:
case objabi.Hplan9: /* plan 9 */
- ld.Thearch.Lput(0x647) /* magic */
- ld.Thearch.Lput(uint32(ld.Segtext.Filelen)) /* sizes */
- ld.Thearch.Lput(uint32(ld.Segdata.Filelen))
- ld.Thearch.Lput(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
- ld.Thearch.Lput(uint32(ld.Symsize)) /* nsyms */
- ld.Thearch.Lput(uint32(ld.Entryvalue(ctxt))) /* va of entry */
- ld.Thearch.Lput(0)
- ld.Thearch.Lput(uint32(ld.Lcsize))
+ ctxt.Out.Write32(0x647) /* magic */
+ ctxt.Out.Write32(uint32(ld.Segtext.Filelen)) /* sizes */
+ ctxt.Out.Write32(uint32(ld.Segdata.Filelen))
+ ctxt.Out.Write32(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
+ ctxt.Out.Write32(uint32(ld.Symsize)) /* nsyms */
+ ctxt.Out.Write32(uint32(ld.Entryvalue(ctxt))) /* va of entry */
+ ctxt.Out.Write32(0)
+ ctxt.Out.Write32(uint32(ld.Lcsize))
case objabi.Hlinux,
objabi.Hfreebsd,
ld.Asmbmacho(ctxt)
}
- ld.Cflush()
+ ctxt.Out.Flush()
if *ld.FlagC {
fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
Elfsetupplt: elfsetupplt,
Gentext: gentext,
Machoreloc1: machoreloc1,
- Lput: ld.Lputl,
- Wput: ld.Wputl,
- Vput: ld.Vputl,
- Append16: ld.Append16l,
- Append32: ld.Append32l,
- Append64: ld.Append64l,
Linuxdynld: "/lib/ld-linux-aarch64.so.1",
}
func CodeblkPad(ctxt *Link, addr int64, size int64, pad []byte) {
if *flagA {
- ctxt.Logf("codeblk [%#x,%#x) at offset %#x\n", addr, addr+size, coutbuf.Offset())
+ ctxt.Logf("codeblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset())
}
blk(ctxt, ctxt.Textp, addr, size, pad)
errorexit()
}
if addr < s.Value {
- strnputPad("", int(s.Value-addr), pad)
+ ctxt.Out.WriteStringPad("", int(s.Value-addr), pad)
addr = s.Value
}
- Cwrite(s.P)
+ ctxt.Out.Write(s.P)
addr += int64(len(s.P))
if addr < s.Value+s.Size {
- strnputPad("", int(s.Value+s.Size-addr), pad)
+ ctxt.Out.WriteStringPad("", int(s.Value+s.Size-addr), pad)
addr = s.Value + s.Size
}
if addr != s.Value+s.Size {
}
if addr < eaddr {
- strnputPad("", int(eaddr-addr), pad)
+ ctxt.Out.WriteStringPad("", int(eaddr-addr), pad)
}
- Cflush()
+ ctxt.Out.Flush()
}
func Datblk(ctxt *Link, addr int64, size int64) {
if *flagA {
- ctxt.Logf("datblk [%#x,%#x) at offset %#x\n", addr, addr+size, coutbuf.Offset())
+ ctxt.Logf("datblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset())
}
blk(ctxt, datap, addr, size, zeros[:])
func Dwarfblk(ctxt *Link, addr int64, size int64) {
if *flagA {
- ctxt.Logf("dwarfblk [%#x,%#x) at offset %#x\n", addr, addr+size, coutbuf.Offset())
+ ctxt.Logf("dwarfblk [%#x,%#x) at offset %#x\n", addr, addr+size, ctxt.Out.Offset())
}
blk(ctxt, dwarfp, addr, size, zeros[:])
var zeros [512]byte
-// strnput writes the first n bytes of s.
-// If n is larger than len(s),
-// it is padded with NUL bytes.
-func strnput(s string, n int) {
- strnputPad(s, n, zeros[:])
-}
-
-// strnput writes the first n bytes of s.
-// If n is larger than len(s),
-// it is padded with the bytes in pad (repeated as needed).
-func strnputPad(s string, n int, pad []byte) {
- if len(s) >= n {
- Cwritestring(s[:n])
- } else {
- Cwritestring(s)
- n -= len(s)
- for n > len(pad) {
- Cwrite(pad)
- n -= len(pad)
-
- }
- Cwrite(pad[:n])
- }
-}
-
var strdata []*Symbol
func addstrdata1(ctxt *Link, arg string) {
import (
"cmd/internal/dwarf"
"cmd/internal/objabi"
+ "cmd/internal/sys"
"fmt"
"log"
"os"
)
// appendPCDeltaCFA appends per-PC CFA deltas to b and returns the final slice.
-func appendPCDeltaCFA(b []byte, deltapc, cfa int64) []byte {
+func appendPCDeltaCFA(arch *sys.Arch, b []byte, deltapc, cfa int64) []byte {
b = append(b, dwarf.DW_CFA_def_cfa_offset_sf)
b = dwarf.AppendSleb128(b, cfa/dataAlignmentFactor)
b = append(b, dwarf.DW_CFA_advance_loc1)
b = append(b, uint8(deltapc))
case deltapc < 0x10000:
- b = append(b, dwarf.DW_CFA_advance_loc2)
- b = Thearch.Append16(b, uint16(deltapc))
+ b = append(b, dwarf.DW_CFA_advance_loc2, 0, 0)
+ arch.ByteOrder.PutUint16(b[len(b)-2:], uint16(deltapc))
default:
- b = append(b, dwarf.DW_CFA_advance_loc4)
- b = Thearch.Append32(b, uint32(deltapc))
+ b = append(b, dwarf.DW_CFA_advance_loc4, 0, 0, 0, 0)
+ arch.ByteOrder.PutUint32(b[len(b)-4:], uint32(deltapc))
}
return b
}
deltaBuf = append(deltaBuf, dwarf.DW_CFA_same_value)
deltaBuf = dwarf.AppendUleb128(deltaBuf, uint64(Thearch.Dwarfreglr))
}
- deltaBuf = appendPCDeltaCFA(deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(pcsp.value))
+ deltaBuf = appendPCDeltaCFA(ctxt.Arch, deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(pcsp.value))
} else {
- deltaBuf = appendPCDeltaCFA(deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(ctxt.Arch.PtrSize)+int64(pcsp.value))
+ deltaBuf = appendPCDeltaCFA(ctxt.Arch, deltaBuf, int64(nextpc)-int64(pcsp.pc), int64(ctxt.Arch.PtrSize)+int64(pcsp.value))
}
}
pad := int(Rnd(int64(len(deltaBuf)), int64(ctxt.Arch.PtrSize))) - len(deltaBuf)
return
}
sym := ctxt.Syms.Lookup(".debug_info", 0)
- putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
+ putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
sym = ctxt.Syms.Lookup(".debug_abbrev", 0)
- putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
+ putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
sym = ctxt.Syms.Lookup(".debug_line", 0)
- putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
+ putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
sym = ctxt.Syms.Lookup(".debug_frame", 0)
- putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
+ putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
sym = ctxt.Syms.Lookup(".debug_loc", 0)
if sym.Sect != nil {
- putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
+ putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
}
sym = ctxt.Syms.Lookup(".debug_ranges", 0)
if sym.Sect != nil {
- putelfsectionsym(sym, sym.Sect.Elfsect.shnum)
+ putelfsectionsym(ctxt.Out, sym, sym.Sect.Elfsect.shnum)
}
}
e.memsz += uint64(frag)
}
-func elf64phdr(e *ElfPhdr) {
+func elf64phdr(out *OutBuf, e *ElfPhdr) {
if e.type_ == PT_LOAD {
fixElfPhdr(e)
}
- Thearch.Lput(e.type_)
- Thearch.Lput(e.flags)
- Thearch.Vput(e.off)
- Thearch.Vput(e.vaddr)
- Thearch.Vput(e.paddr)
- Thearch.Vput(e.filesz)
- Thearch.Vput(e.memsz)
- Thearch.Vput(e.align)
+ out.Write32(e.type_)
+ out.Write32(e.flags)
+ out.Write64(e.off)
+ out.Write64(e.vaddr)
+ out.Write64(e.paddr)
+ out.Write64(e.filesz)
+ out.Write64(e.memsz)
+ out.Write64(e.align)
}
-func elf32phdr(e *ElfPhdr) {
+func elf32phdr(out *OutBuf, e *ElfPhdr) {
if e.type_ == PT_LOAD {
fixElfPhdr(e)
}
- Thearch.Lput(e.type_)
- Thearch.Lput(uint32(e.off))
- Thearch.Lput(uint32(e.vaddr))
- Thearch.Lput(uint32(e.paddr))
- Thearch.Lput(uint32(e.filesz))
- Thearch.Lput(uint32(e.memsz))
- Thearch.Lput(e.flags)
- Thearch.Lput(uint32(e.align))
-}
-
-func elf64shdr(e *ElfShdr) {
- Thearch.Lput(e.name)
- Thearch.Lput(e.type_)
- Thearch.Vput(e.flags)
- Thearch.Vput(e.addr)
- Thearch.Vput(e.off)
- Thearch.Vput(e.size)
- Thearch.Lput(e.link)
- Thearch.Lput(e.info)
- Thearch.Vput(e.addralign)
- Thearch.Vput(e.entsize)
-}
-
-func elf32shdr(e *ElfShdr) {
- Thearch.Lput(e.name)
- Thearch.Lput(e.type_)
- Thearch.Lput(uint32(e.flags))
- Thearch.Lput(uint32(e.addr))
- Thearch.Lput(uint32(e.off))
- Thearch.Lput(uint32(e.size))
- Thearch.Lput(e.link)
- Thearch.Lput(e.info)
- Thearch.Lput(uint32(e.addralign))
- Thearch.Lput(uint32(e.entsize))
-}
-
-func elfwriteshdrs() uint32 {
+ out.Write32(e.type_)
+ out.Write32(uint32(e.off))
+ out.Write32(uint32(e.vaddr))
+ out.Write32(uint32(e.paddr))
+ out.Write32(uint32(e.filesz))
+ out.Write32(uint32(e.memsz))
+ out.Write32(e.flags)
+ out.Write32(uint32(e.align))
+}
+
+func elf64shdr(out *OutBuf, e *ElfShdr) {
+ out.Write32(e.name)
+ out.Write32(e.type_)
+ out.Write64(e.flags)
+ out.Write64(e.addr)
+ out.Write64(e.off)
+ out.Write64(e.size)
+ out.Write32(e.link)
+ out.Write32(e.info)
+ out.Write64(e.addralign)
+ out.Write64(e.entsize)
+}
+
+func elf32shdr(out *OutBuf, e *ElfShdr) {
+ out.Write32(e.name)
+ out.Write32(e.type_)
+ out.Write32(uint32(e.flags))
+ out.Write32(uint32(e.addr))
+ out.Write32(uint32(e.off))
+ out.Write32(uint32(e.size))
+ out.Write32(e.link)
+ out.Write32(e.info)
+ out.Write32(uint32(e.addralign))
+ out.Write32(uint32(e.entsize))
+}
+
+func elfwriteshdrs(out *OutBuf) uint32 {
if elf64 {
for i := 0; i < int(ehdr.shnum); i++ {
- elf64shdr(shdr[i])
+ elf64shdr(out, shdr[i])
}
return uint32(ehdr.shnum) * ELF64SHDRSIZE
}
for i := 0; i < int(ehdr.shnum); i++ {
- elf32shdr(shdr[i])
+ elf32shdr(out, shdr[i])
}
return uint32(ehdr.shnum) * ELF32SHDRSIZE
}
nelfstr++
}
-func elfwritephdrs() uint32 {
+func elfwritephdrs(out *OutBuf) uint32 {
if elf64 {
for i := 0; i < int(ehdr.phnum); i++ {
- elf64phdr(phdr[i])
+ elf64phdr(out, phdr[i])
}
return uint32(ehdr.phnum) * ELF64PHDRSIZE
}
for i := 0; i < int(ehdr.phnum); i++ {
- elf32phdr(phdr[i])
+ elf32phdr(out, phdr[i])
}
return uint32(ehdr.phnum) * ELF32PHDRSIZE
}
return &ehdr
}
-func elf64writehdr() uint32 {
- Cwrite(ehdr.ident[:])
- Thearch.Wput(ehdr.type_)
- Thearch.Wput(ehdr.machine)
- Thearch.Lput(ehdr.version)
- Thearch.Vput(ehdr.entry)
- Thearch.Vput(ehdr.phoff)
- Thearch.Vput(ehdr.shoff)
- Thearch.Lput(ehdr.flags)
- Thearch.Wput(ehdr.ehsize)
- Thearch.Wput(ehdr.phentsize)
- Thearch.Wput(ehdr.phnum)
- Thearch.Wput(ehdr.shentsize)
- Thearch.Wput(ehdr.shnum)
- Thearch.Wput(ehdr.shstrndx)
+func elf64writehdr(out *OutBuf) uint32 {
+ out.Write(ehdr.ident[:])
+ out.Write16(ehdr.type_)
+ out.Write16(ehdr.machine)
+ out.Write32(ehdr.version)
+ out.Write64(ehdr.entry)
+ out.Write64(ehdr.phoff)
+ out.Write64(ehdr.shoff)
+ out.Write32(ehdr.flags)
+ out.Write16(ehdr.ehsize)
+ out.Write16(ehdr.phentsize)
+ out.Write16(ehdr.phnum)
+ out.Write16(ehdr.shentsize)
+ out.Write16(ehdr.shnum)
+ out.Write16(ehdr.shstrndx)
return ELF64HDRSIZE
}
-func elf32writehdr() uint32 {
- Cwrite(ehdr.ident[:])
- Thearch.Wput(ehdr.type_)
- Thearch.Wput(ehdr.machine)
- Thearch.Lput(ehdr.version)
- Thearch.Lput(uint32(ehdr.entry))
- Thearch.Lput(uint32(ehdr.phoff))
- Thearch.Lput(uint32(ehdr.shoff))
- Thearch.Lput(ehdr.flags)
- Thearch.Wput(ehdr.ehsize)
- Thearch.Wput(ehdr.phentsize)
- Thearch.Wput(ehdr.phnum)
- Thearch.Wput(ehdr.shentsize)
- Thearch.Wput(ehdr.shnum)
- Thearch.Wput(ehdr.shstrndx)
+func elf32writehdr(out *OutBuf) uint32 {
+ out.Write(ehdr.ident[:])
+ out.Write16(ehdr.type_)
+ out.Write16(ehdr.machine)
+ out.Write32(ehdr.version)
+ out.Write32(uint32(ehdr.entry))
+ out.Write32(uint32(ehdr.phoff))
+ out.Write32(uint32(ehdr.shoff))
+ out.Write32(ehdr.flags)
+ out.Write16(ehdr.ehsize)
+ out.Write16(ehdr.phentsize)
+ out.Write16(ehdr.phnum)
+ out.Write16(ehdr.shentsize)
+ out.Write16(ehdr.shnum)
+ out.Write16(ehdr.shstrndx)
return ELF32HDRSIZE
}
-func elfwritehdr() uint32 {
+func elfwritehdr(out *OutBuf) uint32 {
if elf64 {
- return elf64writehdr()
+ return elf64writehdr(out)
}
- return elf32writehdr()
+ return elf32writehdr(out)
}
/* Taken directly from the definition document for ELF64 */
return n
}
-func elfwriteinterp() int {
+func elfwriteinterp(out *OutBuf) int {
sh := elfshname(".interp")
- Cseek(int64(sh.off))
- coutbuf.WriteString(interp)
- Cput(0)
+ out.SeekSet(int64(sh.off))
+ out.WriteString(interp)
+ out.Write8(0)
return int(sh.size)
}
return int(n)
}
-func elfwritenotehdr(str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
+func elfwritenotehdr(out *OutBuf, str string, namesz uint32, descsz uint32, tag uint32) *ElfShdr {
sh := elfshname(str)
// Write Elf_Note header.
- Cseek(int64(sh.off))
+ out.SeekSet(int64(sh.off))
- Thearch.Lput(namesz)
- Thearch.Lput(descsz)
- Thearch.Lput(tag)
+ out.Write32(namesz)
+ out.Write32(descsz)
+ out.Write32(tag)
return sh
}
return elfnote(sh, startva, resoff, n, true)
}
-func elfwritenetbsdsig() int {
+func elfwritenetbsdsig(out *OutBuf) int {
// Write Elf_Note header.
- sh := elfwritenotehdr(".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
+ sh := elfwritenotehdr(out, ".note.netbsd.ident", ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG)
if sh == nil {
return 0
}
// Followed by NetBSD string and version.
- Cwrite(ELF_NOTE_NETBSD_NAME)
- Cput(0)
-
- Thearch.Lput(ELF_NOTE_NETBSD_VERSION)
+ out.Write(ELF_NOTE_NETBSD_NAME)
+ out.Write8(0)
+ out.Write32(ELF_NOTE_NETBSD_VERSION)
return int(sh.size)
}
return elfnote(sh, startva, resoff, n, true)
}
-func elfwriteopenbsdsig() int {
+func elfwriteopenbsdsig(out *OutBuf) int {
// Write Elf_Note header.
- sh := elfwritenotehdr(".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
+ sh := elfwritenotehdr(out, ".note.openbsd.ident", ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG)
if sh == nil {
return 0
}
// Followed by OpenBSD string and version.
- Cwrite(ELF_NOTE_OPENBSD_NAME)
+ out.Write(ELF_NOTE_OPENBSD_NAME)
- Thearch.Lput(ELF_NOTE_OPENBSD_VERSION)
+ out.Write32(ELF_NOTE_OPENBSD_VERSION)
return int(sh.size)
}
return elfnote(sh, startva, resoff, n, true)
}
-func elfwritebuildinfo() int {
- sh := elfwritenotehdr(".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
+func elfwritebuildinfo(out *OutBuf) int {
+ sh := elfwritenotehdr(out, ".note.gnu.build-id", ELF_NOTE_BUILDINFO_NAMESZ, uint32(len(buildinfo)), ELF_NOTE_BUILDINFO_TAG)
if sh == nil {
return 0
}
- Cwrite(ELF_NOTE_BUILDINFO_NAME)
- Cwrite(buildinfo)
+ out.Write(ELF_NOTE_BUILDINFO_NAME)
+ out.Write(buildinfo)
var zero = make([]byte, 4)
- Cwrite(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))])
+ out.Write(zero[:int(Rnd(int64(len(buildinfo)), 4)-int64(len(buildinfo)))])
return int(sh.size)
}
-func elfwritegobuildid() int {
- sh := elfwritenotehdr(".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(*flagBuildid)), ELF_NOTE_GOBUILDID_TAG)
+func elfwritegobuildid(out *OutBuf) int {
+ sh := elfwritenotehdr(out, ".note.go.buildid", uint32(len(ELF_NOTE_GO_NAME)), uint32(len(*flagBuildid)), ELF_NOTE_GOBUILDID_TAG)
if sh == nil {
return 0
}
- Cwrite(ELF_NOTE_GO_NAME)
- Cwrite([]byte(*flagBuildid))
+ out.Write(ELF_NOTE_GO_NAME)
+ out.Write([]byte(*flagBuildid))
var zero = make([]byte, 4)
- Cwrite(zero[:int(Rnd(int64(len(*flagBuildid)), 4)-int64(len(*flagBuildid)))])
+ out.Write(zero[:int(Rnd(int64(len(*flagBuildid)), 4)-int64(len(*flagBuildid)))])
return int(sh.size)
}
return
}
- sect.Reloff = uint64(coutbuf.Offset())
+ sect.Reloff = uint64(ctxt.Out.Offset())
for i, s := range syms {
if !s.Attr.Reachable() {
continue
}
}
- sect.Rellen = uint64(coutbuf.Offset()) - sect.Reloff
+ sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
}
func Elfemitreloc(ctxt *Link) {
- for coutbuf.Offset()&7 != 0 {
- Cput(0)
+ for ctxt.Out.Offset()&7 != 0 {
+ ctxt.Out.Write8(0)
}
for _, sect := range Segtext.Sections {
pph.memsz = pph.filesz
}
- Cseek(0)
+ ctxt.Out.SeekSet(0)
a := int64(0)
- a += int64(elfwritehdr())
- a += int64(elfwritephdrs())
- a += int64(elfwriteshdrs())
+ a += int64(elfwritehdr(ctxt.Out))
+ a += int64(elfwritephdrs(ctxt.Out))
+ a += int64(elfwriteshdrs(ctxt.Out))
if !*FlagD {
- a += int64(elfwriteinterp())
+ a += int64(elfwriteinterp(ctxt.Out))
}
if Linkmode != LinkExternal {
if Headtype == objabi.Hnetbsd {
- a += int64(elfwritenetbsdsig())
+ a += int64(elfwritenetbsdsig(ctxt.Out))
}
if Headtype == objabi.Hopenbsd {
- a += int64(elfwriteopenbsdsig())
+ a += int64(elfwriteopenbsdsig(ctxt.Out))
}
if len(buildinfo) > 0 {
- a += int64(elfwritebuildinfo())
+ a += int64(elfwritebuildinfo(ctxt.Out))
}
if *flagBuildid != "" {
- a += int64(elfwritegobuildid())
+ a += int64(elfwritegobuildid(ctxt.Out))
}
}
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.
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 (
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 {
}
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)
}
}
}
} else {
- hostlinksetup()
+ hostlinksetup(ctxt)
}
// We've loaded all the code now.
os.RemoveAll(*flagTmpdir)
}
-func hostlinksetup() {
+func hostlinksetup(ctxt *Link) {
if Linkmode != LinkExternal {
return
}
}
// change our output to temporary object file
- coutbuf.f.Close()
+ ctxt.Out.f.Close()
mayberemoveoutfile()
p := filepath.Join(*flagTmpdir, "go.o")
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
// 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"))
}
}
-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)
// Link holds the context for writing object code from a compiler
// or for reading that input into the linker.
type Link struct {
+ Out *OutBuf
+
Syms *Symbols
Arch *sys.Arch
var linkoff int64
-func machowrite(arch *sys.Arch) int {
- o1 := coutbuf.Offset()
+func machowrite(arch *sys.Arch, out *OutBuf) int {
+ o1 := out.Offset()
loadsize := 4 * 4 * ndebug
for i := 0; i < len(load); i++ {
}
if arch.PtrSize == 8 {
- Thearch.Lput(MH_MAGIC_64)
+ out.Write32(MH_MAGIC_64)
} else {
- Thearch.Lput(MH_MAGIC)
+ out.Write32(MH_MAGIC)
}
- Thearch.Lput(machohdr.cpu)
- Thearch.Lput(machohdr.subcpu)
+ out.Write32(machohdr.cpu)
+ out.Write32(machohdr.subcpu)
if Linkmode == LinkExternal {
- Thearch.Lput(MH_OBJECT) /* file type - mach object */
+ out.Write32(MH_OBJECT) /* file type - mach object */
} else {
- Thearch.Lput(MH_EXECUTE) /* file type - mach executable */
+ out.Write32(MH_EXECUTE) /* file type - mach executable */
}
- Thearch.Lput(uint32(len(load)) + uint32(nseg) + uint32(ndebug))
- Thearch.Lput(uint32(loadsize))
+ out.Write32(uint32(len(load)) + uint32(nseg) + uint32(ndebug))
+ out.Write32(uint32(loadsize))
if nkind[SymKindUndef] == 0 {
- Thearch.Lput(MH_NOUNDEFS) /* flags - no undefines */
+ out.Write32(MH_NOUNDEFS) /* flags - no undefines */
} else {
- Thearch.Lput(0) /* flags */
+ out.Write32(0) /* flags */
}
if arch.PtrSize == 8 {
- Thearch.Lput(0) /* reserved */
+ out.Write32(0) /* reserved */
}
for i := 0; i < nseg; i++ {
s := &seg[i]
if arch.PtrSize == 8 {
- Thearch.Lput(LC_SEGMENT_64)
- Thearch.Lput(72 + 80*s.nsect)
- strnput(s.name, 16)
- Thearch.Vput(s.vaddr)
- Thearch.Vput(s.vsize)
- Thearch.Vput(s.fileoffset)
- Thearch.Vput(s.filesize)
- Thearch.Lput(s.prot1)
- Thearch.Lput(s.prot2)
- Thearch.Lput(s.nsect)
- Thearch.Lput(s.flag)
+ out.Write32(LC_SEGMENT_64)
+ out.Write32(72 + 80*s.nsect)
+ out.WriteStringN(s.name, 16)
+ out.Write64(s.vaddr)
+ out.Write64(s.vsize)
+ out.Write64(s.fileoffset)
+ out.Write64(s.filesize)
+ out.Write32(s.prot1)
+ out.Write32(s.prot2)
+ out.Write32(s.nsect)
+ out.Write32(s.flag)
} else {
- Thearch.Lput(LC_SEGMENT)
- Thearch.Lput(56 + 68*s.nsect)
- strnput(s.name, 16)
- Thearch.Lput(uint32(s.vaddr))
- Thearch.Lput(uint32(s.vsize))
- Thearch.Lput(uint32(s.fileoffset))
- Thearch.Lput(uint32(s.filesize))
- Thearch.Lput(s.prot1)
- Thearch.Lput(s.prot2)
- Thearch.Lput(s.nsect)
- Thearch.Lput(s.flag)
+ out.Write32(LC_SEGMENT)
+ out.Write32(56 + 68*s.nsect)
+ out.WriteStringN(s.name, 16)
+ out.Write32(uint32(s.vaddr))
+ out.Write32(uint32(s.vsize))
+ out.Write32(uint32(s.fileoffset))
+ out.Write32(uint32(s.filesize))
+ out.Write32(s.prot1)
+ out.Write32(s.prot2)
+ out.Write32(s.nsect)
+ out.Write32(s.flag)
}
for j := uint32(0); j < s.nsect; j++ {
t := &s.sect[j]
if arch.PtrSize == 8 {
- strnput(t.name, 16)
- strnput(t.segname, 16)
- Thearch.Vput(t.addr)
- Thearch.Vput(t.size)
- Thearch.Lput(t.off)
- Thearch.Lput(t.align)
- Thearch.Lput(t.reloc)
- Thearch.Lput(t.nreloc)
- Thearch.Lput(t.flag)
- Thearch.Lput(t.res1) /* reserved */
- Thearch.Lput(t.res2) /* reserved */
- Thearch.Lput(0) /* reserved */
+ out.WriteStringN(t.name, 16)
+ out.WriteStringN(t.segname, 16)
+ out.Write64(t.addr)
+ out.Write64(t.size)
+ out.Write32(t.off)
+ out.Write32(t.align)
+ out.Write32(t.reloc)
+ out.Write32(t.nreloc)
+ out.Write32(t.flag)
+ out.Write32(t.res1) /* reserved */
+ out.Write32(t.res2) /* reserved */
+ out.Write32(0) /* reserved */
} else {
- strnput(t.name, 16)
- strnput(t.segname, 16)
- Thearch.Lput(uint32(t.addr))
- Thearch.Lput(uint32(t.size))
- Thearch.Lput(t.off)
- Thearch.Lput(t.align)
- Thearch.Lput(t.reloc)
- Thearch.Lput(t.nreloc)
- Thearch.Lput(t.flag)
- Thearch.Lput(t.res1) /* reserved */
- Thearch.Lput(t.res2) /* reserved */
+ out.WriteStringN(t.name, 16)
+ out.WriteStringN(t.segname, 16)
+ out.Write32(uint32(t.addr))
+ out.Write32(uint32(t.size))
+ out.Write32(t.off)
+ out.Write32(t.align)
+ out.Write32(t.reloc)
+ out.Write32(t.nreloc)
+ out.Write32(t.flag)
+ out.Write32(t.res1) /* reserved */
+ out.Write32(t.res2) /* reserved */
}
}
}
for i := 0; i < len(load); i++ {
l := &load[i]
- Thearch.Lput(l.type_)
- Thearch.Lput(4 * (uint32(len(l.data)) + 2))
+ out.Write32(l.type_)
+ out.Write32(4 * (uint32(len(l.data)) + 2))
for j := 0; j < len(l.data); j++ {
- Thearch.Lput(l.data[j])
+ out.Write32(l.data[j])
}
}
- return int(coutbuf.Offset() - o1)
+ return int(out.Offset() - o1)
}
func (ctxt *Link) domacho() {
ml.data[1] = 10<<16 | 7<<8 | 0<<0 // SDK 10.7.0
}
- a := machowrite(ctxt.Arch)
+ a := machowrite(ctxt.Arch, ctxt.Out)
if int32(a) > HEADR {
Exitf("HEADR too small: %d > %d", a, HEADR)
}
if size > 0 {
linkoff = Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound)) + Rnd(int64(Segdata.Filelen), int64(*FlagRound)) + Rnd(int64(Segdwarf.Filelen), int64(*FlagRound))
- Cseek(linkoff)
+ ctxt.Out.SeekSet(linkoff)
- Cwrite(s1.P[:s1.Size])
- Cwrite(s2.P[:s2.Size])
- Cwrite(s3.P[:s3.Size])
- Cwrite(s4.P[:s4.Size])
+ ctxt.Out.Write(s1.P[:s1.Size])
+ ctxt.Out.Write(s2.P[:s2.Size])
+ ctxt.Out.Write(s3.P[:s3.Size])
+ ctxt.Out.Write(s4.P[:s4.Size])
}
return Rnd(int64(size), int64(*FlagRound))
return
}
- sect.Reloff = uint64(coutbuf.Offset())
+ sect.Reloff = uint64(ctxt.Out.Offset())
for i, s := range syms {
if !s.Attr.Reachable() {
continue
if !r.Xsym.Attr.Reachable() {
Errorf(sym, "unreachable reloc %d (%s) target %v", r.Type, RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
}
- if !Thearch.Machoreloc1(ctxt.Arch, sym, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) {
+ if !Thearch.Machoreloc1(ctxt.Arch, ctxt.Out, sym, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) {
Errorf(sym, "unsupported obj reloc %d (%s)/%d to %s", r.Type, RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name)
}
}
}
- sect.Rellen = uint64(coutbuf.Offset()) - sect.Reloff
+ sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
}
func Machoemitreloc(ctxt *Link) {
- for coutbuf.Offset()&7 != 0 {
- Cput(0)
+ for ctxt.Out.Offset()&7 != 0 {
+ ctxt.Out.Write8(0)
}
machorelocsect(ctxt, Segtext.Sections[0], ctxt.Textp)
--- /dev/null
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ld
+
+import (
+ "bufio"
+ "cmd/internal/sys"
+ "encoding/binary"
+ "os"
+)
+
+// OutBuf is a buffered file writer.
+//
+// It is simlar to the Writer in cmd/internal/bio with a few small differences.
+//
+// First, it tracks the output architecture and uses it to provide
+// endian helpers.
+//
+// Second, it provides a very cheap offset counter that doesn't require
+// any system calls to read the value.
+type OutBuf struct {
+ arch *sys.Arch
+ off int64
+ w *bufio.Writer
+ f *os.File
+ encbuf [8]byte // temp buffer used by WriteN methods
+}
+
+func (out *OutBuf) SeekSet(p int64) {
+ if p == out.off {
+ return
+ }
+ out.Flush()
+ if _, err := out.f.Seek(p, 0); err != nil {
+ Exitf("seeking to %d in %s: %v", p, out.f.Name(), err)
+ }
+ out.off = p
+}
+
+func (out *OutBuf) Offset() int64 {
+ return out.off
+}
+
+// Write writes the contents of v to the buffer.
+//
+// As Write is backed by a bufio.Writer, callers do not have
+// to explicitly handle the returned error as long as Flush is
+// eventually called.
+func (out *OutBuf) Write(v []byte) (int, error) {
+ n, err := out.w.Write(v)
+ out.off += int64(n)
+ return n, err
+}
+
+func (out *OutBuf) Write8(v uint8) {
+ if err := out.w.WriteByte(v); err == nil {
+ out.off++
+ }
+}
+
+func (out *OutBuf) Write16(v uint16) {
+ out.arch.ByteOrder.PutUint16(out.encbuf[:], v)
+ out.Write(out.encbuf[:2])
+}
+
+func (out *OutBuf) Write32(v uint32) {
+ out.arch.ByteOrder.PutUint32(out.encbuf[:], v)
+ out.Write(out.encbuf[:4])
+}
+
+func (out *OutBuf) Write32b(v uint32) {
+ binary.BigEndian.PutUint32(out.encbuf[:], v)
+ out.Write(out.encbuf[:4])
+}
+
+func (out *OutBuf) Write64(v uint64) {
+ out.arch.ByteOrder.PutUint64(out.encbuf[:], v)
+ out.Write(out.encbuf[:8])
+}
+
+func (out *OutBuf) Write64b(v uint64) {
+ binary.BigEndian.PutUint64(out.encbuf[:], v)
+ out.Write(out.encbuf[:8])
+}
+
+func (out *OutBuf) WriteString(s string) {
+ n, _ := out.w.WriteString(s)
+ out.off += int64(n)
+}
+
+// WriteStringN writes the first n bytes of s.
+// If n is larger than len(s) then it is padded with zero bytes.
+func (out *OutBuf) WriteStringN(s string, n int) {
+ out.WriteStringPad(s, n, zeros[:])
+}
+
+// WriteStringPad writes the first n bytes of s.
+// If n is larger than len(s) then it is padded with the bytes in pad (repeated as needed).
+func (out *OutBuf) WriteStringPad(s string, n int, pad []byte) {
+ if len(s) >= n {
+ out.WriteString(s[:n])
+ } else {
+ out.WriteString(s)
+ n -= len(s)
+ for n > len(pad) {
+ out.Write(pad)
+ n -= len(pad)
+
+ }
+ out.Write(pad[:n])
+ }
+}
+
+func (out *OutBuf) Flush() {
+ if err := out.w.Flush(); err != nil {
+ Exitf("flushing %s: %v", out.f.Name(), err)
+ }
+}
}
// write writes string table t into the output file.
-func (t *peStringTable) write() {
- Lputl(uint32(t.size()))
+func (t *peStringTable) write(out *OutBuf) {
+ out.Write32(uint32(t.size()))
for _, s := range t.strings {
- Cwritestring(s)
- Cput(0)
+ out.WriteString(s)
+ out.Write8(0)
}
}
// pad adds zeros to the section sect. It writes as many bytes
// as necessary to make section sect.SizeOfRawData bytes long.
// It assumes that n bytes are already written to the file.
-func (sect *peSection) pad(n uint32) {
- strnput("", int(sect.sizeOfRawData-n))
+func (sect *peSection) pad(out *OutBuf, n uint32) {
+ out.WriteStringN("", int(sect.sizeOfRawData-n))
}
// write writes COFF section sect into the output file.
-func (sect *peSection) write() error {
+func (sect *peSection) write(out *OutBuf) error {
h := pe.SectionHeader32{
VirtualSize: sect.virtualSize,
SizeOfRawData: sect.sizeOfRawData,
h.VirtualAddress = sect.virtualAddress
}
copy(h.Name[:], sect.shortName)
- return binary.Write(&coutbuf, binary.LittleEndian, h)
+ return binary.Write(out, binary.LittleEndian, h)
}
// emitRelocations emits the relocation entries for the sect.
// The actual relocations are emitted by relocfn.
// This updates the corresponding PE section table entry
// with the relocation offset and count.
-func (sect *peSection) emitRelocations(relocfn func() int) {
- sect.pointerToRelocations = uint32(coutbuf.Offset())
+func (sect *peSection) emitRelocations(out *OutBuf, relocfn func() int) {
+ sect.pointerToRelocations = uint32(out.Offset())
// first entry: extended relocs
- Lputl(0) // placeholder for number of relocation + 1
- Lputl(0)
- Wputl(0)
+ out.Write32(0) // placeholder for number of relocation + 1
+ out.Write32(0)
+ out.Write16(0)
n := relocfn() + 1
- cpos := coutbuf.Offset()
- Cseek(int64(sect.pointerToRelocations))
- Lputl(uint32(n))
- Cseek(cpos)
+ cpos := out.Offset()
+ out.SeekSet(int64(sect.pointerToRelocations))
+ out.Write32(uint32(n))
+ out.SeekSet(cpos)
if n > 0x10000 {
n = 0x10000
sect.characteristics |= IMAGE_SCN_LNK_NRELOC_OVFL
sect := f.addSection(".ctors", size, size)
sect.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
sect.sizeOfRawData = uint32(size)
- Cseek(int64(sect.pointerToRawData))
- sect.checkOffset(coutbuf.Offset())
+ ctxt.Out.SeekSet(int64(sect.pointerToRawData))
+ sect.checkOffset(ctxt.Out.Offset())
init_entry := ctxt.Syms.Lookup(*flagEntrySymbol, 0)
addr := uint64(init_entry.Value) - init_entry.Sect.Vaddr
switch objabi.GOARCH {
case "386":
- Lputl(uint32(addr))
+ ctxt.Out.Write32(uint32(addr))
case "amd64":
- Vputl(addr)
+ ctxt.Out.Write64(addr)
}
return sect
}
// emitRelocations emits relocation entries for go.o in external linking.
func (f *peFile) emitRelocations(ctxt *Link) {
- for coutbuf.Offset()&7 != 0 {
- Cput(0)
+ for ctxt.Out.Offset()&7 != 0 {
+ ctxt.Out.Write8(0)
}
// relocsect relocates symbols from first in section sect, and returns
return 0
}
relocs := 0
- sect.Reloff = uint64(coutbuf.Offset())
+ sect.Reloff = uint64(ctxt.Out.Offset())
for i, s := range syms {
if !s.Attr.Reachable() {
continue
if r.Xsym.Dynid < 0 {
Errorf(sym, "reloc %d to non-coff symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
}
- if !Thearch.PEreloc1(ctxt.Arch, sym, r, int64(uint64(sym.Value+int64(r.Off))-base)) {
+ if !Thearch.PEreloc1(ctxt.Arch, ctxt.Out, sym, r, int64(uint64(sym.Value+int64(r.Off))-base)) {
Errorf(sym, "unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
}
relocs++
}
}
- sect.Rellen = uint64(coutbuf.Offset()) - sect.Reloff
+ sect.Rellen = uint64(ctxt.Out.Offset()) - sect.Reloff
return relocs
}
- f.textSect.emitRelocations(func() int {
+ f.textSect.emitRelocations(ctxt.Out, func() int {
n := relocsect(Segtext.Sections[0], ctxt.Textp, Segtext.Vaddr)
for _, sect := range Segtext.Sections[1:] {
n += relocsect(sect, datap, Segtext.Vaddr)
return n
})
- f.dataSect.emitRelocations(func() int {
+ f.dataSect.emitRelocations(ctxt.Out, func() int {
var n int
for _, sect := range Segdata.Sections {
n += relocsect(sect, datap, Segdata.Vaddr)
for _, sect := range Segdwarf.Sections {
for _, pesect := range f.sections {
if sect.Name == pesect.name {
- pesect.emitRelocations(func() int {
+ pesect.emitRelocations(ctxt.Out, func() int {
return relocsect(sect, dwarfp, sect.Vaddr)
})
continue dwarfLoop
Errorf(nil, "emitRelocations: could not find %q section", sect.Name)
}
- f.ctorsSect.emitRelocations(func() int {
+ f.ctorsSect.emitRelocations(ctxt.Out, func() int {
dottext := ctxt.Syms.Lookup(".text", 0)
- Lputl(0)
- Lputl(uint32(dottext.Dynid))
+ ctxt.Out.Write32(0)
+ ctxt.Out.Write32(uint32(dottext.Dynid))
switch objabi.GOARCH {
default:
Errorf(dottext, "unknown architecture for PE: %q\n", objabi.GOARCH)
case "386":
- Wputl(IMAGE_REL_I386_DIR32)
+ ctxt.Out.Write16(IMAGE_REL_I386_DIR32)
case "amd64":
- Wputl(IMAGE_REL_AMD64_ADDR64)
+ ctxt.Out.Write16(IMAGE_REL_AMD64_ADDR64)
}
return 1
})
// writeSymbol appends symbol s to file f symbol table.
// It also sets s.Dynid to written symbol number.
-func (f *peFile) writeSymbol(s *Symbol, value int64, sectidx int, typ uint16, class uint8) {
+func (f *peFile) writeSymbol(out *OutBuf, s *Symbol, value int64, sectidx int, typ uint16, class uint8) {
if len(s.Name) > 8 {
- Lputl(0)
- Lputl(uint32(f.stringTable.add(s.Name)))
+ out.Write32(0)
+ out.Write32(uint32(f.stringTable.add(s.Name)))
} else {
- strnput(s.Name, 8)
+ out.WriteStringN(s.Name, 8)
}
- Lputl(uint32(value))
- Wputl(uint16(sectidx))
- Wputl(typ)
- Cput(class)
- Cput(0) // no aux entries
+ out.Write32(uint32(value))
+ out.Write16(uint16(sectidx))
+ out.Write16(typ)
+ out.Write8(class)
+ out.Write8(0) // no aux entries
s.Dynid = int32(f.symbolCount)
if s.Version != 0 || (s.Type&SHIDDEN != 0) || s.Attr.Local() {
class = IMAGE_SYM_CLASS_STATIC
}
- f.writeSymbol(s, value, sect, typ, uint8(class))
+ f.writeSymbol(ctxt.Out, s, value, sect, typ, uint8(class))
}
if Linkmode == LinkExternal {
// .ctors and .debug_* section relocations refer to it.
for _, pesect := range f.sections {
sym := ctxt.Syms.Lookup(pesect.name, 0)
- f.writeSymbol(sym, 0, pesect.index, IMAGE_SYM_TYPE_NULL, IMAGE_SYM_CLASS_STATIC)
+ f.writeSymbol(ctxt.Out, sym, 0, pesect.index, IMAGE_SYM_TYPE_NULL, IMAGE_SYM_CLASS_STATIC)
}
}
// writeSymbolTableAndStringTable writes out symbol and string tables for peFile f.
func (f *peFile) writeSymbolTableAndStringTable(ctxt *Link) {
- f.symtabOffset = coutbuf.Offset()
+ f.symtabOffset = ctxt.Out.Offset()
// write COFF symbol table
if !*FlagS || Linkmode == LinkExternal {
}
// write COFF string table
- f.stringTable.write()
+ f.stringTable.write(ctxt.Out)
if Linkmode != LinkExternal {
- h.pad(uint32(size))
+ h.pad(ctxt.Out, uint32(size))
}
}
// writeFileHeader writes COFF file header for peFile f.
-func (f *peFile) writeFileHeader(arch *sys.Arch) {
+func (f *peFile) writeFileHeader(arch *sys.Arch, out *OutBuf) {
var fh pe.FileHeader
switch arch.Family {
fh.PointerToSymbolTable = uint32(f.symtabOffset)
fh.NumberOfSymbols = uint32(f.symbolCount)
- binary.Write(&coutbuf, binary.LittleEndian, &fh)
+ binary.Write(out, binary.LittleEndian, &fh)
}
// writeOptionalHeader writes COFF optional header for peFile f.
}
if pe64 != 0 {
- binary.Write(&coutbuf, binary.LittleEndian, &oh64)
+ binary.Write(ctxt.Out, binary.LittleEndian, &oh64)
} else {
- binary.Write(&coutbuf, binary.LittleEndian, &oh)
+ binary.Write(ctxt.Out, binary.LittleEndian, &oh)
}
}
}
func pewrite(ctxt *Link) {
- Cseek(0)
+ ctxt.Out.SeekSet(0)
if Linkmode != LinkExternal {
- Cwrite(dosstub)
- strnput("PE", 4)
+ ctxt.Out.Write(dosstub)
+ ctxt.Out.WriteStringN("PE", 4)
}
- pefile.writeFileHeader(ctxt.Arch)
+ pefile.writeFileHeader(ctxt.Arch, ctxt.Out)
pefile.writeOptionalHeader(ctxt)
for _, sect := range pefile.sections {
- sect.write()
+ sect.write(ctxt.Out)
}
}
-func strput(s string) {
- coutbuf.WriteString(s)
- Cput(0)
+func strput(out *OutBuf, s string) {
+ out.WriteString(s)
+ out.Write8(0)
// string must be padded to even size
if (len(s)+1)%2 != 0 {
- Cput(0)
+ out.Write8(0)
}
}
}
func addimports(ctxt *Link, datsect *peSection) {
- startoff := coutbuf.Offset()
+ startoff := ctxt.Out.Offset()
dynamic := ctxt.Syms.Lookup(".windynamic", 0)
// skip import descriptor table (will write it later)
for d := dr; d != nil; d = d.next {
n++
}
- Cseek(startoff + int64(binary.Size(&IMAGE_IMPORT_DESCRIPTOR{}))*int64(n+1))
+ ctxt.Out.SeekSet(startoff + int64(binary.Size(&IMAGE_IMPORT_DESCRIPTOR{}))*int64(n+1))
// write dll names
for d := dr; d != nil; d = d.next {
- d.nameoff = uint64(coutbuf.Offset()) - uint64(startoff)
- strput(d.name)
+ d.nameoff = uint64(ctxt.Out.Offset()) - uint64(startoff)
+ strput(ctxt.Out, d.name)
}
// write function names
var m *Imp
for d := dr; d != nil; d = d.next {
for m = d.ms; m != nil; m = m.next {
- m.off = uint64(pefile.nextSectOffset) + uint64(coutbuf.Offset()) - uint64(startoff)
- Wputl(0) // hint
- strput(m.s.Extname)
+ m.off = uint64(pefile.nextSectOffset) + uint64(ctxt.Out.Offset()) - uint64(startoff)
+ ctxt.Out.Write16(0) // hint
+ strput(ctxt.Out, m.s.Extname)
}
}
// write OriginalFirstThunks
- oftbase := uint64(coutbuf.Offset()) - uint64(startoff)
+ oftbase := uint64(ctxt.Out.Offset()) - uint64(startoff)
- n = uint64(coutbuf.Offset())
+ n = uint64(ctxt.Out.Offset())
for d := dr; d != nil; d = d.next {
- d.thunkoff = uint64(coutbuf.Offset()) - n
+ d.thunkoff = uint64(ctxt.Out.Offset()) - n
for m = d.ms; m != nil; m = m.next {
if pe64 != 0 {
- Vputl(m.off)
+ ctxt.Out.Write64(m.off)
} else {
- Lputl(uint32(m.off))
+ ctxt.Out.Write32(uint32(m.off))
}
}
if pe64 != 0 {
- Vputl(0)
+ ctxt.Out.Write64(0)
} else {
- Lputl(0)
+ ctxt.Out.Write32(0)
}
}
// add pe section and pad it at the end
- n = uint64(coutbuf.Offset()) - uint64(startoff)
+ n = uint64(ctxt.Out.Offset()) - uint64(startoff)
isect := pefile.addSection(".idata", int(n), int(n))
isect.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
isect.checkOffset(startoff)
- isect.pad(uint32(n))
- endoff := coutbuf.Offset()
+ isect.pad(ctxt.Out, uint32(n))
+ endoff := ctxt.Out.Offset()
// write FirstThunks (allocated in .data section)
ftbase := uint64(dynamic.Value) - uint64(datsect.virtualAddress) - PEBASE
- Cseek(int64(uint64(datsect.pointerToRawData) + ftbase))
+ ctxt.Out.SeekSet(int64(uint64(datsect.pointerToRawData) + ftbase))
for d := dr; d != nil; d = d.next {
for m = d.ms; m != nil; m = m.next {
if pe64 != 0 {
- Vputl(m.off)
+ ctxt.Out.Write64(m.off)
} else {
- Lputl(uint32(m.off))
+ ctxt.Out.Write32(uint32(m.off))
}
}
if pe64 != 0 {
- Vputl(0)
+ ctxt.Out.Write64(0)
} else {
- Lputl(0)
+ ctxt.Out.Write32(0)
}
}
// finally write import descriptor table
- Cseek(startoff)
+ out := ctxt.Out
+ out.SeekSet(startoff)
for d := dr; d != nil; d = d.next {
- Lputl(uint32(uint64(isect.virtualAddress) + oftbase + d.thunkoff))
- Lputl(0)
- Lputl(0)
- Lputl(uint32(uint64(isect.virtualAddress) + d.nameoff))
- Lputl(uint32(uint64(datsect.virtualAddress) + ftbase + d.thunkoff))
+ out.Write32(uint32(uint64(isect.virtualAddress) + oftbase + d.thunkoff))
+ out.Write32(0)
+ out.Write32(0)
+ out.Write32(uint32(uint64(isect.virtualAddress) + d.nameoff))
+ out.Write32(uint32(uint64(datsect.virtualAddress) + ftbase + d.thunkoff))
}
- Lputl(0) //end
- Lputl(0)
- Lputl(0)
- Lputl(0)
- Lputl(0)
+ out.Write32(0) //end
+ out.Write32(0)
+ out.Write32(0)
+ out.Write32(0)
+ out.Write32(0)
// update data directory
pefile.dataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = isect.virtualAddress
pefile.dataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = uint32(dynamic.Value - PEBASE)
pefile.dataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = uint32(dynamic.Size)
- Cseek(endoff)
+ out.SeekSet(endoff)
}
type byExtname []*Symbol
sect := pefile.addSection(".edata", size, size)
sect.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ
- sect.checkOffset(coutbuf.Offset())
+ sect.checkOffset(ctxt.Out.Offset())
va := int(sect.virtualAddress)
pefile.dataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = uint32(va)
pefile.dataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size = sect.virtualSize
e.AddressOfNames = uint32(vaName)
e.AddressOfNameOrdinals = uint32(vaNa)
+ out := ctxt.Out
+
// put IMAGE_EXPORT_DIRECTORY
- binary.Write(&coutbuf, binary.LittleEndian, &e)
+ binary.Write(out, binary.LittleEndian, &e)
// put EXPORT Address Table
for i := 0; i < nexport; i++ {
- Lputl(uint32(dexport[i].Value - PEBASE))
+ out.Write32(uint32(dexport[i].Value - PEBASE))
}
// put EXPORT Name Pointer Table
v := int(e.Name + uint32(len(*flagOutfile)) + 1)
for i := 0; i < nexport; i++ {
- Lputl(uint32(v))
+ out.Write32(uint32(v))
v += len(dexport[i].Extname) + 1
}
// put EXPORT Ordinal Table
for i := 0; i < nexport; i++ {
- Wputl(uint16(i))
+ out.Write16(uint16(i))
}
// put Names
- strnput(*flagOutfile, len(*flagOutfile)+1)
+ out.WriteStringN(*flagOutfile, len(*flagOutfile)+1)
for i := 0; i < nexport; i++ {
- strnput(dexport[i].Extname, len(dexport[i].Extname)+1)
+ out.WriteStringN(dexport[i].Extname, len(dexport[i].Extname)+1)
}
- sect.pad(uint32(size))
+ sect.pad(out, uint32(size))
}
func (ctxt *Link) dope() {
h := pefile.addSection(".rsrc", int(rsrcsym.Size), int(rsrcsym.Size))
h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_INITIALIZED_DATA
- h.checkOffset(coutbuf.Offset())
+ h.checkOffset(ctxt.Out.Offset())
// relocation
var p []byte
p[3] = byte(val >> 24)
}
- Cwrite(rsrcsym.P)
- h.pad(uint32(rsrcsym.Size))
+ ctxt.Out.Write(rsrcsym.P)
+ h.pad(ctxt.Out, uint32(rsrcsym.Size))
// update data directory
pefile.dataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = h.virtualAddress
pefile.ctorsSect = pefile.addInitArray(ctxt)
}
- Cseek(int64(pefile.nextFileOffset))
+ ctxt.Out.SeekSet(int64(pefile.nextFileOffset))
if Linkmode != LinkExternal {
addimports(ctxt, d)
addexports(ctxt)
},
Allsym: make([]*Symbol, 0, 100000),
},
+ Out: &OutBuf{arch: arch},
Arch: arch,
LibraryByPkg: make(map[string]*Library),
}
log.Fatalf("invalid objabi.GOARCH %s (want %s)", objabi.GOARCH, arch.Name)
}
+ AtExit(func() {
+ if nerrors > 0 && ctxt.Out.f != nil {
+ ctxt.Out.f.Close()
+ mayberemoveoutfile()
+ }
+ })
+
return ctxt
}
return off
}
-func putelfsyment(off int, addr int64, size int64, info int, shndx int, other int) {
+func putelfsyment(out *OutBuf, off int, addr int64, size int64, info int, shndx int, other int) {
if elf64 {
- Thearch.Lput(uint32(off))
- Cput(uint8(info))
- Cput(uint8(other))
- Thearch.Wput(uint16(shndx))
- Thearch.Vput(uint64(addr))
- Thearch.Vput(uint64(size))
+ out.Write32(uint32(off))
+ out.Write8(uint8(info))
+ out.Write8(uint8(other))
+ out.Write16(uint16(shndx))
+ out.Write64(uint64(addr))
+ out.Write64(uint64(size))
Symsize += ELF64SYMSIZE
} else {
- Thearch.Lput(uint32(off))
- Thearch.Lput(uint32(addr))
- Thearch.Lput(uint32(size))
- Cput(uint8(info))
- Cput(uint8(other))
- Thearch.Wput(uint16(shndx))
+ out.Write32(uint32(off))
+ out.Write32(uint32(addr))
+ out.Write32(uint32(size))
+ out.Write8(uint8(info))
+ out.Write8(uint8(other))
+ out.Write16(uint16(shndx))
Symsize += ELF32SYMSIZE
}
}
// (*Symbol).ElfsymForReloc). This is approximately equivalent to the
// ELF linker -Bsymbolic-functions option, but that is buggy on
// several platforms.
- putelfsyment(putelfstr("local."+s), addr, size, STB_LOCAL<<4|typ&0xf, elfshnum, other)
+ putelfsyment(ctxt.Out, putelfstr("local."+s), addr, size, STB_LOCAL<<4|typ&0xf, elfshnum, other)
x.LocalElfsym = int32(numelfsym)
numelfsym++
return
return
}
- putelfsyment(putelfstr(s), addr, size, bind<<4|typ&0xf, elfshnum, other)
+ putelfsyment(ctxt.Out, putelfstr(s), addr, size, bind<<4|typ&0xf, elfshnum, other)
x.Elfsym = int32(numelfsym)
numelfsym++
}
-func putelfsectionsym(s *Symbol, shndx int) {
- putelfsyment(0, 0, 0, STB_LOCAL<<4|STT_SECTION, shndx, 0)
+func putelfsectionsym(out *OutBuf, s *Symbol, shndx int) {
+ putelfsyment(out, 0, 0, 0, STB_LOCAL<<4|STT_SECTION, shndx, 0)
s.Elfsym = int32(numelfsym)
numelfsym++
}
func Asmelfsym(ctxt *Link) {
// the first symbol entry is reserved
- putelfsyment(0, 0, 0, STB_LOCAL<<4|STT_NOTYPE, 0, 0)
+ putelfsyment(ctxt.Out, 0, 0, 0, STB_LOCAL<<4|STT_NOTYPE, 0, 0)
dwarfaddelfsectionsyms(ctxt)
// Avoid having the working directory inserted into the symbol table.
// It is added with a name to avoid problems with external linking
// encountered on some versions of Solaris. See issue #14957.
- putelfsyment(putelfstr("go.go"), 0, 0, STB_LOCAL<<4|STT_FILE, SHN_ABS, 0)
+ putelfsyment(ctxt.Out, putelfstr("go.go"), 0, 0, STB_LOCAL<<4|STT_FILE, SHN_ABS, 0)
numelfsym++
elfbind = STB_LOCAL
case AutoSym, ParamSym, FrameSym:
l := 4
if Headtype == objabi.Hplan9 && ctxt.Arch.Family == sys.AMD64 && !Flag8 {
- Lputb(uint32(addr >> 32))
+ ctxt.Out.Write32b(uint32(addr >> 32))
l = 8
}
- Lputb(uint32(addr))
- Cput(uint8(t + 0x80)) /* 0x80 is variable length */
+ ctxt.Out.Write32b(uint32(addr))
+ ctxt.Out.Write8(uint8(t + 0x80)) /* 0x80 is variable length */
- Cwritestring(s)
- Cput(0)
+ ctxt.Out.WriteString(s)
+ ctxt.Out.Write8(0)
Symsize += int32(l) + 1 + int32(len(s)) + 1
var symt *Symbol
-var encbuf [10]byte
-
-func Wputb(w uint16) { Cwrite(Append16b(encbuf[:0], w)) }
-func Lputb(l uint32) { Cwrite(Append32b(encbuf[:0], l)) }
-func Vputb(v uint64) { Cwrite(Append64b(encbuf[:0], v)) }
-
-func Wputl(w uint16) { Cwrite(Append16l(encbuf[:0], w)) }
-func Lputl(l uint32) { Cwrite(Append32l(encbuf[:0], l)) }
-func Vputl(v uint64) { Cwrite(Append64l(encbuf[:0], v)) }
-
-func Append16b(b []byte, v uint16) []byte {
- return append(b, uint8(v>>8), uint8(v))
-}
-func Append16l(b []byte, v uint16) []byte {
- return append(b, uint8(v), uint8(v>>8))
-}
-
-func Append32b(b []byte, v uint32) []byte {
- return append(b, uint8(v>>24), uint8(v>>16), uint8(v>>8), uint8(v))
-}
-func Append32l(b []byte, v uint32) []byte {
- return append(b, uint8(v), uint8(v>>8), uint8(v>>16), uint8(v>>24))
-}
-
-func Append64b(b []byte, v uint64) []byte {
- return append(b, uint8(v>>56), uint8(v>>48), uint8(v>>40), uint8(v>>32),
- uint8(v>>24), uint8(v>>16), uint8(v>>8), uint8(v))
-}
-
-func Append64l(b []byte, v uint64) []byte {
- return append(b, uint8(v), uint8(v>>8), uint8(v>>16), uint8(v>>24),
- uint8(v>>32), uint8(v>>40), uint8(v>>48), uint8(v>>56))
-}
-
type byPkg []*Library
func (libs byPkg) Len() int {
// Exitf logs an error message then calls Exit(2).
func Exitf(format string, a ...interface{}) {
fmt.Fprintf(os.Stderr, os.Args[0]+": "+format+"\n", a...)
- if coutbuf.f != nil {
- coutbuf.f.Close()
- mayberemoveoutfile()
- }
+ nerrors++
Exit(2)
}
}
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 {
if r.Siz != 4 {
return false
}
- ld.Thearch.Lput(ld.R_MIPS_32 | uint32(elfsym)<<8)
+ ctxt.Out.Write32(ld.R_MIPS_32 | uint32(elfsym)<<8)
case objabi.R_ADDRMIPS:
- ld.Thearch.Lput(ld.R_MIPS_LO16 | uint32(elfsym)<<8)
+ ctxt.Out.Write32(ld.R_MIPS_LO16 | uint32(elfsym)<<8)
case objabi.R_ADDRMIPSU:
- ld.Thearch.Lput(ld.R_MIPS_HI16 | uint32(elfsym)<<8)
+ ctxt.Out.Write32(ld.R_MIPS_HI16 | uint32(elfsym)<<8)
case objabi.R_ADDRMIPSTLS:
- ld.Thearch.Lput(ld.R_MIPS_TLS_TPREL_LO16 | uint32(elfsym)<<8)
+ ctxt.Out.Write32(ld.R_MIPS_TLS_TPREL_LO16 | uint32(elfsym)<<8)
case objabi.R_CALLMIPS, objabi.R_JMPMIPS:
- ld.Thearch.Lput(ld.R_MIPS_26 | uint32(elfsym)<<8)
+ ctxt.Out.Write32(ld.R_MIPS_26 | uint32(elfsym)<<8)
}
return true
return
}
-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 {
return false
}
}
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))
ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
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))
}
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))
}
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))
/* output symbol table */
symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
- ld.Cseek(int64(symo))
+ ctxt.Out.SeekSet(int64(symo))
if ctxt.Debugvlog != 0 {
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 ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
ctxt.Logf("%5.2f header\n", ld.Cputime())
}
- ld.Cseek(0)
+ ctxt.Out.SeekSet(0)
switch ld.Headtype {
default:
ld.Errorf(nil, "unsupported operating system")
ld.Asmbelf(ctxt, int64(symo))
}
- ld.Cflush()
+ ctxt.Out.Flush()
if *ld.FlagC {
fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
Solarisdynld: "XXX",
}
- if arch == sys.ArchMIPSLE {
- theArch.Lput = ld.Lputl
- theArch.Wput = ld.Wputl
- theArch.Vput = ld.Vputl
- theArch.Append16 = ld.Append16l
- theArch.Append32 = ld.Append32l
- theArch.Append64 = ld.Append64l
- } else {
- theArch.Lput = ld.Lputb
- theArch.Wput = ld.Wputb
- theArch.Vput = ld.Vputb
- theArch.Append16 = ld.Append16b
- theArch.Append32 = ld.Append32b
- theArch.Append64 = ld.Append64b
- }
-
return arch, theArch
}
// type uint8
// addend int64
- ld.Thearch.Vput(uint64(sectoff))
+ ctxt.Out.Write64(uint64(sectoff))
elfsym := r.Xsym.ElfsymForReloc()
- ld.Thearch.Lput(uint32(elfsym))
- ld.Cput(0)
- ld.Cput(0)
- ld.Cput(0)
+ ctxt.Out.Write32(uint32(elfsym))
+ ctxt.Out.Write8(0)
+ ctxt.Out.Write8(0)
+ ctxt.Out.Write8(0)
switch r.Type {
default:
return false
case objabi.R_ADDR:
switch r.Siz {
case 4:
- ld.Cput(ld.R_MIPS_32)
+ ctxt.Out.Write8(ld.R_MIPS_32)
case 8:
- ld.Cput(ld.R_MIPS_64)
+ ctxt.Out.Write8(ld.R_MIPS_64)
default:
return false
}
case objabi.R_ADDRMIPS:
- ld.Cput(ld.R_MIPS_LO16)
+ ctxt.Out.Write8(ld.R_MIPS_LO16)
case objabi.R_ADDRMIPSU:
- ld.Cput(ld.R_MIPS_HI16)
+ ctxt.Out.Write8(ld.R_MIPS_HI16)
case objabi.R_ADDRMIPSTLS:
- ld.Cput(ld.R_MIPS_TLS_TPREL_LO16)
+ ctxt.Out.Write8(ld.R_MIPS_TLS_TPREL_LO16)
case objabi.R_CALLMIPS,
objabi.R_JMPMIPS:
- ld.Cput(ld.R_MIPS_26)
+ ctxt.Out.Write8(ld.R_MIPS_26)
}
- ld.Thearch.Vput(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(r.Xadd))
return true
}
return
}
-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 {
return false
}
}
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))
ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
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))
}
if ctxt.Debugvlog != 0 {
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 rodatblk\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))
}
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))
/* output symbol table */
symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
}
- ld.Cseek(int64(symo))
+ ctxt.Out.SeekSet(int64(symo))
switch ld.Headtype {
default:
if ld.Iself {
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)
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()
}
}
}
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f header\n", ld.Cputime())
}
- ld.Cseek(0)
+ ctxt.Out.SeekSet(0)
switch ld.Headtype {
default:
case objabi.Hplan9: /* plan 9 */
if ctxt.Arch == sys.ArchMIPS64LE {
magic = uint32(4*26*26 + 7)
}
- ld.Thearch.Lput(magic) /* magic */
- ld.Thearch.Lput(uint32(ld.Segtext.Filelen)) /* sizes */
- ld.Thearch.Lput(uint32(ld.Segdata.Filelen))
- ld.Thearch.Lput(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
- ld.Thearch.Lput(uint32(ld.Symsize)) /* nsyms */
- ld.Thearch.Lput(uint32(ld.Entryvalue(ctxt))) /* va of entry */
- ld.Thearch.Lput(0)
- ld.Thearch.Lput(uint32(ld.Lcsize))
+ ctxt.Out.Write32(magic) /* magic */
+ ctxt.Out.Write32(uint32(ld.Segtext.Filelen)) /* sizes */
+ ctxt.Out.Write32(uint32(ld.Segdata.Filelen))
+ ctxt.Out.Write32(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
+ ctxt.Out.Write32(uint32(ld.Symsize)) /* nsyms */
+ ctxt.Out.Write32(uint32(ld.Entryvalue(ctxt))) /* va of entry */
+ ctxt.Out.Write32(0)
+ ctxt.Out.Write32(uint32(ld.Lcsize))
case objabi.Hlinux,
objabi.Hfreebsd,
ld.Asmbelf(ctxt, int64(symo))
}
- ld.Cflush()
+ ctxt.Out.Flush()
if *ld.FlagC {
fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
Dragonflydynld: "XXX",
Solarisdynld: "XXX",
}
- if arch == sys.ArchMIPS64LE {
- theArch.Lput = ld.Lputl
- theArch.Wput = ld.Wputl
- theArch.Vput = ld.Vputl
- theArch.Append16 = ld.Append16l
- theArch.Append32 = ld.Append32l
- theArch.Append64 = ld.Append64l
- } else {
- theArch.Lput = ld.Lputb
- theArch.Wput = ld.Wputb
- theArch.Vput = ld.Vputb
- theArch.Append16 = ld.Append16b
- theArch.Append32 = ld.Append32b
- theArch.Append64 = ld.Append64b
- }
return arch, theArch
}
}
func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
- ld.Thearch.Vput(uint64(sectoff))
+ ctxt.Out.Write64(uint64(sectoff))
elfsym := r.Xsym.ElfsymForReloc()
switch r.Type {
case objabi.R_ADDR:
switch r.Siz {
case 4:
- ld.Thearch.Vput(ld.R_PPC64_ADDR32 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_PPC64_ADDR32 | uint64(elfsym)<<32)
case 8:
- ld.Thearch.Vput(ld.R_PPC64_ADDR64 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_PPC64_ADDR64 | uint64(elfsym)<<32)
default:
return false
}
case objabi.R_POWER_TLS:
- ld.Thearch.Vput(ld.R_PPC64_TLS | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_PPC64_TLS | uint64(elfsym)<<32)
case objabi.R_POWER_TLS_LE:
- ld.Thearch.Vput(ld.R_PPC64_TPREL16 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_PPC64_TPREL16 | uint64(elfsym)<<32)
case objabi.R_POWER_TLS_IE:
- ld.Thearch.Vput(ld.R_PPC64_GOT_TPREL16_HA | uint64(elfsym)<<32)
- ld.Thearch.Vput(uint64(r.Xadd))
- ld.Thearch.Vput(uint64(sectoff + 4))
- ld.Thearch.Vput(ld.R_PPC64_GOT_TPREL16_LO_DS | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_PPC64_GOT_TPREL16_HA | uint64(elfsym)<<32)
+ ctxt.Out.Write64(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(sectoff + 4))
+ ctxt.Out.Write64(ld.R_PPC64_GOT_TPREL16_LO_DS | uint64(elfsym)<<32)
case objabi.R_ADDRPOWER:
- ld.Thearch.Vput(ld.R_PPC64_ADDR16_HA | uint64(elfsym)<<32)
- ld.Thearch.Vput(uint64(r.Xadd))
- ld.Thearch.Vput(uint64(sectoff + 4))
- ld.Thearch.Vput(ld.R_PPC64_ADDR16_LO | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_PPC64_ADDR16_HA | uint64(elfsym)<<32)
+ ctxt.Out.Write64(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(sectoff + 4))
+ ctxt.Out.Write64(ld.R_PPC64_ADDR16_LO | uint64(elfsym)<<32)
case objabi.R_ADDRPOWER_DS:
- ld.Thearch.Vput(ld.R_PPC64_ADDR16_HA | uint64(elfsym)<<32)
- ld.Thearch.Vput(uint64(r.Xadd))
- ld.Thearch.Vput(uint64(sectoff + 4))
- ld.Thearch.Vput(ld.R_PPC64_ADDR16_LO_DS | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_PPC64_ADDR16_HA | uint64(elfsym)<<32)
+ ctxt.Out.Write64(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(sectoff + 4))
+ ctxt.Out.Write64(ld.R_PPC64_ADDR16_LO_DS | uint64(elfsym)<<32)
case objabi.R_ADDRPOWER_GOT:
- ld.Thearch.Vput(ld.R_PPC64_GOT16_HA | uint64(elfsym)<<32)
- ld.Thearch.Vput(uint64(r.Xadd))
- ld.Thearch.Vput(uint64(sectoff + 4))
- ld.Thearch.Vput(ld.R_PPC64_GOT16_LO_DS | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_PPC64_GOT16_HA | uint64(elfsym)<<32)
+ ctxt.Out.Write64(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(sectoff + 4))
+ ctxt.Out.Write64(ld.R_PPC64_GOT16_LO_DS | uint64(elfsym)<<32)
case objabi.R_ADDRPOWER_PCREL:
- ld.Thearch.Vput(ld.R_PPC64_REL16_HA | uint64(elfsym)<<32)
- ld.Thearch.Vput(uint64(r.Xadd))
- ld.Thearch.Vput(uint64(sectoff + 4))
- ld.Thearch.Vput(ld.R_PPC64_REL16_LO | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_PPC64_REL16_HA | uint64(elfsym)<<32)
+ ctxt.Out.Write64(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(sectoff + 4))
+ ctxt.Out.Write64(ld.R_PPC64_REL16_LO | uint64(elfsym)<<32)
r.Xadd += 4
case objabi.R_ADDRPOWER_TOCREL:
- ld.Thearch.Vput(ld.R_PPC64_TOC16_HA | uint64(elfsym)<<32)
- ld.Thearch.Vput(uint64(r.Xadd))
- ld.Thearch.Vput(uint64(sectoff + 4))
- ld.Thearch.Vput(ld.R_PPC64_TOC16_LO | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_PPC64_TOC16_HA | uint64(elfsym)<<32)
+ ctxt.Out.Write64(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(sectoff + 4))
+ ctxt.Out.Write64(ld.R_PPC64_TOC16_LO | uint64(elfsym)<<32)
case objabi.R_ADDRPOWER_TOCREL_DS:
- ld.Thearch.Vput(ld.R_PPC64_TOC16_HA | uint64(elfsym)<<32)
- ld.Thearch.Vput(uint64(r.Xadd))
- ld.Thearch.Vput(uint64(sectoff + 4))
- ld.Thearch.Vput(ld.R_PPC64_TOC16_LO_DS | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_PPC64_TOC16_HA | uint64(elfsym)<<32)
+ ctxt.Out.Write64(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(sectoff + 4))
+ ctxt.Out.Write64(ld.R_PPC64_TOC16_LO_DS | uint64(elfsym)<<32)
case objabi.R_CALLPOWER:
if r.Siz != 4 {
return false
}
- ld.Thearch.Vput(ld.R_PPC64_REL24 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_PPC64_REL24 | uint64(elfsym)<<32)
}
- ld.Thearch.Vput(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(r.Xadd))
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 {
return false
}
}
for _, sect := range ld.Segtext.Sections {
- ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
+ ctxt.Out.SeekSet(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
// Handle additional text sections with Codeblk
if sect.Name == ".text" {
ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
if ctxt.Debugvlog != 0 {
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))
}
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))
/* output symbol table */
symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
}
- ld.Cseek(int64(symo))
+ ctxt.Out.SeekSet(int64(symo))
switch ld.Headtype {
default:
if ld.Iself {
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)
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()
}
}
}
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f header\n", ld.Cputime())
}
- ld.Cseek(0)
+ ctxt.Out.SeekSet(0)
switch ld.Headtype {
default:
case objabi.Hplan9: /* plan 9 */
- ld.Thearch.Lput(0x647) /* magic */
- ld.Thearch.Lput(uint32(ld.Segtext.Filelen)) /* sizes */
- ld.Thearch.Lput(uint32(ld.Segdata.Filelen))
- ld.Thearch.Lput(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
- ld.Thearch.Lput(uint32(ld.Symsize)) /* nsyms */
- ld.Thearch.Lput(uint32(ld.Entryvalue(ctxt))) /* va of entry */
- ld.Thearch.Lput(0)
- ld.Thearch.Lput(uint32(ld.Lcsize))
+ ctxt.Out.Write32(0x647) /* magic */
+ ctxt.Out.Write32(uint32(ld.Segtext.Filelen)) /* sizes */
+ ctxt.Out.Write32(uint32(ld.Segdata.Filelen))
+ ctxt.Out.Write32(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
+ ctxt.Out.Write32(uint32(ld.Symsize)) /* nsyms */
+ ctxt.Out.Write32(uint32(ld.Entryvalue(ctxt))) /* va of entry */
+ ctxt.Out.Write32(0)
+ ctxt.Out.Write32(uint32(ld.Lcsize))
case objabi.Hlinux,
objabi.Hfreebsd,
ld.Asmbelf(ctxt, int64(symo))
}
- ld.Cflush()
+ ctxt.Out.Flush()
if *ld.FlagC {
fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
Solarisdynld: "XXX",
}
- if arch == sys.ArchPPC64LE {
- theArch.Lput = ld.Lputl
- theArch.Wput = ld.Wputl
- theArch.Vput = ld.Vputl
- theArch.Append16 = ld.Append16l
- theArch.Append32 = ld.Append32l
- theArch.Append64 = ld.Append64l
- } else {
- theArch.Lput = ld.Lputb
- theArch.Wput = ld.Wputb
- theArch.Vput = ld.Vputb
- theArch.Append16 = ld.Append16b
- theArch.Append32 = ld.Append32b
- theArch.Append64 = ld.Append64b
- }
-
return arch, theArch
}
}
func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
- ld.Thearch.Vput(uint64(sectoff))
+ ctxt.Out.Write64(uint64(sectoff))
elfsym := r.Xsym.ElfsymForReloc()
switch r.Type {
return false
case 4:
// WARNING - silently ignored by linker in ELF64
- ld.Thearch.Vput(ld.R_390_TLS_LE32 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_390_TLS_LE32 | uint64(elfsym)<<32)
case 8:
// WARNING - silently ignored by linker in ELF32
- ld.Thearch.Vput(ld.R_390_TLS_LE64 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_390_TLS_LE64 | uint64(elfsym)<<32)
}
case objabi.R_TLS_IE:
switch r.Siz {
default:
return false
case 4:
- ld.Thearch.Vput(ld.R_390_TLS_IEENT | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_390_TLS_IEENT | uint64(elfsym)<<32)
}
case objabi.R_ADDR:
switch r.Siz {
default:
return false
case 4:
- ld.Thearch.Vput(ld.R_390_32 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_390_32 | uint64(elfsym)<<32)
case 8:
- ld.Thearch.Vput(ld.R_390_64 | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_390_64 | uint64(elfsym)<<32)
}
case objabi.R_GOTPCREL:
if r.Siz == 4 {
- ld.Thearch.Vput(ld.R_390_GOTENT | uint64(elfsym)<<32)
+ ctxt.Out.Write64(ld.R_390_GOTENT | uint64(elfsym)<<32)
} else {
return false
}
if elfrel == ld.R_390_NONE {
return false // unsupported size/dbl combination
}
- ld.Thearch.Vput(uint64(elfrel) | uint64(elfsym)<<32)
+ ctxt.Out.Write64(uint64(elfrel) | uint64(elfsym)<<32)
}
- ld.Thearch.Vput(uint64(r.Xadd))
+ ctxt.Out.Write64(uint64(r.Xadd))
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 {
return false
}
}
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))
ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
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))
}
if ctxt.Debugvlog != 0 {
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 rodatblk\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))
}
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))
/* output symbol table */
symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
- ld.Cseek(int64(symo))
+ ctxt.Out.SeekSet(int64(symo))
if ctxt.Debugvlog != 0 {
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 ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
if ctxt.Debugvlog != 0 {
ctxt.Logf("%5.2f header\n", ld.Cputime())
}
- ld.Cseek(0)
+ ctxt.Out.SeekSet(0)
switch ld.Headtype {
default:
ld.Errorf(nil, "unsupported operating system")
ld.Asmbelf(ctxt, int64(symo))
}
- ld.Cflush()
+ ctxt.Out.Flush()
if *ld.FlagC {
fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
Elfsetupplt: elfsetupplt,
Gentext: gentext,
Machoreloc1: machoreloc1,
- Lput: ld.Lputb,
- Wput: ld.Wputb,
- Vput: ld.Vputb,
- Append16: ld.Append16b,
- Append32: ld.Append32b,
- Append64: ld.Append64b,
Linuxdynld: "/lib64/ld64.so.1",
}
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 {
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
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
}
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
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
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:
v = ld.IMAGE_REL_I386_REL32
}
- ld.Thearch.Wput(uint16(v))
+ out.Write16(uint16(v))
return true
}
}
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))
}
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))
}
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)
symo = uint32(ld.Rnd(int64(symo), ld.PEFILEALIGN))
}
- ld.Cseek(int64(symo))
+ ctxt.Out.SeekSet(int64(symo))
switch ld.Headtype {
default:
if ld.Iself {
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)
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:
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)
ld.Asmbpe(ctxt)
}
- ld.Cflush()
+ ctxt.Out.Flush()
}
Gentext: gentext,
Machoreloc1: machoreloc1,
PEreloc1: pereloc1,
- Lput: ld.Lputl,
- Wput: ld.Wputl,
- Vput: ld.Vputl,
- Append16: ld.Append16l,
- Append32: ld.Append32l,
- Append64: ld.Append64l,
Linuxdynld: "/lib/ld-linux.so.2",
Freebsddynld: "/usr/libexec/ld-elf.so.1",