Commit 4338e5a8 authored by Michael Matloob's avatar Michael Matloob

cmd/link/internal: remove global Ctxt variable

This change threads the *ld.Link Ctxt variable through
code in arch-specific packages. This removes all remaining
uses of Ctxt, so remove the global variable too.

This CL continues the work in golang.org/cl/27408

Updates #16818

Change-Id: I5f4536847a1825fd0b944824e8ae4e122ec0fb78
Reviewed-on: https://go-review.googlesource.com/27459
Run-TryBot: Michael Matloob <matloob@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent e2b30e90
...@@ -55,63 +55,63 @@ func Addcall(ctxt *ld.Link, s *ld.Symbol, t *ld.Symbol) int64 { ...@@ -55,63 +55,63 @@ func Addcall(ctxt *ld.Link, s *ld.Symbol, t *ld.Symbol) int64 {
return i + int64(r.Siz) return i + int64(r.Siz)
} }
func gentext() { func gentext(ctxt *ld.Link) {
if !ld.DynlinkingGo() { if !ld.DynlinkingGo() {
return return
} }
addmoduledata := ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) addmoduledata := ld.Linklookup(ctxt, "runtime.addmoduledata", 0)
if addmoduledata.Type == obj.STEXT { if addmoduledata.Type == obj.STEXT {
// we're linking a module containing the runtime -> no need for // we're linking a module containing the runtime -> no need for
// an init function // an init function
return return
} }
addmoduledata.Attr |= ld.AttrReachable addmoduledata.Attr |= ld.AttrReachable
initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0) initfunc := ld.Linklookup(ctxt, "go.link.addmoduledata", 0)
initfunc.Type = obj.STEXT initfunc.Type = obj.STEXT
initfunc.Attr |= ld.AttrLocal initfunc.Attr |= ld.AttrLocal
initfunc.Attr |= ld.AttrReachable initfunc.Attr |= ld.AttrReachable
o := func(op ...uint8) { o := func(op ...uint8) {
for _, op1 := range op { for _, op1 := range op {
ld.Adduint8(ld.Ctxt, initfunc, op1) ld.Adduint8(ctxt, initfunc, op1)
} }
} }
// 0000000000000000 <local.dso_init>: // 0000000000000000 <local.dso_init>:
// 0: 48 8d 3d 00 00 00 00 lea 0x0(%rip),%rdi # 7 <local.dso_init+0x7> // 0: 48 8d 3d 00 00 00 00 lea 0x0(%rip),%rdi # 7 <local.dso_init+0x7>
// 3: R_X86_64_PC32 runtime.firstmoduledata-0x4 // 3: R_X86_64_PC32 runtime.firstmoduledata-0x4
o(0x48, 0x8d, 0x3d) o(0x48, 0x8d, 0x3d)
ld.Addpcrelplus(ld.Ctxt, initfunc, ld.Ctxt.Moduledata, 0) ld.Addpcrelplus(ctxt, initfunc, ctxt.Moduledata, 0)
// 7: e8 00 00 00 00 callq c <local.dso_init+0xc> // 7: e8 00 00 00 00 callq c <local.dso_init+0xc>
// 8: R_X86_64_PLT32 runtime.addmoduledata-0x4 // 8: R_X86_64_PLT32 runtime.addmoduledata-0x4
o(0xe8) o(0xe8)
Addcall(ld.Ctxt, initfunc, addmoduledata) Addcall(ctxt, initfunc, addmoduledata)
// c: c3 retq // c: c3 retq
o(0xc3) o(0xc3)
ld.Ctxt.Textp = append(ld.Ctxt.Textp, initfunc) ctxt.Textp = append(ctxt.Textp, initfunc)
initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0) initarray_entry := ld.Linklookup(ctxt, "go.link.addmoduledatainit", 0)
initarray_entry.Attr |= ld.AttrReachable initarray_entry.Attr |= ld.AttrReachable
initarray_entry.Attr |= ld.AttrLocal initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = obj.SINITARR initarray_entry.Type = obj.SINITARR
ld.Addaddr(ld.Ctxt, initarray_entry, initfunc) ld.Addaddr(ctxt, initarray_entry, initfunc)
} }
func adddynrel(s *ld.Symbol, r *ld.Reloc) { func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) {
targ := r.Sym targ := r.Sym
ld.Ctxt.Cursym = s ctxt.Cursym = s
switch r.Type { switch r.Type {
default: default:
if r.Type >= 256 { if r.Type >= 256 {
ld.Ctxt.Diag("unexpected relocation type %d", r.Type) ctxt.Diag("unexpected relocation type %d", r.Type)
return return
} }
// Handle relocations found in ELF object files. // Handle relocations found in ELF object files.
case 256 + ld.R_X86_64_PC32: case 256 + ld.R_X86_64_PC32:
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
ld.Ctxt.Diag("unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ.Name) ctxt.Diag("unexpected R_X86_64_PC32 relocation for dynamic symbol %s", targ.Name)
} }
if targ.Type == 0 || targ.Type == obj.SXREF { if targ.Type == 0 || targ.Type == obj.SXREF {
ld.Ctxt.Diag("unknown symbol %s in pcrel", targ.Name) ctxt.Diag("unknown symbol %s in pcrel", targ.Name)
} }
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Add += 4 r.Add += 4
...@@ -121,8 +121,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -121,8 +121,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Add += 4 r.Add += 4
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
addpltsym(targ) addpltsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) r.Sym = ld.Linklookup(ctxt, ".plt", 0)
r.Add += int64(targ.Plt) r.Add += int64(targ.Plt)
} }
...@@ -143,17 +143,17 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -143,17 +143,17 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
// fall back to using GOT and hope for the best (CMOV*) // fall back to using GOT and hope for the best (CMOV*)
// TODO: just needs relocation, no need to put in .dynsym // TODO: just needs relocation, no need to put in .dynsym
addgotsym(targ) addgotsym(ctxt, targ)
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0) r.Sym = ld.Linklookup(ctxt, ".got", 0)
r.Add += 4 r.Add += 4
r.Add += int64(targ.Got) r.Add += int64(targ.Got)
return return
case 256 + ld.R_X86_64_64: case 256 + ld.R_X86_64_64:
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
ld.Ctxt.Diag("unexpected R_X86_64_64 relocation for dynamic symbol %s", targ.Name) ctxt.Diag("unexpected R_X86_64_64 relocation for dynamic symbol %s", targ.Name)
} }
r.Type = obj.R_ADDR r.Type = obj.R_ADDR
return return
...@@ -166,14 +166,14 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -166,14 +166,14 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
r.Type = obj.R_ADDR r.Type = obj.R_ADDR
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
ld.Ctxt.Diag("unexpected reloc for dynamic symbol %s", targ.Name) ctxt.Diag("unexpected reloc for dynamic symbol %s", targ.Name)
} }
return return
case 512 + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1: case 512 + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1:
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
addpltsym(targ) addpltsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) r.Sym = ld.Linklookup(ctxt, ".plt", 0)
r.Add = int64(targ.Plt) r.Add = int64(targ.Plt)
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
return return
...@@ -189,7 +189,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -189,7 +189,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
ld.Ctxt.Diag("unexpected pc-relative reloc for dynamic symbol %s", targ.Name) ctxt.Diag("unexpected pc-relative reloc for dynamic symbol %s", targ.Name)
} }
return return
...@@ -198,7 +198,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -198,7 +198,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
// have symbol // have symbol
// turn MOVQ of GOT entry into LEAQ of symbol itself // turn MOVQ of GOT entry into LEAQ of symbol itself
if r.Off < 2 || s.P[r.Off-2] != 0x8b { if r.Off < 2 || s.P[r.Off-2] != 0x8b {
ld.Ctxt.Diag("unexpected GOT_LOAD reloc for non-dynamic symbol %s", targ.Name) ctxt.Diag("unexpected GOT_LOAD reloc for non-dynamic symbol %s", targ.Name)
return return
} }
...@@ -211,11 +211,11 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -211,11 +211,11 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
// fall through // fall through
case 512 + ld.MACHO_X86_64_RELOC_GOT*2 + 1: case 512 + ld.MACHO_X86_64_RELOC_GOT*2 + 1:
if targ.Type != obj.SDYNIMPORT { if targ.Type != obj.SDYNIMPORT {
ld.Ctxt.Diag("unexpected GOT reloc for non-dynamic symbol %s", targ.Name) ctxt.Diag("unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
} }
addgotsym(targ) addgotsym(ctxt, targ)
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0) r.Sym = ld.Linklookup(ctxt, ".got", 0)
r.Add += int64(targ.Got) r.Add += int64(targ.Got)
return return
} }
...@@ -233,8 +233,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -233,8 +233,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
return return
} else { } else {
// for both ELF and Mach-O // for both ELF and Mach-O
addpltsym(targ) addpltsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) r.Sym = ld.Linklookup(ctxt, ".plt", 0)
r.Add = int64(targ.Plt) r.Add = int64(targ.Plt)
return return
} }
...@@ -242,17 +242,17 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -242,17 +242,17 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
case obj.R_ADDR: case obj.R_ADDR:
if s.Type == obj.STEXT && ld.Iself { if s.Type == obj.STEXT && ld.Iself {
if ld.HEADTYPE == obj.Hsolaris { if ld.HEADTYPE == obj.Hsolaris {
addpltsym(targ) addpltsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) r.Sym = ld.Linklookup(ctxt, ".plt", 0)
r.Add += int64(targ.Plt) r.Add += int64(targ.Plt)
return return
} }
// The code is asking for the address of an external // The code is asking for the address of an external
// function. We provide it with the address of the // function. We provide it with the address of the
// correspondent GOT symbol. // correspondent GOT symbol.
addgotsym(targ) addgotsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0) r.Sym = ld.Linklookup(ctxt, ".got", 0)
r.Add += int64(targ.Got) r.Add += int64(targ.Got)
return return
} }
...@@ -261,15 +261,15 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -261,15 +261,15 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
break break
} }
if ld.Iself { if ld.Iself {
ld.Adddynsym(ld.Ctxt, targ) ld.Adddynsym(ctxt, targ)
rela := ld.Linklookup(ld.Ctxt, ".rela", 0) rela := ld.Linklookup(ctxt, ".rela", 0)
ld.Addaddrplus(ld.Ctxt, rela, s, int64(r.Off)) ld.Addaddrplus(ctxt, rela, s, int64(r.Off))
if r.Siz == 8 { if r.Siz == 8 {
ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_X86_64_64)) ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_X86_64_64))
} else { } else {
ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_X86_64_32)) ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_X86_64_32))
} }
ld.Adduint64(ld.Ctxt, rela, uint64(r.Add)) ld.Adduint64(ctxt, rela, uint64(r.Add))
r.Type = 256 // ignore during relocsym r.Type = 256 // ignore during relocsym
return return
} }
...@@ -285,16 +285,16 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -285,16 +285,16 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
// just in case the C code assigns to the variable, // just in case the C code assigns to the variable,
// and of course it only works for single pointers, // and of course it only works for single pointers,
// but we only need to support cgo and that's all it needs. // but we only need to support cgo and that's all it needs.
ld.Adddynsym(ld.Ctxt, targ) ld.Adddynsym(ctxt, targ)
got := ld.Linklookup(ld.Ctxt, ".got", 0) got := ld.Linklookup(ctxt, ".got", 0)
s.Type = got.Type | obj.SSUB s.Type = got.Type | obj.SSUB
s.Outer = got s.Outer = got
s.Sub = got.Sub s.Sub = got.Sub
got.Sub = s got.Sub = s
s.Value = got.Size s.Value = got.Size
ld.Adduint64(ld.Ctxt, got, 0) ld.Adduint64(ctxt, got, 0)
ld.Adduint32(ld.Ctxt, ld.Linklookup(ld.Ctxt, ".linkedit.got", 0), uint32(targ.Dynid)) ld.Adduint32(ctxt, ld.Linklookup(ctxt, ".linkedit.got", 0), uint32(targ.Dynid))
r.Type = 256 // ignore during relocsym r.Type = 256 // ignore during relocsym
return return
} }
...@@ -305,11 +305,11 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -305,11 +305,11 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
} }
} }
ld.Ctxt.Cursym = s ctxt.Cursym = s
ld.Ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type) ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
} }
func elfreloc1(r *ld.Reloc, sectoff int64) int { func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
ld.Thearch.Vput(uint64(sectoff)) ld.Thearch.Vput(uint64(sectoff))
elfsym := r.Xsym.ElfsymForReloc() elfsym := r.Xsym.ElfsymForReloc()
...@@ -378,14 +378,14 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -378,14 +378,14 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
return 0 return 0
} }
func machoreloc1(r *ld.Reloc, sectoff int64) int { func machoreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
var v uint32 var v uint32
rs := r.Xsym rs := r.Xsym
if rs.Type == obj.SHOSTOBJ || r.Type == obj.R_PCREL { if rs.Type == obj.SHOSTOBJ || r.Type == obj.R_PCREL {
if rs.Dynid < 0 { if rs.Dynid < 0 {
ld.Ctxt.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type) ctxt.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
return -1 return -1
} }
...@@ -394,7 +394,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -394,7 +394,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
} else { } else {
v = uint32(rs.Sect.Extnum) v = uint32(rs.Sect.Extnum)
if v == 0 { if v == 0 {
ld.Ctxt.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type) ctxt.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
return -1 return -1
} }
} }
...@@ -438,13 +438,13 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -438,13 +438,13 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
return 0 return 0
} }
func pereloc1(r *ld.Reloc, sectoff int64) bool { func pereloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
var v uint32 var v uint32
rs := r.Xsym rs := r.Xsym
if rs.Dynid < 0 { if rs.Dynid < 0 {
ld.Ctxt.Diag("reloc %d to non-coff symbol %s type=%d", r.Type, rs.Name, rs.Type) ctxt.Diag("reloc %d to non-coff symbol %s type=%d", r.Type, rs.Name, rs.Type)
return false return false
} }
...@@ -472,81 +472,81 @@ func pereloc1(r *ld.Reloc, sectoff int64) bool { ...@@ -472,81 +472,81 @@ func pereloc1(r *ld.Reloc, sectoff int64) bool {
return true return true
} }
func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
return -1 return -1
} }
func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
log.Fatalf("unexpected relocation variant") log.Fatalf("unexpected relocation variant")
return t return t
} }
func elfsetupplt() { func elfsetupplt(ctxt *ld.Link) {
plt := ld.Linklookup(ld.Ctxt, ".plt", 0) plt := ld.Linklookup(ctxt, ".plt", 0)
got := ld.Linklookup(ld.Ctxt, ".got.plt", 0) got := ld.Linklookup(ctxt, ".got.plt", 0)
if plt.Size == 0 { if plt.Size == 0 {
// pushq got+8(IP) // pushq got+8(IP)
ld.Adduint8(ld.Ctxt, plt, 0xff) ld.Adduint8(ctxt, plt, 0xff)
ld.Adduint8(ld.Ctxt, plt, 0x35) ld.Adduint8(ctxt, plt, 0x35)
ld.Addpcrelplus(ld.Ctxt, plt, got, 8) ld.Addpcrelplus(ctxt, plt, got, 8)
// jmpq got+16(IP) // jmpq got+16(IP)
ld.Adduint8(ld.Ctxt, plt, 0xff) ld.Adduint8(ctxt, plt, 0xff)
ld.Adduint8(ld.Ctxt, plt, 0x25) ld.Adduint8(ctxt, plt, 0x25)
ld.Addpcrelplus(ld.Ctxt, plt, got, 16) ld.Addpcrelplus(ctxt, plt, got, 16)
// nopl 0(AX) // nopl 0(AX)
ld.Adduint32(ld.Ctxt, plt, 0x00401f0f) ld.Adduint32(ctxt, plt, 0x00401f0f)
// assume got->size == 0 too // assume got->size == 0 too
ld.Addaddrplus(ld.Ctxt, got, ld.Linklookup(ld.Ctxt, ".dynamic", 0), 0) ld.Addaddrplus(ctxt, got, ld.Linklookup(ctxt, ".dynamic", 0), 0)
ld.Adduint64(ld.Ctxt, got, 0) ld.Adduint64(ctxt, got, 0)
ld.Adduint64(ld.Ctxt, got, 0) ld.Adduint64(ctxt, got, 0)
} }
} }
func addpltsym(s *ld.Symbol) { func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
if s.Plt >= 0 { if s.Plt >= 0 {
return return
} }
ld.Adddynsym(ld.Ctxt, s) ld.Adddynsym(ctxt, s)
if ld.Iself { if ld.Iself {
plt := ld.Linklookup(ld.Ctxt, ".plt", 0) plt := ld.Linklookup(ctxt, ".plt", 0)
got := ld.Linklookup(ld.Ctxt, ".got.plt", 0) got := ld.Linklookup(ctxt, ".got.plt", 0)
rela := ld.Linklookup(ld.Ctxt, ".rela.plt", 0) rela := ld.Linklookup(ctxt, ".rela.plt", 0)
if plt.Size == 0 { if plt.Size == 0 {
elfsetupplt() elfsetupplt(ctxt)
} }
// jmpq *got+size(IP) // jmpq *got+size(IP)
ld.Adduint8(ld.Ctxt, plt, 0xff) ld.Adduint8(ctxt, plt, 0xff)
ld.Adduint8(ld.Ctxt, plt, 0x25) ld.Adduint8(ctxt, plt, 0x25)
ld.Addpcrelplus(ld.Ctxt, plt, got, got.Size) ld.Addpcrelplus(ctxt, plt, got, got.Size)
// add to got: pointer to current pos in plt // add to got: pointer to current pos in plt
ld.Addaddrplus(ld.Ctxt, got, plt, plt.Size) ld.Addaddrplus(ctxt, got, plt, plt.Size)
// pushq $x // pushq $x
ld.Adduint8(ld.Ctxt, plt, 0x68) ld.Adduint8(ctxt, plt, 0x68)
ld.Adduint32(ld.Ctxt, plt, uint32((got.Size-24-8)/8)) ld.Adduint32(ctxt, plt, uint32((got.Size-24-8)/8))
// jmpq .plt // jmpq .plt
ld.Adduint8(ld.Ctxt, plt, 0xe9) ld.Adduint8(ctxt, plt, 0xe9)
ld.Adduint32(ld.Ctxt, plt, uint32(-(plt.Size + 4))) ld.Adduint32(ctxt, plt, uint32(-(plt.Size + 4)))
// rela // rela
ld.Addaddrplus(ld.Ctxt, rela, got, got.Size-8) ld.Addaddrplus(ctxt, rela, got, got.Size-8)
ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_JMP_SLOT)) ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_JMP_SLOT))
ld.Adduint64(ld.Ctxt, rela, 0) ld.Adduint64(ctxt, rela, 0)
s.Plt = int32(plt.Size - 16) s.Plt = int32(plt.Size - 16)
} else if ld.HEADTYPE == obj.Hdarwin { } else if ld.HEADTYPE == obj.Hdarwin {
...@@ -560,41 +560,41 @@ func addpltsym(s *ld.Symbol) { ...@@ -560,41 +560,41 @@ func addpltsym(s *ld.Symbol) {
// http://networkpx.blogspot.com/2009/09/about-lcdyldinfoonly-command.html // http://networkpx.blogspot.com/2009/09/about-lcdyldinfoonly-command.html
// has details about what we're avoiding. // has details about what we're avoiding.
addgotsym(s) addgotsym(ctxt, s)
plt := ld.Linklookup(ld.Ctxt, ".plt", 0) plt := ld.Linklookup(ctxt, ".plt", 0)
ld.Adduint32(ld.Ctxt, ld.Linklookup(ld.Ctxt, ".linkedit.plt", 0), uint32(s.Dynid)) ld.Adduint32(ctxt, ld.Linklookup(ctxt, ".linkedit.plt", 0), uint32(s.Dynid))
// jmpq *got+size(IP) // jmpq *got+size(IP)
s.Plt = int32(plt.Size) s.Plt = int32(plt.Size)
ld.Adduint8(ld.Ctxt, plt, 0xff) ld.Adduint8(ctxt, plt, 0xff)
ld.Adduint8(ld.Ctxt, plt, 0x25) ld.Adduint8(ctxt, plt, 0x25)
ld.Addpcrelplus(ld.Ctxt, plt, ld.Linklookup(ld.Ctxt, ".got", 0), int64(s.Got)) ld.Addpcrelplus(ctxt, plt, ld.Linklookup(ctxt, ".got", 0), int64(s.Got))
} else { } else {
ld.Ctxt.Diag("addpltsym: unsupported binary format") ctxt.Diag("addpltsym: unsupported binary format")
} }
} }
func addgotsym(s *ld.Symbol) { func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
if s.Got >= 0 { if s.Got >= 0 {
return return
} }
ld.Adddynsym(ld.Ctxt, s) ld.Adddynsym(ctxt, s)
got := ld.Linklookup(ld.Ctxt, ".got", 0) got := ld.Linklookup(ctxt, ".got", 0)
s.Got = int32(got.Size) s.Got = int32(got.Size)
ld.Adduint64(ld.Ctxt, got, 0) ld.Adduint64(ctxt, got, 0)
if ld.Iself { if ld.Iself {
rela := ld.Linklookup(ld.Ctxt, ".rela", 0) rela := ld.Linklookup(ctxt, ".rela", 0)
ld.Addaddrplus(ld.Ctxt, rela, got, int64(s.Got)) ld.Addaddrplus(ctxt, rela, got, int64(s.Got))
ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_GLOB_DAT)) ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_GLOB_DAT))
ld.Adduint64(ld.Ctxt, rela, 0) ld.Adduint64(ctxt, rela, 0)
} else if ld.HEADTYPE == obj.Hdarwin { } else if ld.HEADTYPE == obj.Hdarwin {
ld.Adduint32(ld.Ctxt, ld.Linklookup(ld.Ctxt, ".linkedit.got", 0), uint32(s.Dynid)) ld.Adduint32(ctxt, ld.Linklookup(ctxt, ".linkedit.got", 0), uint32(s.Dynid))
} else { } else {
ld.Ctxt.Diag("addgotsym: unsupported binary format") ctxt.Diag("addgotsym: unsupported binary format")
} }
} }
...@@ -650,7 +650,7 @@ func asmb(ctxt *ld.Link) { ...@@ -650,7 +650,7 @@ func asmb(ctxt *ld.Link) {
switch ld.HEADTYPE { switch ld.HEADTYPE {
default: default:
ld.Ctxt.Diag("unknown header type %d", ld.HEADTYPE) ctxt.Diag("unknown header type %d", ld.HEADTYPE)
fallthrough fallthrough
case obj.Hplan9: case obj.Hplan9:
...@@ -727,7 +727,7 @@ func asmb(ctxt *ld.Link) { ...@@ -727,7 +727,7 @@ func asmb(ctxt *ld.Link) {
ld.Asmplan9sym(ctxt) ld.Asmplan9sym(ctxt)
ld.Cflush() ld.Cflush()
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0) sym := ld.Linklookup(ctxt, "pclntab", 0)
if sym != nil { if sym != nil {
ld.Lcsize = int32(len(sym.P)) ld.Lcsize = int32(len(sym.P))
for i := 0; int32(i) < ld.Lcsize; i++ { for i := 0; int32(i) < ld.Lcsize; i++ {
......
...@@ -82,9 +82,7 @@ func linkarchinit() { ...@@ -82,9 +82,7 @@ func linkarchinit() {
ld.Thearch.Solarisdynld = "/lib/amd64/ld.so.1" ld.Thearch.Solarisdynld = "/lib/amd64/ld.so.1"
} }
func archinit() { func archinit(ctxt *ld.Link) {
ctxt := ld.Ctxt
// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
// Go was built; see ../../make.bash. // Go was built; see ../../make.bash.
if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" { if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" {
...@@ -153,7 +151,7 @@ func archinit() { ...@@ -153,7 +151,7 @@ func archinit() {
obj.Hopenbsd, /* openbsd */ obj.Hopenbsd, /* openbsd */
obj.Hdragonfly, /* dragonfly */ obj.Hdragonfly, /* dragonfly */
obj.Hsolaris: /* solaris */ obj.Hsolaris: /* solaris */
ld.Elfinit(ld.Ctxt) ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 { if ld.INITTEXT == -1 {
...@@ -167,7 +165,7 @@ func archinit() { ...@@ -167,7 +165,7 @@ func archinit() {
} }
case obj.Hnacl: case obj.Hnacl:
ld.Elfinit(ld.Ctxt) ld.Elfinit(ctxt)
ld.Debug['w']++ // disable dwarf, which gets confused and is useless anyway ld.Debug['w']++ // disable dwarf, which gets confused and is useless anyway
ld.HEADR = 0x10000 ld.HEADR = 0x10000
ld.Funcalign = 32 ld.Funcalign = 32
......
...@@ -58,23 +58,23 @@ import ( ...@@ -58,23 +58,23 @@ import (
// c: 00000004 .word 0x00000004 // c: 00000004 .word 0x00000004
// c: R_ARM_GOT_PREL local.moduledata // c: R_ARM_GOT_PREL local.moduledata
func gentext() { func gentext(ctxt *ld.Link) {
if !ld.DynlinkingGo() { if !ld.DynlinkingGo() {
return return
} }
addmoduledata := ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) addmoduledata := ld.Linklookup(ctxt, "runtime.addmoduledata", 0)
if addmoduledata.Type == obj.STEXT { if addmoduledata.Type == obj.STEXT {
// we're linking a module containing the runtime -> no need for // we're linking a module containing the runtime -> no need for
// an init function // an init function
return return
} }
addmoduledata.Attr |= ld.AttrReachable addmoduledata.Attr |= ld.AttrReachable
initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0) initfunc := ld.Linklookup(ctxt, "go.link.addmoduledata", 0)
initfunc.Type = obj.STEXT initfunc.Type = obj.STEXT
initfunc.Attr |= ld.AttrLocal initfunc.Attr |= ld.AttrLocal
initfunc.Attr |= ld.AttrReachable initfunc.Attr |= ld.AttrReachable
o := func(op uint32) { o := func(op uint32) {
ld.Adduint32(ld.Ctxt, initfunc, op) ld.Adduint32(ctxt, initfunc, op)
} }
o(0xe59f0004) o(0xe59f0004)
o(0xe08f0000) o(0xe08f0000)
...@@ -83,7 +83,7 @@ func gentext() { ...@@ -83,7 +83,7 @@ func gentext() {
rel := ld.Addrel(initfunc) rel := ld.Addrel(initfunc)
rel.Off = 8 rel.Off = 8
rel.Siz = 4 rel.Siz = 4
rel.Sym = ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) rel.Sym = ld.Linklookup(ctxt, "runtime.addmoduledata", 0)
rel.Type = obj.R_CALLARM rel.Type = obj.R_CALLARM
rel.Add = 0xeafffffe // vomit rel.Add = 0xeafffffe // vomit
...@@ -91,16 +91,16 @@ func gentext() { ...@@ -91,16 +91,16 @@ func gentext() {
rel = ld.Addrel(initfunc) rel = ld.Addrel(initfunc)
rel.Off = 12 rel.Off = 12
rel.Siz = 4 rel.Siz = 4
rel.Sym = ld.Ctxt.Moduledata rel.Sym = ctxt.Moduledata
rel.Type = obj.R_PCREL rel.Type = obj.R_PCREL
rel.Add = 4 rel.Add = 4
ld.Ctxt.Textp = append(ld.Ctxt.Textp, initfunc) ctxt.Textp = append(ctxt.Textp, initfunc)
initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0) initarray_entry := ld.Linklookup(ctxt, "go.link.addmoduledatainit", 0)
initarray_entry.Attr |= ld.AttrReachable initarray_entry.Attr |= ld.AttrReachable
initarray_entry.Attr |= ld.AttrLocal initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = obj.SINITARR initarray_entry.Type = obj.SINITARR
ld.Addaddr(ld.Ctxt, initarray_entry, initfunc) ld.Addaddr(ctxt, initarray_entry, initfunc)
} }
// Preserve highest 8 bits of a, and do addition to lower 24-bit // Preserve highest 8 bits of a, and do addition to lower 24-bit
...@@ -109,14 +109,14 @@ func braddoff(a int32, b int32) int32 { ...@@ -109,14 +109,14 @@ func braddoff(a int32, b int32) int32 {
return int32((uint32(a))&0xff000000 | 0x00ffffff&uint32(a+b)) return int32((uint32(a))&0xff000000 | 0x00ffffff&uint32(a+b))
} }
func adddynrel(s *ld.Symbol, r *ld.Reloc) { func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) {
targ := r.Sym targ := r.Sym
ld.Ctxt.Cursym = s ctxt.Cursym = s
switch r.Type { switch r.Type {
default: default:
if r.Type >= 256 { if r.Type >= 256 {
ld.Ctxt.Diag("unexpected relocation type %d", r.Type) ctxt.Diag("unexpected relocation type %d", r.Type)
return return
} }
...@@ -125,8 +125,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -125,8 +125,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
r.Type = obj.R_CALLARM r.Type = obj.R_CALLARM
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
addpltsym(ld.Ctxt, targ) addpltsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) r.Sym = ld.Linklookup(ctxt, ".plt", 0)
r.Add = int64(braddoff(int32(r.Add), targ.Plt/4)) r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
} }
...@@ -138,9 +138,9 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -138,9 +138,9 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
case 256 + ld.R_ARM_GOT32: // R_ARM_GOT_BREL case 256 + ld.R_ARM_GOT32: // R_ARM_GOT_BREL
if targ.Type != obj.SDYNIMPORT { if targ.Type != obj.SDYNIMPORT {
addgotsyminternal(ld.Ctxt, targ) addgotsyminternal(ctxt, targ)
} else { } else {
addgotsym(ld.Ctxt, targ) addgotsym(ctxt, targ)
} }
r.Type = obj.R_CONST // write r->add during relocsym r.Type = obj.R_CONST // write r->add during relocsym
...@@ -150,13 +150,13 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -150,13 +150,13 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
case 256 + ld.R_ARM_GOT_PREL: // GOT(nil) + A - nil case 256 + ld.R_ARM_GOT_PREL: // GOT(nil) + A - nil
if targ.Type != obj.SDYNIMPORT { if targ.Type != obj.SDYNIMPORT {
addgotsyminternal(ld.Ctxt, targ) addgotsyminternal(ctxt, targ)
} else { } else {
addgotsym(ld.Ctxt, targ) addgotsym(ctxt, targ)
} }
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0) r.Sym = ld.Linklookup(ctxt, ".got", 0)
r.Add += int64(targ.Got) + 4 r.Add += int64(targ.Got) + 4
return return
...@@ -168,15 +168,15 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -168,15 +168,15 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
case 256 + ld.R_ARM_GOTPC: // R_ARM_BASE_PREL case 256 + ld.R_ARM_GOTPC: // R_ARM_BASE_PREL
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0) r.Sym = ld.Linklookup(ctxt, ".got", 0)
r.Add += 4 r.Add += 4
return return
case 256 + ld.R_ARM_CALL: case 256 + ld.R_ARM_CALL:
r.Type = obj.R_CALLARM r.Type = obj.R_CALLARM
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
addpltsym(ld.Ctxt, targ) addpltsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) r.Sym = ld.Linklookup(ctxt, ".plt", 0)
r.Add = int64(braddoff(int32(r.Add), targ.Plt/4)) r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
} }
...@@ -190,7 +190,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -190,7 +190,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
case 256 + ld.R_ARM_ABS32: case 256 + ld.R_ARM_ABS32:
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
ld.Ctxt.Diag("unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ.Name) ctxt.Diag("unexpected R_ARM_ABS32 relocation for dynamic symbol %s", targ.Name)
} }
r.Type = obj.R_ADDR r.Type = obj.R_ADDR
return return
...@@ -209,8 +209,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -209,8 +209,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
256 + ld.R_ARM_JUMP24: 256 + ld.R_ARM_JUMP24:
r.Type = obj.R_CALLARM r.Type = obj.R_CALLARM
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
addpltsym(ld.Ctxt, targ) addpltsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) r.Sym = ld.Linklookup(ctxt, ".plt", 0)
r.Add = int64(braddoff(int32(r.Add), targ.Plt/4)) r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
} }
...@@ -224,8 +224,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -224,8 +224,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
switch r.Type { switch r.Type {
case obj.R_CALLARM: case obj.R_CALLARM:
addpltsym(ld.Ctxt, targ) addpltsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) r.Sym = ld.Linklookup(ctxt, ".plt", 0)
r.Add = int64(targ.Plt) r.Add = int64(targ.Plt)
return return
...@@ -234,21 +234,21 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -234,21 +234,21 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
break break
} }
if ld.Iself { if ld.Iself {
ld.Adddynsym(ld.Ctxt, targ) ld.Adddynsym(ctxt, targ)
rel := ld.Linklookup(ld.Ctxt, ".rel", 0) rel := ld.Linklookup(ctxt, ".rel", 0)
ld.Addaddrplus(ld.Ctxt, rel, s, int64(r.Off)) ld.Addaddrplus(ctxt, rel, s, int64(r.Off))
ld.Adduint32(ld.Ctxt, rel, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_ARM_GLOB_DAT)) // we need a nil + A dynamic reloc ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_ARM_GLOB_DAT)) // we need a nil + A dynamic reloc
r.Type = obj.R_CONST // write r->add during relocsym r.Type = obj.R_CONST // write r->add during relocsym
r.Sym = nil r.Sym = nil
return return
} }
} }
ld.Ctxt.Cursym = s ctxt.Cursym = s
ld.Ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type) ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
} }
func elfreloc1(r *ld.Reloc, sectoff int64) int { func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
ld.Thearch.Lput(uint32(sectoff)) ld.Thearch.Lput(uint32(sectoff))
elfsym := r.Xsym.ElfsymForReloc() elfsym := r.Xsym.ElfsymForReloc()
...@@ -298,41 +298,41 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -298,41 +298,41 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
return 0 return 0
} }
func elfsetupplt() { func elfsetupplt(ctxt *ld.Link) {
plt := ld.Linklookup(ld.Ctxt, ".plt", 0) plt := ld.Linklookup(ctxt, ".plt", 0)
got := ld.Linklookup(ld.Ctxt, ".got.plt", 0) got := ld.Linklookup(ctxt, ".got.plt", 0)
if plt.Size == 0 { if plt.Size == 0 {
// str lr, [sp, #-4]! // str lr, [sp, #-4]!
ld.Adduint32(ld.Ctxt, plt, 0xe52de004) ld.Adduint32(ctxt, plt, 0xe52de004)
// ldr lr, [pc, #4] // ldr lr, [pc, #4]
ld.Adduint32(ld.Ctxt, plt, 0xe59fe004) ld.Adduint32(ctxt, plt, 0xe59fe004)
// add lr, pc, lr // add lr, pc, lr
ld.Adduint32(ld.Ctxt, plt, 0xe08fe00e) ld.Adduint32(ctxt, plt, 0xe08fe00e)
// ldr pc, [lr, #8]! // ldr pc, [lr, #8]!
ld.Adduint32(ld.Ctxt, plt, 0xe5bef008) ld.Adduint32(ctxt, plt, 0xe5bef008)
// .word &GLOBAL_OFFSET_TABLE[0] - . // .word &GLOBAL_OFFSET_TABLE[0] - .
ld.Addpcrelplus(ld.Ctxt, plt, got, 4) ld.Addpcrelplus(ctxt, plt, got, 4)
// the first .plt entry requires 3 .plt.got entries // the first .plt entry requires 3 .plt.got entries
ld.Adduint32(ld.Ctxt, got, 0) ld.Adduint32(ctxt, got, 0)
ld.Adduint32(ld.Ctxt, got, 0) ld.Adduint32(ctxt, got, 0)
ld.Adduint32(ld.Ctxt, got, 0) ld.Adduint32(ctxt, got, 0)
} }
} }
func machoreloc1(r *ld.Reloc, sectoff int64) int { func machoreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
var v uint32 var v uint32
rs := r.Xsym rs := r.Xsym
if r.Type == obj.R_PCREL { if r.Type == obj.R_PCREL {
if rs.Type == obj.SHOSTOBJ { if rs.Type == obj.SHOSTOBJ {
ld.Ctxt.Diag("pc-relative relocation of external symbol is not supported") ctxt.Diag("pc-relative relocation of external symbol is not supported")
return -1 return -1
} }
if r.Siz != 4 { if r.Siz != 4 {
...@@ -354,15 +354,15 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -354,15 +354,15 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
o2 |= 2 << 28 // size = 4 o2 |= 2 << 28 // size = 4
ld.Thearch.Lput(o1) ld.Thearch.Lput(o1)
ld.Thearch.Lput(uint32(ld.Symaddr(ld.Ctxt, rs))) ld.Thearch.Lput(uint32(ld.Symaddr(ctxt, rs)))
ld.Thearch.Lput(o2) ld.Thearch.Lput(o2)
ld.Thearch.Lput(uint32(ld.Ctxt.Cursym.Value + int64(r.Off))) ld.Thearch.Lput(uint32(ctxt.Cursym.Value + int64(r.Off)))
return 0 return 0
} }
if rs.Type == obj.SHOSTOBJ || r.Type == obj.R_CALLARM { if rs.Type == obj.SHOSTOBJ || r.Type == obj.R_CALLARM {
if rs.Dynid < 0 { if rs.Dynid < 0 {
ld.Ctxt.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type) ctxt.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
return -1 return -1
} }
...@@ -371,7 +371,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -371,7 +371,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
} else { } else {
v = uint32(rs.Sect.Extnum) v = uint32(rs.Sect.Extnum)
if v == 0 { if v == 0 {
ld.Ctxt.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type) ctxt.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
return -1 return -1
} }
} }
...@@ -410,8 +410,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -410,8 +410,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
return 0 return 0
} }
func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
ctxt := ld.Ctxt
if ld.Linkmode == ld.LinkExternal { if ld.Linkmode == ld.LinkExternal {
switch r.Type { switch r.Type {
case obj.R_CALLARM: case obj.R_CALLARM:
...@@ -431,7 +430,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -431,7 +430,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
} }
if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil { if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil {
ld.Ctxt.Diag("missing section for %s", rs.Name) ctxt.Diag("missing section for %s", rs.Name)
} }
r.Xsym = rs r.Xsym = rs
...@@ -457,25 +456,25 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -457,25 +456,25 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
return 0 return 0
case obj.R_GOTOFF: case obj.R_GOTOFF:
*val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".got", 0)) *val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ctxt, ".got", 0))
return 0 return 0
// The following three arch specific relocations are only for generation of // The following three arch specific relocations are only for generation of
// Linux/ARM ELF's PLT entry (3 assembler instruction) // Linux/ARM ELF's PLT entry (3 assembler instruction)
case obj.R_PLT0: // add ip, pc, #0xXX00000 case obj.R_PLT0: // add ip, pc, #0xXX00000
if ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".got.plt", 0)) < ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".plt", 0)) { if ld.Symaddr(ctxt, ld.Linklookup(ctxt, ".got.plt", 0)) < ld.Symaddr(ctxt, ld.Linklookup(ctxt, ".plt", 0)) {
ld.Ctxt.Diag(".got.plt should be placed after .plt section.") ctxt.Diag(".got.plt should be placed after .plt section.")
} }
*val = 0xe28fc600 + (0xff & (int64(uint32(ld.Symaddr(ctxt, r.Sym)-(ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".plt", 0))+int64(r.Off))+r.Add)) >> 20)) *val = 0xe28fc600 + (0xff & (int64(uint32(ld.Symaddr(ctxt, r.Sym)-(ld.Symaddr(ctxt, ld.Linklookup(ctxt, ".plt", 0))+int64(r.Off))+r.Add)) >> 20))
return 0 return 0
case obj.R_PLT1: // add ip, ip, #0xYY000 case obj.R_PLT1: // add ip, ip, #0xYY000
*val = 0xe28cca00 + (0xff & (int64(uint32(ld.Symaddr(ctxt, r.Sym)-(ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".plt", 0))+int64(r.Off))+r.Add+4)) >> 12)) *val = 0xe28cca00 + (0xff & (int64(uint32(ld.Symaddr(ctxt, r.Sym)-(ld.Symaddr(ctxt, ld.Linklookup(ctxt, ".plt", 0))+int64(r.Off))+r.Add+4)) >> 12))
return 0 return 0
case obj.R_PLT2: // ldr pc, [ip, #0xZZZ]! case obj.R_PLT2: // ldr pc, [ip, #0xZZZ]!
*val = 0xe5bcf000 + (0xfff & int64(uint32(ld.Symaddr(ctxt, r.Sym)-(ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".plt", 0))+int64(r.Off))+r.Add+8))) *val = 0xe5bcf000 + (0xfff & int64(uint32(ld.Symaddr(ctxt, r.Sym)-(ld.Symaddr(ctxt, ld.Linklookup(ctxt, ".plt", 0))+int64(r.Off))+r.Add+8)))
return 0 return 0
...@@ -488,7 +487,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -488,7 +487,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
return -1 return -1
} }
func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
log.Fatalf("unexpected relocation variant") log.Fatalf("unexpected relocation variant")
return t return t
} }
...@@ -520,7 +519,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { ...@@ -520,7 +519,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
got := ld.Linklookup(ctxt, ".got.plt", 0) got := ld.Linklookup(ctxt, ".got.plt", 0)
rel := ld.Linklookup(ctxt, ".rel.plt", 0) rel := ld.Linklookup(ctxt, ".rel.plt", 0)
if plt.Size == 0 { if plt.Size == 0 {
elfsetupplt() elfsetupplt(ctxt)
} }
// .got entry // .got entry
...@@ -543,7 +542,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { ...@@ -543,7 +542,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_JUMP_SLOT)) ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_JUMP_SLOT))
} else { } else {
ld.Ctxt.Diag("addpltsym: unsupported binary format") ctxt.Diag("addpltsym: unsupported binary format")
} }
} }
...@@ -559,7 +558,7 @@ func addgotsyminternal(ctxt *ld.Link, s *ld.Symbol) { ...@@ -559,7 +558,7 @@ func addgotsyminternal(ctxt *ld.Link, s *ld.Symbol) {
if ld.Iself { if ld.Iself {
} else { } else {
ld.Ctxt.Diag("addgotsyminternal: unsupported binary format") ctxt.Diag("addgotsyminternal: unsupported binary format")
} }
} }
...@@ -578,7 +577,7 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) { ...@@ -578,7 +577,7 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
ld.Addaddrplus(ctxt, rel, got, int64(s.Got)) ld.Addaddrplus(ctxt, rel, got, int64(s.Got))
ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_GLOB_DAT)) ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_GLOB_DAT))
} else { } else {
ld.Ctxt.Diag("addgotsym: unsupported binary format") ctxt.Diag("addgotsym: unsupported binary format")
} }
} }
...@@ -671,7 +670,7 @@ func asmb(ctxt *ld.Link) { ...@@ -671,7 +670,7 @@ func asmb(ctxt *ld.Link) {
ld.Asmplan9sym(ctxt) ld.Asmplan9sym(ctxt)
ld.Cflush() ld.Cflush()
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0) sym := ld.Linklookup(ctxt, "pclntab", 0)
if sym != nil { if sym != nil {
ld.Lcsize = int32(len(sym.P)) ld.Lcsize = int32(len(sym.P))
for i := 0; int32(i) < ld.Lcsize; i++ { for i := 0; int32(i) < ld.Lcsize; i++ {
...@@ -688,7 +687,7 @@ func asmb(ctxt *ld.Link) { ...@@ -688,7 +687,7 @@ func asmb(ctxt *ld.Link) {
} }
} }
ld.Ctxt.Cursym = nil ctxt.Cursym = nil
if ld.Debug['v'] != 0 { if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f header\n", obj.Cputime()) fmt.Fprintf(ld.Bso, "%5.2f header\n", obj.Cputime())
} }
......
...@@ -78,7 +78,7 @@ func linkarchinit() { ...@@ -78,7 +78,7 @@ func linkarchinit() {
ld.Thearch.Solarisdynld = "XXX" ld.Thearch.Solarisdynld = "XXX"
} }
func archinit() { func archinit(ctxt *ld.Link) {
// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
// Go was built; see ../../make.bash. // Go was built; see ../../make.bash.
if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" { if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" {
...@@ -128,7 +128,7 @@ func archinit() { ...@@ -128,7 +128,7 @@ func archinit() {
obj.Hopenbsd: obj.Hopenbsd:
ld.Debug['d'] = 0 ld.Debug['d'] = 0
// with dynamic linking // with dynamic linking
ld.Elfinit(ld.Ctxt) ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 { if ld.INITTEXT == -1 {
ld.INITTEXT = 0x10000 + int64(ld.HEADR) ld.INITTEXT = 0x10000 + int64(ld.HEADR)
...@@ -141,7 +141,7 @@ func archinit() { ...@@ -141,7 +141,7 @@ func archinit() {
} }
case obj.Hnacl: case obj.Hnacl:
ld.Elfinit(ld.Ctxt) ld.Elfinit(ctxt)
ld.HEADR = 0x10000 ld.HEADR = 0x10000
ld.Funcalign = 16 ld.Funcalign = 16
if ld.INITTEXT == -1 { if ld.INITTEXT == -1 {
......
...@@ -38,23 +38,23 @@ import ( ...@@ -38,23 +38,23 @@ import (
"log" "log"
) )
func gentext() { func gentext(ctxt *ld.Link) {
if !ld.DynlinkingGo() { if !ld.DynlinkingGo() {
return return
} }
addmoduledata := ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) addmoduledata := ld.Linklookup(ctxt, "runtime.addmoduledata", 0)
if addmoduledata.Type == obj.STEXT { if addmoduledata.Type == obj.STEXT {
// we're linking a module containing the runtime -> no need for // we're linking a module containing the runtime -> no need for
// an init function // an init function
return return
} }
addmoduledata.Attr |= ld.AttrReachable addmoduledata.Attr |= ld.AttrReachable
initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0) initfunc := ld.Linklookup(ctxt, "go.link.addmoduledata", 0)
initfunc.Type = obj.STEXT initfunc.Type = obj.STEXT
initfunc.Attr |= ld.AttrLocal initfunc.Attr |= ld.AttrLocal
initfunc.Attr |= ld.AttrReachable initfunc.Attr |= ld.AttrReachable
o := func(op uint32) { o := func(op uint32) {
ld.Adduint32(ld.Ctxt, initfunc, op) ld.Adduint32(ctxt, initfunc, op)
} }
// 0000000000000000 <local.dso_init>: // 0000000000000000 <local.dso_init>:
// 0: 90000000 adrp x0, 0 <runtime.firstmoduledata> // 0: 90000000 adrp x0, 0 <runtime.firstmoduledata>
...@@ -66,7 +66,7 @@ func gentext() { ...@@ -66,7 +66,7 @@ func gentext() {
rel := ld.Addrel(initfunc) rel := ld.Addrel(initfunc)
rel.Off = 0 rel.Off = 0
rel.Siz = 8 rel.Siz = 8
rel.Sym = ld.Ctxt.Moduledata rel.Sym = ctxt.Moduledata
rel.Type = obj.R_ADDRARM64 rel.Type = obj.R_ADDRARM64
// 8: 14000000 bl 0 <runtime.addmoduledata> // 8: 14000000 bl 0 <runtime.addmoduledata>
...@@ -75,22 +75,22 @@ func gentext() { ...@@ -75,22 +75,22 @@ func gentext() {
rel = ld.Addrel(initfunc) rel = ld.Addrel(initfunc)
rel.Off = 8 rel.Off = 8
rel.Siz = 4 rel.Siz = 4
rel.Sym = ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) rel.Sym = ld.Linklookup(ctxt, "runtime.addmoduledata", 0)
rel.Type = obj.R_CALLARM64 // Really should be R_AARCH64_JUMP26 but doesn't seem to make any difference rel.Type = obj.R_CALLARM64 // Really should be R_AARCH64_JUMP26 but doesn't seem to make any difference
ld.Ctxt.Textp = append(ld.Ctxt.Textp, initfunc) ctxt.Textp = append(ctxt.Textp, initfunc)
initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0) initarray_entry := ld.Linklookup(ctxt, "go.link.addmoduledatainit", 0)
initarray_entry.Attr |= ld.AttrReachable initarray_entry.Attr |= ld.AttrReachable
initarray_entry.Attr |= ld.AttrLocal initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = obj.SINITARR initarray_entry.Type = obj.SINITARR
ld.Addaddr(ld.Ctxt, initarray_entry, initfunc) ld.Addaddr(ctxt, initarray_entry, initfunc)
} }
func adddynrel(s *ld.Symbol, r *ld.Reloc) { func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) {
log.Fatalf("adddynrel not implemented") log.Fatalf("adddynrel not implemented")
} }
func elfreloc1(r *ld.Reloc, sectoff int64) int { func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
ld.Thearch.Vput(uint64(sectoff)) ld.Thearch.Vput(uint64(sectoff))
elfsym := r.Xsym.ElfsymForReloc() elfsym := r.Xsym.ElfsymForReloc()
...@@ -142,12 +142,12 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -142,12 +142,12 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
return 0 return 0
} }
func elfsetupplt() { func elfsetupplt(ctxt *ld.Link) {
// TODO(aram) // TODO(aram)
return return
} }
func machoreloc1(r *ld.Reloc, sectoff int64) int { func machoreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
var v uint32 var v uint32
rs := r.Xsym rs := r.Xsym
...@@ -157,7 +157,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -157,7 +157,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
// UNSIGNED relocation at all. // UNSIGNED relocation at all.
if rs.Type == obj.SHOSTOBJ || r.Type == obj.R_CALLARM64 || r.Type == obj.R_ADDRARM64 || r.Type == obj.R_ADDR { if rs.Type == obj.SHOSTOBJ || r.Type == obj.R_CALLARM64 || r.Type == obj.R_ADDRARM64 || r.Type == obj.R_ADDR {
if rs.Dynid < 0 { if rs.Dynid < 0 {
ld.Ctxt.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type) ctxt.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
return -1 return -1
} }
...@@ -166,7 +166,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -166,7 +166,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
} else { } else {
v = uint32(rs.Sect.Extnum) v = uint32(rs.Sect.Extnum)
if v == 0 { if v == 0 {
ld.Ctxt.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type) ctxt.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
return -1 return -1
} }
} }
...@@ -180,7 +180,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -180,7 +180,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
case obj.R_CALLARM64: case obj.R_CALLARM64:
if r.Xadd != 0 { if r.Xadd != 0 {
ld.Ctxt.Diag("ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", rs.Name, r.Xadd) ctxt.Diag("ld64 doesn't allow BR26 reloc with non-zero addend: %s+%d", rs.Name, r.Xadd)
} }
v |= 1 << 24 // pc-relative bit v |= 1 << 24 // pc-relative bit
...@@ -226,8 +226,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -226,8 +226,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
return 0 return 0
} }
func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
ctxt := ld.Ctxt
if ld.Linkmode == ld.LinkExternal { if ld.Linkmode == ld.LinkExternal {
switch r.Type { switch r.Type {
default: default:
...@@ -235,7 +234,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -235,7 +234,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
case obj.R_ARM64_GOTPCREL: case obj.R_ARM64_GOTPCREL:
var o1, o2 uint32 var o1, o2 uint32
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { if ctxt.Arch.ByteOrder == binary.BigEndian {
o1 = uint32(*val >> 32) o1 = uint32(*val >> 32)
o2 = uint32(*val) o2 = uint32(*val)
} else { } else {
...@@ -252,12 +251,12 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -252,12 +251,12 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
// add + R_ADDRARM64. // add + R_ADDRARM64.
if !(r.Sym.Version != 0 || (r.Sym.Type&obj.SHIDDEN != 0) || r.Sym.Attr.Local()) && r.Sym.Type == obj.STEXT && ld.DynlinkingGo() { if !(r.Sym.Version != 0 || (r.Sym.Type&obj.SHIDDEN != 0) || r.Sym.Attr.Local()) && r.Sym.Type == obj.STEXT && ld.DynlinkingGo() {
if o2&0xffc00000 != 0xf9400000 { if o2&0xffc00000 != 0xf9400000 {
ld.Ctxt.Diag("R_ARM64_GOTPCREL against unexpected instruction %x", o2) ctxt.Diag("R_ARM64_GOTPCREL against unexpected instruction %x", o2)
} }
o2 = 0x91000000 | (o2 & 0x000003ff) o2 = 0x91000000 | (o2 & 0x000003ff)
r.Type = obj.R_ADDRARM64 r.Type = obj.R_ADDRARM64
} }
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { if ctxt.Arch.ByteOrder == binary.BigEndian {
*val = int64(o1)<<32 | int64(o2) *val = int64(o1)<<32 | int64(o2)
} else { } else {
*val = int64(o2)<<32 | int64(o1) *val = int64(o2)<<32 | int64(o1)
...@@ -276,7 +275,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -276,7 +275,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
} }
if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil { if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil {
ld.Ctxt.Diag("missing section for %s", rs.Name) ctxt.Diag("missing section for %s", rs.Name)
} }
r.Xsym = rs r.Xsym = rs
...@@ -288,7 +287,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -288,7 +287,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
if false && ld.HEADTYPE == obj.Hdarwin { if false && ld.HEADTYPE == obj.Hdarwin {
var o0, o1 uint32 var o0, o1 uint32
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { if ctxt.Arch.ByteOrder == binary.BigEndian {
o0 = uint32(*val >> 32) o0 = uint32(*val >> 32)
o1 = uint32(*val) o1 = uint32(*val)
} else { } else {
...@@ -305,7 +304,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -305,7 +304,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
r.Xadd = 0 r.Xadd = 0
// when laid out, the instruction order must always be o1, o2. // when laid out, the instruction order must always be o1, o2.
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { if ctxt.Arch.ByteOrder == binary.BigEndian {
*val = int64(o0)<<32 | int64(o1) *val = int64(o0)<<32 | int64(o1)
} else { } else {
*val = int64(o1)<<32 | int64(o0) *val = int64(o1)<<32 | int64(o0)
...@@ -330,18 +329,18 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -330,18 +329,18 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
return 0 return 0
case obj.R_GOTOFF: case obj.R_GOTOFF:
*val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".got", 0)) *val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ctxt, ".got", 0))
return 0 return 0
case obj.R_ADDRARM64: case obj.R_ADDRARM64:
t := ld.Symaddr(ctxt, r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff) t := ld.Symaddr(ctxt, r.Sym) + r.Add - ((s.Value + int64(r.Off)) &^ 0xfff)
if t >= 1<<32 || t < -1<<32 { if t >= 1<<32 || t < -1<<32 {
ld.Ctxt.Diag("program too large, address relocation distance = %d", t) ctxt.Diag("program too large, address relocation distance = %d", t)
} }
var o0, o1 uint32 var o0, o1 uint32
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { if ctxt.Arch.ByteOrder == binary.BigEndian {
o0 = uint32(*val >> 32) o0 = uint32(*val >> 32)
o1 = uint32(*val) o1 = uint32(*val)
} else { } else {
...@@ -353,7 +352,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -353,7 +352,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
o1 |= uint32(t&0xfff) << 10 o1 |= uint32(t&0xfff) << 10
// when laid out, the instruction order must always be o1, o2. // when laid out, the instruction order must always be o1, o2.
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { if ctxt.Arch.ByteOrder == binary.BigEndian {
*val = int64(o0)<<32 | int64(o1) *val = int64(o0)<<32 | int64(o1)
} else { } else {
*val = int64(o1)<<32 | int64(o0) *val = int64(o1)<<32 | int64(o0)
...@@ -363,13 +362,13 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -363,13 +362,13 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
case obj.R_ARM64_TLS_LE: case obj.R_ARM64_TLS_LE:
r.Done = 0 r.Done = 0
if ld.HEADTYPE != obj.Hlinux { if ld.HEADTYPE != obj.Hlinux {
ld.Ctxt.Diag("TLS reloc on unsupported OS %s", ld.Headstr(int(ld.HEADTYPE))) ctxt.Diag("TLS reloc on unsupported OS %s", ld.Headstr(int(ld.HEADTYPE)))
} }
// The TCB is two pointers. This is not documented anywhere, but is // The TCB is two pointers. This is not documented anywhere, but is
// de facto part of the ABI. // de facto part of the ABI.
v := r.Sym.Value + int64(2*ld.SysArch.PtrSize) v := r.Sym.Value + int64(2*ld.SysArch.PtrSize)
if v < 0 || v >= 32678 { if v < 0 || v >= 32678 {
ld.Ctxt.Diag("TLS offset out of range %d", v) ctxt.Diag("TLS offset out of range %d", v)
} }
*val |= v << 5 *val |= v << 5
return 0 return 0
...@@ -377,7 +376,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -377,7 +376,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
case obj.R_CALLARM64: case obj.R_CALLARM64:
t := (ld.Symaddr(ctxt, r.Sym) + r.Add) - (s.Value + int64(r.Off)) t := (ld.Symaddr(ctxt, r.Sym) + r.Add) - (s.Value + int64(r.Off))
if t >= 1<<27 || t < -1<<27 { if t >= 1<<27 || t < -1<<27 {
ld.Ctxt.Diag("program too large, call relocation distance = %d", t) ctxt.Diag("program too large, call relocation distance = %d", t)
} }
*val |= (t >> 2) & 0x03ffffff *val |= (t >> 2) & 0x03ffffff
return 0 return 0
...@@ -386,7 +385,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -386,7 +385,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
return -1 return -1
} }
func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
log.Fatalf("unexpected relocation variant") log.Fatalf("unexpected relocation variant")
return -1 return -1
} }
...@@ -480,7 +479,7 @@ func asmb(ctxt *ld.Link) { ...@@ -480,7 +479,7 @@ func asmb(ctxt *ld.Link) {
ld.Asmplan9sym(ctxt) ld.Asmplan9sym(ctxt)
ld.Cflush() ld.Cflush()
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0) sym := ld.Linklookup(ctxt, "pclntab", 0)
if sym != nil { if sym != nil {
ld.Lcsize = int32(len(sym.P)) ld.Lcsize = int32(len(sym.P))
for i := 0; int32(i) < ld.Lcsize; i++ { for i := 0; int32(i) < ld.Lcsize; i++ {
...@@ -497,7 +496,7 @@ func asmb(ctxt *ld.Link) { ...@@ -497,7 +496,7 @@ func asmb(ctxt *ld.Link) {
} }
} }
ld.Ctxt.Cursym = nil ctxt.Cursym = nil
if ld.Debug['v'] != 0 { if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f header\n", obj.Cputime()) fmt.Fprintf(ld.Bso, "%5.2f header\n", obj.Cputime())
} }
......
...@@ -79,7 +79,7 @@ func linkarchinit() { ...@@ -79,7 +79,7 @@ func linkarchinit() {
ld.Thearch.Solarisdynld = "XXX" ld.Thearch.Solarisdynld = "XXX"
} }
func archinit() { func archinit(ctxt *ld.Link) {
// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
// Go was built; see ../../make.bash. // Go was built; see ../../make.bash.
if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" { if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" {
...@@ -125,7 +125,7 @@ func archinit() { ...@@ -125,7 +125,7 @@ func archinit() {
} }
case obj.Hlinux: /* arm64 elf */ case obj.Hlinux: /* arm64 elf */
ld.Elfinit(ld.Ctxt) ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 { if ld.INITTEXT == -1 {
ld.INITTEXT = 0x10000 + int64(ld.HEADR) ld.INITTEXT = 0x10000 + int64(ld.HEADR)
...@@ -152,7 +152,7 @@ func archinit() { ...@@ -152,7 +152,7 @@ func archinit() {
} }
case obj.Hnacl: case obj.Hnacl:
ld.Elfinit(ld.Ctxt) ld.Elfinit(ctxt)
ld.HEADR = 0x10000 ld.HEADR = 0x10000
ld.Funcalign = 16 ld.Funcalign = 16
if ld.INITTEXT == -1 { if ld.INITTEXT == -1 {
......
...@@ -399,7 +399,7 @@ func relocsym(ctxt *Link, s *Symbol) { ...@@ -399,7 +399,7 @@ func relocsym(ctxt *Link, s *Symbol) {
case 8: case 8:
o = int64(ctxt.Arch.ByteOrder.Uint64(s.P[off:])) o = int64(ctxt.Arch.ByteOrder.Uint64(s.P[off:]))
} }
if Thearch.Archreloc(r, s, &o) < 0 { if Thearch.Archreloc(ctxt, r, s, &o) < 0 {
ctxt.Diag("unknown reloc %d", r.Type) ctxt.Diag("unknown reloc %d", r.Type)
} }
...@@ -604,7 +604,7 @@ func relocsym(ctxt *Link, s *Symbol) { ...@@ -604,7 +604,7 @@ func relocsym(ctxt *Link, s *Symbol) {
} }
if r.Variant != RV_NONE { if r.Variant != RV_NONE {
o = Thearch.Archrelocvariant(r, s, o) o = Thearch.Archrelocvariant(ctxt, r, s, o)
} }
if false { if false {
...@@ -717,7 +717,7 @@ func dynrelocsym(ctxt *Link, s *Symbol) { ...@@ -717,7 +717,7 @@ func dynrelocsym(ctxt *Link, s *Symbol) {
if r.Sym != nil && !r.Sym.Attr.Reachable() { if r.Sym != nil && !r.Sym.Attr.Reachable() {
ctxt.Diag("internal inconsistency: dynamic symbol %s is not reachable.", r.Sym.Name) ctxt.Diag("internal inconsistency: dynamic symbol %s is not reachable.", r.Sym.Name)
} }
Thearch.Adddynrel(s, r) Thearch.Adddynrel(ctxt, s, r)
} }
} }
} }
......
...@@ -1762,7 +1762,7 @@ func elfrelocsect(ctxt *Link, sect *Section, syms []*Symbol) { ...@@ -1762,7 +1762,7 @@ func elfrelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
if r.Xsym.ElfsymForReloc() == 0 { if r.Xsym.ElfsymForReloc() == 0 {
ctxt.Diag("reloc %d to non-elf symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type) ctxt.Diag("reloc %d to non-elf symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
} }
if Thearch.Elfreloc1(r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) < 0 { if Thearch.Elfreloc1(ctxt, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) < 0 {
ctxt.Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name) ctxt.Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
} }
} }
...@@ -1990,7 +1990,7 @@ func (ctxt *Link) doelf() { ...@@ -1990,7 +1990,7 @@ func (ctxt *Link) doelf() {
s.Type = obj.SELFRXSECT s.Type = obj.SELFRXSECT
} }
Thearch.Elfsetupplt() Thearch.Elfsetupplt(ctxt)
s = Linklookup(ctxt, elfRelType+".plt", 0) s = Linklookup(ctxt, elfRelType+".plt", 0)
s.Attr |= AttrReachable s.Attr |= AttrReachable
......
...@@ -95,16 +95,16 @@ type Arch struct { ...@@ -95,16 +95,16 @@ type Arch struct {
Openbsddynld string Openbsddynld string
Dragonflydynld string Dragonflydynld string
Solarisdynld string Solarisdynld string
Adddynrel func(*Symbol, *Reloc) Adddynrel func(*Link, *Symbol, *Reloc)
Archinit func() Archinit func(*Link)
Archreloc func(*Reloc, *Symbol, *int64) int Archreloc func(*Link, *Reloc, *Symbol, *int64) int
Archrelocvariant func(*Reloc, *Symbol, int64) int64 Archrelocvariant func(*Link, *Reloc, *Symbol, int64) int64
Asmb func(*Link) Asmb func(*Link)
Elfreloc1 func(*Reloc, int64) int Elfreloc1 func(*Link, *Reloc, int64) int
Elfsetupplt func() Elfsetupplt func(*Link)
Gentext func() Gentext func(*Link)
Machoreloc1 func(*Reloc, int64) int Machoreloc1 func(*Link, *Reloc, int64) int
PEreloc1 func(*Reloc, int64) bool PEreloc1 func(*Link, *Reloc, int64) bool
Wput func(uint16) Wput func(uint16)
Lput func(uint32) Lput func(uint32)
Vput func(uint64) Vput func(uint64)
...@@ -209,8 +209,7 @@ var ( ...@@ -209,8 +209,7 @@ var (
extldflags string extldflags string
extar string extar string
libgccfile string libgccfile string
debug_s int // backup old value of debug['s'] debug_s int // backup old value of debug['s']
Ctxt *Link // Global pointer to ctxt used by arch-specific packages
HEADR int32 HEADR int32
HEADTYPE int32 HEADTYPE int32
INITRND int32 INITRND int32
......
...@@ -841,7 +841,7 @@ func machorelocsect(ctxt *Link, sect *Section, syms []*Symbol) { ...@@ -841,7 +841,7 @@ func machorelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
if r.Done != 0 { if r.Done != 0 {
continue continue
} }
if Thearch.Machoreloc1(r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) < 0 { if Thearch.Machoreloc1(ctxt, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) < 0 {
ctxt.Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name) ctxt.Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
} }
} }
......
...@@ -806,7 +806,7 @@ func perelocsect(ctxt *Link, sect *Section, syms []*Symbol) int { ...@@ -806,7 +806,7 @@ func perelocsect(ctxt *Link, sect *Section, syms []*Symbol) int {
if r.Xsym.Dynid < 0 { if r.Xsym.Dynid < 0 {
ctxt.Diag("reloc %d to non-coff symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type) ctxt.Diag("reloc %d to non-coff symbol %s (outer=%s) %d", r.Type, r.Sym.Name, r.Xsym.Name, r.Sym.Type)
} }
if !Thearch.PEreloc1(r, int64(uint64(sym.Value+int64(r.Off))-PEBASE)) { if !Thearch.PEreloc1(ctxt, r, int64(uint64(sym.Value+int64(r.Off))-PEBASE)) {
ctxt.Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name) ctxt.Diag("unsupported obj reloc %d/%d to %s", r.Type, r.Siz, r.Sym.Name)
} }
......
...@@ -49,7 +49,6 @@ func Ldmain() { ...@@ -49,7 +49,6 @@ func Ldmain() {
Bso = bufio.NewWriter(os.Stdout) Bso = bufio.NewWriter(os.Stdout)
ctxt := linknew(SysArch) ctxt := linknew(SysArch)
Ctxt = ctxt // Export Ctxt because it's currently used by the arch-specific packages
ctxt.Bso = Bso ctxt.Bso = Bso
Debug = [128]int{} Debug = [128]int{}
...@@ -158,7 +157,7 @@ func Ldmain() { ...@@ -158,7 +157,7 @@ func Ldmain() {
headstring = Headstr(int(HEADTYPE)) headstring = Headstr(int(HEADTYPE))
} }
Thearch.Archinit() Thearch.Archinit(ctxt)
if Linkshared && !Iself { if Linkshared && !Iself {
Exitf("-linkshared can only be used on elf systems") Exitf("-linkshared can only be used on elf systems")
...@@ -202,7 +201,7 @@ func Ldmain() { ...@@ -202,7 +201,7 @@ func Ldmain() {
ctxt.dope() ctxt.dope()
} }
ctxt.addexport() ctxt.addexport()
Thearch.Gentext() // trampolines, call stubs, etc. Thearch.Gentext(ctxt) // trampolines, call stubs, etc.
ctxt.textbuildid() ctxt.textbuildid()
ctxt.textaddress() ctxt.textaddress()
ctxt.pclntab() ctxt.pclntab()
......
...@@ -38,13 +38,13 @@ import ( ...@@ -38,13 +38,13 @@ import (
"log" "log"
) )
func gentext() {} func gentext(ctxt *ld.Link) {}
func adddynrel(s *ld.Symbol, r *ld.Reloc) { func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) {
log.Fatalf("adddynrel not implemented") log.Fatalf("adddynrel not implemented")
} }
func elfreloc1(r *ld.Reloc, sectoff int64) int { func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
// mips64 ELF relocation (endian neutral) // mips64 ELF relocation (endian neutral)
// offset uint64 // offset uint64
// sym uint32 // sym uint32
...@@ -93,16 +93,15 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -93,16 +93,15 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
return 0 return 0
} }
func elfsetupplt() { func elfsetupplt(ctxt *ld.Link) {
return return
} }
func machoreloc1(r *ld.Reloc, sectoff int64) int { func machoreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
return -1 return -1
} }
func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
ctxt := ld.Ctxt
if ld.Linkmode == ld.LinkExternal { if ld.Linkmode == ld.LinkExternal {
switch r.Type { switch r.Type {
default: default:
...@@ -121,7 +120,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -121,7 +120,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
} }
if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil { if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil {
ld.Ctxt.Diag("missing section for %s", rs.Name) ctxt.Diag("missing section for %s", rs.Name)
} }
r.Xsym = rs r.Xsym = rs
...@@ -143,7 +142,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -143,7 +142,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
return 0 return 0
case obj.R_GOTOFF: case obj.R_GOTOFF:
*val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".got", 0)) *val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ctxt, ".got", 0))
return 0 return 0
case obj.R_ADDRMIPS, case obj.R_ADDRMIPS,
...@@ -161,7 +160,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -161,7 +160,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
// thread pointer is at 0x7000 offset from the start of TLS data area // thread pointer is at 0x7000 offset from the start of TLS data area
t := ld.Symaddr(ctxt, r.Sym) + r.Add - 0x7000 t := ld.Symaddr(ctxt, r.Sym) + r.Add - 0x7000
if t < -32768 || t >= 32678 { if t < -32768 || t >= 32678 {
ld.Ctxt.Diag("TLS offset out of range %d", t) ctxt.Diag("TLS offset out of range %d", t)
} }
o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:]) o1 := ld.SysArch.ByteOrder.Uint32(s.P[r.Off:])
*val = int64(o1&0xffff0000 | uint32(t)&0xffff) *val = int64(o1&0xffff0000 | uint32(t)&0xffff)
...@@ -179,7 +178,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -179,7 +178,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
return -1 return -1
} }
func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
return -1 return -1
} }
...@@ -264,7 +263,7 @@ func asmb(ctxt *ld.Link) { ...@@ -264,7 +263,7 @@ func asmb(ctxt *ld.Link) {
ld.Asmplan9sym(ctxt) ld.Asmplan9sym(ctxt)
ld.Cflush() ld.Cflush()
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0) sym := ld.Linklookup(ctxt, "pclntab", 0)
if sym != nil { if sym != nil {
ld.Lcsize = int32(len(sym.P)) ld.Lcsize = int32(len(sym.P))
for i := 0; int32(i) < ld.Lcsize; i++ { for i := 0; int32(i) < ld.Lcsize; i++ {
...@@ -276,7 +275,7 @@ func asmb(ctxt *ld.Link) { ...@@ -276,7 +275,7 @@ func asmb(ctxt *ld.Link) {
} }
} }
ld.Ctxt.Cursym = nil ctxt.Cursym = nil
if ld.Debug['v'] != 0 { if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f header\n", obj.Cputime()) fmt.Fprintf(ld.Bso, "%5.2f header\n", obj.Cputime())
} }
......
...@@ -92,7 +92,7 @@ func linkarchinit() { ...@@ -92,7 +92,7 @@ func linkarchinit() {
ld.Thearch.Solarisdynld = "XXX" ld.Thearch.Solarisdynld = "XXX"
} }
func archinit() { func archinit(ctxt *ld.Link) {
// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
// Go was built; see ../../make.bash. // Go was built; see ../../make.bash.
if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" { if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" {
...@@ -130,7 +130,7 @@ func archinit() { ...@@ -130,7 +130,7 @@ func archinit() {
} }
case obj.Hlinux: /* mips64 elf */ case obj.Hlinux: /* mips64 elf */
ld.Elfinit(ld.Ctxt) ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 { if ld.INITTEXT == -1 {
ld.INITTEXT = 0x10000 + int64(ld.HEADR) ld.INITTEXT = 0x10000 + int64(ld.HEADR)
...@@ -143,7 +143,7 @@ func archinit() { ...@@ -143,7 +143,7 @@ func archinit() {
} }
case obj.Hnacl: case obj.Hnacl:
ld.Elfinit(ld.Ctxt) ld.Elfinit(ctxt)
ld.HEADR = 0x10000 ld.HEADR = 0x10000
ld.Funcalign = 16 ld.Funcalign = 16
if ld.INITTEXT == -1 { if ld.INITTEXT == -1 {
......
...@@ -38,7 +38,7 @@ import ( ...@@ -38,7 +38,7 @@ import (
"log" "log"
) )
func genplt() { func genplt(ctxt *ld.Link) {
// The ppc64 ABI PLT has similar concepts to other // The ppc64 ABI PLT has similar concepts to other
// architectures, but is laid out quite differently. When we // architectures, but is laid out quite differently. When we
// see an R_PPC64_REL24 relocation to a dynamic symbol // see an R_PPC64_REL24 relocation to a dynamic symbol
...@@ -87,7 +87,7 @@ func genplt() { ...@@ -87,7 +87,7 @@ func genplt() {
// //
// This assumes "case 1" from the ABI, where the caller needs // This assumes "case 1" from the ABI, where the caller needs
// us to save and restore the TOC pointer. // us to save and restore the TOC pointer.
for _, s := range ld.Ctxt.Textp { for _, s := range ctxt.Textp {
for i := range s.R { for i := range s.R {
r := &s.R[i] r := &s.R[i]
if r.Type != 256+ld.R_PPC64_REL24 || r.Sym.Type != obj.SDYNIMPORT { if r.Type != 256+ld.R_PPC64_REL24 || r.Sym.Type != obj.SDYNIMPORT {
...@@ -96,20 +96,20 @@ func genplt() { ...@@ -96,20 +96,20 @@ func genplt() {
// Reserve PLT entry and generate symbol // Reserve PLT entry and generate symbol
// resolver // resolver
addpltsym(ld.Ctxt, r.Sym) addpltsym(ctxt, r.Sym)
// Generate call stub // Generate call stub
n := fmt.Sprintf("%s.%s", s.Name, r.Sym.Name) n := fmt.Sprintf("%s.%s", s.Name, r.Sym.Name)
stub := ld.Linklookup(ld.Ctxt, n, 0) stub := ld.Linklookup(ctxt, n, 0)
if s.Attr.Reachable() { if s.Attr.Reachable() {
stub.Attr |= ld.AttrReachable stub.Attr |= ld.AttrReachable
} }
if stub.Size == 0 { if stub.Size == 0 {
// Need outer to resolve .TOC. // Need outer to resolve .TOC.
stub.Outer = s stub.Outer = s
ld.Ctxt.Textp = append(ld.Ctxt.Textp, stub) ctxt.Textp = append(ctxt.Textp, stub)
gencallstub(1, stub, r.Sym) gencallstub(ctxt, 1, stub, r.Sym)
} }
// Update the relocation to use the call stub // Update the relocation to use the call stub
...@@ -118,29 +118,29 @@ func genplt() { ...@@ -118,29 +118,29 @@ func genplt() {
// Restore TOC after bl. The compiler put a // Restore TOC after bl. The compiler put a
// nop here for us to overwrite. // nop here for us to overwrite.
const o1 = 0xe8410018 // ld r2,24(r1) const o1 = 0xe8410018 // ld r2,24(r1)
ld.Ctxt.Arch.ByteOrder.PutUint32(s.P[r.Off+4:], o1) ctxt.Arch.ByteOrder.PutUint32(s.P[r.Off+4:], o1)
} }
} }
} }
func genaddmoduledata() { func genaddmoduledata(ctxt *ld.Link) {
addmoduledata := ld.Linkrlookup(ld.Ctxt, "runtime.addmoduledata", 0) addmoduledata := ld.Linkrlookup(ctxt, "runtime.addmoduledata", 0)
if addmoduledata.Type == obj.STEXT { if addmoduledata.Type == obj.STEXT {
return return
} }
addmoduledata.Attr |= ld.AttrReachable addmoduledata.Attr |= ld.AttrReachable
initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0) initfunc := ld.Linklookup(ctxt, "go.link.addmoduledata", 0)
initfunc.Type = obj.STEXT initfunc.Type = obj.STEXT
initfunc.Attr |= ld.AttrLocal initfunc.Attr |= ld.AttrLocal
initfunc.Attr |= ld.AttrReachable initfunc.Attr |= ld.AttrReachable
o := func(op uint32) { o := func(op uint32) {
ld.Adduint32(ld.Ctxt, initfunc, op) ld.Adduint32(ctxt, initfunc, op)
} }
// addis r2, r12, .TOC.-func@ha // addis r2, r12, .TOC.-func@ha
rel := ld.Addrel(initfunc) rel := ld.Addrel(initfunc)
rel.Off = int32(initfunc.Size) rel.Off = int32(initfunc.Size)
rel.Siz = 8 rel.Siz = 8
rel.Sym = ld.Linklookup(ld.Ctxt, ".TOC.", 0) rel.Sym = ld.Linklookup(ctxt, ".TOC.", 0)
rel.Type = obj.R_ADDRPOWER_PCREL rel.Type = obj.R_ADDRPOWER_PCREL
o(0x3c4c0000) o(0x3c4c0000)
// addi r2, r2, .TOC.-func@l // addi r2, r2, .TOC.-func@l
...@@ -153,7 +153,7 @@ func genaddmoduledata() { ...@@ -153,7 +153,7 @@ func genaddmoduledata() {
rel = ld.Addrel(initfunc) rel = ld.Addrel(initfunc)
rel.Off = int32(initfunc.Size) rel.Off = int32(initfunc.Size)
rel.Siz = 8 rel.Siz = 8
rel.Sym = ld.Linklookup(ld.Ctxt, "local.moduledata", 0) rel.Sym = ld.Linklookup(ctxt, "local.moduledata", 0)
rel.Type = obj.R_ADDRPOWER_GOT rel.Type = obj.R_ADDRPOWER_GOT
o(0x3c620000) o(0x3c620000)
// ld r3, local.moduledata@got@l(r3) // ld r3, local.moduledata@got@l(r3)
...@@ -176,39 +176,39 @@ func genaddmoduledata() { ...@@ -176,39 +176,39 @@ func genaddmoduledata() {
// blr // blr
o(0x4e800020) o(0x4e800020)
ld.Ctxt.Textp = append(ld.Ctxt.Textp, initfunc) ctxt.Textp = append(ctxt.Textp, initfunc)
initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0) initarray_entry := ld.Linklookup(ctxt, "go.link.addmoduledatainit", 0)
initarray_entry.Attr |= ld.AttrReachable initarray_entry.Attr |= ld.AttrReachable
initarray_entry.Attr |= ld.AttrLocal initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = obj.SINITARR initarray_entry.Type = obj.SINITARR
ld.Addaddr(ld.Ctxt, initarray_entry, initfunc) ld.Addaddr(ctxt, initarray_entry, initfunc)
} }
func gentext() { func gentext(ctxt *ld.Link) {
if ld.DynlinkingGo() { if ld.DynlinkingGo() {
genaddmoduledata() genaddmoduledata(ctxt)
} }
if ld.Linkmode == ld.LinkInternal { if ld.Linkmode == ld.LinkInternal {
genplt() genplt(ctxt)
} }
} }
// Construct a call stub in stub that calls symbol targ via its PLT // Construct a call stub in stub that calls symbol targ via its PLT
// entry. // entry.
func gencallstub(abicase int, stub *ld.Symbol, targ *ld.Symbol) { func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) {
if abicase != 1 { if abicase != 1 {
// If we see R_PPC64_TOCSAVE or R_PPC64_REL24_NOTOC // If we see R_PPC64_TOCSAVE or R_PPC64_REL24_NOTOC
// relocations, we'll need to implement cases 2 and 3. // relocations, we'll need to implement cases 2 and 3.
log.Fatalf("gencallstub only implements case 1 calls") log.Fatalf("gencallstub only implements case 1 calls")
} }
plt := ld.Linklookup(ld.Ctxt, ".plt", 0) plt := ld.Linklookup(ctxt, ".plt", 0)
stub.Type = obj.STEXT stub.Type = obj.STEXT
// Save TOC pointer in TOC save slot // Save TOC pointer in TOC save slot
ld.Adduint32(ld.Ctxt, stub, 0xf8410018) // std r2,24(r1) ld.Adduint32(ctxt, stub, 0xf8410018) // std r2,24(r1)
// Load the function pointer from the PLT. // Load the function pointer from the PLT.
r := ld.Addrel(stub) r := ld.Addrel(stub)
...@@ -217,37 +217,37 @@ func gencallstub(abicase int, stub *ld.Symbol, targ *ld.Symbol) { ...@@ -217,37 +217,37 @@ func gencallstub(abicase int, stub *ld.Symbol, targ *ld.Symbol) {
r.Sym = plt r.Sym = plt
r.Add = int64(targ.Plt) r.Add = int64(targ.Plt)
r.Siz = 2 r.Siz = 2
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { if ctxt.Arch.ByteOrder == binary.BigEndian {
r.Off += int32(r.Siz) r.Off += int32(r.Siz)
} }
r.Type = obj.R_POWER_TOC r.Type = obj.R_POWER_TOC
r.Variant = ld.RV_POWER_HA r.Variant = ld.RV_POWER_HA
ld.Adduint32(ld.Ctxt, stub, 0x3d820000) // addis r12,r2,targ@plt@toc@ha ld.Adduint32(ctxt, stub, 0x3d820000) // addis r12,r2,targ@plt@toc@ha
r = ld.Addrel(stub) r = ld.Addrel(stub)
r.Off = int32(stub.Size) r.Off = int32(stub.Size)
r.Sym = plt r.Sym = plt
r.Add = int64(targ.Plt) r.Add = int64(targ.Plt)
r.Siz = 2 r.Siz = 2
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { if ctxt.Arch.ByteOrder == binary.BigEndian {
r.Off += int32(r.Siz) r.Off += int32(r.Siz)
} }
r.Type = obj.R_POWER_TOC r.Type = obj.R_POWER_TOC
r.Variant = ld.RV_POWER_LO r.Variant = ld.RV_POWER_LO
ld.Adduint32(ld.Ctxt, stub, 0xe98c0000) // ld r12,targ@plt@toc@l(r12) ld.Adduint32(ctxt, stub, 0xe98c0000) // ld r12,targ@plt@toc@l(r12)
// Jump to the loaded pointer // Jump to the loaded pointer
ld.Adduint32(ld.Ctxt, stub, 0x7d8903a6) // mtctr r12 ld.Adduint32(ctxt, stub, 0x7d8903a6) // mtctr r12
ld.Adduint32(ld.Ctxt, stub, 0x4e800420) // bctr ld.Adduint32(ctxt, stub, 0x4e800420) // bctr
} }
func adddynrel(s *ld.Symbol, r *ld.Reloc) { func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) {
targ := r.Sym targ := r.Sym
ld.Ctxt.Cursym = s ctxt.Cursym = s
switch r.Type { switch r.Type {
default: default:
if r.Type >= 256 { if r.Type >= 256 {
ld.Ctxt.Diag("unexpected relocation type %d", r.Type) ctxt.Diag("unexpected relocation type %d", r.Type)
return return
} }
...@@ -264,7 +264,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -264,7 +264,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
// Should have been handled in elfsetupplt // Should have been handled in elfsetupplt
ld.Ctxt.Diag("unexpected R_PPC64_REL24 for dyn import") ctxt.Diag("unexpected R_PPC64_REL24 for dyn import")
} }
return return
...@@ -274,7 +274,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -274,7 +274,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
r.Add += 4 r.Add += 4
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
ld.Ctxt.Diag("unexpected R_PPC_REL32 for dyn import") ctxt.Diag("unexpected R_PPC_REL32 for dyn import")
} }
return return
...@@ -283,12 +283,12 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -283,12 +283,12 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
r.Type = obj.R_ADDR r.Type = obj.R_ADDR
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
// These happen in .toc sections // These happen in .toc sections
ld.Adddynsym(ld.Ctxt, targ) ld.Adddynsym(ctxt, targ)
rela := ld.Linklookup(ld.Ctxt, ".rela", 0) rela := ld.Linklookup(ctxt, ".rela", 0)
ld.Addaddrplus(ld.Ctxt, rela, s, int64(r.Off)) ld.Addaddrplus(ctxt, rela, s, int64(r.Off))
ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_PPC64_ADDR64)) ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_PPC64_ADDR64))
ld.Adduint64(ld.Ctxt, rela, uint64(r.Add)) ld.Adduint64(ctxt, rela, uint64(r.Add))
r.Type = 256 // ignore during relocsym r.Type = 256 // ignore during relocsym
} }
...@@ -350,10 +350,10 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -350,10 +350,10 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
// TODO(austin): Translate our relocations to ELF // TODO(austin): Translate our relocations to ELF
ld.Ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type) ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
} }
func elfreloc1(r *ld.Reloc, sectoff int64) int { func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
ld.Thearch.Vput(uint64(sectoff)) ld.Thearch.Vput(uint64(sectoff))
elfsym := r.Xsym.ElfsymForReloc() elfsym := r.Xsym.ElfsymForReloc()
...@@ -432,8 +432,8 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -432,8 +432,8 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
return 0 return 0
} }
func elfsetupplt() { func elfsetupplt(ctxt *ld.Link) {
plt := ld.Linklookup(ld.Ctxt, ".plt", 0) plt := ld.Linklookup(ctxt, ".plt", 0)
if plt.Size == 0 { if plt.Size == 0 {
// The dynamic linker stores the address of the // The dynamic linker stores the address of the
// dynamic resolver and the DSO identifier in the two // dynamic resolver and the DSO identifier in the two
...@@ -443,32 +443,31 @@ func elfsetupplt() { ...@@ -443,32 +443,31 @@ func elfsetupplt() {
} }
} }
func machoreloc1(r *ld.Reloc, sectoff int64) int { func machoreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
return -1 return -1
} }
// Return the value of .TOC. for symbol s // Return the value of .TOC. for symbol s
func symtoc(s *ld.Symbol) int64 { func symtoc(ctxt *ld.Link, s *ld.Symbol) int64 {
var toc *ld.Symbol var toc *ld.Symbol
if s.Outer != nil { if s.Outer != nil {
toc = ld.Linkrlookup(ld.Ctxt, ".TOC.", int(s.Outer.Version)) toc = ld.Linkrlookup(ctxt, ".TOC.", int(s.Outer.Version))
} else { } else {
toc = ld.Linkrlookup(ld.Ctxt, ".TOC.", int(s.Version)) toc = ld.Linkrlookup(ctxt, ".TOC.", int(s.Version))
} }
if toc == nil { if toc == nil {
ld.Ctxt.Diag("TOC-relative relocation in object without .TOC.") ctxt.Diag("TOC-relative relocation in object without .TOC.")
return 0 return 0
} }
return toc.Value return toc.Value
} }
func archrelocaddr(r *ld.Reloc, s *ld.Symbol, val *int64) int { func archrelocaddr(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
ctxt := ld.Ctxt
var o1, o2 uint32 var o1, o2 uint32
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { if ctxt.Arch.ByteOrder == binary.BigEndian {
o1 = uint32(*val >> 32) o1 = uint32(*val >> 32)
o2 = uint32(*val) o2 = uint32(*val)
} else { } else {
...@@ -485,7 +484,7 @@ func archrelocaddr(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -485,7 +484,7 @@ func archrelocaddr(r *ld.Reloc, s *ld.Symbol, val *int64) int {
t := ld.Symaddr(ctxt, r.Sym) + r.Add t := ld.Symaddr(ctxt, r.Sym) + r.Add
if t < 0 || t >= 1<<31 { if t < 0 || t >= 1<<31 {
ld.Ctxt.Diag("relocation for %s is too big (>=2G): %d", s.Name, ld.Symaddr(ctxt, r.Sym)) ctxt.Diag("relocation for %s is too big (>=2G): %d", s.Name, ld.Symaddr(ctxt, r.Sym))
} }
if t&0x8000 != 0 { if t&0x8000 != 0 {
t += 0x10000 t += 0x10000
...@@ -499,7 +498,7 @@ func archrelocaddr(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -499,7 +498,7 @@ func archrelocaddr(r *ld.Reloc, s *ld.Symbol, val *int64) int {
case obj.R_ADDRPOWER_DS: case obj.R_ADDRPOWER_DS:
o1 |= (uint32(t) >> 16) & 0xffff o1 |= (uint32(t) >> 16) & 0xffff
if t&3 != 0 { if t&3 != 0 {
ld.Ctxt.Diag("bad DS reloc for %s: %d", s.Name, ld.Symaddr(ctxt, r.Sym)) ctxt.Diag("bad DS reloc for %s: %d", s.Name, ld.Symaddr(ctxt, r.Sym))
} }
o2 |= uint32(t) & 0xfffc o2 |= uint32(t) & 0xfffc
...@@ -507,7 +506,7 @@ func archrelocaddr(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -507,7 +506,7 @@ func archrelocaddr(r *ld.Reloc, s *ld.Symbol, val *int64) int {
return -1 return -1
} }
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { if ctxt.Arch.ByteOrder == binary.BigEndian {
*val = int64(o1)<<32 | int64(o2) *val = int64(o1)<<32 | int64(o2)
} else { } else {
*val = int64(o2)<<32 | int64(o1) *val = int64(o2)<<32 | int64(o1)
...@@ -515,8 +514,7 @@ func archrelocaddr(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -515,8 +514,7 @@ func archrelocaddr(r *ld.Reloc, s *ld.Symbol, val *int64) int {
return 0 return 0
} }
func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
ctxt := ld.Ctxt
if ld.Linkmode == ld.LinkExternal { if ld.Linkmode == ld.LinkExternal {
switch r.Type { switch r.Type {
default: default:
...@@ -546,7 +544,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -546,7 +544,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
} }
if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil { if rs.Type != obj.SHOSTOBJ && rs.Type != obj.SDYNIMPORT && rs.Sect == nil {
ld.Ctxt.Diag("missing section for %s", rs.Name) ctxt.Diag("missing section for %s", rs.Name)
} }
r.Xsym = rs r.Xsym = rs
...@@ -566,30 +564,30 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -566,30 +564,30 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
return 0 return 0
case obj.R_GOTOFF: case obj.R_GOTOFF:
*val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".got", 0)) *val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ctxt, ".got", 0))
return 0 return 0
case obj.R_ADDRPOWER, obj.R_ADDRPOWER_DS: case obj.R_ADDRPOWER, obj.R_ADDRPOWER_DS:
return archrelocaddr(r, s, val) return archrelocaddr(ctxt, r, s, val)
case obj.R_CALLPOWER: case obj.R_CALLPOWER:
// Bits 6 through 29 = (S + A - P) >> 2 // Bits 6 through 29 = (S + A - P) >> 2
t := ld.Symaddr(ctxt, r.Sym) + r.Add - (s.Value + int64(r.Off)) t := ld.Symaddr(ctxt, r.Sym) + r.Add - (s.Value + int64(r.Off))
if t&3 != 0 { if t&3 != 0 {
ld.Ctxt.Diag("relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t) ctxt.Diag("relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
} }
if int64(int32(t<<6)>>6) != t { if int64(int32(t<<6)>>6) != t {
// TODO(austin) This can happen if text > 32M. // TODO(austin) This can happen if text > 32M.
// Add a call trampoline to .text in that case. // Add a call trampoline to .text in that case.
ld.Ctxt.Diag("relocation for %s+%d is too big: %d", r.Sym.Name, r.Off, t) ctxt.Diag("relocation for %s+%d is too big: %d", r.Sym.Name, r.Off, t)
} }
*val |= int64(uint32(t) &^ 0xfc000003) *val |= int64(uint32(t) &^ 0xfc000003)
return 0 return 0
case obj.R_POWER_TOC: // S + A - .TOC. case obj.R_POWER_TOC: // S + A - .TOC.
*val = ld.Symaddr(ctxt, r.Sym) + r.Add - symtoc(s) *val = ld.Symaddr(ctxt, r.Sym) + r.Add - symtoc(ctxt, s)
return 0 return 0
...@@ -600,7 +598,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -600,7 +598,7 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
// Specification". // Specification".
v := r.Sym.Value - 0x7000 v := r.Sym.Value - 0x7000
if int64(int16(v)) != v { if int64(int16(v)) != v {
ld.Ctxt.Diag("TLS offset out of range %d", v) ctxt.Diag("TLS offset out of range %d", v)
} }
*val = (*val &^ 0xffff) | (v & 0xffff) *val = (*val &^ 0xffff) | (v & 0xffff)
return 0 return 0
...@@ -609,10 +607,10 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -609,10 +607,10 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
return -1 return -1
} }
func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
switch r.Variant & ld.RV_TYPE_MASK { switch r.Variant & ld.RV_TYPE_MASK {
default: default:
ld.Ctxt.Diag("unexpected relocation variant %d", r.Variant) ctxt.Diag("unexpected relocation variant %d", r.Variant)
fallthrough fallthrough
case ld.RV_NONE: case ld.RV_NONE:
...@@ -623,7 +621,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { ...@@ -623,7 +621,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 {
// Whether to check for signed or unsigned // Whether to check for signed or unsigned
// overflow depends on the instruction // overflow depends on the instruction
var o1 uint32 var o1 uint32
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { if ctxt.Arch.ByteOrder == binary.BigEndian {
o1 = ld.Be32(s.P[r.Off-2:]) o1 = ld.Be32(s.P[r.Off-2:])
} else { } else {
o1 = ld.Le32(s.P[r.Off:]) o1 = ld.Le32(s.P[r.Off:])
...@@ -657,7 +655,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { ...@@ -657,7 +655,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 {
// Whether to check for signed or unsigned // Whether to check for signed or unsigned
// overflow depends on the instruction // overflow depends on the instruction
var o1 uint32 var o1 uint32
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { if ctxt.Arch.ByteOrder == binary.BigEndian {
o1 = ld.Be32(s.P[r.Off-2:]) o1 = ld.Be32(s.P[r.Off-2:])
} else { } else {
o1 = ld.Le32(s.P[r.Off:]) o1 = ld.Le32(s.P[r.Off:])
...@@ -681,13 +679,13 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { ...@@ -681,13 +679,13 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 {
case ld.RV_POWER_DS: case ld.RV_POWER_DS:
var o1 uint32 var o1 uint32
if ld.Ctxt.Arch.ByteOrder == binary.BigEndian { if ctxt.Arch.ByteOrder == binary.BigEndian {
o1 = uint32(ld.Be16(s.P[r.Off:])) o1 = uint32(ld.Be16(s.P[r.Off:]))
} else { } else {
o1 = uint32(ld.Le16(s.P[r.Off:])) o1 = uint32(ld.Le16(s.P[r.Off:]))
} }
if t&3 != 0 { if t&3 != 0 {
ld.Ctxt.Diag("relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t) ctxt.Diag("relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
} }
if (r.Variant&ld.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t { if (r.Variant&ld.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t {
goto overflow goto overflow
...@@ -696,7 +694,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { ...@@ -696,7 +694,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 {
} }
overflow: overflow:
ld.Ctxt.Diag("relocation for %s+%d is too big: %d", r.Sym.Name, r.Off, t) ctxt.Diag("relocation for %s+%d is too big: %d", r.Sym.Name, r.Off, t)
return t return t
} }
...@@ -711,11 +709,11 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { ...@@ -711,11 +709,11 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
plt := ld.Linklookup(ctxt, ".plt", 0) plt := ld.Linklookup(ctxt, ".plt", 0)
rela := ld.Linklookup(ctxt, ".rela.plt", 0) rela := ld.Linklookup(ctxt, ".rela.plt", 0)
if plt.Size == 0 { if plt.Size == 0 {
elfsetupplt() elfsetupplt(ctxt)
} }
// Create the glink resolver if necessary // Create the glink resolver if necessary
glink := ensureglinkresolver() glink := ensureglinkresolver(ctxt)
// Write symbol resolver stub (just a branch to the // Write symbol resolver stub (just a branch to the
// glink resolver stub) // glink resolver stub)
...@@ -741,13 +739,13 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { ...@@ -741,13 +739,13 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_PPC64_JMP_SLOT)) ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_PPC64_JMP_SLOT))
ld.Adduint64(ctxt, rela, 0) ld.Adduint64(ctxt, rela, 0)
} else { } else {
ld.Ctxt.Diag("addpltsym: unsupported binary format") ctxt.Diag("addpltsym: unsupported binary format")
} }
} }
// Generate the glink resolver stub if necessary and return the .glink section // Generate the glink resolver stub if necessary and return the .glink section
func ensureglinkresolver() *ld.Symbol { func ensureglinkresolver(ctxt *ld.Link) *ld.Symbol {
glink := ld.Linklookup(ld.Ctxt, ".glink", 0) glink := ld.Linklookup(ctxt, ".glink", 0)
if glink.Size != 0 { if glink.Size != 0 {
return glink return glink
} }
...@@ -759,48 +757,48 @@ func ensureglinkresolver() *ld.Symbol { ...@@ -759,48 +757,48 @@ func ensureglinkresolver() *ld.Symbol {
// //
// This stub is PIC, so first get the PC of label 1 into r11. // This stub is PIC, so first get the PC of label 1 into r11.
// Other things will be relative to this. // Other things will be relative to this.
ld.Adduint32(ld.Ctxt, glink, 0x7c0802a6) // mflr r0 ld.Adduint32(ctxt, glink, 0x7c0802a6) // mflr r0
ld.Adduint32(ld.Ctxt, glink, 0x429f0005) // bcl 20,31,1f ld.Adduint32(ctxt, glink, 0x429f0005) // bcl 20,31,1f
ld.Adduint32(ld.Ctxt, glink, 0x7d6802a6) // 1: mflr r11 ld.Adduint32(ctxt, glink, 0x7d6802a6) // 1: mflr r11
ld.Adduint32(ld.Ctxt, glink, 0x7c0803a6) // mtlf r0 ld.Adduint32(ctxt, glink, 0x7c0803a6) // mtlf r0
// Compute the .plt array index from the entry point address. // Compute the .plt array index from the entry point address.
// Because this is PIC, everything is relative to label 1b (in // Because this is PIC, everything is relative to label 1b (in
// r11): // r11):
// r0 = ((r12 - r11) - (res_0 - r11)) / 4 = (r12 - res_0) / 4 // r0 = ((r12 - r11) - (res_0 - r11)) / 4 = (r12 - res_0) / 4
ld.Adduint32(ld.Ctxt, glink, 0x3800ffd0) // li r0,-(res_0-1b)=-48 ld.Adduint32(ctxt, glink, 0x3800ffd0) // li r0,-(res_0-1b)=-48
ld.Adduint32(ld.Ctxt, glink, 0x7c006214) // add r0,r0,r12 ld.Adduint32(ctxt, glink, 0x7c006214) // add r0,r0,r12
ld.Adduint32(ld.Ctxt, glink, 0x7c0b0050) // sub r0,r0,r11 ld.Adduint32(ctxt, glink, 0x7c0b0050) // sub r0,r0,r11
ld.Adduint32(ld.Ctxt, glink, 0x7800f082) // srdi r0,r0,2 ld.Adduint32(ctxt, glink, 0x7800f082) // srdi r0,r0,2
// r11 = address of the first byte of the PLT // r11 = address of the first byte of the PLT
r := ld.Addrel(glink) r := ld.Addrel(glink)
r.Off = int32(glink.Size) r.Off = int32(glink.Size)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) r.Sym = ld.Linklookup(ctxt, ".plt", 0)
r.Siz = 8 r.Siz = 8
r.Type = obj.R_ADDRPOWER r.Type = obj.R_ADDRPOWER
ld.Adduint32(ld.Ctxt, glink, 0x3d600000) // addis r11,0,.plt@ha ld.Adduint32(ctxt, glink, 0x3d600000) // addis r11,0,.plt@ha
ld.Adduint32(ld.Ctxt, glink, 0x396b0000) // addi r11,r11,.plt@l ld.Adduint32(ctxt, glink, 0x396b0000) // addi r11,r11,.plt@l
// Load r12 = dynamic resolver address and r11 = DSO // Load r12 = dynamic resolver address and r11 = DSO
// identifier from the first two doublewords of the PLT. // identifier from the first two doublewords of the PLT.
ld.Adduint32(ld.Ctxt, glink, 0xe98b0000) // ld r12,0(r11) ld.Adduint32(ctxt, glink, 0xe98b0000) // ld r12,0(r11)
ld.Adduint32(ld.Ctxt, glink, 0xe96b0008) // ld r11,8(r11) ld.Adduint32(ctxt, glink, 0xe96b0008) // ld r11,8(r11)
// Jump to the dynamic resolver // Jump to the dynamic resolver
ld.Adduint32(ld.Ctxt, glink, 0x7d8903a6) // mtctr r12 ld.Adduint32(ctxt, glink, 0x7d8903a6) // mtctr r12
ld.Adduint32(ld.Ctxt, glink, 0x4e800420) // bctr ld.Adduint32(ctxt, glink, 0x4e800420) // bctr
// The symbol resolvers must immediately follow. // The symbol resolvers must immediately follow.
// res_0: // res_0:
// Add DT_PPC64_GLINK .dynamic entry, which points to 32 bytes // Add DT_PPC64_GLINK .dynamic entry, which points to 32 bytes
// before the first symbol resolver stub. // before the first symbol resolver stub.
s := ld.Linklookup(ld.Ctxt, ".dynamic", 0) s := ld.Linklookup(ctxt, ".dynamic", 0)
ld.Elfwritedynentsymplus(ld.Ctxt, s, ld.DT_PPC64_GLINK, glink, glink.Size-32) ld.Elfwritedynentsymplus(ctxt, s, ld.DT_PPC64_GLINK, glink, glink.Size-32)
return glink return glink
} }
...@@ -886,7 +884,7 @@ func asmb(ctxt *ld.Link) { ...@@ -886,7 +884,7 @@ func asmb(ctxt *ld.Link) {
ld.Asmplan9sym(ctxt) ld.Asmplan9sym(ctxt)
ld.Cflush() ld.Cflush()
sym := ld.Linklookup(ld.Ctxt, "pclntab", 0) sym := ld.Linklookup(ctxt, "pclntab", 0)
if sym != nil { if sym != nil {
ld.Lcsize = int32(len(sym.P)) ld.Lcsize = int32(len(sym.P))
for i := 0; int32(i) < ld.Lcsize; i++ { for i := 0; int32(i) < ld.Lcsize; i++ {
...@@ -898,7 +896,7 @@ func asmb(ctxt *ld.Link) { ...@@ -898,7 +896,7 @@ func asmb(ctxt *ld.Link) {
} }
} }
ld.Ctxt.Cursym = nil ctxt.Cursym = nil
if ld.Debug['v'] != 0 { if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f header\n", obj.Cputime()) fmt.Fprintf(ld.Bso, "%5.2f header\n", obj.Cputime())
} }
......
...@@ -93,7 +93,7 @@ func linkarchinit() { ...@@ -93,7 +93,7 @@ func linkarchinit() {
ld.Thearch.Solarisdynld = "XXX" ld.Thearch.Solarisdynld = "XXX"
} }
func archinit() { func archinit(ctxt *ld.Link) {
// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
// Go was built; see ../../make.bash. // Go was built; see ../../make.bash.
if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" { if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" {
...@@ -110,7 +110,7 @@ func archinit() { ...@@ -110,7 +110,7 @@ func archinit() {
} }
if ld.Linkmode == ld.LinkExternal { if ld.Linkmode == ld.LinkExternal {
toc := ld.Linklookup(ld.Ctxt, ".TOC.", 0) toc := ld.Linklookup(ctxt, ".TOC.", 0)
toc.Type = obj.SDYNIMPORT toc.Type = obj.SDYNIMPORT
} }
...@@ -148,7 +148,7 @@ func archinit() { ...@@ -148,7 +148,7 @@ func archinit() {
if ld.SysArch == sys.ArchPPC64 { if ld.SysArch == sys.ArchPPC64 {
ld.Debug['d'] = 1 // TODO(austin): ELF ABI v1 not supported yet ld.Debug['d'] = 1 // TODO(austin): ELF ABI v1 not supported yet
} }
ld.Elfinit(ld.Ctxt) ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 { if ld.INITTEXT == -1 {
ld.INITTEXT = 0x10000 + int64(ld.HEADR) ld.INITTEXT = 0x10000 + int64(ld.HEADR)
...@@ -161,7 +161,7 @@ func archinit() { ...@@ -161,7 +161,7 @@ func archinit() {
} }
case obj.Hnacl: case obj.Hnacl:
ld.Elfinit(ld.Ctxt) ld.Elfinit(ctxt)
ld.HEADR = 0x10000 ld.HEADR = 0x10000
ld.Funcalign = 16 ld.Funcalign = 16
if ld.INITTEXT == -1 { if ld.INITTEXT == -1 {
......
...@@ -47,72 +47,72 @@ import ( ...@@ -47,72 +47,72 @@ import (
// undef // undef
// //
// The job of appending the moduledata is delegated to runtime.addmoduledata. // The job of appending the moduledata is delegated to runtime.addmoduledata.
func gentext() { func gentext(ctxt *ld.Link) {
if !ld.DynlinkingGo() { if !ld.DynlinkingGo() {
return return
} }
addmoduledata := ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) addmoduledata := ld.Linklookup(ctxt, "runtime.addmoduledata", 0)
if addmoduledata.Type == obj.STEXT { if addmoduledata.Type == obj.STEXT {
// we're linking a module containing the runtime -> no need for // we're linking a module containing the runtime -> no need for
// an init function // an init function
return return
} }
addmoduledata.Attr |= ld.AttrReachable addmoduledata.Attr |= ld.AttrReachable
initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0) initfunc := ld.Linklookup(ctxt, "go.link.addmoduledata", 0)
initfunc.Type = obj.STEXT initfunc.Type = obj.STEXT
initfunc.Attr |= ld.AttrLocal initfunc.Attr |= ld.AttrLocal
initfunc.Attr |= ld.AttrReachable initfunc.Attr |= ld.AttrReachable
// larl %r2, <local.moduledata> // larl %r2, <local.moduledata>
ld.Adduint8(ld.Ctxt, initfunc, 0xc0) ld.Adduint8(ctxt, initfunc, 0xc0)
ld.Adduint8(ld.Ctxt, initfunc, 0x20) ld.Adduint8(ctxt, initfunc, 0x20)
lmd := ld.Addrel(initfunc) lmd := ld.Addrel(initfunc)
lmd.Off = int32(initfunc.Size) lmd.Off = int32(initfunc.Size)
lmd.Siz = 4 lmd.Siz = 4
lmd.Sym = ld.Ctxt.Moduledata lmd.Sym = ctxt.Moduledata
lmd.Type = obj.R_PCREL lmd.Type = obj.R_PCREL
lmd.Variant = ld.RV_390_DBL lmd.Variant = ld.RV_390_DBL
lmd.Add = 2 + int64(lmd.Siz) lmd.Add = 2 + int64(lmd.Siz)
ld.Adduint32(ld.Ctxt, initfunc, 0) ld.Adduint32(ctxt, initfunc, 0)
// jg <runtime.addmoduledata[@plt]> // jg <runtime.addmoduledata[@plt]>
ld.Adduint8(ld.Ctxt, initfunc, 0xc0) ld.Adduint8(ctxt, initfunc, 0xc0)
ld.Adduint8(ld.Ctxt, initfunc, 0xf4) ld.Adduint8(ctxt, initfunc, 0xf4)
rel := ld.Addrel(initfunc) rel := ld.Addrel(initfunc)
rel.Off = int32(initfunc.Size) rel.Off = int32(initfunc.Size)
rel.Siz = 4 rel.Siz = 4
rel.Sym = ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) rel.Sym = ld.Linklookup(ctxt, "runtime.addmoduledata", 0)
rel.Type = obj.R_CALL rel.Type = obj.R_CALL
rel.Variant = ld.RV_390_DBL rel.Variant = ld.RV_390_DBL
rel.Add = 2 + int64(rel.Siz) rel.Add = 2 + int64(rel.Siz)
ld.Adduint32(ld.Ctxt, initfunc, 0) ld.Adduint32(ctxt, initfunc, 0)
// undef (for debugging) // undef (for debugging)
ld.Adduint32(ld.Ctxt, initfunc, 0) ld.Adduint32(ctxt, initfunc, 0)
ld.Ctxt.Textp = append(ld.Ctxt.Textp, initfunc) ctxt.Textp = append(ctxt.Textp, initfunc)
initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0) initarray_entry := ld.Linklookup(ctxt, "go.link.addmoduledatainit", 0)
initarray_entry.Attr |= ld.AttrLocal initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Attr |= ld.AttrReachable initarray_entry.Attr |= ld.AttrReachable
initarray_entry.Type = obj.SINITARR initarray_entry.Type = obj.SINITARR
ld.Addaddr(ld.Ctxt, initarray_entry, initfunc) ld.Addaddr(ctxt, initarray_entry, initfunc)
} }
func adddynrel(s *ld.Symbol, r *ld.Reloc) { func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) {
targ := r.Sym targ := r.Sym
ld.Ctxt.Cursym = s ctxt.Cursym = s
switch r.Type { switch r.Type {
default: default:
if r.Type >= 256 { if r.Type >= 256 {
ld.Ctxt.Diag("unexpected relocation type %d", r.Type) ctxt.Diag("unexpected relocation type %d", r.Type)
return return
} }
// Handle relocations found in ELF object files. // Handle relocations found in ELF object files.
case 256 + ld.R_390_12, case 256 + ld.R_390_12,
256 + ld.R_390_GOT12: 256 + ld.R_390_GOT12:
ld.Ctxt.Diag("s390x 12-bit relocations have not been implemented (relocation type %d)", r.Type-256) ctxt.Diag("s390x 12-bit relocations have not been implemented (relocation type %d)", r.Type-256)
return return
case 256 + ld.R_390_8, case 256 + ld.R_390_8,
...@@ -120,7 +120,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -120,7 +120,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
256 + ld.R_390_32, 256 + ld.R_390_32,
256 + ld.R_390_64: 256 + ld.R_390_64:
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
ld.Ctxt.Diag("unexpected R_390_nn relocation for dynamic symbol %s", targ.Name) ctxt.Diag("unexpected R_390_nn relocation for dynamic symbol %s", targ.Name)
} }
r.Type = obj.R_ADDR r.Type = obj.R_ADDR
return return
...@@ -129,10 +129,10 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -129,10 +129,10 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
256 + ld.R_390_PC32, 256 + ld.R_390_PC32,
256 + ld.R_390_PC64: 256 + ld.R_390_PC64:
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
ld.Ctxt.Diag("unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name) ctxt.Diag("unexpected R_390_PCnn relocation for dynamic symbol %s", targ.Name)
} }
if targ.Type == 0 || targ.Type == obj.SXREF { if targ.Type == 0 || targ.Type == obj.SXREF {
ld.Ctxt.Diag("unknown symbol %s in pcrel", targ.Name) ctxt.Diag("unknown symbol %s in pcrel", targ.Name)
} }
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Add += int64(r.Siz) r.Add += int64(r.Siz)
...@@ -141,7 +141,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -141,7 +141,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
case 256 + ld.R_390_GOT16, case 256 + ld.R_390_GOT16,
256 + ld.R_390_GOT32, 256 + ld.R_390_GOT32,
256 + ld.R_390_GOT64: 256 + ld.R_390_GOT64:
ld.Ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256) ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256)
return return
case 256 + ld.R_390_PLT16DBL, case 256 + ld.R_390_PLT16DBL,
...@@ -150,8 +150,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -150,8 +150,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
r.Variant = ld.RV_390_DBL r.Variant = ld.RV_390_DBL
r.Add += int64(r.Siz) r.Add += int64(r.Siz)
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
addpltsym(ld.Ctxt, targ) addpltsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) r.Sym = ld.Linklookup(ctxt, ".plt", 0)
r.Add += int64(targ.Plt) r.Add += int64(targ.Plt)
} }
return return
...@@ -161,34 +161,34 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -161,34 +161,34 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Add += int64(r.Siz) r.Add += int64(r.Siz)
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
addpltsym(ld.Ctxt, targ) addpltsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) r.Sym = ld.Linklookup(ctxt, ".plt", 0)
r.Add += int64(targ.Plt) r.Add += int64(targ.Plt)
} }
return return
case 256 + ld.R_390_COPY: case 256 + ld.R_390_COPY:
ld.Ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256) ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256)
case 256 + ld.R_390_GLOB_DAT: case 256 + ld.R_390_GLOB_DAT:
ld.Ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256) ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256)
case 256 + ld.R_390_JMP_SLOT: case 256 + ld.R_390_JMP_SLOT:
ld.Ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256) ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256)
case 256 + ld.R_390_RELATIVE: case 256 + ld.R_390_RELATIVE:
ld.Ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256) ctxt.Diag("unimplemented S390x relocation: %v", r.Type-256)
case 256 + ld.R_390_GOTOFF: case 256 + ld.R_390_GOTOFF:
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
ld.Ctxt.Diag("unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name) ctxt.Diag("unexpected R_390_GOTOFF relocation for dynamic symbol %s", targ.Name)
} }
r.Type = obj.R_GOTOFF r.Type = obj.R_GOTOFF
return return
case 256 + ld.R_390_GOTPC: case 256 + ld.R_390_GOTPC:
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0) r.Sym = ld.Linklookup(ctxt, ".got", 0)
r.Add += int64(r.Siz) r.Add += int64(r.Siz)
return return
...@@ -198,23 +198,23 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -198,23 +198,23 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
r.Variant = ld.RV_390_DBL r.Variant = ld.RV_390_DBL
r.Add += int64(r.Siz) r.Add += int64(r.Siz)
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
ld.Ctxt.Diag("unexpected R_390_PCnnDBL relocation for dynamic symbol %s", targ.Name) ctxt.Diag("unexpected R_390_PCnnDBL relocation for dynamic symbol %s", targ.Name)
} }
return return
case 256 + ld.R_390_GOTPCDBL: case 256 + ld.R_390_GOTPCDBL:
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Variant = ld.RV_390_DBL r.Variant = ld.RV_390_DBL
r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0) r.Sym = ld.Linklookup(ctxt, ".got", 0)
r.Add += int64(r.Siz) r.Add += int64(r.Siz)
return return
case 256 + ld.R_390_GOTENT: case 256 + ld.R_390_GOTENT:
addgotsym(targ) addgotsym(ctxt, targ)
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Variant = ld.RV_390_DBL r.Variant = ld.RV_390_DBL
r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0) r.Sym = ld.Linklookup(ctxt, ".got", 0)
r.Add += int64(targ.Got) r.Add += int64(targ.Got)
r.Add += int64(r.Siz) r.Add += int64(r.Siz)
return return
...@@ -224,10 +224,10 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -224,10 +224,10 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
return return
} }
ld.Ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type) ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
} }
func elfreloc1(r *ld.Reloc, sectoff int64) int { func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
ld.Thearch.Vput(uint64(sectoff)) ld.Thearch.Vput(uint64(sectoff))
elfsym := r.Xsym.ElfsymForReloc() elfsym := r.Xsym.ElfsymForReloc()
...@@ -326,62 +326,61 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -326,62 +326,61 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
return 0 return 0
} }
func elfsetupplt() { func elfsetupplt(ctxt *ld.Link) {
plt := ld.Linklookup(ld.Ctxt, ".plt", 0) plt := ld.Linklookup(ctxt, ".plt", 0)
got := ld.Linklookup(ld.Ctxt, ".got", 0) got := ld.Linklookup(ctxt, ".got", 0)
if plt.Size == 0 { if plt.Size == 0 {
// stg %r1,56(%r15) // stg %r1,56(%r15)
ld.Adduint8(ld.Ctxt, plt, 0xe3) ld.Adduint8(ctxt, plt, 0xe3)
ld.Adduint8(ld.Ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0x10)
ld.Adduint8(ld.Ctxt, plt, 0xf0) ld.Adduint8(ctxt, plt, 0xf0)
ld.Adduint8(ld.Ctxt, plt, 0x38) ld.Adduint8(ctxt, plt, 0x38)
ld.Adduint8(ld.Ctxt, plt, 0x00) ld.Adduint8(ctxt, plt, 0x00)
ld.Adduint8(ld.Ctxt, plt, 0x24) ld.Adduint8(ctxt, plt, 0x24)
// larl %r1,_GLOBAL_OFFSET_TABLE_ // larl %r1,_GLOBAL_OFFSET_TABLE_
ld.Adduint8(ld.Ctxt, plt, 0xc0) ld.Adduint8(ctxt, plt, 0xc0)
ld.Adduint8(ld.Ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0x10)
ld.Addpcrelplus(ld.Ctxt, plt, got, 6) ld.Addpcrelplus(ctxt, plt, got, 6)
// mvc 48(8,%r15),8(%r1) // mvc 48(8,%r15),8(%r1)
ld.Adduint8(ld.Ctxt, plt, 0xd2) ld.Adduint8(ctxt, plt, 0xd2)
ld.Adduint8(ld.Ctxt, plt, 0x07) ld.Adduint8(ctxt, plt, 0x07)
ld.Adduint8(ld.Ctxt, plt, 0xf0) ld.Adduint8(ctxt, plt, 0xf0)
ld.Adduint8(ld.Ctxt, plt, 0x30) ld.Adduint8(ctxt, plt, 0x30)
ld.Adduint8(ld.Ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0x10)
ld.Adduint8(ld.Ctxt, plt, 0x08) ld.Adduint8(ctxt, plt, 0x08)
// lg %r1,16(%r1) // lg %r1,16(%r1)
ld.Adduint8(ld.Ctxt, plt, 0xe3) ld.Adduint8(ctxt, plt, 0xe3)
ld.Adduint8(ld.Ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0x10)
ld.Adduint8(ld.Ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0x10)
ld.Adduint8(ld.Ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0x10)
ld.Adduint8(ld.Ctxt, plt, 0x00) ld.Adduint8(ctxt, plt, 0x00)
ld.Adduint8(ld.Ctxt, plt, 0x04) ld.Adduint8(ctxt, plt, 0x04)
// br %r1 // br %r1
ld.Adduint8(ld.Ctxt, plt, 0x07) ld.Adduint8(ctxt, plt, 0x07)
ld.Adduint8(ld.Ctxt, plt, 0xf1) ld.Adduint8(ctxt, plt, 0xf1)
// nopr %r0 // nopr %r0
ld.Adduint8(ld.Ctxt, plt, 0x07) ld.Adduint8(ctxt, plt, 0x07)
ld.Adduint8(ld.Ctxt, plt, 0x00) ld.Adduint8(ctxt, plt, 0x00)
// nopr %r0 // nopr %r0
ld.Adduint8(ld.Ctxt, plt, 0x07) ld.Adduint8(ctxt, plt, 0x07)
ld.Adduint8(ld.Ctxt, plt, 0x00) ld.Adduint8(ctxt, plt, 0x00)
// nopr %r0 // nopr %r0
ld.Adduint8(ld.Ctxt, plt, 0x07) ld.Adduint8(ctxt, plt, 0x07)
ld.Adduint8(ld.Ctxt, plt, 0x00) ld.Adduint8(ctxt, plt, 0x00)
// assume got->size == 0 too // assume got->size == 0 too
ld.Addaddrplus(ld.Ctxt, got, ld.Linklookup(ld.Ctxt, ".dynamic", 0), 0) ld.Addaddrplus(ctxt, got, ld.Linklookup(ctxt, ".dynamic", 0), 0)
ld.Adduint64(ld.Ctxt, got, 0) ld.Adduint64(ctxt, got, 0)
ld.Adduint64(ld.Ctxt, got, 0) ld.Adduint64(ctxt, got, 0)
} }
} }
func machoreloc1(r *ld.Reloc, sectoff int64) int { func machoreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
return -1 return -1
} }
func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
ctxt := ld.Ctxt
if ld.Linkmode == ld.LinkExternal { if ld.Linkmode == ld.LinkExternal {
return -1 return -1
} }
...@@ -392,17 +391,17 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -392,17 +391,17 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
return 0 return 0
case obj.R_GOTOFF: case obj.R_GOTOFF:
*val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ld.Ctxt, ".got", 0)) *val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ctxt, ".got", 0))
return 0 return 0
} }
return -1 return -1
} }
func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
switch r.Variant & ld.RV_TYPE_MASK { switch r.Variant & ld.RV_TYPE_MASK {
default: default:
ld.Ctxt.Diag("unexpected relocation variant %d", r.Variant) ctxt.Diag("unexpected relocation variant %d", r.Variant)
return t return t
case ld.RV_NONE: case ld.RV_NONE:
...@@ -410,7 +409,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { ...@@ -410,7 +409,7 @@ func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 {
case ld.RV_390_DBL: case ld.RV_390_DBL:
if (t & 1) != 0 { if (t & 1) != 0 {
ld.Ctxt.Diag("%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value) ctxt.Diag("%s+%v is not 2-byte aligned", r.Sym.Name, r.Sym.Value)
} }
return t >> 1 return t >> 1
} }
...@@ -428,7 +427,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { ...@@ -428,7 +427,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
got := ld.Linklookup(ctxt, ".got", 0) got := ld.Linklookup(ctxt, ".got", 0)
rela := ld.Linklookup(ctxt, ".rela.plt", 0) rela := ld.Linklookup(ctxt, ".rela.plt", 0)
if plt.Size == 0 { if plt.Size == 0 {
elfsetupplt() elfsetupplt(ctxt)
} }
// larl %r1,_GLOBAL_OFFSET_TABLE_+index // larl %r1,_GLOBAL_OFFSET_TABLE_+index
...@@ -475,27 +474,27 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { ...@@ -475,27 +474,27 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
s.Plt = int32(plt.Size - 32) s.Plt = int32(plt.Size - 32)
} else { } else {
ld.Ctxt.Diag("addpltsym: unsupported binary format") ctxt.Diag("addpltsym: unsupported binary format")
} }
} }
func addgotsym(s *ld.Symbol) { func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
if s.Got >= 0 { if s.Got >= 0 {
return return
} }
ld.Adddynsym(ld.Ctxt, s) ld.Adddynsym(ctxt, s)
got := ld.Linklookup(ld.Ctxt, ".got", 0) got := ld.Linklookup(ctxt, ".got", 0)
s.Got = int32(got.Size) s.Got = int32(got.Size)
ld.Adduint64(ld.Ctxt, got, 0) ld.Adduint64(ctxt, got, 0)
if ld.Iself { if ld.Iself {
rela := ld.Linklookup(ld.Ctxt, ".rela", 0) rela := ld.Linklookup(ctxt, ".rela", 0)
ld.Addaddrplus(ld.Ctxt, rela, got, int64(s.Got)) ld.Addaddrplus(ctxt, rela, got, int64(s.Got))
ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_GLOB_DAT)) ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_GLOB_DAT))
ld.Adduint64(ld.Ctxt, rela, 0) ld.Adduint64(ctxt, rela, 0)
} else { } else {
ld.Ctxt.Diag("addgotsym: unsupported binary format") ctxt.Diag("addgotsym: unsupported binary format")
} }
} }
...@@ -545,7 +544,7 @@ func asmb(ctxt *ld.Link) { ...@@ -545,7 +544,7 @@ func asmb(ctxt *ld.Link) {
symo := uint32(0) symo := uint32(0)
if ld.Debug['s'] == 0 { if ld.Debug['s'] == 0 {
if !ld.Iself { if !ld.Iself {
ld.Ctxt.Diag("unsupported executable format") ctxt.Diag("unsupported executable format")
} }
if ld.Debug['v'] != 0 { if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f sym\n", obj.Cputime()) fmt.Fprintf(ld.Bso, "%5.2f sym\n", obj.Cputime())
...@@ -571,7 +570,7 @@ func asmb(ctxt *ld.Link) { ...@@ -571,7 +570,7 @@ func asmb(ctxt *ld.Link) {
} }
} }
ld.Ctxt.Cursym = nil ctxt.Cursym = nil
if ld.Debug['v'] != 0 { if ld.Debug['v'] != 0 {
fmt.Fprintf(ld.Bso, "%5.2f header\n", obj.Cputime()) fmt.Fprintf(ld.Bso, "%5.2f header\n", obj.Cputime())
} }
...@@ -579,7 +578,7 @@ func asmb(ctxt *ld.Link) { ...@@ -579,7 +578,7 @@ func asmb(ctxt *ld.Link) {
ld.Cseek(0) ld.Cseek(0)
switch ld.HEADTYPE { switch ld.HEADTYPE {
default: default:
ld.Ctxt.Diag("unsupported operating system") ctxt.Diag("unsupported operating system")
case obj.Hlinux: case obj.Hlinux:
ld.Asmbelf(ctxt, int64(symo)) ld.Asmbelf(ctxt, int64(symo))
} }
......
...@@ -79,7 +79,7 @@ func linkarchinit() { ...@@ -79,7 +79,7 @@ func linkarchinit() {
ld.Thearch.Solarisdynld = "XXX" ld.Thearch.Solarisdynld = "XXX"
} }
func archinit() { func archinit(ctxt *ld.Link) {
// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
// Go was built; see ../../make.bash. // Go was built; see ../../make.bash.
if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" { if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" {
...@@ -95,7 +95,7 @@ func archinit() { ...@@ -95,7 +95,7 @@ func archinit() {
ld.Exitf("unknown -H option: %v", ld.HEADTYPE) ld.Exitf("unknown -H option: %v", ld.HEADTYPE)
case obj.Hlinux: // s390x ELF case obj.Hlinux: // s390x ELF
ld.Elfinit(ld.Ctxt) ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 { if ld.INITTEXT == -1 {
ld.INITTEXT = 0x10000 + int64(ld.HEADR) ld.INITTEXT = 0x10000 + int64(ld.HEADR)
......
...@@ -50,7 +50,7 @@ func addcall(ctxt *ld.Link, s *ld.Symbol, t *ld.Symbol) { ...@@ -50,7 +50,7 @@ func addcall(ctxt *ld.Link, s *ld.Symbol, t *ld.Symbol) {
r.Siz = 4 r.Siz = 4
} }
func gentext() { func gentext(ctxt *ld.Link) {
if !ld.DynlinkingGo() && ld.Buildmode != ld.BuildmodePIE && ld.Buildmode != ld.BuildmodeCShared { if !ld.DynlinkingGo() && ld.Buildmode != ld.BuildmodePIE && ld.Buildmode != ld.BuildmodeCShared {
return return
} }
...@@ -69,13 +69,13 @@ func gentext() { ...@@ -69,13 +69,13 @@ func gentext() {
{"si", 6}, {"si", 6},
{"di", 7}, {"di", 7},
} { } {
thunkfunc := ld.Linklookup(ld.Ctxt, "__x86.get_pc_thunk."+r.name, 0) thunkfunc := ld.Linklookup(ctxt, "__x86.get_pc_thunk."+r.name, 0)
thunkfunc.Type = obj.STEXT thunkfunc.Type = obj.STEXT
thunkfunc.Attr |= ld.AttrLocal thunkfunc.Attr |= ld.AttrLocal
thunkfunc.Attr |= ld.AttrReachable //TODO: remove? thunkfunc.Attr |= ld.AttrReachable //TODO: remove?
o := func(op ...uint8) { o := func(op ...uint8) {
for _, op1 := range op { for _, op1 := range op {
ld.Adduint8(ld.Ctxt, thunkfunc, op1) ld.Adduint8(ctxt, thunkfunc, op1)
} }
} }
// 8b 04 24 mov (%esp),%eax // 8b 04 24 mov (%esp),%eax
...@@ -84,10 +84,10 @@ func gentext() { ...@@ -84,10 +84,10 @@ func gentext() {
// c3 ret // c3 ret
o(0xc3) o(0xc3)
ld.Ctxt.Textp = append(ld.Ctxt.Textp, thunkfunc) ctxt.Textp = append(ctxt.Textp, thunkfunc)
} }
addmoduledata := ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) addmoduledata := ld.Linklookup(ctxt, "runtime.addmoduledata", 0)
if addmoduledata.Type == obj.STEXT { if addmoduledata.Type == obj.STEXT {
// we're linking a module containing the runtime -> no need for // we're linking a module containing the runtime -> no need for
// an init function // an init function
...@@ -96,20 +96,20 @@ func gentext() { ...@@ -96,20 +96,20 @@ func gentext() {
addmoduledata.Attr |= ld.AttrReachable addmoduledata.Attr |= ld.AttrReachable
initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0) initfunc := ld.Linklookup(ctxt, "go.link.addmoduledata", 0)
initfunc.Type = obj.STEXT initfunc.Type = obj.STEXT
initfunc.Attr |= ld.AttrLocal initfunc.Attr |= ld.AttrLocal
initfunc.Attr |= ld.AttrReachable initfunc.Attr |= ld.AttrReachable
o := func(op ...uint8) { o := func(op ...uint8) {
for _, op1 := range op { for _, op1 := range op {
ld.Adduint8(ld.Ctxt, initfunc, op1) ld.Adduint8(ctxt, initfunc, op1)
} }
} }
// go.link.addmoduledata: // go.link.addmoduledata:
// 53 push %ebx // 53 push %ebx
// e8 00 00 00 00 call __x86.get_pc_thunk.cx + R_CALL __x86.get_pc_thunk.cx // e8 00 00 00 00 call __x86.get_pc_thunk.cx + R_CALL __x86.get_pc_thunk.cx
// 8d 81 00 00 00 00 lea 0x0(%ecx), %eax + R_PCREL ld.Ctxt.Moduledata // 8d 81 00 00 00 00 lea 0x0(%ecx), %eax + R_PCREL ctxt.Moduledata
// 8d 99 00 00 00 00 lea 0x0(%ecx), %ebx + R_GOTPC _GLOBAL_OFFSET_TABLE_ // 8d 99 00 00 00 00 lea 0x0(%ecx), %ebx + R_GOTPC _GLOBAL_OFFSET_TABLE_
// e8 00 00 00 00 call runtime.addmoduledata@plt + R_CALL runtime.addmoduledata // e8 00 00 00 00 call runtime.addmoduledata@plt + R_CALL runtime.addmoduledata
// 5b pop %ebx // 5b pop %ebx
...@@ -118,55 +118,55 @@ func gentext() { ...@@ -118,55 +118,55 @@ func gentext() {
o(0x53) o(0x53)
o(0xe8) o(0xe8)
addcall(ld.Ctxt, initfunc, ld.Linklookup(ld.Ctxt, "__x86.get_pc_thunk.cx", 0)) addcall(ctxt, initfunc, ld.Linklookup(ctxt, "__x86.get_pc_thunk.cx", 0))
o(0x8d, 0x81) o(0x8d, 0x81)
ld.Addpcrelplus(ld.Ctxt, initfunc, ld.Ctxt.Moduledata, 6) ld.Addpcrelplus(ctxt, initfunc, ctxt.Moduledata, 6)
o(0x8d, 0x99) o(0x8d, 0x99)
i := initfunc.Size i := initfunc.Size
initfunc.Size += 4 initfunc.Size += 4
ld.Symgrow(ld.Ctxt, initfunc, initfunc.Size) ld.Symgrow(ctxt, initfunc, initfunc.Size)
r := ld.Addrel(initfunc) r := ld.Addrel(initfunc)
r.Sym = ld.Linklookup(ld.Ctxt, "_GLOBAL_OFFSET_TABLE_", 0) r.Sym = ld.Linklookup(ctxt, "_GLOBAL_OFFSET_TABLE_", 0)
r.Off = int32(i) r.Off = int32(i)
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Add = 12 r.Add = 12
r.Siz = 4 r.Siz = 4
o(0xe8) o(0xe8)
addcall(ld.Ctxt, initfunc, addmoduledata) addcall(ctxt, initfunc, addmoduledata)
o(0x5b) o(0x5b)
o(0xc3) o(0xc3)
ld.Ctxt.Textp = append(ld.Ctxt.Textp, initfunc) ctxt.Textp = append(ctxt.Textp, initfunc)
initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0) initarray_entry := ld.Linklookup(ctxt, "go.link.addmoduledatainit", 0)
initarray_entry.Attr |= ld.AttrReachable initarray_entry.Attr |= ld.AttrReachable
initarray_entry.Attr |= ld.AttrLocal initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = obj.SINITARR initarray_entry.Type = obj.SINITARR
ld.Addaddr(ld.Ctxt, initarray_entry, initfunc) ld.Addaddr(ctxt, initarray_entry, initfunc)
} }
func adddynrel(s *ld.Symbol, r *ld.Reloc) { func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) {
targ := r.Sym targ := r.Sym
ld.Ctxt.Cursym = s ctxt.Cursym = s
switch r.Type { switch r.Type {
default: default:
if r.Type >= 256 { if r.Type >= 256 {
ld.Ctxt.Diag("unexpected relocation type %d", r.Type) ctxt.Diag("unexpected relocation type %d", r.Type)
return return
} }
// Handle relocations found in ELF object files. // Handle relocations found in ELF object files.
case 256 + ld.R_386_PC32: case 256 + ld.R_386_PC32:
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
ld.Ctxt.Diag("unexpected R_386_PC32 relocation for dynamic symbol %s", targ.Name) ctxt.Diag("unexpected R_386_PC32 relocation for dynamic symbol %s", targ.Name)
} }
if targ.Type == 0 || targ.Type == obj.SXREF { if targ.Type == 0 || targ.Type == obj.SXREF {
ld.Ctxt.Diag("unknown symbol %s in pcrel", targ.Name) ctxt.Diag("unknown symbol %s in pcrel", targ.Name)
} }
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Add += 4 r.Add += 4
...@@ -176,8 +176,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -176,8 +176,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Add += 4 r.Add += 4
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
addpltsym(ld.Ctxt, targ) addpltsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) r.Sym = ld.Linklookup(ctxt, ".plt", 0)
r.Add += int64(targ.Plt) r.Add += int64(targ.Plt)
} }
...@@ -204,11 +204,11 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -204,11 +204,11 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
return return
} }
ld.Ctxt.Diag("unexpected GOT reloc for non-dynamic symbol %s", targ.Name) ctxt.Diag("unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
return return
} }
addgotsym(ld.Ctxt, targ) addgotsym(ctxt, targ)
r.Type = obj.R_CONST // write r->add during relocsym r.Type = obj.R_CONST // write r->add during relocsym
r.Sym = nil r.Sym = nil
r.Add += int64(targ.Got) r.Add += int64(targ.Got)
...@@ -220,13 +220,13 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -220,13 +220,13 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
case 256 + ld.R_386_GOTPC: case 256 + ld.R_386_GOTPC:
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0) r.Sym = ld.Linklookup(ctxt, ".got", 0)
r.Add += 4 r.Add += 4
return return
case 256 + ld.R_386_32: case 256 + ld.R_386_32:
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
ld.Ctxt.Diag("unexpected R_386_32 relocation for dynamic symbol %s", targ.Name) ctxt.Diag("unexpected R_386_32 relocation for dynamic symbol %s", targ.Name)
} }
r.Type = obj.R_ADDR r.Type = obj.R_ADDR
return return
...@@ -234,14 +234,14 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -234,14 +234,14 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 0: case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 0:
r.Type = obj.R_ADDR r.Type = obj.R_ADDR
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
ld.Ctxt.Diag("unexpected reloc for dynamic symbol %s", targ.Name) ctxt.Diag("unexpected reloc for dynamic symbol %s", targ.Name)
} }
return return
case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 1: case 512 + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 1:
if targ.Type == obj.SDYNIMPORT { if targ.Type == obj.SDYNIMPORT {
addpltsym(ld.Ctxt, targ) addpltsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) r.Sym = ld.Linklookup(ctxt, ".plt", 0)
r.Add = int64(targ.Plt) r.Add = int64(targ.Plt)
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
return return
...@@ -255,7 +255,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -255,7 +255,7 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
// have symbol // have symbol
// turn MOVL of GOT entry into LEAL of symbol itself // turn MOVL of GOT entry into LEAL of symbol itself
if r.Off < 2 || s.P[r.Off-2] != 0x8b { if r.Off < 2 || s.P[r.Off-2] != 0x8b {
ld.Ctxt.Diag("unexpected GOT reloc for non-dynamic symbol %s", targ.Name) ctxt.Diag("unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
return return
} }
...@@ -264,8 +264,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -264,8 +264,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
return return
} }
addgotsym(ld.Ctxt, targ) addgotsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".got", 0) r.Sym = ld.Linklookup(ctxt, ".got", 0)
r.Add += int64(targ.Got) r.Add += int64(targ.Got)
r.Type = obj.R_PCREL r.Type = obj.R_PCREL
return return
...@@ -279,8 +279,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -279,8 +279,8 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
switch r.Type { switch r.Type {
case obj.R_CALL, case obj.R_CALL,
obj.R_PCREL: obj.R_PCREL:
addpltsym(ld.Ctxt, targ) addpltsym(ctxt, targ)
r.Sym = ld.Linklookup(ld.Ctxt, ".plt", 0) r.Sym = ld.Linklookup(ctxt, ".plt", 0)
r.Add = int64(targ.Plt) r.Add = int64(targ.Plt)
return return
...@@ -289,10 +289,10 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -289,10 +289,10 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
break break
} }
if ld.Iself { if ld.Iself {
ld.Adddynsym(ld.Ctxt, targ) ld.Adddynsym(ctxt, targ)
rel := ld.Linklookup(ld.Ctxt, ".rel", 0) rel := ld.Linklookup(ctxt, ".rel", 0)
ld.Addaddrplus(ld.Ctxt, rel, s, int64(r.Off)) ld.Addaddrplus(ctxt, rel, s, int64(r.Off))
ld.Adduint32(ld.Ctxt, rel, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_386_32)) ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_386_32))
r.Type = obj.R_CONST // write r->add during relocsym r.Type = obj.R_CONST // write r->add during relocsym
r.Sym = nil r.Sym = nil
return return
...@@ -309,16 +309,16 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -309,16 +309,16 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
// just in case the C code assigns to the variable, // just in case the C code assigns to the variable,
// and of course it only works for single pointers, // and of course it only works for single pointers,
// but we only need to support cgo and that's all it needs. // but we only need to support cgo and that's all it needs.
ld.Adddynsym(ld.Ctxt, targ) ld.Adddynsym(ctxt, targ)
got := ld.Linklookup(ld.Ctxt, ".got", 0) got := ld.Linklookup(ctxt, ".got", 0)
s.Type = got.Type | obj.SSUB s.Type = got.Type | obj.SSUB
s.Outer = got s.Outer = got
s.Sub = got.Sub s.Sub = got.Sub
got.Sub = s got.Sub = s
s.Value = got.Size s.Value = got.Size
ld.Adduint32(ld.Ctxt, got, 0) ld.Adduint32(ctxt, got, 0)
ld.Adduint32(ld.Ctxt, ld.Linklookup(ld.Ctxt, ".linkedit.got", 0), uint32(targ.Dynid)) ld.Adduint32(ctxt, ld.Linklookup(ctxt, ".linkedit.got", 0), uint32(targ.Dynid))
r.Type = 256 // ignore during relocsym r.Type = 256 // ignore during relocsym
return return
} }
...@@ -329,11 +329,11 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) { ...@@ -329,11 +329,11 @@ func adddynrel(s *ld.Symbol, r *ld.Reloc) {
} }
} }
ld.Ctxt.Cursym = s ctxt.Cursym = s
ld.Ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type) ctxt.Diag("unsupported relocation for dynamic symbol %s (type=%d stype=%d)", targ.Name, r.Type, targ.Type)
} }
func elfreloc1(r *ld.Reloc, sectoff int64) int { func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
ld.Thearch.Lput(uint32(sectoff)) ld.Thearch.Lput(uint32(sectoff))
elfsym := r.Xsym.ElfsymForReloc() elfsym := r.Xsym.ElfsymForReloc()
...@@ -397,14 +397,14 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -397,14 +397,14 @@ func elfreloc1(r *ld.Reloc, sectoff int64) int {
return 0 return 0
} }
func machoreloc1(r *ld.Reloc, sectoff int64) int { func machoreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
var v uint32 var v uint32
rs := r.Xsym rs := r.Xsym
if rs.Type == obj.SHOSTOBJ { if rs.Type == obj.SHOSTOBJ {
if rs.Dynid < 0 { if rs.Dynid < 0 {
ld.Ctxt.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type) ctxt.Diag("reloc %d to non-macho symbol %s type=%d", r.Type, rs.Name, rs.Type)
return -1 return -1
} }
...@@ -413,7 +413,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -413,7 +413,7 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
} else { } else {
v = uint32(rs.Sect.Extnum) v = uint32(rs.Sect.Extnum)
if v == 0 { if v == 0 {
ld.Ctxt.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type) ctxt.Diag("reloc %d to symbol %s in non-macho section %s type=%d", r.Type, rs.Name, rs.Sect.Name, rs.Type)
return -1 return -1
} }
} }
...@@ -453,13 +453,13 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int { ...@@ -453,13 +453,13 @@ func machoreloc1(r *ld.Reloc, sectoff int64) int {
return 0 return 0
} }
func pereloc1(r *ld.Reloc, sectoff int64) bool { func pereloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
var v uint32 var v uint32
rs := r.Xsym rs := r.Xsym
if rs.Dynid < 0 { if rs.Dynid < 0 {
ld.Ctxt.Diag("reloc %d to non-coff symbol %s type=%d", r.Type, rs.Name, rs.Type) ctxt.Diag("reloc %d to non-coff symbol %s type=%d", r.Type, rs.Name, rs.Type)
return false return false
} }
...@@ -483,7 +483,7 @@ func pereloc1(r *ld.Reloc, sectoff int64) bool { ...@@ -483,7 +483,7 @@ func pereloc1(r *ld.Reloc, sectoff int64) bool {
return true return true
} }
func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
if ld.Linkmode == ld.LinkExternal { if ld.Linkmode == ld.LinkExternal {
return -1 return -1
} }
...@@ -493,42 +493,42 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int { ...@@ -493,42 +493,42 @@ func archreloc(r *ld.Reloc, s *ld.Symbol, val *int64) int {
return 0 return 0
case obj.R_GOTOFF: case obj.R_GOTOFF:
*val = ld.Symaddr(ld.Ctxt, r.Sym) + r.Add - ld.Symaddr(ld.Ctxt, ld.Linklookup(ld.Ctxt, ".got", 0)) *val = ld.Symaddr(ctxt, r.Sym) + r.Add - ld.Symaddr(ctxt, ld.Linklookup(ctxt, ".got", 0))
return 0 return 0
} }
return -1 return -1
} }
func archrelocvariant(r *ld.Reloc, s *ld.Symbol, t int64) int64 { func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
log.Fatalf("unexpected relocation variant") log.Fatalf("unexpected relocation variant")
return t return t
} }
func elfsetupplt() { func elfsetupplt(ctxt *ld.Link) {
plt := ld.Linklookup(ld.Ctxt, ".plt", 0) plt := ld.Linklookup(ctxt, ".plt", 0)
got := ld.Linklookup(ld.Ctxt, ".got.plt", 0) got := ld.Linklookup(ctxt, ".got.plt", 0)
if plt.Size == 0 { if plt.Size == 0 {
// pushl got+4 // pushl got+4
ld.Adduint8(ld.Ctxt, plt, 0xff) ld.Adduint8(ctxt, plt, 0xff)
ld.Adduint8(ld.Ctxt, plt, 0x35) ld.Adduint8(ctxt, plt, 0x35)
ld.Addaddrplus(ld.Ctxt, plt, got, 4) ld.Addaddrplus(ctxt, plt, got, 4)
// jmp *got+8 // jmp *got+8
ld.Adduint8(ld.Ctxt, plt, 0xff) ld.Adduint8(ctxt, plt, 0xff)
ld.Adduint8(ld.Ctxt, plt, 0x25) ld.Adduint8(ctxt, plt, 0x25)
ld.Addaddrplus(ld.Ctxt, plt, got, 8) ld.Addaddrplus(ctxt, plt, got, 8)
// zero pad // zero pad
ld.Adduint32(ld.Ctxt, plt, 0) ld.Adduint32(ctxt, plt, 0)
// assume got->size == 0 too // assume got->size == 0 too
ld.Addaddrplus(ld.Ctxt, got, ld.Linklookup(ld.Ctxt, ".dynamic", 0), 0) ld.Addaddrplus(ctxt, got, ld.Linklookup(ctxt, ".dynamic", 0), 0)
ld.Adduint32(ld.Ctxt, got, 0) ld.Adduint32(ctxt, got, 0)
ld.Adduint32(ld.Ctxt, got, 0) ld.Adduint32(ctxt, got, 0)
} }
} }
...@@ -544,7 +544,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { ...@@ -544,7 +544,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
got := ld.Linklookup(ctxt, ".got.plt", 0) got := ld.Linklookup(ctxt, ".got.plt", 0)
rel := ld.Linklookup(ctxt, ".rel.plt", 0) rel := ld.Linklookup(ctxt, ".rel.plt", 0)
if plt.Size == 0 { if plt.Size == 0 {
elfsetupplt() elfsetupplt(ctxt)
} }
// jmpq *got+size // jmpq *got+size
...@@ -588,7 +588,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) { ...@@ -588,7 +588,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
ld.Adduint8(ctxt, plt, 0x25) ld.Adduint8(ctxt, plt, 0x25)
ld.Addaddrplus(ctxt, plt, ld.Linklookup(ctxt, ".got", 0), int64(s.Got)) ld.Addaddrplus(ctxt, plt, ld.Linklookup(ctxt, ".got", 0), int64(s.Got))
} else { } else {
ld.Ctxt.Diag("addpltsym: unsupported binary format") ctxt.Diag("addpltsym: unsupported binary format")
} }
} }
...@@ -609,7 +609,7 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) { ...@@ -609,7 +609,7 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
} else if ld.HEADTYPE == obj.Hdarwin { } else if ld.HEADTYPE == obj.Hdarwin {
ld.Adduint32(ctxt, ld.Linklookup(ctxt, ".linkedit.got", 0), uint32(s.Dynid)) ld.Adduint32(ctxt, ld.Linklookup(ctxt, ".linkedit.got", 0), uint32(s.Dynid))
} else { } else {
ld.Ctxt.Diag("addgotsym: unsupported binary format") ctxt.Diag("addgotsym: unsupported binary format")
} }
} }
......
...@@ -78,7 +78,7 @@ func linkarchinit() { ...@@ -78,7 +78,7 @@ func linkarchinit() {
ld.Thearch.Solarisdynld = "/lib/ld.so.1" ld.Thearch.Solarisdynld = "/lib/ld.so.1"
} }
func archinit() { func archinit(ctxt *ld.Link) {
// getgoextlinkenabled is based on GO_EXTLINK_ENABLED when // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when
// Go was built; see ../../make.bash. // Go was built; see ../../make.bash.
if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" { if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" {
...@@ -87,7 +87,7 @@ func archinit() { ...@@ -87,7 +87,7 @@ func archinit() {
if ld.Buildmode == ld.BuildmodeCShared || ld.Buildmode == ld.BuildmodePIE || ld.DynlinkingGo() { if ld.Buildmode == ld.BuildmodeCShared || ld.Buildmode == ld.BuildmodePIE || ld.DynlinkingGo() {
ld.Linkmode = ld.LinkExternal ld.Linkmode = ld.LinkExternal
got := ld.Linklookup(ld.Ctxt, "_GLOBAL_OFFSET_TABLE_", 0) got := ld.Linklookup(ctxt, "_GLOBAL_OFFSET_TABLE_", 0)
got.Type = obj.SDYNIMPORT got.Type = obj.SDYNIMPORT
got.Attr |= ld.AttrReachable got.Attr |= ld.AttrReachable
} }
...@@ -145,7 +145,7 @@ func archinit() { ...@@ -145,7 +145,7 @@ func archinit() {
obj.Hfreebsd, obj.Hfreebsd,
obj.Hnetbsd, obj.Hnetbsd,
obj.Hopenbsd: obj.Hopenbsd:
ld.Elfinit(ld.Ctxt) ld.Elfinit(ctxt)
ld.HEADR = ld.ELFRESERVE ld.HEADR = ld.ELFRESERVE
if ld.INITTEXT == -1 { if ld.INITTEXT == -1 {
...@@ -159,7 +159,7 @@ func archinit() { ...@@ -159,7 +159,7 @@ func archinit() {
} }
case obj.Hnacl: case obj.Hnacl:
ld.Elfinit(ld.Ctxt) ld.Elfinit(ctxt)
ld.HEADR = 0x10000 ld.HEADR = 0x10000
ld.Funcalign = 32 ld.Funcalign = 32
if ld.INITTEXT == -1 { if ld.INITTEXT == -1 {
...@@ -173,7 +173,7 @@ func archinit() { ...@@ -173,7 +173,7 @@ func archinit() {
} }
case obj.Hwindows: /* PE executable */ case obj.Hwindows: /* PE executable */
ld.Peinit(ld.Ctxt) ld.Peinit(ctxt)
ld.HEADR = ld.PEFILEHEADR ld.HEADR = ld.PEFILEHEADR
if ld.INITTEXT == -1 { if ld.INITTEXT == -1 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment