func gentext() { if !ld.DynlinkingGo() { return } addmoduledata := ld.Linklookup(ld.Ctxt, "runtime.addmoduledata", 0) if addmoduledata.Type == ld.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 = ld.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.Linklookup(ld.Ctxt, "runtime.firstmoduledata", 0), 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 = ld.SINITARR ld.Addaddr(ld.Ctxt, initarray_entry, initfunc) }
func elfreloc1(r *ld.Reloc, sectoff int64) int { ld.Thearch.Vput(uint64(sectoff)) elfsym := r.Xsym.Elfsym switch r.Type { default: return -1 case ld.R_ADDR: if r.Siz == 4 { ld.Thearch.Vput(ld.R_X86_64_32 | uint64(elfsym)<<32) } else if r.Siz == 8 { ld.Thearch.Vput(ld.R_X86_64_64 | uint64(elfsym)<<32) } else { return -1 } case ld.R_TLS_LE: if r.Siz == 4 { ld.Thearch.Vput(ld.R_X86_64_TPOFF32 | uint64(elfsym)<<32) } else { return -1 } case ld.R_TLS_IE: if r.Siz == 4 { ld.Thearch.Vput(ld.R_X86_64_GOTTPOFF | uint64(elfsym)<<32) } else { return -1 } case ld.R_CALL: if r.Siz == 4 { if r.Xsym.Type == ld.SDYNIMPORT { if ld.DynlinkingGo() { ld.Thearch.Vput(ld.R_X86_64_PLT32 | uint64(elfsym)<<32) } else { ld.Thearch.Vput(ld.R_X86_64_GOTPCREL | uint64(elfsym)<<32) } } else { ld.Thearch.Vput(ld.R_X86_64_PC32 | uint64(elfsym)<<32) } } else { return -1 } case ld.R_PCREL: if r.Siz == 4 { ld.Thearch.Vput(ld.R_X86_64_PC32 | uint64(elfsym)<<32) } else { return -1 } case ld.R_GOTPCREL: if r.Siz == 4 { ld.Thearch.Vput(ld.R_X86_64_GOTPCREL | uint64(elfsym)<<32) } else { return -1 } case ld.R_TLS: if r.Siz == 4 { if ld.Buildmode == ld.BuildmodeCShared { ld.Thearch.Vput(ld.R_X86_64_GOTTPOFF | uint64(elfsym)<<32) } else { ld.Thearch.Vput(ld.R_X86_64_TPOFF32 | uint64(elfsym)<<32) } } else { return -1 } } ld.Thearch.Vput(uint64(r.Xadd)) return 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 } if ld.Buildmode == ld.BuildmodeCShared || ld.DynlinkingGo() { ld.Linkmode = ld.LinkExternal } 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 ld.Hdarwin, ld.Hdragonfly, ld.Hfreebsd, ld.Hlinux, ld.Hnacl, ld.Hnetbsd, ld.Hopenbsd, ld.Hsolaris, ld.Hwindows: break } switch ld.HEADTYPE { default: ld.Diag("unknown -H option") ld.Errorexit() fallthrough case ld.Hplan9: /* plan 9 */ ld.HEADR = 32 + 8 if ld.INITTEXT == -1 { ld.INITTEXT = 0x200000 + int64(ld.HEADR) } if ld.INITDAT == -1 { ld.INITDAT = 0 } if ld.INITRND == -1 { ld.INITRND = 0x200000 } case ld.Helf: /* elf32 executable */ ld.HEADR = int32(ld.Rnd(52+3*32, 16)) if ld.INITTEXT == -1 { ld.INITTEXT = 0x80110000 } if ld.INITDAT == -1 { ld.INITDAT = 0 } if ld.INITRND == -1 { ld.INITRND = 4096 } case ld.Hdarwin: /* apple MACH */ ld.Machoinit() ld.HEADR = ld.INITIAL_MACHO_HEADR if ld.INITRND == -1 { ld.INITRND = 4096 } if ld.INITTEXT == -1 { ld.INITTEXT = 4096 + int64(ld.HEADR) } if ld.INITDAT == -1 { ld.INITDAT = 0 } case ld.Hlinux, /* elf64 executable */ ld.Hfreebsd, /* freebsd */ ld.Hnetbsd, /* netbsd */ ld.Hopenbsd, /* openbsd */ ld.Hdragonfly, /* dragonfly */ ld.Hsolaris: /* solaris */ ld.Elfinit() ld.HEADR = ld.ELFRESERVE if ld.INITTEXT == -1 { ld.INITTEXT = (1 << 22) + int64(ld.HEADR) } if ld.INITDAT == -1 { ld.INITDAT = 0 } if ld.INITRND == -1 { ld.INITRND = 4096 } case ld.Hnacl: ld.Elfinit() ld.Debug['w']++ // disable dwarf, which gets confused and is useless anyway ld.HEADR = 0x10000 ld.Funcalign = 32 if ld.INITTEXT == -1 { ld.INITTEXT = 0x20000 } if ld.INITDAT == -1 { ld.INITDAT = 0 } if ld.INITRND == -1 { ld.INITRND = 0x10000 } case ld.Hwindows: /* PE executable */ ld.Peinit() ld.HEADR = ld.PEFILEHEADR if ld.INITTEXT == -1 { ld.INITTEXT = ld.PEBASE + int64(ld.PESECTHEADR) } if ld.INITDAT == -1 { ld.INITDAT = 0 } if ld.INITRND == -1 { ld.INITRND = ld.PESECTALIGN } } 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)) } }