// Return the value of .TOC. for symbol s func symtoc(s *ld.LSym) int64 { var toc *ld.LSym if s.Outer != nil { toc = ld.Linkrlookup(ld.Ctxt, ".TOC.", int(s.Outer.Version)) } else { toc = ld.Linkrlookup(ld.Ctxt, ".TOC.", int(s.Version)) } if toc == nil { ld.Diag("TOC-relative relocation in object without .TOC.") return 0 } return toc.Value }
func genaddmoduledata() { addmoduledata := ld.Linkrlookup(ld.Ctxt, "runtime.addmoduledata", 0) if addmoduledata.Type == obj.STEXT { return } addmoduledata.Reachable = true initfunc := ld.Linklookup(ld.Ctxt, "go.link.addmoduledata", 0) initfunc.Type = obj.STEXT initfunc.Local = true initfunc.Reachable = true o := func(op uint32) { ld.Adduint32(ld.Ctxt, initfunc, op) } // addis r2, r12, .TOC.-func@ha rel := ld.Addrel(initfunc) rel.Off = int32(initfunc.Size) rel.Siz = 8 rel.Sym = ld.Linklookup(ld.Ctxt, ".TOC.", 0) rel.Type = obj.R_ADDRPOWER_PCREL o(0x3c4c0000) // addi r2, r2, .TOC.-func@l o(0x38420000) // mflr r31 o(0x7c0802a6) // stdu r31, -32(r1) o(0xf801ffe1) // addis r3, r2, local.moduledata@got@ha rel = ld.Addrel(initfunc) rel.Off = int32(initfunc.Size) rel.Siz = 8 rel.Sym = ld.Linklookup(ld.Ctxt, "local.moduledata", 0) rel.Type = obj.R_ADDRPOWER_GOT o(0x3c620000) // ld r3, local.moduledata@got@l(r3) o(0xe8630000) // bl runtime.addmoduledata rel = ld.Addrel(initfunc) rel.Off = int32(initfunc.Size) rel.Siz = 4 rel.Sym = addmoduledata rel.Type = obj.R_CALLPOWER o(0x48000001) // nop o(0x60000000) // ld r31, 0(r1) o(0xe8010000) // mtlr r31 o(0x7c0803a6) // addi r1,r1,32 o(0x38210020) // blr o(0x4e800020) if ld.Ctxt.Etextp != nil { ld.Ctxt.Etextp.Next = initfunc } else { ld.Ctxt.Textp = initfunc } ld.Ctxt.Etextp = initfunc initarray_entry := ld.Linklookup(ld.Ctxt, "go.link.addmoduledatainit", 0) initarray_entry.Reachable = true initarray_entry.Local = true initarray_entry.Type = obj.SINITARR ld.Addaddr(ld.Ctxt, initarray_entry, initfunc) }