mirror of
https://github.com/golang/go
synced 2024-11-18 04:14:49 -07:00
[dev.link] cmd/link: begin converting gentext to loader APIs
Begin the job of converting the linker's "gentext" phase over to use loader APIs. This patch includes most architectures except for s390x and PPC (these will be added in subsequent patches, since they require a couple of loader changes first). Change-Id: Ic7f55c207dcdbbba657330ef007a72ff7c837416 Reviewed-on: https://go-review.googlesource.com/c/go/+/227017 Reviewed-by: Jeremy Faller <jeremy@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
6435590182
commit
8e457c865d
@ -45,59 +45,29 @@ func PADDR(x uint32) uint32 {
|
||||
return x &^ 0x80000000
|
||||
}
|
||||
|
||||
func Addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) int64 {
|
||||
s.Attr |= sym.AttrReachable
|
||||
i := s.Size
|
||||
s.Size += 4
|
||||
s.Grow(s.Size)
|
||||
r := s.AddRel()
|
||||
r.Sym = t
|
||||
r.Off = int32(i)
|
||||
r.Type = objabi.R_CALL
|
||||
r.Siz = 4
|
||||
return i + int64(r.Siz)
|
||||
}
|
||||
func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
|
||||
initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt)
|
||||
if initfunc == nil {
|
||||
return
|
||||
}
|
||||
|
||||
func gentext(ctxt *ld.Link) {
|
||||
if !ctxt.DynlinkingGo() {
|
||||
return
|
||||
}
|
||||
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
||||
if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
|
||||
// we're linking a module containing the runtime -> no need for
|
||||
// an init function
|
||||
return
|
||||
}
|
||||
addmoduledata.Attr |= sym.AttrReachable
|
||||
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
||||
initfunc.Type = sym.STEXT
|
||||
initfunc.Attr |= sym.AttrLocal
|
||||
initfunc.Attr |= sym.AttrReachable
|
||||
o := func(op ...uint8) {
|
||||
for _, op1 := range op {
|
||||
initfunc.AddUint8(op1)
|
||||
}
|
||||
}
|
||||
|
||||
// 0000000000000000 <local.dso_init>:
|
||||
// 0: 48 8d 3d 00 00 00 00 lea 0x0(%rip),%rdi # 7 <local.dso_init+0x7>
|
||||
// 3: R_X86_64_PC32 runtime.firstmoduledata-0x4
|
||||
o(0x48, 0x8d, 0x3d)
|
||||
initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata, 0)
|
||||
initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata2, 0)
|
||||
// 7: e8 00 00 00 00 callq c <local.dso_init+0xc>
|
||||
// 8: R_X86_64_PLT32 runtime.addmoduledata-0x4
|
||||
o(0xe8)
|
||||
Addcall(ctxt, initfunc, addmoduledata)
|
||||
initfunc.AddSymRef(ctxt.Arch, addmoduledata, 0, objabi.R_CALL, 4)
|
||||
// c: c3 retq
|
||||
o(0xc3)
|
||||
if ctxt.BuildMode == ld.BuildModePlugin {
|
||||
ctxt.Textp = append(ctxt.Textp, addmoduledata)
|
||||
}
|
||||
ctxt.Textp = append(ctxt.Textp, initfunc)
|
||||
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
||||
initarray_entry.Attr |= sym.AttrReachable
|
||||
initarray_entry.Attr |= sym.AttrLocal
|
||||
initarray_entry.Type = sym.SINITARR
|
||||
initarray_entry.AddAddr(ctxt.Arch, initfunc)
|
||||
}
|
||||
|
||||
// makeWritable makes a readonly symbol writable if we do opcode rewriting.
|
||||
|
@ -54,7 +54,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
Asmb2: asmb2,
|
||||
Elfreloc1: elfreloc1,
|
||||
Elfsetupplt: elfsetupplt,
|
||||
Gentext: gentext,
|
||||
Gentext2: gentext2,
|
||||
Machoreloc1: machoreloc1,
|
||||
PEreloc1: pereloc1,
|
||||
TLSIEtoLE: tlsIEtoLE,
|
||||
|
@ -63,21 +63,12 @@ import (
|
||||
// c: 00000004 .word 0x00000004
|
||||
// c: R_ARM_GOT_PREL local.moduledata
|
||||
|
||||
func gentext(ctxt *ld.Link) {
|
||||
if !ctxt.DynlinkingGo() {
|
||||
func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
|
||||
initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt)
|
||||
if initfunc == nil {
|
||||
return
|
||||
}
|
||||
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
||||
if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
|
||||
// we're linking a module containing the runtime -> no need for
|
||||
// an init function
|
||||
return
|
||||
}
|
||||
addmoduledata.Attr |= sym.AttrReachable
|
||||
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
||||
initfunc.Type = sym.STEXT
|
||||
initfunc.Attr |= sym.AttrLocal
|
||||
initfunc.Attr |= sym.AttrReachable
|
||||
|
||||
o := func(op uint32) {
|
||||
initfunc.AddUint32(ctxt.Arch, op)
|
||||
}
|
||||
@ -85,30 +76,25 @@ func gentext(ctxt *ld.Link) {
|
||||
o(0xe08f0000)
|
||||
|
||||
o(0xeafffffe)
|
||||
rel := initfunc.AddRel()
|
||||
rel.Off = 8
|
||||
rel.Siz = 4
|
||||
rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
||||
rel.Type = objabi.R_CALLARM
|
||||
rel.Add = 0xeafffffe // vomit
|
||||
rel := loader.Reloc{
|
||||
Off: 8,
|
||||
Size: 4,
|
||||
Type: objabi.R_CALLARM,
|
||||
Sym: addmoduledata,
|
||||
Add: 0xeafffffe, // vomit
|
||||
}
|
||||
initfunc.AddReloc(rel)
|
||||
|
||||
o(0x00000000)
|
||||
rel = initfunc.AddRel()
|
||||
rel.Off = 12
|
||||
rel.Siz = 4
|
||||
rel.Sym = ctxt.Moduledata
|
||||
rel.Type = objabi.R_PCREL
|
||||
rel.Add = 4
|
||||
|
||||
if ctxt.BuildMode == ld.BuildModePlugin {
|
||||
ctxt.Textp = append(ctxt.Textp, addmoduledata)
|
||||
rel2 := loader.Reloc{
|
||||
Off: 12,
|
||||
Size: 4,
|
||||
Type: objabi.R_PCREL,
|
||||
Sym: ctxt.Moduledata2,
|
||||
Add: 4,
|
||||
}
|
||||
ctxt.Textp = append(ctxt.Textp, initfunc)
|
||||
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
||||
initarray_entry.Attr |= sym.AttrReachable
|
||||
initarray_entry.Attr |= sym.AttrLocal
|
||||
initarray_entry.Type = sym.SINITARR
|
||||
initarray_entry.AddAddr(ctxt.Arch, initfunc)
|
||||
initfunc.AddReloc(rel2)
|
||||
}
|
||||
|
||||
// Preserve highest 8 bits of a, and do addition to lower 24-bit
|
||||
|
@ -55,7 +55,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
Asmb2: asmb2,
|
||||
Elfreloc1: elfreloc1,
|
||||
Elfsetupplt: elfsetupplt,
|
||||
Gentext: gentext,
|
||||
Gentext2: gentext2,
|
||||
Machoreloc1: machoreloc1,
|
||||
PEreloc1: pereloc1,
|
||||
|
||||
|
@ -42,21 +42,12 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
func gentext(ctxt *ld.Link) {
|
||||
if !ctxt.DynlinkingGo() {
|
||||
func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
|
||||
initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt)
|
||||
if initfunc == nil {
|
||||
return
|
||||
}
|
||||
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
||||
if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
|
||||
// we're linking a module containing the runtime -> no need for
|
||||
// an init function
|
||||
return
|
||||
}
|
||||
addmoduledata.Attr |= sym.AttrReachable
|
||||
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
||||
initfunc.Type = sym.STEXT
|
||||
initfunc.Attr |= sym.AttrLocal
|
||||
initfunc.Attr |= sym.AttrReachable
|
||||
|
||||
o := func(op uint32) {
|
||||
initfunc.AddUint32(ctxt.Arch, op)
|
||||
}
|
||||
@ -67,30 +58,24 @@ func gentext(ctxt *ld.Link) {
|
||||
// 4: R_AARCH64_ADD_ABS_LO12_NC local.moduledata
|
||||
o(0x90000000)
|
||||
o(0x91000000)
|
||||
rel := initfunc.AddRel()
|
||||
rel.Off = 0
|
||||
rel.Siz = 8
|
||||
rel.Sym = ctxt.Moduledata
|
||||
rel.Type = objabi.R_ADDRARM64
|
||||
rel := loader.Reloc{
|
||||
Off: 0,
|
||||
Size: 8,
|
||||
Type: objabi.R_ADDRARM64,
|
||||
Sym: ctxt.Moduledata2,
|
||||
}
|
||||
initfunc.AddReloc(rel)
|
||||
|
||||
// 8: 14000000 b 0 <runtime.addmoduledata>
|
||||
// 8: R_AARCH64_CALL26 runtime.addmoduledata
|
||||
o(0x14000000)
|
||||
rel = initfunc.AddRel()
|
||||
rel.Off = 8
|
||||
rel.Siz = 4
|
||||
rel.Sym = ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
||||
rel.Type = objabi.R_CALLARM64 // Really should be R_AARCH64_JUMP26 but doesn't seem to make any difference
|
||||
|
||||
if ctxt.BuildMode == ld.BuildModePlugin {
|
||||
ctxt.Textp = append(ctxt.Textp, addmoduledata)
|
||||
rel2 := loader.Reloc{
|
||||
Off: 8,
|
||||
Size: 4,
|
||||
Type: objabi.R_CALLARM64, // Really should be R_AARCH64_JUMP26 but doesn't seem to make any difference
|
||||
Sym: addmoduledata,
|
||||
}
|
||||
ctxt.Textp = append(ctxt.Textp, initfunc)
|
||||
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
||||
initarray_entry.Attr |= sym.AttrReachable
|
||||
initarray_entry.Attr |= sym.AttrLocal
|
||||
initarray_entry.Type = sym.SINITARR
|
||||
initarray_entry.AddAddr(ctxt.Arch, initfunc)
|
||||
initfunc.AddReloc(rel2)
|
||||
}
|
||||
|
||||
func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
|
||||
|
@ -54,7 +54,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
Asmb2: asmb2,
|
||||
Elfreloc1: elfreloc1,
|
||||
Elfsetupplt: elfsetupplt,
|
||||
Gentext: gentext,
|
||||
Gentext2: gentext2,
|
||||
Machoreloc1: machoreloc1,
|
||||
|
||||
Androiddynld: "/system/bin/linker64",
|
||||
|
@ -32,6 +32,7 @@
|
||||
package ld
|
||||
|
||||
import (
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
@ -215,3 +216,46 @@ func atolwhex(s string) int64 {
|
||||
n, _ := strconv.ParseInt(s, 0, 64)
|
||||
return n
|
||||
}
|
||||
|
||||
// PrepareAddmoduledata returns a symbol builder that target-specific
|
||||
// code can use to build up the linker-generated go.link.addmoduledata
|
||||
// function, along with the sym for runtime.addmoduledata itself. If
|
||||
// this function is not needed (for example in cases where we're
|
||||
// linking a module that contains the runtime) the returned builder
|
||||
// will be nil.
|
||||
func PrepareAddmoduledata(ctxt *Link) (*loader.SymbolBuilder, loader.Sym) {
|
||||
if !ctxt.DynlinkingGo() {
|
||||
return nil, 0
|
||||
}
|
||||
amd := ctxt.loader.LookupOrCreateSym("runtime.addmoduledata", 0)
|
||||
if ctxt.loader.SymType(amd) == sym.STEXT && ctxt.BuildMode != BuildModePlugin {
|
||||
// we're linking a module containing the runtime -> no need for
|
||||
// an init function
|
||||
return nil, 0
|
||||
}
|
||||
ctxt.loader.SetAttrReachable(amd, true)
|
||||
|
||||
// Create a new init func text symbol. Caller will populate this
|
||||
// sym with arch-specific content.
|
||||
ifs := ctxt.loader.LookupOrCreateSym("go.link.addmoduledata", 0)
|
||||
initfunc := ctxt.loader.MakeSymbolUpdater(ifs)
|
||||
ctxt.loader.SetAttrReachable(ifs, true)
|
||||
ctxt.loader.SetAttrLocal(ifs, true)
|
||||
initfunc.SetType(sym.STEXT)
|
||||
|
||||
// Add the init func and/or addmoduledata to Textp2.
|
||||
if ctxt.BuildMode == BuildModePlugin {
|
||||
ctxt.Textp2 = append(ctxt.Textp2, amd)
|
||||
}
|
||||
ctxt.Textp2 = append(ctxt.Textp2, initfunc.Sym())
|
||||
|
||||
// Create an init array entry
|
||||
amdi := ctxt.loader.LookupOrCreateSym("go.link.addmoduledatainit", 0)
|
||||
initarray_entry := ctxt.loader.MakeSymbolUpdater(amdi)
|
||||
ctxt.loader.SetAttrReachable(amdi, true)
|
||||
ctxt.loader.SetAttrLocal(amdi, true)
|
||||
initarray_entry.SetType(sym.SINITARR)
|
||||
initarray_entry.AddAddr(ctxt.Arch, ifs)
|
||||
|
||||
return initfunc, amd
|
||||
}
|
||||
|
@ -263,6 +263,7 @@ type Arch struct {
|
||||
Elfreloc1 func(*Link, *sym.Reloc, int64) bool
|
||||
Elfsetupplt func(ctxt *Link, plt, gotplt *loader.SymbolBuilder, dynamic loader.Sym)
|
||||
Gentext func(*Link)
|
||||
Gentext2 func(*Link, *loader.Loader)
|
||||
Machoreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
|
||||
PEreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
|
||||
Xcoffreloc1 func(*sys.Arch, *OutBuf, *sym.Symbol, *sym.Reloc, int64) bool
|
||||
|
@ -285,12 +285,19 @@ func Main(arch *sys.Arch, theArch Arch) {
|
||||
setupdynexp(ctxt)
|
||||
ctxt.setArchSyms(BeforeLoadlibFull)
|
||||
ctxt.addexport()
|
||||
if thearch.Gentext2 != nil {
|
||||
bench.Start("Gentext")
|
||||
thearch.Gentext2(ctxt, ctxt.loader) // trampolines, call stubs, etc.
|
||||
}
|
||||
|
||||
bench.Start("loadlibfull")
|
||||
ctxt.loadlibfull() // XXX do it here for now
|
||||
|
||||
bench.Start("Gentext")
|
||||
thearch.Gentext(ctxt) // trampolines, call stubs, etc.
|
||||
if thearch.Gentext2 == nil {
|
||||
bench.Start("Gentext")
|
||||
thearch.Gentext(ctxt) // trampolines, call stubs, etc.
|
||||
}
|
||||
|
||||
bench.Start("textaddress")
|
||||
ctxt.textaddress()
|
||||
bench.Start("pclntab")
|
||||
|
@ -42,7 +42,7 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
func gentext(ctxt *ld.Link) {
|
||||
func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
Asmb2: asmb2,
|
||||
Elfreloc1: elfreloc1,
|
||||
Elfsetupplt: elfsetupplt,
|
||||
Gentext: gentext,
|
||||
Gentext2: gentext2,
|
||||
Machoreloc1: machoreloc1,
|
||||
|
||||
Linuxdynld: "/lib/ld.so.1",
|
||||
|
@ -42,7 +42,7 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
func gentext(ctxt *ld.Link) {}
|
||||
func gentext2(ctxt *ld.Link, ldr *loader.Loader) {}
|
||||
|
||||
func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
|
||||
log.Fatalf("adddynrel not implemented")
|
||||
|
@ -56,7 +56,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
Asmb2: asmb2,
|
||||
Elfreloc1: elfreloc1,
|
||||
Elfsetupplt: elfsetupplt,
|
||||
Gentext: gentext,
|
||||
Gentext2: gentext2,
|
||||
Machoreloc1: machoreloc1,
|
||||
|
||||
Linuxdynld: "/lib64/ld64.so.1",
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
func gentext(ctxt *ld.Link) {
|
||||
func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
|
||||
}
|
||||
|
||||
func adddynrela(target *ld.Target, syms *ld.ArchSyms, rel *sym.Symbol, s *sym.Symbol, r *sym.Reloc) {
|
||||
|
@ -28,7 +28,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
Asmb2: asmb2,
|
||||
Elfreloc1: elfreloc1,
|
||||
Elfsetupplt: elfsetupplt,
|
||||
Gentext: gentext,
|
||||
Gentext2: gentext2,
|
||||
Machoreloc1: machoreloc1,
|
||||
|
||||
Linuxdynld: "/lib/ld.so.1",
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"bytes"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/link/internal/ld"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"io"
|
||||
"regexp"
|
||||
@ -38,7 +39,7 @@ const (
|
||||
// funcValueOffset is the offset between the PC_F value of a function and the index of the function in WebAssembly
|
||||
const funcValueOffset = 0x1000 // TODO(neelance): make function addresses play nice with heap addresses
|
||||
|
||||
func gentext(ctxt *ld.Link) {
|
||||
func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
|
||||
}
|
||||
|
||||
type wasmFunc struct {
|
||||
|
@ -19,7 +19,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
AssignAddress: assignAddress,
|
||||
Asmb: asmb,
|
||||
Asmb2: asmb2,
|
||||
Gentext: gentext,
|
||||
Gentext2: gentext2,
|
||||
}
|
||||
|
||||
return sys.ArchWasm, theArch
|
||||
|
@ -41,20 +41,7 @@ import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Append 4 bytes to s and create a R_CALL relocation targeting t to fill them in.
|
||||
func addcall(ctxt *ld.Link, s *sym.Symbol, t *sym.Symbol) {
|
||||
s.Attr |= sym.AttrReachable
|
||||
i := s.Size
|
||||
s.Size += 4
|
||||
s.Grow(s.Size)
|
||||
r := s.AddRel()
|
||||
r.Sym = t
|
||||
r.Off = int32(i)
|
||||
r.Type = objabi.R_CALL
|
||||
r.Siz = 4
|
||||
}
|
||||
|
||||
func gentext(ctxt *ld.Link) {
|
||||
func gentext2(ctxt *ld.Link, ldr *loader.Loader) {
|
||||
if ctxt.DynlinkingGo() {
|
||||
// We need get_pc_thunk.
|
||||
} else {
|
||||
@ -71,7 +58,7 @@ func gentext(ctxt *ld.Link) {
|
||||
}
|
||||
|
||||
// Generate little thunks that load the PC of the next instruction into a register.
|
||||
thunks := make([]*sym.Symbol, 0, 7+len(ctxt.Textp))
|
||||
thunks := make([]loader.Sym, 0, 7+len(ctxt.Textp2))
|
||||
for _, r := range [...]struct {
|
||||
name string
|
||||
num uint8
|
||||
@ -85,10 +72,9 @@ func gentext(ctxt *ld.Link) {
|
||||
{"si", 6},
|
||||
{"di", 7},
|
||||
} {
|
||||
thunkfunc := ctxt.Syms.Lookup("__x86.get_pc_thunk."+r.name, 0)
|
||||
thunkfunc.Type = sym.STEXT
|
||||
thunkfunc.Attr |= sym.AttrLocal
|
||||
thunkfunc.Attr |= sym.AttrReachable //TODO: remove?
|
||||
thunkfunc := ldr.CreateSymForUpdate("__x86.get_pc_thunk."+r.name, 0)
|
||||
thunkfunc.SetType(sym.STEXT)
|
||||
ldr.SetAttrLocal(thunkfunc.Sym(), true)
|
||||
o := func(op ...uint8) {
|
||||
for _, op1 := range op {
|
||||
thunkfunc.AddUint8(op1)
|
||||
@ -100,23 +86,15 @@ func gentext(ctxt *ld.Link) {
|
||||
// c3 ret
|
||||
o(0xc3)
|
||||
|
||||
thunks = append(thunks, thunkfunc)
|
||||
thunks = append(thunks, thunkfunc.Sym())
|
||||
}
|
||||
ctxt.Textp = append(thunks, ctxt.Textp...) // keep Textp in dependency order
|
||||
ctxt.Textp2 = append(thunks, ctxt.Textp2...) // keep Textp2 in dependency order
|
||||
|
||||
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
|
||||
if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
|
||||
// we're linking a module containing the runtime -> no need for
|
||||
// an init function
|
||||
initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt)
|
||||
if initfunc == nil {
|
||||
return
|
||||
}
|
||||
|
||||
addmoduledata.Attr |= sym.AttrReachable
|
||||
|
||||
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
|
||||
initfunc.Type = sym.STEXT
|
||||
initfunc.Attr |= sym.AttrLocal
|
||||
initfunc.Attr |= sym.AttrReachable
|
||||
o := func(op ...uint8) {
|
||||
for _, op1 := range op {
|
||||
initfunc.AddUint8(op1)
|
||||
@ -135,38 +113,20 @@ func gentext(ctxt *ld.Link) {
|
||||
o(0x53)
|
||||
|
||||
o(0xe8)
|
||||
addcall(ctxt, initfunc, ctxt.Syms.Lookup("__x86.get_pc_thunk.cx", 0))
|
||||
initfunc.AddSymRef(ctxt.Arch, ldr.Lookup("__x86.get_pc_thunk.cx", 0), 0, objabi.R_CALL, 4)
|
||||
|
||||
o(0x8d, 0x81)
|
||||
initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata, 6)
|
||||
initfunc.AddPCRelPlus(ctxt.Arch, ctxt.Moduledata2, 6)
|
||||
|
||||
o(0x8d, 0x99)
|
||||
i := initfunc.Size
|
||||
initfunc.Size += 4
|
||||
initfunc.Grow(initfunc.Size)
|
||||
r := initfunc.AddRel()
|
||||
r.Sym = ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
|
||||
r.Off = int32(i)
|
||||
r.Type = objabi.R_PCREL
|
||||
r.Add = 12
|
||||
r.Siz = 4
|
||||
|
||||
gotsym := ldr.LookupOrCreateSym("_GLOBAL_OFFSET_TABLE_", 0)
|
||||
initfunc.AddSymRef(ctxt.Arch, gotsym, 12, objabi.R_PCREL, 4)
|
||||
o(0xe8)
|
||||
addcall(ctxt, initfunc, addmoduledata)
|
||||
initfunc.AddSymRef(ctxt.Arch, addmoduledata, 0, objabi.R_CALL, 4)
|
||||
|
||||
o(0x5b)
|
||||
|
||||
o(0xc3)
|
||||
|
||||
if ctxt.BuildMode == ld.BuildModePlugin {
|
||||
ctxt.Textp = append(ctxt.Textp, addmoduledata)
|
||||
}
|
||||
ctxt.Textp = append(ctxt.Textp, initfunc)
|
||||
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
|
||||
initarray_entry.Attr |= sym.AttrReachable
|
||||
initarray_entry.Attr |= sym.AttrLocal
|
||||
initarray_entry.Type = sym.SINITARR
|
||||
initarray_entry.AddAddr(ctxt.Arch, initfunc)
|
||||
}
|
||||
|
||||
func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s *sym.Symbol, r *sym.Reloc) bool {
|
||||
|
@ -54,7 +54,7 @@ func Init() (*sys.Arch, ld.Arch) {
|
||||
Asmb2: asmb2,
|
||||
Elfreloc1: elfreloc1,
|
||||
Elfsetupplt: elfsetupplt,
|
||||
Gentext: gentext,
|
||||
Gentext2: gentext2,
|
||||
Machoreloc1: machoreloc1,
|
||||
PEreloc1: pereloc1,
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user