Replace Buildmode with BuildMode and Linkmode with LinkMode.
For #22095
Change-Id: I51a6f5719d107727bca29ec8e68e3e9d87e31e33
Reviewed-on: https://go-review.googlesource.com/68334
Run-TryBot: David Crawshaw <crawshaw@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
return
}
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
- if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin {
+ if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
// we're linking a module containing the runtime -> no need for
// an init function
return
Addcall(ctxt, initfunc, addmoduledata)
// c: c3 retq
o(0xc3)
- if ld.Buildmode == ld.BuildmodePlugin {
+ if ctxt.BuildMode == ld.BuildModePlugin {
ctxt.Textp = append(ctxt.Textp, addmoduledata)
}
ctxt.Textp = append(ctxt.Textp, initfunc)
}
// Process dynamic relocations for the data sections.
- if ld.Buildmode == ld.BuildmodePIE && ld.Linkmode == ld.LinkInternal {
+ if ctxt.BuildMode == ld.BuildModePIE && ctxt.LinkMode == ld.LinkInternal {
// When internally linking, generate dynamic relocations
// for all typical R_ADDR relocations. The exception
// are those R_ADDR that are created as part of generating
ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
}
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt)
}
}
}
case objabi.Hdarwin:
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
ld.Machoemitreloc(ctxt)
}
}
return
}
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
- if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin {
+ if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
// we're linking a module containing the runtime -> no need for
// an init function
return
rel.Type = objabi.R_PCREL
rel.Add = 4
- if ld.Buildmode == ld.BuildmodePlugin {
+ if ctxt.BuildMode == ld.BuildModePlugin {
ctxt.Textp = append(ctxt.Textp, addmoduledata)
}
ctxt.Textp = append(ctxt.Textp, initfunc)
ld.Errorf(s, "odd offset in dynlink direct call: %v+%d", r.Sym, offset)
}
gentrampdyn(ctxt.Arch, tramp, r.Sym, int64(offset))
- } else if ld.Buildmode == ld.BuildmodeCArchive || ld.Buildmode == ld.BuildmodeCShared || ld.Buildmode == ld.BuildmodePIE {
+ } else if ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE {
gentramppic(ctxt.Arch, tramp, r.Sym, int64(offset))
} else {
- gentramp(ctxt.Arch, tramp, r.Sym, int64(offset))
+ gentramp(ctxt.Arch, ctxt.LinkMode, tramp, r.Sym, int64(offset))
}
}
// modify reloc to point to tramp, which will be resolved later
}
// generate a trampoline to target+offset
-func gentramp(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
+func gentramp(arch *sys.Arch, linkmode ld.LinkMode, tramp, target *sym.Symbol, offset int64) {
tramp.Size = 12 // 3 instructions
tramp.P = make([]byte, tramp.Size)
t := ld.Symaddr(target) + int64(offset)
arch.ByteOrder.PutUint32(tramp.P[4:], o2)
arch.ByteOrder.PutUint32(tramp.P[8:], o3)
- if ld.Linkmode == ld.LinkExternal {
+ if linkmode == ld.LinkExternal {
r := tramp.AddRel()
r.Off = 8
r.Type = objabi.R_ADDR
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
switch r.Type {
case objabi.R_CALLARM:
r.Done = false
ctxt.Out.Flush()
ctxt.Out.Write(ld.Elfstrdat)
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt)
}
}
}
case objabi.Hdarwin:
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
ld.Machoemitreloc(ctxt)
}
}
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
switch r.Type {
default:
return false
ctxt.Out.Flush()
ctxt.Out.Write(ld.Elfstrdat)
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt)
}
}
}
case objabi.Hdarwin:
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
ld.Machoemitreloc(ctxt)
}
}
"log"
)
-var (
- Linkmode LinkMode
- Buildmode BuildMode
-)
-
// A BuildMode indicates the sort of object we are building.
//
// Possible build modes are the same as those for the -buildmode flag
type BuildMode uint8
const (
- BuildmodeUnset BuildMode = iota
- BuildmodeExe
- BuildmodePIE
- BuildmodeCArchive
- BuildmodeCShared
- BuildmodeShared
- BuildmodePlugin
+ BuildModeUnset BuildMode = iota
+ BuildModeExe
+ BuildModePIE
+ BuildModeCArchive
+ BuildModeCShared
+ BuildModeShared
+ BuildModePlugin
)
func (mode *BuildMode) Set(s string) error {
default:
return fmt.Errorf("invalid buildmode: %q", s)
case "exe":
- *mode = BuildmodeExe
+ *mode = BuildModeExe
case "pie":
switch objabi.GOOS {
case "android", "linux":
default:
return badmode()
}
- *mode = BuildmodePIE
+ *mode = BuildModePIE
case "c-archive":
switch objabi.GOOS {
case "darwin", "linux":
default:
return badmode()
}
- *mode = BuildmodeCArchive
+ *mode = BuildModeCArchive
case "c-shared":
switch objabi.GOARCH {
case "386", "amd64", "arm", "arm64", "ppc64le":
default:
return badmode()
}
- *mode = BuildmodeCShared
+ *mode = BuildModeCShared
case "shared":
switch objabi.GOOS {
case "linux":
default:
return badmode()
}
- *mode = BuildmodeShared
+ *mode = BuildModeShared
case "plugin":
switch objabi.GOOS {
case "linux":
default:
return badmode()
}
- *mode = BuildmodePlugin
+ *mode = BuildModePlugin
}
return nil
}
func (mode *BuildMode) String() string {
switch *mode {
- case BuildmodeUnset:
+ case BuildModeUnset:
return "" // avoid showing a default in usage message
- case BuildmodeExe:
+ case BuildModeExe:
return "exe"
- case BuildmodePIE:
+ case BuildModePIE:
return "pie"
- case BuildmodeCArchive:
+ case BuildModeCArchive:
return "c-archive"
- case BuildmodeCShared:
+ case BuildModeCShared:
return "c-shared"
- case BuildmodeShared:
+ case BuildModeShared:
return "shared"
- case BuildmodePlugin:
+ case BuildModePlugin:
return "plugin"
}
return fmt.Sprintf("BuildMode(%d)", uint8(*mode))
}
// Some build modes require work the internal linker cannot do (yet).
- switch Buildmode {
- case BuildmodeCArchive:
+ switch ctxt.BuildMode {
+ case BuildModeCArchive:
return true, "buildmode=c-archive"
- case BuildmodeCShared:
+ case BuildModeCShared:
return true, "buildmode=c-shared"
- case BuildmodePIE:
+ case BuildModePIE:
switch objabi.GOOS + "/" + objabi.GOARCH {
case "linux/amd64":
default:
// Internal linking does not support TLS_IE.
return true, "buildmode=pie"
}
- case BuildmodePlugin:
+ case BuildModePlugin:
return true, "buildmode=plugin"
- case BuildmodeShared:
+ case BuildModeShared:
return true, "buildmode=shared"
}
if *FlagLinkshared {
return false, ""
}
-// determineLinkMode sets Linkmode.
+// determineLinkMode sets ctxt.LinkMode.
//
// It is called after flags are processed and inputs are processed,
-// so the Linkmode variable has an initial value from the -linkmode
+// so the ctxt.LinkMode variable has an initial value from the -linkmode
// flag and the iscgo externalobj variables are set.
func determineLinkMode(ctxt *Link) {
- switch Linkmode {
+ switch ctxt.LinkMode {
case LinkAuto:
// The environment variable GO_EXTLINK_ENABLED controls the
// default value of -linkmode. If it is not set when the
if needed, reason := mustLinkExternal(ctxt); needed {
Exitf("internal linking requested via GO_EXTLINK_ENABLED, but external linking required: %s", reason)
}
- Linkmode = LinkInternal
+ ctxt.LinkMode = LinkInternal
case "1":
- Linkmode = LinkExternal
+ ctxt.LinkMode = LinkExternal
default:
if needed, _ := mustLinkExternal(ctxt); needed {
- Linkmode = LinkExternal
+ ctxt.LinkMode = LinkExternal
} else if iscgo && externalobj {
- Linkmode = LinkExternal
- } else if Buildmode == BuildmodePIE {
- Linkmode = LinkExternal // https://golang.org/issue/18968
+ ctxt.LinkMode = LinkExternal
+ } else if ctxt.BuildMode == BuildModePIE {
+ ctxt.LinkMode = LinkExternal // https://golang.org/issue/18968
} else {
- Linkmode = LinkInternal
+ ctxt.LinkMode = LinkInternal
}
}
case LinkInternal:
if r.Sym != nil && (r.Sym.Type&(sym.SMASK|sym.SHIDDEN) == 0 || r.Sym.Type&sym.SMASK == sym.SXREF) {
// When putting the runtime but not main into a shared library
// these symbols are undefined and that's OK.
- if Buildmode == BuildmodeShared {
+ if ctxt.BuildMode == BuildModeShared {
if r.Sym.Name == "main.main" || r.Sym.Name == "main.init" {
r.Sym.Type = sym.SDYNIMPORT
} else if strings.HasPrefix(r.Sym.Name, "go.info.") {
// We need to be able to reference dynimport symbols when linking against
// shared libraries, and Solaris needs it always
if Headtype != objabi.Hsolaris && r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT && !ctxt.DynlinkingGo() {
- if !(ctxt.Arch.Family == sys.PPC64 && Linkmode == LinkExternal && r.Sym.Name == ".TOC.") {
+ if !(ctxt.Arch.Family == sys.PPC64 && ctxt.LinkMode == LinkExternal && r.Sym.Name == ".TOC.") {
Errorf(s, "unhandled relocation for %s (type %d (%s) rtype %d (%s))", r.Sym.Name, r.Sym.Type, r.Sym.Type, r.Type, sym.RelocName(ctxt.Arch, r.Type))
}
}
case objabi.R_TLS_LE:
isAndroidX86 := objabi.GOOS == "android" && (ctxt.Arch.InFamily(sys.AMD64, sys.I386))
- if Linkmode == LinkExternal && Iself && !isAndroidX86 {
+ if ctxt.LinkMode == LinkExternal && Iself && !isAndroidX86 {
r.Done = false
if r.Sym == nil {
r.Sym = ctxt.Tlsg
case objabi.R_TLS_IE:
isAndroidX86 := objabi.GOOS == "android" && (ctxt.Arch.InFamily(sys.AMD64, sys.I386))
- if Linkmode == LinkExternal && Iself && !isAndroidX86 {
+ if ctxt.LinkMode == LinkExternal && Iself && !isAndroidX86 {
r.Done = false
if r.Sym == nil {
r.Sym = ctxt.Tlsg
}
break
}
- if Buildmode == BuildmodePIE && Iself {
+ if ctxt.BuildMode == BuildModePIE && Iself {
// We are linking the final executable, so we
// can optimize any TLS IE relocation to LE.
if Thearch.TLSIEtoLE == nil {
log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", s.Name)
}
case objabi.R_ADDR:
- if Linkmode == LinkExternal && r.Sym.Type != sym.SCONST {
+ if ctxt.LinkMode == LinkExternal && r.Sym.Type != sym.SCONST {
r.Done = false
// set up addend for eventual relocation via outer symbol.
Errorf(s, "missing DWARF section for relocation target %s", r.Sym.Name)
}
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
r.Done = false
// PE code emits IMAGE_REL_I386_SECREL and IMAGE_REL_AMD64_SECREL
// for R_DWARFREF relocations, while R_ADDR is replaced with
}
fallthrough
case objabi.R_CALL, objabi.R_PCREL:
- if Linkmode == LinkExternal && r.Sym != nil && r.Sym.Type != sym.SCONST && (r.Sym.Sect != s.Sect || r.Type == objabi.R_GOTPCREL) {
+ if ctxt.LinkMode == LinkExternal && r.Sym != nil && r.Sym.Type != sym.SCONST && (r.Sym.Sect != s.Sect || r.Type == objabi.R_GOTPCREL) {
r.Done = false
// set up addend for eventual relocation via outer symbol.
func dynrelocsym(ctxt *Link, s *sym.Symbol) {
if Headtype == objabi.Hwindows {
- if Linkmode == LinkInternal {
+ if ctxt.LinkMode == LinkInternal {
windynrelocsym(ctxt, s)
}
return
for ri := 0; ri < len(s.R); ri++ {
r := &s.R[ri]
- if Buildmode == BuildmodePIE && Linkmode == LinkInternal {
+ if ctxt.BuildMode == BuildModePIE && ctxt.LinkMode == LinkInternal {
// It's expected that some relocations will be done
// later by relocsym (R_TLS_LE, R_ADDROFF), so
// don't worry if Adddynrel returns false.
}
ctxt.Logf("\n")
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
continue
}
for _, r := range sym.R {
Exitf("-X flag requires argument of the form importpath.name=value")
}
pkg := objabi.PathToPrefix(arg[:dot])
- if Buildmode == BuildmodePlugin && pkg == "main" {
+ if ctxt.BuildMode == BuildModePlugin && pkg == "main" {
pkg = *flagPluginPath
}
addstrdata(ctxt, pkg+arg[dot:eq], arg[eq+1:])
}
func dosymtype(ctxt *Link) {
- switch Buildmode {
- case BuildmodeCArchive, BuildmodeCShared:
+ switch ctxt.BuildMode {
+ case BuildModeCArchive, BuildModeCShared:
for _, s := range ctxt.Syms.Allsym {
// Create a new entry in the .init_array section that points to the
// library initializer function.
}
dynreloc(ctxt, &data)
- if UseRelro() {
+ if ctxt.UseRelro() {
// "read only" data with relocations needs to go in its own section
// when building a shared library. We do this by boosting objects of
// type SXXX with relocations to type SXXXRELRO.
hasinitarr := *FlagLinkshared
/* shared library initializer */
- switch Buildmode {
- case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared, BuildmodePlugin:
+ switch ctxt.BuildMode {
+ case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
hasinitarr = true
}
if hasinitarr {
if len(data[sym.STLSBSS]) > 0 {
var sect *sym.Section
- if Iself && (Linkmode == LinkExternal || !*FlagD) {
+ if Iself && (ctxt.LinkMode == LinkExternal || !*FlagD) {
sect = addsection(ctxt.Arch, &Segdata, ".tbss", 06)
sect.Align = int32(ctxt.Arch.PtrSize)
sect.Vaddr = 0
* segtext.
*/
var segro *sym.Segment
- if Iself && Linkmode == LinkInternal {
+ if Iself && ctxt.LinkMode == LinkInternal {
segro = &Segrodata
} else {
segro = &Segtext
sect.Vaddr = 0
ctxt.Syms.Lookup("runtime.rodata", 0).Sect = sect
ctxt.Syms.Lookup("runtime.erodata", 0).Sect = sect
- if !UseRelro() {
+ if !ctxt.UseRelro() {
ctxt.Syms.Lookup("runtime.types", 0).Sect = sect
ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect
}
return addsection(ctxt.Arch, segro, suffix, 04)
}
- if UseRelro() {
+ if ctxt.UseRelro() {
addrelrosection = func(suffix string) *sym.Section {
seg := &Segrelrodata
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
// Using a separate segment with an external
// linker results in some programs moving
// their data sections unexpectedly, which
// at the very beginning of the text segment.
// This ``header'' is read by cmd/go.
func (ctxt *Link) textbuildid() {
- if Iself || Buildmode == BuildmodePlugin || *flagBuildid == "" {
+ if Iself || ctxt.BuildMode == BuildModePlugin || *flagBuildid == "" {
return
}
// Only break at outermost syms.
- if ctxt.Arch.InFamily(sys.PPC64) && s.Outer == nil && Iself && Linkmode == LinkExternal && va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(s, isTramp) > 0x1c00000 {
+ if ctxt.Arch.InFamily(sys.PPC64) && s.Outer == nil && Iself && ctxt.LinkMode == LinkExternal && va-sect.Vaddr+funcsize+maxSizeTrampolinesPPC64(s, isTramp) > 0x1c00000 {
// Set the length for the previous text section
sect.Length = va - sect.Vaddr
}
}
- if Buildmode == BuildmodeShared {
+ if ctxt.BuildMode == BuildModeShared {
s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
sectSym := ctxt.Syms.Lookup(".note.go.abihash", 0)
s.Sect = sectSym.Sect
}
}
- if Buildmode != BuildmodeShared {
+ if ctxt.BuildMode != BuildModeShared {
// Keep a itablink if the symbol it points at is being kept.
- // (When BuildmodeShared, always keep itablinks.)
+ // (When BuildModeShared, always keep itablinks.)
for _, s := range ctxt.Syms.Allsym {
if strings.HasPrefix(s.Name, "go.itablink.") {
s.Attr.Set(sym.AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable())
names = append(names, "runtime.read_tls_fallback")
}
- if Buildmode == BuildmodeShared {
+ if d.ctxt.BuildMode == BuildModeShared {
// Mark all symbols defined in this library as reachable when
// building a shared library.
for _, s := range d.ctxt.Syms.Allsym {
// In a normal binary, start at main.main and the init
// functions and mark what is reachable from there.
- if *FlagLinkshared && (Buildmode == BuildmodeExe || Buildmode == BuildmodePIE) {
+ if *FlagLinkshared && (d.ctxt.BuildMode == BuildModeExe || d.ctxt.BuildMode == BuildModePIE) {
names = append(names, "main.main", "main.init")
} else {
// The external linker refers main symbol directly.
- if Linkmode == LinkExternal && (Buildmode == BuildmodeExe || Buildmode == BuildmodePIE) {
+ if d.ctxt.LinkMode == LinkExternal && (d.ctxt.BuildMode == BuildModeExe || d.ctxt.BuildMode == BuildModePIE) {
if Headtype == objabi.Hwindows && d.ctxt.Arch.Family == sys.I386 {
*flagEntrySymbol = "_main"
} else {
}
}
names = append(names, *flagEntrySymbol)
- if Buildmode == BuildmodePlugin {
+ if d.ctxt.BuildMode == BuildModePlugin {
names = append(names, *flagPluginPath+".init", *flagPluginPath+".main", "go.plugin.tabs")
// We don't keep the go.plugin.exports symbol,
dsym.Type = sym.SDWARFINFO
for _, r := range dsym.R {
if r.Type == objabi.R_DWARFREF && r.Sym.Size == 0 {
- if Buildmode == BuildmodeShared {
- // These type symbols may not be present in BuildmodeShared. Skip.
+ if ctxt.BuildMode == BuildModeShared {
+ // These type symbols may not be present in BuildModeShared. Skip.
continue
}
n := nameFromDIESym(r.Sym)
// ptrsize: initial location
// ptrsize: address range
fs.AddUint32(ctxt.Arch, uint32(4+2*ctxt.Arch.PtrSize+len(deltaBuf))) // length (excludes itself)
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
adddwarfref(ctxt, fs, fs, 4)
} else {
fs.AddUint32(ctxt.Arch, 0) // CIE offset
}
func writegdbscript(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
- if Linkmode == LinkExternal && Headtype == objabi.Hwindows && Buildmode == BuildmodeCArchive {
+ if ctxt.LinkMode == LinkExternal && Headtype == objabi.Hwindows && ctxt.BuildMode == BuildModeCArchive {
// gcc on Windows places .debug_gdb_scripts in the wrong location, which
// causes the program not to run. See https://golang.org/issue/20183
// Non c-archives can avoid this issue via a linker script
return
}
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
switch {
case Iself:
case Headtype == objabi.Hdarwin:
Addstring(shstrtab, ".debug_pubtypes")
Addstring(shstrtab, ".debug_gdb_scripts")
Addstring(shstrtab, ".debug_ranges")
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
Addstring(shstrtab, elfRelType+".debug_info")
Addstring(shstrtab, elfRelType+".debug_loc")
Addstring(shstrtab, elfRelType+".debug_aranges")
if *FlagW { // disable dwarf
return
}
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
return
}
s := ctxt.Syms.Lookup(".debug_info", 0)
return sh
}
-func elfshbits(sect *sym.Section) *ElfShdr {
+func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr {
var sh *ElfShdr
if sect.Name == ".text" {
// If this section has already been set up as a note, we assume type_ and
// flags are already correct, but the other fields still need filling in.
if sh.type_ == SHT_NOTE {
- if Linkmode != LinkExternal {
+ if linkmode != LinkExternal {
// TODO(mwhudson): the approach here will work OK when
// linking internally for notes that we want to be included
// in a loadable segment (e.g. the abihash note) but not for
sh.flags = 0
}
- if Linkmode != LinkExternal {
+ if linkmode != LinkExternal {
sh.addr = sect.Vaddr
}
sh.addralign = uint64(sect.Align)
// 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 || Linkmode == LinkExternal {
+ if !*FlagD || ctxt.LinkMode == LinkExternal {
Addstring(shstrtab, ".tbss")
}
if Headtype == objabi.Hnetbsd {
Addstring(shstrtab, ".rodata")
// See the comment about data.rel.ro.FOO section names in data.go.
relro_prefix := ""
- if UseRelro() {
+ if ctxt.UseRelro() {
Addstring(shstrtab, ".data.rel.ro")
relro_prefix = ".data.rel.ro"
}
Addstring(shstrtab, relro_prefix+".gosymtab")
Addstring(shstrtab, relro_prefix+".gopclntab")
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
*FlagD = true
Addstring(shstrtab, elfRelType+".text")
Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab")
Addstring(shstrtab, elfRelType+".noptrdata")
Addstring(shstrtab, elfRelType+".data")
- if UseRelro() {
+ if ctxt.UseRelro() {
Addstring(shstrtab, elfRelType+".data.rel.ro")
}
// add a .note.GNU-stack section to mark the stack as non-executable
Addstring(shstrtab, ".note.GNU-stack")
- if Buildmode == BuildmodeShared {
+ if ctxt.BuildMode == BuildModeShared {
Addstring(shstrtab, ".note.go.abihash")
Addstring(shstrtab, ".note.go.pkg-list")
Addstring(shstrtab, ".note.go.deps")
hasinitarr := *FlagLinkshared
/* shared library initializer */
- switch Buildmode {
- case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared, BuildmodePlugin:
+ switch ctxt.BuildMode {
+ case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
hasinitarr = true
}
Elfwritedynent(ctxt, s, DT_DEBUG, 0)
}
- if Buildmode == BuildmodeShared {
+ if ctxt.BuildMode == BuildModeShared {
// 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)
addgonote(ctxt, ".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n")))
}
- if Linkmode == LinkExternal && *flagBuildid != "" {
+ if ctxt.LinkMode == LinkExternal && *flagBuildid != "" {
addgonote(ctxt, ".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(*flagBuildid))
}
}
var pph *ElfPhdr
var pnote *ElfPhdr
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
/* skip program headers */
eh.phoff = 0
eh.phentsize = 0
- if Buildmode == BuildmodeShared {
+ if ctxt.BuildMode == BuildModeShared {
sh := elfshname(".note.go.pkg-list")
sh.type_ = SHT_NOTE
sh = elfshname(".note.go.abihash")
}
for _, sect := range Segtext.Sections {
- elfshbits(sect)
+ elfshbits(ctxt.LinkMode, sect)
}
for _, sect := range Segrodata.Sections {
- elfshbits(sect)
+ elfshbits(ctxt.LinkMode, sect)
}
for _, sect := range Segrelrodata.Sections {
- elfshbits(sect)
+ elfshbits(ctxt.LinkMode, sect)
}
for _, sect := range Segdata.Sections {
- elfshbits(sect)
+ elfshbits(ctxt.LinkMode, sect)
}
for _, sect := range Segdwarf.Sections {
- elfshbits(sect)
+ elfshbits(ctxt.LinkMode, sect)
}
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
for _, sect := range Segtext.Sections {
elfshreloc(ctxt.Arch, sect)
}
}
eh.ident[EI_VERSION] = EV_CURRENT
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
eh.type_ = ET_REL
- } else if Buildmode == BuildmodePIE {
+ } else if ctxt.BuildMode == BuildModePIE {
eh.type_ = ET_DYN
} else {
eh.type_ = ET_EXEC
}
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
eh.entry = uint64(Entryvalue(ctxt))
}
if !*FlagD {
a += int64(elfwriteinterp(ctxt.Out))
}
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
if Headtype == objabi.Hnetbsd {
a += int64(elfwritenetbsdsig(ctxt.Out))
}
havedynamic = 1
if Headtype == objabi.Hdarwin {
- machoadddynlib(lib)
+ machoadddynlib(lib, ctxt.LinkMode)
} else {
dynlib = append(dynlib, lib)
}
local = expandpkg(local, pkg)
s = ctxt.Syms.Lookup(local, 0)
- switch Buildmode {
- case BuildmodeCShared, BuildmodeCArchive, BuildmodePlugin:
+ switch ctxt.BuildMode {
+ case BuildModeCShared, BuildModeCArchive, BuildModePlugin:
if s == ctxt.Syms.Lookup("main", 0) {
continue
}
var seenlib = make(map[string]bool)
func adddynlib(ctxt *Link, lib string) {
- if seenlib[lib] || Linkmode == LinkExternal {
+ if seenlib[lib] || ctxt.LinkMode == LinkExternal {
return
}
seenlib[lib] = true
}
func Adddynsym(ctxt *Link, s *sym.Symbol) {
- if s.Dynid >= 0 || Linkmode == LinkExternal {
+ if s.Dynid >= 0 || ctxt.LinkMode == LinkExternal {
return
}
if !ctxt.Loaded {
panic("DynlinkingGo called before all symbols loaded")
}
- return Buildmode == BuildmodeShared || *FlagLinkshared || Buildmode == BuildmodePlugin || ctxt.CanUsePlugins()
+ return ctxt.BuildMode == BuildModeShared || *FlagLinkshared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins()
}
// CanUsePlugins returns whether a plugins can be used
// UseRelro returns whether to make use of "read only relocations" aka
// relro.
-func UseRelro() bool {
- switch Buildmode {
- case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared, BuildmodePIE, BuildmodePlugin:
+func (ctxt *Link) UseRelro() bool {
+ switch ctxt.BuildMode {
+ case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePIE, BuildModePlugin:
return Iself
default:
return *FlagLinkshared
ctxt.Out.f = f
if *flagEntrySymbol == "" {
- switch Buildmode {
- case BuildmodeCShared, BuildmodeCArchive:
+ switch ctxt.BuildMode {
+ case BuildModeCShared, BuildModeCArchive:
*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s_lib", objabi.GOARCH, objabi.GOOS)
- case BuildmodeExe, BuildmodePIE:
+ case BuildModeExe, BuildModePIE:
*flagEntrySymbol = fmt.Sprintf("_rt0_%s_%s", objabi.GOARCH, objabi.GOOS)
- case BuildmodeShared, BuildmodePlugin:
+ case BuildModeShared, BuildModePlugin:
// No *flagEntrySymbol for -buildmode=shared and plugin
default:
- Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", Buildmode)
+ Errorf(nil, "unknown *flagEntrySymbol for buildmode %v", ctxt.BuildMode)
}
}
}
}
func (ctxt *Link) loadlib() {
- switch Buildmode {
- case BuildmodeCShared, BuildmodePlugin:
+ switch ctxt.BuildMode {
+ case BuildModeCShared, BuildModePlugin:
s := ctxt.Syms.Lookup("runtime.islibrary", 0)
s.Attr |= sym.AttrDuplicateOK
s.AddUint8(1)
- case BuildmodeCArchive:
+ case BuildModeCArchive:
s := ctxt.Syms.Lookup("runtime.isarchive", 0)
s.Attr |= sym.AttrDuplicateOK
s.AddUint8(1)
// We now have enough information to determine the link mode.
determineLinkMode(ctxt)
- // Recalculate pe parameters now that we have Linkmode set.
+ // Recalculate pe parameters now that we have ctxt.LinkMode set.
if Headtype == objabi.Hwindows {
Peinit(ctxt)
}
- if Headtype == objabi.Hdarwin && Linkmode == LinkExternal {
+ if Headtype == objabi.Hdarwin && ctxt.LinkMode == LinkExternal {
*FlagTextAddr = 0
}
- if Linkmode == LinkExternal && ctxt.Arch.Family == sys.PPC64 {
+ if ctxt.LinkMode == LinkExternal && ctxt.Arch.Family == sys.PPC64 {
toc := ctxt.Syms.Lookup(".TOC.", 0)
toc.Type = sym.SDYNIMPORT
}
- if Linkmode == LinkExternal && !iscgo && ctxt.LibraryByPkg["runtime/cgo"] == nil {
+ if ctxt.LinkMode == LinkExternal && !iscgo && ctxt.LibraryByPkg["runtime/cgo"] == nil {
// This indicates a user requested -linkmode=external.
// The startup code uses an import of runtime/cgo to decide
// whether to initialize the TLS. So give it one. This could
if lib.Shlib != "" {
ldshlibsyms(ctxt, lib.Shlib)
} else {
- if Buildmode == BuildmodeShared || *FlagLinkshared {
+ if ctxt.BuildMode == BuildModeShared || *FlagLinkshared {
Exitf("cannot implicitly include runtime/cgo in a shared library")
}
loadobjfile(ctxt, lib)
}
}
- if Linkmode == LinkInternal {
+ if ctxt.LinkMode == LinkInternal {
// Drop all the cgo_import_static declarations.
// Turns out we won't be needing them.
for _, s := range ctxt.Syms.Allsym {
ctxt.Tlsg = tlsg
var moduledata *sym.Symbol
- if Buildmode == BuildmodePlugin {
+ if ctxt.BuildMode == BuildModePlugin {
moduledata = ctxt.Syms.Lookup("local.pluginmoduledata", 0)
moduledata.Attr |= sym.AttrLocal
} else {
// Now that we know the link mode, trim the dynexp list.
x := sym.AttrCgoExportDynamic
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
x = sym.AttrCgoExportStatic
}
w := 0
dynexp = dynexp[:w]
// In internal link mode, read the host object files.
- if Linkmode == LinkInternal {
+ if ctxt.LinkMode == LinkInternal {
hostobjs(ctxt)
// If we have any undefined symbols in external
// binaries, so leave it enabled on OS X (Mach-O) binaries.
// Also leave it enabled on Solaris which doesn't support
// statically linked binaries.
- if Buildmode == BuildmodeExe {
+ if ctxt.BuildMode == BuildModeExe {
if havedynamic == 0 && Headtype != objabi.Hdarwin && Headtype != objabi.Hsolaris {
*FlagD = true
}
// Leave type.runtime. symbols alone, because other parts of
// the linker manipulates them, and also symbols whose names
// would not be shortened by this process.
- if typeSymbolMangling(ctxt.Syms) {
+ if typeSymbolMangling(ctxt) {
*FlagW = true // disable DWARF generation
for _, s := range ctxt.Syms.Allsym {
newName := typeSymbolMangle(ctxt.Syms, s.Name)
// If package versioning is required, generate a hash of the
// the packages used in the link.
- if Buildmode == BuildmodeShared || Buildmode == BuildmodePlugin || ctxt.CanUsePlugins() {
+ if ctxt.BuildMode == BuildModeShared || ctxt.BuildMode == BuildModePlugin || ctxt.CanUsePlugins() {
for _, lib := range ctxt.Library {
if lib.Shlib == "" {
genhash(ctxt, lib)
}
if ctxt.Arch == sys.Arch386 {
- if (Buildmode == BuildmodeCArchive && Iself) || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE || ctxt.DynlinkingGo() {
+ if (ctxt.BuildMode == BuildModeCArchive && Iself) || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE || ctxt.DynlinkingGo() {
got := ctxt.Syms.Lookup("_GLOBAL_OFFSET_TABLE_", 0)
got.Type = sym.SDYNIMPORT
got.Attr |= sym.AttrReachable
// packages. All Go binaries contain these symbols, but only only
// those programs loaded dynamically in multiple parts need these
// symbols to have entries in the symbol table.
-func typeSymbolMangling(syms *sym.Symbols) bool {
- return Buildmode == BuildmodeShared || *FlagLinkshared || Buildmode == BuildmodePlugin || syms.ROLookup("plugin.Open", 0) != nil
+func typeSymbolMangling(ctxt *Link) bool {
+ return ctxt.BuildMode == BuildModeShared || *FlagLinkshared || ctxt.BuildMode == BuildModePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil
}
// typeSymbolMangle mangles the given symbol name into something shorter.
func typeSymbolMangle(syms *sym.Symbols, name string) string {
- if !typeSymbolMangling(syms) {
- return name
- }
if !strings.HasPrefix(name, "type.") {
return name
}
}
func hostlinksetup(ctxt *Link) {
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
return
}
// archive builds a .a archive from the hostobj object files.
func (ctxt *Link) archive() {
- if Buildmode != BuildmodeCArchive {
+ if ctxt.BuildMode != BuildModeCArchive {
return
}
}
}
-func (l *Link) hostlink() {
- if Linkmode != LinkExternal || nerrors > 0 {
+func (ctxt *Link) hostlink() {
+ if ctxt.LinkMode != LinkExternal || nerrors > 0 {
return
}
- if Buildmode == BuildmodeCArchive {
+ if ctxt.BuildMode == BuildModeCArchive {
return
}
var argv []string
argv = append(argv, *flagExtld)
- argv = append(argv, hostlinkArchArgs(l.Arch)...)
+ argv = append(argv, hostlinkArchArgs(ctxt.Arch)...)
if !*FlagS && !debug_s {
argv = append(argv, "-gdwarf-2")
switch Headtype {
case objabi.Hdarwin:
argv = append(argv, "-Wl,-headerpad,1144")
- if l.DynlinkingGo() {
+ if ctxt.DynlinkingGo() {
argv = append(argv, "-Wl,-flat_namespace")
}
- if Buildmode == BuildmodeExe && !l.Arch.InFamily(sys.ARM64) {
+ if ctxt.BuildMode == BuildModeExe && !ctxt.Arch.InFamily(sys.ARM64) {
argv = append(argv, "-Wl,-no_pie")
}
case objabi.Hopenbsd:
}
}
- switch Buildmode {
- case BuildmodeExe:
+ switch ctxt.BuildMode {
+ case BuildModeExe:
if Headtype == objabi.Hdarwin {
argv = append(argv, "-Wl,-pagezero_size,4000000")
}
- case BuildmodePIE:
+ case BuildModePIE:
// ELF.
if Headtype != objabi.Hdarwin {
- if UseRelro() {
+ if ctxt.UseRelro() {
argv = append(argv, "-Wl,-z,relro")
}
argv = append(argv, "-pie")
}
- case BuildmodeCShared:
+ case BuildModeCShared:
if Headtype == objabi.Hdarwin {
argv = append(argv, "-dynamiclib")
- if l.Arch.Family != sys.AMD64 {
+ if ctxt.Arch.Family != sys.AMD64 {
argv = append(argv, "-Wl,-read_only_relocs,suppress")
}
} else {
// ELF.
argv = append(argv, "-Wl,-Bsymbolic")
- if UseRelro() {
+ if ctxt.UseRelro() {
argv = append(argv, "-Wl,-z,relro")
}
// Pass -z nodelete to mark the shared library as
// non-closeable: a dlclose will do nothing.
argv = append(argv, "-shared", "-Wl,-z,nodelete")
}
- case BuildmodeShared:
- if UseRelro() {
+ case BuildModeShared:
+ if ctxt.UseRelro() {
argv = append(argv, "-Wl,-z,relro")
}
argv = append(argv, "-shared")
- case BuildmodePlugin:
+ case BuildModePlugin:
if Headtype == objabi.Hdarwin {
argv = append(argv, "-dynamiclib")
} else {
- if UseRelro() {
+ if ctxt.UseRelro() {
argv = append(argv, "-Wl,-z,relro")
}
argv = append(argv, "-shared")
}
}
- if Iself && l.DynlinkingGo() {
+ if Iself && ctxt.DynlinkingGo() {
// We force all symbol resolution to be done at program startup
// because lazy PLT resolution can use large amounts of stack at
// times we cannot allow it to do so.
// from the beginning of the section (like sym.STYPE).
argv = append(argv, "-Wl,-znocopyreloc")
- if l.Arch.InFamily(sys.ARM, sys.ARM64) {
+ if ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
// On ARM, the GNU linker will generate COPY relocations
// even with -znocopyreloc set.
// https://sourceware.org/bugzilla/show_bug.cgi?id=19962
seenLibs[base] = true
}
}
- for _, shlib := range l.Shlibs {
+ for _, shlib := range ctxt.Shlibs {
addshlib(shlib.Path)
for _, dep := range shlib.Deps {
if dep == "" {
continue
}
- libpath := findshlib(l, dep)
+ libpath := findshlib(ctxt, dep)
if libpath != "" {
addshlib(libpath)
}
// does not work, the resulting programs will not run. See
// issue #17847. To avoid this problem pass -no-pie to the
// toolchain if it is supported.
- if Buildmode == BuildmodeExe {
+ if ctxt.BuildMode == BuildModeExe {
src := filepath.Join(*flagTmpdir, "trivial.c")
if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
Errorf(nil, "WriteFile trivial.c failed: %v", err)
argv = append(argv, peimporteddlls()...)
}
- if l.Debugvlog != 0 {
- l.Logf("%5.2f host link:", Cputime())
+ if ctxt.Debugvlog != 0 {
+ ctxt.Logf("%5.2f host link:", Cputime())
for _, v := range argv {
- l.Logf(" %q", v)
+ ctxt.Logf(" %q", v)
}
- l.Logf("\n")
+ ctxt.Logf("\n")
}
if out, err := exec.Command(argv[0], argv[1:]...).CombinedOutput(); err != nil {
} else if len(out) > 0 {
// always print external output even if the command is successful, so that we don't
// swallow linker warnings (see https://golang.org/issue/17935).
- l.Logf("%s", out)
+ ctxt.Logf("%s", out)
}
if !*FlagS && !*FlagW && !debug_s && Headtype == objabi.Hdarwin {
// Skip combining dwarf on arm.
- if !l.Arch.InFamily(sys.ARM, sys.ARM64) {
+ if !ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
dsym := filepath.Join(*flagTmpdir, "go.dwarf")
if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
}
// For os.Rename to work reliably, must be in same directory as outfile.
combinedOutput := *flagOutfile + "~"
- if err := machoCombineDwarf(*flagOutfile, dsym, combinedOutput); err != nil {
+ if err := machoCombineDwarf(*flagOutfile, dsym, combinedOutput, ctxt.BuildMode); err != nil {
Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
}
os.Remove(*flagOutfile)
// onlyctxt.Diagnose the direct caller.
// TODO(mwhudson): actually think about this.
if depth == 1 && s.Type != sym.SXREF && !ctxt.DynlinkingGo() &&
- Buildmode != BuildmodeCArchive && Buildmode != BuildmodePIE && Buildmode != BuildmodeCShared && Buildmode != BuildmodePlugin {
+ ctxt.BuildMode != BuildModeCArchive && ctxt.BuildMode != BuildModePIE && ctxt.BuildMode != BuildModeCShared && ctxt.BuildMode != BuildModePlugin {
Errorf(s, "call to external function")
}
put(ctxt, s, s.Extname, UndefinedSym, 0, nil)
case sym.STLSBSS:
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
put(ctxt, s, s.Name, TLSSym, Symaddr(s), s.Gotype)
}
}
Loaded bool // set after all inputs have been loaded as symbols
+ LinkMode LinkMode
+ BuildMode BuildMode
+
Tlsg *sym.Symbol
Libdir []string
Library []*sym.Library
var linkoff int64
-func machowrite(arch *sys.Arch, out *OutBuf) int {
+func machowrite(arch *sys.Arch, out *OutBuf, linkmode LinkMode) int {
o1 := out.Offset()
loadsize := 4 * 4 * ndebug
}
out.Write32(machohdr.cpu)
out.Write32(machohdr.subcpu)
- if Linkmode == LinkExternal {
+ if linkmode == LinkExternal {
out.Write32(MH_OBJECT) /* file type - mach object */
} else {
out.Write32(MH_EXECUTE) /* file type - mach executable */
s.Type = sym.SMACHOSYMTAB
s.Attr |= sym.AttrReachable
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
s := ctxt.Syms.Lookup(".plt", 0) // will be __symbol_stub
s.Type = sym.SMACHOPLT
s.Attr |= sym.AttrReachable
}
}
-func machoadddynlib(lib string) {
- if seenlib[lib] || Linkmode == LinkExternal {
+func machoadddynlib(lib string, linkmode LinkMode) {
+ if seenlib[lib] || linkmode == LinkExternal {
return
}
seenlib[lib] = true
var msect *MachoSect
if sect.Rwx&1 == 0 && segname != "__DWARF" && (ctxt.Arch.Family == sys.ARM64 ||
- (ctxt.Arch.Family == sys.AMD64 && Buildmode != BuildmodeExe) ||
- (ctxt.Arch.Family == sys.ARM && Buildmode != BuildmodeExe)) {
+ (ctxt.Arch.Family == sys.AMD64 && ctxt.BuildMode != BuildModeExe) ||
+ (ctxt.Arch.Family == sys.ARM && ctxt.BuildMode != BuildModeExe)) {
// Darwin external linker on arm64 and on amd64 and arm in c-shared/c-archive buildmode
// complains about absolute relocs in __TEXT, so if the section is not
// executable, put it in __DATA segment.
}
var ms *MachoSeg
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
/* segment for entire file */
ms = newMachoSeg("", 40)
ms.fileoffset = Segtext.Fileoff
- if ctxt.Arch.Family == sys.ARM || Buildmode == BuildmodeCArchive {
+ if ctxt.Arch.Family == sys.ARM || ctxt.BuildMode == BuildModeCArchive {
ms.filesize = Segdata.Fileoff + Segdata.Filelen - Segtext.Fileoff
} else {
ms.filesize = Segdwarf.Fileoff + Segdwarf.Filelen - Segtext.Fileoff
}
/* segment for zero page */
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
ms = newMachoSeg("__PAGEZERO", 0)
ms.vsize = uint64(va)
}
/* text */
v := Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound))
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
ms = newMachoSeg("__TEXT", 20)
ms.vaddr = uint64(va)
ms.vsize = uint64(v)
}
/* data */
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
w := int64(Segdata.Length)
ms = newMachoSeg("__DATA", 20)
ms.vaddr = uint64(va) + uint64(v)
/* dwarf */
if !*FlagW {
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
ms = newMachoSeg("__DWARF", 20)
ms.vaddr = Segdwarf.Vaddr
ms.vsize = 0
}
}
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
switch ctxt.Arch.Family {
default:
Exitf("unknown macho architecture: %v", ctxt.Arch.Family)
s3 := ctxt.Syms.Lookup(".linkedit.got", 0)
s4 := ctxt.Syms.Lookup(".machosymstr", 0)
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
ms := newMachoSeg("__LINKEDIT", 0)
ms.vaddr = uint64(va) + uint64(v) + uint64(Rnd(int64(Segdata.Length), int64(*FlagRound)))
ms.vsize = uint64(s1.Size) + uint64(s2.Size) + uint64(s3.Size) + uint64(s4.Size)
machodysymtab(ctxt)
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
ml := newMachoLoad(ctxt.Arch, LC_LOAD_DYLINKER, 6)
ml.data[0] = 12 /* offset to string */
stringtouint32(ml.data[1:], "/usr/lib/dyld")
}
}
- if Linkmode == LinkInternal {
+ if ctxt.LinkMode == LinkInternal {
// For lldb, must say LC_VERSION_MIN_MACOSX or else
// it won't know that this Mach-O binary is from OS X
// (could be iOS or WatchOS instead).
ml.data[1] = 10<<16 | 7<<8 | 0<<0 // SDK 10.7.0
}
- a := machowrite(ctxt.Arch, ctxt.Out)
+ a := machowrite(ctxt.Arch, ctxt.Out, ctxt.LinkMode)
if int32(a) > HEADR {
Exitf("HEADR too small: %d > %d", a, HEADR)
}
if !ctxt.DynlinkingGo() || s.Attr.Local() {
return false
}
- if Buildmode == BuildmodePlugin && strings.HasPrefix(s.Extname, objabi.PathToPrefix(*flagPluginPath)) {
+ if ctxt.BuildMode == BuildModePlugin && strings.HasPrefix(s.Extname, objabi.PathToPrefix(*flagPluginPath)) {
return true
}
if strings.HasPrefix(s.Name, "go.itab.") {
// symbols like crosscall2 are in pclntab and end up
// pointing at the host binary, breaking unwinding.
// See Issue #18190.
- cexport := !strings.Contains(s.Extname, ".") && (Buildmode != BuildmodePlugin || onlycsymbol(s))
+ cexport := !strings.Contains(s.Extname, ".") && (ctxt.BuildMode != BuildModePlugin || onlycsymbol(s))
if cexport || export {
symstr.AddUint8('_')
}
// header to add the DWARF sections. (Use ld's -headerpad option)
// dsym is the path to the macho file containing DWARF from dsymutil.
// outexe is the path where the combined executable should be saved.
-func machoCombineDwarf(inexe, dsym, outexe string) error {
+func machoCombineDwarf(inexe, dsym, outexe string, buildmode BuildMode) error {
exef, err := os.Open(inexe)
if err != nil {
return err
return err
}
}
- return machoUpdateDwarfHeader(&reader)
+ return machoUpdateDwarfHeader(&reader, buildmode)
}
// machoUpdateSegment updates the load command for a moved segment.
}
// machoUpdateDwarfHeader updates the DWARF segment load command.
-func machoUpdateDwarfHeader(r *loadCmdReader) error {
+func machoUpdateDwarfHeader(r *loadCmdReader, buildmode BuildMode) error {
var seg, sect interface{}
cmd, err := r.Next()
if err != nil {
// We don't need the DWARF information actually available in memory.
// But if we do this for buildmode=c-shared then the user-space
// dynamic loader complains about memsz < filesz. Sigh.
- if Buildmode != BuildmodeCShared {
+ if buildmode != BuildModeCShared {
segv.FieldByName("Addr").SetUint(0)
segv.FieldByName("Memsz").SetUint(0)
deltaAddr = 0
)
func init() {
- flag.Var(&Linkmode, "linkmode", "set link `mode`")
- flag.Var(&Buildmode, "buildmode", "set build `mode`")
flag.Var(&rpath, "r", "set the ELF dynamic linker search `path` to dir1:dir2:...")
}
if ctxt.Arch.Family == sys.AMD64 && objabi.GOOS == "plan9" {
flag.BoolVar(&Flag8, "8", false, "use 64-bit addresses in symbol table")
}
+ flag.Var(&ctxt.LinkMode, "linkmode", "set link `mode`")
+ flag.Var(&ctxt.BuildMode, "buildmode", "set build `mode`")
objabi.Flagfn1("B", "add an ELF NT_GNU_BUILD_ID `note` when using ELF", addbuildinfo)
objabi.Flagfn1("L", "add specified `directory` to library path", func(a string) { Lflag(ctxt, a) })
objabi.Flagfn0("V", "print version and exit", doversion)
}
startProfile()
- if Buildmode == BuildmodeUnset {
- Buildmode = BuildmodeExe
+ if ctxt.BuildMode == BuildModeUnset {
+ ctxt.BuildMode = BuildModeExe
}
- if Buildmode != BuildmodeShared && flag.NArg() != 1 {
+ if ctxt.BuildMode != BuildModeShared && flag.NArg() != 1 {
usage()
}
ctxt.Logf("HEADER = -H%d -T0x%x -D0x%x -R0x%x\n", Headtype, uint64(*FlagTextAddr), uint64(*FlagDataAddr), uint32(*FlagRound))
}
- switch Buildmode {
- case BuildmodeShared:
+ switch ctxt.BuildMode {
+ case BuildModeShared:
for i := 0; i < flag.NArg(); i++ {
arg := flag.Arg(i)
parts := strings.SplitN(arg, "=", 2)
pkglistfornote = append(pkglistfornote, '\n')
addlibpath(ctxt, "command line", "command line", file, pkgpath, "")
}
- case BuildmodePlugin:
+ case BuildModePlugin:
addlibpath(ctxt, "command line", "command line", flag.Arg(0), *flagPluginPath, "")
default:
addlibpath(ctxt, "command line", "command line", flag.Arg(0), "main", "")
return false
}
-func emitPcln(s *sym.Symbol) bool {
+func emitPcln(ctxt *Link, s *sym.Symbol) bool {
if s == nil {
return true
}
- if Buildmode == BuildmodePlugin && Headtype == objabi.Hdarwin && onlycsymbol(s) {
+ if ctxt.BuildMode == BuildModePlugin && Headtype == objabi.Hdarwin && onlycsymbol(s) {
return false
}
// We want to generate func table entries only for the "lowest level" symbols,
}
for _, s := range ctxt.Textp {
- if emitPcln(s) {
+ if emitPcln(ctxt, s) {
nfunc++
}
}
var last *sym.Symbol
for _, s := range ctxt.Textp {
last = s
- if !emitPcln(s) {
+ if !emitPcln(ctxt, s) {
continue
}
pcln := s.FuncInfo
}
idx := int32(0)
for i, s := range ctxt.Textp {
- if !emitPcln(s) {
+ if !emitPcln(ctxt, s) {
continue
}
p := s.Value
if i < len(ctxt.Textp) {
e = ctxt.Textp[i]
}
- for !emitPcln(e) && i < len(ctxt.Textp) {
+ for !emitPcln(ctxt, e) && i < len(ctxt.Textp) {
e = ctxt.Textp[i]
i++
}
}
// write writes COFF section sect into the output file.
-func (sect *peSection) write(out *OutBuf) error {
+func (sect *peSection) write(out *OutBuf, linkmode LinkMode) error {
h := pe.SectionHeader32{
VirtualSize: sect.virtualSize,
SizeOfRawData: sect.sizeOfRawData,
NumberOfRelocations: sect.numberOfRelocations,
Characteristics: sect.characteristics,
}
- if Linkmode != LinkExternal {
+ if linkmode != LinkExternal {
h.VirtualAddress = sect.virtualAddress
}
copy(h.Name[:], sect.shortName)
// mapToPESection searches peFile f for s symbol's location.
// It returns PE section index, and offset within that section.
-func (f *peFile) mapToPESection(s *sym.Symbol) (pesectidx int, offset int64, err error) {
+func (f *peFile) mapToPESection(s *sym.Symbol, linkmode LinkMode) (pesectidx int, offset int64, err error) {
if s.Sect == nil {
return 0, 0, fmt.Errorf("could not map %s symbol with no section", s.Name)
}
return 0, 0, fmt.Errorf("could not map %s symbol with non .text or .data section", s.Name)
}
v := uint64(s.Value) - Segdata.Vaddr
- if Linkmode != LinkExternal {
+ if linkmode != LinkExternal {
return f.dataSect.index, int64(v), nil
}
if s.Type == sym.SDATA {
// Only windows/386 requires underscore prefix on external symbols.
if ctxt.Arch.Family == sys.I386 &&
- Linkmode == LinkExternal &&
+ ctxt.LinkMode == LinkExternal &&
(s.Type == sym.SHOSTOBJ || s.Attr.CgoExport()) {
s.Name = "_" + s.Name
}
var typ uint16
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
typ = IMAGE_SYM_TYPE_NULL
} else {
// TODO: fix IMAGE_SYM_DTYPE_ARRAY value and use following expression, instead of 0x0308
typ = IMAGE_SYM_DTYPE_ARRAY<<8 + IMAGE_SYM_TYPE_STRUCT
typ = 0x0308 // "array of structs"
}
- sect, value, err := f.mapToPESection(s)
+ sect, value, err := f.mapToPESection(s, ctxt.LinkMode)
if err != nil {
if type_ == UndefinedSym {
typ = IMAGE_SYM_DTYPE_FUNCTION
f.writeSymbol(ctxt.Out, s, value, sect, typ, uint8(class))
}
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
// Include section symbols as external, because
// .ctors and .debug_* section relocations refer to it.
for _, pesect := range f.sections {
f.symtabOffset = ctxt.Out.Offset()
// write COFF symbol table
- if !*FlagS || Linkmode == LinkExternal {
+ if !*FlagS || ctxt.LinkMode == LinkExternal {
f.writeSymbols(ctxt)
}
// update COFF file header and section table
size := f.stringTable.size() + 18*f.symbolCount
var h *peSection
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
// We do not really need .symtab for go.o, and if we have one, ld
// will also include it in the exe, and that will confuse windows.
h = f.addSection(".symtab", size, size)
// write COFF string table
f.stringTable.write(ctxt.Out)
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
h.pad(ctxt.Out, uint32(size))
}
}
// writeFileHeader writes COFF file header for peFile f.
-func (f *peFile) writeFileHeader(arch *sys.Arch, out *OutBuf) {
+func (f *peFile) writeFileHeader(arch *sys.Arch, out *OutBuf, linkmode LinkMode) {
var fh pe.FileHeader
switch arch.Family {
// much more beneficial than having build timestamp in the header.
fh.TimeDateStamp = 0
- if Linkmode == LinkExternal {
+ if linkmode == LinkExternal {
fh.Characteristics = IMAGE_FILE_LINE_NUMS_STRIPPED
} else {
fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DEBUG_STRIPPED
oh.SizeOfInitializedData = f.dataSect.sizeOfRawData
oh64.SizeOfUninitializedData = 0
oh.SizeOfUninitializedData = 0
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
oh64.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE)
oh.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE)
}
}
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
PESECTALIGN = 0
PEFILEALIGN = 0
}
var sh [16]pe.SectionHeader32
var fh pe.FileHeader
PEFILEHEADR = int32(Rnd(int64(len(dosstub)+binary.Size(&fh)+l+binary.Size(&sh)), PEFILEALIGN))
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
PESECTHEADR = int32(Rnd(int64(PEFILEHEADR), PESECTALIGN))
} else {
PESECTHEADR = 0
pefile.nextSectOffset = uint32(PESECTHEADR)
pefile.nextFileOffset = uint32(PEFILEHEADR)
- if Linkmode == LinkInternal {
+ if ctxt.LinkMode == LinkInternal {
// some mingw libs depend on this symbol, for example, FindPESectionByName
ctxt.xdefine("__image_base__", sym.SDATA, PEBASE)
ctxt.xdefine("_image_base__", sym.SDATA, PEBASE)
func pewrite(ctxt *Link) {
ctxt.Out.SeekSet(0)
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
ctxt.Out.Write(dosstub)
ctxt.Out.WriteStringN("PE", 4)
}
- pefile.writeFileHeader(ctxt.Arch, ctxt.Out)
+ pefile.writeFileHeader(ctxt.Arch, ctxt.Out, ctxt.LinkMode)
pefile.writeOptionalHeader(ctxt)
for _, sect := range pefile.sections {
- sect.write(ctxt.Out)
+ sect.write(ctxt.Out, ctxt.LinkMode)
}
}
d.ms = m
}
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
// Add real symbol name
for d := dr; d != nil; d = d.next {
for m = d.ms; m != nil; m = m.next {
t := pefile.addSection(".text", int(Segtext.Length), int(Segtext.Length))
t.characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
// some data symbols (e.g. masks) end up in the .text section, and they normally
// expect larger alignment requirement than the default text section alignment.
t.characteristics |= IMAGE_SCN_ALIGN_32BYTES
pefile.textSect = t
var d *peSection
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
d = pefile.addSection(".data", int(Segdata.Length), int(Segdata.Filelen))
d.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
d.checkSegment(&Segdata)
pefile.addDWARF()
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
pefile.ctorsSect = pefile.addInitArray(ctxt)
}
ctxt.Out.SeekSet(int64(pefile.nextFileOffset))
- if Linkmode != LinkExternal {
+ if ctxt.LinkMode != LinkExternal {
addimports(ctxt, d)
addexports(ctxt)
}
pefile.writeSymbolTableAndStringTable(ctxt)
addpersrc(ctxt)
- if Linkmode == LinkExternal {
+ if ctxt.LinkMode == LinkExternal {
pefile.emitRelocations(ctxt)
}
// To avoid filling the dynamic table with lots of unnecessary symbols,
// mark all Go symbols local (not global) in the final executable.
// But when we're dynamically linking, we need all those global symbols.
- if !ctxt.DynlinkingGo() && Linkmode == LinkExternal && !x.Attr.CgoExportStatic() && elfshnum != SHN_UNDEF {
+ if !ctxt.DynlinkingGo() && ctxt.LinkMode == LinkExternal && !x.Attr.CgoExportStatic() && elfshnum != SHN_UNDEF {
bind = STB_LOCAL
}
- if Linkmode == LinkExternal && elfshnum != SHN_UNDEF {
+ if ctxt.LinkMode == LinkExternal && elfshnum != SHN_UNDEF {
addr -= int64(xo.Sect.Vaddr)
}
other := STV_DEFAULT
// pseudo-symbols to mark locations of type, string, and go string data.
var symtype *sym.Symbol
var symtyperel *sym.Symbol
- if UseRelro() && (Buildmode == BuildmodeCArchive || Buildmode == BuildmodeCShared || Buildmode == BuildmodePIE) {
+ if ctxt.UseRelro() && (ctxt.BuildMode == BuildModeCArchive || ctxt.BuildMode == BuildModeCShared || ctxt.BuildMode == BuildModePIE) {
s = ctxt.Syms.Lookup("type.*", 0)
s.Type = sym.STYPE
var symgofuncrel *sym.Symbol
if !ctxt.DynlinkingGo() {
- if UseRelro() {
+ if ctxt.UseRelro() {
symgofuncrel = groupSym("go.funcrel.*", sym.SGOFUNCRELRO)
} else {
symgofuncrel = symgofunc
if !ctxt.DynlinkingGo() {
s.Attr |= sym.AttrNotInSymbolTable
}
- if UseRelro() {
+ if ctxt.UseRelro() {
s.Type = sym.STYPERELRO
s.Outer = symtyperel
} else {
s.Outer = symtype
}
- case strings.HasPrefix(s.Name, "go.importpath.") && UseRelro():
+ case strings.HasPrefix(s.Name, "go.importpath.") && ctxt.UseRelro():
// Keep go.importpath symbols in the same section as types and
// names, as they can be referred to by a section offset.
s.Type = sym.STYPERELRO
if !ctxt.DynlinkingGo() {
s.Attr |= sym.AttrNotInSymbolTable
}
- if UseRelro() {
+ if ctxt.UseRelro() {
s.Type = sym.SGOFUNCRELRO
s.Outer = symgofuncrel
} else {
}
}
- if Buildmode == BuildmodeShared {
+ if ctxt.BuildMode == BuildModeShared {
abihashgostr := ctxt.Syms.Lookup("go.link.abihash."+filepath.Base(*flagOutfile), 0)
abihashgostr.Attr |= sym.AttrReachable
abihashgostr.Type = sym.SRODATA
abihashgostr.AddAddr(ctxt.Arch, hashsym)
abihashgostr.AddUint(ctxt.Arch, uint64(hashsym.Size))
}
- if Buildmode == BuildmodePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil {
+ if ctxt.BuildMode == BuildModePlugin || ctxt.Syms.ROLookup("plugin.Open", 0) != nil {
for _, l := range ctxt.Library {
s := ctxt.Syms.Lookup("go.link.pkghashbytes."+l.Pkg, 0)
s.Attr |= sym.AttrReachable
moduledata.AddUint(ctxt.Arch, 0)
moduledata.AddUint(ctxt.Arch, 0)
}
- if Buildmode == BuildmodePlugin {
+ if ctxt.BuildMode == BuildModePlugin {
addgostring(ctxt, moduledata, "go.link.thispluginpath", *flagPluginPath)
pkghashes := ctxt.Syms.Lookup("go.link.pkghashes", 0)
}
if len(ctxt.Shlibs) > 0 {
thismodulename := filepath.Base(*flagOutfile)
- switch Buildmode {
- case BuildmodeExe, BuildmodePIE:
+ switch ctxt.BuildMode {
+ case BuildModeExe, BuildModePIE:
// When linking an executable, outfile is just "a.out". Make
// it something slightly more comprehensible.
thismodulename = "the executable"
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
switch r.Type {
default:
return false
ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
}
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt)
}
}
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
switch r.Type {
default:
return false
ctxt.Out.Flush()
ctxt.Out.Write(ld.Elfstrdat)
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt)
}
}
func genaddmoduledata(ctxt *ld.Link) {
addmoduledata := ctxt.Syms.ROLookup("runtime.addmoduledata", 0)
- if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin {
+ if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
return
}
addmoduledata.Attr |= sym.AttrReachable
// blr
o(0x4e800020)
- if ld.Buildmode == ld.BuildmodePlugin {
+ if ctxt.BuildMode == ld.BuildModePlugin {
ctxt.Textp = append(ctxt.Textp, addmoduledata)
}
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
genaddmoduledata(ctxt)
}
- if ld.Linkmode == ld.LinkInternal {
+ if ctxt.LinkMode == ld.LinkInternal {
genplt(ctxt)
}
}
// For internal linking, trampolines are always created for long calls.
// For external linking, the linker can insert a call stub to handle a long call, but depends on having the TOC address in
// r2. For those build modes with external linking where the TOC address is not maintained in r2, trampolines must be created.
- if ld.Linkmode == ld.LinkExternal && (ctxt.DynlinkingGo() || ld.Buildmode == ld.BuildmodeCArchive || ld.Buildmode == ld.BuildmodeCShared || ld.Buildmode == ld.BuildmodePIE) {
+ if ctxt.LinkMode == ld.LinkExternal && (ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE) {
// No trampolines needed since r2 contains the TOC
return
}
// If branch offset is too far then create a trampoline.
- if (ld.Linkmode == ld.LinkExternal && s.Sect != r.Sym.Sect) || (ld.Linkmode == ld.LinkInternal && int64(int32(t<<6)>>6) != t) || (*ld.FlagDebugTramp > 1 && s.File != r.Sym.File) {
+ if (ctxt.LinkMode == ld.LinkExternal && s.Sect != r.Sym.Sect) || (ctxt.LinkMode == ld.LinkInternal && int64(int32(t<<6)>>6) != t) || (*ld.FlagDebugTramp > 1 && s.File != r.Sym.File) {
var tramp *sym.Symbol
for i := 0; ; i++ {
// With internal linking, the trampoline can be used if it is not too far.
// With external linking, the trampoline must be in this section for it to be reused.
- if (ld.Linkmode == ld.LinkInternal && int64(int32(t<<6)>>6) == t) || (ld.Linkmode == ld.LinkExternal && s.Sect == tramp.Sect) {
+ if (ctxt.LinkMode == ld.LinkInternal && int64(int32(t<<6)>>6) == t) || (ctxt.LinkMode == ld.LinkExternal && s.Sect == tramp.Sect) {
break
}
}
if tramp.Type == 0 {
- if ctxt.DynlinkingGo() || ld.Buildmode == ld.BuildmodeCArchive || ld.Buildmode == ld.BuildmodeCShared || ld.Buildmode == ld.BuildmodePIE {
+ if ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE {
// Should have returned for above cases
ld.Errorf(s, "unexpected trampoline for shared or dynamic linking\n")
} else {
ctxt.AddTramp(tramp)
- gentramp(ctxt.Arch, tramp, r.Sym, int64(r.Add))
+ gentramp(ctxt.Arch, ctxt.LinkMode, tramp, r.Sym, int64(r.Add))
}
}
r.Sym = tramp
}
}
-func gentramp(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
+func gentramp(arch *sys.Arch, linkmode ld.LinkMode, tramp, target *sym.Symbol, offset int64) {
// Used for default build mode for an executable
// Address of the call target is generated using
// relocation and doesn't depend on r2 (TOC).
o2 := uint32(0x3bff0000) // addi r31,targetaddr lo
// With external linking, the target address must be
// relocated using LO and HA
- if ld.Linkmode == ld.LinkExternal {
+ if linkmode == ld.LinkExternal {
tr := tramp.AddRel()
tr.Off = 0
tr.Type = objabi.R_ADDRPOWER
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
switch r.Type {
default:
return false
ctxt.Out.Flush()
ctxt.Out.Write(ld.Elfstrdat)
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt)
}
}
return
}
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
- if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin {
+ if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
// we're linking a module containing the runtime -> no need for
// an init function
return
// undef (for debugging)
initfunc.AddUint32(ctxt.Arch, 0)
- if ld.Buildmode == ld.BuildmodePlugin {
+ if ctxt.BuildMode == ld.BuildModePlugin {
ctxt.Textp = append(ctxt.Textp, addmoduledata)
}
ctxt.Textp = append(ctxt.Textp, initfunc)
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
return false
}
ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
}
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt)
}
}
if ctxt.DynlinkingGo() {
// We need get_pc_thunk.
} else {
- switch ld.Buildmode {
- case ld.BuildmodeCArchive:
+ switch ctxt.BuildMode {
+ case ld.BuildModeCArchive:
if !ld.Iself {
return
}
- case ld.BuildmodePIE, ld.BuildmodeCShared, ld.BuildmodePlugin:
+ case ld.BuildModePIE, ld.BuildModeCShared, ld.BuildModePlugin:
// We need get_pc_thunk.
default:
return
ctxt.Textp = append(thunks, ctxt.Textp...) // keep Textp in dependency order
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
- if addmoduledata.Type == sym.STEXT && ld.Buildmode != ld.BuildmodePlugin {
+ if addmoduledata.Type == sym.STEXT && ctxt.BuildMode != ld.BuildModePlugin {
// we're linking a module containing the runtime -> no need for
// an init function
return
o(0xc3)
- if ld.Buildmode == ld.BuildmodePlugin {
+ if ctxt.BuildMode == ld.BuildModePlugin {
ctxt.Textp = append(ctxt.Textp, addmoduledata)
}
ctxt.Textp = append(ctxt.Textp, initfunc)
}
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
return false
}
switch r.Type {
ctxt.Out.Flush()
ctxt.Out.Write(ld.Elfstrdat)
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt)
}
}
}
case objabi.Hdarwin:
- if ld.Linkmode == ld.LinkExternal {
+ if ctxt.LinkMode == ld.LinkExternal {
ld.Machoemitreloc(ctxt)
}
}