}
}
-func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
+func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
targ := r.Sym
switch r.Type {
default:
if r.Type >= objabi.ElfRelocOffset {
- ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
+ ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(target.Arch, r.Type))
return false
}
r.Type = objabi.R_PCREL
r.Add += 4
if targ.Type == sym.SDYNIMPORT {
- addpltsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".plt", 0)
+ addpltsym(target, syms, targ)
+ r.Sym = syms.PLT
r.Add += int64(targ.Plt())
}
// fall back to using GOT and hope for the best (CMOV*)
// TODO: just needs relocation, no need to put in .dynsym
- addgotsym(ctxt, targ)
+ addgotsym(target, syms, targ)
r.Type = objabi.R_PCREL
- r.Sym = ctxt.Syms.Lookup(".got", 0)
+ r.Sym = syms.GOT
r.Add += 4
r.Add += int64(targ.Got())
return true
ld.Errorf(s, "unexpected R_X86_64_64 relocation for dynamic symbol %s", targ.Name)
}
r.Type = objabi.R_ADDR
- if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal {
+ if target.IsPIE() && target.IsInternal() {
// For internal linking PIE, this R_ADDR relocation cannot
// be resolved statically. We need to generate a dynamic
// relocation. Let the code below handle it.
case objabi.MachoRelocOffset + ld.MACHO_X86_64_RELOC_BRANCH*2 + 1:
if targ.Type == sym.SDYNIMPORT {
- addpltsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".plt", 0)
+ addpltsym(target, syms, targ)
+ r.Sym = syms.PLT
r.Add = int64(targ.Plt())
r.Type = objabi.R_PCREL
return true
if targ.Type != sym.SDYNIMPORT {
ld.Errorf(s, "unexpected GOT reloc for non-dynamic symbol %s", targ.Name)
}
- addgotsym(ctxt, targ)
+ addgotsym(target, syms, targ)
r.Type = objabi.R_PCREL
- r.Sym = ctxt.Syms.Lookup(".got", 0)
+ r.Sym = syms.GOT
r.Add += int64(targ.Got())
return true
}
// nothing to do, the relocation will be laid out in reloc
return true
}
- if ctxt.LinkMode == ld.LinkExternal {
+ if target.IsExternal() {
// External linker will do this relocation.
return true
}
// Internal linking, for both ELF and Mach-O.
// Build a PLT entry and change the relocation target to that entry.
- addpltsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".plt", 0)
+ addpltsym(target, syms, targ)
+ r.Sym = syms.PLT
r.Add = int64(targ.Plt())
return true
case objabi.R_ADDR:
- if s.Type == sym.STEXT && ctxt.IsELF {
- if ctxt.HeadType == objabi.Hsolaris {
- addpltsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".plt", 0)
+ if s.Type == sym.STEXT && target.IsElf() {
+ if target.IsSolaris() {
+ addpltsym(target, syms, targ)
+ r.Sym = syms.PLT
r.Add += int64(targ.Plt())
return true
}
// The code is asking for the address of an external
// function. We provide it with the address of the
// correspondent GOT symbol.
- addgotsym(ctxt, targ)
+ addgotsym(target, syms, targ)
- r.Sym = ctxt.Syms.Lookup(".got", 0)
+ r.Sym = syms.GOT
r.Add += int64(targ.Got())
return true
}
// Process dynamic relocations for the data sections.
- if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal {
+ if target.IsPIE() && target.IsInternal() {
// When internally linking, generate dynamic relocations
// for all typical R_ADDR relocations. The exception
// are those R_ADDR that are created as part of generating
}
}
- if ctxt.IsELF {
+ if target.IsElf() {
// Generate R_X86_64_RELATIVE relocations for best
// efficiency in the dynamic linker.
//
// AddAddrPlus is used for r_offset and r_addend to
// generate new R_ADDR relocations that will update
// these fields in the 'reloc' phase.
- rela := ctxt.Syms.Lookup(".rela", 0)
- rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
+ rela := syms.Rela
+ rela.AddAddrPlus(target.Arch, s, int64(r.Off))
if r.Siz == 8 {
- rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_X86_64_RELATIVE)))
+ rela.AddUint64(target.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_X86_64_RELATIVE)))
} else {
ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
}
- rela.AddAddrPlus(ctxt.Arch, targ, int64(r.Add))
+ rela.AddAddrPlus(target.Arch, targ, int64(r.Add))
// Not mark r done here. So we still apply it statically,
// so in the file content we'll also have the right offset
// to the relocation target. So it can be examined statically
return true
}
- if ctxt.HeadType == objabi.Hdarwin && s.Size == int64(ctxt.Arch.PtrSize) && r.Off == 0 {
+ if target.IsDarwin() && s.Size == int64(target.Arch.PtrSize) && r.Off == 0 {
// Mach-O relocations are a royal pain to lay out.
// They use a compact stateful bytecode representation
// that is too much bother to deal with.
// just in case the C code assigns to the variable,
// and of course it only works for single pointers,
// but we only need to support cgo and that's all it needs.
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, targ)
+ ld.Adddynsym(target, syms, targ)
- got := ctxt.Syms.Lookup(".got", 0)
+ got := syms.GOT
s.Type = got.Type
s.Attr |= sym.AttrSubSymbol
s.Outer = got
s.Sub = got.Sub
got.Sub = s
s.Value = got.Size
- got.AddUint64(ctxt.Arch, 0)
- ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid))
+ got.AddUint64(target.Arch, 0)
+ syms.LinkEditGOT.AddUint32(target.Arch, uint32(targ.Dynid))
r.Type = objabi.ElfRelocOffset // ignore during relocsym
return true
}
}
}
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
+func addpltsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) {
if s.Plt() >= 0 {
return
}
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s)
+ ld.Adddynsym(target, syms, s)
- if ctxt.IsELF {
- plt := ctxt.Syms.Lookup(".plt", 0)
- got := ctxt.Syms.Lookup(".got.plt", 0)
- rela := ctxt.Syms.Lookup(".rela.plt", 0)
+ if target.IsElf() {
+ plt := syms.PLT
+ got := syms.GOTPLT
+ rela := syms.RelaPLT
if plt.Size == 0 {
panic("plt is not set up")
}
plt.AddUint8(0xff)
plt.AddUint8(0x25)
- plt.AddPCRelPlus(ctxt.Arch, got, got.Size)
+ plt.AddPCRelPlus(target.Arch, got, got.Size)
// add to got: pointer to current pos in plt
- got.AddAddrPlus(ctxt.Arch, plt, plt.Size)
+ got.AddAddrPlus(target.Arch, plt, plt.Size)
// pushq $x
plt.AddUint8(0x68)
- plt.AddUint32(ctxt.Arch, uint32((got.Size-24-8)/8))
+ plt.AddUint32(target.Arch, uint32((got.Size-24-8)/8))
// jmpq .plt
plt.AddUint8(0xe9)
- plt.AddUint32(ctxt.Arch, uint32(-(plt.Size + 4)))
+ plt.AddUint32(target.Arch, uint32(-(plt.Size + 4)))
// rela
- rela.AddAddrPlus(ctxt.Arch, got, got.Size-8)
+ rela.AddAddrPlus(target.Arch, got, got.Size-8)
- rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_JMP_SLOT)))
- rela.AddUint64(ctxt.Arch, 0)
+ rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_JMP_SLOT)))
+ rela.AddUint64(target.Arch, 0)
s.SetPlt(int32(plt.Size - 16))
- } else if ctxt.HeadType == objabi.Hdarwin {
+ } else if target.IsDarwin() {
// To do lazy symbol lookup right, we're supposed
// to tell the dynamic loader which library each
// symbol comes from and format the link info
// https://networkpx.blogspot.com/2009/09/about-lcdyldinfoonly-command.html
// has details about what we're avoiding.
- addgotsym(ctxt, s)
- plt := ctxt.Syms.Lookup(".plt", 0)
+ addgotsym(target, syms, s)
+ plt := syms.PLT
- ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
+ syms.LinkEditPLT.AddUint32(target.Arch, uint32(s.Dynid))
// jmpq *got+size(IP)
s.SetPlt(int32(plt.Size))
plt.AddUint8(0xff)
plt.AddUint8(0x25)
- plt.AddPCRelPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got()))
+ plt.AddPCRelPlus(target.Arch, syms.GOT, int64(s.Got()))
} else {
ld.Errorf(s, "addpltsym: unsupported binary format")
}
}
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
+func addgotsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) {
if s.Got() >= 0 {
return
}
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s)
- got := ctxt.Syms.Lookup(".got", 0)
+ ld.Adddynsym(target, syms, s)
+ got := syms.GOT
s.SetGot(int32(got.Size))
- got.AddUint64(ctxt.Arch, 0)
-
- if ctxt.IsELF {
- rela := ctxt.Syms.Lookup(".rela", 0)
- rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
- rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_GLOB_DAT)))
- rela.AddUint64(ctxt.Arch, 0)
- } else if ctxt.HeadType == objabi.Hdarwin {
- ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
+ got.AddUint64(target.Arch, 0)
+
+ if target.IsElf() {
+ rela := syms.Rela
+ rela.AddAddrPlus(target.Arch, got, int64(s.Got()))
+ rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_GLOB_DAT)))
+ rela.AddUint64(target.Arch, 0)
+ } else if target.IsDarwin() {
+ syms.LinkEditGOT.AddUint32(target.Arch, uint32(s.Dynid))
} else {
ld.Errorf(s, "addgotsym: unsupported binary format")
}
return int32((uint32(a))&0xff000000 | 0x00ffffff&uint32(a+b))
}
-func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
+func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
targ := r.Sym
switch r.Type {
default:
if r.Type >= objabi.ElfRelocOffset {
- ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
+ ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(target.Arch, r.Type))
return false
}
r.Type = objabi.R_CALLARM
if targ.Type == sym.SDYNIMPORT {
- addpltsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".plt", 0)
+ addpltsym(target, syms, targ)
+ r.Sym = syms.PLT
r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4))
}
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOT32): // R_ARM_GOT_BREL
if targ.Type != sym.SDYNIMPORT {
- addgotsyminternal(ctxt, targ)
+ addgotsyminternal(target, syms, targ)
} else {
- addgotsym(ctxt, targ)
+ addgotsym(target, syms, targ)
}
r.Type = objabi.R_CONST // write r->add during relocsym
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOT_PREL): // GOT(nil) + A - nil
if targ.Type != sym.SDYNIMPORT {
- addgotsyminternal(ctxt, targ)
+ addgotsyminternal(target, syms, targ)
} else {
- addgotsym(ctxt, targ)
+ addgotsym(target, syms, targ)
}
r.Type = objabi.R_PCREL
- r.Sym = ctxt.Syms.Lookup(".got", 0)
+ r.Sym = syms.GOT
r.Add += int64(targ.Got()) + 4
return true
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_GOTPC): // R_ARM_BASE_PREL
r.Type = objabi.R_PCREL
- r.Sym = ctxt.Syms.Lookup(".got", 0)
+ r.Sym = syms.GOT
r.Add += 4
return true
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_CALL):
r.Type = objabi.R_CALLARM
if targ.Type == sym.SDYNIMPORT {
- addpltsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".plt", 0)
+ addpltsym(target, syms, targ)
+ r.Sym = syms.PLT
r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4))
}
objabi.ElfRelocOffset + objabi.RelocType(elf.R_ARM_JUMP24):
r.Type = objabi.R_CALLARM
if targ.Type == sym.SDYNIMPORT {
- addpltsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".plt", 0)
+ addpltsym(target, syms, targ)
+ r.Sym = syms.PLT
r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4))
}
switch r.Type {
case objabi.R_CALLARM:
- if ctxt.LinkMode == ld.LinkExternal {
+ if target.IsExternal() {
// External linker will do this relocation.
return true
}
- addpltsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".plt", 0)
+ addpltsym(target, syms, targ)
+ r.Sym = syms.PLT
r.Add = int64(targ.Plt())
return true
if s.Type != sym.SDATA {
break
}
- if ctxt.IsELF {
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, targ)
- rel := ctxt.Syms.Lookup(".rel", 0)
- rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
- rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_ARM_GLOB_DAT))) // we need a nil + A dynamic reloc
- r.Type = objabi.R_CONST // write r->add during relocsym
+ if target.IsElf() {
+ ld.Adddynsym(target, syms, targ)
+ rel := syms.Rel
+ rel.AddAddrPlus(target.Arch, s, int64(r.Off))
+ rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_ARM_GLOB_DAT))) // we need a nil + A dynamic reloc
+ r.Type = objabi.R_CONST // write r->add during relocsym
r.Sym = nil
return true
}
return t
}
-func addpltreloc(ctxt *ld.Link, plt *sym.Symbol, got *sym.Symbol, s *sym.Symbol, typ objabi.RelocType) {
+func addpltreloc(plt *sym.Symbol, got *sym.Symbol, s *sym.Symbol, typ objabi.RelocType) {
r := plt.AddRel()
r.Sym = got
r.Off = int32(plt.Size)
plt.Grow(plt.Size)
}
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
+func addpltsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) {
if s.Plt() >= 0 {
return
}
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s)
+ ld.Adddynsym(target, syms, s)
- if ctxt.IsELF {
- plt := ctxt.Syms.Lookup(".plt", 0)
- got := ctxt.Syms.Lookup(".got.plt", 0)
- rel := ctxt.Syms.Lookup(".rel.plt", 0)
+ if target.IsElf() {
+ plt := syms.PLT
+ got := syms.GOTPLT
+ rel := syms.RelPLT
if plt.Size == 0 {
panic("plt is not set up")
}
// In theory, all GOT should point to the first PLT entry,
// Linux/ARM's dynamic linker will do that for us, but FreeBSD/ARM's
// dynamic linker won't, so we'd better do it ourselves.
- got.AddAddrPlus(ctxt.Arch, plt, 0)
+ got.AddAddrPlus(target.Arch, plt, 0)
// .plt entry, this depends on the .got entry
s.SetPlt(int32(plt.Size))
- addpltreloc(ctxt, plt, got, s, objabi.R_PLT0) // add lr, pc, #0xXX00000
- addpltreloc(ctxt, plt, got, s, objabi.R_PLT1) // add lr, lr, #0xYY000
- addpltreloc(ctxt, plt, got, s, objabi.R_PLT2) // ldr pc, [lr, #0xZZZ]!
+ addpltreloc(plt, got, s, objabi.R_PLT0) // add lr, pc, #0xXX00000
+ addpltreloc(plt, got, s, objabi.R_PLT1) // add lr, lr, #0xYY000
+ addpltreloc(plt, got, s, objabi.R_PLT2) // ldr pc, [lr, #0xZZZ]!
// rel
- rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
+ rel.AddAddrPlus(target.Arch, got, int64(s.Got()))
- rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_JUMP_SLOT)))
+ rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_JUMP_SLOT)))
} else {
ld.Errorf(s, "addpltsym: unsupported binary format")
}
}
-func addgotsyminternal(ctxt *ld.Link, s *sym.Symbol) {
+func addgotsyminternal(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) {
if s.Got() >= 0 {
return
}
- got := ctxt.Syms.Lookup(".got", 0)
+ got := syms.GOT
s.SetGot(int32(got.Size))
- got.AddAddrPlus(ctxt.Arch, s, 0)
+ got.AddAddrPlus(target.Arch, s, 0)
- if ctxt.IsELF {
+ if target.IsElf() {
} else {
ld.Errorf(s, "addgotsyminternal: unsupported binary format")
}
}
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
+func addgotsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) {
if s.Got() >= 0 {
return
}
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s)
- got := ctxt.Syms.Lookup(".got", 0)
+ ld.Adddynsym(target, syms, s)
+ got := syms.GOT
s.SetGot(int32(got.Size))
- got.AddUint32(ctxt.Arch, 0)
+ got.AddUint32(target.Arch, 0)
- if ctxt.IsELF {
- rel := ctxt.Syms.Lookup(".rel", 0)
- rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
- rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_GLOB_DAT)))
+ if target.IsElf() {
+ rel := syms.Rel
+ rel.AddAddrPlus(target.Arch, got, int64(s.Got()))
+ rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_GLOB_DAT)))
} else {
ld.Errorf(s, "addgotsym: unsupported binary format")
}
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
-func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
+func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
targ := r.Sym
switch r.Type {
default:
if r.Type >= objabi.ElfRelocOffset {
- ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
+ ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(target.Arch, r.Type))
return false
}
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_CALL26),
objabi.ElfRelocOffset + objabi.RelocType(elf.R_AARCH64_JUMP26):
if targ.Type == sym.SDYNIMPORT {
- addpltsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".plt", 0)
+ addpltsym(target, syms, targ)
+ r.Sym = syms.PLT
r.Add += int64(targ.Plt())
}
if (targ.Type == 0 || targ.Type == sym.SXREF) && !targ.Attr.VisibilityHidden() {
// fall back to using GOT
// TODO: just needs relocation, no need to put in .dynsym
- addgotsym(ctxt, targ)
+ addgotsym(target, syms, targ)
r.Type = objabi.R_ARM64_GOT
- r.Sym = ctxt.Syms.Lookup(".got", 0)
+ r.Sym = syms.GOT
r.Add += int64(targ.Got())
return true
ld.Errorf(s, "unexpected R_AARCH64_ABS64 relocation for dynamic symbol %s", targ.Name)
}
r.Type = objabi.R_ADDR
- if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal {
+ if target.IsPIE() && target.IsInternal() {
// For internal linking PIE, this R_ADDR relocation cannot
// be resolved statically. We need to generate a dynamic
// relocation. Let the code below handle it.
// nothing to do, the relocation will be laid out in reloc
return true
}
- if ctxt.LinkMode == ld.LinkExternal {
+ if target.IsExternal() {
// External linker will do this relocation.
return true
}
case objabi.R_ADDR:
- if s.Type == sym.STEXT && ctxt.IsELF {
+ if s.Type == sym.STEXT && target.IsElf() {
// The code is asking for the address of an external
// function. We provide it with the address of the
// correspondent GOT symbol.
- addgotsym(ctxt, targ)
+ addgotsym(target, syms, targ)
- r.Sym = ctxt.Syms.Lookup(".got", 0)
+ r.Sym = syms.GOT
r.Add += int64(targ.Got())
return true
}
// Process dynamic relocations for the data sections.
- if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal {
+ if target.IsPIE() && target.IsInternal() {
// When internally linking, generate dynamic relocations
// for all typical R_ADDR relocations. The exception
// are those R_ADDR that are created as part of generating
}
}
- if ctxt.IsELF {
+ if target.IsElf() {
// Generate R_AARCH64_RELATIVE relocations for best
// efficiency in the dynamic linker.
//
// AddAddrPlus is used for r_offset and r_addend to
// generate new R_ADDR relocations that will update
// these fields in the 'reloc' phase.
- rela := ctxt.Syms.Lookup(".rela", 0)
- rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
+ rela := syms.Rela
+ rela.AddAddrPlus(target.Arch, s, int64(r.Off))
if r.Siz == 8 {
- rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_AARCH64_RELATIVE)))
+ rela.AddUint64(target.Arch, ld.ELF64_R_INFO(0, uint32(elf.R_AARCH64_RELATIVE)))
} else {
ld.Errorf(s, "unexpected relocation for dynamic symbol %s", targ.Name)
}
- rela.AddAddrPlus(ctxt.Arch, targ, int64(r.Add))
+ rela.AddAddrPlus(target.Arch, targ, int64(r.Add))
// Not mark r done here. So we still apply it statically,
// so in the file content we'll also have the right offset
// to the relocation target. So it can be examined statically
}
}
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
+func addpltsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) {
if s.Plt() >= 0 {
return
}
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s)
+ ld.Adddynsym(target, syms, s)
- if ctxt.IsELF {
- plt := ctxt.Syms.Lookup(".plt", 0)
- gotplt := ctxt.Syms.Lookup(".got.plt", 0)
- rela := ctxt.Syms.Lookup(".rela.plt", 0)
+ if target.IsElf() {
+ plt := syms.PLT
+ gotplt := syms.GOTPLT
+ rela := syms.RelaPLT
if plt.Size == 0 {
panic("plt is not set up")
}
// adrp x16, &got.plt[0]
plt.AddAddrPlus4(gotplt, gotplt.Size)
- plt.SetUint32(ctxt.Arch, plt.Size-4, 0x90000010)
+ plt.SetUint32(target.Arch, plt.Size-4, 0x90000010)
plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT
// <offset> is the offset value of &got.plt[n] to &got.plt[0]
// ldr x17, [x16, <offset>]
plt.AddAddrPlus4(gotplt, gotplt.Size)
- plt.SetUint32(ctxt.Arch, plt.Size-4, 0xf9400211)
+ plt.SetUint32(target.Arch, plt.Size-4, 0xf9400211)
plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT
// add x16, x16, <offset>
plt.AddAddrPlus4(gotplt, gotplt.Size)
- plt.SetUint32(ctxt.Arch, plt.Size-4, 0x91000210)
+ plt.SetUint32(target.Arch, plt.Size-4, 0x91000210)
plt.R[len(plt.R)-1].Type = objabi.R_ARM64_PCREL
// br x17
- plt.AddUint32(ctxt.Arch, 0xd61f0220)
+ plt.AddUint32(target.Arch, 0xd61f0220)
// add to got.plt: pointer to plt[0]
- gotplt.AddAddrPlus(ctxt.Arch, plt, 0)
+ gotplt.AddAddrPlus(target.Arch, plt, 0)
// rela
- rela.AddAddrPlus(ctxt.Arch, gotplt, gotplt.Size-8)
- rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_AARCH64_JUMP_SLOT)))
- rela.AddUint64(ctxt.Arch, 0)
+ rela.AddAddrPlus(target.Arch, gotplt, gotplt.Size-8)
+ rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_AARCH64_JUMP_SLOT)))
+ rela.AddUint64(target.Arch, 0)
s.SetPlt(int32(plt.Size - 16))
} else {
}
}
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
+func addgotsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) {
if s.Got() >= 0 {
return
}
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s)
- got := ctxt.Syms.Lookup(".got", 0)
+ ld.Adddynsym(target, syms, s)
+ got := syms.GOT
s.SetGot(int32(got.Size))
- got.AddUint64(ctxt.Arch, 0)
+ got.AddUint64(target.Arch, 0)
- if ctxt.IsELF {
- rela := ctxt.Syms.Lookup(".rela", 0)
- rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
- rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_AARCH64_GLOB_DAT)))
- rela.AddUint64(ctxt.Arch, 0)
+ if target.IsElf() {
+ rela := syms.Rela
+ rela.AddAddrPlus(target.Arch, got, int64(s.Got()))
+ rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_AARCH64_GLOB_DAT)))
+ rela.AddUint64(target.Arch, 0)
} else {
ld.Errorf(s, "addgotsym: unsupported binary format")
}
Dynamic *sym.Symbol
DynSym *sym.Symbol
DynStr *sym.Symbol
+
+ // Elf specific
+ Rel *sym.Symbol
+ Rela *sym.Symbol
+ RelPLT *sym.Symbol
+ RelaPLT *sym.Symbol
+
+ // Darwin symbols
+ LinkEditGOT *sym.Symbol
+ LinkEditPLT *sym.Symbol
}
// setArchSyms sets up the ArchSyms structure, and must be called before
ctxt.DotTOC[i] = ctxt.Syms.Lookup(".TOC.", i)
}
}
+ if ctxt.IsElf() {
+ ctxt.Rel = ctxt.Syms.Lookup(".rel", 0)
+ ctxt.Rela = ctxt.Syms.Lookup(".rela", 0)
+ ctxt.RelPLT = ctxt.Syms.Lookup(".rel.plt", 0)
+ ctxt.RelaPLT = ctxt.Syms.Lookup(".rela.plt", 0)
+ }
+ if ctxt.IsDarwin() {
+ ctxt.LinkEditGOT = ctxt.Syms.Lookup(".linkedit.got", 0)
+ ctxt.LinkEditPLT = ctxt.Syms.Lookup(".linkedit.plt", 0)
+ }
}
type Arch struct {
ctxt.cgodata = nil
addToTextp(ctxt)
+
+ // Set special global symbols.
+ ctxt.setArchSyms()
}
func (ctxt *Link) dumpsyms() {
return
}
-func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
+func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
log.Fatalf("adddynrel not implemented")
return false
}
func gentext(ctxt *ld.Link) {}
-func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
+func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
log.Fatalf("adddynrel not implemented")
return false
}
stub.AddUint32(ctxt.Arch, 0x4e800420) // bctr
}
-func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
- if ctxt.IsELF {
- return addelfdynrel(ctxt, s, r)
- } else if ctxt.HeadType == objabi.Haix {
- return ld.Xcoffadddynrel(&ctxt.Target, s, r)
+func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
+ if target.IsElf() {
+ return addelfdynrel(target, syms, s, r)
+ } else if target.IsAIX() {
+ return ld.Xcoffadddynrel(target, s, r)
}
return false
}
-func addelfdynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
+
+func addelfdynrel(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
targ := r.Sym
r.InitExt()
switch r.Type {
default:
if r.Type >= objabi.ElfRelocOffset {
- ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
+ ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(target.Arch, r.Type))
return false
}
r.Type = objabi.R_ADDR
if targ.Type == sym.SDYNIMPORT {
// These happen in .toc sections
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, targ)
+ ld.Adddynsym(target, syms, targ)
- rela := ctxt.Syms.Lookup(".rela", 0)
- rela.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
- rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_PPC64_ADDR64)))
- rela.AddUint64(ctxt.Arch, uint64(r.Add))
+ rela := syms.Rela
+ rela.AddAddrPlus(target.Arch, s, int64(r.Off))
+ rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(targ.Dynid), uint32(elf.R_PPC64_ADDR64)))
+ rela.AddUint64(target.Arch, uint64(r.Add))
r.Type = objabi.ElfRelocOffset // ignore during relocsym
}
func gentext(ctxt *ld.Link) {
}
-func adddynrela(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, rel *sym.Symbol, s *sym.Symbol, r *sym.Reloc) {
+func adddynrela(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, rel *sym.Symbol, s *sym.Symbol, r *sym.Reloc) {
log.Fatalf("adddynrela not implemented")
}
-func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
+func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
log.Fatalf("adddynrel not implemented")
return false
}
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
-func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
+func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
targ := r.Sym
r.InitExt()
r.Variant = sym.RV_390_DBL
r.Add += int64(r.Siz)
if targ.Type == sym.SDYNIMPORT {
- addpltsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".plt", 0)
+ addpltsym(target, syms, targ)
+ r.Sym = syms.PLT
r.Add += int64(targ.Plt())
}
return true
r.Type = objabi.R_PCREL
r.Add += int64(r.Siz)
if targ.Type == sym.SDYNIMPORT {
- addpltsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".plt", 0)
+ addpltsym(target, syms, targ)
+ r.Sym = syms.PLT
r.Add += int64(targ.Plt())
}
return true
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPC):
r.Type = objabi.R_PCREL
- r.Sym = ctxt.Syms.Lookup(".got", 0)
+ r.Sym = syms.GOT
r.Add += int64(r.Siz)
return true
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTPCDBL):
r.Type = objabi.R_PCREL
r.Variant = sym.RV_390_DBL
- r.Sym = ctxt.Syms.Lookup(".got", 0)
+ r.Sym = syms.GOT
r.Add += int64(r.Siz)
return true
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_390_GOTENT):
- addgotsym(ctxt, targ)
+ addgotsym(target, syms, targ)
r.Type = objabi.R_PCREL
r.Variant = sym.RV_390_DBL
- r.Sym = ctxt.Syms.Lookup(".got", 0)
+ r.Sym = syms.GOT
r.Add += int64(targ.Got())
r.Add += int64(r.Siz)
return true
}
}
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
+func addpltsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) {
if s.Plt() >= 0 {
return
}
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s)
+ ld.Adddynsym(target, syms, s)
- if ctxt.IsELF {
- plt := ctxt.Syms.Lookup(".plt", 0)
- got := ctxt.Syms.Lookup(".got", 0)
- rela := ctxt.Syms.Lookup(".rela.plt", 0)
+ if target.IsElf() {
+ plt := syms.PLT
+ got := syms.GOT
+ rela := syms.RelaPLT
if plt.Size == 0 {
panic("plt is not set up")
}
plt.AddUint8(0xc0)
plt.AddUint8(0x10)
- plt.AddPCRelPlus(ctxt.Arch, got, got.Size+6) // need variant?
+ plt.AddPCRelPlus(target.Arch, got, got.Size+6) // need variant?
// add to got: pointer to current pos in plt
- got.AddAddrPlus(ctxt.Arch, plt, plt.Size+8) // weird but correct
+ got.AddAddrPlus(target.Arch, plt, plt.Size+8) // weird but correct
// lg %r1,0(%r1)
plt.AddUint8(0xe3)
plt.AddUint8(0x10)
plt.AddUint8(0xc0)
plt.AddUint8(0xf4)
- plt.AddUint32(ctxt.Arch, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation
+ plt.AddUint32(target.Arch, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation
//.plt index
- plt.AddUint32(ctxt.Arch, uint32(rela.Size)) // rela size before current entry
+ plt.AddUint32(target.Arch, uint32(rela.Size)) // rela size before current entry
// rela
- rela.AddAddrPlus(ctxt.Arch, got, got.Size-8)
+ rela.AddAddrPlus(target.Arch, got, got.Size-8)
- rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_JMP_SLOT)))
- rela.AddUint64(ctxt.Arch, 0)
+ rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_JMP_SLOT)))
+ rela.AddUint64(target.Arch, 0)
s.SetPlt(int32(plt.Size - 32))
}
}
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
+func addgotsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) {
if s.Got() >= 0 {
return
}
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s)
- got := ctxt.Syms.Lookup(".got", 0)
+ ld.Adddynsym(target, syms, s)
+ got := syms.GOT
s.SetGot(int32(got.Size))
- got.AddUint64(ctxt.Arch, 0)
+ got.AddUint64(target.Arch, 0)
- if ctxt.IsELF {
- rela := ctxt.Syms.Lookup(".rela", 0)
- rela.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
- rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_GLOB_DAT)))
- rela.AddUint64(ctxt.Arch, 0)
+ if target.IsElf() {
+ rela := syms.Rela
+ rela.AddAddrPlus(target.Arch, got, int64(s.Got()))
+ rela.AddUint64(target.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_GLOB_DAT)))
+ rela.AddUint64(target.Arch, 0)
} else {
ld.Errorf(s, "addgotsym: unsupported binary format")
}
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
-func adddynrel(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
+func adddynrel(_ *ld.Link, target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
targ := r.Sym
switch r.Type {
default:
if r.Type >= objabi.ElfRelocOffset {
- ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(ctxt.Arch, r.Type))
+ ld.Errorf(s, "unexpected relocation type %d (%s)", r.Type, sym.RelocName(target.Arch, r.Type))
return false
}
r.Type = objabi.R_PCREL
r.Add += 4
if targ.Type == sym.SDYNIMPORT {
- addpltsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".plt", 0)
+ addpltsym(target, syms, targ)
+ r.Sym = syms.PLT
r.Add += int64(targ.Plt())
}
return false
}
- addgotsym(ctxt, targ)
+ addgotsym(target, syms, targ)
r.Type = objabi.R_CONST // write r->add during relocsym
r.Sym = nil
r.Add += int64(targ.Got())
case objabi.ElfRelocOffset + objabi.RelocType(elf.R_386_GOTPC):
r.Type = objabi.R_PCREL
- r.Sym = ctxt.Syms.Lookup(".got", 0)
+ r.Sym = syms.GOT
r.Add += 4
return true
case objabi.MachoRelocOffset + ld.MACHO_GENERIC_RELOC_VANILLA*2 + 1:
if targ.Type == sym.SDYNIMPORT {
- addpltsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".plt", 0)
+ addpltsym(target, syms, targ)
+ r.Sym = syms.PLT
r.Add = int64(targ.Plt())
r.Type = objabi.R_PCREL
return true
return true
}
- addgotsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".got", 0)
+ addgotsym(target, syms, targ)
+ r.Sym = syms.GOT
r.Add += int64(targ.Got())
r.Type = objabi.R_PCREL
return true
switch r.Type {
case objabi.R_CALL,
objabi.R_PCREL:
- if ctxt.LinkMode == ld.LinkExternal {
+ if target.IsExternal() {
// External linker will do this relocation.
return true
}
- addpltsym(ctxt, targ)
- r.Sym = ctxt.Syms.Lookup(".plt", 0)
+ addpltsym(target, syms, targ)
+ r.Sym = syms.PLT
r.Add = int64(targ.Plt())
return true
if s.Type != sym.SDATA {
break
}
- if ctxt.IsELF {
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, targ)
- rel := ctxt.Syms.Lookup(".rel", 0)
- rel.AddAddrPlus(ctxt.Arch, s, int64(r.Off))
- rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_386_32)))
+ if target.IsElf() {
+ ld.Adddynsym(target, syms, targ)
+ rel := syms.Rel
+ rel.AddAddrPlus(target.Arch, s, int64(r.Off))
+ rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(targ.Dynid), uint32(elf.R_386_32)))
r.Type = objabi.R_CONST // write r->add during relocsym
r.Sym = nil
return true
}
- if ctxt.HeadType == objabi.Hdarwin && s.Size == int64(ctxt.Arch.PtrSize) && r.Off == 0 {
+ if target.IsDarwin() && s.Size == int64(target.Arch.PtrSize) && r.Off == 0 {
// Mach-O relocations are a royal pain to lay out.
// They use a compact stateful bytecode representation
// that is too much bother to deal with.
// just in case the C code assigns to the variable,
// and of course it only works for single pointers,
// but we only need to support cgo and that's all it needs.
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, targ)
+ ld.Adddynsym(target, syms, targ)
- got := ctxt.Syms.Lookup(".got", 0)
+ got := syms.GOT
s.Type = got.Type
s.Attr |= sym.AttrSubSymbol
s.Outer = got
s.Sub = got.Sub
got.Sub = s
s.Value = got.Size
- got.AddUint32(ctxt.Arch, 0)
- ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(targ.Dynid))
+ got.AddUint32(target.Arch, 0)
+ syms.LinkEditGOT.AddUint32(target.Arch, uint32(targ.Dynid))
r.Type = objabi.ElfRelocOffset // ignore during relocsym
return true
}
}
}
-func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
+func addpltsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) {
if s.Plt() >= 0 {
return
}
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s)
+ ld.Adddynsym(target, syms, s)
- if ctxt.IsELF {
- plt := ctxt.Syms.Lookup(".plt", 0)
- got := ctxt.Syms.Lookup(".got.plt", 0)
- rel := ctxt.Syms.Lookup(".rel.plt", 0)
+ if target.IsElf() {
+ plt := syms.PLT
+ got := syms.GOTPLT
+ rel := syms.RelPLT
if plt.Size == 0 {
panic("plt is not set up")
}
plt.AddUint8(0xff)
plt.AddUint8(0x25)
- plt.AddAddrPlus(ctxt.Arch, got, got.Size)
+ plt.AddAddrPlus(target.Arch, got, got.Size)
// add to got: pointer to current pos in plt
- got.AddAddrPlus(ctxt.Arch, plt, plt.Size)
+ got.AddAddrPlus(target.Arch, plt, plt.Size)
// pushl $x
plt.AddUint8(0x68)
- plt.AddUint32(ctxt.Arch, uint32(rel.Size))
+ plt.AddUint32(target.Arch, uint32(rel.Size))
// jmp .plt
plt.AddUint8(0xe9)
- plt.AddUint32(ctxt.Arch, uint32(-(plt.Size + 4)))
+ plt.AddUint32(target.Arch, uint32(-(plt.Size + 4)))
// rel
- rel.AddAddrPlus(ctxt.Arch, got, got.Size-4)
+ rel.AddAddrPlus(target.Arch, got, got.Size-4)
- rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_JMP_SLOT)))
+ rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_JMP_SLOT)))
s.SetPlt(int32(plt.Size - 16))
- } else if ctxt.HeadType == objabi.Hdarwin {
+ } else if target.IsDarwin() {
// Same laziness as in 6l.
- plt := ctxt.Syms.Lookup(".plt", 0)
+ plt := syms.PLT
- addgotsym(ctxt, s)
+ addgotsym(target, syms, s)
- ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
+ syms.LinkEditPLT.AddUint32(target.Arch, uint32(s.Dynid))
// jmpq *got+size(IP)
s.SetPlt(int32(plt.Size))
plt.AddUint8(0xff)
plt.AddUint8(0x25)
- plt.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got()))
+ plt.AddAddrPlus(target.Arch, syms.GOT, int64(s.Got()))
} else {
ld.Errorf(s, "addpltsym: unsupported binary format")
}
}
-func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
+func addgotsym(target *ld.Target, syms *ld.ArchSyms, s *sym.Symbol) {
if s.Got() >= 0 {
return
}
- ld.Adddynsym(&ctxt.Target, &ctxt.ArchSyms, s)
- got := ctxt.Syms.Lookup(".got", 0)
+ ld.Adddynsym(target, syms, s)
+ got := syms.GOT
s.SetGot(int32(got.Size))
- got.AddUint32(ctxt.Arch, 0)
-
- if ctxt.IsELF {
- rel := ctxt.Syms.Lookup(".rel", 0)
- rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
- rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_GLOB_DAT)))
- } else if ctxt.HeadType == objabi.Hdarwin {
- ctxt.Syms.Lookup(".linkedit.got", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
+ got.AddUint32(target.Arch, 0)
+
+ if target.IsElf() {
+ rel := syms.Rel
+ rel.AddAddrPlus(target.Arch, got, int64(s.Got()))
+ rel.AddUint32(target.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_GLOB_DAT)))
+ } else if target.IsDarwin() {
+ syms.LinkEditGOT.AddUint32(target.Arch, uint32(s.Dynid))
} else {
ld.Errorf(s, "addgotsym: unsupported binary format")
}