mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
2e405bde03
commit
0346664421
17 changed files with 752 additions and 739 deletions
|
|
@ -46,8 +46,8 @@ func Addcall(ctxt *ld.Link, s *ld.Symbol, t *ld.Symbol) int64 {
|
||||||
s.Attr |= ld.AttrReachable
|
s.Attr |= ld.AttrReachable
|
||||||
i := s.Size
|
i := s.Size
|
||||||
s.Size += 4
|
s.Size += 4
|
||||||
ld.Symgrow(s, s.Size)
|
s.Grow(s.Size)
|
||||||
r := ld.Addrel(s)
|
r := s.AddRel()
|
||||||
r.Sym = t
|
r.Sym = t
|
||||||
r.Off = int32(i)
|
r.Off = int32(i)
|
||||||
r.Type = objabi.R_CALL
|
r.Type = objabi.R_CALL
|
||||||
|
|
@ -72,14 +72,14 @@ func gentext(ctxt *ld.Link) {
|
||||||
initfunc.Attr |= ld.AttrReachable
|
initfunc.Attr |= ld.AttrReachable
|
||||||
o := func(op ...uint8) {
|
o := func(op ...uint8) {
|
||||||
for _, op1 := range op {
|
for _, op1 := range op {
|
||||||
ld.Adduint8(ctxt, initfunc, op1)
|
initfunc.AddUint8(op1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 0000000000000000 <local.dso_init>:
|
// 0000000000000000 <local.dso_init>:
|
||||||
// 0: 48 8d 3d 00 00 00 00 lea 0x0(%rip),%rdi # 7 <local.dso_init+0x7>
|
// 0: 48 8d 3d 00 00 00 00 lea 0x0(%rip),%rdi # 7 <local.dso_init+0x7>
|
||||||
// 3: R_X86_64_PC32 runtime.firstmoduledata-0x4
|
// 3: R_X86_64_PC32 runtime.firstmoduledata-0x4
|
||||||
o(0x48, 0x8d, 0x3d)
|
o(0x48, 0x8d, 0x3d)
|
||||||
ld.Addpcrelplus(ctxt, initfunc, ctxt.Moduledata, 0)
|
initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata, 0)
|
||||||
// 7: e8 00 00 00 00 callq c <local.dso_init+0xc>
|
// 7: e8 00 00 00 00 callq c <local.dso_init+0xc>
|
||||||
// 8: R_X86_64_PLT32 runtime.addmoduledata-0x4
|
// 8: R_X86_64_PLT32 runtime.addmoduledata-0x4
|
||||||
o(0xe8)
|
o(0xe8)
|
||||||
|
|
@ -94,7 +94,7 @@ func gentext(ctxt *ld.Link) {
|
||||||
initarray_entry.Attr |= ld.AttrReachable
|
initarray_entry.Attr |= ld.AttrReachable
|
||||||
initarray_entry.Attr |= ld.AttrLocal
|
initarray_entry.Attr |= ld.AttrLocal
|
||||||
initarray_entry.Type = ld.SINITARR
|
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 {
|
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.
|
// generated R_X86_RELATIVE instead.
|
||||||
ld.Adddynsym(ctxt, targ)
|
ld.Adddynsym(ctxt, targ)
|
||||||
rela := ctxt.Syms.Lookup(".rela", 0)
|
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 {
|
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 {
|
} else {
|
||||||
// TODO: never happens, remove.
|
// 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
|
r.Type = 256 // ignore during relocsym
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -350,8 +350,8 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
s.Sub = got.Sub
|
s.Sub = got.Sub
|
||||||
got.Sub = s
|
got.Sub = s
|
||||||
s.Value = got.Size
|
s.Value = got.Size
|
||||||
ld.Adduint64(ctxt, got, 0)
|
got.AddUint64(ctxt.Arch, 0)
|
||||||
ld.Adduint32(ctxt, ctxt.Syms.Lookup(".linkedit.got", 0), uint32(targ.Dynid))
|
ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid))
|
||||||
r.Type = 256 // ignore during relocsym
|
r.Type = 256 // ignore during relocsym
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -537,25 +537,25 @@ func elfsetupplt(ctxt *ld.Link) {
|
||||||
got := ctxt.Syms.Lookup(".got.plt", 0)
|
got := ctxt.Syms.Lookup(".got.plt", 0)
|
||||||
if plt.Size == 0 {
|
if plt.Size == 0 {
|
||||||
// pushq got+8(IP)
|
// pushq got+8(IP)
|
||||||
ld.Adduint8(ctxt, plt, 0xff)
|
plt.AddUint8(0xff)
|
||||||
|
|
||||||
ld.Adduint8(ctxt, plt, 0x35)
|
plt.AddUint8(0x35)
|
||||||
ld.Addpcrelplus(ctxt, plt, got, 8)
|
plt.AddPCRelPlus(ctxt.Arch, got, 8)
|
||||||
|
|
||||||
// jmpq got+16(IP)
|
// jmpq got+16(IP)
|
||||||
ld.Adduint8(ctxt, plt, 0xff)
|
plt.AddUint8(0xff)
|
||||||
|
|
||||||
ld.Adduint8(ctxt, plt, 0x25)
|
plt.AddUint8(0x25)
|
||||||
ld.Addpcrelplus(ctxt, plt, got, 16)
|
plt.AddPCRelPlus(ctxt.Arch, got, 16)
|
||||||
|
|
||||||
// nopl 0(AX)
|
// nopl 0(AX)
|
||||||
ld.Adduint32(ctxt, plt, 0x00401f0f)
|
plt.AddUint32(ctxt.Arch, 0x00401f0f)
|
||||||
|
|
||||||
// assume got->size == 0 too
|
// 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)
|
got.AddUint64(ctxt.Arch, 0)
|
||||||
ld.Adduint64(ctxt, got, 0)
|
got.AddUint64(ctxt.Arch, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -575,29 +575,29 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// jmpq *got+size(IP)
|
// jmpq *got+size(IP)
|
||||||
ld.Adduint8(ctxt, plt, 0xff)
|
plt.AddUint8(0xff)
|
||||||
|
|
||||||
ld.Adduint8(ctxt, plt, 0x25)
|
plt.AddUint8(0x25)
|
||||||
ld.Addpcrelplus(ctxt, plt, got, got.Size)
|
plt.AddPCRelPlus(ctxt.Arch, got, got.Size)
|
||||||
|
|
||||||
// add to got: pointer to current pos in plt
|
// 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
|
// 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
|
// 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
|
// 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))
|
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_JMP_SLOT))
|
||||||
ld.Adduint64(ctxt, rela, 0)
|
rela.AddUint64(ctxt.Arch, 0)
|
||||||
|
|
||||||
s.Plt = int32(plt.Size - 16)
|
s.Plt = int32(plt.Size - 16)
|
||||||
} else if ld.Headtype == objabi.Hdarwin {
|
} else if ld.Headtype == objabi.Hdarwin {
|
||||||
|
|
@ -614,14 +614,14 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
|
||||||
addgotsym(ctxt, s)
|
addgotsym(ctxt, s)
|
||||||
plt := ctxt.Syms.Lookup(".plt", 0)
|
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)
|
// jmpq *got+size(IP)
|
||||||
s.Plt = int32(plt.Size)
|
s.Plt = int32(plt.Size)
|
||||||
|
|
||||||
ld.Adduint8(ctxt, plt, 0xff)
|
plt.AddUint8(0xff)
|
||||||
ld.Adduint8(ctxt, plt, 0x25)
|
plt.AddUint8(0x25)
|
||||||
ld.Addpcrelplus(ctxt, plt, ctxt.Syms.Lookup(".got", 0), int64(s.Got))
|
plt.AddPCRelPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got))
|
||||||
} else {
|
} else {
|
||||||
ld.Errorf(s, "addpltsym: unsupported binary format")
|
ld.Errorf(s, "addpltsym: unsupported binary format")
|
||||||
}
|
}
|
||||||
|
|
@ -635,15 +635,15 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
|
||||||
ld.Adddynsym(ctxt, s)
|
ld.Adddynsym(ctxt, s)
|
||||||
got := ctxt.Syms.Lookup(".got", 0)
|
got := ctxt.Syms.Lookup(".got", 0)
|
||||||
s.Got = int32(got.Size)
|
s.Got = int32(got.Size)
|
||||||
ld.Adduint64(ctxt, got, 0)
|
got.AddUint64(ctxt.Arch, 0)
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
rela := ctxt.Syms.Lookup(".rela", 0)
|
rela := ctxt.Syms.Lookup(".rela", 0)
|
||||||
ld.Addaddrplus(ctxt, rela, got, int64(s.Got))
|
rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
|
||||||
ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_GLOB_DAT))
|
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_GLOB_DAT))
|
||||||
ld.Adduint64(ctxt, rela, 0)
|
rela.AddUint64(ctxt.Arch, 0)
|
||||||
} else if ld.Headtype == objabi.Hdarwin {
|
} 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 {
|
} else {
|
||||||
ld.Errorf(s, "addgotsym: unsupported binary format")
|
ld.Errorf(s, "addgotsym: unsupported binary format")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,13 +75,13 @@ func gentext(ctxt *ld.Link) {
|
||||||
initfunc.Attr |= ld.AttrLocal
|
initfunc.Attr |= ld.AttrLocal
|
||||||
initfunc.Attr |= ld.AttrReachable
|
initfunc.Attr |= ld.AttrReachable
|
||||||
o := func(op uint32) {
|
o := func(op uint32) {
|
||||||
ld.Adduint32(ctxt, initfunc, op)
|
initfunc.AddUint32(ctxt.Arch, op)
|
||||||
}
|
}
|
||||||
o(0xe59f0004)
|
o(0xe59f0004)
|
||||||
o(0xe08f0000)
|
o(0xe08f0000)
|
||||||
|
|
||||||
o(0xeafffffe)
|
o(0xeafffffe)
|
||||||
rel := ld.Addrel(initfunc)
|
rel := initfunc.AddRel()
|
||||||
rel.Off = 8
|
rel.Off = 8
|
||||||
rel.Siz = 4
|
rel.Siz = 4
|
||||||
rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
||||||
|
|
@ -89,7 +89,7 @@ func gentext(ctxt *ld.Link) {
|
||||||
rel.Add = 0xeafffffe // vomit
|
rel.Add = 0xeafffffe // vomit
|
||||||
|
|
||||||
o(0x00000000)
|
o(0x00000000)
|
||||||
rel = ld.Addrel(initfunc)
|
rel = initfunc.AddRel()
|
||||||
rel.Off = 12
|
rel.Off = 12
|
||||||
rel.Siz = 4
|
rel.Siz = 4
|
||||||
rel.Sym = ctxt.Moduledata
|
rel.Sym = ctxt.Moduledata
|
||||||
|
|
@ -104,7 +104,7 @@ func gentext(ctxt *ld.Link) {
|
||||||
initarray_entry.Attr |= ld.AttrReachable
|
initarray_entry.Attr |= ld.AttrReachable
|
||||||
initarray_entry.Attr |= ld.AttrLocal
|
initarray_entry.Attr |= ld.AttrLocal
|
||||||
initarray_entry.Type = ld.SINITARR
|
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
|
// 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 {
|
if ld.Iself {
|
||||||
ld.Adddynsym(ctxt, targ)
|
ld.Adddynsym(ctxt, targ)
|
||||||
rel := ctxt.Syms.Lookup(".rel", 0)
|
rel := ctxt.Syms.Lookup(".rel", 0)
|
||||||
ld.Addaddrplus(ctxt, rel, s, int64(r.Off))
|
rel.AddAddrPlus(ctxt.Arch, 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
|
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.Type = objabi.R_CONST // write r->add during relocsym
|
||||||
r.Sym = nil
|
r.Sym = nil
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -299,25 +299,25 @@ func elfsetupplt(ctxt *ld.Link) {
|
||||||
got := ctxt.Syms.Lookup(".got.plt", 0)
|
got := ctxt.Syms.Lookup(".got.plt", 0)
|
||||||
if plt.Size == 0 {
|
if plt.Size == 0 {
|
||||||
// str lr, [sp, #-4]!
|
// str lr, [sp, #-4]!
|
||||||
ld.Adduint32(ctxt, plt, 0xe52de004)
|
plt.AddUint32(ctxt.Arch, 0xe52de004)
|
||||||
|
|
||||||
// ldr lr, [pc, #4]
|
// ldr lr, [pc, #4]
|
||||||
ld.Adduint32(ctxt, plt, 0xe59fe004)
|
plt.AddUint32(ctxt.Arch, 0xe59fe004)
|
||||||
|
|
||||||
// add lr, pc, lr
|
// add lr, pc, lr
|
||||||
ld.Adduint32(ctxt, plt, 0xe08fe00e)
|
plt.AddUint32(ctxt.Arch, 0xe08fe00e)
|
||||||
|
|
||||||
// ldr pc, [lr, #8]!
|
// ldr pc, [lr, #8]!
|
||||||
ld.Adduint32(ctxt, plt, 0xe5bef008)
|
plt.AddUint32(ctxt.Arch, 0xe5bef008)
|
||||||
|
|
||||||
// .word &GLOBAL_OFFSET_TABLE[0] - .
|
// .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
|
// the first .plt entry requires 3 .plt.got entries
|
||||||
ld.Adduint32(ctxt, got, 0)
|
got.AddUint32(ctxt.Arch, 0)
|
||||||
|
|
||||||
ld.Adduint32(ctxt, got, 0)
|
got.AddUint32(ctxt.Arch, 0)
|
||||||
ld.Adduint32(ctxt, got, 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)
|
arch.ByteOrder.PutUint32(tramp.P[8:], o3)
|
||||||
|
|
||||||
if ld.Linkmode == ld.LinkExternal {
|
if ld.Linkmode == ld.LinkExternal {
|
||||||
r := ld.Addrel(tramp)
|
r := tramp.AddRel()
|
||||||
r.Off = 8
|
r.Off = 8
|
||||||
r.Type = objabi.R_ADDR
|
r.Type = objabi.R_ADDR
|
||||||
r.Siz = 4
|
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[8:], o3)
|
||||||
arch.ByteOrder.PutUint32(tramp.P[12:], o4)
|
arch.ByteOrder.PutUint32(tramp.P[12:], o4)
|
||||||
|
|
||||||
r := ld.Addrel(tramp)
|
r := tramp.AddRel()
|
||||||
r.Off = 12
|
r.Off = 12
|
||||||
r.Type = objabi.R_PCREL
|
r.Type = objabi.R_PCREL
|
||||||
r.Siz = 4
|
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)
|
arch.ByteOrder.PutUint32(tramp.P[20:], o6)
|
||||||
}
|
}
|
||||||
|
|
||||||
r := ld.Addrel(tramp)
|
r := tramp.AddRel()
|
||||||
r.Off = 16
|
r.Off = 16
|
||||||
r.Type = objabi.R_GOTPCREL
|
r.Type = objabi.R_GOTPCREL
|
||||||
r.Siz = 4
|
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 {
|
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.Sym = got
|
||||||
r.Off = int32(plt.Size)
|
r.Off = int32(plt.Size)
|
||||||
r.Siz = 4
|
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.Attr |= ld.AttrReachable
|
||||||
plt.Size += 4
|
plt.Size += 4
|
||||||
ld.Symgrow(plt, plt.Size)
|
plt.Grow(plt.Size)
|
||||||
|
|
||||||
return r
|
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,
|
// 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
|
// 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.
|
// 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
|
// .plt entry, this depends on the .got entry
|
||||||
s.Plt = int32(plt.Size)
|
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]!
|
addpltreloc(ctxt, plt, got, s, objabi.R_PLT2) // ldr pc, [lr, #0xZZZ]!
|
||||||
|
|
||||||
// rel
|
// 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 {
|
} else {
|
||||||
ld.Errorf(s, "addpltsym: unsupported binary format")
|
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)
|
got := ctxt.Syms.Lookup(".got", 0)
|
||||||
s.Got = int32(got.Size)
|
s.Got = int32(got.Size)
|
||||||
|
|
||||||
ld.Addaddrplus(ctxt, got, s, 0)
|
got.AddAddrPlus(ctxt.Arch, s, 0)
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -725,12 +725,12 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
|
||||||
ld.Adddynsym(ctxt, s)
|
ld.Adddynsym(ctxt, s)
|
||||||
got := ctxt.Syms.Lookup(".got", 0)
|
got := ctxt.Syms.Lookup(".got", 0)
|
||||||
s.Got = int32(got.Size)
|
s.Got = int32(got.Size)
|
||||||
ld.Adduint32(ctxt, got, 0)
|
got.AddUint32(ctxt.Arch, 0)
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
rel := ctxt.Syms.Lookup(".rel", 0)
|
rel := ctxt.Syms.Lookup(".rel", 0)
|
||||||
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_GLOB_DAT))
|
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_ARM_GLOB_DAT))
|
||||||
} else {
|
} else {
|
||||||
ld.Errorf(s, "addgotsym: unsupported binary format")
|
ld.Errorf(s, "addgotsym: unsupported binary format")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ func gentext(ctxt *ld.Link) {
|
||||||
initfunc.Attr |= ld.AttrLocal
|
initfunc.Attr |= ld.AttrLocal
|
||||||
initfunc.Attr |= ld.AttrReachable
|
initfunc.Attr |= ld.AttrReachable
|
||||||
o := func(op uint32) {
|
o := func(op uint32) {
|
||||||
ld.Adduint32(ctxt, initfunc, op)
|
initfunc.AddUint32(ctxt.Arch, op)
|
||||||
}
|
}
|
||||||
// 0000000000000000 <local.dso_init>:
|
// 0000000000000000 <local.dso_init>:
|
||||||
// 0: 90000000 adrp x0, 0 <runtime.firstmoduledata>
|
// 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
|
// 4: R_AARCH64_ADD_ABS_LO12_NC local.moduledata
|
||||||
o(0x90000000)
|
o(0x90000000)
|
||||||
o(0x91000000)
|
o(0x91000000)
|
||||||
rel := ld.Addrel(initfunc)
|
rel := initfunc.AddRel()
|
||||||
rel.Off = 0
|
rel.Off = 0
|
||||||
rel.Siz = 8
|
rel.Siz = 8
|
||||||
rel.Sym = ctxt.Moduledata
|
rel.Sym = ctxt.Moduledata
|
||||||
|
|
@ -73,7 +73,7 @@ func gentext(ctxt *ld.Link) {
|
||||||
// 8: 14000000 bl 0 <runtime.addmoduledata>
|
// 8: 14000000 bl 0 <runtime.addmoduledata>
|
||||||
// 8: R_AARCH64_CALL26 runtime.addmoduledata
|
// 8: R_AARCH64_CALL26 runtime.addmoduledata
|
||||||
o(0x14000000)
|
o(0x14000000)
|
||||||
rel = ld.Addrel(initfunc)
|
rel = initfunc.AddRel()
|
||||||
rel.Off = 8
|
rel.Off = 8
|
||||||
rel.Siz = 4
|
rel.Siz = 4
|
||||||
rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
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.AttrReachable
|
||||||
initarray_entry.Attr |= ld.AttrLocal
|
initarray_entry.Attr |= ld.AttrLocal
|
||||||
initarray_entry.Type = ld.SINITARR
|
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 {
|
func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
|
|
|
||||||
|
|
@ -44,203 +44,6 @@ import (
|
||||||
"sync"
|
"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.
|
* 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).
|
* 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
|
// jmp *addr
|
||||||
if ctxt.Arch.Family == sys.I386 {
|
if ctxt.Arch.Family == sys.I386 {
|
||||||
Adduint8(ctxt, rel, 0xff)
|
rel.AddUint8(0xff)
|
||||||
Adduint8(ctxt, rel, 0x25)
|
rel.AddUint8(0x25)
|
||||||
Addaddr(ctxt, rel, targ)
|
rel.AddAddr(ctxt.Arch, targ)
|
||||||
Adduint8(ctxt, rel, 0x90)
|
rel.AddUint8(0x90)
|
||||||
Adduint8(ctxt, rel, 0x90)
|
rel.AddUint8(0x90)
|
||||||
} else {
|
} else {
|
||||||
Adduint8(ctxt, rel, 0xff)
|
rel.AddUint8(0xff)
|
||||||
Adduint8(ctxt, rel, 0x24)
|
rel.AddUint8(0x24)
|
||||||
Adduint8(ctxt, rel, 0x25)
|
rel.AddUint8(0x25)
|
||||||
addaddrplus4(ctxt, rel, targ, 0)
|
rel.AddAddrPlus4(targ, 0)
|
||||||
Adduint8(ctxt, rel, 0x90)
|
rel.AddUint8(0x90)
|
||||||
}
|
}
|
||||||
} else if r.Sym.Plt >= 0 {
|
} else if r.Sym.Plt >= 0 {
|
||||||
r.Sym = rel
|
r.Sym = rel
|
||||||
|
|
@ -1063,8 +866,8 @@ func addstrdata(ctxt *Link, name string, value string) {
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
s.Attr |= AttrDuplicateOK
|
s.Attr |= AttrDuplicateOK
|
||||||
reachable := s.Attr.Reachable()
|
reachable := s.Attr.Reachable()
|
||||||
Addaddr(ctxt, s, sp)
|
s.AddAddr(ctxt.Arch, sp)
|
||||||
adduintxx(ctxt, s, uint64(len(value)), ctxt.Arch.PtrSize)
|
s.AddUint(ctxt.Arch, uint64(len(value)))
|
||||||
|
|
||||||
// addstring, addaddr, etc., mark the symbols as reachable.
|
// addstring, addaddr, etc., mark the symbols as reachable.
|
||||||
// In this case that is not necessarily true, so stick to what
|
// 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.Type = SRODATA
|
||||||
sym.Size = int64(len(str))
|
sym.Size = int64(len(str))
|
||||||
sym.P = []byte(str)
|
sym.P = []byte(str)
|
||||||
Addaddr(ctxt, s, sym)
|
s.AddAddr(ctxt.Arch, sym)
|
||||||
adduint(ctxt, s, uint64(len(str)))
|
s.AddUint(ctxt.Arch, uint64(len(str)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func addinitarrdata(ctxt *Link, s *Symbol) {
|
func addinitarrdata(ctxt *Link, s *Symbol) {
|
||||||
|
|
@ -1123,7 +926,7 @@ func addinitarrdata(ctxt *Link, s *Symbol) {
|
||||||
sp.Type = SINITARR
|
sp.Type = SINITARR
|
||||||
sp.Size = 0
|
sp.Size = 0
|
||||||
sp.Attr |= AttrDuplicateOK
|
sp.Attr |= AttrDuplicateOK
|
||||||
Addaddr(ctxt, sp, s)
|
sp.AddAddr(ctxt.Arch, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func dosymtype(ctxt *Link) {
|
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) {
|
func (p *GCProg) writeByte(ctxt *Link) func(x byte) {
|
||||||
return func(x byte) {
|
return func(x byte) {
|
||||||
Adduint8(ctxt, p.sym, x)
|
p.sym.AddUint8(x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,11 @@ func (c dwctxt) PtrSize() int {
|
||||||
}
|
}
|
||||||
func (c dwctxt) AddInt(s dwarf.Sym, size int, i int64) {
|
func (c dwctxt) AddInt(s dwarf.Sym, size int, i int64) {
|
||||||
ls := s.(*Symbol)
|
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) {
|
func (c dwctxt) AddBytes(s dwarf.Sym, b []byte) {
|
||||||
ls := s.(*Symbol)
|
ls := s.(*Symbol)
|
||||||
Addbytes(ls, b)
|
ls.AddBytes(b)
|
||||||
}
|
}
|
||||||
func (c dwctxt) AddString(s dwarf.Sym, v string) {
|
func (c dwctxt) AddString(s dwarf.Sym, v string) {
|
||||||
Addstring(s.(*Symbol), v)
|
Addstring(s.(*Symbol), v)
|
||||||
|
|
@ -49,7 +49,7 @@ func (c dwctxt) AddAddress(s dwarf.Sym, data interface{}, value int64) {
|
||||||
if value != 0 {
|
if value != 0 {
|
||||||
value -= (data.(*Symbol)).Value
|
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) {
|
func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64) {
|
||||||
|
|
@ -59,9 +59,9 @@ func (c dwctxt) AddSectionOffset(s dwarf.Sym, size int, t interface{}, ofs int64
|
||||||
Errorf(ls, "invalid size %d in adddwarfref\n", size)
|
Errorf(ls, "invalid size %d in adddwarfref\n", size)
|
||||||
fallthrough
|
fallthrough
|
||||||
case c.linkctxt.Arch.PtrSize:
|
case c.linkctxt.Arch.PtrSize:
|
||||||
Addaddr(c.linkctxt, ls, t.(*Symbol))
|
ls.AddAddr(c.linkctxt.Arch, t.(*Symbol))
|
||||||
case 4:
|
case 4:
|
||||||
addaddrplus4(c.linkctxt, ls, t.(*Symbol), 0)
|
ls.AddAddrPlus4(t.(*Symbol), 0)
|
||||||
}
|
}
|
||||||
r := &ls.R[len(ls.R)-1]
|
r := &ls.R[len(ls.R)-1]
|
||||||
r.Type = objabi.R_DWARFREF
|
r.Type = objabi.R_DWARFREF
|
||||||
|
|
@ -75,7 +75,7 @@ var dwarfp []*Symbol
|
||||||
func writeabbrev(ctxt *Link) *Symbol {
|
func writeabbrev(ctxt *Link) *Symbol {
|
||||||
s := ctxt.Syms.Lookup(".debug_abbrev", 0)
|
s := ctxt.Syms.Lookup(".debug_abbrev", 0)
|
||||||
s.Type = SDWARFSECT
|
s.Type = SDWARFSECT
|
||||||
Addbytes(s, dwarf.GetAbbrev())
|
s.AddBytes(dwarf.GetAbbrev())
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -213,9 +213,9 @@ func adddwarfref(ctxt *Link, s *Symbol, t *Symbol, size int) int64 {
|
||||||
Errorf(s, "invalid size %d in adddwarfref\n", size)
|
Errorf(s, "invalid size %d in adddwarfref\n", size)
|
||||||
fallthrough
|
fallthrough
|
||||||
case ctxt.Arch.PtrSize:
|
case ctxt.Arch.PtrSize:
|
||||||
result = Addaddr(ctxt, s, t)
|
result = s.AddAddr(ctxt.Arch, t)
|
||||||
case 4:
|
case 4:
|
||||||
result = addaddrplus4(ctxt, s, t, 0)
|
result = s.AddAddrPlus4(t, 0)
|
||||||
}
|
}
|
||||||
r := &s.R[len(s.R)-1]
|
r := &s.R[len(s.R)-1]
|
||||||
r.Type = objabi.R_DWARFREF
|
r.Type = objabi.R_DWARFREF
|
||||||
|
|
@ -233,7 +233,7 @@ func putdies(linkctxt *Link, ctxt dwarf.Context, syms []*Symbol, die *dwarf.DWDi
|
||||||
for ; die != nil; die = die.Link {
|
for ; die != nil; die = die.Link {
|
||||||
syms = putdie(linkctxt, ctxt, syms, die)
|
syms = putdie(linkctxt, ctxt, syms, die)
|
||||||
}
|
}
|
||||||
Adduint8(linkctxt, syms[len(syms)-1], 0)
|
syms[len(syms)-1].AddUint8(0)
|
||||||
|
|
||||||
return syms
|
return syms
|
||||||
}
|
}
|
||||||
|
|
@ -942,24 +942,24 @@ func putpclcdelta(linkctxt *Link, ctxt dwarf.Context, s *Symbol, deltaPC uint64,
|
||||||
if opcode < OPCODE_BASE {
|
if opcode < OPCODE_BASE {
|
||||||
panic(fmt.Sprintf("produced invalid special opcode %d", opcode))
|
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) {
|
} else if (1<<14) <= deltaPC && deltaPC < (1<<16) {
|
||||||
Adduint8(linkctxt, s, dwarf.DW_LNS_fixed_advance_pc)
|
s.AddUint8(dwarf.DW_LNS_fixed_advance_pc)
|
||||||
Adduint16(linkctxt, s, uint16(deltaPC))
|
s.AddUint16(linkctxt.Arch, uint16(deltaPC))
|
||||||
} else {
|
} else {
|
||||||
Adduint8(linkctxt, s, dwarf.DW_LNS_advance_pc)
|
s.AddUint8(dwarf.DW_LNS_advance_pc)
|
||||||
dwarf.Uleb128put(ctxt, s, int64(deltaPC))
|
dwarf.Uleb128put(ctxt, s, int64(deltaPC))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encode deltaLC.
|
// Encode deltaLC.
|
||||||
if deltaLC != 0 {
|
if deltaLC != 0 {
|
||||||
Adduint8(linkctxt, s, dwarf.DW_LNS_advance_line)
|
s.AddUint8(dwarf.DW_LNS_advance_line)
|
||||||
dwarf.Sleb128put(ctxt, s, deltaLC)
|
dwarf.Sleb128put(ctxt, s, deltaLC)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output the special opcode.
|
// Output the special opcode.
|
||||||
Adduint8(linkctxt, s, uint8(opcode))
|
s.AddUint8(uint8(opcode))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1024,50 +1024,50 @@ func writelines(ctxt *Link, syms []*Symbol) ([]*Symbol, []*Symbol) {
|
||||||
// Write .debug_line Line Number Program Header (sec 6.2.4)
|
// Write .debug_line Line Number Program Header (sec 6.2.4)
|
||||||
// Fields marked with (*) must be changed for 64-bit dwarf
|
// Fields marked with (*) must be changed for 64-bit dwarf
|
||||||
unitLengthOffset := ls.Size
|
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
|
unitstart = ls.Size
|
||||||
Adduint16(ctxt, ls, 2) // dwarf version (appendix F)
|
ls.AddUint16(ctxt.Arch, 2) // dwarf version (appendix F)
|
||||||
headerLengthOffset := ls.Size
|
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
|
headerstart = ls.Size
|
||||||
|
|
||||||
// cpos == unitstart + 4 + 2 + 4
|
// cpos == unitstart + 4 + 2 + 4
|
||||||
Adduint8(ctxt, ls, 1) // minimum_instruction_length
|
ls.AddUint8(1) // minimum_instruction_length
|
||||||
Adduint8(ctxt, ls, 1) // default_is_stmt
|
ls.AddUint8(1) // default_is_stmt
|
||||||
Adduint8(ctxt, ls, LINE_BASE&0xFF) // line_base
|
ls.AddUint8(LINE_BASE & 0xFF) // line_base
|
||||||
Adduint8(ctxt, ls, LINE_RANGE) // line_range
|
ls.AddUint8(LINE_RANGE) // line_range
|
||||||
Adduint8(ctxt, ls, OPCODE_BASE) // opcode_base
|
ls.AddUint8(OPCODE_BASE) // opcode_base
|
||||||
Adduint8(ctxt, ls, 0) // standard_opcode_lengths[1]
|
ls.AddUint8(0) // standard_opcode_lengths[1]
|
||||||
Adduint8(ctxt, ls, 1) // standard_opcode_lengths[2]
|
ls.AddUint8(1) // standard_opcode_lengths[2]
|
||||||
Adduint8(ctxt, ls, 1) // standard_opcode_lengths[3]
|
ls.AddUint8(1) // standard_opcode_lengths[3]
|
||||||
Adduint8(ctxt, ls, 1) // standard_opcode_lengths[4]
|
ls.AddUint8(1) // standard_opcode_lengths[4]
|
||||||
Adduint8(ctxt, ls, 1) // standard_opcode_lengths[5]
|
ls.AddUint8(1) // standard_opcode_lengths[5]
|
||||||
Adduint8(ctxt, ls, 0) // standard_opcode_lengths[6]
|
ls.AddUint8(0) // standard_opcode_lengths[6]
|
||||||
Adduint8(ctxt, ls, 0) // standard_opcode_lengths[7]
|
ls.AddUint8(0) // standard_opcode_lengths[7]
|
||||||
Adduint8(ctxt, ls, 0) // standard_opcode_lengths[8]
|
ls.AddUint8(0) // standard_opcode_lengths[8]
|
||||||
Adduint8(ctxt, ls, 1) // standard_opcode_lengths[9]
|
ls.AddUint8(1) // standard_opcode_lengths[9]
|
||||||
Adduint8(ctxt, ls, 0) // include_directories (empty)
|
ls.AddUint8(0) // include_directories (empty)
|
||||||
|
|
||||||
for _, f := range ctxt.Filesyms {
|
for _, f := range ctxt.Filesyms {
|
||||||
Addstring(ls, f.Name)
|
Addstring(ls, f.Name)
|
||||||
Adduint8(ctxt, ls, 0)
|
ls.AddUint8(0)
|
||||||
Adduint8(ctxt, ls, 0)
|
ls.AddUint8(0)
|
||||||
Adduint8(ctxt, ls, 0)
|
ls.AddUint8(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4 zeros: the string termination + 3 fields.
|
// 4 zeros: the string termination + 3 fields.
|
||||||
Adduint8(ctxt, ls, 0)
|
ls.AddUint8(0)
|
||||||
// terminate file_names.
|
// terminate file_names.
|
||||||
headerend = ls.Size
|
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))
|
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
|
pc := s.Value
|
||||||
line := 1
|
line := 1
|
||||||
file := 1
|
file := 1
|
||||||
Addaddr(ctxt, ls, s)
|
ls.AddAddr(ctxt.Arch, s)
|
||||||
|
|
||||||
var pcfile Pciter
|
var pcfile Pciter
|
||||||
var pcline Pciter
|
var pcline Pciter
|
||||||
|
|
@ -1100,7 +1100,7 @@ func writelines(ctxt *Link, syms []*Symbol) ([]*Symbol, []*Symbol) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if int32(file) != pcfile.value {
|
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))
|
dwarf.Uleb128put(dwarfctxt, ls, int64(pcfile.value))
|
||||||
file = int(pcfile.value)
|
file = int(pcfile.value)
|
||||||
}
|
}
|
||||||
|
|
@ -1118,14 +1118,14 @@ func writelines(ctxt *Link, syms []*Symbol) ([]*Symbol, []*Symbol) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Adduint8(ctxt, ls, 0) // start extended opcode
|
ls.AddUint8(0) // start extended opcode
|
||||||
dwarf.Uleb128put(dwarfctxt, ls, 1)
|
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)
|
newattr(dwinfo, dwarf.DW_AT_high_pc, dwarf.DW_CLS_ADDRESS, epc+1, epcs)
|
||||||
|
|
||||||
setuint32(ctxt, ls, unitLengthOffset, uint32(ls.Size-unitstart))
|
ls.SetUint32(ctxt.Arch, unitLengthOffset, uint32(ls.Size-unitstart))
|
||||||
setuint32(ctxt, ls, headerLengthOffset, uint32(headerend-headerstart))
|
ls.SetUint32(ctxt.Arch, headerLengthOffset, uint32(headerend-headerstart))
|
||||||
|
|
||||||
return syms, funcs
|
return syms, funcs
|
||||||
}
|
}
|
||||||
|
|
@ -1170,29 +1170,29 @@ func writeframes(ctxt *Link, syms []*Symbol) []*Symbol {
|
||||||
if haslinkregister(ctxt) {
|
if haslinkregister(ctxt) {
|
||||||
cieReserve = 32
|
cieReserve = 32
|
||||||
}
|
}
|
||||||
Adduint32(ctxt, fs, cieReserve) // initial length, must be multiple of thearch.ptrsize
|
fs.AddUint32(ctxt.Arch, cieReserve) // initial length, must be multiple of thearch.ptrsize
|
||||||
Adduint32(ctxt, fs, 0xffffffff) // cid.
|
fs.AddUint32(ctxt.Arch, 0xffffffff) // cid.
|
||||||
Adduint8(ctxt, fs, 3) // dwarf version (appendix F)
|
fs.AddUint8(3) // dwarf version (appendix F)
|
||||||
Adduint8(ctxt, fs, 0) // augmentation ""
|
fs.AddUint8(0) // augmentation ""
|
||||||
dwarf.Uleb128put(dwarfctxt, fs, 1) // code_alignment_factor
|
dwarf.Uleb128put(dwarfctxt, fs, 1) // code_alignment_factor
|
||||||
dwarf.Sleb128put(dwarfctxt, fs, dataAlignmentFactor) // all CFI offset calculations include multiplication with this 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
|
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)...
|
dwarf.Uleb128put(dwarfctxt, fs, int64(Thearch.Dwarfregsp)) // ...to use the value in the platform's SP register (defined in l.go)...
|
||||||
if haslinkregister(ctxt) {
|
if haslinkregister(ctxt) {
|
||||||
dwarf.Uleb128put(dwarfctxt, fs, int64(0)) // ...plus a 0 offset.
|
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))
|
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(Thearch.Dwarfregsp)) // ...of the platform's SP register...
|
||||||
dwarf.Uleb128put(dwarfctxt, fs, int64(0)) // ...is CFA+0.
|
dwarf.Uleb128put(dwarfctxt, fs, int64(0)) // ...is CFA+0.
|
||||||
} else {
|
} else {
|
||||||
dwarf.Uleb128put(dwarfctxt, fs, int64(ctxt.Arch.PtrSize)) // ...plus the word size (because the call instruction implicitly adds one word to the frame).
|
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(Thearch.Dwarfreglr)) // ...of the return address...
|
||||||
dwarf.Uleb128put(dwarfctxt, fs, int64(-ctxt.Arch.PtrSize)/dataAlignmentFactor) // ...is saved at [CFA - (PtrSize/4)].
|
dwarf.Uleb128put(dwarfctxt, fs, int64(-ctxt.Arch.PtrSize)/dataAlignmentFactor) // ...is saved at [CFA - (PtrSize/4)].
|
||||||
}
|
}
|
||||||
|
|
@ -1204,7 +1204,7 @@ func writeframes(ctxt *Link, syms []*Symbol) []*Symbol {
|
||||||
Exitf("dwarf: cieReserve too small by %d bytes.", -pad)
|
Exitf("dwarf: cieReserve too small by %d bytes.", -pad)
|
||||||
}
|
}
|
||||||
|
|
||||||
Addbytes(fs, zeros[:pad])
|
fs.AddBytes(zeros[:pad])
|
||||||
|
|
||||||
var deltaBuf []byte
|
var deltaBuf []byte
|
||||||
var pcsp Pciter
|
var pcsp Pciter
|
||||||
|
|
@ -1257,15 +1257,15 @@ func writeframes(ctxt *Link, syms []*Symbol) []*Symbol {
|
||||||
// 4 bytes: Pointer to the CIE above, at offset 0
|
// 4 bytes: Pointer to the CIE above, at offset 0
|
||||||
// ptrsize: initial location
|
// ptrsize: initial location
|
||||||
// ptrsize: address range
|
// 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 {
|
if Linkmode == LinkExternal {
|
||||||
adddwarfref(ctxt, fs, fs, 4)
|
adddwarfref(ctxt, fs, fs, 4)
|
||||||
} else {
|
} else {
|
||||||
Adduint32(ctxt, fs, 0) // CIE offset
|
fs.AddUint32(ctxt.Arch, 0) // CIE offset
|
||||||
}
|
}
|
||||||
Addaddr(ctxt, fs, s)
|
fs.AddAddr(ctxt.Arch, s)
|
||||||
adduintxx(ctxt, fs, uint64(s.Size), ctxt.Arch.PtrSize) // address range
|
fs.addUintXX(ctxt.Arch, uint64(s.Size), ctxt.Arch.PtrSize) // address range
|
||||||
Addbytes(fs, deltaBuf)
|
fs.AddBytes(deltaBuf)
|
||||||
}
|
}
|
||||||
return syms
|
return syms
|
||||||
}
|
}
|
||||||
|
|
@ -1319,13 +1319,13 @@ func writeinfo(ctxt *Link, syms []*Symbol, funcs, consts []*Symbol, abbrevsym *S
|
||||||
// Write .debug_info Compilation Unit Header (sec 7.5.1)
|
// Write .debug_info Compilation Unit Header (sec 7.5.1)
|
||||||
// Fields marked with (*) must be changed for 64-bit dwarf
|
// Fields marked with (*) must be changed for 64-bit dwarf
|
||||||
// This must match COMPUNITHEADERSIZE above.
|
// This must match COMPUNITHEADERSIZE above.
|
||||||
Adduint32(ctxt, s, 0) // unit_length (*), will be filled in later.
|
s.AddUint32(ctxt.Arch, 0) // unit_length (*), will be filled in later.
|
||||||
Adduint16(ctxt, s, 4) // dwarf version (appendix F)
|
s.AddUint16(ctxt.Arch, 4) // dwarf version (appendix F)
|
||||||
|
|
||||||
// debug_abbrev_offset (*)
|
// debug_abbrev_offset (*)
|
||||||
adddwarfref(ctxt, s, abbrevsym, 4)
|
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.Uleb128put(dwarfctxt, s, int64(compunit.Abbrev))
|
||||||
dwarf.PutAttrs(dwarfctxt, s, compunit.Abbrev, compunit.Attr)
|
dwarf.PutAttrs(dwarfctxt, s, compunit.Abbrev, compunit.Attr)
|
||||||
|
|
@ -1345,7 +1345,7 @@ func writeinfo(ctxt *Link, syms []*Symbol, funcs, consts []*Symbol, abbrevsym *S
|
||||||
cusize += child.Size
|
cusize += child.Size
|
||||||
}
|
}
|
||||||
cusize -= 4 // exclude the length field.
|
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)
|
newattr(compunit, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, cusize, 0)
|
||||||
syms = append(syms, cu...)
|
syms = append(syms, cu...)
|
||||||
}
|
}
|
||||||
|
|
@ -1380,10 +1380,10 @@ func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*S
|
||||||
culength := uint32(getattr(compunit, dwarf.DW_AT_byte_size).Value) + 4
|
culength := uint32(getattr(compunit, dwarf.DW_AT_byte_size).Value) + 4
|
||||||
|
|
||||||
// Write .debug_pubnames/types Header (sec 6.1.1)
|
// Write .debug_pubnames/types Header (sec 6.1.1)
|
||||||
Adduint32(ctxt, s, 0) // unit_length (*), will be filled in later.
|
s.AddUint32(ctxt.Arch, 0) // unit_length (*), will be filled in later.
|
||||||
Adduint16(ctxt, s, 2) // dwarf version (appendix F)
|
s.AddUint16(ctxt.Arch, 2) // dwarf version (appendix F)
|
||||||
adddwarfref(ctxt, s, dtolsym(compunit.Sym), 4) // debug_info_offset (of the Comp unit Header)
|
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 {
|
for die := compunit.Child; die != nil; die = die.Link {
|
||||||
if !ispub(die) {
|
if !ispub(die) {
|
||||||
|
|
@ -1398,9 +1398,9 @@ func writepub(ctxt *Link, sname string, ispub func(*dwarf.DWDie) bool, syms []*S
|
||||||
Addstring(s, name)
|
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
|
return syms
|
||||||
|
|
@ -1429,22 +1429,22 @@ func writearanges(ctxt *Link, syms []*Symbol) []*Symbol {
|
||||||
|
|
||||||
// Write .debug_aranges Header + entry (sec 6.1.2)
|
// Write .debug_aranges Header + entry (sec 6.1.2)
|
||||||
unitlength := uint32(headersize) + 4*uint32(ctxt.Arch.PtrSize) - 4
|
unitlength := uint32(headersize) + 4*uint32(ctxt.Arch.PtrSize) - 4
|
||||||
Adduint32(ctxt, s, unitlength) // unit_length (*)
|
s.AddUint32(ctxt.Arch, unitlength) // unit_length (*)
|
||||||
Adduint16(ctxt, s, 2) // dwarf version (appendix F)
|
s.AddUint16(ctxt.Arch, 2) // dwarf version (appendix F)
|
||||||
|
|
||||||
adddwarfref(ctxt, s, dtolsym(compunit.Sym), 4)
|
adddwarfref(ctxt, s, dtolsym(compunit.Sym), 4)
|
||||||
|
|
||||||
Adduint8(ctxt, s, uint8(ctxt.Arch.PtrSize)) // address_size
|
s.AddUint8(uint8(ctxt.Arch.PtrSize)) // address_size
|
||||||
Adduint8(ctxt, s, 0) // segment_size
|
s.AddUint8(0) // segment_size
|
||||||
padding := headersize - (4 + 2 + 4 + 1 + 1)
|
padding := headersize - (4 + 2 + 4 + 1 + 1)
|
||||||
for i := 0; i < padding; i++ {
|
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)
|
s.AddAddrPlus(ctxt.Arch, b.Data.(*Symbol), b.Value-(b.Data.(*Symbol)).Value)
|
||||||
adduintxx(ctxt, s, uint64(e.Value-b.Value), ctxt.Arch.PtrSize)
|
s.addUintXX(ctxt.Arch, uint64(e.Value-b.Value), ctxt.Arch.PtrSize)
|
||||||
adduintxx(ctxt, s, 0, ctxt.Arch.PtrSize)
|
s.addUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize)
|
||||||
adduintxx(ctxt, s, 0, ctxt.Arch.PtrSize)
|
s.addUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize)
|
||||||
}
|
}
|
||||||
if s.Size > 0 {
|
if s.Size > 0 {
|
||||||
syms = append(syms, s)
|
syms = append(syms, s)
|
||||||
|
|
@ -1467,7 +1467,7 @@ func writegdbscript(ctxt *Link, syms []*Symbol) []*Symbol {
|
||||||
s := ctxt.Syms.Lookup(".debug_gdb_scripts", 0)
|
s := ctxt.Syms.Lookup(".debug_gdb_scripts", 0)
|
||||||
s.Type = SDWARFSECT
|
s.Type = SDWARFSECT
|
||||||
syms = append(syms, s)
|
syms = append(syms, s)
|
||||||
Adduint8(ctxt, s, 1) // magic 1 byte?
|
s.AddUint8(1) // magic 1 byte?
|
||||||
Addstring(s, gdbscript)
|
Addstring(s, gdbscript)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1177,11 +1177,11 @@ func elfhash(name string) uint32 {
|
||||||
|
|
||||||
func Elfwritedynent(ctxt *Link, s *Symbol, tag int, val uint64) {
|
func Elfwritedynent(ctxt *Link, s *Symbol, tag int, val uint64) {
|
||||||
if elf64 {
|
if elf64 {
|
||||||
Adduint64(ctxt, s, uint64(tag))
|
s.AddUint64(ctxt.Arch, uint64(tag))
|
||||||
Adduint64(ctxt, s, val)
|
s.AddUint64(ctxt.Arch, val)
|
||||||
} else {
|
} else {
|
||||||
Adduint32(ctxt, s, uint32(tag))
|
s.AddUint32(ctxt.Arch, uint32(tag))
|
||||||
Adduint32(ctxt, s, uint32(val))
|
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) {
|
func Elfwritedynentsymplus(ctxt *Link, s *Symbol, tag int, t *Symbol, add int64) {
|
||||||
if elf64 {
|
if elf64 {
|
||||||
Adduint64(ctxt, s, uint64(tag))
|
s.AddUint64(ctxt.Arch, uint64(tag))
|
||||||
} else {
|
} 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) {
|
func elfwritedynentsymsize(ctxt *Link, s *Symbol, tag int, t *Symbol) {
|
||||||
if elf64 {
|
if elf64 {
|
||||||
Adduint64(ctxt, s, uint64(tag))
|
s.AddUint64(ctxt.Arch, uint64(tag))
|
||||||
} else {
|
} 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 {
|
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
|
// s390x (ELF64) hash table entries are 8 bytes
|
||||||
if ctxt.Arch.Family == sys.S390X {
|
if ctxt.Arch.Family == sys.S390X {
|
||||||
Adduint64(ctxt, s, uint64(nbucket))
|
s.AddUint64(ctxt.Arch, uint64(nbucket))
|
||||||
Adduint64(ctxt, s, uint64(nsym))
|
s.AddUint64(ctxt.Arch, uint64(nsym))
|
||||||
for i := 0; i < nbucket; i++ {
|
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++ {
|
for i := 0; i < nsym; i++ {
|
||||||
Adduint64(ctxt, s, uint64(chain[i]))
|
s.AddUint64(ctxt.Arch, uint64(chain[i]))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Adduint32(ctxt, s, uint32(nbucket))
|
s.AddUint32(ctxt.Arch, uint32(nbucket))
|
||||||
Adduint32(ctxt, s, uint32(nsym))
|
s.AddUint32(ctxt.Arch, uint32(nsym))
|
||||||
for i := 0; i < nbucket; i++ {
|
for i := 0; i < nbucket; i++ {
|
||||||
Adduint32(ctxt, s, buckets[i])
|
s.AddUint32(ctxt.Arch, buckets[i])
|
||||||
}
|
}
|
||||||
for i := 0; i < nsym; 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++
|
nfile++
|
||||||
|
|
||||||
// header
|
// header
|
||||||
Adduint16(ctxt, s, 1) // table version
|
s.AddUint16(ctxt.Arch, 1) // table version
|
||||||
j := 0
|
j := 0
|
||||||
for x := l.aux; x != nil; x = x.next {
|
for x := l.aux; x != nil; x = x.next {
|
||||||
j++
|
j++
|
||||||
}
|
}
|
||||||
Adduint16(ctxt, s, uint16(j)) // aux count
|
s.AddUint16(ctxt.Arch, uint16(j)) // aux count
|
||||||
Adduint32(ctxt, s, uint32(Addstring(dynstr, l.file))) // file string offset
|
s.AddUint32(ctxt.Arch, uint32(Addstring(dynstr, l.file))) // file string offset
|
||||||
Adduint32(ctxt, s, 16) // offset from header to first aux
|
s.AddUint32(ctxt.Arch, 16) // offset from header to first aux
|
||||||
if l.next != nil {
|
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 {
|
} else {
|
||||||
Adduint32(ctxt, s, 0)
|
s.AddUint32(ctxt.Arch, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
for x := l.aux; x != nil; x = x.next {
|
for x := l.aux; x != nil; x = x.next {
|
||||||
|
|
@ -1528,14 +1528,14 @@ func elfdynhash(ctxt *Link) {
|
||||||
i++
|
i++
|
||||||
|
|
||||||
// aux struct
|
// aux struct
|
||||||
Adduint32(ctxt, s, elfhash(x.vers)) // hash
|
s.AddUint32(ctxt.Arch, elfhash(x.vers)) // hash
|
||||||
Adduint16(ctxt, s, 0) // flags
|
s.AddUint16(ctxt.Arch, 0) // flags
|
||||||
Adduint16(ctxt, s, uint16(x.num)) // other - index we refer to this by
|
s.AddUint16(ctxt.Arch, 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, uint32(Addstring(dynstr, x.vers))) // version string offset
|
||||||
if x.next != nil {
|
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 {
|
} else {
|
||||||
Adduint32(ctxt, s, 0)
|
s.AddUint32(ctxt.Arch, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1545,11 +1545,11 @@ func elfdynhash(ctxt *Link) {
|
||||||
|
|
||||||
for i := 0; i < nsym; i++ {
|
for i := 0; i < nsym; i++ {
|
||||||
if i == 0 {
|
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 {
|
} else if need[i] == nil {
|
||||||
Adduint16(ctxt, s, 1) // global
|
s.AddUint16(ctxt.Arch, 1) // global
|
||||||
} else {
|
} 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.Attr |= AttrReachable
|
||||||
s.Type = SELFROSECT
|
s.Type = SELFROSECT
|
||||||
// namesz
|
// namesz
|
||||||
Adduint32(ctxt, s, uint32(len(ELF_NOTE_GO_NAME)))
|
s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME)))
|
||||||
// descsz
|
// descsz
|
||||||
Adduint32(ctxt, s, uint32(len(desc)))
|
s.AddUint32(ctxt.Arch, uint32(len(desc)))
|
||||||
// tag
|
// tag
|
||||||
Adduint32(ctxt, s, tag)
|
s.AddUint32(ctxt.Arch, tag)
|
||||||
// name + padding
|
// name + padding
|
||||||
s.P = append(s.P, ELF_NOTE_GO_NAME...)
|
s.P = append(s.P, ELF_NOTE_GO_NAME...)
|
||||||
for len(s.P)%4 != 0 {
|
for len(s.P)%4 != 0 {
|
||||||
|
|
@ -2690,7 +2690,7 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
|
||||||
d := ctxt.Syms.Lookup(".dynsym", 0)
|
d := ctxt.Syms.Lookup(".dynsym", 0)
|
||||||
|
|
||||||
name := s.Extname
|
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 */
|
/* type */
|
||||||
t := STB_GLOBAL << 4
|
t := STB_GLOBAL << 4
|
||||||
|
|
@ -2700,27 +2700,27 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
|
||||||
} else {
|
} else {
|
||||||
t |= STT_OBJECT
|
t |= STT_OBJECT
|
||||||
}
|
}
|
||||||
Adduint8(ctxt, d, uint8(t))
|
d.AddUint8(uint8(t))
|
||||||
|
|
||||||
/* reserved */
|
/* reserved */
|
||||||
Adduint8(ctxt, d, 0)
|
d.AddUint8(0)
|
||||||
|
|
||||||
/* section where symbol is defined */
|
/* section where symbol is defined */
|
||||||
if s.Type == SDYNIMPORT {
|
if s.Type == SDYNIMPORT {
|
||||||
Adduint16(ctxt, d, SHN_UNDEF)
|
d.AddUint16(ctxt.Arch, SHN_UNDEF)
|
||||||
} else {
|
} else {
|
||||||
Adduint16(ctxt, d, 1)
|
d.AddUint16(ctxt.Arch, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* value */
|
/* value */
|
||||||
if s.Type == SDYNIMPORT {
|
if s.Type == SDYNIMPORT {
|
||||||
Adduint64(ctxt, d, 0)
|
d.AddUint64(ctxt.Arch, 0)
|
||||||
} else {
|
} else {
|
||||||
Addaddr(ctxt, d, s)
|
d.AddAddr(ctxt.Arch, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* size of object */
|
/* 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] {
|
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)))
|
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 */
|
||||||
name := s.Extname
|
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 */
|
/* value */
|
||||||
if s.Type == SDYNIMPORT {
|
if s.Type == SDYNIMPORT {
|
||||||
Adduint32(ctxt, d, 0)
|
d.AddUint32(ctxt.Arch, 0)
|
||||||
} else {
|
} else {
|
||||||
Addaddr(ctxt, d, s)
|
d.AddAddr(ctxt.Arch, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* size of object */
|
/* size of object */
|
||||||
Adduint32(ctxt, d, uint32(s.Size))
|
d.AddUint32(ctxt.Arch, uint32(s.Size))
|
||||||
|
|
||||||
/* type */
|
/* type */
|
||||||
t := STB_GLOBAL << 4
|
t := STB_GLOBAL << 4
|
||||||
|
|
@ -2757,14 +2757,14 @@ func elfadddynsym(ctxt *Link, s *Symbol) {
|
||||||
} else {
|
} else {
|
||||||
t |= STT_OBJECT
|
t |= STT_OBJECT
|
||||||
}
|
}
|
||||||
Adduint8(ctxt, d, uint8(t))
|
d.AddUint8(uint8(t))
|
||||||
Adduint8(ctxt, d, 0)
|
d.AddUint8(0)
|
||||||
|
|
||||||
/* shndx */
|
/* shndx */
|
||||||
if s.Type == SDYNIMPORT {
|
if s.Type == SDYNIMPORT {
|
||||||
Adduint16(ctxt, d, SHN_UNDEF)
|
d.AddUint16(ctxt.Arch, SHN_UNDEF)
|
||||||
} else {
|
} else {
|
||||||
Adduint16(ctxt, d, 1)
|
d.AddUint16(ctxt.Arch, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -359,11 +359,11 @@ func (ctxt *Link) loadlib() {
|
||||||
case BuildmodeCShared, BuildmodePlugin:
|
case BuildmodeCShared, BuildmodePlugin:
|
||||||
s := ctxt.Syms.Lookup("runtime.islibrary", 0)
|
s := ctxt.Syms.Lookup("runtime.islibrary", 0)
|
||||||
s.Attr |= AttrDuplicateOK
|
s.Attr |= AttrDuplicateOK
|
||||||
Adduint8(ctxt, s, 1)
|
s.AddUint8(1)
|
||||||
case BuildmodeCArchive:
|
case BuildmodeCArchive:
|
||||||
s := ctxt.Syms.Lookup("runtime.isarchive", 0)
|
s := ctxt.Syms.Lookup("runtime.isarchive", 0)
|
||||||
s.Attr |= AttrDuplicateOK
|
s.Attr |= AttrDuplicateOK
|
||||||
Adduint8(ctxt, s, 1)
|
s.AddUint8(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
loadinternal(ctxt, "runtime")
|
loadinternal(ctxt, "runtime")
|
||||||
|
|
@ -485,14 +485,14 @@ func (ctxt *Link) loadlib() {
|
||||||
s := ctxt.Syms.Lookup("runtime.goarm", 0)
|
s := ctxt.Syms.Lookup("runtime.goarm", 0)
|
||||||
s.Type = SRODATA
|
s.Type = SRODATA
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
Adduint8(ctxt, s, uint8(objabi.GOARM))
|
s.AddUint8(uint8(objabi.GOARM))
|
||||||
}
|
}
|
||||||
|
|
||||||
if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
|
if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
|
||||||
s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0)
|
s := ctxt.Syms.Lookup("runtime.framepointer_enabled", 0)
|
||||||
s.Type = SRODATA
|
s.Type = SRODATA
|
||||||
s.Size = 0
|
s.Size = 0
|
||||||
Adduint8(ctxt, s, 1)
|
s.AddUint8(1)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If OTOH the module does not contain the runtime package,
|
// If OTOH the module does not contain the runtime package,
|
||||||
|
|
|
||||||
|
|
@ -38,61 +38,6 @@ import (
|
||||||
"fmt"
|
"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.
|
// Attribute is a set of common symbol attributes.
|
||||||
type Attribute int16
|
type Attribute int16
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -348,8 +348,8 @@ func (ctxt *Link) domacho() {
|
||||||
|
|
||||||
s.Type = SMACHOSYMSTR
|
s.Type = SMACHOSYMSTR
|
||||||
s.Attr |= AttrReachable
|
s.Attr |= AttrReachable
|
||||||
Adduint8(ctxt, s, ' ')
|
s.AddUint8(' ')
|
||||||
Adduint8(ctxt, s, '\x00')
|
s.AddUint8('\x00')
|
||||||
|
|
||||||
s = ctxt.Syms.Lookup(".machosymtab", 0)
|
s = ctxt.Syms.Lookup(".machosymtab", 0)
|
||||||
s.Type = SMACHOSYMTAB
|
s.Type = SMACHOSYMTAB
|
||||||
|
|
@ -761,7 +761,7 @@ func machosymtab(ctxt *Link) {
|
||||||
|
|
||||||
for i := 0; i < nsortsym; i++ {
|
for i := 0; i < nsortsym; i++ {
|
||||||
s := sortsym[i]
|
s := sortsym[i]
|
||||||
Adduint32(ctxt, symtab, uint32(symstr.Size))
|
symtab.AddUint32(ctxt.Arch, uint32(symstr.Size))
|
||||||
|
|
||||||
export := machoShouldExport(ctxt, s)
|
export := machoShouldExport(ctxt, s)
|
||||||
|
|
||||||
|
|
@ -774,22 +774,22 @@ func machosymtab(ctxt *Link) {
|
||||||
// See Issue #18190.
|
// See Issue #18190.
|
||||||
cexport := !strings.Contains(s.Extname, ".") && (Buildmode != BuildmodePlugin || onlycsymbol(s))
|
cexport := !strings.Contains(s.Extname, ".") && (Buildmode != BuildmodePlugin || onlycsymbol(s))
|
||||||
if cexport || export {
|
if cexport || export {
|
||||||
Adduint8(ctxt, symstr, '_')
|
symstr.AddUint8('_')
|
||||||
}
|
}
|
||||||
|
|
||||||
// replace "·" as ".", because DTrace cannot handle it.
|
// replace "·" as ".", because DTrace cannot handle it.
|
||||||
Addstring(symstr, strings.Replace(s.Extname, "·", ".", -1))
|
Addstring(symstr, strings.Replace(s.Extname, "·", ".", -1))
|
||||||
|
|
||||||
if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ {
|
if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ {
|
||||||
Adduint8(ctxt, symtab, 0x01) // type N_EXT, external symbol
|
symtab.AddUint8(0x01) // type N_EXT, external symbol
|
||||||
Adduint8(ctxt, symtab, 0) // no section
|
symtab.AddUint8(0) // no section
|
||||||
Adduint16(ctxt, symtab, 0) // desc
|
symtab.AddUint16(ctxt.Arch, 0) // desc
|
||||||
adduintxx(ctxt, symtab, 0, ctxt.Arch.PtrSize) // no value
|
symtab.addUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) // no value
|
||||||
} else {
|
} else {
|
||||||
if s.Attr.CgoExport() || export {
|
if s.Attr.CgoExport() || export {
|
||||||
Adduint8(ctxt, symtab, 0x0f)
|
symtab.AddUint8(0x0f)
|
||||||
} else {
|
} else {
|
||||||
Adduint8(ctxt, symtab, 0x0e)
|
symtab.AddUint8(0x0e)
|
||||||
}
|
}
|
||||||
o := s
|
o := s
|
||||||
for o.Outer != nil {
|
for o.Outer != nil {
|
||||||
|
|
@ -797,12 +797,12 @@ func machosymtab(ctxt *Link) {
|
||||||
}
|
}
|
||||||
if o.Sect == nil {
|
if o.Sect == nil {
|
||||||
Errorf(s, "missing section for symbol")
|
Errorf(s, "missing section for symbol")
|
||||||
Adduint8(ctxt, symtab, 0)
|
symtab.AddUint8(0)
|
||||||
} else {
|
} else {
|
||||||
Adduint8(ctxt, symtab, uint8(o.Sect.Extnum))
|
symtab.AddUint8(uint8(o.Sect.Extnum))
|
||||||
}
|
}
|
||||||
Adduint16(ctxt, symtab, 0) // desc
|
symtab.AddUint16(ctxt.Arch, 0) // desc
|
||||||
adduintxx(ctxt, symtab, uint64(Symaddr(s)), ctxt.Arch.PtrSize)
|
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
|
// any alignment padding itself, working around the
|
||||||
// issue.
|
// issue.
|
||||||
for s4.Size%16 != 0 {
|
for s4.Size%16 != 0 {
|
||||||
Adduint8(ctxt, s4, 0)
|
s4.AddUint8(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
size := int(s1.Size + s2.Size + s3.Size + s4.Size)
|
size := int(s1.Size + s2.Size + s3.Size + s4.Size)
|
||||||
|
|
|
||||||
|
|
@ -404,9 +404,9 @@ func (r *objReader) readRef() {
|
||||||
if uint64(uint32(x)) != x {
|
if uint64(uint32(x)) != x {
|
||||||
log.Panicf("$-symbol %s too large: %d", s.Name, 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.":
|
case "$f64.", "$i64.":
|
||||||
Adduint64(r.ctxt, s, x)
|
s.AddUint64(r.ctxt.Arch, x)
|
||||||
default:
|
default:
|
||||||
log.Panicf("unrecognized $-symbol: %s", s.Name)
|
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
|
var start int32
|
||||||
if len(d.P) > 0 {
|
if len(d.P) > 0 {
|
||||||
start = int32(len(ftab.P))
|
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 {
|
func ftabaddstring(ctxt *Link, ftab *Symbol, s string) int32 {
|
||||||
n := int32(len(s)) + 1
|
n := int32(len(s)) + 1
|
||||||
start := int32(len(ftab.P))
|
start := int32(len(ftab.P))
|
||||||
Symgrow(ftab, int64(start)+int64(n)+1)
|
ftab.Grow(int64(start) + int64(n) + 1)
|
||||||
copy(ftab.P[start:], s)
|
copy(ftab.P[start:], s)
|
||||||
return start
|
return start
|
||||||
}
|
}
|
||||||
|
|
@ -226,11 +226,11 @@ func (ctxt *Link) pclntab() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pclntabNfunc = nfunc
|
pclntabNfunc = nfunc
|
||||||
Symgrow(ftab, 8+int64(ctxt.Arch.PtrSize)+int64(nfunc)*2*int64(ctxt.Arch.PtrSize)+int64(ctxt.Arch.PtrSize)+4)
|
ftab.Grow(8 + int64(ctxt.Arch.PtrSize) + int64(nfunc)*2*int64(ctxt.Arch.PtrSize) + int64(ctxt.Arch.PtrSize) + 4)
|
||||||
setuint32(ctxt, ftab, 0, 0xfffffffb)
|
ftab.SetUint32(ctxt.Arch, 0, 0xfffffffb)
|
||||||
setuint8(ctxt, ftab, 6, uint8(ctxt.Arch.MinLC))
|
ftab.SetUint8(ctxt.Arch, 6, uint8(ctxt.Arch.MinLC))
|
||||||
setuint8(ctxt, ftab, 7, uint8(ctxt.Arch.PtrSize))
|
ftab.SetUint8(ctxt.Arch, 7, uint8(ctxt.Arch.PtrSize))
|
||||||
setuint(ctxt, ftab, 8, uint64(nfunc))
|
ftab.SetUint(ctxt.Arch, 8, uint64(nfunc))
|
||||||
pclntabPclntabOffset = int32(8 + ctxt.Arch.PtrSize)
|
pclntabPclntabOffset = int32(8 + ctxt.Arch.PtrSize)
|
||||||
|
|
||||||
funcnameoff := make(map[string]int32)
|
funcnameoff := make(map[string]int32)
|
||||||
|
|
@ -281,8 +281,8 @@ func (ctxt *Link) pclntab() {
|
||||||
funcstart := int32(len(ftab.P))
|
funcstart := int32(len(ftab.P))
|
||||||
funcstart += int32(-len(ftab.P)) & (int32(ctxt.Arch.PtrSize) - 1)
|
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)
|
ftab.SetAddr(ctxt.Arch, 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.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
|
// Write runtime._func. Keep in sync with ../../../../runtime/runtime2.go:/_func
|
||||||
// and package debug/gosym.
|
// and package debug/gosym.
|
||||||
|
|
@ -294,14 +294,14 @@ func (ctxt *Link) pclntab() {
|
||||||
if len(pcln.Funcdata) > 0 && (end&int32(ctxt.Arch.PtrSize-1) != 0) {
|
if len(pcln.Funcdata) > 0 && (end&int32(ctxt.Arch.PtrSize-1) != 0) {
|
||||||
end += 4
|
end += 4
|
||||||
}
|
}
|
||||||
Symgrow(ftab, int64(end))
|
ftab.Grow(int64(end))
|
||||||
|
|
||||||
// entry uintptr
|
// entry uintptr
|
||||||
off = int32(setaddr(ctxt, ftab, int64(off), s))
|
off = int32(ftab.SetAddr(ctxt.Arch, int64(off), s))
|
||||||
|
|
||||||
// name int32
|
// name int32
|
||||||
nameoff := nameToOffset(s.Name)
|
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
|
// args int32
|
||||||
// TODO: Move into funcinfo.
|
// TODO: Move into funcinfo.
|
||||||
|
|
@ -309,14 +309,14 @@ func (ctxt *Link) pclntab() {
|
||||||
if s.FuncInfo != nil {
|
if s.FuncInfo != nil {
|
||||||
args = uint32(s.FuncInfo.Args)
|
args = uint32(s.FuncInfo.Args)
|
||||||
}
|
}
|
||||||
off = int32(setuint32(ctxt, ftab, int64(off), args))
|
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), args))
|
||||||
|
|
||||||
// frame int32
|
// frame int32
|
||||||
// This has been removed (it was never set quite correctly anyway).
|
// This has been removed (it was never set quite correctly anyway).
|
||||||
// Nothing should use it.
|
// Nothing should use it.
|
||||||
// Leave an obviously incorrect value.
|
// Leave an obviously incorrect value.
|
||||||
// TODO: Remove entirely.
|
// TODO: Remove entirely.
|
||||||
off = int32(setuint32(ctxt, ftab, int64(off), 0x1234567))
|
off = int32(ftab.SetUint32(ctxt.Arch, int64(off), 0x1234567))
|
||||||
|
|
||||||
if pcln != &pclntabZpcln {
|
if pcln != &pclntabZpcln {
|
||||||
renumberfiles(ctxt, pcln.File, &pcln.Pcfile)
|
renumberfiles(ctxt, pcln.File, &pcln.Pcfile)
|
||||||
|
|
@ -346,10 +346,10 @@ func (ctxt *Link) pclntab() {
|
||||||
numberfile(ctxt, call.File)
|
numberfile(ctxt, call.File)
|
||||||
nameoff := nameToOffset(call.Func.Name)
|
nameoff := nameToOffset(call.Func.Name)
|
||||||
|
|
||||||
setuint32(ctxt, inlTreeSym, int64(i*16+0), uint32(call.Parent))
|
inlTreeSym.SetUint32(ctxt.Arch, int64(i*16+0), uint32(call.Parent))
|
||||||
setuint32(ctxt, inlTreeSym, int64(i*16+4), uint32(call.File.Value))
|
inlTreeSym.SetUint32(ctxt.Arch, int64(i*16+4), uint32(call.File.Value))
|
||||||
setuint32(ctxt, inlTreeSym, int64(i*16+8), uint32(call.Line))
|
inlTreeSym.SetUint32(ctxt.Arch, int64(i*16+8), uint32(call.Line))
|
||||||
setuint32(ctxt, inlTreeSym, int64(i*16+12), uint32(nameoff))
|
inlTreeSym.SetUint32(ctxt.Arch, int64(i*16+12), uint32(nameoff))
|
||||||
}
|
}
|
||||||
|
|
||||||
pcln.Funcdata[objabi.FUNCDATA_InlTree] = inlTreeSym
|
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.Pcfile)
|
||||||
off = addpctab(ctxt, ftab, off, &pcln.Pcline)
|
off = addpctab(ctxt, ftab, off, &pcln.Pcline)
|
||||||
off = int32(setuint32(ctxt, ftab, int64(off), uint32(len(pcln.Pcdata))))
|
off = int32(ftab.SetUint32(ctxt.Arch, 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.Funcdata))))
|
||||||
for i := 0; i < len(pcln.Pcdata); i++ {
|
for i := 0; i < len(pcln.Pcdata); i++ {
|
||||||
off = addpctab(ctxt, ftab, off, &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++ {
|
for i := 0; i < len(pcln.Funcdata); i++ {
|
||||||
if pcln.Funcdata[i] == nil {
|
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 {
|
} else {
|
||||||
// TODO: Dedup.
|
// TODO: Dedup.
|
||||||
funcdataBytes += pcln.Funcdata[i].Size
|
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
|
pclntabLastFunc = last
|
||||||
// Final entry of table is just end pc.
|
// 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 file table.
|
||||||
start := int32(len(ftab.P))
|
start := int32(len(ftab.P))
|
||||||
|
|
||||||
start += int32(-len(ftab.P)) & (int32(ctxt.Arch.PtrSize) - 1)
|
start += int32(-len(ftab.P)) & (int32(ctxt.Arch.PtrSize) - 1)
|
||||||
pclntabFiletabOffset = start
|
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)
|
ftab.Grow(int64(start) + (int64(len(ctxt.Filesyms))+1)*4)
|
||||||
setuint32(ctxt, ftab, int64(start), uint32(len(ctxt.Filesyms)+1))
|
ftab.SetUint32(ctxt.Arch, int64(start), uint32(len(ctxt.Filesyms)+1))
|
||||||
for i := len(ctxt.Filesyms) - 1; i >= 0; i-- {
|
for i := len(ctxt.Filesyms) - 1; i >= 0; i-- {
|
||||||
s := ctxt.Filesyms[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))
|
ftab.Size = int64(len(ftab.P))
|
||||||
|
|
@ -500,7 +500,7 @@ func (ctxt *Link) findfunctab() {
|
||||||
// allocate table
|
// allocate table
|
||||||
nbuckets := int32((max - min + BUCKETSIZE - 1) / BUCKETSIZE)
|
nbuckets := int32((max - min + BUCKETSIZE - 1) / BUCKETSIZE)
|
||||||
|
|
||||||
Symgrow(t, 4*int64(nbuckets)+int64(n))
|
t.Grow(4*int64(nbuckets) + int64(n))
|
||||||
|
|
||||||
// fill in table
|
// fill in table
|
||||||
for i := int32(0); i < nbuckets; i++ {
|
for i := int32(0); i < nbuckets; i++ {
|
||||||
|
|
@ -508,7 +508,7 @@ func (ctxt *Link) findfunctab() {
|
||||||
if base == NOIDX {
|
if base == NOIDX {
|
||||||
Errorf(nil, "hole in findfunctab")
|
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++ {
|
for j := int32(0); j < SUBBUCKETS && i*SUBBUCKETS+j < n; j++ {
|
||||||
idx = indexes[i*SUBBUCKETS+j]
|
idx = indexes[i*SUBBUCKETS+j]
|
||||||
if idx == NOIDX {
|
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)
|
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 d := dr; d != nil; d = d.next {
|
||||||
for m = d.ms; m != nil; m = m.next {
|
for m = d.ms; m != nil; m = m.next {
|
||||||
m.s.Type = SDATA
|
m.s.Type = SDATA
|
||||||
Symgrow(m.s, int64(ctxt.Arch.PtrSize))
|
m.s.Grow(int64(ctxt.Arch.PtrSize))
|
||||||
dynName := m.s.Extname
|
dynName := m.s.Extname
|
||||||
// only windows/386 requires stdcall decoration
|
// only windows/386 requires stdcall decoration
|
||||||
if ctxt.Arch.Family == sys.I386 && m.argsize >= 0 {
|
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 := ctxt.Syms.Lookup(dynName, 0)
|
||||||
dynSym.Attr |= AttrReachable
|
dynSym.Attr |= AttrReachable
|
||||||
dynSym.Type = SHOSTOBJ
|
dynSym.Type = SHOSTOBJ
|
||||||
r := Addrel(m.s)
|
r := m.s.AddRel()
|
||||||
r.Sym = dynSym
|
r.Sym = dynSym
|
||||||
r.Off = 0
|
r.Off = 0
|
||||||
r.Siz = uint8(ctxt.Arch.PtrSize)
|
r.Siz = uint8(ctxt.Arch.PtrSize)
|
||||||
|
|
|
||||||
265
src/cmd/link/internal/ld/symbol.go
Normal file
265
src/cmd/link/internal/ld/symbol.go
Normal file
|
|
@ -0,0 +1,265 @@
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
@ -279,7 +279,7 @@ func textsectionmap(ctxt *Link) uint32 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Symgrow(t, 3*nsections*int64(ctxt.Arch.PtrSize))
|
t.Grow(3 * nsections * int64(ctxt.Arch.PtrSize))
|
||||||
|
|
||||||
off := int64(0)
|
off := int64(0)
|
||||||
n := 0
|
n := 0
|
||||||
|
|
@ -298,21 +298,21 @@ func textsectionmap(ctxt *Link) uint32 {
|
||||||
if sect.Name != ".text" {
|
if sect.Name != ".text" {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
off = setuint(ctxt, t, off, sect.Vaddr-textbase)
|
off = t.SetUint(ctxt.Arch, off, sect.Vaddr-textbase)
|
||||||
off = setuint(ctxt, t, off, sect.Length)
|
off = t.SetUint(ctxt.Arch, off, sect.Length)
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
s := ctxt.Syms.ROLookup("runtime.text", 0)
|
s := ctxt.Syms.ROLookup("runtime.text", 0)
|
||||||
if s == nil {
|
if s == nil {
|
||||||
Errorf(nil, "Unable to find symbol runtime.text\n")
|
Errorf(nil, "Unable to find symbol runtime.text\n")
|
||||||
}
|
}
|
||||||
off = setaddr(ctxt, t, off, s)
|
off = t.SetAddr(ctxt.Arch, off, s)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
s := ctxt.Syms.Lookup(fmt.Sprintf("runtime.text.%d", n), 0)
|
s := ctxt.Syms.Lookup(fmt.Sprintf("runtime.text.%d", n), 0)
|
||||||
if s == nil {
|
if s == nil {
|
||||||
Errorf(nil, "Unable to find symbol runtime.text.%d\n", n)
|
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++
|
n++
|
||||||
}
|
}
|
||||||
|
|
@ -491,8 +491,8 @@ func (ctxt *Link) symtab() {
|
||||||
abihashgostr.Attr |= AttrReachable
|
abihashgostr.Attr |= AttrReachable
|
||||||
abihashgostr.Type = SRODATA
|
abihashgostr.Type = SRODATA
|
||||||
hashsym := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
|
hashsym := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
|
||||||
Addaddr(ctxt, abihashgostr, hashsym)
|
abihashgostr.AddAddr(ctxt.Arch, hashsym)
|
||||||
adduint(ctxt, abihashgostr, uint64(hashsym.Size))
|
abihashgostr.AddUint(ctxt.Arch, uint64(hashsym.Size))
|
||||||
}
|
}
|
||||||
if Buildmode == BuildmodePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil {
|
if Buildmode == BuildmodePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil {
|
||||||
for _, l := range ctxt.Library {
|
for _, l := range ctxt.Library {
|
||||||
|
|
@ -504,8 +504,8 @@ func (ctxt *Link) symtab() {
|
||||||
str := ctxt.Syms.Lookup("go.link.pkghash."+l.Pkg, 0)
|
str := ctxt.Syms.Lookup("go.link.pkghash."+l.Pkg, 0)
|
||||||
str.Attr |= AttrReachable
|
str.Attr |= AttrReachable
|
||||||
str.Type = SRODATA
|
str.Type = SRODATA
|
||||||
Addaddr(ctxt, str, s)
|
str.AddAddr(ctxt.Arch, s)
|
||||||
adduint(ctxt, str, uint64(len(l.hash)))
|
str.AddUint(ctxt.Arch, uint64(len(l.hash)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -517,67 +517,67 @@ func (ctxt *Link) symtab() {
|
||||||
// This code uses several global variables that are set by pcln.go:pclntab.
|
// This code uses several global variables that are set by pcln.go:pclntab.
|
||||||
moduledata := ctxt.Moduledata
|
moduledata := ctxt.Moduledata
|
||||||
// The pclntab slice
|
// The pclntab slice
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.pclntab", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0))
|
||||||
adduint(ctxt, moduledata, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
|
moduledata.AddUint(ctxt.Arch, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
|
||||||
adduint(ctxt, moduledata, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
|
moduledata.AddUint(ctxt.Arch, uint64(ctxt.Syms.Lookup("runtime.pclntab", 0).Size))
|
||||||
// The ftab slice
|
// The ftab slice
|
||||||
Addaddrplus(ctxt, moduledata, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabPclntabOffset))
|
moduledata.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabPclntabOffset))
|
||||||
adduint(ctxt, moduledata, uint64(pclntabNfunc+1))
|
moduledata.AddUint(ctxt.Arch, uint64(pclntabNfunc+1))
|
||||||
adduint(ctxt, moduledata, uint64(pclntabNfunc+1))
|
moduledata.AddUint(ctxt.Arch, uint64(pclntabNfunc+1))
|
||||||
// The filetab slice
|
// The filetab slice
|
||||||
Addaddrplus(ctxt, moduledata, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabFiletabOffset))
|
moduledata.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup("runtime.pclntab", 0), int64(pclntabFiletabOffset))
|
||||||
adduint(ctxt, moduledata, uint64(len(ctxt.Filesyms))+1)
|
moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Filesyms))+1)
|
||||||
adduint(ctxt, moduledata, uint64(len(ctxt.Filesyms))+1)
|
moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Filesyms))+1)
|
||||||
// findfunctab
|
// findfunctab
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.findfunctab", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.findfunctab", 0))
|
||||||
// minpc, maxpc
|
// minpc, maxpc
|
||||||
Addaddr(ctxt, moduledata, pclntabFirstFunc)
|
moduledata.AddAddr(ctxt.Arch, pclntabFirstFunc)
|
||||||
Addaddrplus(ctxt, moduledata, pclntabLastFunc, pclntabLastFunc.Size)
|
moduledata.AddAddrPlus(ctxt.Arch, pclntabLastFunc, pclntabLastFunc.Size)
|
||||||
// pointers to specific parts of the module
|
// pointers to specific parts of the module
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.text", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.text", 0))
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.etext", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.etext", 0))
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.noptrdata", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.noptrdata", 0))
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.enoptrdata", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.enoptrdata", 0))
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.data", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.data", 0))
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.edata", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.edata", 0))
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.bss", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.bss", 0))
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.ebss", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.ebss", 0))
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.noptrbss", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.noptrbss", 0))
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.enoptrbss", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.enoptrbss", 0))
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.end", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.end", 0))
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.gcdata", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.gcdata", 0))
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.gcbss", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.gcbss", 0))
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.types", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.types", 0))
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.etypes", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.etypes", 0))
|
||||||
|
|
||||||
// text section information
|
// text section information
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.textsectionmap", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.textsectionmap", 0))
|
||||||
adduint(ctxt, moduledata, uint64(nsections))
|
moduledata.AddUint(ctxt.Arch, uint64(nsections))
|
||||||
adduint(ctxt, moduledata, uint64(nsections))
|
moduledata.AddUint(ctxt.Arch, uint64(nsections))
|
||||||
|
|
||||||
// The typelinks slice
|
// The typelinks slice
|
||||||
typelinkSym := ctxt.Syms.Lookup("runtime.typelink", 0)
|
typelinkSym := ctxt.Syms.Lookup("runtime.typelink", 0)
|
||||||
ntypelinks := uint64(typelinkSym.Size) / 4
|
ntypelinks := uint64(typelinkSym.Size) / 4
|
||||||
Addaddr(ctxt, moduledata, typelinkSym)
|
moduledata.AddAddr(ctxt.Arch, typelinkSym)
|
||||||
adduint(ctxt, moduledata, ntypelinks)
|
moduledata.AddUint(ctxt.Arch, ntypelinks)
|
||||||
adduint(ctxt, moduledata, ntypelinks)
|
moduledata.AddUint(ctxt.Arch, ntypelinks)
|
||||||
// The itablinks slice
|
// The itablinks slice
|
||||||
Addaddr(ctxt, moduledata, ctxt.Syms.Lookup("runtime.itablink", 0))
|
moduledata.AddAddr(ctxt.Arch, ctxt.Syms.Lookup("runtime.itablink", 0))
|
||||||
adduint(ctxt, moduledata, uint64(nitablinks))
|
moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
|
||||||
adduint(ctxt, moduledata, uint64(nitablinks))
|
moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
|
||||||
// The ptab slice
|
// The ptab slice
|
||||||
if ptab := ctxt.Syms.ROLookup("go.plugin.tabs", 0); ptab != nil && ptab.Attr.Reachable() {
|
if ptab := ctxt.Syms.ROLookup("go.plugin.tabs", 0); ptab != nil && ptab.Attr.Reachable() {
|
||||||
ptab.Attr |= AttrLocal
|
ptab.Attr |= AttrLocal
|
||||||
ptab.Type = SRODATA
|
ptab.Type = SRODATA
|
||||||
|
|
||||||
nentries := uint64(len(ptab.P) / 8) // sizeof(nameOff) + sizeof(typeOff)
|
nentries := uint64(len(ptab.P) / 8) // sizeof(nameOff) + sizeof(typeOff)
|
||||||
Addaddr(ctxt, moduledata, ptab)
|
moduledata.AddAddr(ctxt.Arch, ptab)
|
||||||
adduint(ctxt, moduledata, nentries)
|
moduledata.AddUint(ctxt.Arch, nentries)
|
||||||
adduint(ctxt, moduledata, nentries)
|
moduledata.AddUint(ctxt.Arch, nentries)
|
||||||
} else {
|
} else {
|
||||||
adduint(ctxt, moduledata, 0)
|
moduledata.AddUint(ctxt.Arch, 0)
|
||||||
adduint(ctxt, moduledata, 0)
|
moduledata.AddUint(ctxt.Arch, 0)
|
||||||
adduint(ctxt, moduledata, 0)
|
moduledata.AddUint(ctxt.Arch, 0)
|
||||||
}
|
}
|
||||||
if Buildmode == BuildmodePlugin {
|
if Buildmode == BuildmodePlugin {
|
||||||
addgostring(ctxt, moduledata, "go.link.thispluginpath", *flagPluginPath)
|
addgostring(ctxt, moduledata, "go.link.thispluginpath", *flagPluginPath)
|
||||||
|
|
@ -594,17 +594,17 @@ func (ctxt *Link) symtab() {
|
||||||
addgostring(ctxt, pkghashes, fmt.Sprintf("go.link.pkglinkhash.%d", i), string(l.hash))
|
addgostring(ctxt, pkghashes, fmt.Sprintf("go.link.pkglinkhash.%d", i), string(l.hash))
|
||||||
// pkghashes[i].runtimehash
|
// pkghashes[i].runtimehash
|
||||||
hash := ctxt.Syms.ROLookup("go.link.pkghash."+l.Pkg, 0)
|
hash := ctxt.Syms.ROLookup("go.link.pkghash."+l.Pkg, 0)
|
||||||
Addaddr(ctxt, pkghashes, hash)
|
pkghashes.AddAddr(ctxt.Arch, hash)
|
||||||
}
|
}
|
||||||
Addaddr(ctxt, moduledata, pkghashes)
|
moduledata.AddAddr(ctxt.Arch, pkghashes)
|
||||||
adduint(ctxt, moduledata, uint64(len(ctxt.Library)))
|
moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Library)))
|
||||||
adduint(ctxt, moduledata, uint64(len(ctxt.Library)))
|
moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Library)))
|
||||||
} else {
|
} else {
|
||||||
adduint(ctxt, moduledata, 0) // pluginpath
|
moduledata.AddUint(ctxt.Arch, 0) // pluginpath
|
||||||
adduint(ctxt, moduledata, 0)
|
moduledata.AddUint(ctxt.Arch, 0)
|
||||||
adduint(ctxt, moduledata, 0) // pkghashes slice
|
moduledata.AddUint(ctxt.Arch, 0) // pkghashes slice
|
||||||
adduint(ctxt, moduledata, 0)
|
moduledata.AddUint(ctxt.Arch, 0)
|
||||||
adduint(ctxt, moduledata, 0)
|
moduledata.AddUint(ctxt.Arch, 0)
|
||||||
}
|
}
|
||||||
if len(ctxt.Shlibs) > 0 {
|
if len(ctxt.Shlibs) > 0 {
|
||||||
thismodulename := filepath.Base(*flagOutfile)
|
thismodulename := filepath.Base(*flagOutfile)
|
||||||
|
|
@ -632,12 +632,12 @@ func (ctxt *Link) symtab() {
|
||||||
// modulehashes[i].runtimehash
|
// modulehashes[i].runtimehash
|
||||||
abihash := ctxt.Syms.Lookup("go.link.abihash."+modulename, 0)
|
abihash := ctxt.Syms.Lookup("go.link.abihash."+modulename, 0)
|
||||||
abihash.Attr |= AttrReachable
|
abihash.Attr |= AttrReachable
|
||||||
Addaddr(ctxt, modulehashes, abihash)
|
modulehashes.AddAddr(ctxt.Arch, abihash)
|
||||||
}
|
}
|
||||||
|
|
||||||
Addaddr(ctxt, moduledata, modulehashes)
|
moduledata.AddAddr(ctxt.Arch, modulehashes)
|
||||||
adduint(ctxt, moduledata, uint64(len(ctxt.Shlibs)))
|
moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
|
||||||
adduint(ctxt, moduledata, uint64(len(ctxt.Shlibs)))
|
moduledata.AddUint(ctxt.Arch, uint64(len(ctxt.Shlibs)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// The rest of moduledata is zero initialized.
|
// The rest of moduledata is zero initialized.
|
||||||
|
|
@ -646,12 +646,12 @@ func (ctxt *Link) symtab() {
|
||||||
// compiler-provided size, so read it from the type data.
|
// compiler-provided size, so read it from the type data.
|
||||||
moduledatatype := ctxt.Syms.ROLookup("type.runtime.moduledata", 0)
|
moduledatatype := ctxt.Syms.ROLookup("type.runtime.moduledata", 0)
|
||||||
moduledata.Size = decodetypeSize(ctxt.Arch, moduledatatype)
|
moduledata.Size = decodetypeSize(ctxt.Arch, moduledatatype)
|
||||||
Symgrow(moduledata, moduledata.Size)
|
moduledata.Grow(moduledata.Size)
|
||||||
|
|
||||||
lastmoduledatap := ctxt.Syms.Lookup("runtime.lastmoduledatap", 0)
|
lastmoduledatap := ctxt.Syms.Lookup("runtime.lastmoduledatap", 0)
|
||||||
if lastmoduledatap.Type != SDYNIMPORT {
|
if lastmoduledatap.Type != SDYNIMPORT {
|
||||||
lastmoduledatap.Type = SNOPTRDATA
|
lastmoduledatap.Type = SNOPTRDATA
|
||||||
lastmoduledatap.Size = 0 // overwrite existing value
|
lastmoduledatap.Size = 0 // overwrite existing value
|
||||||
Addaddr(ctxt, lastmoduledatap, moduledata)
|
lastmoduledatap.AddAddr(ctxt.Arch, moduledata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,10 +141,10 @@ func genaddmoduledata(ctxt *ld.Link) {
|
||||||
initfunc.Attr |= ld.AttrLocal
|
initfunc.Attr |= ld.AttrLocal
|
||||||
initfunc.Attr |= ld.AttrReachable
|
initfunc.Attr |= ld.AttrReachable
|
||||||
o := func(op uint32) {
|
o := func(op uint32) {
|
||||||
ld.Adduint32(ctxt, initfunc, op)
|
initfunc.AddUint32(ctxt.Arch, op)
|
||||||
}
|
}
|
||||||
// addis r2, r12, .TOC.-func@ha
|
// addis r2, r12, .TOC.-func@ha
|
||||||
rel := ld.Addrel(initfunc)
|
rel := initfunc.AddRel()
|
||||||
rel.Off = int32(initfunc.Size)
|
rel.Off = int32(initfunc.Size)
|
||||||
rel.Siz = 8
|
rel.Siz = 8
|
||||||
rel.Sym = ctxt.Syms.Lookup(".TOC.", 0)
|
rel.Sym = ctxt.Syms.Lookup(".TOC.", 0)
|
||||||
|
|
@ -158,7 +158,7 @@ func genaddmoduledata(ctxt *ld.Link) {
|
||||||
// stdu r31, -32(r1)
|
// stdu r31, -32(r1)
|
||||||
o(0xf801ffe1)
|
o(0xf801ffe1)
|
||||||
// addis r3, r2, local.moduledata@got@ha
|
// addis r3, r2, local.moduledata@got@ha
|
||||||
rel = ld.Addrel(initfunc)
|
rel = initfunc.AddRel()
|
||||||
rel.Off = int32(initfunc.Size)
|
rel.Off = int32(initfunc.Size)
|
||||||
rel.Siz = 8
|
rel.Siz = 8
|
||||||
if !ctxt.CanUsePlugins() {
|
if !ctxt.CanUsePlugins() {
|
||||||
|
|
@ -173,7 +173,7 @@ func genaddmoduledata(ctxt *ld.Link) {
|
||||||
// ld r3, local.moduledata@got@l(r3)
|
// ld r3, local.moduledata@got@l(r3)
|
||||||
o(0xe8630000)
|
o(0xe8630000)
|
||||||
// bl runtime.addmoduledata
|
// bl runtime.addmoduledata
|
||||||
rel = ld.Addrel(initfunc)
|
rel = initfunc.AddRel()
|
||||||
rel.Off = int32(initfunc.Size)
|
rel.Off = int32(initfunc.Size)
|
||||||
rel.Siz = 4
|
rel.Siz = 4
|
||||||
rel.Sym = addmoduledata
|
rel.Sym = addmoduledata
|
||||||
|
|
@ -198,7 +198,7 @@ func genaddmoduledata(ctxt *ld.Link) {
|
||||||
initarray_entry.Attr |= ld.AttrReachable
|
initarray_entry.Attr |= ld.AttrReachable
|
||||||
initarray_entry.Attr |= ld.AttrLocal
|
initarray_entry.Attr |= ld.AttrLocal
|
||||||
initarray_entry.Type = ld.SINITARR
|
initarray_entry.Type = ld.SINITARR
|
||||||
ld.Addaddr(ctxt, initarray_entry, initfunc)
|
initarray_entry.AddAddr(ctxt.Arch, initfunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func gentext(ctxt *ld.Link) {
|
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
|
stub.Type = ld.STEXT
|
||||||
|
|
||||||
// Save TOC pointer in TOC save slot
|
// 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.
|
// Load the function pointer from the PLT.
|
||||||
r := ld.Addrel(stub)
|
r := stub.AddRel()
|
||||||
|
|
||||||
r.Off = int32(stub.Size)
|
r.Off = int32(stub.Size)
|
||||||
r.Sym = plt
|
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.Type = objabi.R_POWER_TOC
|
||||||
r.Variant = ld.RV_POWER_HA
|
r.Variant = ld.RV_POWER_HA
|
||||||
ld.Adduint32(ctxt, stub, 0x3d820000) // addis r12,r2,targ@plt@toc@ha
|
stub.AddUint32(ctxt.Arch, 0x3d820000) // addis r12,r2,targ@plt@toc@ha
|
||||||
r = ld.Addrel(stub)
|
r = stub.AddRel()
|
||||||
r.Off = int32(stub.Size)
|
r.Off = int32(stub.Size)
|
||||||
r.Sym = plt
|
r.Sym = plt
|
||||||
r.Add = int64(targ.Plt)
|
r.Add = int64(targ.Plt)
|
||||||
|
|
@ -250,11 +250,11 @@ func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) {
|
||||||
}
|
}
|
||||||
r.Type = objabi.R_POWER_TOC
|
r.Type = objabi.R_POWER_TOC
|
||||||
r.Variant = ld.RV_POWER_LO
|
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
|
// Jump to the loaded pointer
|
||||||
ld.Adduint32(ctxt, stub, 0x7d8903a6) // mtctr r12
|
stub.AddUint32(ctxt.Arch, 0x7d8903a6) // mtctr r12
|
||||||
ld.Adduint32(ctxt, stub, 0x4e800420) // bctr
|
stub.AddUint32(ctxt.Arch, 0x4e800420) // bctr
|
||||||
}
|
}
|
||||||
|
|
||||||
func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
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)
|
ld.Adddynsym(ctxt, targ)
|
||||||
|
|
||||||
rela := ctxt.Syms.Lookup(".rela", 0)
|
rela := ctxt.Syms.Lookup(".rela", 0)
|
||||||
ld.Addaddrplus(ctxt, rela, s, int64(r.Off))
|
rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
|
||||||
ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_PPC64_ADDR64))
|
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_PPC64_ADDR64))
|
||||||
ld.Adduint64(ctxt, rela, uint64(r.Add))
|
rela.AddUint64(ctxt.Arch, uint64(r.Add))
|
||||||
r.Type = 256 // ignore during relocsym
|
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
|
// With external linking, the target address must be
|
||||||
// relocated using LO and HA
|
// relocated using LO and HA
|
||||||
if ld.Linkmode == ld.LinkExternal {
|
if ld.Linkmode == ld.LinkExternal {
|
||||||
tr := ld.Addrel(tramp)
|
tr := tramp.AddRel()
|
||||||
tr.Off = 0
|
tr.Off = 0
|
||||||
tr.Type = objabi.R_ADDRPOWER
|
tr.Type = objabi.R_ADDRPOWER
|
||||||
tr.Siz = 8 // generates 2 relocations: HA + LO
|
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
|
// Write symbol resolver stub (just a branch to the
|
||||||
// glink resolver stub)
|
// glink resolver stub)
|
||||||
r := ld.Addrel(glink)
|
r := glink.AddRel()
|
||||||
|
|
||||||
r.Sym = glink
|
r.Sym = glink
|
||||||
r.Off = int32(glink.Size)
|
r.Off = int32(glink.Size)
|
||||||
r.Siz = 4
|
r.Siz = 4
|
||||||
r.Type = objabi.R_CALLPOWER
|
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
|
// In the ppc64 ABI, the dynamic linker is responsible
|
||||||
// for writing the entire PLT. We just need to
|
// for writing the entire PLT. We just need to
|
||||||
|
|
@ -832,9 +832,9 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
|
||||||
|
|
||||||
plt.Size += 8
|
plt.Size += 8
|
||||||
|
|
||||||
ld.Addaddrplus(ctxt, rela, plt, int64(s.Plt))
|
rela.AddAddrPlus(ctxt.Arch, plt, int64(s.Plt))
|
||||||
ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_PPC64_JMP_SLOT))
|
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_PPC64_JMP_SLOT))
|
||||||
ld.Adduint64(ctxt, rela, 0)
|
rela.AddUint64(ctxt.Arch, 0)
|
||||||
} else {
|
} else {
|
||||||
ld.Errorf(s, "addpltsym: unsupported binary format")
|
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.
|
// This stub is PIC, so first get the PC of label 1 into r11.
|
||||||
// Other things will be relative to this.
|
// Other things will be relative to this.
|
||||||
ld.Adduint32(ctxt, glink, 0x7c0802a6) // mflr r0
|
glink.AddUint32(ctxt.Arch, 0x7c0802a6) // mflr r0
|
||||||
ld.Adduint32(ctxt, glink, 0x429f0005) // bcl 20,31,1f
|
glink.AddUint32(ctxt.Arch, 0x429f0005) // bcl 20,31,1f
|
||||||
ld.Adduint32(ctxt, glink, 0x7d6802a6) // 1: mflr r11
|
glink.AddUint32(ctxt.Arch, 0x7d6802a6) // 1: mflr r11
|
||||||
ld.Adduint32(ctxt, glink, 0x7c0803a6) // mtlf r0
|
glink.AddUint32(ctxt.Arch, 0x7c0803a6) // mtlf r0
|
||||||
|
|
||||||
// Compute the .plt array index from the entry point address.
|
// Compute the .plt array index from the entry point address.
|
||||||
// Because this is PIC, everything is relative to label 1b (in
|
// Because this is PIC, everything is relative to label 1b (in
|
||||||
// r11):
|
// r11):
|
||||||
// r0 = ((r12 - r11) - (res_0 - r11)) / 4 = (r12 - res_0) / 4
|
// r0 = ((r12 - r11) - (res_0 - r11)) / 4 = (r12 - res_0) / 4
|
||||||
ld.Adduint32(ctxt, glink, 0x3800ffd0) // li r0,-(res_0-1b)=-48
|
glink.AddUint32(ctxt.Arch, 0x3800ffd0) // li r0,-(res_0-1b)=-48
|
||||||
ld.Adduint32(ctxt, glink, 0x7c006214) // add r0,r0,r12
|
glink.AddUint32(ctxt.Arch, 0x7c006214) // add r0,r0,r12
|
||||||
ld.Adduint32(ctxt, glink, 0x7c0b0050) // sub r0,r0,r11
|
glink.AddUint32(ctxt.Arch, 0x7c0b0050) // sub r0,r0,r11
|
||||||
ld.Adduint32(ctxt, glink, 0x7800f082) // srdi r0,r0,2
|
glink.AddUint32(ctxt.Arch, 0x7800f082) // srdi r0,r0,2
|
||||||
|
|
||||||
// r11 = address of the first byte of the PLT
|
// r11 = address of the first byte of the PLT
|
||||||
r := ld.Addrel(glink)
|
r := glink.AddRel()
|
||||||
|
|
||||||
r.Off = int32(glink.Size)
|
r.Off = int32(glink.Size)
|
||||||
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
r.Sym = ctxt.Syms.Lookup(".plt", 0)
|
||||||
r.Siz = 8
|
r.Siz = 8
|
||||||
r.Type = objabi.R_ADDRPOWER
|
r.Type = objabi.R_ADDRPOWER
|
||||||
|
|
||||||
ld.Adduint32(ctxt, glink, 0x3d600000) // addis r11,0,.plt@ha
|
glink.AddUint32(ctxt.Arch, 0x3d600000) // addis r11,0,.plt@ha
|
||||||
ld.Adduint32(ctxt, glink, 0x396b0000) // addi r11,r11,.plt@l
|
glink.AddUint32(ctxt.Arch, 0x396b0000) // addi r11,r11,.plt@l
|
||||||
|
|
||||||
// Load r12 = dynamic resolver address and r11 = DSO
|
// Load r12 = dynamic resolver address and r11 = DSO
|
||||||
// identifier from the first two doublewords of the PLT.
|
// identifier from the first two doublewords of the PLT.
|
||||||
ld.Adduint32(ctxt, glink, 0xe98b0000) // ld r12,0(r11)
|
glink.AddUint32(ctxt.Arch, 0xe98b0000) // ld r12,0(r11)
|
||||||
ld.Adduint32(ctxt, glink, 0xe96b0008) // ld r11,8(r11)
|
glink.AddUint32(ctxt.Arch, 0xe96b0008) // ld r11,8(r11)
|
||||||
|
|
||||||
// Jump to the dynamic resolver
|
// Jump to the dynamic resolver
|
||||||
ld.Adduint32(ctxt, glink, 0x7d8903a6) // mtctr r12
|
glink.AddUint32(ctxt.Arch, 0x7d8903a6) // mtctr r12
|
||||||
ld.Adduint32(ctxt, glink, 0x4e800420) // bctr
|
glink.AddUint32(ctxt.Arch, 0x4e800420) // bctr
|
||||||
|
|
||||||
// The symbol resolvers must immediately follow.
|
// The symbol resolvers must immediately follow.
|
||||||
// res_0:
|
// res_0:
|
||||||
|
|
|
||||||
|
|
@ -65,31 +65,31 @@ func gentext(ctxt *ld.Link) {
|
||||||
initfunc.Attr |= ld.AttrReachable
|
initfunc.Attr |= ld.AttrReachable
|
||||||
|
|
||||||
// larl %r2, <local.moduledata>
|
// larl %r2, <local.moduledata>
|
||||||
ld.Adduint8(ctxt, initfunc, 0xc0)
|
initfunc.AddUint8(0xc0)
|
||||||
ld.Adduint8(ctxt, initfunc, 0x20)
|
initfunc.AddUint8(0x20)
|
||||||
lmd := ld.Addrel(initfunc)
|
lmd := initfunc.AddRel()
|
||||||
lmd.Off = int32(initfunc.Size)
|
lmd.Off = int32(initfunc.Size)
|
||||||
lmd.Siz = 4
|
lmd.Siz = 4
|
||||||
lmd.Sym = ctxt.Moduledata
|
lmd.Sym = ctxt.Moduledata
|
||||||
lmd.Type = objabi.R_PCREL
|
lmd.Type = objabi.R_PCREL
|
||||||
lmd.Variant = ld.RV_390_DBL
|
lmd.Variant = ld.RV_390_DBL
|
||||||
lmd.Add = 2 + int64(lmd.Siz)
|
lmd.Add = 2 + int64(lmd.Siz)
|
||||||
ld.Adduint32(ctxt, initfunc, 0)
|
initfunc.AddUint32(ctxt.Arch, 0)
|
||||||
|
|
||||||
// jg <runtime.addmoduledata[@plt]>
|
// jg <runtime.addmoduledata[@plt]>
|
||||||
ld.Adduint8(ctxt, initfunc, 0xc0)
|
initfunc.AddUint8(0xc0)
|
||||||
ld.Adduint8(ctxt, initfunc, 0xf4)
|
initfunc.AddUint8(0xf4)
|
||||||
rel := ld.Addrel(initfunc)
|
rel := initfunc.AddRel()
|
||||||
rel.Off = int32(initfunc.Size)
|
rel.Off = int32(initfunc.Size)
|
||||||
rel.Siz = 4
|
rel.Siz = 4
|
||||||
rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
||||||
rel.Type = objabi.R_CALL
|
rel.Type = objabi.R_CALL
|
||||||
rel.Variant = ld.RV_390_DBL
|
rel.Variant = ld.RV_390_DBL
|
||||||
rel.Add = 2 + int64(rel.Siz)
|
rel.Add = 2 + int64(rel.Siz)
|
||||||
ld.Adduint32(ctxt, initfunc, 0)
|
initfunc.AddUint32(ctxt.Arch, 0)
|
||||||
|
|
||||||
// undef (for debugging)
|
// undef (for debugging)
|
||||||
ld.Adduint32(ctxt, initfunc, 0)
|
initfunc.AddUint32(ctxt.Arch, 0)
|
||||||
if ld.Buildmode == ld.BuildmodePlugin {
|
if ld.Buildmode == ld.BuildmodePlugin {
|
||||||
ctxt.Textp = append(ctxt.Textp, addmoduledata)
|
ctxt.Textp = append(ctxt.Textp, addmoduledata)
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +98,7 @@ func gentext(ctxt *ld.Link) {
|
||||||
initarray_entry.Attr |= ld.AttrLocal
|
initarray_entry.Attr |= ld.AttrLocal
|
||||||
initarray_entry.Attr |= ld.AttrReachable
|
initarray_entry.Attr |= ld.AttrReachable
|
||||||
initarray_entry.Type = ld.SINITARR
|
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 {
|
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)
|
got := ctxt.Syms.Lookup(".got", 0)
|
||||||
if plt.Size == 0 {
|
if plt.Size == 0 {
|
||||||
// stg %r1,56(%r15)
|
// stg %r1,56(%r15)
|
||||||
ld.Adduint8(ctxt, plt, 0xe3)
|
plt.AddUint8(0xe3)
|
||||||
ld.Adduint8(ctxt, plt, 0x10)
|
plt.AddUint8(0x10)
|
||||||
ld.Adduint8(ctxt, plt, 0xf0)
|
plt.AddUint8(0xf0)
|
||||||
ld.Adduint8(ctxt, plt, 0x38)
|
plt.AddUint8(0x38)
|
||||||
ld.Adduint8(ctxt, plt, 0x00)
|
plt.AddUint8(0x00)
|
||||||
ld.Adduint8(ctxt, plt, 0x24)
|
plt.AddUint8(0x24)
|
||||||
// larl %r1,_GLOBAL_OFFSET_TABLE_
|
// larl %r1,_GLOBAL_OFFSET_TABLE_
|
||||||
ld.Adduint8(ctxt, plt, 0xc0)
|
plt.AddUint8(0xc0)
|
||||||
ld.Adduint8(ctxt, plt, 0x10)
|
plt.AddUint8(0x10)
|
||||||
ld.Addpcrelplus(ctxt, plt, got, 6)
|
plt.AddPCRelPlus(ctxt.Arch, got, 6)
|
||||||
// mvc 48(8,%r15),8(%r1)
|
// mvc 48(8,%r15),8(%r1)
|
||||||
ld.Adduint8(ctxt, plt, 0xd2)
|
plt.AddUint8(0xd2)
|
||||||
ld.Adduint8(ctxt, plt, 0x07)
|
plt.AddUint8(0x07)
|
||||||
ld.Adduint8(ctxt, plt, 0xf0)
|
plt.AddUint8(0xf0)
|
||||||
ld.Adduint8(ctxt, plt, 0x30)
|
plt.AddUint8(0x30)
|
||||||
ld.Adduint8(ctxt, plt, 0x10)
|
plt.AddUint8(0x10)
|
||||||
ld.Adduint8(ctxt, plt, 0x08)
|
plt.AddUint8(0x08)
|
||||||
// lg %r1,16(%r1)
|
// lg %r1,16(%r1)
|
||||||
ld.Adduint8(ctxt, plt, 0xe3)
|
plt.AddUint8(0xe3)
|
||||||
ld.Adduint8(ctxt, plt, 0x10)
|
plt.AddUint8(0x10)
|
||||||
ld.Adduint8(ctxt, plt, 0x10)
|
plt.AddUint8(0x10)
|
||||||
ld.Adduint8(ctxt, plt, 0x10)
|
plt.AddUint8(0x10)
|
||||||
ld.Adduint8(ctxt, plt, 0x00)
|
plt.AddUint8(0x00)
|
||||||
ld.Adduint8(ctxt, plt, 0x04)
|
plt.AddUint8(0x04)
|
||||||
// br %r1
|
// br %r1
|
||||||
ld.Adduint8(ctxt, plt, 0x07)
|
plt.AddUint8(0x07)
|
||||||
ld.Adduint8(ctxt, plt, 0xf1)
|
plt.AddUint8(0xf1)
|
||||||
// nopr %r0
|
// nopr %r0
|
||||||
ld.Adduint8(ctxt, plt, 0x07)
|
plt.AddUint8(0x07)
|
||||||
ld.Adduint8(ctxt, plt, 0x00)
|
plt.AddUint8(0x00)
|
||||||
// nopr %r0
|
// nopr %r0
|
||||||
ld.Adduint8(ctxt, plt, 0x07)
|
plt.AddUint8(0x07)
|
||||||
ld.Adduint8(ctxt, plt, 0x00)
|
plt.AddUint8(0x00)
|
||||||
// nopr %r0
|
// nopr %r0
|
||||||
ld.Adduint8(ctxt, plt, 0x07)
|
plt.AddUint8(0x07)
|
||||||
ld.Adduint8(ctxt, plt, 0x00)
|
plt.AddUint8(0x00)
|
||||||
|
|
||||||
// assume got->size == 0 too
|
// 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)
|
got.AddUint64(ctxt.Arch, 0)
|
||||||
ld.Adduint64(ctxt, got, 0)
|
got.AddUint64(ctxt.Arch, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -431,45 +431,45 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
|
||||||
}
|
}
|
||||||
// larl %r1,_GLOBAL_OFFSET_TABLE_+index
|
// larl %r1,_GLOBAL_OFFSET_TABLE_+index
|
||||||
|
|
||||||
ld.Adduint8(ctxt, plt, 0xc0)
|
plt.AddUint8(0xc0)
|
||||||
ld.Adduint8(ctxt, plt, 0x10)
|
plt.AddUint8(0x10)
|
||||||
ld.Addpcrelplus(ctxt, plt, got, got.Size+6) // need variant?
|
plt.AddPCRelPlus(ctxt.Arch, got, got.Size+6) // need variant?
|
||||||
|
|
||||||
// add to got: pointer to current pos in plt
|
// 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)
|
// lg %r1,0(%r1)
|
||||||
ld.Adduint8(ctxt, plt, 0xe3)
|
plt.AddUint8(0xe3)
|
||||||
ld.Adduint8(ctxt, plt, 0x10)
|
plt.AddUint8(0x10)
|
||||||
ld.Adduint8(ctxt, plt, 0x10)
|
plt.AddUint8(0x10)
|
||||||
ld.Adduint8(ctxt, plt, 0x00)
|
plt.AddUint8(0x00)
|
||||||
ld.Adduint8(ctxt, plt, 0x00)
|
plt.AddUint8(0x00)
|
||||||
ld.Adduint8(ctxt, plt, 0x04)
|
plt.AddUint8(0x04)
|
||||||
// br %r1
|
// br %r1
|
||||||
ld.Adduint8(ctxt, plt, 0x07)
|
plt.AddUint8(0x07)
|
||||||
ld.Adduint8(ctxt, plt, 0xf1)
|
plt.AddUint8(0xf1)
|
||||||
// basr %r1,%r0
|
// basr %r1,%r0
|
||||||
ld.Adduint8(ctxt, plt, 0x0d)
|
plt.AddUint8(0x0d)
|
||||||
ld.Adduint8(ctxt, plt, 0x10)
|
plt.AddUint8(0x10)
|
||||||
// lgf %r1,12(%r1)
|
// lgf %r1,12(%r1)
|
||||||
ld.Adduint8(ctxt, plt, 0xe3)
|
plt.AddUint8(0xe3)
|
||||||
ld.Adduint8(ctxt, plt, 0x10)
|
plt.AddUint8(0x10)
|
||||||
ld.Adduint8(ctxt, plt, 0x10)
|
plt.AddUint8(0x10)
|
||||||
ld.Adduint8(ctxt, plt, 0x0c)
|
plt.AddUint8(0x0c)
|
||||||
ld.Adduint8(ctxt, plt, 0x00)
|
plt.AddUint8(0x00)
|
||||||
ld.Adduint8(ctxt, plt, 0x14)
|
plt.AddUint8(0x14)
|
||||||
// jg .plt
|
// jg .plt
|
||||||
ld.Adduint8(ctxt, plt, 0xc0)
|
plt.AddUint8(0xc0)
|
||||||
ld.Adduint8(ctxt, plt, 0xf4)
|
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
|
//.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
|
// 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))
|
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_JMP_SLOT))
|
||||||
ld.Adduint64(ctxt, rela, 0)
|
rela.AddUint64(ctxt.Arch, 0)
|
||||||
|
|
||||||
s.Plt = int32(plt.Size - 32)
|
s.Plt = int32(plt.Size - 32)
|
||||||
|
|
||||||
|
|
@ -486,13 +486,13 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
|
||||||
ld.Adddynsym(ctxt, s)
|
ld.Adddynsym(ctxt, s)
|
||||||
got := ctxt.Syms.Lookup(".got", 0)
|
got := ctxt.Syms.Lookup(".got", 0)
|
||||||
s.Got = int32(got.Size)
|
s.Got = int32(got.Size)
|
||||||
ld.Adduint64(ctxt, got, 0)
|
got.AddUint64(ctxt.Arch, 0)
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
rela := ctxt.Syms.Lookup(".rela", 0)
|
rela := ctxt.Syms.Lookup(".rela", 0)
|
||||||
ld.Addaddrplus(ctxt, rela, got, int64(s.Got))
|
rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
|
||||||
ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_GLOB_DAT))
|
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_GLOB_DAT))
|
||||||
ld.Adduint64(ctxt, rela, 0)
|
rela.AddUint64(ctxt.Arch, 0)
|
||||||
} else {
|
} else {
|
||||||
ld.Errorf(s, "addgotsym: unsupported binary format")
|
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
|
s.Attr |= ld.AttrReachable
|
||||||
i := s.Size
|
i := s.Size
|
||||||
s.Size += 4
|
s.Size += 4
|
||||||
ld.Symgrow(s, s.Size)
|
s.Grow(s.Size)
|
||||||
r := ld.Addrel(s)
|
r := s.AddRel()
|
||||||
r.Sym = t
|
r.Sym = t
|
||||||
r.Off = int32(i)
|
r.Off = int32(i)
|
||||||
r.Type = objabi.R_CALL
|
r.Type = objabi.R_CALL
|
||||||
|
|
@ -87,7 +87,7 @@ func gentext(ctxt *ld.Link) {
|
||||||
thunkfunc.Attr |= ld.AttrReachable //TODO: remove?
|
thunkfunc.Attr |= ld.AttrReachable //TODO: remove?
|
||||||
o := func(op ...uint8) {
|
o := func(op ...uint8) {
|
||||||
for _, op1 := range op {
|
for _, op1 := range op {
|
||||||
ld.Adduint8(ctxt, thunkfunc, op1)
|
thunkfunc.AddUint8(op1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 8b 04 24 mov (%esp),%eax
|
// 8b 04 24 mov (%esp),%eax
|
||||||
|
|
@ -115,7 +115,7 @@ func gentext(ctxt *ld.Link) {
|
||||||
initfunc.Attr |= ld.AttrReachable
|
initfunc.Attr |= ld.AttrReachable
|
||||||
o := func(op ...uint8) {
|
o := func(op ...uint8) {
|
||||||
for _, op1 := range op {
|
for _, op1 := range op {
|
||||||
ld.Adduint8(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))
|
addcall(ctxt, initfunc, ctxt.Syms.Lookup("__x86.get_pc_thunk.cx", 0))
|
||||||
|
|
||||||
o(0x8d, 0x81)
|
o(0x8d, 0x81)
|
||||||
ld.Addpcrelplus(ctxt, initfunc, ctxt.Moduledata, 6)
|
initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata, 6)
|
||||||
|
|
||||||
o(0x8d, 0x99)
|
o(0x8d, 0x99)
|
||||||
i := initfunc.Size
|
i := initfunc.Size
|
||||||
initfunc.Size += 4
|
initfunc.Size += 4
|
||||||
ld.Symgrow(initfunc, initfunc.Size)
|
initfunc.Grow(initfunc.Size)
|
||||||
r := ld.Addrel(initfunc)
|
r := initfunc.AddRel()
|
||||||
r.Sym = ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
|
r.Sym = ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
|
||||||
r.Off = int32(i)
|
r.Off = int32(i)
|
||||||
r.Type = objabi.R_PCREL
|
r.Type = objabi.R_PCREL
|
||||||
|
|
@ -162,7 +162,7 @@ func gentext(ctxt *ld.Link) {
|
||||||
initarray_entry.Attr |= ld.AttrReachable
|
initarray_entry.Attr |= ld.AttrReachable
|
||||||
initarray_entry.Attr |= ld.AttrLocal
|
initarray_entry.Attr |= ld.AttrLocal
|
||||||
initarray_entry.Type = ld.SINITARR
|
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 {
|
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 {
|
if ld.Iself {
|
||||||
ld.Adddynsym(ctxt, targ)
|
ld.Adddynsym(ctxt, targ)
|
||||||
rel := ctxt.Syms.Lookup(".rel", 0)
|
rel := ctxt.Syms.Lookup(".rel", 0)
|
||||||
ld.Addaddrplus(ctxt, rel, s, int64(r.Off))
|
rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
|
||||||
ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(targ.Dynid), ld.R_386_32))
|
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.Type = objabi.R_CONST // write r->add during relocsym
|
||||||
r.Sym = nil
|
r.Sym = nil
|
||||||
return true
|
return true
|
||||||
|
|
@ -331,8 +331,8 @@ func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
|
||||||
s.Sub = got.Sub
|
s.Sub = got.Sub
|
||||||
got.Sub = s
|
got.Sub = s
|
||||||
s.Value = got.Size
|
s.Value = got.Size
|
||||||
ld.Adduint32(ctxt, got, 0)
|
got.AddUint32(ctxt.Arch, 0)
|
||||||
ld.Adduint32(ctxt, ctxt.Syms.Lookup(".linkedit.got", 0), uint32(targ.Dynid))
|
ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid))
|
||||||
r.Type = 256 // ignore during relocsym
|
r.Type = 256 // ignore during relocsym
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -508,25 +508,25 @@ func elfsetupplt(ctxt *ld.Link) {
|
||||||
got := ctxt.Syms.Lookup(".got.plt", 0)
|
got := ctxt.Syms.Lookup(".got.plt", 0)
|
||||||
if plt.Size == 0 {
|
if plt.Size == 0 {
|
||||||
// pushl got+4
|
// pushl got+4
|
||||||
ld.Adduint8(ctxt, plt, 0xff)
|
plt.AddUint8(0xff)
|
||||||
|
|
||||||
ld.Adduint8(ctxt, plt, 0x35)
|
plt.AddUint8(0x35)
|
||||||
ld.Addaddrplus(ctxt, plt, got, 4)
|
plt.AddAddrPlus(ctxt.Arch, got, 4)
|
||||||
|
|
||||||
// jmp *got+8
|
// jmp *got+8
|
||||||
ld.Adduint8(ctxt, plt, 0xff)
|
plt.AddUint8(0xff)
|
||||||
|
|
||||||
ld.Adduint8(ctxt, plt, 0x25)
|
plt.AddUint8(0x25)
|
||||||
ld.Addaddrplus(ctxt, plt, got, 8)
|
plt.AddAddrPlus(ctxt.Arch, got, 8)
|
||||||
|
|
||||||
// zero pad
|
// zero pad
|
||||||
ld.Adduint32(ctxt, plt, 0)
|
plt.AddUint32(ctxt.Arch, 0)
|
||||||
|
|
||||||
// assume got->size == 0 too
|
// 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)
|
got.AddUint32(ctxt.Arch, 0)
|
||||||
ld.Adduint32(ctxt, got, 0)
|
got.AddUint32(ctxt.Arch, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -546,28 +546,28 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// jmpq *got+size
|
// jmpq *got+size
|
||||||
ld.Adduint8(ctxt, plt, 0xff)
|
plt.AddUint8(0xff)
|
||||||
|
|
||||||
ld.Adduint8(ctxt, plt, 0x25)
|
plt.AddUint8(0x25)
|
||||||
ld.Addaddrplus(ctxt, plt, got, got.Size)
|
plt.AddAddrPlus(ctxt.Arch, got, got.Size)
|
||||||
|
|
||||||
// add to got: pointer to current pos in plt
|
// 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
|
// 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
|
// 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
|
// 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)
|
s.Plt = int32(plt.Size - 16)
|
||||||
} else if ld.Headtype == objabi.Hdarwin {
|
} else if ld.Headtype == objabi.Hdarwin {
|
||||||
|
|
@ -577,14 +577,14 @@ func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
|
||||||
|
|
||||||
addgotsym(ctxt, s)
|
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)
|
// jmpq *got+size(IP)
|
||||||
s.Plt = int32(plt.Size)
|
s.Plt = int32(plt.Size)
|
||||||
|
|
||||||
ld.Adduint8(ctxt, plt, 0xff)
|
plt.AddUint8(0xff)
|
||||||
ld.Adduint8(ctxt, plt, 0x25)
|
plt.AddUint8(0x25)
|
||||||
ld.Addaddrplus(ctxt, plt, ctxt.Syms.Lookup(".got", 0), int64(s.Got))
|
plt.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got))
|
||||||
} else {
|
} else {
|
||||||
ld.Errorf(s, "addpltsym: unsupported binary format")
|
ld.Errorf(s, "addpltsym: unsupported binary format")
|
||||||
}
|
}
|
||||||
|
|
@ -598,14 +598,14 @@ func addgotsym(ctxt *ld.Link, s *ld.Symbol) {
|
||||||
ld.Adddynsym(ctxt, s)
|
ld.Adddynsym(ctxt, s)
|
||||||
got := ctxt.Syms.Lookup(".got", 0)
|
got := ctxt.Syms.Lookup(".got", 0)
|
||||||
s.Got = int32(got.Size)
|
s.Got = int32(got.Size)
|
||||||
ld.Adduint32(ctxt, got, 0)
|
got.AddUint32(ctxt.Arch, 0)
|
||||||
|
|
||||||
if ld.Iself {
|
if ld.Iself {
|
||||||
rel := ctxt.Syms.Lookup(".rel", 0)
|
rel := ctxt.Syms.Lookup(".rel", 0)
|
||||||
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_386_GLOB_DAT))
|
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_GLOB_DAT))
|
||||||
} else if ld.Headtype == objabi.Hdarwin {
|
} 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 {
|
} else {
|
||||||
ld.Errorf(s, "addgotsym: unsupported binary format")
|
ld.Errorf(s, "addgotsym: unsupported binary format")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue