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
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)
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 {
// 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
}
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
}
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)
}
}
}
// 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 {
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")
}
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")
}
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)
rel.Add = 0xeafffffe // vomit
o(0x00000000)
- rel = ld.Addrel(initfunc)
+ rel = initfunc.AddRel()
rel.Off = 12
rel.Siz = 4
rel.Sym = ctxt.Moduledata
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
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
}
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)
}
}
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
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
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
}
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
plt.Attr |= ld.AttrReachable
plt.Size += 4
- ld.Symgrow(plt, plt.Size)
+ plt.Grow(plt.Size)
return r
}
// 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)
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")
}
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 {
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")
}
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>
// 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
// 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)
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 {
"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).
// 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
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
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) {
sp.Type = SINITARR
sp.Size = 0
sp.Attr |= AttrDuplicateOK
- Addaddr(ctxt, sp, s)
+ sp.AddAddr(ctxt.Arch, s)
}
func dosymtype(ctxt *Link) {
func (p *GCProg) writeByte(ctxt *Link) func(x byte) {
return func(x byte) {
- Adduint8(ctxt, p.sym, x)
+ p.sym.AddUint8(x)
}
}
}
func (c dwctxt) AddInt(s dwarf.Sym, size int, i int64) {
ls := s.(*Symbol)
- adduintxx(c.linkctxt, ls, uint64(i), size)
+ ls.addUintXX(c.linkctxt.Arch, uint64(i), size)
}
func (c dwctxt) AddBytes(s dwarf.Sym, b []byte) {
ls := s.(*Symbol)
- Addbytes(ls, b)
+ ls.AddBytes(b)
}
func (c dwctxt) AddString(s dwarf.Sym, v string) {
Addstring(s.(*Symbol), v)
if value != 0 {
value -= (data.(*Symbol)).Value
}
- Addaddrplus(c.linkctxt, s.(*Symbol), data.(*Symbol), value)
+ s.(*Symbol).AddAddrPlus(c.linkctxt.Arch, data.(*Symbol), value)
}
func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
Errorf(ls, "invalid size %d in adddwarfref\n", size)
fallthrough
case c.linkctxt.Arch.PtrSize:
- Addaddr(c.linkctxt, ls, t.(*Symbol))
+ ls.AddAddr(c.linkctxt.Arch, t.(*Symbol))
case 4:
- addaddrplus4(c.linkctxt, ls, t.(*Symbol), 0)
+ ls.AddAddrPlus4(t.(*Symbol), 0)
}
r := &ls.R[len(ls.R)-1]
r.Type = objabi.R_DWARFREF
func writeabbrev(ctxt *Link) *Symbol {
s := ctxt.Syms.Lookup(".debug_abbrev", 0)
s.Type = SDWARFSECT
- Addbytes(s, dwarf.GetAbbrev())
+ s.AddBytes(dwarf.GetAbbrev())
return s
}
Errorf(s, "invalid size %d in adddwarfref\n", size)
fallthrough
case ctxt.Arch.PtrSize:
- result = Addaddr(ctxt, s, t)
+ result = s.AddAddr(ctxt.Arch, t)
case 4:
- result = addaddrplus4(ctxt, s, t, 0)
+ result = s.AddAddrPlus4(t, 0)
}
r := &s.R[len(s.R)-1]
r.Type = objabi.R_DWARFREF
for ; die != nil; die = die.Link {
syms = putdie(linkctxt, ctxt, syms, die)
}
- Adduint8(linkctxt, syms[len(syms)-1], 0)
+ syms[len(syms)-1].AddUint8(0)
return syms
}
if opcode < OPCODE_BASE {
panic(fmt.Sprintf("produced invalid special opcode %d", opcode))
}
- Adduint8(linkctxt, s, dwarf.DW_LNS_const_add_pc)
+ s.AddUint8(dwarf.DW_LNS_const_add_pc)
} else if (1<<14) <= deltaPC && deltaPC < (1<<16) {
- Adduint8(linkctxt, s, dwarf.DW_LNS_fixed_advance_pc)
- Adduint16(linkctxt, s, uint16(deltaPC))
+ s.AddUint8(dwarf.DW_LNS_fixed_advance_pc)
+ s.AddUint16(linkctxt.Arch, uint16(deltaPC))
} else {
- Adduint8(linkctxt, s, dwarf.DW_LNS_advance_pc)
+ s.AddUint8(dwarf.DW_LNS_advance_pc)
dwarf.Uleb128put(ctxt, s, int64(deltaPC))
}
}
// Encode deltaLC.
if deltaLC != 0 {
- Adduint8(linkctxt, s, dwarf.DW_LNS_advance_line)
+ s.AddUint8(dwarf.DW_LNS_advance_line)
dwarf.Sleb128put(ctxt, s, deltaLC)
}
// Output the special opcode.
- Adduint8(linkctxt, s, uint8(opcode))
+ s.AddUint8(uint8(opcode))
}
/*
// Write .debug_line Line Number Program Header (sec 6.2.4)
// Fields marked with (*) must be changed for 64-bit dwarf
unitLengthOffset := ls.Size
- Adduint32(ctxt, ls, 0) // unit_length (*), filled in at end.
+ ls.AddUint32(ctxt.Arch, 0) // unit_length (*), filled in at end.
unitstart = ls.Size
- Adduint16(ctxt, ls, 2) // dwarf version (appendix F)
+ ls.AddUint16(ctxt.Arch, 2) // dwarf version (appendix F)
headerLengthOffset := ls.Size
- Adduint32(ctxt, ls, 0) // header_length (*), filled in at end.
+ ls.AddUint32(ctxt.Arch, 0) // header_length (*), filled in at end.
headerstart = ls.Size
// cpos == unitstart + 4 + 2 + 4
- Adduint8(ctxt, ls, 1) // minimum_instruction_length
- Adduint8(ctxt, ls, 1) // default_is_stmt
- Adduint8(ctxt, ls, LINE_BASE&0xFF) // line_base
- Adduint8(ctxt, ls, LINE_RANGE) // line_range
- Adduint8(ctxt, ls, OPCODE_BASE) // opcode_base
- Adduint8(ctxt, ls, 0) // standard_opcode_lengths[1]
- Adduint8(ctxt, ls, 1) // standard_opcode_lengths[2]
- Adduint8(ctxt, ls, 1) // standard_opcode_lengths[3]
- Adduint8(ctxt, ls, 1) // standard_opcode_lengths[4]
- Adduint8(ctxt, ls, 1) // standard_opcode_lengths[5]
- Adduint8(ctxt, ls, 0) // standard_opcode_lengths[6]
- Adduint8(ctxt, ls, 0) // standard_opcode_lengths[7]
- Adduint8(ctxt, ls, 0) // standard_opcode_lengths[8]
- Adduint8(ctxt, ls, 1) // standard_opcode_lengths[9]
- Adduint8(ctxt, ls, 0) // include_directories (empty)
+ ls.AddUint8(1) // minimum_instruction_length
+ ls.AddUint8(1) // default_is_stmt
+ ls.AddUint8(LINE_BASE & 0xFF) // line_base
+ ls.AddUint8(LINE_RANGE) // line_range
+ ls.AddUint8(OPCODE_BASE) // opcode_base
+ ls.AddUint8(0) // standard_opcode_lengths[1]
+ ls.AddUint8(1) // standard_opcode_lengths[2]
+ ls.AddUint8(1) // standard_opcode_lengths[3]
+ ls.AddUint8(1) // standard_opcode_lengths[4]
+ ls.AddUint8(1) // standard_opcode_lengths[5]
+ ls.AddUint8(0) // standard_opcode_lengths[6]
+ ls.AddUint8(0) // standard_opcode_lengths[7]
+ ls.AddUint8(0) // standard_opcode_lengths[8]
+ ls.AddUint8(1) // standard_opcode_lengths[9]
+ ls.AddUint8(0) // include_directories (empty)
for _, f := range ctxt.Filesyms {
Addstring(ls, f.Name)
- Adduint8(ctxt, ls, 0)
- Adduint8(ctxt, ls, 0)
- Adduint8(ctxt, ls, 0)
+ ls.AddUint8(0)
+ ls.AddUint8(0)
+ ls.AddUint8(0)
}
// 4 zeros: the string termination + 3 fields.
- Adduint8(ctxt, ls, 0)
+ ls.AddUint8(0)
// terminate file_names.
headerend = ls.Size
- Adduint8(ctxt, ls, 0) // start extended opcode
+ ls.AddUint8(0) // start extended opcode
dwarf.Uleb128put(dwarfctxt, ls, 1+int64(ctxt.Arch.PtrSize))
- Adduint8(ctxt, ls, dwarf.DW_LNE_set_address)
+ ls.AddUint8(dwarf.DW_LNE_set_address)
pc := s.Value
line := 1
file := 1
- Addaddr(ctxt, ls, s)
+ ls.AddAddr(ctxt.Arch, s)
var pcfile Pciter
var pcline Pciter
}
if int32(file) != pcfile.value {
- Adduint8(ctxt, ls, dwarf.DW_LNS_set_file)
+ ls.AddUint8(dwarf.DW_LNS_set_file)
dwarf.Uleb128put(dwarfctxt, ls, int64(pcfile.value))
file = int(pcfile.value)
}
}
}
- Adduint8(ctxt, ls, 0) // start extended opcode
+ ls.AddUint8(0) // start extended opcode
dwarf.Uleb128put(dwarfctxt, ls, 1)
- Adduint8(ctxt, ls, dwarf.DW_LNE_end_sequence)
+ ls.AddUint8(dwarf.DW_LNE_end_sequence)
newattr(dwinfo, dwarf.DW_AT_high_pc, dwarf.DW_CLS_ADDRESS, epc+1, epcs)
- setuint32(ctxt, ls, unitLengthOffset, uint32(ls.Size-unitstart))
- setuint32(ctxt, ls, headerLengthOffset, uint32(headerend-headerstart))
+ ls.SetUint32(ctxt.Arch, unitLengthOffset, uint32(ls.Size-unitstart))
+ ls.SetUint32(ctxt.Arch, headerLengthOffset, uint32(headerend-headerstart))
return syms, funcs
}
if haslinkregister(ctxt) {
cieReserve = 32
}
- Adduint32(ctxt, fs, cieReserve) // initial length, must be multiple of thearch.ptrsize
- Adduint32(ctxt, fs, 0xffffffff) // cid.
- Adduint8(ctxt, fs, 3) // dwarf version (appendix F)
- Adduint8(ctxt, fs, 0) // augmentation ""
+ fs.AddUint32(ctxt.Arch, cieReserve) // initial length, must be multiple of thearch.ptrsize
+ fs.AddUint32(ctxt.Arch, 0xffffffff) // cid.
+ fs.AddUint8(3) // dwarf version (appendix F)
+ fs.AddUint8(0) // augmentation ""
dwarf.Uleb128put(dwarfctxt, fs, 1) // code_alignment_factor
dwarf.Sleb128put(dwarfctxt, fs, dataAlignmentFactor) // all CFI offset calculations include multiplication with this factor
dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfreglr)) // return_address_register
- Adduint8(ctxt, fs, dwarf.DW_CFA_def_cfa) // Set the current frame address..
+ fs.AddUint8(dwarf.DW_CFA_def_cfa) // Set the current frame address..
dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfregsp)) // ...to use the value in the platform's SP register (defined in l.go)...
if haslinkregister(ctxt) {
dwarf.Uleb128put(dwarfctxt, fs, int64(0)) // ...plus a 0 offset.
- Adduint8(ctxt, fs, dwarf.DW_CFA_same_value) // The platform's link register is unchanged during the prologue.
+ fs.AddUint8(dwarf.DW_CFA_same_value) // The platform's link register is unchanged during the prologue.
dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfreglr))
- Adduint8(ctxt, fs, dwarf.DW_CFA_val_offset) // The previous value...
+ fs.AddUint8(dwarf.DW_CFA_val_offset) // The previous value...
dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfregsp)) // ...of the platform's SP register...
dwarf.Uleb128put(dwarfctxt, fs, int64(0)) // ...is CFA+0.
} else {
dwarf.Uleb128put(dwarfctxt, fs, int64(ctxt.Arch.PtrSize)) // ...plus the word size (because the call instruction implicitly adds one word to the frame).
- Adduint8(ctxt, fs, dwarf.DW_CFA_offset_extended) // The previous value...
+ fs.AddUint8(dwarf.DW_CFA_offset_extended) // The previous value...
dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfreglr)) // ...of the return address...
dwarf.Uleb128put(dwarfctxt, fs, int64(-ctxt.Arch.PtrSize)/dataAlignmentFactor) // ...is saved at [CFA - (PtrSize/4)].
}
Exitf("dwarf: cieReserve too small by %d bytes.", -pad)
}
- Addbytes(fs, zeros[:pad])
+ fs.AddBytes(zeros[:pad])
var deltaBuf []byte
var pcsp Pciter
// 4 bytes: Pointer to the CIE above, at offset 0
// ptrsize: initial location
// ptrsize: address range
- Adduint32(ctxt, fs, uint32(4+2*ctxt.Arch.PtrSize+len(deltaBuf))) // length (excludes itself)
+ fs.AddUint32(ctxt.Arch, uint32(4+2*ctxt.Arch.PtrSize+len(deltaBuf))) // length (excludes itself)
if Linkmode == LinkExternal {
adddwarfref(ctxt, fs, fs, 4)
} else {
- Adduint32(ctxt, fs, 0) // CIE offset
+ fs.AddUint32(ctxt.Arch, 0) // CIE offset
}
- Addaddr(ctxt, fs, s)
- adduintxx(ctxt, fs, uint64(s.Size), ctxt.Arch.PtrSize) // address range
- Addbytes(fs, deltaBuf)
+ fs.AddAddr(ctxt.Arch, s)
+ fs.addUintXX(ctxt.Arch, uint64(s.Size), ctxt.Arch.PtrSize) // address range
+ fs.AddBytes(deltaBuf)
}
return syms
}
// Write .debug_info Compilation Unit Header (sec 7.5.1)
// Fields marked with (*) must be changed for 64-bit dwarf
// This must match COMPUNITHEADERSIZE above.
- Adduint32(ctxt, s, 0) // unit_length (*), will be filled in later.
- Adduint16(ctxt, s, 4) // dwarf version (appendix F)
+ s.AddUint32(ctxt.Arch, 0) // unit_length (*), will be filled in later.
+ s.AddUint16(ctxt.Arch, 4) // dwarf version (appendix F)
// debug_abbrev_offset (*)
adddwarfref(ctxt, s, abbrevsym, 4)
- Adduint8(ctxt, s, uint8(ctxt.Arch.PtrSize)) // address_size
+ s.AddUint8(uint8(ctxt.Arch.PtrSize)) // address_size
dwarf.Uleb128put(dwarfctxt, s, int64(compunit.Abbrev))
dwarf.PutAttrs(dwarfctxt, s, compunit.Abbrev, compunit.Attr)
cusize += child.Size
}
cusize -= 4 // exclude the length field.
- setuint32(ctxt, s, 0, uint32(cusize))
+ s.SetUint32(ctxt.Arch, 0, uint32(cusize))
newattr(compunit, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, cusize, 0)
syms = append(syms, cu...)
}
culength := uint32(getattr(compunit, dwarf.DW_AT_byte_size).Value) + 4
// Write .debug_pubnames/types Header (sec 6.1.1)
- Adduint32(ctxt, s, 0) // unit_length (*), will be filled in later.
- Adduint16(ctxt, s, 2) // dwarf version (appendix F)
+ s.AddUint32(ctxt.Arch, 0) // unit_length (*), will be filled in later.
+ s.AddUint16(ctxt.Arch, 2) // dwarf version (appendix F)
adddwarfref(ctxt, s, dtolsym(compunit.Sym), 4) // debug_info_offset (of the Comp unit Header)
- Adduint32(ctxt, s, culength) // debug_info_length
+ s.AddUint32(ctxt.Arch, culength) // debug_info_length
for die := compunit.Child; die != nil; die = die.Link {
if !ispub(die) {
Addstring(s, name)
}
- Adduint32(ctxt, s, 0)
+ s.AddUint32(ctxt.Arch, 0)
- setuint32(ctxt, s, sectionstart, uint32(s.Size-sectionstart)-4) // exclude the length field.
+ s.SetUint32(ctxt.Arch, sectionstart, uint32(s.Size-sectionstart)-4) // exclude the length field.
}
return syms
// Write .debug_aranges Header + entry (sec 6.1.2)
unitlength := uint32(headersize) + 4*uint32(ctxt.Arch.PtrSize) - 4
- Adduint32(ctxt, s, unitlength) // unit_length (*)
- Adduint16(ctxt, s, 2) // dwarf version (appendix F)
+ s.AddUint32(ctxt.Arch, unitlength) // unit_length (*)
+ s.AddUint16(ctxt.Arch, 2) // dwarf version (appendix F)
adddwarfref(ctxt, s, dtolsym(compunit.Sym), 4)
- Adduint8(ctxt, s, uint8(ctxt.Arch.PtrSize)) // address_size
- Adduint8(ctxt, s, 0) // segment_size
+ s.AddUint8(uint8(ctxt.Arch.PtrSize)) // address_size
+ s.AddUint8(0) // segment_size
padding := headersize - (4 + 2 + 4 + 1 + 1)
for i := 0; i < padding; i++ {
- Adduint8(ctxt, s, 0)
+ s.AddUint8(0)
}
- Addaddrplus(ctxt, s, b.Data.(*Symbol), b.Value-(b.Data.(*Symbol)).Value)
- adduintxx(ctxt, s, uint64(e.Value-b.Value), ctxt.Arch.PtrSize)
- adduintxx(ctxt, s, 0, ctxt.Arch.PtrSize)
- adduintxx(ctxt, s, 0, ctxt.Arch.PtrSize)
+ s.AddAddrPlus(ctxt.Arch, b.Data.(*Symbol), b.Value-(b.Data.(*Symbol)).Value)
+ s.addUintXX(ctxt.Arch, uint64(e.Value-b.Value), ctxt.Arch.PtrSize)
+ s.addUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize)
+ s.addUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize)
}
if s.Size > 0 {
syms = append(syms, s)
s := ctxt.Syms.Lookup(".debug_gdb_scripts", 0)
s.Type = SDWARFSECT
syms = append(syms, s)
- Adduint8(ctxt, s, 1) // magic 1 byte?
+ s.AddUint8(1) // magic 1 byte?
Addstring(s, gdbscript)
}
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))
}
}
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 {
// 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])
}
}
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 {
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)
}
}
}
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))
}
}
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 {
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
} 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)))
/* 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
} 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)
}
}
}
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")
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,
"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
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
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)
// 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 {
}
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)
}
}
}
// 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)
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)
}
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
}
}
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)
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.
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.
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)
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
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])
}
}
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])
}
}
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))
// 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++ {
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 {
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))
}
}
}
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 {
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)
--- /dev/null
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ld
+
+import (
+ "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
+}
break
}
}
- Symgrow(t, 3*nsections*int64(ctxt.Arch.PtrSize))
+ t.Grow(3 * nsections * int64(ctxt.Arch.PtrSize))
off := int64(0)
n := 0
if sect.Name != ".text" {
break
}
- off = setuint(ctxt, t, off, sect.Vaddr-textbase)
- off = setuint(ctxt, t, off, sect.Length)
+ off = t.SetUint(ctxt.Arch, off, sect.Vaddr-textbase)
+ off = t.SetUint(ctxt.Arch, off, sect.Length)
if n == 0 {
s := ctxt.Syms.ROLookup("runtime.text", 0)
if s == nil {
Errorf(nil, "Unable to find symbol runtime.text\n")
}
- off = setaddr(ctxt, t, off, s)
+ off = t.SetAddr(ctxt.Arch, off, s)
} else {
s := ctxt.Syms.Lookup(fmt.Sprintf("runtime.text.%d", n), 0)
if s == nil {
Errorf(nil, "Unable to find symbol runtime.text.%d\n", n)
}
- off = setaddr(ctxt, t, off, s)
+ off = t.SetAddr(ctxt.Arch, off, s)
}
n++
}
abihashgostr.Attr |= AttrReachable
abihashgostr.Type = SRODATA
hashsym := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
- Addaddr(ctxt, abihashgostr, hashsym)
- adduint(ctxt, abihashgostr, uint64(hashsym.Size))
+ abihashgostr.AddAddr(ctxt.Arch, hashsym)
+ abihashgostr.AddUint(ctxt.Arch, uint64(hashsym.Size))
}
if Buildmode == BuildmodePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil {
for _, l := range ctxt.Library {
str := ctxt.Syms.Lookup("go.link.pkghash."+l.Pkg, 0)
str.Attr |= AttrReachable
str.Type = SRODATA
- Addaddr(ctxt, str, s)
- adduint(ctxt, str, uint64(len(l.hash)))
+ str.AddAddr(ctxt.Arch, s)
+ str.AddUint(ctxt.Arch, uint64(len(l.hash)))
}
}
// This code uses several global variables that are set by pcln.go:pclntab.
moduledata := ctxt.Moduledata
// The pclntab slice
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.pclntab", 0))
- adduint(ctxt, moduledata, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
- adduint(ctxt, moduledata, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0))
+ moduledata.AddUint(ctxt.Arch, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
+ moduledata.AddUint(ctxt.Arch, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
// The ftab slice
- Addaddrplus(ctxt, moduledata, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabPclntabOffset))
- adduint(ctxt, moduledata, uint64(pclntabNfunc+1))
- adduint(ctxt, moduledata, uint64(pclntabNfunc+1))
+ moduledata.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabPclntabOffset))
+ moduledata.AddUint(ctxt.Arch, uint64(pclntabNfunc+1))
+ moduledata.AddUint(ctxt.Arch, uint64(pclntabNfunc+1))
// The filetab slice
- Addaddrplus(ctxt, moduledata, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabFiletabOffset))
- adduint(ctxt, moduledata, uint64(len(ctxt.Filesyms))+1)
- adduint(ctxt, moduledata, uint64(len(ctxt.Filesyms))+1)
+ moduledata.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabFiletabOffset))
+ moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Filesyms))+1)
+ moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Filesyms))+1)
// findfunctab
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.findfunctab", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.findfunctab", 0))
// minpc, maxpc
- Addaddr(ctxt, moduledata, pclntabFirstFunc)
- Addaddrplus(ctxt, moduledata, pclntabLastFunc, pclntabLastFunc.Size)
+ moduledata.AddAddr(ctxt.Arch, pclntabFirstFunc)
+ moduledata.AddAddrPlus(ctxt.Arch, pclntabLastFunc, pclntabLastFunc.Size)
// pointers to specific parts of the module
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.text", 0))
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.etext", 0))
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.noptrdata", 0))
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.enoptrdata", 0))
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.data", 0))
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.edata", 0))
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.bss", 0))
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.ebss", 0))
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.noptrbss", 0))
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.enoptrbss", 0))
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.end", 0))
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.gcdata", 0))
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.gcbss", 0))
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.types", 0))
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.etypes", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.text", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.etext", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.noptrdata", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.enoptrdata", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.data", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.edata", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.bss", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.ebss", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.noptrbss", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.enoptrbss", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.end", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.gcdata", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.gcbss", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.types", 0))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.etypes", 0))
// text section information
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.textsectionmap", 0))
- adduint(ctxt, moduledata, uint64(nsections))
- adduint(ctxt, moduledata, uint64(nsections))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.textsectionmap", 0))
+ moduledata.AddUint(ctxt.Arch, uint64(nsections))
+ moduledata.AddUint(ctxt.Arch, uint64(nsections))
// The typelinks slice
typelinkSym := ctxt.Syms.Lookup("runtime.typelink", 0)
ntypelinks := uint64(typelinkSym.Size) / 4
- Addaddr(ctxt, moduledata, typelinkSym)
- adduint(ctxt, moduledata, ntypelinks)
- adduint(ctxt, moduledata, ntypelinks)
+ moduledata.AddAddr(ctxt.Arch, typelinkSym)
+ moduledata.AddUint(ctxt.Arch, ntypelinks)
+ moduledata.AddUint(ctxt.Arch, ntypelinks)
// The itablinks slice
- Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.itablink", 0))
- adduint(ctxt, moduledata, uint64(nitablinks))
- adduint(ctxt, moduledata, uint64(nitablinks))
+ moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.itablink", 0))
+ moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
+ moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
// The ptab slice
if ptab := ctxt.Syms.ROLookup("go.plugin.tabs", 0); ptab != nil && ptab.Attr.Reachable() {
ptab.Attr |= AttrLocal
ptab.Type = SRODATA
nentries := uint64(len(ptab.P) / 8) // sizeof(nameOff) + sizeof(typeOff)
- Addaddr(ctxt, moduledata, ptab)
- adduint(ctxt, moduledata, nentries)
- adduint(ctxt, moduledata, nentries)
+ moduledata.AddAddr(ctxt.Arch, ptab)
+ moduledata.AddUint(ctxt.Arch, nentries)
+ moduledata.AddUint(ctxt.Arch, nentries)
} else {
- adduint(ctxt, moduledata, 0)
- adduint(ctxt, moduledata, 0)
- adduint(ctxt, moduledata, 0)
+ moduledata.AddUint(ctxt.Arch, 0)
+ moduledata.AddUint(ctxt.Arch, 0)
+ moduledata.AddUint(ctxt.Arch, 0)
}
if Buildmode == BuildmodePlugin {
addgostring(ctxt, moduledata, "go.link.thispluginpath", *flagPluginPath)
addgostring(ctxt, pkghashes, fmt.Sprintf("go.link.pkglinkhash.%d", i), string(l.hash))
// pkghashes[i].runtimehash
hash := ctxt.Syms.ROLookup("go.link.pkghash."+l.Pkg, 0)
- Addaddr(ctxt, pkghashes, hash)
+ pkghashes.AddAddr(ctxt.Arch, hash)
}
- Addaddr(ctxt, moduledata, pkghashes)
- adduint(ctxt, moduledata, uint64(len(ctxt.Library)))
- adduint(ctxt, moduledata, uint64(len(ctxt.Library)))
+ moduledata.AddAddr(ctxt.Arch, pkghashes)
+ moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Library)))
+ moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Library)))
} else {
- adduint(ctxt, moduledata, 0) // pluginpath
- adduint(ctxt, moduledata, 0)
- adduint(ctxt, moduledata, 0) // pkghashes slice
- adduint(ctxt, moduledata, 0)
- adduint(ctxt, moduledata, 0)
+ moduledata.AddUint(ctxt.Arch, 0) // pluginpath
+ moduledata.AddUint(ctxt.Arch, 0)
+ moduledata.AddUint(ctxt.Arch, 0) // pkghashes slice
+ moduledata.AddUint(ctxt.Arch, 0)
+ moduledata.AddUint(ctxt.Arch, 0)
}
if len(ctxt.Shlibs) > 0 {
thismodulename := filepath.Base(*flagOutfile)
// modulehashes[i].runtimehash
abihash := ctxt.Syms.Lookup("go.link.abihash."+modulename, 0)
abihash.Attr |= AttrReachable
- Addaddr(ctxt, modulehashes, abihash)
+ modulehashes.AddAddr(ctxt.Arch, abihash)
}
- Addaddr(ctxt, moduledata, modulehashes)
- adduint(ctxt, moduledata, uint64(len(ctxt.Shlibs)))
- adduint(ctxt, moduledata, uint64(len(ctxt.Shlibs)))
+ moduledata.AddAddr(ctxt.Arch, modulehashes)
+ moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
+ moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
}
// The rest of moduledata is zero initialized.
// compiler-provided size, so read it from the type data.
moduledatatype := ctxt.Syms.ROLookup("type.runtime.moduledata", 0)
moduledata.Size = decodetypeSize(ctxt.Arch, moduledatatype)
- Symgrow(moduledata, moduledata.Size)
+ moduledata.Grow(moduledata.Size)
lastmoduledatap := ctxt.Syms.Lookup("runtime.lastmoduledatap", 0)
if lastmoduledatap.Type != SDYNIMPORT {
lastmoduledatap.Type = SNOPTRDATA
lastmoduledatap.Size = 0 // overwrite existing value
- Addaddr(ctxt, lastmoduledatap, moduledata)
+ lastmoduledatap.AddAddr(ctxt.Arch, moduledata)
}
}
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)
// 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() {
// 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
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) {
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
}
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)
}
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 {
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
}
// 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
// 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
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")
}
//
// 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:
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)
}
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 {
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)
}
}
}
// 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)
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")
}
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
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
initfunc.Attr |= ld.AttrReachable
o := func(op ...uint8) {
for _, op1 := range op {
- ld.Adduint8(ctxt, initfunc, op1)
+ initfunc.AddUint8(op1)
}
}
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
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 {
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
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
}
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)
}
}
}
// 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 {
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")
}
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")
}