func elfsetupplt(ctxt *ld.Link) { plt := ctxt.Syms.Lookup(".plt", 0) got := ctxt.Syms.Lookup(".got.plt", 0) if plt.Size == 0 { // pushl got+4 ld.Adduint8(ctxt, plt, 0xff) ld.Adduint8(ctxt, plt, 0x35) ld.Addaddrplus(ctxt, plt, got, 4) // jmp *got+8 ld.Adduint8(ctxt, plt, 0xff) ld.Adduint8(ctxt, plt, 0x25) ld.Addaddrplus(ctxt, plt, got, 8) // zero pad ld.Adduint32(ctxt, plt, 0) // assume got->size == 0 too ld.Addaddrplus(ctxt, got, ctxt.Syms.Lookup(".dynamic", 0), 0) ld.Adduint32(ctxt, got, 0) ld.Adduint32(ctxt, got, 0) } }
func elfsetupplt() { plt := ld.Linklookup(ld.Ctxt, ".plt", 0) got := ld.Linklookup(ld.Ctxt, ".got.plt", 0) if plt.Size == 0 { // pushl got+4 ld.Adduint8(ld.Ctxt, plt, 0xff) ld.Adduint8(ld.Ctxt, plt, 0x35) ld.Addaddrplus(ld.Ctxt, plt, got, 4) // jmp *got+8 ld.Adduint8(ld.Ctxt, plt, 0xff) ld.Adduint8(ld.Ctxt, plt, 0x25) ld.Addaddrplus(ld.Ctxt, plt, got, 8) // zero pad ld.Adduint32(ld.Ctxt, plt, 0) // assume got->size == 0 too ld.Addaddrplus(ld.Ctxt, got, ld.Linklookup(ld.Ctxt, ".dynamic", 0), 0) ld.Adduint32(ld.Ctxt, got, 0) ld.Adduint32(ld.Ctxt, got, 0) } }
func elfsetupplt() { plt := ld.Linklookup(ld.Ctxt, ".plt", 0) got := ld.Linklookup(ld.Ctxt, ".got.plt", 0) if plt.Size == 0 { // pushq got+8(IP) ld.Adduint8(ld.Ctxt, plt, 0xff) ld.Adduint8(ld.Ctxt, plt, 0x35) ld.Addpcrelplus(ld.Ctxt, plt, got, 8) // jmpq got+16(IP) ld.Adduint8(ld.Ctxt, plt, 0xff) ld.Adduint8(ld.Ctxt, plt, 0x25) ld.Addpcrelplus(ld.Ctxt, plt, got, 16) // nopl 0(AX) ld.Adduint32(ld.Ctxt, plt, 0x00401f0f) // assume got->size == 0 too ld.Addaddrplus(ld.Ctxt, got, ld.Linklookup(ld.Ctxt, ".dynamic", 0), 0) ld.Adduint64(ld.Ctxt, got, 0) ld.Adduint64(ld.Ctxt, got, 0) } }
// gentext generates assembly to append the local moduledata to the global // moduledata linked list at initialization time. This is only done if the runtime // is in a different module. // // <go.link.addmoduledata>: // larl %r2, <local.moduledata> // jg <runtime.addmoduledata@plt> // undef // // The job of appending the moduledata is delegated to runtime.addmoduledata. func gentext(ctxt *ld.Link) { if !ld.DynlinkingGo() { return } addmoduledata := ld.Linklookup(ctxt, "runtime.addmoduledata", 0) if addmoduledata.Type == obj.STEXT { // we're linking a module containing the runtime -> no need for // an init function return } addmoduledata.Attr |= ld.AttrReachable initfunc := ld.Linklookup(ctxt, "go.link.addmoduledata", 0) initfunc.Type = obj.STEXT initfunc.Attr |= ld.AttrLocal initfunc.Attr |= ld.AttrReachable // larl %r2, <local.moduledata> ld.Adduint8(ctxt, initfunc, 0xc0) ld.Adduint8(ctxt, initfunc, 0x20) lmd := ld.Addrel(initfunc) lmd.Off = int32(initfunc.Size) lmd.Siz = 4 lmd.Sym = ctxt.Moduledata lmd.Type = obj.R_PCREL lmd.Variant = ld.RV_390_DBL lmd.Add = 2 + int64(lmd.Siz) ld.Adduint32(ctxt, initfunc, 0) // jg <runtime.addmoduledata[@plt]> ld.Adduint8(ctxt, initfunc, 0xc0) ld.Adduint8(ctxt, initfunc, 0xf4) rel := ld.Addrel(initfunc) rel.Off = int32(initfunc.Size) rel.Siz = 4 rel.Sym = ld.Linklookup(ctxt, "runtime.addmoduledata", 0) rel.Type = obj.R_CALL rel.Variant = ld.RV_390_DBL rel.Add = 2 + int64(rel.Siz) ld.Adduint32(ctxt, initfunc, 0) // undef (for debugging) ld.Adduint32(ctxt, initfunc, 0) ctxt.Textp = append(ctxt.Textp, initfunc) initarray_entry := ld.Linklookup(ctxt, "go.link.addmoduledatainit", 0) initarray_entry.Attr |= ld.AttrLocal initarray_entry.Attr |= ld.AttrReachable initarray_entry.Type = obj.SINITARR ld.Addaddr(ctxt, initarray_entry, initfunc) }
func gentext() { if !ld.DynlinkingGo() && ld.Buildmode != ld.BuildmodePIE { return } thunkfunc := ld.Linklookup(ld.Ctxt, "__x86.get_pc_thunk.cx", 0) thunkfunc.Type = obj.STEXT thunkfunc.Local = true thunkfunc.Reachable = true o := func(op ...uint8) { for _, op1 := range op { ld.Adduint8(ld.Ctxt, thunkfunc, op1) } } // 8b 0c 24 mov (%esp),%ecx o(0x8b, 0x0c, 0x24) // c3 ret o(0xc3) if ld.Ctxt.Etextp != nil { ld.Ctxt.Etextp.Next = thunkfunc } else { ld.Ctxt.Textp = thunkfunc } ld.Ctxt.Etextp = thunkfunc }
func addpltsym(ctxt *ld.Link, s *ld.LSym) { if s.Plt >= 0 { return } ld.Adddynsym(ctxt, s) if ld.Iself { plt := ld.Linklookup(ctxt, ".plt", 0) got := ld.Linklookup(ctxt, ".got.plt", 0) rel := ld.Linklookup(ctxt, ".rel.plt", 0) if plt.Size == 0 { elfsetupplt() } // jmpq *got+size ld.Adduint8(ctxt, plt, 0xff) ld.Adduint8(ctxt, plt, 0x25) ld.Addaddrplus(ctxt, plt, got, got.Size) // add to got: pointer to current pos in plt ld.Addaddrplus(ctxt, got, plt, plt.Size) // pushl $x ld.Adduint8(ctxt, plt, 0x68) ld.Adduint32(ctxt, plt, uint32(rel.Size)) // jmp .plt ld.Adduint8(ctxt, plt, 0xe9) ld.Adduint32(ctxt, plt, uint32(-(plt.Size + 4))) // rel ld.Addaddrplus(ctxt, rel, got, got.Size-4) ld.Adduint32(ctxt, rel, ld.ELF32_R_INFO(uint32(s.Dynid), ld.R_386_JMP_SLOT)) s.Plt = int32(plt.Size - 16) } else if ld.HEADTYPE == obj.Hdarwin { // Same laziness as in 6l. plt := ld.Linklookup(ctxt, ".plt", 0) addgotsym(ctxt, s) ld.Adduint32(ctxt, ld.Linklookup(ctxt, ".linkedit.plt", 0), uint32(s.Dynid)) // jmpq *got+size(IP) s.Plt = int32(plt.Size) ld.Adduint8(ctxt, plt, 0xff) ld.Adduint8(ctxt, plt, 0x25) ld.Addaddrplus(ctxt, plt, ld.Linklookup(ctxt, ".got", 0), int64(s.Got)) } else { ld.Diag("addpltsym: unsupported binary format") } }
func gentext() { if !ld.DynlinkingGo() { return } addmoduledata := ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) if addmoduledata.Type == obj.STEXT { // we're linking a module containing the runtime -> no need for // an init function 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 ...uint8) { for _, op1 := range op { ld.Adduint8(ld.Ctxt, initfunc, 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) ld.Addpcrelplus(ld.Ctxt, initfunc, ld.Ctxt.Moduledata, 0) // 7: e8 00 00 00 00 callq c <local.dso_init+0xc> // 8: R_X86_64_PLT32 runtime.addmoduledata-0x4 o(0xe8) Addcall(ld.Ctxt, initfunc, addmoduledata) // c: c3 retq o(0xc3) 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) }
func gentext(ctxt *ld.Link) { if !ctxt.DynlinkingGo() { return } addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0) if addmoduledata.Type == obj.STEXT && ld.Buildmode != ld.BuildmodePlugin { // we're linking a module containing the runtime -> no need for // an init function return } addmoduledata.Attr |= ld.AttrReachable initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0) initfunc.Type = obj.STEXT initfunc.Attr |= ld.AttrLocal initfunc.Attr |= ld.AttrReachable o := func(op ...uint8) { for _, op1 := range op { ld.Adduint8(ctxt, initfunc, 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) ld.Addpcrelplus(ctxt, initfunc, ctxt.Moduledata, 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) // c: c3 retq o(0xc3) if ld.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 |= ld.AttrReachable initarray_entry.Attr |= ld.AttrLocal initarray_entry.Type = obj.SINITARR ld.Addaddr(ctxt, initarray_entry, initfunc) }
func addpltsym(s *ld.LSym) { if s.Plt >= 0 { return } ld.Adddynsym(ld.Ctxt, s) if ld.Iself { plt := ld.Linklookup(ld.Ctxt, ".plt", 0) got := ld.Linklookup(ld.Ctxt, ".got.plt", 0) rela := ld.Linklookup(ld.Ctxt, ".rela.plt", 0) if plt.Size == 0 { elfsetupplt() } // jmpq *got+size(IP) ld.Adduint8(ld.Ctxt, plt, 0xff) ld.Adduint8(ld.Ctxt, plt, 0x25) ld.Addpcrelplus(ld.Ctxt, plt, got, got.Size) // add to got: pointer to current pos in plt ld.Addaddrplus(ld.Ctxt, got, plt, plt.Size) // pushq $x ld.Adduint8(ld.Ctxt, plt, 0x68) ld.Adduint32(ld.Ctxt, plt, uint32((got.Size-24-8)/8)) // jmpq .plt ld.Adduint8(ld.Ctxt, plt, 0xe9) ld.Adduint32(ld.Ctxt, plt, uint32(-(plt.Size + 4))) // rela ld.Addaddrplus(ld.Ctxt, rela, got, got.Size-8) ld.Adduint64(ld.Ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_X86_64_JMP_SLOT)) ld.Adduint64(ld.Ctxt, rela, 0) s.Plt = int32(plt.Size - 16) } else if ld.HEADTYPE == obj.Hdarwin { // 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 // section just so. I'm too lazy (ha!) to do that // so for now we'll just use non-lazy pointers, // which don't need to be told which library to use. // // http://networkpx.blogspot.com/2009/09/about-lcdyldinfoonly-command.html // has details about what we're avoiding. addgotsym(s) plt := ld.Linklookup(ld.Ctxt, ".plt", 0) ld.Adduint32(ld.Ctxt, ld.Linklookup(ld.Ctxt, ".linkedit.plt", 0), uint32(s.Dynid)) // jmpq *got+size(IP) s.Plt = int32(plt.Size) ld.Adduint8(ld.Ctxt, plt, 0xff) ld.Adduint8(ld.Ctxt, plt, 0x25) ld.Addpcrelplus(ld.Ctxt, plt, ld.Linklookup(ld.Ctxt, ".got", 0), int64(s.Got)) } else { ld.Diag("addpltsym: unsupported binary format") } }
func gentext() { if !ld.DynlinkingGo() && ld.Buildmode != ld.BuildmodePIE && ld.Buildmode != ld.BuildmodeCShared { return } thunkfunc := ld.Linklookup(ld.Ctxt, "__x86.get_pc_thunk.cx", 0) thunkfunc.Type = obj.STEXT thunkfunc.Local = true thunkfunc.Reachable = true o := func(op ...uint8) { for _, op1 := range op { ld.Adduint8(ld.Ctxt, thunkfunc, op1) } } // 8b 0c 24 mov (%esp),%ecx o(0x8b, 0x0c, 0x24) // c3 ret o(0xc3) if ld.Ctxt.Etextp != nil { ld.Ctxt.Etextp.Next = thunkfunc } else { ld.Ctxt.Textp = thunkfunc } ld.Ctxt.Etextp = thunkfunc addmoduledata := ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) if addmoduledata.Type == obj.STEXT { // we're linking a module containing the runtime -> no need for // an init function 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 ...uint8) { for _, op1 := range op { ld.Adduint8(ld.Ctxt, initfunc, op1) } } // go.link.addmoduledata: // 53 push %ebx // e8 00 00 00 00 call __x86.get_pc_thunk.cx + R_CALL __x86.get_pc_thunk.cx // 8d 81 00 00 00 00 lea 0x0(%ecx), %eax + R_PCREL ld.Ctxt.Moduledata // 8d 99 00 00 00 00 lea 0x0(%ecx), %ebx + R_GOTPC _GLOBAL_OFFSET_TABLE_ // e8 00 00 00 00 call runtime.addmoduledata@plt + R_CALL runtime.addmoduledata // 5b pop %ebx // c3 ret o(0x53) o(0xe8) addcall(ld.Ctxt, initfunc, ld.Linklookup(ld.Ctxt, "__x86.get_pc_thunk.cx", 0)) o(0x8d, 0x81) ld.Addpcrelplus(ld.Ctxt, initfunc, ld.Ctxt.Moduledata, 6) o(0x8d, 0x99) i := initfunc.Size initfunc.Size += 4 ld.Symgrow(ld.Ctxt, initfunc, initfunc.Size) r := ld.Addrel(initfunc) r.Sym = ld.Linklookup(ld.Ctxt, "_GLOBAL_OFFSET_TABLE_", 0) r.Off = int32(i) r.Type = obj.R_PCREL r.Add = 12 r.Siz = 4 o(0xe8) addcall(ld.Ctxt, initfunc, addmoduledata) o(0x5b) o(0xc3) ld.Ctxt.Etextp.Next = 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) }
func gentext(ctxt *ld.Link) { if !ld.DynlinkingGo() && ld.Buildmode != ld.BuildmodePIE && ld.Buildmode != ld.BuildmodeCShared { return } // Generate little thunks that load the PC of the next instruction into a register. for _, r := range [...]struct { name string num uint8 }{ {"ax", 0}, {"cx", 1}, {"dx", 2}, {"bx", 3}, // sp {"bp", 5}, {"si", 6}, {"di", 7}, } { thunkfunc := ld.Linklookup(ctxt, "__x86.get_pc_thunk."+r.name, 0) thunkfunc.Type = obj.STEXT thunkfunc.Attr |= ld.AttrLocal thunkfunc.Attr |= ld.AttrReachable //TODO: remove? o := func(op ...uint8) { for _, op1 := range op { ld.Adduint8(ctxt, thunkfunc, op1) } } // 8b 04 24 mov (%esp),%eax // Destination register is in bits 3-5 of the middle byte, so add that in. o(0x8b, 0x04+r.num<<3, 0x24) // c3 ret o(0xc3) ctxt.Textp = append(ctxt.Textp, thunkfunc) } addmoduledata := ld.Linklookup(ctxt, "runtime.addmoduledata", 0) if addmoduledata.Type == obj.STEXT { // we're linking a module containing the runtime -> no need for // an init function return } addmoduledata.Attr |= ld.AttrReachable initfunc := ld.Linklookup(ctxt, "go.link.addmoduledata", 0) initfunc.Type = obj.STEXT initfunc.Attr |= ld.AttrLocal initfunc.Attr |= ld.AttrReachable o := func(op ...uint8) { for _, op1 := range op { ld.Adduint8(ctxt, initfunc, op1) } } // go.link.addmoduledata: // 53 push %ebx // e8 00 00 00 00 call __x86.get_pc_thunk.cx + R_CALL __x86.get_pc_thunk.cx // 8d 81 00 00 00 00 lea 0x0(%ecx), %eax + R_PCREL ctxt.Moduledata // 8d 99 00 00 00 00 lea 0x0(%ecx), %ebx + R_GOTPC _GLOBAL_OFFSET_TABLE_ // e8 00 00 00 00 call runtime.addmoduledata@plt + R_CALL runtime.addmoduledata // 5b pop %ebx // c3 ret o(0x53) o(0xe8) addcall(ctxt, initfunc, ld.Linklookup(ctxt, "__x86.get_pc_thunk.cx", 0)) o(0x8d, 0x81) ld.Addpcrelplus(ctxt, initfunc, ctxt.Moduledata, 6) o(0x8d, 0x99) i := initfunc.Size initfunc.Size += 4 ld.Symgrow(ctxt, initfunc, initfunc.Size) r := ld.Addrel(initfunc) r.Sym = ld.Linklookup(ctxt, "_GLOBAL_OFFSET_TABLE_", 0) r.Off = int32(i) r.Type = obj.R_PCREL r.Add = 12 r.Siz = 4 o(0xe8) addcall(ctxt, initfunc, addmoduledata) o(0x5b) o(0xc3) ctxt.Textp = append(ctxt.Textp, initfunc) initarray_entry := ld.Linklookup(ctxt, "go.link.addmoduledatainit", 0) initarray_entry.Attr |= ld.AttrReachable initarray_entry.Attr |= ld.AttrLocal initarray_entry.Type = obj.SINITARR ld.Addaddr(ctxt, initarray_entry, initfunc) }
func addpltsym(ctxt *ld.Link, s *ld.Symbol) { if s.Plt >= 0 { return } ld.Adddynsym(ctxt, s) if ld.Iself { plt := ld.Linklookup(ctxt, ".plt", 0) got := ld.Linklookup(ctxt, ".got", 0) rela := ld.Linklookup(ctxt, ".rela.plt", 0) if plt.Size == 0 { elfsetupplt(ctxt) } // larl %r1,_GLOBAL_OFFSET_TABLE_+index ld.Adduint8(ctxt, plt, 0xc0) ld.Adduint8(ctxt, plt, 0x10) ld.Addpcrelplus(ctxt, plt, got, got.Size+6) // need variant? // add to got: pointer to current pos in plt ld.Addaddrplus(ctxt, got, plt, plt.Size+8) // weird but correct // lg %r1,0(%r1) ld.Adduint8(ctxt, plt, 0xe3) ld.Adduint8(ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0x00) ld.Adduint8(ctxt, plt, 0x00) ld.Adduint8(ctxt, plt, 0x04) // br %r1 ld.Adduint8(ctxt, plt, 0x07) ld.Adduint8(ctxt, plt, 0xf1) // basr %r1,%r0 ld.Adduint8(ctxt, plt, 0x0d) ld.Adduint8(ctxt, plt, 0x10) // lgf %r1,12(%r1) ld.Adduint8(ctxt, plt, 0xe3) ld.Adduint8(ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0x0c) ld.Adduint8(ctxt, plt, 0x00) ld.Adduint8(ctxt, plt, 0x14) // jg .plt ld.Adduint8(ctxt, plt, 0xc0) ld.Adduint8(ctxt, plt, 0xf4) ld.Adduint32(ctxt, plt, uint32(-((plt.Size - 2) >> 1))) // roll-your-own relocation //.plt index ld.Adduint32(ctxt, plt, uint32(rela.Size)) // rela size before current entry // rela ld.Addaddrplus(ctxt, rela, got, got.Size-8) ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_390_JMP_SLOT)) ld.Adduint64(ctxt, rela, 0) s.Plt = int32(plt.Size - 32) } else { ctxt.Diag("addpltsym: unsupported binary format") } }
func elfsetupplt(ctxt *ld.Link) { plt := ld.Linklookup(ctxt, ".plt", 0) got := ld.Linklookup(ctxt, ".got", 0) if plt.Size == 0 { // stg %r1,56(%r15) ld.Adduint8(ctxt, plt, 0xe3) ld.Adduint8(ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0xf0) ld.Adduint8(ctxt, plt, 0x38) ld.Adduint8(ctxt, plt, 0x00) ld.Adduint8(ctxt, plt, 0x24) // larl %r1,_GLOBAL_OFFSET_TABLE_ ld.Adduint8(ctxt, plt, 0xc0) ld.Adduint8(ctxt, plt, 0x10) ld.Addpcrelplus(ctxt, plt, got, 6) // mvc 48(8,%r15),8(%r1) ld.Adduint8(ctxt, plt, 0xd2) ld.Adduint8(ctxt, plt, 0x07) ld.Adduint8(ctxt, plt, 0xf0) ld.Adduint8(ctxt, plt, 0x30) ld.Adduint8(ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0x08) // lg %r1,16(%r1) ld.Adduint8(ctxt, plt, 0xe3) ld.Adduint8(ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0x10) ld.Adduint8(ctxt, plt, 0x00) ld.Adduint8(ctxt, plt, 0x04) // br %r1 ld.Adduint8(ctxt, plt, 0x07) ld.Adduint8(ctxt, plt, 0xf1) // nopr %r0 ld.Adduint8(ctxt, plt, 0x07) ld.Adduint8(ctxt, plt, 0x00) // nopr %r0 ld.Adduint8(ctxt, plt, 0x07) ld.Adduint8(ctxt, plt, 0x00) // nopr %r0 ld.Adduint8(ctxt, plt, 0x07) ld.Adduint8(ctxt, plt, 0x00) // assume got->size == 0 too ld.Addaddrplus(ctxt, got, ld.Linklookup(ctxt, ".dynamic", 0), 0) ld.Adduint64(ctxt, got, 0) ld.Adduint64(ctxt, got, 0) } }
func archinit() { // getgoextlinkenabled is based on GO_EXTLINK_ENABLED when // Go was built; see ../../make.bash. if ld.Linkmode == ld.LinkAuto && obj.Getgoextlinkenabled() == "0" { ld.Linkmode = ld.LinkInternal } switch ld.HEADTYPE { default: if ld.Linkmode == ld.LinkAuto { ld.Linkmode = ld.LinkInternal } if ld.Linkmode == ld.LinkExternal && obj.Getgoextlinkenabled() != "1" { log.Fatalf("cannot use -linkmode=external with -H %s", ld.Headstr(int(ld.HEADTYPE))) } case obj.Hlinux, obj.Hfreebsd, obj.Hnacl, obj.Hdarwin: break } switch ld.HEADTYPE { default: ld.Exitf("unknown -H option: %v", ld.HEADTYPE) case obj.Hplan9: /* plan 9 */ ld.HEADR = 32 if ld.INITTEXT == -1 { ld.INITTEXT = 4128 } if ld.INITDAT == -1 { ld.INITDAT = 0 } if ld.INITRND == -1 { ld.INITRND = 16384 } case obj.Hlinux, /* arm elf */ obj.Hfreebsd, obj.Hnetbsd, obj.Hopenbsd: ld.Debug['d'] = 0 // with dynamic linking ld.Elfinit() ld.HEADR = ld.ELFRESERVE if ld.INITTEXT == -1 { ld.INITTEXT = 0x10000 + int64(ld.HEADR) } if ld.INITDAT == -1 { ld.INITDAT = 0 } if ld.INITRND == -1 { ld.INITRND = 16384 } case obj.Hnacl: ld.Elfinit() ld.HEADR = 0x10000 ld.Funcalign = 16 if ld.INITTEXT == -1 { ld.INITTEXT = 0x20000 } if ld.INITDAT == -1 { ld.INITDAT = 0 } if ld.INITRND == -1 { ld.INITRND = 0x10000 } case obj.Hdarwin: /* apple MACH */ ld.Debug['w'] = 1 // disable DWARF generataion ld.Machoinit() ld.HEADR = ld.INITIAL_MACHO_HEADR if ld.INITTEXT == -1 { ld.INITTEXT = 16384 + int64(ld.HEADR) } if ld.INITDAT == -1 { ld.INITDAT = 0 } if ld.INITRND == -1 { ld.INITRND = 16384 } } if ld.INITDAT != 0 && ld.INITRND != 0 { fmt.Printf("warning: -D0x%x is ignored because of -R0x%x\n", uint64(ld.INITDAT), uint32(ld.INITRND)) } // embed goarm to runtime.goarm s := ld.Linklookup(ld.Ctxt, "runtime.goarm", 0) s.Type = obj.SRODATA ld.Adduint8(ld.Ctxt, s, uint8(ld.Ctxt.Goarm)) }