mirror of
https://github.com/golang/go
synced 2024-09-30 01:34:35 -06:00
[dev.link] cmd/link: convert doelf to new style
Change-Id: I448fe632ae73ddcb79c05793c96f48e358060305 Reviewed-on: https://go-review.googlesource.com/c/go/+/222977 Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
a8e8e05ed1
commit
a3e965ce8a
@ -34,6 +34,7 @@ import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"cmd/link/internal/ld"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"debug/elf"
|
||||
"log"
|
||||
@ -572,27 +573,25 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym
|
||||
return t
|
||||
}
|
||||
|
||||
func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
|
||||
plt := ctxt.Syms.Lookup(".plt", 0)
|
||||
got := ctxt.Syms.Lookup(".got.plt", 0)
|
||||
if plt.Size == 0 {
|
||||
func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
|
||||
if plt.Size() == 0 {
|
||||
// pushq got+8(IP)
|
||||
plt.AddUint8(0xff)
|
||||
|
||||
plt.AddUint8(0x35)
|
||||
plt.AddPCRelPlus(ctxt.Arch, got, 8)
|
||||
plt.AddPCRelPlus(ctxt.Arch, got.Sym(), 8)
|
||||
|
||||
// jmpq got+16(IP)
|
||||
plt.AddUint8(0xff)
|
||||
|
||||
plt.AddUint8(0x25)
|
||||
plt.AddPCRelPlus(ctxt.Arch, got, 16)
|
||||
plt.AddPCRelPlus(ctxt.Arch, got.Sym(), 16)
|
||||
|
||||
// nopl 0(AX)
|
||||
plt.AddUint32(ctxt.Arch, 0x00401f0f)
|
||||
|
||||
// assume got->size == 0 too
|
||||
got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
|
||||
got.AddAddrPlus(ctxt.Arch, dynamic, 0)
|
||||
|
||||
got.AddUint64(ctxt.Arch, 0)
|
||||
got.AddUint64(ctxt.Arch, 0)
|
||||
@ -611,7 +610,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
|
||||
got := ctxt.Syms.Lookup(".got.plt", 0)
|
||||
rela := ctxt.Syms.Lookup(".rela.plt", 0)
|
||||
if plt.Size == 0 {
|
||||
elfsetupplt(ctxt, &ctxt.Target, &ctxt.ArchSyms)
|
||||
panic("plt is not set up")
|
||||
}
|
||||
|
||||
// jmpq *got+size(IP)
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"cmd/link/internal/ld"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"debug/elf"
|
||||
"fmt"
|
||||
@ -300,10 +301,8 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
|
||||
plt := ctxt.Syms.Lookup(".plt", 0)
|
||||
got := ctxt.Syms.Lookup(".got.plt", 0)
|
||||
if plt.Size == 0 {
|
||||
func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
|
||||
if plt.Size() == 0 {
|
||||
// str lr, [sp, #-4]!
|
||||
plt.AddUint32(ctxt.Arch, 0xe52de004)
|
||||
|
||||
@ -317,7 +316,7 @@ func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
|
||||
plt.AddUint32(ctxt.Arch, 0xe5bef008)
|
||||
|
||||
// .word &GLOBAL_OFFSET_TABLE[0] - .
|
||||
plt.AddPCRelPlus(ctxt.Arch, got, 4)
|
||||
plt.AddPCRelPlus(ctxt.Arch, got.Sym(), 4)
|
||||
|
||||
// the first .plt entry requires 3 .plt.got entries
|
||||
got.AddUint32(ctxt.Arch, 0)
|
||||
@ -697,7 +696,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
|
||||
got := ctxt.Syms.Lookup(".got.plt", 0)
|
||||
rel := ctxt.Syms.Lookup(".rel.plt", 0)
|
||||
if plt.Size == 0 {
|
||||
elfsetupplt(ctxt, &ctxt.Target, &ctxt.ArchSyms)
|
||||
panic("plt is not set up")
|
||||
}
|
||||
|
||||
// .got entry
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"cmd/link/internal/ld"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"debug/elf"
|
||||
"fmt"
|
||||
@ -711,30 +712,25 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym
|
||||
return -1
|
||||
}
|
||||
|
||||
func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
|
||||
plt := ctxt.Syms.Lookup(".plt", 0)
|
||||
gotplt := ctxt.Syms.Lookup(".got.plt", 0)
|
||||
if plt.Size == 0 {
|
||||
func elfsetupplt(ctxt *ld.Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) {
|
||||
if plt.Size() == 0 {
|
||||
// stp x16, x30, [sp, #-16]!
|
||||
// identifying information
|
||||
plt.AddUint32(ctxt.Arch, 0xa9bf7bf0)
|
||||
|
||||
// the following two instructions (adrp + ldr) load *got[2] into x17
|
||||
// adrp x16, &got[0]
|
||||
plt.AddAddrPlus4(gotplt, 16)
|
||||
plt.SetUint32(ctxt.Arch, plt.Size-4, 0x90000010)
|
||||
plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT
|
||||
plt.AddSymRef(ctxt.Arch, gotplt.Sym(), 16, objabi.R_ARM64_GOT, 4)
|
||||
plt.SetUint32(ctxt.Arch, plt.Size()-4, 0x90000010)
|
||||
|
||||
// <imm> is the offset value of &got[2] to &got[0], the same below
|
||||
// ldr x17, [x16, <imm>]
|
||||
plt.AddAddrPlus4(gotplt, 16)
|
||||
plt.SetUint32(ctxt.Arch, plt.Size-4, 0xf9400211)
|
||||
plt.R[len(plt.R)-1].Type = objabi.R_ARM64_GOT
|
||||
plt.AddSymRef(ctxt.Arch, gotplt.Sym(), 16, objabi.R_ARM64_GOT, 4)
|
||||
plt.SetUint32(ctxt.Arch, plt.Size()-4, 0xf9400211)
|
||||
|
||||
// add x16, x16, <imm>
|
||||
plt.AddAddrPlus4(gotplt, 16)
|
||||
plt.SetUint32(ctxt.Arch, plt.Size-4, 0x91000210)
|
||||
plt.R[len(plt.R)-1].Type = objabi.R_ARM64_PCREL
|
||||
plt.AddSymRef(ctxt.Arch, gotplt.Sym(), 16, objabi.R_ARM64_PCREL, 4)
|
||||
plt.SetUint32(ctxt.Arch, plt.Size()-4, 0x91000210)
|
||||
|
||||
// br x17
|
||||
plt.AddUint32(ctxt.Arch, 0xd61f0220)
|
||||
@ -745,10 +741,10 @@ func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
|
||||
plt.AddUint32(ctxt.Arch, 0xd503201f)
|
||||
|
||||
// check gotplt.size == 0
|
||||
if gotplt.Size != 0 {
|
||||
ld.Errorf(gotplt, "got.plt is not empty at the very beginning")
|
||||
if gotplt.Size() != 0 {
|
||||
ctxt.Errorf(gotplt.Sym(), "got.plt is not empty at the very beginning")
|
||||
}
|
||||
gotplt.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
|
||||
gotplt.AddAddrPlus(ctxt.Arch, dynamic, 0)
|
||||
|
||||
gotplt.AddUint64(ctxt.Arch, 0)
|
||||
gotplt.AddUint64(ctxt.Arch, 0)
|
||||
@ -767,7 +763,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
|
||||
gotplt := ctxt.Syms.Lookup(".got.plt", 0)
|
||||
rela := ctxt.Syms.Lookup(".rela.plt", 0)
|
||||
if plt.Size == 0 {
|
||||
elfsetupplt(ctxt, &ctxt.Target, &ctxt.ArchSyms)
|
||||
panic("plt is not set up")
|
||||
}
|
||||
|
||||
// adrp x16, &got.plt[0]
|
||||
|
@ -15,6 +15,7 @@ package ld
|
||||
|
||||
import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"log"
|
||||
)
|
||||
@ -28,18 +29,18 @@ var dwarfp []*sym.Symbol
|
||||
/*
|
||||
* Elf.
|
||||
*/
|
||||
func dwarfaddshstrings(ctxt *Link, shstrtab *sym.Symbol) {
|
||||
func dwarfaddshstrings(ctxt *Link, shstrtab *loader.SymbolBuilder) {
|
||||
if *FlagW { // disable dwarf
|
||||
return
|
||||
}
|
||||
|
||||
secs := []string{"abbrev", "frame", "info", "loc", "line", "pubnames", "pubtypes", "gdb_scripts", "ranges"}
|
||||
for _, sec := range secs {
|
||||
Addstring(shstrtab, ".debug_"+sec)
|
||||
if ctxt.LinkMode == LinkExternal {
|
||||
Addstring(shstrtab, elfRelType+".debug_"+sec)
|
||||
shstrtab.Addstring(".debug_" + sec)
|
||||
if ctxt.IsExternal() {
|
||||
shstrtab.Addstring(elfRelType + ".debug_" + sec)
|
||||
} else {
|
||||
Addstring(shstrtab, ".zdebug_"+sec)
|
||||
shstrtab.Addstring(".zdebug_" + sec)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ package ld
|
||||
import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"crypto/sha1"
|
||||
"encoding/binary"
|
||||
@ -774,6 +775,39 @@ func elfWriteDynEntSymSize(arch *sys.Arch, s *sym.Symbol, tag int, t *sym.Symbol
|
||||
s.AddSize(arch, t)
|
||||
}
|
||||
|
||||
// temporary
|
||||
func Elfwritedynent2(ctxt *Link, s *loader.SymbolBuilder, tag int, val uint64) {
|
||||
if elf64 {
|
||||
s.AddUint64(ctxt.Arch, uint64(tag))
|
||||
s.AddUint64(ctxt.Arch, val)
|
||||
} else {
|
||||
s.AddUint32(ctxt.Arch, uint32(tag))
|
||||
s.AddUint32(ctxt.Arch, uint32(val))
|
||||
}
|
||||
}
|
||||
|
||||
func elfwritedynentsym2(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym) {
|
||||
Elfwritedynentsymplus2(ctxt, s, tag, t, 0)
|
||||
}
|
||||
|
||||
func Elfwritedynentsymplus2(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym, add int64) {
|
||||
if elf64 {
|
||||
s.AddUint64(ctxt.Arch, uint64(tag))
|
||||
} else {
|
||||
s.AddUint32(ctxt.Arch, uint32(tag))
|
||||
}
|
||||
s.AddAddrPlus(ctxt.Arch, t, add)
|
||||
}
|
||||
|
||||
func elfwritedynentsymsize2(ctxt *Link, s *loader.SymbolBuilder, tag int, t loader.Sym) {
|
||||
if elf64 {
|
||||
s.AddUint64(ctxt.Arch, uint64(tag))
|
||||
} else {
|
||||
s.AddUint32(ctxt.Arch, uint32(tag))
|
||||
}
|
||||
s.AddSize(ctxt.Arch, t)
|
||||
}
|
||||
|
||||
func elfinterp(sh *ElfShdr, startva uint64, resoff uint64, p string) int {
|
||||
interp = p
|
||||
n := len(interp) + 1
|
||||
@ -1400,9 +1434,10 @@ func Elfemitreloc(ctxt *Link) {
|
||||
}
|
||||
|
||||
func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
|
||||
s := ctxt.Syms.Lookup(sectionName, 0)
|
||||
s.Attr |= sym.AttrReachable
|
||||
s.Type = sym.SELFROSECT
|
||||
ldr := ctxt.loader
|
||||
s := ldr.CreateSymForUpdate(sectionName, 0)
|
||||
s.SetReachable(true)
|
||||
s.SetType(sym.SELFROSECT)
|
||||
// namesz
|
||||
s.AddUint32(ctxt.Arch, uint32(len(ELF_NOTE_GO_NAME)))
|
||||
// descsz
|
||||
@ -1410,93 +1445,91 @@ func addgonote(ctxt *Link, sectionName string, tag uint32, desc []byte) {
|
||||
// tag
|
||||
s.AddUint32(ctxt.Arch, tag)
|
||||
// name + padding
|
||||
s.P = append(s.P, ELF_NOTE_GO_NAME...)
|
||||
for len(s.P)%4 != 0 {
|
||||
s.P = append(s.P, 0)
|
||||
s.AddBytes(ELF_NOTE_GO_NAME)
|
||||
for len(s.Data())%4 != 0 {
|
||||
s.AddUint8(0)
|
||||
}
|
||||
// desc + padding
|
||||
s.P = append(s.P, desc...)
|
||||
for len(s.P)%4 != 0 {
|
||||
s.P = append(s.P, 0)
|
||||
s.AddBytes(desc)
|
||||
for len(s.Data())%4 != 0 {
|
||||
s.AddUint8(0)
|
||||
}
|
||||
s.Size = int64(len(s.P))
|
||||
s.Align = 4
|
||||
s.SetSize(int64(len(s.Data())))
|
||||
s.SetAlign(4)
|
||||
}
|
||||
|
||||
func (ctxt *Link) doelf() {
|
||||
if !ctxt.IsELF {
|
||||
return
|
||||
}
|
||||
ldr := ctxt.loader
|
||||
|
||||
/* predefine strings we need for section headers */
|
||||
shstrtab := ctxt.Syms.Lookup(".shstrtab", 0)
|
||||
shstrtab := ldr.CreateSymForUpdate(".shstrtab", 0)
|
||||
|
||||
shstrtab.Type = sym.SELFROSECT
|
||||
shstrtab.Attr |= sym.AttrReachable
|
||||
shstrtab.SetType(sym.SELFROSECT)
|
||||
shstrtab.SetReachable(true)
|
||||
|
||||
Addstring(shstrtab, "")
|
||||
Addstring(shstrtab, ".text")
|
||||
Addstring(shstrtab, ".noptrdata")
|
||||
Addstring(shstrtab, ".data")
|
||||
Addstring(shstrtab, ".bss")
|
||||
Addstring(shstrtab, ".noptrbss")
|
||||
Addstring(shstrtab, "__libfuzzer_extra_counters")
|
||||
Addstring(shstrtab, ".go.buildinfo")
|
||||
shstrtab.Addstring("")
|
||||
shstrtab.Addstring(".text")
|
||||
shstrtab.Addstring(".noptrdata")
|
||||
shstrtab.Addstring(".data")
|
||||
shstrtab.Addstring(".bss")
|
||||
shstrtab.Addstring(".noptrbss")
|
||||
shstrtab.Addstring("__libfuzzer_extra_counters")
|
||||
shstrtab.Addstring(".go.buildinfo")
|
||||
|
||||
// generate .tbss section for dynamic internal linker or external
|
||||
// linking, so that various binutils could correctly calculate
|
||||
// PT_TLS size. See https://golang.org/issue/5200.
|
||||
if !*FlagD || ctxt.LinkMode == LinkExternal {
|
||||
Addstring(shstrtab, ".tbss")
|
||||
if !*FlagD || ctxt.IsExternal() {
|
||||
shstrtab.Addstring(".tbss")
|
||||
}
|
||||
if ctxt.HeadType == objabi.Hnetbsd {
|
||||
Addstring(shstrtab, ".note.netbsd.ident")
|
||||
if ctxt.IsNetbsd() {
|
||||
shstrtab.Addstring(".note.netbsd.ident")
|
||||
}
|
||||
if ctxt.HeadType == objabi.Hopenbsd {
|
||||
Addstring(shstrtab, ".note.openbsd.ident")
|
||||
if ctxt.IsOpenbsd() {
|
||||
shstrtab.Addstring(".note.openbsd.ident")
|
||||
}
|
||||
if len(buildinfo) > 0 {
|
||||
Addstring(shstrtab, ".note.gnu.build-id")
|
||||
shstrtab.Addstring(".note.gnu.build-id")
|
||||
}
|
||||
if *flagBuildid != "" {
|
||||
Addstring(shstrtab, ".note.go.buildid")
|
||||
shstrtab.Addstring(".note.go.buildid")
|
||||
}
|
||||
Addstring(shstrtab, ".elfdata")
|
||||
Addstring(shstrtab, ".rodata")
|
||||
shstrtab.Addstring(".elfdata")
|
||||
shstrtab.Addstring(".rodata")
|
||||
// See the comment about data.rel.ro.FOO section names in data.go.
|
||||
relro_prefix := ""
|
||||
if ctxt.UseRelro() {
|
||||
Addstring(shstrtab, ".data.rel.ro")
|
||||
shstrtab.Addstring(".data.rel.ro")
|
||||
relro_prefix = ".data.rel.ro"
|
||||
}
|
||||
Addstring(shstrtab, relro_prefix+".typelink")
|
||||
Addstring(shstrtab, relro_prefix+".itablink")
|
||||
Addstring(shstrtab, relro_prefix+".gosymtab")
|
||||
Addstring(shstrtab, relro_prefix+".gopclntab")
|
||||
shstrtab.Addstring(relro_prefix + ".typelink")
|
||||
shstrtab.Addstring(relro_prefix + ".itablink")
|
||||
shstrtab.Addstring(relro_prefix + ".gosymtab")
|
||||
shstrtab.Addstring(relro_prefix + ".gopclntab")
|
||||
|
||||
if ctxt.LinkMode == LinkExternal {
|
||||
if ctxt.IsExternal() {
|
||||
*FlagD = true
|
||||
|
||||
Addstring(shstrtab, elfRelType+".text")
|
||||
Addstring(shstrtab, elfRelType+".rodata")
|
||||
Addstring(shstrtab, elfRelType+relro_prefix+".typelink")
|
||||
Addstring(shstrtab, elfRelType+relro_prefix+".itablink")
|
||||
Addstring(shstrtab, elfRelType+relro_prefix+".gosymtab")
|
||||
Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab")
|
||||
Addstring(shstrtab, elfRelType+".noptrdata")
|
||||
Addstring(shstrtab, elfRelType+".data")
|
||||
shstrtab.Addstring(elfRelType + ".text")
|
||||
shstrtab.Addstring(elfRelType + ".rodata")
|
||||
shstrtab.Addstring(elfRelType + relro_prefix + ".typelink")
|
||||
shstrtab.Addstring(elfRelType + relro_prefix + ".itablink")
|
||||
shstrtab.Addstring(elfRelType + relro_prefix + ".gosymtab")
|
||||
shstrtab.Addstring(elfRelType + relro_prefix + ".gopclntab")
|
||||
shstrtab.Addstring(elfRelType + ".noptrdata")
|
||||
shstrtab.Addstring(elfRelType + ".data")
|
||||
if ctxt.UseRelro() {
|
||||
Addstring(shstrtab, elfRelType+".data.rel.ro")
|
||||
shstrtab.Addstring(elfRelType + ".data.rel.ro")
|
||||
}
|
||||
Addstring(shstrtab, elfRelType+".go.buildinfo")
|
||||
shstrtab.Addstring(elfRelType + ".go.buildinfo")
|
||||
|
||||
// add a .note.GNU-stack section to mark the stack as non-executable
|
||||
Addstring(shstrtab, ".note.GNU-stack")
|
||||
shstrtab.Addstring(".note.GNU-stack")
|
||||
|
||||
if ctxt.BuildMode == BuildModeShared {
|
||||
Addstring(shstrtab, ".note.go.abihash")
|
||||
Addstring(shstrtab, ".note.go.pkg-list")
|
||||
Addstring(shstrtab, ".note.go.deps")
|
||||
if ctxt.IsShared() {
|
||||
shstrtab.Addstring(".note.go.abihash")
|
||||
shstrtab.Addstring(".note.go.pkg-list")
|
||||
shstrtab.Addstring(".note.go.deps")
|
||||
}
|
||||
}
|
||||
|
||||
@ -1509,171 +1542,169 @@ func (ctxt *Link) doelf() {
|
||||
}
|
||||
|
||||
if hasinitarr {
|
||||
Addstring(shstrtab, ".init_array")
|
||||
Addstring(shstrtab, elfRelType+".init_array")
|
||||
shstrtab.Addstring(".init_array")
|
||||
shstrtab.Addstring(elfRelType + ".init_array")
|
||||
}
|
||||
|
||||
if !*FlagS {
|
||||
Addstring(shstrtab, ".symtab")
|
||||
Addstring(shstrtab, ".strtab")
|
||||
shstrtab.Addstring(".symtab")
|
||||
shstrtab.Addstring(".strtab")
|
||||
dwarfaddshstrings(ctxt, shstrtab)
|
||||
}
|
||||
|
||||
Addstring(shstrtab, ".shstrtab")
|
||||
shstrtab.Addstring(".shstrtab")
|
||||
|
||||
if !*FlagD { /* -d suppresses dynamic loader format */
|
||||
Addstring(shstrtab, ".interp")
|
||||
Addstring(shstrtab, ".hash")
|
||||
Addstring(shstrtab, ".got")
|
||||
if ctxt.Arch.Family == sys.PPC64 {
|
||||
Addstring(shstrtab, ".glink")
|
||||
shstrtab.Addstring(".interp")
|
||||
shstrtab.Addstring(".hash")
|
||||
shstrtab.Addstring(".got")
|
||||
if ctxt.IsPPC64() {
|
||||
shstrtab.Addstring(".glink")
|
||||
}
|
||||
Addstring(shstrtab, ".got.plt")
|
||||
Addstring(shstrtab, ".dynamic")
|
||||
Addstring(shstrtab, ".dynsym")
|
||||
Addstring(shstrtab, ".dynstr")
|
||||
Addstring(shstrtab, elfRelType)
|
||||
Addstring(shstrtab, elfRelType+".plt")
|
||||
shstrtab.Addstring(".got.plt")
|
||||
shstrtab.Addstring(".dynamic")
|
||||
shstrtab.Addstring(".dynsym")
|
||||
shstrtab.Addstring(".dynstr")
|
||||
shstrtab.Addstring(elfRelType)
|
||||
shstrtab.Addstring(elfRelType + ".plt")
|
||||
|
||||
Addstring(shstrtab, ".plt")
|
||||
Addstring(shstrtab, ".gnu.version")
|
||||
Addstring(shstrtab, ".gnu.version_r")
|
||||
shstrtab.Addstring(".plt")
|
||||
shstrtab.Addstring(".gnu.version")
|
||||
shstrtab.Addstring(".gnu.version_r")
|
||||
|
||||
/* dynamic symbol table - first entry all zeros */
|
||||
s := ctxt.Syms.Lookup(".dynsym", 0)
|
||||
dynsym := ldr.CreateSymForUpdate(".dynsym", 0)
|
||||
|
||||
s.Type = sym.SELFROSECT
|
||||
s.Attr |= sym.AttrReachable
|
||||
dynsym.SetType(sym.SELFROSECT)
|
||||
dynsym.SetReachable(true)
|
||||
if elf64 {
|
||||
s.Size += ELF64SYMSIZE
|
||||
dynsym.SetSize(dynsym.Size() + ELF64SYMSIZE)
|
||||
} else {
|
||||
s.Size += ELF32SYMSIZE
|
||||
dynsym.SetSize(dynsym.Size() + ELF32SYMSIZE)
|
||||
}
|
||||
|
||||
/* dynamic string table */
|
||||
s = ctxt.Syms.Lookup(".dynstr", 0)
|
||||
dynstr := ldr.CreateSymForUpdate(".dynstr", 0)
|
||||
|
||||
s.Type = sym.SELFROSECT
|
||||
s.Attr |= sym.AttrReachable
|
||||
if s.Size == 0 {
|
||||
Addstring(s, "")
|
||||
dynstr.SetType(sym.SELFROSECT)
|
||||
dynstr.SetReachable(true)
|
||||
if dynstr.Size() == 0 {
|
||||
dynstr.Addstring("")
|
||||
}
|
||||
dynstr := s
|
||||
|
||||
/* relocation table */
|
||||
s = ctxt.Syms.Lookup(elfRelType, 0)
|
||||
s.Attr |= sym.AttrReachable
|
||||
s.Type = sym.SELFROSECT
|
||||
s := ldr.CreateSymForUpdate(elfRelType, 0)
|
||||
s.SetReachable(true)
|
||||
s.SetType(sym.SELFROSECT)
|
||||
|
||||
/* global offset table */
|
||||
s = ctxt.Syms.Lookup(".got", 0)
|
||||
|
||||
s.Attr |= sym.AttrReachable
|
||||
s.Type = sym.SELFGOT // writable
|
||||
got := ldr.CreateSymForUpdate(".got", 0)
|
||||
got.SetReachable(true)
|
||||
got.SetType(sym.SELFGOT) // writable
|
||||
|
||||
/* ppc64 glink resolver */
|
||||
if ctxt.Arch.Family == sys.PPC64 {
|
||||
s := ctxt.Syms.Lookup(".glink", 0)
|
||||
s.Attr |= sym.AttrReachable
|
||||
s.Type = sym.SELFRXSECT
|
||||
if ctxt.IsPPC64() {
|
||||
s := ldr.CreateSymForUpdate(".glink", 0)
|
||||
s.SetReachable(true)
|
||||
s.SetType(sym.SELFRXSECT)
|
||||
}
|
||||
|
||||
/* hash */
|
||||
s = ctxt.Syms.Lookup(".hash", 0)
|
||||
hash := ldr.CreateSymForUpdate(".hash", 0)
|
||||
hash.SetReachable(true)
|
||||
hash.SetType(sym.SELFROSECT)
|
||||
|
||||
s.Attr |= sym.AttrReachable
|
||||
s.Type = sym.SELFROSECT
|
||||
gotplt := ldr.CreateSymForUpdate(".got.plt", 0)
|
||||
gotplt.SetReachable(true)
|
||||
gotplt.SetType(sym.SELFSECT) // writable
|
||||
|
||||
s = ctxt.Syms.Lookup(".got.plt", 0)
|
||||
s.Attr |= sym.AttrReachable
|
||||
s.Type = sym.SELFSECT // writable
|
||||
|
||||
s = ctxt.Syms.Lookup(".plt", 0)
|
||||
|
||||
s.Attr |= sym.AttrReachable
|
||||
if ctxt.Arch.Family == sys.PPC64 {
|
||||
plt := ldr.CreateSymForUpdate(".plt", 0)
|
||||
plt.SetReachable(true)
|
||||
if ctxt.IsPPC64() {
|
||||
// In the ppc64 ABI, .plt is a data section
|
||||
// written by the dynamic linker.
|
||||
s.Type = sym.SELFSECT
|
||||
plt.SetType(sym.SELFSECT)
|
||||
} else {
|
||||
s.Type = sym.SELFRXSECT
|
||||
plt.SetType(sym.SELFRXSECT)
|
||||
}
|
||||
|
||||
thearch.Elfsetupplt(ctxt, &ctxt.Target, &ctxt.ArchSyms)
|
||||
s = ldr.CreateSymForUpdate(elfRelType+".plt", 0)
|
||||
s.SetReachable(true)
|
||||
s.SetType(sym.SELFROSECT)
|
||||
|
||||
s = ctxt.Syms.Lookup(elfRelType+".plt", 0)
|
||||
s.Attr |= sym.AttrReachable
|
||||
s.Type = sym.SELFROSECT
|
||||
s = ldr.CreateSymForUpdate(".gnu.version", 0)
|
||||
s.SetReachable(true)
|
||||
s.SetType(sym.SELFROSECT)
|
||||
|
||||
s = ctxt.Syms.Lookup(".gnu.version", 0)
|
||||
s.Attr |= sym.AttrReachable
|
||||
s.Type = sym.SELFROSECT
|
||||
|
||||
s = ctxt.Syms.Lookup(".gnu.version_r", 0)
|
||||
s.Attr |= sym.AttrReachable
|
||||
s.Type = sym.SELFROSECT
|
||||
s = ldr.CreateSymForUpdate(".gnu.version_r", 0)
|
||||
s.SetReachable(true)
|
||||
s.SetType(sym.SELFROSECT)
|
||||
|
||||
/* define dynamic elf table */
|
||||
s = ctxt.Syms.Lookup(".dynamic", 0)
|
||||
dynamic := ldr.CreateSymForUpdate(".dynamic", 0)
|
||||
dynamic.SetReachable(true)
|
||||
dynamic.SetType(sym.SELFSECT) // writable
|
||||
|
||||
s.Attr |= sym.AttrReachable
|
||||
s.Type = sym.SELFSECT // writable
|
||||
thearch.Elfsetupplt(ctxt, plt, gotplt, dynamic.Sym())
|
||||
|
||||
/*
|
||||
* .dynamic table
|
||||
*/
|
||||
elfWriteDynEntSym(ctxt.Arch, s, DT_HASH, ctxt.Syms.Lookup(".hash", 0))
|
||||
elfwritedynentsym2(ctxt, dynamic, DT_HASH, hash.Sym())
|
||||
|
||||
elfWriteDynEntSym(ctxt.Arch, s, DT_SYMTAB, ctxt.Syms.Lookup(".dynsym", 0))
|
||||
elfwritedynentsym2(ctxt, dynamic, DT_SYMTAB, dynsym.Sym())
|
||||
if elf64 {
|
||||
elfWriteDynEnt(ctxt.Arch, s, DT_SYMENT, ELF64SYMSIZE)
|
||||
Elfwritedynent2(ctxt, dynamic, DT_SYMENT, ELF64SYMSIZE)
|
||||
} else {
|
||||
elfWriteDynEnt(ctxt.Arch, s, DT_SYMENT, ELF32SYMSIZE)
|
||||
Elfwritedynent2(ctxt, dynamic, DT_SYMENT, ELF32SYMSIZE)
|
||||
}
|
||||
elfWriteDynEntSym(ctxt.Arch, s, DT_STRTAB, ctxt.Syms.Lookup(".dynstr", 0))
|
||||
elfWriteDynEntSymSize(ctxt.Arch, s, DT_STRSZ, ctxt.Syms.Lookup(".dynstr", 0))
|
||||
elfwritedynentsym2(ctxt, dynamic, DT_STRTAB, dynstr.Sym())
|
||||
elfwritedynentsymsize2(ctxt, dynamic, DT_STRSZ, dynstr.Sym())
|
||||
if elfRelType == ".rela" {
|
||||
elfWriteDynEntSym(ctxt.Arch, s, DT_RELA, ctxt.Syms.Lookup(".rela", 0))
|
||||
elfWriteDynEntSymSize(ctxt.Arch, s, DT_RELASZ, ctxt.Syms.Lookup(".rela", 0))
|
||||
elfWriteDynEnt(ctxt.Arch, s, DT_RELAENT, ELF64RELASIZE)
|
||||
rela := ldr.LookupOrCreateSym(".rela", 0)
|
||||
elfwritedynentsym2(ctxt, dynamic, DT_RELA, rela)
|
||||
elfwritedynentsymsize2(ctxt, dynamic, DT_RELASZ, rela)
|
||||
Elfwritedynent2(ctxt, dynamic, DT_RELAENT, ELF64RELASIZE)
|
||||
} else {
|
||||
elfWriteDynEntSym(ctxt.Arch, s, DT_REL, ctxt.Syms.Lookup(".rel", 0))
|
||||
elfWriteDynEntSymSize(ctxt.Arch, s, DT_RELSZ, ctxt.Syms.Lookup(".rel", 0))
|
||||
elfWriteDynEnt(ctxt.Arch, s, DT_RELENT, ELF32RELSIZE)
|
||||
rel := ldr.LookupOrCreateSym(".rel", 0)
|
||||
elfwritedynentsym2(ctxt, dynamic, DT_REL, rel)
|
||||
elfwritedynentsymsize2(ctxt, dynamic, DT_RELSZ, rel)
|
||||
Elfwritedynent2(ctxt, dynamic, DT_RELENT, ELF32RELSIZE)
|
||||
}
|
||||
|
||||
if rpath.val != "" {
|
||||
elfWriteDynEnt(ctxt.Arch, s, DT_RUNPATH, uint64(Addstring(dynstr, rpath.val)))
|
||||
Elfwritedynent2(ctxt, dynamic, DT_RUNPATH, uint64(dynstr.Addstring(rpath.val)))
|
||||
}
|
||||
|
||||
if ctxt.Arch.Family == sys.PPC64 {
|
||||
elfWriteDynEntSym(ctxt.Arch, s, DT_PLTGOT, ctxt.Syms.Lookup(".plt", 0))
|
||||
} else if ctxt.Arch.Family == sys.S390X {
|
||||
elfWriteDynEntSym(ctxt.Arch, s, DT_PLTGOT, ctxt.Syms.Lookup(".got", 0))
|
||||
if ctxt.IsPPC64() {
|
||||
elfwritedynentsym2(ctxt, dynamic, DT_PLTGOT, plt.Sym())
|
||||
} else if ctxt.IsS390X() {
|
||||
elfwritedynentsym2(ctxt, dynamic, DT_PLTGOT, got.Sym())
|
||||
} else {
|
||||
elfWriteDynEntSym(ctxt.Arch, s, DT_PLTGOT, ctxt.Syms.Lookup(".got.plt", 0))
|
||||
elfwritedynentsym2(ctxt, dynamic, DT_PLTGOT, gotplt.Sym())
|
||||
}
|
||||
|
||||
if ctxt.Arch.Family == sys.PPC64 {
|
||||
elfWriteDynEnt(ctxt.Arch, s, DT_PPC64_OPT, 0)
|
||||
if ctxt.IsPPC64() {
|
||||
Elfwritedynent2(ctxt, dynamic, DT_PPC64_OPT, 0)
|
||||
}
|
||||
|
||||
// Solaris dynamic linker can't handle an empty .rela.plt if
|
||||
// DT_JMPREL is emitted so we have to defer generation of DT_PLTREL,
|
||||
// DT_PLTRELSZ, and DT_JMPREL dynamic entries until after we know the
|
||||
// size of .rel(a).plt section.
|
||||
elfWriteDynEnt(ctxt.Arch, s, DT_DEBUG, 0)
|
||||
Elfwritedynent2(ctxt, dynamic, DT_DEBUG, 0)
|
||||
}
|
||||
|
||||
if ctxt.BuildMode == BuildModeShared {
|
||||
if ctxt.IsShared() {
|
||||
// The go.link.abihashbytes symbol will be pointed at the appropriate
|
||||
// part of the .note.go.abihash section in data.go:func address().
|
||||
s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
|
||||
s.Attr |= sym.AttrLocal
|
||||
s.Type = sym.SRODATA
|
||||
s.Attr |= sym.AttrSpecial
|
||||
s.Attr |= sym.AttrReachable
|
||||
s.Size = int64(sha1.Size)
|
||||
s := ldr.LookupOrCreateSym("go.link.abihashbytes", 0)
|
||||
sb := ldr.MakeSymbolUpdater(s)
|
||||
ldr.SetAttrLocal(s, true)
|
||||
sb.SetType(sym.SRODATA)
|
||||
ldr.SetAttrSpecial(s, true)
|
||||
sb.SetReachable(true)
|
||||
sb.SetSize(sha1.Size)
|
||||
|
||||
sort.Sort(byPkg(ctxt.Library))
|
||||
h := sha1.New()
|
||||
|
@ -174,7 +174,7 @@ type Arch struct {
|
||||
Asmb2 func(*Link)
|
||||
|
||||
Elfreloc1 func(*Link, *sym.Reloc, int64) bool
|
||||
Elfsetupplt func(*Link, *Target, *ArchSyms)
|
||||
Elfsetupplt func(ctxt *Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym)
|
||||
Gentext func(*Link)
|
||||
Machoreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
|
||||
PEreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
|
||||
|
@ -250,7 +250,7 @@ func Main(arch *sys.Arch, theArch Arch) {
|
||||
bench.Start("dostkcheck")
|
||||
ctxt.dostkcheck()
|
||||
|
||||
if !ctxt.IsDarwin() {
|
||||
if !ctxt.IsELF && !ctxt.IsDarwin() {
|
||||
bench.Start("loadlibfull")
|
||||
ctxt.loadlibfull() // XXX do it here for now
|
||||
}
|
||||
@ -258,6 +258,8 @@ func Main(arch *sys.Arch, theArch Arch) {
|
||||
if ctxt.IsELF {
|
||||
bench.Start("doelf")
|
||||
ctxt.doelf()
|
||||
bench.Start("loadlibfull")
|
||||
ctxt.loadlibfull() // XXX do it here for now
|
||||
}
|
||||
if ctxt.IsDarwin() {
|
||||
bench.Start("domacho")
|
||||
|
@ -112,6 +112,14 @@ func (t *Target) IsSolaris() bool {
|
||||
return t.HeadType == objabi.Hsolaris
|
||||
}
|
||||
|
||||
func (t *Target) IsNetbsd() bool {
|
||||
return t.HeadType == objabi.Hnetbsd
|
||||
}
|
||||
|
||||
func (t *Target) IsOpenbsd() bool {
|
||||
return t.HeadType == objabi.Hopenbsd
|
||||
}
|
||||
|
||||
//
|
||||
// MISC
|
||||
//
|
||||
|
@ -60,6 +60,13 @@ func (l *Loader) MakeSymbolUpdater(symIdx Sym) *SymbolBuilder {
|
||||
return sb
|
||||
}
|
||||
|
||||
// CreateSymForUpdate creates a symbol with given name and version,
|
||||
// returns a CreateSymForUpdate for update. If the symbol already
|
||||
// exists, it will update in-place.
|
||||
func (l *Loader) CreateSymForUpdate(name string, version int) *SymbolBuilder {
|
||||
return l.MakeSymbolUpdater(l.LookupOrCreateSym(name, version))
|
||||
}
|
||||
|
||||
// Getters for properties of the symbol we're working on.
|
||||
|
||||
func (sb *SymbolBuilder) Sym() Sym { return sb.symIdx }
|
||||
@ -271,7 +278,7 @@ func (sb *SymbolBuilder) addRel() *Reloc {
|
||||
return &sb.relocs[len(sb.relocs)-1]
|
||||
}
|
||||
|
||||
func (sb *SymbolBuilder) addAddrPlus(tgt Sym, add int64, typ objabi.RelocType, rsize int) int64 {
|
||||
func (sb *SymbolBuilder) addSymRef(tgt Sym, add int64, typ objabi.RelocType, rsize int) int64 {
|
||||
if sb.kind == 0 {
|
||||
sb.kind = sym.SDATA
|
||||
}
|
||||
@ -290,17 +297,34 @@ func (sb *SymbolBuilder) addAddrPlus(tgt Sym, add int64, typ objabi.RelocType, r
|
||||
return i + int64(r.Size)
|
||||
}
|
||||
|
||||
// Add a symbol reference (relocation) with given type, addend, and size
|
||||
// (the most generic form).
|
||||
func (sb *SymbolBuilder) AddSymRef(arch *sys.Arch, tgt Sym, add int64, typ objabi.RelocType, rsize int) int64 {
|
||||
sb.setReachable()
|
||||
return sb.addSymRef(tgt, add, typ, rsize)
|
||||
}
|
||||
|
||||
func (sb *SymbolBuilder) AddAddrPlus(arch *sys.Arch, tgt Sym, add int64) int64 {
|
||||
sb.setReachable()
|
||||
return sb.addAddrPlus(tgt, add, objabi.R_ADDR, arch.PtrSize)
|
||||
return sb.addSymRef(tgt, add, objabi.R_ADDR, arch.PtrSize)
|
||||
}
|
||||
|
||||
func (sb *SymbolBuilder) AddAddrPlus4(arch *sys.Arch, tgt Sym, add int64) int64 {
|
||||
sb.setReachable()
|
||||
return sb.addAddrPlus(tgt, add, objabi.R_ADDR, 4)
|
||||
return sb.addSymRef(tgt, add, objabi.R_ADDR, 4)
|
||||
}
|
||||
|
||||
func (sb *SymbolBuilder) AddPCRelPlus(arch *sys.Arch, tgt Sym, add int64) int64 {
|
||||
sb.setReachable()
|
||||
return sb.addSymRef(tgt, add, objabi.R_PCREL, 4)
|
||||
}
|
||||
|
||||
func (sb *SymbolBuilder) AddCURelativeAddrPlus(arch *sys.Arch, tgt Sym, add int64) int64 {
|
||||
sb.setReachable()
|
||||
return sb.addAddrPlus(tgt, add, objabi.R_ADDRCUOFF, arch.PtrSize)
|
||||
return sb.addSymRef(tgt, add, objabi.R_ADDRCUOFF, arch.PtrSize)
|
||||
}
|
||||
|
||||
func (sb *SymbolBuilder) AddSize(arch *sys.Arch, tgt Sym) int64 {
|
||||
sb.setReachable()
|
||||
return sb.addSymRef(tgt, 0, objabi.R_SIZE, arch.PtrSize)
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"cmd/link/internal/ld"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"debug/elf"
|
||||
"fmt"
|
||||
@ -74,7 +75,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
|
||||
func elfsetupplt(ctxt *ld.Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"cmd/link/internal/ld"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"debug/elf"
|
||||
"fmt"
|
||||
@ -91,7 +92,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
|
||||
func elfsetupplt(ctxt *ld.Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"cmd/link/internal/ld"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"debug/elf"
|
||||
"encoding/binary"
|
||||
@ -498,14 +499,13 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
|
||||
plt := ctxt.Syms.Lookup(".plt", 0)
|
||||
if plt.Size == 0 {
|
||||
func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
|
||||
if plt.Size() == 0 {
|
||||
// The dynamic linker stores the address of the
|
||||
// dynamic resolver and the DSO identifier in the two
|
||||
// doublewords at the beginning of the .plt section
|
||||
// before the PLT array. Reserve space for these.
|
||||
plt.Size = 16
|
||||
plt.SetSize(16)
|
||||
}
|
||||
}
|
||||
|
||||
@ -949,7 +949,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
|
||||
plt := ctxt.Syms.Lookup(".plt", 0)
|
||||
rela := ctxt.Syms.Lookup(".rela.plt", 0)
|
||||
if plt.Size == 0 {
|
||||
elfsetupplt(ctxt, &ctxt.Target, &ctxt.ArchSyms)
|
||||
panic("plt is not set up")
|
||||
}
|
||||
|
||||
// Create the glink resolver if necessary
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"cmd/link/internal/ld"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"fmt"
|
||||
"log"
|
||||
@ -31,7 +32,7 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
|
||||
func elfsetupplt(ctxt *ld.Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym) {
|
||||
log.Fatalf("elfsetuplt")
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"cmd/link/internal/ld"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"debug/elf"
|
||||
"fmt"
|
||||
@ -333,10 +334,8 @@ func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
|
||||
plt := ctxt.Syms.Lookup(".plt", 0)
|
||||
got := ctxt.Syms.Lookup(".got", 0)
|
||||
if plt.Size == 0 {
|
||||
func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
|
||||
if plt.Size() == 0 {
|
||||
// stg %r1,56(%r15)
|
||||
plt.AddUint8(0xe3)
|
||||
plt.AddUint8(0x10)
|
||||
@ -347,7 +346,7 @@ func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
|
||||
// larl %r1,_GLOBAL_OFFSET_TABLE_
|
||||
plt.AddUint8(0xc0)
|
||||
plt.AddUint8(0x10)
|
||||
plt.AddPCRelPlus(ctxt.Arch, got, 6)
|
||||
plt.AddPCRelPlus(ctxt.Arch, got.Sym(), 6)
|
||||
// mvc 48(8,%r15),8(%r1)
|
||||
plt.AddUint8(0xd2)
|
||||
plt.AddUint8(0x07)
|
||||
@ -376,7 +375,7 @@ func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
|
||||
plt.AddUint8(0x00)
|
||||
|
||||
// assume got->size == 0 too
|
||||
got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
|
||||
got.AddAddrPlus(ctxt.Arch, dynamic, 0)
|
||||
|
||||
got.AddUint64(ctxt.Arch, 0)
|
||||
got.AddUint64(ctxt.Arch, 0)
|
||||
@ -431,7 +430,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
|
||||
got := ctxt.Syms.Lookup(".got", 0)
|
||||
rela := ctxt.Syms.Lookup(".rela.plt", 0)
|
||||
if plt.Size == 0 {
|
||||
elfsetupplt(ctxt, &ctxt.Target, &ctxt.ArchSyms)
|
||||
panic("plt is not set up")
|
||||
}
|
||||
// larl %r1,_GLOBAL_OFFSET_TABLE_+index
|
||||
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"cmd/link/internal/ld"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"debug/elf"
|
||||
"log"
|
||||
@ -511,27 +512,25 @@ func archrelocvariant(target *ld.Target, syms *ld.ArchSyms, r *sym.Reloc, s *sym
|
||||
return t
|
||||
}
|
||||
|
||||
func elfsetupplt(ctxt *ld.Link, target *ld.Target, syms *ld.ArchSyms) {
|
||||
plt := ctxt.Syms.Lookup(".plt", 0)
|
||||
got := ctxt.Syms.Lookup(".got.plt", 0)
|
||||
if plt.Size == 0 {
|
||||
func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
|
||||
if plt.Size() == 0 {
|
||||
// pushl got+4
|
||||
plt.AddUint8(0xff)
|
||||
|
||||
plt.AddUint8(0x35)
|
||||
plt.AddAddrPlus(ctxt.Arch, got, 4)
|
||||
plt.AddAddrPlus(ctxt.Arch, got.Sym(), 4)
|
||||
|
||||
// jmp *got+8
|
||||
plt.AddUint8(0xff)
|
||||
|
||||
plt.AddUint8(0x25)
|
||||
plt.AddAddrPlus(ctxt.Arch, got, 8)
|
||||
plt.AddAddrPlus(ctxt.Arch, got.Sym(), 8)
|
||||
|
||||
// zero pad
|
||||
plt.AddUint32(ctxt.Arch, 0)
|
||||
|
||||
// assume got->size == 0 too
|
||||
got.AddAddrPlus(ctxt.Arch, ctxt.Syms.Lookup(".dynamic", 0), 0)
|
||||
got.AddAddrPlus(ctxt.Arch, dynamic, 0)
|
||||
|
||||
got.AddUint32(ctxt.Arch, 0)
|
||||
got.AddUint32(ctxt.Arch, 0)
|
||||
@ -550,7 +549,7 @@ func addpltsym(ctxt *ld.Link, s *sym.Symbol) {
|
||||
got := ctxt.Syms.Lookup(".got.plt", 0)
|
||||
rel := ctxt.Syms.Lookup(".rel.plt", 0)
|
||||
if plt.Size == 0 {
|
||||
elfsetupplt(ctxt, &ctxt.Target, &ctxt.ArchSyms)
|
||||
panic("plt is not set up")
|
||||
}
|
||||
|
||||
// jmpq *got+size
|
||||
|
Loading…
Reference in New Issue
Block a user