if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
- r.Add += int64(targ.Plt)
+ r.Add += int64(targ.Plt())
}
return true
r.Type = objabi.R_PCREL
r.Sym = ctxt.Syms.Lookup(".got", 0)
r.Add += 4
- r.Add += int64(targ.Got)
+ r.Add += int64(targ.Got())
return true
case 256 + objabi.RelocType(elf.R_X86_64_64):
if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
- r.Add = int64(targ.Plt)
+ r.Add = int64(targ.Plt())
r.Type = objabi.R_PCREL
return true
}
addgotsym(ctxt, targ)
r.Type = objabi.R_PCREL
r.Sym = ctxt.Syms.Lookup(".got", 0)
- r.Add += int64(targ.Got)
+ r.Add += int64(targ.Got())
return true
}
// Build a PLT entry and change the relocation target to that entry.
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
- r.Add = int64(targ.Plt)
+ r.Add = int64(targ.Plt())
return true
case objabi.R_ADDR:
if ctxt.HeadType == objabi.Hsolaris {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
- r.Add += int64(targ.Plt)
+ r.Add += int64(targ.Plt())
return true
}
// The code is asking for the address of an external
addgotsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".got", 0)
- r.Add += int64(targ.Got)
+ r.Add += int64(targ.Got())
return true
}
}
func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
- if s.Plt >= 0 {
+ if s.Plt() >= 0 {
return
}
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_X86_64_JMP_SLOT)))
rela.AddUint64(ctxt.Arch, 0)
- s.Plt = int32(plt.Size - 16)
+ s.SetPlt(int32(plt.Size - 16))
} else if ctxt.HeadType == objabi.Hdarwin {
// To do lazy symbol lookup right, we're supposed
// to tell the dynamic loader which library each
ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
// jmpq *got+size(IP)
- s.Plt = int32(plt.Size)
+ 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(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got()))
} else {
ld.Errorf(s, "addpltsym: unsupported binary format")
}
}
func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
- if s.Got >= 0 {
+ if s.Got() >= 0 {
return
}
ld.Adddynsym(ctxt, s)
got := ctxt.Syms.Lookup(".got", 0)
- s.Got = int32(got.Size)
+ 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.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 {
if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
- r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
+ r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4))
}
return true
r.Type = objabi.R_CONST // write r->add during relocsym
r.Sym = nil
- r.Add += int64(targ.Got)
+ r.Add += int64(targ.Got())
return true
case 256 + objabi.RelocType(elf.R_ARM_GOT_PREL): // GOT(nil) + A - nil
r.Type = objabi.R_PCREL
r.Sym = ctxt.Syms.Lookup(".got", 0)
- r.Add += int64(targ.Got) + 4
+ r.Add += int64(targ.Got()) + 4
return true
case 256 + objabi.RelocType(elf.R_ARM_GOTOFF): // R_ARM_GOTOFF32
if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
- r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
+ r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4))
}
return true
if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
- r.Add = int64(braddoff(int32(r.Add), targ.Plt/4))
+ r.Add = int64(braddoff(int32(r.Add), targ.Plt()/4))
}
return true
}
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
- r.Add = int64(targ.Plt)
+ r.Add = int64(targ.Plt())
return true
case objabi.R_ADDR:
r.Off = int32(plt.Size)
r.Siz = 4
r.Type = typ
- r.Add = int64(s.Got) - 8
+ r.Add = int64(s.Got()) - 8
plt.Attr |= sym.AttrReachable
plt.Size += 4
}
func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
- if s.Plt >= 0 {
+ if s.Plt() >= 0 {
return
}
}
// .got entry
- s.Got = int32(got.Size)
+ s.SetGot(int32(got.Size))
// 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
got.AddAddrPlus(ctxt.Arch, plt, 0)
// .plt entry, this depends on the .got entry
- s.Plt = int32(plt.Size)
+ 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]!
// rel
- rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got))
+ rel.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_JUMP_SLOT)))
} else {
}
func addgotsyminternal(ctxt *ld.Link, s *sym.Symbol) {
- if s.Got >= 0 {
+ if s.Got() >= 0 {
return
}
got := ctxt.Syms.Lookup(".got", 0)
- s.Got = int32(got.Size)
+ s.SetGot(int32(got.Size))
got.AddAddrPlus(ctxt.Arch, s, 0)
}
func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
- if s.Got >= 0 {
+ if s.Got() >= 0 {
return
}
ld.Adddynsym(ctxt, s)
got := ctxt.Syms.Lookup(".got", 0)
- s.Got = int32(got.Size)
+ 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.AddAddrPlus(ctxt.Arch, got, int64(s.Got()))
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_ARM_GLOB_DAT)))
} else {
ld.Errorf(s, "addgotsym: unsupported binary format")
}
Errorf(s, "dynamic relocation to unreachable symbol %s", targ.Name)
}
- if r.Sym.Plt == -2 && r.Sym.Got != -2 { // make dynimport JMP table for PE object files.
- targ.Plt = int32(rel.Size)
+ if r.Sym.Plt() == -2 && r.Sym.Got() != -2 { // make dynimport JMP table for PE object files.
+ targ.SetPlt(int32(rel.Size))
r.Sym = rel
- r.Add = int64(targ.Plt)
+ r.Add = int64(targ.Plt())
// jmp *addr
switch ctxt.Arch.Family {
rel.AddAddrPlus4(targ, 0)
rel.AddUint8(0x90)
}
- } else if r.Sym.Plt >= 0 {
+ } else if r.Sym.Plt() >= 0 {
r.Sym = rel
- r.Add = int64(targ.Plt)
+ r.Add = int64(targ.Plt())
}
}
}
if pesym.SectionNumber == 0 { // extern
if s.Type == sym.SDYNIMPORT {
- s.Plt = -2 // flag for dynimport in PE object files.
+ s.SetPlt(-2) // flag for dynimport in PE object files.
}
if s.Type == sym.SXREF && pesym.Value > 0 { // global data
s.Type = sym.SNOPTRDATA
s.Type = sym.SXREF
}
if strings.HasPrefix(symname, "__imp_") {
- s.Got = -2 // flag for __imp_
+ s.SetGot(-2) // flag for __imp_
}
return s, nil
r.Off = int32(stub.Size)
r.Sym = plt
- r.Add = int64(targ.Plt)
+ r.Add = int64(targ.Plt())
r.Siz = 2
if ctxt.Arch.ByteOrder == binary.BigEndian {
r.Off += int32(r.Siz)
r = stub.AddRel()
r.Off = int32(stub.Size)
r.Sym = plt
- r.Add = int64(targ.Plt)
+ r.Add = int64(targ.Plt())
r.Siz = 2
if ctxt.Arch.ByteOrder == binary.BigEndian {
r.Off += int32(r.Siz)
}
func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
- if s.Plt >= 0 {
+ if s.Plt() >= 0 {
return
}
// JMP_SLOT dynamic relocation for it.
//
// TODO(austin): ABI v1 is different
- s.Plt = int32(plt.Size)
+ s.SetPlt(int32(plt.Size))
plt.Size += 8
- rela.AddAddrPlus(ctxt.Arch, plt, int64(s.Plt))
+ rela.AddAddrPlus(ctxt.Arch, plt, int64(s.Plt()))
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_PPC64_JMP_SLOT)))
rela.AddUint64(ctxt.Arch, 0)
} else {
if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
- r.Add += int64(targ.Plt)
+ r.Add += int64(targ.Plt())
}
return true
if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
- r.Add += int64(targ.Plt)
+ r.Add += int64(targ.Plt())
}
return true
r.Type = objabi.R_PCREL
r.Variant = sym.RV_390_DBL
r.Sym = ctxt.Syms.Lookup(".got", 0)
- r.Add += int64(targ.Got)
+ r.Add += int64(targ.Got())
r.Add += int64(r.Siz)
return true
}
}
func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
- if s.Plt >= 0 {
+ if s.Plt() >= 0 {
return
}
rela.AddUint64(ctxt.Arch, ld.ELF64_R_INFO(uint32(s.Dynid), uint32(elf.R_390_JMP_SLOT)))
rela.AddUint64(ctxt.Arch, 0)
- s.Plt = int32(plt.Size - 32)
+ s.SetPlt(int32(plt.Size - 32))
} else {
ld.Errorf(s, "addpltsym: unsupported binary format")
}
func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
- if s.Got >= 0 {
+ if s.Got() >= 0 {
return
}
ld.Adddynsym(ctxt, s)
got := ctxt.Syms.Lookup(".got", 0)
- s.Got = int32(got.Size)
+ 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.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)
} else {
_32bit uintptr // size on 32bit platforms
_64bit uintptr // size on 64bit platforms
}{
- {Symbol{}, 120, 192},
+ {Symbol{}, 112, 184},
}
for _, tt := range tests {
Version int16
Attr Attribute
Dynid int32
- Plt int32
- Got int32
Align int32
Elfsym int32
LocalElfsym int32
dynimplib string
dynimpvers string
localentry uint8
+ plt int32
+ got int32
}
func (s *Symbol) String() string {
func (s *Symbol) makeAuxInfo() {
if s.auxinfo == nil {
- s.auxinfo = &AuxSymbol{extname: s.Name}
+ s.auxinfo = &AuxSymbol{extname: s.Name, plt: -1, got: -1}
}
}
s.auxinfo.localentry = val
}
+func (s *Symbol) Plt() int32 {
+ if s.auxinfo == nil {
+ return -1
+ }
+ return s.auxinfo.plt
+}
+
+func (s *Symbol) SetPlt(val int32) {
+ if s.auxinfo == nil {
+ if val == -1 {
+ return
+ }
+ s.makeAuxInfo()
+ }
+ s.auxinfo.plt = val
+}
+
+func (s *Symbol) Got() int32 {
+ if s.auxinfo == nil {
+ return -1
+ }
+ return s.auxinfo.got
+}
+
+func (s *Symbol) SetGot(val int32) {
+ if s.auxinfo == nil {
+ if val == -1 {
+ return
+ }
+ s.makeAuxInfo()
+ }
+ s.auxinfo.got = val
+}
+
// SortSub sorts a linked-list (by Sub) of *Symbol by Value.
// Used for sub-symbols when loading host objects (see e.g. ldelf.go).
func SortSub(l *Symbol) *Symbol {
syms.symbolBatch = batch[1:]
s.Dynid = -1
- s.Plt = -1
- s.Got = -1
s.Name = name
s.Version = int16(v)
syms.Allsym = append(syms.Allsym, s)
if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
- r.Add += int64(targ.Plt)
+ r.Add += int64(targ.Plt())
}
return true
addgotsym(ctxt, targ)
r.Type = objabi.R_CONST // write r->add during relocsym
r.Sym = nil
- r.Add += int64(targ.Got)
+ r.Add += int64(targ.Got())
return true
case 256 + objabi.RelocType(elf.R_386_GOTOFF):
if targ.Type == sym.SDYNIMPORT {
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
- r.Add = int64(targ.Plt)
+ r.Add = int64(targ.Plt())
r.Type = objabi.R_PCREL
return true
}
addgotsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".got", 0)
- r.Add += int64(targ.Got)
+ r.Add += int64(targ.Got())
r.Type = objabi.R_PCREL
return true
}
}
addpltsym(ctxt, targ)
r.Sym = ctxt.Syms.Lookup(".plt", 0)
- r.Add = int64(targ.Plt)
+ r.Add = int64(targ.Plt())
return true
case objabi.R_ADDR:
}
func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
- if s.Plt >= 0 {
+ if s.Plt() >= 0 {
return
}
rel.AddUint32(ctxt.Arch, ld.ELF32_R_INFO(uint32(s.Dynid), uint32(elf.R_386_JMP_SLOT)))
- s.Plt = int32(plt.Size - 16)
+ s.SetPlt(int32(plt.Size - 16))
} else if ctxt.HeadType == objabi.Hdarwin {
// Same laziness as in 6l.
ctxt.Syms.Lookup(".linkedit.plt", 0).AddUint32(ctxt.Arch, uint32(s.Dynid))
// jmpq *got+size(IP)
- s.Plt = int32(plt.Size)
+ 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(ctxt.Arch, ctxt.Syms.Lookup(".got", 0), int64(s.Got()))
} else {
ld.Errorf(s, "addpltsym: unsupported binary format")
}
}
func addgotsym(ctxt *ld.Link, s *sym.Symbol) {
- if s.Got >= 0 {
+ if s.Got() >= 0 {
return
}
ld.Adddynsym(ctxt, s)
got := ctxt.Syms.Lookup(".got", 0)
- s.Got = int32(got.Size)
+ 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.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))