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