Commit 03466644 authored by David Crawshaw's avatar David Crawshaw

cmd/link: convert symbol Add* functions to methods

Also reduce the passed context from *Link to *sys.Arch, so fewer
data dependencies need to be wired through all the code dealing
with symbols.

For #22095

Change-Id: I50969405d6562c5152bd1a3c443b72413e9b70bc
Reviewed-on: https://go-review.googlesource.com/67313
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 2e405bde
......@@ -46,8 +46,8 @@ func Addcall(ctxt *ld.Link, s *ld.Symbol, t *ld.Symbol) int64 {
s.Attr |= ld.AttrReachable
i := s.Size
s.Size += 4
ld.Symgrow(s, s.Size)
r := ld.Addrel(s)
s.Grow(s.Size)
r := s.AddRel()
r.Sym = t
r.Off = int32(i)
r.Type = objabi.R_CALL
......@@ -72,14 +72,14 @@ func gentext(ctxt *ld.Link) {
initfunc.Attr |= ld.AttrReachable
o := func(op ...uint8) {
for _, op1 := range op {
ld.Adduint8(ctxt, initfunc, op1)
initfunc.AddUint8(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(ctxt, initfunc, ctxt.Moduledata, 0)
initfunc.AddPCRelPlus(ctxt.Arch, 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)
......@@ -94,7 +94,7 @@ func gentext(ctxt *ld.Link) {
initarray_entry.Attr |= ld.AttrReachable
initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = ld.SINITARR
ld.Addaddr(ctxt, initarray_entry, initfunc)
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
......@@ -319,14 +319,14 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
// generated R_X86_RELATIVE instead.
ld.Adddynsym(ctxt, targ)
rela := ctxt.Syms.Lookup(".rela", 0)
ld.Addaddrplus(ctxt, rela, s, int64(r.Off))
rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
if r.Siz == 8 {
ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_X86_64_64))
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_X86_64_64))
} else {
// TODO: never happens, remove.
ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_X86_64_32))
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_X86_64_32))
}
ld.Adduint64(ctxt, rela, uint64(r.Add))
rela.AddUint64(ctxt.Arch, uint64(r.Add))
r.Type = 256 // ignore during relocsym
return true
}
......@@ -350,8 +350,8 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
s.Sub = got.Sub
got.Sub = s
s.Value = got.Size
ld.Adduint64(ctxt, got, 0)
ld.Adduint32(ctxt, ctxt.Syms.Lookup(".linkedit.got", 0), uint32(targ.Dynid))
got.AddUint64(ctxt.Arch, 0)
ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid))
r.Type = 256 // ignore during relocsym
return true
}
......@@ -537,25 +537,25 @@ func elfsetupplt(ctxt *ld.Link) {
got := ctxt.Syms.Lookup(".got.plt", 0)
if plt.Size == 0 {
// pushq got+8(IP)
ld.Adduint8(ctxt, plt, 0xff)
plt.AddUint8(0xff)
ld.Adduint8(ctxt, plt, 0x35)
ld.Addpcrelplus(ctxt, plt, got, 8)
plt.AddUint8(0x35)
plt.AddPCRelPlus(ctxt.Arch, got, 8)
// jmpq got+16(IP)
ld.Adduint8(ctxt, plt, 0xff)
plt.AddUint8(0xff)
ld.Adduint8(ctxt, plt, 0x25)
ld.Addpcrelplus(ctxt, plt, got, 16)
plt.AddUint8(0x25)
plt.AddPCRelPlus(ctxt.Arch, got, 16)
// nopl 0(AX)
ld.Adduint32(ctxt, plt, 0x00401f0f)
plt.AddUint32(ctxt.Arch, 0x00401f0f)
// assume got->size == 0 too
ld.Addaddrplus(ctxt, got, ctxt.Syms.Lookup(".dynamic", 0), 0)
got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
ld.Adduint64(ctxt, got, 0)
ld.Adduint64(ctxt, got, 0)
got.AddUint64(ctxt.Arch, 0)
got.AddUint64(ctxt.Arch, 0)
}
}
......@@ -575,29 +575,29 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
}
// jmpq *got+size(IP)
ld.Adduint8(ctxt, plt, 0xff)
plt.AddUint8(0xff)
ld.Adduint8(ctxt, plt, 0x25)
ld.Addpcrelplus(ctxt, plt, got, got.Size)
plt.AddUint8(0x25)
plt.AddPCRelPlus(ctxt.Arch, got, got.Size)
// add to got: pointer to current pos in plt
ld.Addaddrplus(ctxt, got, plt, plt.Size)
got.AddAddrPlus(ctxt.Arch, plt, plt.Size)
// pushq $x
ld.Adduint8(ctxt, plt, 0x68)
plt.AddUint8(0x68)
ld.Adduint32(ctxt, plt, uint32((got.Size-24-8)/8))
plt.AddUint32(ctxt.Arch, uint32((got.Size-24-8)/8))
// jmpq .plt
ld.Adduint8(ctxt, plt, 0xe9)
plt.AddUint8(0xe9)
ld.Adduint32(ctxt, plt, uint32(-(plt.Size + 4)))
plt.AddUint32(ctxt.Arch, uint32(-(plt.Size + 4)))
// rela
ld.Addaddrplus(ctxt, rela, got, got.Size-8)
rela.AddAddrPlus(ctxt.Arch, got, got.Size-8)
ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_JMP_SLOT))
ld.Adduint64(ctxt, rela, 0)
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_JMP_SLOT))
rela.AddUint64(ctxt.Arch, 0)
s.Plt = int32(plt.Size - 16)
} else if ld.Headtype == objabi.Hdarwin {
......@@ -614,14 +614,14 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
addgotsym(ctxt, s)
plt := ctxt.Syms.Lookup(".plt", 0)
ld.Adduint32(ctxt, ctxt.Syms.Lookup(".linkedit.plt", 0), uint32(s.Dynid))
ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
// jmpq *got+size(IP)
s.Plt = int32(plt.Size)
ld.Adduint8(ctxt, plt, 0xff)
ld.Adduint8(ctxt, plt, 0x25)
ld.Addpcrelplus(ctxt, plt, ctxt.Syms.Lookup(".got", 0), int64(s.Got))
plt.AddUint8(0xff)
plt.AddUint8(0x25)
plt.AddPCRelPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got))
} else {
ld.Errorf(s, "addpltsym: unsupported binary format")
}
......@@ -635,15 +635,15 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
ld.Adddynsym(ctxt, s)
got := ctxt.Syms.Lookup(".got", 0)
s.Got = int32(got.Size)
ld.Adduint64(ctxt, got, 0)
got.AddUint64(ctxt.Arch, 0)
if ld.Iself {
rela := ctxt.Syms.Lookup(".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)
rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_GLOB_DAT))
rela.AddUint64(ctxt.Arch, 0)
} else if ld.Headtype == objabi.Hdarwin {
ld.Adduint32(ctxt, ctxt.Syms.Lookup(".linkedit.got", 0), uint32(s.Dynid))
ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
} else {
ld.Errorf(s, "addgotsym: unsupported binary format")
}
......
......@@ -75,13 +75,13 @@ func gentext(ctxt *ld.Link) {
initfunc.Attr |= ld.AttrLocal
initfunc.Attr |= ld.AttrReachable
o := func(op uint32) {
ld.Adduint32(ctxt, initfunc, op)
initfunc.AddUint32(ctxt.Arch, op)
}
o(0xe59f0004)
o(0xe08f0000)
o(0xeafffffe)
rel := ld.Addrel(initfunc)
rel := initfunc.AddRel()
rel.Off = 8
rel.Siz = 4
rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
......@@ -89,7 +89,7 @@ func gentext(ctxt *ld.Link) {
rel.Add = 0xeafffffe // vomit
o(0x00000000)
rel = ld.Addrel(initfunc)
rel = initfunc.AddRel()
rel.Off = 12
rel.Siz = 4
rel.Sym = ctxt.Moduledata
......@@ -104,7 +104,7 @@ func gentext(ctxt *ld.Link) {
initarray_entry.Attr |= ld.AttrReachable
initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = ld.SINITARR
ld.Addaddr(ctxt, initarray_entry, initfunc)
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
// Preserve highest 8 bits of a, and do addition to lower 24-bit
......@@ -239,9 +239,9 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
if ld.Iself {
ld.Adddynsym(ctxt, targ)
rel := ctxt.Syms.Lookup(".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 = objabi.R_CONST // write r->add during relocsym
rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_ARM_GLOB_DAT)) // we need a nil + A dynamic reloc
r.Type = objabi.R_CONST // write r->add during relocsym
r.Sym = nil
return true
}
......@@ -299,25 +299,25 @@ func elfsetupplt(ctxt *ld.Link) {
got := ctxt.Syms.Lookup(".got.plt", 0)
if plt.Size == 0 {
// str lr, [sp, #-4]!
ld.Adduint32(ctxt, plt, 0xe52de004)
plt.AddUint32(ctxt.Arch, 0xe52de004)
// ldr lr, [pc, #4]
ld.Adduint32(ctxt, plt, 0xe59fe004)
plt.AddUint32(ctxt.Arch, 0xe59fe004)
// add lr, pc, lr
ld.Adduint32(ctxt, plt, 0xe08fe00e)
plt.AddUint32(ctxt.Arch, 0xe08fe00e)
// ldr pc, [lr, #8]!
ld.Adduint32(ctxt, plt, 0xe5bef008)
plt.AddUint32(ctxt.Arch, 0xe5bef008)
// .word &GLOBAL_OFFSET_TABLE[0] - .
ld.Addpcrelplus(ctxt, plt, got, 4)
plt.AddPCRelPlus(ctxt.Arch, got, 4)
// the first .plt entry requires 3 .plt.got entries
ld.Adduint32(ctxt, got, 0)
got.AddUint32(ctxt.Arch, 0)
ld.Adduint32(ctxt, got, 0)
ld.Adduint32(ctxt, got, 0)
got.AddUint32(ctxt.Arch, 0)
got.AddUint32(ctxt.Arch, 0)
}
}
......@@ -492,7 +492,7 @@ func gentramp(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
arch.ByteOrder.PutUint32(tramp.P[8:], o3)
if ld.Linkmode == ld.LinkExternal {
r := ld.Addrel(tramp)
r := tramp.AddRel()
r.Off = 8
r.Type = objabi.R_ADDR
r.Siz = 4
......@@ -514,7 +514,7 @@ func gentramppic(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
arch.ByteOrder.PutUint32(tramp.P[8:], o3)
arch.ByteOrder.PutUint32(tramp.P[12:], o4)
r := ld.Addrel(tramp)
r := tramp.AddRel()
r.Off = 12
r.Type = objabi.R_PCREL
r.Siz = 4
......@@ -549,7 +549,7 @@ func gentrampdyn(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
arch.ByteOrder.PutUint32(tramp.P[20:], o6)
}
r := ld.Addrel(tramp)
r := tramp.AddRel()
r.Off = 16
r.Type = objabi.R_GOTPCREL
r.Siz = 4
......@@ -648,7 +648,7 @@ func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
}
func addpltreloc(ctxt *ld.Link, plt *ld.Symbol, got *ld.Symbol, sym *ld.Symbol, typ objabi.RelocType) *ld.Reloc {
r := ld.Addrel(plt)
r := plt.AddRel()
r.Sym = got
r.Off = int32(plt.Size)
r.Siz = 4
......@@ -657,7 +657,7 @@ func addpltreloc(ctxt *ld.Link, plt *ld.Symbol, got *ld.Symbol, sym *ld.Symbol,
plt.Attr |= ld.AttrReachable
plt.Size += 4
ld.Symgrow(plt, plt.Size)
plt.Grow(plt.Size)
return r
}
......@@ -683,7 +683,7 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
// In theory, all GOT should point to the first PLT entry,
// Linux/ARM's dynamic linker will do that for us, but FreeBSD/ARM's
// dynamic linker won't, so we'd better do it ourselves.
ld.Addaddrplus(ctxt, got, plt, 0)
got.AddAddrPlus(ctxt.Arch, plt, 0)
// .plt entry, this depends on the .got entry
s.Plt = int32(plt.Size)
......@@ -693,9 +693,9 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
addpltreloc(ctxt, plt, got, s, objabi.R_PLT2) // ldr pc, [lr, #0xZZZ]!
// rel
ld.Addaddrplus(ctxt, rel, got, int64(s.Got))
rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_JUMP_SLOT))
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_JUMP_SLOT))
} else {
ld.Errorf(s, "addpltsym: unsupported binary format")
}
......@@ -709,7 +709,7 @@ func addgotsyminternal(ctxt *ld.Link, s *ld.Symbol) {
got := ctxt.Syms.Lookup(".got", 0)
s.Got = int32(got.Size)
ld.Addaddrplus(ctxt, got, s, 0)
got.AddAddrPlus(ctxt.Arch, s, 0)
if ld.Iself {
} else {
......@@ -725,12 +725,12 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
ld.Adddynsym(ctxt, s)
got := ctxt.Syms.Lookup(".got", 0)
s.Got = int32(got.Size)
ld.Adduint32(ctxt, got, 0)
got.AddUint32(ctxt.Arch, 0)
if ld.Iself {
rel := ctxt.Syms.Lookup(".rel", 0)
ld.Addaddrplus(ctxt, rel, got, int64(s.Got))
ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_GLOB_DAT))
rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_GLOB_DAT))
} else {
ld.Errorf(s, "addgotsym: unsupported binary format")
}
......
......@@ -55,7 +55,7 @@ func gentext(ctxt *ld.Link) {
initfunc.Attr |= ld.AttrLocal
initfunc.Attr |= ld.AttrReachable
o := func(op uint32) {
ld.Adduint32(ctxt, initfunc, op)
initfunc.AddUint32(ctxt.Arch, op)
}
// 0000000000000000 <local.dso_init>:
// 0: 90000000 adrp x0, 0 <runtime.firstmoduledata>
......@@ -64,7 +64,7 @@ func gentext(ctxt *ld.Link) {
// 4: R_AARCH64_ADD_ABS_LO12_NC local.moduledata
o(0x90000000)
o(0x91000000)
rel := ld.Addrel(initfunc)
rel := initfunc.AddRel()
rel.Off = 0
rel.Siz = 8
rel.Sym = ctxt.Moduledata
......@@ -73,7 +73,7 @@ func gentext(ctxt *ld.Link) {
// 8: 14000000 bl 0 <runtime.addmoduledata>
// 8: R_AARCH64_CALL26 runtime.addmoduledata
o(0x14000000)
rel = ld.Addrel(initfunc)
rel = initfunc.AddRel()
rel.Off = 8
rel.Siz = 4
rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
......@@ -84,7 +84,7 @@ func gentext(ctxt *ld.Link) {
initarray_entry.Attr |= ld.AttrReachable
initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = ld.SINITARR
ld.Addaddr(ctxt, initarray_entry, initfunc)
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
......
......@@ -44,203 +44,6 @@ import (
"sync"
)
func Symgrow(s *Symbol, siz int64) {
if int64(int(siz)) != siz {
log.Fatalf("symgrow size %d too long", siz)
}
if int64(len(s.P)) >= siz {
return
}
if cap(s.P) < int(siz) {
p := make([]byte, 2*(siz+1))
s.P = append(p[:0], s.P...)
}
s.P = s.P[:siz]
}
func Addrel(s *Symbol) *Reloc {
s.R = append(s.R, Reloc{})
return &s.R[len(s.R)-1]
}
func setuintxx(ctxt *Link, s *Symbol, off int64, v uint64, wid int64) int64 {
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
if s.Size < off+wid {
s.Size = off + wid
Symgrow(s, s.Size)
}
switch wid {
case 1:
s.P[off] = uint8(v)
case 2:
ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(v))
case 4:
ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(v))
case 8:
ctxt.Arch.ByteOrder.PutUint64(s.P[off:], v)
}
return off + wid
}
func Addbytes(s *Symbol, bytes []byte) int64 {
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
s.P = append(s.P, bytes...)
s.Size = int64(len(s.P))
return s.Size
}
func adduintxx(ctxt *Link, s *Symbol, v uint64, wid int) int64 {
off := s.Size
setuintxx(ctxt, s, off, v, int64(wid))
return off
}
func Adduint8(ctxt *Link, s *Symbol, v uint8) int64 {
off := s.Size
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
s.Size++
s.P = append(s.P, v)
return off
}
func Adduint16(ctxt *Link, s *Symbol, v uint16) int64 {
return adduintxx(ctxt, s, uint64(v), 2)
}
func Adduint32(ctxt *Link, s *Symbol, v uint32) int64 {
return adduintxx(ctxt, s, uint64(v), 4)
}
func Adduint64(ctxt *Link, s *Symbol, v uint64) int64 {
return adduintxx(ctxt, s, v, 8)
}
func adduint(ctxt *Link, s *Symbol, v uint64) int64 {
return adduintxx(ctxt, s, v, ctxt.Arch.PtrSize)
}
func setuint8(ctxt *Link, s *Symbol, r int64, v uint8) int64 {
return setuintxx(ctxt, s, r, uint64(v), 1)
}
func setuint32(ctxt *Link, s *Symbol, r int64, v uint32) int64 {
return setuintxx(ctxt, s, r, uint64(v), 4)
}
func setuint(ctxt *Link, s *Symbol, r int64, v uint64) int64 {
return setuintxx(ctxt, s, r, v, int64(ctxt.Arch.PtrSize))
}
func Addaddrplus(ctxt *Link, s *Symbol, t *Symbol, add int64) int64 {
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
i := s.Size
s.Size += int64(ctxt.Arch.PtrSize)
Symgrow(s, s.Size)
r := Addrel(s)
r.Sym = t
r.Off = int32(i)
r.Siz = uint8(ctxt.Arch.PtrSize)
r.Type = objabi.R_ADDR
r.Add = add
return i + int64(r.Siz)
}
func Addpcrelplus(ctxt *Link, s *Symbol, t *Symbol, add int64) int64 {
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
i := s.Size
s.Size += 4
Symgrow(s, s.Size)
r := Addrel(s)
r.Sym = t
r.Off = int32(i)
r.Add = add
r.Type = objabi.R_PCREL
r.Siz = 4
if ctxt.Arch.Family == sys.S390X {
r.Variant = RV_390_DBL
}
return i + int64(r.Siz)
}
func Addaddr(ctxt *Link, s *Symbol, t *Symbol) int64 {
return Addaddrplus(ctxt, s, t, 0)
}
func setaddrplus(ctxt *Link, s *Symbol, off int64, t *Symbol, add int64) int64 {
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
if off+int64(ctxt.Arch.PtrSize) > s.Size {
s.Size = off + int64(ctxt.Arch.PtrSize)
Symgrow(s, s.Size)
}
r := Addrel(s)
r.Sym = t
r.Off = int32(off)
r.Siz = uint8(ctxt.Arch.PtrSize)
r.Type = objabi.R_ADDR
r.Add = add
return off + int64(r.Siz)
}
func setaddr(ctxt *Link, s *Symbol, off int64, t *Symbol) int64 {
return setaddrplus(ctxt, s, off, t, 0)
}
func addsize(ctxt *Link, s *Symbol, t *Symbol) int64 {
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
i := s.Size
s.Size += int64(ctxt.Arch.PtrSize)
Symgrow(s, s.Size)
r := Addrel(s)
r.Sym = t
r.Off = int32(i)
r.Siz = uint8(ctxt.Arch.PtrSize)
r.Type = objabi.R_SIZE
return i + int64(r.Siz)
}
func addaddrplus4(ctxt *Link, s *Symbol, t *Symbol, add int64) int64 {
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
i := s.Size
s.Size += 4
Symgrow(s, s.Size)
r := Addrel(s)
r.Sym = t
r.Off = int32(i)
r.Siz = 4
r.Type = objabi.R_ADDR
r.Add = add
return i + int64(r.Siz)
}
/*
* divide-and-conquer list-link (by Sub) sort of Symbol* by Value.
* Used for sub-symbols when loading host objects (see e.g. ldelf.go).
......@@ -774,17 +577,17 @@ func windynrelocsym(ctxt *Link, s *Symbol) {
// jmp *addr
if ctxt.Arch.Family == sys.I386 {
Adduint8(ctxt, rel, 0xff)
Adduint8(ctxt, rel, 0x25)
Addaddr(ctxt, rel, targ)
Adduint8(ctxt, rel, 0x90)
Adduint8(ctxt, rel, 0x90)
rel.AddUint8(0xff)
rel.AddUint8(0x25)
rel.AddAddr(ctxt.Arch, targ)
rel.AddUint8(0x90)
rel.AddUint8(0x90)
} else {
Adduint8(ctxt, rel, 0xff)
Adduint8(ctxt, rel, 0x24)
Adduint8(ctxt, rel, 0x25)
addaddrplus4(ctxt, rel, targ, 0)
Adduint8(ctxt, rel, 0x90)
rel.AddUint8(0xff)
rel.AddUint8(0x24)
rel.AddUint8(0x25)
rel.AddAddrPlus4(targ, 0)
rel.AddUint8(0x90)
}
} else if r.Sym.Plt >= 0 {
r.Sym = rel
......@@ -1063,8 +866,8 @@ func addstrdata(ctxt *Link, name string, value string) {
s.Size = 0
s.Attr |= AttrDuplicateOK
reachable := s.Attr.Reachable()
Addaddr(ctxt, s, sp)
adduintxx(ctxt, s, uint64(len(value)), ctxt.Arch.PtrSize)
s.AddAddr(ctxt.Arch, sp)
s.AddUint(ctxt.Arch, uint64(len(value)))
// addstring, addaddr, etc., mark the symbols as reachable.
// In this case that is not necessarily true, so stick to what
......@@ -1113,8 +916,8 @@ func addgostring(ctxt *Link, s *Symbol, symname, str string) {
sym.Type = SRODATA
sym.Size = int64(len(str))
sym.P = []byte(str)
Addaddr(ctxt, s, sym)
adduint(ctxt, s, uint64(len(str)))
s.AddAddr(ctxt.Arch, sym)
s.AddUint(ctxt.Arch, uint64(len(str)))
}
func addinitarrdata(ctxt *Link, s *Symbol) {
......@@ -1123,7 +926,7 @@ func addinitarrdata(ctxt *Link, s *Symbol) {
sp.Type = SINITARR
sp.Size = 0
sp.Attr |= AttrDuplicateOK
Addaddr(ctxt, sp, s)
sp.AddAddr(ctxt.Arch, s)
}
func dosymtype(ctxt *Link) {
......@@ -1183,7 +986,7 @@ func (p *GCProg) Init(ctxt *Link, name string) {
func (p *GCProg) writeByte(ctxt *Link) func(x byte) {
return func(x byte) {
Adduint8(ctxt, p.sym, x)
p.sym.AddUint8(x)
}
}
......
This diff is collapsed.
......@@ -1177,11 +1177,11 @@ func elfhash(name string) uint32 {
func Elfwritedynent(ctxt *Link, s *Symbol, tag int, val uint64) {
if elf64 {
Adduint64(ctxt, s, uint64(tag))
Adduint64(ctxt, s, val)
s.AddUint64(ctxt.Arch, uint64(tag))
s.AddUint64(ctxt.Arch, val)
} else {
Adduint32(ctxt, s, uint32(tag))
Adduint32(ctxt, s, uint32(val))
s.AddUint32(ctxt.Arch, uint32(tag))
s.AddUint32(ctxt.Arch, uint32(val))
}
}
......@@ -1191,20 +1191,20 @@ func elfwritedynentsym(ctxt *Link, s *Symbol, tag int, t *Symbol) {
func Elfwritedynentsymplus(ctxt *Link, s *Symbol, tag int, t *Symbol, add int64) {
if elf64 {
Adduint64(ctxt, s, uint64(tag))
s.AddUint64(ctxt.Arch, uint64(tag))
} else {
Adduint32(ctxt, s, uint32(tag))
s.AddUint32(ctxt.Arch, uint32(tag))
}
Addaddrplus(ctxt, s, t, add)
s.AddAddrPlus(ctxt.Arch, t, add)
}
func elfwritedynentsymsize(ctxt *Link, s *Symbol, tag int, t *Symbol) {
if elf64 {
Adduint64(ctxt, s, uint64(tag))
s.AddUint64(ctxt.Arch, uint64(tag))
} else {
Adduint32(ctxt, s, uint32(tag))
s.AddUint32(ctxt.Arch, uint32(tag))
}
addsize(ctxt, s, t)
s.AddSize(ctxt.Arch, t)
}
func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
......@@ -1480,22 +1480,22 @@ func elfdynhash(ctxt *Link) {
// s390x (ELF64) hash table entries are 8 bytes
if ctxt.Arch.Family == sys.S390X {
Adduint64(ctxt, s, uint64(nbucket))
Adduint64(ctxt, s, uint64(nsym))
s.AddUint64(ctxt.Arch, uint64(nbucket))
s.AddUint64(ctxt.Arch, uint64(nsym))
for i := 0; i < nbucket; i++ {
Adduint64(ctxt, s, uint64(buckets[i]))
s.AddUint64(ctxt.Arch, uint64(buckets[i]))
}
for i := 0; i < nsym; i++ {
Adduint64(ctxt, s, uint64(chain[i]))
s.AddUint64(ctxt.Arch, uint64(chain[i]))
}
} else {
Adduint32(ctxt, s, uint32(nbucket))
Adduint32(ctxt, s, uint32(nsym))
s.AddUint32(ctxt.Arch, uint32(nbucket))
s.AddUint32(ctxt.Arch, uint32(nsym))
for i := 0; i < nbucket; i++ {
Adduint32(ctxt, s, buckets[i])
s.AddUint32(ctxt.Arch, buckets[i])
}
for i := 0; i < nsym; i++ {
Adduint32(ctxt, s, chain[i])
s.AddUint32(ctxt.Arch, chain[i])
}
}
......@@ -1509,18 +1509,18 @@ func elfdynhash(ctxt *Link) {
nfile++
// header
Adduint16(ctxt, s, 1) // table version
s.AddUint16(ctxt.Arch, 1) // table version
j := 0
for x := l.aux; x != nil; x = x.next {
j++
}
Adduint16(ctxt, s, uint16(j)) // aux count
Adduint32(ctxt, s, uint32(Addstring(dynstr, l.file))) // file string offset
Adduint32(ctxt, s, 16) // offset from header to first aux
s.AddUint16(ctxt.Arch, uint16(j)) // aux count
s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, l.file))) // file string offset
s.AddUint32(ctxt.Arch, 16) // offset from header to first aux
if l.next != nil {
Adduint32(ctxt, s, 16+uint32(j)*16) // offset from this header to next
s.AddUint32(ctxt.Arch, 16+uint32(j)*16) // offset from this header to next
} else {
Adduint32(ctxt, s, 0)
s.AddUint32(ctxt.Arch, 0)
}
for x := l.aux; x != nil; x = x.next {
......@@ -1528,14 +1528,14 @@ func elfdynhash(ctxt *Link) {
i++
// aux struct
Adduint32(ctxt, s, elfhash(x.vers)) // hash
Adduint16(ctxt, s, 0) // flags
Adduint16(ctxt, s, uint16(x.num)) // other - index we refer to this by
Adduint32(ctxt, s, uint32(Addstring(dynstr, x.vers))) // version string offset
s.AddUint32(ctxt.Arch, elfhash(x.vers)) // hash
s.AddUint16(ctxt.Arch, 0) // flags
s.AddUint16(ctxt.Arch, uint16(x.num)) // other - index we refer to this by
s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, x.vers))) // version string offset
if x.next != nil {
Adduint32(ctxt, s, 16) // offset from this aux to next
s.AddUint32(ctxt.Arch, 16) // offset from this aux to next
} else {
Adduint32(ctxt, s, 0)
s.AddUint32(ctxt.Arch, 0)
}
}
}
......@@ -1545,11 +1545,11 @@ func elfdynhash(ctxt *Link) {
for i := 0; i < nsym; i++ {
if i == 0 {
Adduint16(ctxt, s, 0) // first entry - no symbol
s.AddUint16(ctxt.Arch, 0) // first entry - no symbol
} else if need[i] == nil {
Adduint16(ctxt, s, 1) // global
s.AddUint16(ctxt.Arch, 1) // global
} else {
Adduint16(ctxt, s, uint16(need[i].num))
s.AddUint16(ctxt.Arch, uint16(need[i].num))
}
}
......@@ -1840,11 +1840,11 @@ func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
s.Attr |= AttrReachable
s.Type = SELFROSECT
// namesz
Adduint32(ctxt, s, uint32(len(ELF_NOTE_GO_NAME)))
s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME)))
// descsz
Adduint32(ctxt, s, uint32(len(desc)))
s.AddUint32(ctxt.Arch, uint32(len(desc)))
// tag
Adduint32(ctxt, s, tag)
s.AddUint32(ctxt.Arch, tag)
// name + padding
s.P = append(s.P, ELF_NOTE_GO_NAME...)
for len(s.P)%4 != 0 {
......@@ -2690,7 +2690,7 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
d := ctxt.Syms.Lookup(".dynsym", 0)
name := s.Extname
Adduint32(ctxt, d, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
/* type */
t := STB_GLOBAL << 4
......@@ -2700,27 +2700,27 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
} else {
t |= STT_OBJECT
}
Adduint8(ctxt, d, uint8(t))
d.AddUint8(uint8(t))
/* reserved */
Adduint8(ctxt, d, 0)
d.AddUint8(0)
/* section where symbol is defined */
if s.Type == SDYNIMPORT {
Adduint16(ctxt, d, SHN_UNDEF)
d.AddUint16(ctxt.Arch, SHN_UNDEF)
} else {
Adduint16(ctxt, d, 1)
d.AddUint16(ctxt.Arch, 1)
}
/* value */
if s.Type == SDYNIMPORT {
Adduint64(ctxt, d, 0)
d.AddUint64(ctxt.Arch, 0)
} else {
Addaddr(ctxt, d, s)
d.AddAddr(ctxt.Arch, s)
}
/* size of object */
Adduint64(ctxt, d, uint64(s.Size))
d.AddUint64(ctxt.Arch, uint64(s.Size))
if ctxt.Arch.Family == sys.AMD64 && !s.Attr.CgoExportDynamic() && s.Dynimplib != "" && !seenlib[s.Dynimplib] {
Elfwritedynent(ctxt, ctxt.Syms.Lookup(".dynamic", 0), DT_NEEDED, uint64(Addstring(ctxt.Syms.Lookup(".dynstr", 0), s.Dynimplib)))
......@@ -2734,17 +2734,17 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
/* name */
name := s.Extname
Adduint32(ctxt, d, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
d.AddUint32(ctxt.Arch, uint32(Addstring(ctxt.Syms.Lookup(".dynstr", 0), name)))
/* value */
if s.Type == SDYNIMPORT {
Adduint32(ctxt, d, 0)
d.AddUint32(ctxt.Arch, 0)
} else {
Addaddr(ctxt, d, s)
d.AddAddr(ctxt.Arch, s)
}
/* size of object */
Adduint32(ctxt, d, uint32(s.Size))
d.AddUint32(ctxt.Arch, uint32(s.Size))
/* type */
t := STB_GLOBAL << 4
......@@ -2757,14 +2757,14 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
} else {
t |= STT_OBJECT
}
Adduint8(ctxt, d, uint8(t))
Adduint8(ctxt, d, 0)
d.AddUint8(uint8(t))
d.AddUint8(0)
/* shndx */
if s.Type == SDYNIMPORT {
Adduint16(ctxt, d, SHN_UNDEF)
d.AddUint16(ctxt.Arch, SHN_UNDEF)
} else {
Adduint16(ctxt, d, 1)
d.AddUint16(ctxt.Arch, 1)
}
}
}
......
......@@ -359,11 +359,11 @@ func (ctxt *Link) loadlib() {
case BuildmodeCShared, BuildmodePlugin:
s := ctxt.Syms.Lookup("runtime.islibrary", 0)
s.Attr |= AttrDuplicateOK
Adduint8(ctxt, s, 1)
s.AddUint8(1)
case BuildmodeCArchive:
s := ctxt.Syms.Lookup("runtime.isarchive", 0)
s.Attr |= AttrDuplicateOK
Adduint8(ctxt, s, 1)
s.AddUint8(1)
}
loadinternal(ctxt, "runtime")
......@@ -485,14 +485,14 @@ func (ctxt *Link) loadlib() {
s := ctxt.Syms.Lookup("runtime.goarm", 0)
s.Type = SRODATA
s.Size = 0
Adduint8(ctxt, s, uint8(objabi.GOARM))
s.AddUint8(uint8(objabi.GOARM))
}
if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0)
s.Type = SRODATA
s.Size = 0
Adduint8(ctxt, s, 1)
s.AddUint8(1)
}
} else {
// If OTOH the module does not contain the runtime package,
......
......@@ -38,61 +38,6 @@ import (
"fmt"
)
// Symbol is an entry in the symbol table.
type Symbol struct {
Name string
Extname string
Type SymKind
Version int16
Attr Attribute
Localentry uint8
Dynid int32
Plt int32
Got int32
Align int32
Elfsym int32
LocalElfsym int32
Value int64
Size int64
// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
// is not set for symbols defined by the packages being linked or by symbols
// read by ldelf (and so is left as elf.STT_NOTYPE).
ElfType elf.SymType
Sub *Symbol
Outer *Symbol
Gotype *Symbol
Reachparent *Symbol
File string
Dynimplib string
Dynimpvers string
Sect *Section
FuncInfo *FuncInfo
// P contains the raw symbol data.
P []byte
R []Reloc
}
func (s *Symbol) String() string {
if s.Version == 0 {
return s.Name
}
return fmt.Sprintf("%s<%d>", s.Name, s.Version)
}
func (s *Symbol) ElfsymForReloc() int32 {
// If putelfsym created a local version of this symbol, use that in all
// relocations.
if s.LocalElfsym != 0 {
return s.LocalElfsym
} else {
return s.Elfsym
}
}
func (s *Symbol) Len() int64 {
return s.Size
}
// Attribute is a set of common symbol attributes.
type Attribute int16
......
......@@ -348,8 +348,8 @@ func (ctxt *Link) domacho() {
s.Type = SMACHOSYMSTR
s.Attr |= AttrReachable
Adduint8(ctxt, s, ' ')
Adduint8(ctxt, s, '\x00')
s.AddUint8(' ')
s.AddUint8('\x00')
s = ctxt.Syms.Lookup(".machosymtab", 0)
s.Type = SMACHOSYMTAB
......@@ -761,7 +761,7 @@ func machosymtab(ctxt *Link) {
for i := 0; i < nsortsym; i++ {
s := sortsym[i]
Adduint32(ctxt, symtab, uint32(symstr.Size))
symtab.AddUint32(ctxt.Arch, uint32(symstr.Size))
export := machoShouldExport(ctxt, s)
......@@ -774,22 +774,22 @@ func machosymtab(ctxt *Link) {
// See Issue #18190.
cexport := !strings.Contains(s.Extname, ".") && (Buildmode != BuildmodePlugin || onlycsymbol(s))
if cexport || export {
Adduint8(ctxt, symstr, '_')
symstr.AddUint8('_')
}
// replace "·" as ".", because DTrace cannot handle it.
Addstring(symstr, strings.Replace(s.Extname, "·", ".", -1))
if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ {
Adduint8(ctxt, symtab, 0x01) // type N_EXT, external symbol
Adduint8(ctxt, symtab, 0) // no section
Adduint16(ctxt, symtab, 0) // desc
adduintxx(ctxt, symtab, 0, ctxt.Arch.PtrSize) // no value
symtab.AddUint8(0x01) // type N_EXT, external symbol
symtab.AddUint8(0) // no section
symtab.AddUint16(ctxt.Arch, 0) // desc
symtab.addUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) // no value
} else {
if s.Attr.CgoExport() || export {
Adduint8(ctxt, symtab, 0x0f)
symtab.AddUint8(0x0f)
} else {
Adduint8(ctxt, symtab, 0x0e)
symtab.AddUint8(0x0e)
}
o := s
for o.Outer != nil {
......@@ -797,12 +797,12 @@ func machosymtab(ctxt *Link) {
}
if o.Sect == nil {
Errorf(s, "missing section for symbol")
Adduint8(ctxt, symtab, 0)
symtab.AddUint8(0)
} else {
Adduint8(ctxt, symtab, uint8(o.Sect.Extnum))
symtab.AddUint8(uint8(o.Sect.Extnum))
}
Adduint16(ctxt, symtab, 0) // desc
adduintxx(ctxt, symtab, uint64(Symaddr(s)), ctxt.Arch.PtrSize)
symtab.AddUint16(ctxt.Arch, 0) // desc
symtab.addUintXX(ctxt.Arch, uint64(Symaddr(s)), ctxt.Arch.PtrSize)
}
}
}
......@@ -871,7 +871,7 @@ func Domacholink(ctxt *Link) int64 {
// any alignment padding itself, working around the
// issue.
for s4.Size%16 != 0 {
Adduint8(ctxt, s4, 0)
s4.AddUint8(0)
}
size := int(s1.Size + s2.Size + s3.Size + s4.Size)
......
......@@ -404,9 +404,9 @@ func (r *objReader) readRef() {
if uint64(uint32(x)) != x {
log.Panicf("$-symbol %s too large: %d", s.Name, x)
}
Adduint32(r.ctxt, s, uint32(x))
s.AddUint32(r.ctxt.Arch, uint32(x))
case "$f64.", "$i64.":
Adduint64(r.ctxt, s, x)
s.AddUint64(r.ctxt.Arch, x)
default:
log.Panicf("unrecognized $-symbol: %s", s.Name)
}
......
......@@ -96,15 +96,15 @@ func addpctab(ctxt *Link, ftab *Symbol, off int32, d *Pcdata) int32 {
var start int32
if len(d.P) > 0 {
start = int32(len(ftab.P))
Addbytes(ftab, d.P)
ftab.AddBytes(d.P)
}
return int32(setuint32(ctxt, ftab, int64(off), uint32(start)))
return int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(start)))
}
func ftabaddstring(ctxt *Link, ftab *Symbol, s string) int32 {
n := int32(len(s)) + 1
start := int32(len(ftab.P))
Symgrow(ftab, int64(start)+int64(n)+1)
ftab.Grow(int64(start) + int64(n) + 1)
copy(ftab.P[start:], s)
return start
}
......@@ -226,11 +226,11 @@ func (ctxt *Link) pclntab() {
}
pclntabNfunc = nfunc
Symgrow(ftab, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize)+4)
setuint32(ctxt, ftab, 0, 0xfffffffb)
setuint8(ctxt, ftab, 6, uint8(ctxt.Arch.MinLC))
setuint8(ctxt, ftab, 7, uint8(ctxt.Arch.PtrSize))
setuint(ctxt, ftab, 8, uint64(nfunc))
ftab.Grow(8 + int64(ctxt.Arch.PtrSize) + int64(nfunc)*2*int64(ctxt.Arch.PtrSize) + int64(ctxt.Arch.PtrSize) + 4)
ftab.SetUint32(ctxt.Arch, 0, 0xfffffffb)
ftab.SetUint8(ctxt.Arch, 6, uint8(ctxt.Arch.MinLC))
ftab.SetUint8(ctxt.Arch, 7, uint8(ctxt.Arch.PtrSize))
ftab.SetUint(ctxt.Arch, 8, uint64(nfunc))
pclntabPclntabOffset = int32(8 + ctxt.Arch.PtrSize)
funcnameoff := make(map[string]int32)
......@@ -281,8 +281,8 @@ func (ctxt *Link) pclntab() {
funcstart := int32(len(ftab.P))
funcstart += int32(-len(ftab.P)) & (int32(ctxt.Arch.PtrSize) - 1)
setaddr(ctxt, ftab, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize), s)
setuint(ctxt, ftab, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize), uint64(funcstart))
ftab.SetAddr(ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize), s)
ftab.SetUint(ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize), uint64(funcstart))
// Write runtime._func. Keep in sync with ../../../../runtime/runtime2.go:/_func
// and package debug/gosym.
......@@ -294,14 +294,14 @@ func (ctxt *Link) pclntab() {
if len(pcln.Funcdata) > 0 && (end&int32(ctxt.Arch.PtrSize-1) != 0) {
end += 4
}
Symgrow(ftab, int64(end))
ftab.Grow(int64(end))
// entry uintptr
off = int32(setaddr(ctxt, ftab, int64(off), s))
off = int32(ftab.SetAddr(ctxt.Arch, int64(off), s))
// name int32
nameoff := nameToOffset(s.Name)
off = int32(setuint32(ctxt, ftab, int64(off), uint32(nameoff)))
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(nameoff)))
// args int32
// TODO: Move into funcinfo.
......@@ -309,14 +309,14 @@ func (ctxt *Link) pclntab() {
if s.FuncInfo != nil {
args = uint32(s.FuncInfo.Args)
}
off = int32(setuint32(ctxt, ftab, int64(off), args))
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), args))
// frame int32
// This has been removed (it was never set quite correctly anyway).
// Nothing should use it.
// Leave an obviously incorrect value.
// TODO: Remove entirely.
off = int32(setuint32(ctxt, ftab, int64(off), 0x1234567))
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), 0x1234567))
if pcln != &pclntabZpcln {
renumberfiles(ctxt, pcln.File, &pcln.Pcfile)
......@@ -346,10 +346,10 @@ func (ctxt *Link) pclntab() {
numberfile(ctxt, call.File)
nameoff := nameToOffset(call.Func.Name)
setuint32(ctxt, inlTreeSym, int64(i*16+0), uint32(call.Parent))
setuint32(ctxt, inlTreeSym, int64(i*16+4), uint32(call.File.Value))
setuint32(ctxt, inlTreeSym, int64(i*16+8), uint32(call.Line))
setuint32(ctxt, inlTreeSym, int64(i*16+12), uint32(nameoff))
inlTreeSym.SetUint32(ctxt.Arch, int64(i*16+0), uint32(call.Parent))
inlTreeSym.SetUint32(ctxt.Arch, int64(i*16+4), uint32(call.File.Value))
inlTreeSym.SetUint32(ctxt.Arch, int64(i*16+8), uint32(call.Line))
inlTreeSym.SetUint32(ctxt.Arch, int64(i*16+12), uint32(nameoff))
}
pcln.Funcdata[objabi.FUNCDATA_InlTree] = inlTreeSym
......@@ -361,8 +361,8 @@ func (ctxt *Link) pclntab() {
off = addpctab(ctxt, ftab, off, &pcln.Pcfile)
off = addpctab(ctxt, ftab, off, &pcln.Pcline)
off = int32(setuint32(ctxt, ftab, int64(off), uint32(len(pcln.Pcdata))))
off = int32(setuint32(ctxt, ftab, int64(off), uint32(len(pcln.Funcdata))))
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(len(pcln.Pcdata))))
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), uint32(len(pcln.Funcdata))))
for i := 0; i < len(pcln.Pcdata); i++ {
off = addpctab(ctxt, ftab, off, &pcln.Pcdata[i])
}
......@@ -375,12 +375,12 @@ func (ctxt *Link) pclntab() {
}
for i := 0; i < len(pcln.Funcdata); i++ {
if pcln.Funcdata[i] == nil {
setuint(ctxt, ftab, int64(off)+int64(ctxt.Arch.PtrSize)*int64(i), uint64(pcln.Funcdataoff[i]))
ftab.SetUint(ctxt.Arch, int64(off)+int64(ctxt.Arch.PtrSize)*int64(i), uint64(pcln.Funcdataoff[i]))
} else {
// TODO: Dedup.
funcdataBytes += pcln.Funcdata[i].Size
setaddrplus(ctxt, ftab, int64(off)+int64(ctxt.Arch.PtrSize)*int64(i), pcln.Funcdata[i], pcln.Funcdataoff[i])
ftab.SetAddrPlus(ctxt.Arch, int64(off)+int64(ctxt.Arch.PtrSize)*int64(i), pcln.Funcdata[i], pcln.Funcdataoff[i])
}
}
......@@ -397,20 +397,20 @@ func (ctxt *Link) pclntab() {
pclntabLastFunc = last
// Final entry of table is just end pc.
setaddrplus(ctxt, ftab, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize), last, last.Size)
ftab.SetAddrPlus(ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize), last, last.Size)
// Start file table.
start := int32(len(ftab.P))
start += int32(-len(ftab.P)) & (int32(ctxt.Arch.PtrSize) - 1)
pclntabFiletabOffset = start
setuint32(ctxt, ftab, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize), uint32(start))
ftab.SetUint32(ctxt.Arch, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize), uint32(start))
Symgrow(ftab, int64(start)+(int64(len(ctxt.Filesyms))+1)*4)
setuint32(ctxt, ftab, int64(start), uint32(len(ctxt.Filesyms)+1))
ftab.Grow(int64(start) + (int64(len(ctxt.Filesyms))+1)*4)
ftab.SetUint32(ctxt.Arch, int64(start), uint32(len(ctxt.Filesyms)+1))
for i := len(ctxt.Filesyms) - 1; i >= 0; i-- {
s := ctxt.Filesyms[i]
setuint32(ctxt, ftab, int64(start)+s.Value*4, uint32(ftabaddstring(ctxt, ftab, s.Name)))
ftab.SetUint32(ctxt.Arch, int64(start)+s.Value*4, uint32(ftabaddstring(ctxt, ftab, s.Name)))
}
ftab.Size = int64(len(ftab.P))
......@@ -500,7 +500,7 @@ func (ctxt *Link) findfunctab() {
// allocate table
nbuckets := int32((max - min + BUCKETSIZE - 1) / BUCKETSIZE)
Symgrow(t, 4*int64(nbuckets)+int64(n))
t.Grow(4*int64(nbuckets) + int64(n))
// fill in table
for i := int32(0); i < nbuckets; i++ {
......@@ -508,7 +508,7 @@ func (ctxt *Link) findfunctab() {
if base == NOIDX {
Errorf(nil, "hole in findfunctab")
}
setuint32(ctxt, t, int64(i)*(4+SUBBUCKETS), uint32(base))
t.SetUint32(ctxt.Arch, int64(i)*(4+SUBBUCKETS), uint32(base))
for j := int32(0); j < SUBBUCKETS && i*SUBBUCKETS+j < n; j++ {
idx = indexes[i*SUBBUCKETS+j]
if idx == NOIDX {
......@@ -518,7 +518,7 @@ func (ctxt *Link) findfunctab() {
Errorf(nil, "too many functions in a findfunc bucket! %d/%d %d %d", i, nbuckets, j, idx-base)
}
setuint8(ctxt, t, int64(i)*(4+SUBBUCKETS)+4+int64(j), uint8(idx-base))
t.SetUint8(ctxt.Arch, int64(i)*(4+SUBBUCKETS)+4+int64(j), uint8(idx-base))
}
}
}
......@@ -990,7 +990,7 @@ func initdynimport(ctxt *Link) *Dll {
for d := dr; d != nil; d = d.next {
for m = d.ms; m != nil; m = m.next {
m.s.Type = SDATA
Symgrow(m.s, int64(ctxt.Arch.PtrSize))
m.s.Grow(int64(ctxt.Arch.PtrSize))
dynName := m.s.Extname
// only windows/386 requires stdcall decoration
if ctxt.Arch.Family == sys.I386 && m.argsize >= 0 {
......@@ -999,7 +999,7 @@ func initdynimport(ctxt *Link) *Dll {
dynSym := ctxt.Syms.Lookup(dynName, 0)
dynSym.Attr |= AttrReachable
dynSym.Type = SHOSTOBJ
r := Addrel(m.s)
r := m.s.AddRel()
r.Sym = dynSym
r.Off = 0
r.Siz = uint8(ctxt.Arch.PtrSize)
......
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ld
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"debug/elf"
"fmt"
"log"
)
// Symbol is an entry in the symbol table.
type Symbol struct {
Name string
Extname string
Type SymKind
Version int16
Attr Attribute
Localentry uint8
Dynid int32
Plt int32
Got int32
Align int32
Elfsym int32
LocalElfsym int32
Value int64
Size int64
// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
// is not set for symbols defined by the packages being linked or by symbols
// read by ldelf (and so is left as elf.STT_NOTYPE).
ElfType elf.SymType
Sub *Symbol
Outer *Symbol
Gotype *Symbol
Reachparent *Symbol
File string
Dynimplib string
Dynimpvers string
Sect *Section
FuncInfo *FuncInfo
// P contains the raw symbol data.
P []byte
R []Reloc
}
func (s *Symbol) String() string {
if s.Version == 0 {
return s.Name
}
return fmt.Sprintf("%s<%d>", s.Name, s.Version)
}
func (s *Symbol) ElfsymForReloc() int32 {
// If putelfsym created a local version of this symbol, use that in all
// relocations.
if s.LocalElfsym != 0 {
return s.LocalElfsym
} else {
return s.Elfsym
}
}
func (s *Symbol) Len() int64 {
return s.Size
}
func (s *Symbol) Grow(siz int64) {
if int64(int(siz)) != siz {
log.Fatalf("symgrow size %d too long", siz)
}
if int64(len(s.P)) >= siz {
return
}
if cap(s.P) < int(siz) {
p := make([]byte, 2*(siz+1))
s.P = append(p[:0], s.P...)
}
s.P = s.P[:siz]
}
func (s *Symbol) AddBytes(bytes []byte) int64 {
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
s.P = append(s.P, bytes...)
s.Size = int64(len(s.P))
return s.Size
}
func (s *Symbol) AddUint8(v uint8) int64 {
off := s.Size
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
s.Size++
s.P = append(s.P, v)
return off
}
func (s *Symbol) AddUint16(arch *sys.Arch, v uint16) int64 {
return s.addUintXX(arch, uint64(v), 2)
}
func (s *Symbol) AddUint32(arch *sys.Arch, v uint32) int64 {
return s.addUintXX(arch, uint64(v), 4)
}
func (s *Symbol) AddUint64(arch *sys.Arch, v uint64) int64 {
return s.addUintXX(arch, v, 8)
}
func (s *Symbol) AddUint(arch *sys.Arch, v uint64) int64 {
return s.addUintXX(arch, v, arch.PtrSize)
}
func (s *Symbol) SetUint8(arch *sys.Arch, r int64, v uint8) int64 {
return s.setUintXX(arch, r, uint64(v), 1)
}
func (s *Symbol) SetUint32(arch *sys.Arch, r int64, v uint32) int64 {
return s.setUintXX(arch, r, uint64(v), 4)
}
func (s *Symbol) SetUint(arch *sys.Arch, r int64, v uint64) int64 {
return s.setUintXX(arch, r, v, int64(arch.PtrSize))
}
func (s *Symbol) AddAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
i := s.Size
s.Size += int64(arch.PtrSize)
s.Grow(s.Size)
r := s.AddRel()
r.Sym = t
r.Off = int32(i)
r.Siz = uint8(arch.PtrSize)
r.Type = objabi.R_ADDR
r.Add = add
return i + int64(r.Siz)
}
func (s *Symbol) AddPCRelPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
i := s.Size
s.Size += 4
s.Grow(s.Size)
r := s.AddRel()
r.Sym = t
r.Off = int32(i)
r.Add = add
r.Type = objabi.R_PCREL
r.Siz = 4
if arch.Family == sys.S390X {
r.Variant = RV_390_DBL
}
return i + int64(r.Siz)
}
func (s *Symbol) AddAddr(arch *sys.Arch, t *Symbol) int64 {
return s.AddAddrPlus(arch, t, 0)
}
func (s *Symbol) SetAddrPlus(arch *sys.Arch, off int64, t *Symbol, add int64) int64 {
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
if off+int64(arch.PtrSize) > s.Size {
s.Size = off + int64(arch.PtrSize)
s.Grow(s.Size)
}
r := s.AddRel()
r.Sym = t
r.Off = int32(off)
r.Siz = uint8(arch.PtrSize)
r.Type = objabi.R_ADDR
r.Add = add
return off + int64(r.Siz)
}
func (s *Symbol) SetAddr(arch *sys.Arch, off int64, t *Symbol) int64 {
return s.SetAddrPlus(arch, off, t, 0)
}
func (s *Symbol) AddSize(arch *sys.Arch, t *Symbol) int64 {
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
i := s.Size
s.Size += int64(arch.PtrSize)
s.Grow(s.Size)
r := s.AddRel()
r.Sym = t
r.Off = int32(i)
r.Siz = uint8(arch.PtrSize)
r.Type = objabi.R_SIZE
return i + int64(r.Siz)
}
func (s *Symbol) AddAddrPlus4(t *Symbol, add int64) int64 {
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
i := s.Size
s.Size += 4
s.Grow(s.Size)
r := s.AddRel()
r.Sym = t
r.Off = int32(i)
r.Siz = 4
r.Type = objabi.R_ADDR
r.Add = add
return i + int64(r.Siz)
}
func (s *Symbol) AddRel() *Reloc {
s.R = append(s.R, Reloc{})
return &s.R[len(s.R)-1]
}
func (s *Symbol) addUintXX(arch *sys.Arch, v uint64, wid int) int64 {
off := s.Size
s.setUintXX(arch, off, v, int64(wid))
return off
}
func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64 {
if s.Type == 0 {
s.Type = SDATA
}
s.Attr |= AttrReachable
if s.Size < off+wid {
s.Size = off + wid
s.Grow(s.Size)
}
switch wid {
case 1:
s.P[off] = uint8(v)
case 2:
arch.ByteOrder.PutUint16(s.P[off:], uint16(v))
case 4:
arch.ByteOrder.PutUint32(s.P[off:], uint32(v))
case 8:
arch.ByteOrder.PutUint64(s.P[off:], v)
}
return off + wid
}
This diff is collapsed.
......@@ -141,10 +141,10 @@ func genaddmoduledata(ctxt *ld.Link) {
initfunc.Attr |= ld.AttrLocal
initfunc.Attr |= ld.AttrReachable
o := func(op uint32) {
ld.Adduint32(ctxt, initfunc, op)
initfunc.AddUint32(ctxt.Arch, op)
}
// addis r2, r12, .TOC.-func@ha
rel := ld.Addrel(initfunc)
rel := initfunc.AddRel()
rel.Off = int32(initfunc.Size)
rel.Siz = 8
rel.Sym = ctxt.Syms.Lookup(".TOC.", 0)
......@@ -158,7 +158,7 @@ func genaddmoduledata(ctxt *ld.Link) {
// stdu r31, -32(r1)
o(0xf801ffe1)
// addis r3, r2, local.moduledata@got@ha
rel = ld.Addrel(initfunc)
rel = initfunc.AddRel()
rel.Off = int32(initfunc.Size)
rel.Siz = 8
if !ctxt.CanUsePlugins() {
......@@ -173,7 +173,7 @@ func genaddmoduledata(ctxt *ld.Link) {
// ld r3, local.moduledata@got@l(r3)
o(0xe8630000)
// bl runtime.addmoduledata
rel = ld.Addrel(initfunc)
rel = initfunc.AddRel()
rel.Off = int32(initfunc.Size)
rel.Siz = 4
rel.Sym = addmoduledata
......@@ -198,7 +198,7 @@ func genaddmoduledata(ctxt *ld.Link) {
initarray_entry.Attr |= ld.AttrReachable
initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = ld.SINITARR
ld.Addaddr(ctxt, initarray_entry, initfunc)
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
func gentext(ctxt *ld.Link) {
......@@ -225,10 +225,10 @@ func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) {
stub.Type = ld.STEXT
// Save TOC pointer in TOC save slot
ld.Adduint32(ctxt, stub, 0xf8410018) // std r2,24(r1)
stub.AddUint32(ctxt.Arch, 0xf8410018) // std r2,24(r1)
// Load the function pointer from the PLT.
r := ld.Addrel(stub)
r := stub.AddRel()
r.Off = int32(stub.Size)
r.Sym = plt
......@@ -239,8 +239,8 @@ func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) {
}
r.Type = objabi.R_POWER_TOC
r.Variant = ld.RV_POWER_HA
ld.Adduint32(ctxt, stub, 0x3d820000) // addis r12,r2,targ@plt@toc@ha
r = ld.Addrel(stub)
stub.AddUint32(ctxt.Arch, 0x3d820000) // addis r12,r2,targ@plt@toc@ha
r = stub.AddRel()
r.Off = int32(stub.Size)
r.Sym = plt
r.Add = int64(targ.Plt)
......@@ -250,11 +250,11 @@ func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) {
}
r.Type = objabi.R_POWER_TOC
r.Variant = ld.RV_POWER_LO
ld.Adduint32(ctxt, stub, 0xe98c0000) // ld r12,targ@plt@toc@l(r12)
stub.AddUint32(ctxt.Arch, 0xe98c0000) // ld r12,targ@plt@toc@l(r12)
// Jump to the loaded pointer
ld.Adduint32(ctxt, stub, 0x7d8903a6) // mtctr r12
ld.Adduint32(ctxt, stub, 0x4e800420) // bctr
stub.AddUint32(ctxt.Arch, 0x7d8903a6) // mtctr r12
stub.AddUint32(ctxt.Arch, 0x4e800420) // bctr
}
func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
......@@ -302,9 +302,9 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
ld.Adddynsym(ctxt, targ)
rela := ctxt.Syms.Lookup(".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))
rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_PPC64_ADDR64))
rela.AddUint64(ctxt.Arch, uint64(r.Add))
r.Type = 256 // ignore during relocsym
}
......@@ -595,7 +595,7 @@ func gentramp(arch *sys.Arch, tramp, target *ld.Symbol, offset int64) {
// With external linking, the target address must be
// relocated using LO and HA
if ld.Linkmode == ld.LinkExternal {
tr := ld.Addrel(tramp)
tr := tramp.AddRel()
tr.Off = 0
tr.Type = objabi.R_ADDRPOWER
tr.Siz = 8 // generates 2 relocations: HA + LO
......@@ -814,13 +814,13 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
// Write symbol resolver stub (just a branch to the
// glink resolver stub)
r := ld.Addrel(glink)
r := glink.AddRel()
r.Sym = glink
r.Off = int32(glink.Size)
r.Siz = 4
r.Type = objabi.R_CALLPOWER
ld.Adduint32(ctxt, glink, 0x48000000) // b .glink
glink.AddUint32(ctxt.Arch, 0x48000000) // b .glink
// In the ppc64 ABI, the dynamic linker is responsible
// for writing the entire PLT. We just need to
......@@ -832,9 +832,9 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
plt.Size += 8
ld.Addaddrplus(ctxt, rela, plt, int64(s.Plt))
ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_PPC64_JMP_SLOT))
ld.Adduint64(ctxt, rela, 0)
rela.AddAddrPlus(ctxt.Arch, plt, int64(s.Plt))
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_PPC64_JMP_SLOT))
rela.AddUint64(ctxt.Arch, 0)
} else {
ld.Errorf(s, "addpltsym: unsupported binary format")
}
......@@ -854,39 +854,39 @@ func ensureglinkresolver(ctxt *ld.Link) *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(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
glink.AddUint32(ctxt.Arch, 0x7c0802a6) // mflr r0
glink.AddUint32(ctxt.Arch, 0x429f0005) // bcl 20,31,1f
glink.AddUint32(ctxt.Arch, 0x7d6802a6) // 1: mflr r11
glink.AddUint32(ctxt.Arch, 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(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
glink.AddUint32(ctxt.Arch, 0x3800ffd0) // li r0,-(res_0-1b)=-48
glink.AddUint32(ctxt.Arch, 0x7c006214) // add r0,r0,r12
glink.AddUint32(ctxt.Arch, 0x7c0b0050) // sub r0,r0,r11
glink.AddUint32(ctxt.Arch, 0x7800f082) // srdi r0,r0,2
// r11 = address of the first byte of the PLT
r := ld.Addrel(glink)
r := glink.AddRel()
r.Off = int32(glink.Size)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
r.Siz = 8
r.Type = objabi.R_ADDRPOWER
ld.Adduint32(ctxt, glink, 0x3d600000) // addis r11,0,.plt@ha
ld.Adduint32(ctxt, glink, 0x396b0000) // addi r11,r11,.plt@l
glink.AddUint32(ctxt.Arch, 0x3d600000) // addis r11,0,.plt@ha
glink.AddUint32(ctxt.Arch, 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(ctxt, glink, 0xe98b0000) // ld r12,0(r11)
ld.Adduint32(ctxt, glink, 0xe96b0008) // ld r11,8(r11)
glink.AddUint32(ctxt.Arch, 0xe98b0000) // ld r12,0(r11)
glink.AddUint32(ctxt.Arch, 0xe96b0008) // ld r11,8(r11)
// Jump to the dynamic resolver
ld.Adduint32(ctxt, glink, 0x7d8903a6) // mtctr r12
ld.Adduint32(ctxt, glink, 0x4e800420) // bctr
glink.AddUint32(ctxt.Arch, 0x7d8903a6) // mtctr r12
glink.AddUint32(ctxt.Arch, 0x4e800420) // bctr
// The symbol resolvers must immediately follow.
// res_0:
......
......@@ -65,31 +65,31 @@ func gentext(ctxt *ld.Link) {
initfunc.Attr |= ld.AttrReachable
// larl %r2, <local.moduledata>
ld.Adduint8(ctxt, initfunc, 0xc0)
ld.Adduint8(ctxt, initfunc, 0x20)
lmd := ld.Addrel(initfunc)
initfunc.AddUint8(0xc0)
initfunc.AddUint8(0x20)
lmd := initfunc.AddRel()
lmd.Off = int32(initfunc.Size)
lmd.Siz = 4
lmd.Sym = ctxt.Moduledata
lmd.Type = objabi.R_PCREL
lmd.Variant = ld.RV_390_DBL
lmd.Add = 2 + int64(lmd.Siz)
ld.Adduint32(ctxt, initfunc, 0)
initfunc.AddUint32(ctxt.Arch, 0)
// jg <runtime.addmoduledata[@plt]>
ld.Adduint8(ctxt, initfunc, 0xc0)
ld.Adduint8(ctxt, initfunc, 0xf4)
rel := ld.Addrel(initfunc)
initfunc.AddUint8(0xc0)
initfunc.AddUint8(0xf4)
rel := initfunc.AddRel()
rel.Off = int32(initfunc.Size)
rel.Siz = 4
rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
rel.Type = objabi.R_CALL
rel.Variant = ld.RV_390_DBL
rel.Add = 2 + int64(rel.Siz)
ld.Adduint32(ctxt, initfunc, 0)
initfunc.AddUint32(ctxt.Arch, 0)
// undef (for debugging)
ld.Adduint32(ctxt, initfunc, 0)
initfunc.AddUint32(ctxt.Arch, 0)
if ld.Buildmode == ld.BuildmodePlugin {
ctxt.Textp = append(ctxt.Textp, addmoduledata)
}
......@@ -98,7 +98,7 @@ func gentext(ctxt *ld.Link) {
initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Attr |= ld.AttrReachable
initarray_entry.Type = ld.SINITARR
ld.Addaddr(ctxt, initarray_entry, initfunc)
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
......@@ -332,48 +332,48 @@ func elfsetupplt(ctxt *ld.Link) {
got := ctxt.Syms.Lookup(".got", 0)
if plt.Size == 0 {
// stg %r1,56(%r15)
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)
plt.AddUint8(0xe3)
plt.AddUint8(0x10)
plt.AddUint8(0xf0)
plt.AddUint8(0x38)
plt.AddUint8(0x00)
plt.AddUint8(0x24)
// larl %r1,_GLOBAL_OFFSET_TABLE_
ld.Adduint8(ctxt, plt, 0xc0)
ld.Adduint8(ctxt, plt, 0x10)
ld.Addpcrelplus(ctxt, plt, got, 6)
plt.AddUint8(0xc0)
plt.AddUint8(0x10)
plt.AddPCRelPlus(ctxt.Arch, got, 6)
// mvc 48(8,%r15),8(%r1)
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)
plt.AddUint8(0xd2)
plt.AddUint8(0x07)
plt.AddUint8(0xf0)
plt.AddUint8(0x30)
plt.AddUint8(0x10)
plt.AddUint8(0x08)
// lg %r1,16(%r1)
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)
plt.AddUint8(0xe3)
plt.AddUint8(0x10)
plt.AddUint8(0x10)
plt.AddUint8(0x10)
plt.AddUint8(0x00)
plt.AddUint8(0x04)
// br %r1
ld.Adduint8(ctxt, plt, 0x07)
ld.Adduint8(ctxt, plt, 0xf1)
plt.AddUint8(0x07)
plt.AddUint8(0xf1)
// nopr %r0
ld.Adduint8(ctxt, plt, 0x07)
ld.Adduint8(ctxt, plt, 0x00)
plt.AddUint8(0x07)
plt.AddUint8(0x00)
// nopr %r0
ld.Adduint8(ctxt, plt, 0x07)
ld.Adduint8(ctxt, plt, 0x00)
plt.AddUint8(0x07)
plt.AddUint8(0x00)
// nopr %r0
ld.Adduint8(ctxt, plt, 0x07)
ld.Adduint8(ctxt, plt, 0x00)
plt.AddUint8(0x07)
plt.AddUint8(0x00)
// assume got->size == 0 too
ld.Addaddrplus(ctxt, got, ctxt.Syms.Lookup(".dynamic", 0), 0)
got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
ld.Adduint64(ctxt, got, 0)
ld.Adduint64(ctxt, got, 0)
got.AddUint64(ctxt.Arch, 0)
got.AddUint64(ctxt.Arch, 0)
}
}
......@@ -431,45 +431,45 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
}
// larl %r1,_GLOBAL_OFFSET_TABLE_+index
ld.Adduint8(ctxt, plt, 0xc0)
ld.Adduint8(ctxt, plt, 0x10)
ld.Addpcrelplus(ctxt, plt, got, got.Size+6) // need variant?
plt.AddUint8(0xc0)
plt.AddUint8(0x10)
plt.AddPCRelPlus(ctxt.Arch, got, got.Size+6) // need variant?
// add to got: pointer to current pos in plt
ld.Addaddrplus(ctxt, got, plt, plt.Size+8) // weird but correct
got.AddAddrPlus(ctxt.Arch, plt, plt.Size+8) // weird but correct
// lg %r1,0(%r1)
ld.Adduint8(ctxt, plt, 0xe3)
ld.Adduint8(ctxt, plt, 0x10)
ld.Adduint8(ctxt, plt, 0x10)
ld.Adduint8(ctxt, plt, 0x00)
ld.Adduint8(ctxt, plt, 0x00)
ld.Adduint8(ctxt, plt, 0x04)
plt.AddUint8(0xe3)
plt.AddUint8(0x10)
plt.AddUint8(0x10)
plt.AddUint8(0x00)
plt.AddUint8(0x00)
plt.AddUint8(0x04)
// br %r1
ld.Adduint8(ctxt, plt, 0x07)
ld.Adduint8(ctxt, plt, 0xf1)
plt.AddUint8(0x07)
plt.AddUint8(0xf1)
// basr %r1,%r0
ld.Adduint8(ctxt, plt, 0x0d)
ld.Adduint8(ctxt, plt, 0x10)
plt.AddUint8(0x0d)
plt.AddUint8(0x10)
// lgf %r1,12(%r1)
ld.Adduint8(ctxt, plt, 0xe3)
ld.Adduint8(ctxt, plt, 0x10)
ld.Adduint8(ctxt, plt, 0x10)
ld.Adduint8(ctxt, plt, 0x0c)
ld.Adduint8(ctxt, plt, 0x00)
ld.Adduint8(ctxt, plt, 0x14)
plt.AddUint8(0xe3)
plt.AddUint8(0x10)
plt.AddUint8(0x10)
plt.AddUint8(0x0c)
plt.AddUint8(0x00)
plt.AddUint8(0x14)
// jg .plt
ld.Adduint8(ctxt, plt, 0xc0)
ld.Adduint8(ctxt, plt, 0xf4)
plt.AddUint8(0xc0)
plt.AddUint8(0xf4)
ld.Adduint32(ctxt, plt, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation
plt.AddUint32(ctxt.Arch, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation
//.plt index
ld.Adduint32(ctxt, plt, uint32(rela.Size)) // rela size before current entry
plt.AddUint32(ctxt.Arch, uint32(rela.Size)) // rela size before current entry
// rela
ld.Addaddrplus(ctxt, rela, got, got.Size-8)
rela.AddAddrPlus(ctxt.Arch, got, got.Size-8)
ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_JMP_SLOT))
ld.Adduint64(ctxt, rela, 0)
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_JMP_SLOT))
rela.AddUint64(ctxt.Arch, 0)
s.Plt = int32(plt.Size - 32)
......@@ -486,13 +486,13 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
ld.Adddynsym(ctxt, s)
got := ctxt.Syms.Lookup(".got", 0)
s.Got = int32(got.Size)
ld.Adduint64(ctxt, got, 0)
got.AddUint64(ctxt.Arch, 0)
if ld.Iself {
rela := ctxt.Syms.Lookup(".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)
rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_GLOB_DAT))
rela.AddUint64(ctxt.Arch, 0)
} else {
ld.Errorf(s, "addgotsym: unsupported binary format")
}
......
......@@ -42,8 +42,8 @@ func addcall(ctxt *ld.Link, s *ld.Symbol, t *ld.Symbol) {
s.Attr |= ld.AttrReachable
i := s.Size
s.Size += 4
ld.Symgrow(s, s.Size)
r := ld.Addrel(s)
s.Grow(s.Size)
r := s.AddRel()
r.Sym = t
r.Off = int32(i)
r.Type = objabi.R_CALL
......@@ -87,7 +87,7 @@ func gentext(ctxt *ld.Link) {
thunkfunc.Attr |= ld.AttrReachable //TODO: remove?
o := func(op ...uint8) {
for _, op1 := range op {
ld.Adduint8(ctxt, thunkfunc, op1)
thunkfunc.AddUint8(op1)
}
}
// 8b 04 24 mov (%esp),%eax
......@@ -115,7 +115,7 @@ func gentext(ctxt *ld.Link) {
initfunc.Attr |= ld.AttrReachable
o := func(op ...uint8) {
for _, op1 := range op {
ld.Adduint8(ctxt, initfunc, op1)
initfunc.AddUint8(op1)
}
}
......@@ -134,13 +134,13 @@ func gentext(ctxt *ld.Link) {
addcall(ctxt, initfunc, ctxt.Syms.Lookup("__x86.get_pc_thunk.cx", 0))
o(0x8d, 0x81)
ld.Addpcrelplus(ctxt, initfunc, ctxt.Moduledata, 6)
initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata, 6)
o(0x8d, 0x99)
i := initfunc.Size
initfunc.Size += 4
ld.Symgrow(initfunc, initfunc.Size)
r := ld.Addrel(initfunc)
initfunc.Grow(initfunc.Size)
r := initfunc.AddRel()
r.Sym = ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
r.Off = int32(i)
r.Type = objabi.R_PCREL
......@@ -162,7 +162,7 @@ func gentext(ctxt *ld.Link) {
initarray_entry.Attr |= ld.AttrReachable
initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = ld.SINITARR
ld.Addaddr(ctxt, initarray_entry, initfunc)
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
......@@ -305,8 +305,8 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
if ld.Iself {
ld.Adddynsym(ctxt, targ)
rel := ctxt.Syms.Lookup(".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))
rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_386_32))
r.Type = objabi.R_CONST // write r->add during relocsym
r.Sym = nil
return true
......@@ -331,8 +331,8 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
s.Sub = got.Sub
got.Sub = s
s.Value = got.Size
ld.Adduint32(ctxt, got, 0)
ld.Adduint32(ctxt, ctxt.Syms.Lookup(".linkedit.got", 0), uint32(targ.Dynid))
got.AddUint32(ctxt.Arch, 0)
ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid))
r.Type = 256 // ignore during relocsym
return true
}
......@@ -508,25 +508,25 @@ func elfsetupplt(ctxt *ld.Link) {
got := ctxt.Syms.Lookup(".got.plt", 0)
if plt.Size == 0 {
// pushl got+4
ld.Adduint8(ctxt, plt, 0xff)
plt.AddUint8(0xff)
ld.Adduint8(ctxt, plt, 0x35)
ld.Addaddrplus(ctxt, plt, got, 4)
plt.AddUint8(0x35)
plt.AddAddrPlus(ctxt.Arch, got, 4)
// jmp *got+8
ld.Adduint8(ctxt, plt, 0xff)
plt.AddUint8(0xff)
ld.Adduint8(ctxt, plt, 0x25)
ld.Addaddrplus(ctxt, plt, got, 8)
plt.AddUint8(0x25)
plt.AddAddrPlus(ctxt.Arch, got, 8)
// zero pad
ld.Adduint32(ctxt, plt, 0)
plt.AddUint32(ctxt.Arch, 0)
// assume got->size == 0 too
ld.Addaddrplus(ctxt, got, ctxt.Syms.Lookup(".dynamic", 0), 0)
got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
ld.Adduint32(ctxt, got, 0)
ld.Adduint32(ctxt, got, 0)
got.AddUint32(ctxt.Arch, 0)
got.AddUint32(ctxt.Arch, 0)
}
}
......@@ -546,28 +546,28 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
}
// jmpq *got+size
ld.Adduint8(ctxt, plt, 0xff)
plt.AddUint8(0xff)
ld.Adduint8(ctxt, plt, 0x25)
ld.Addaddrplus(ctxt, plt, got, got.Size)
plt.AddUint8(0x25)
plt.AddAddrPlus(ctxt.Arch, got, got.Size)
// add to got: pointer to current pos in plt
ld.Addaddrplus(ctxt, got, plt, plt.Size)
got.AddAddrPlus(ctxt.Arch, plt, plt.Size)
// pushl $x
ld.Adduint8(ctxt, plt, 0x68)
plt.AddUint8(0x68)
ld.Adduint32(ctxt, plt, uint32(rel.Size))
plt.AddUint32(ctxt.Arch, uint32(rel.Size))
// jmp .plt
ld.Adduint8(ctxt, plt, 0xe9)
plt.AddUint8(0xe9)
ld.Adduint32(ctxt, plt, uint32(-(plt.Size + 4)))
plt.AddUint32(ctxt.Arch, uint32(-(plt.Size + 4)))
// rel
ld.Addaddrplus(ctxt, rel, got, got.Size-4)
rel.AddAddrPlus(ctxt.Arch, got, got.Size-4)
ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_JMP_SLOT))
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_JMP_SLOT))
s.Plt = int32(plt.Size - 16)
} else if ld.Headtype == objabi.Hdarwin {
......@@ -577,14 +577,14 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
addgotsym(ctxt, s)
ld.Adduint32(ctxt, ctxt.Syms.Lookup(".linkedit.plt", 0), uint32(s.Dynid))
ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
// jmpq *got+size(IP)
s.Plt = int32(plt.Size)
ld.Adduint8(ctxt, plt, 0xff)
ld.Adduint8(ctxt, plt, 0x25)
ld.Addaddrplus(ctxt, plt, ctxt.Syms.Lookup(".got", 0), int64(s.Got))
plt.AddUint8(0xff)
plt.AddUint8(0x25)
plt.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got))
} else {
ld.Errorf(s, "addpltsym: unsupported binary format")
}
......@@ -598,14 +598,14 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
ld.Adddynsym(ctxt, s)
got := ctxt.Syms.Lookup(".got", 0)
s.Got = int32(got.Size)
ld.Adduint32(ctxt, got, 0)
got.AddUint32(ctxt.Arch, 0)
if ld.Iself {
rel := ctxt.Syms.Lookup(".rel", 0)
ld.Addaddrplus(ctxt, rel, got, int64(s.Got))
ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_GLOB_DAT))
rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_GLOB_DAT))
} else if ld.Headtype == objabi.Hdarwin {
ld.Adduint32(ctxt, ctxt.Syms.Lookup(".linkedit.got", 0), uint32(s.Dynid))
ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
} else {
ld.Errorf(s, "addgotsym: unsupported binary format")
}
......
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