Commit 2e854553 authored by David Crawshaw's avatar David Crawshaw

cmd/link: move build/link mode globals into ctxt

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: default avatarIan Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 9f9bb974
...@@ -61,7 +61,7 @@ func gentext(ctxt *ld.Link) { ...@@ -61,7 +61,7 @@ func gentext(ctxt *ld.Link) {
return return
} }
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0) 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 // we're linking a module containing the runtime -> no need for
// an init function // an init function
return return
...@@ -87,7 +87,7 @@ func gentext(ctxt *ld.Link) { ...@@ -87,7 +87,7 @@ func gentext(ctxt *ld.Link) {
Addcall(ctxt, initfunc, addmoduledata) Addcall(ctxt, initfunc, addmoduledata)
// c: c3 retq // c: c3 retq
o(0xc3) o(0xc3)
if ld.Buildmode == ld.BuildmodePlugin { if ctxt.BuildMode == ld.BuildModePlugin {
ctxt.Textp = append(ctxt.Textp, addmoduledata) ctxt.Textp = append(ctxt.Textp, addmoduledata)
} }
ctxt.Textp = append(ctxt.Textp, initfunc) ctxt.Textp = append(ctxt.Textp, initfunc)
...@@ -266,7 +266,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool { ...@@ -266,7 +266,7 @@ func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
} }
// Process dynamic relocations for the data sections. // 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 // When internally linking, generate dynamic relocations
// for all typical R_ADDR relocations. The exception // for all typical R_ADDR relocations. The exception
// are those R_ADDR that are created as part of generating // are those R_ADDR that are created as part of generating
...@@ -771,7 +771,7 @@ func asmb(ctxt *ld.Link) { ...@@ -771,7 +771,7 @@ func asmb(ctxt *ld.Link) {
ctxt.Logf("%5.2f dwarf\n", ld.Cputime()) ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
} }
if ld.Linkmode == ld.LinkExternal { if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt) ld.Elfemitreloc(ctxt)
} }
} }
...@@ -793,7 +793,7 @@ func asmb(ctxt *ld.Link) { ...@@ -793,7 +793,7 @@ func asmb(ctxt *ld.Link) {
} }
case objabi.Hdarwin: case objabi.Hdarwin:
if ld.Linkmode == ld.LinkExternal { if ctxt.LinkMode == ld.LinkExternal {
ld.Machoemitreloc(ctxt) ld.Machoemitreloc(ctxt)
} }
} }
......
...@@ -65,7 +65,7 @@ func gentext(ctxt *ld.Link) { ...@@ -65,7 +65,7 @@ func gentext(ctxt *ld.Link) {
return return
} }
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0) 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 // we're linking a module containing the runtime -> no need for
// an init function // an init function
return return
...@@ -97,7 +97,7 @@ func gentext(ctxt *ld.Link) { ...@@ -97,7 +97,7 @@ func gentext(ctxt *ld.Link) {
rel.Type = objabi.R_PCREL rel.Type = objabi.R_PCREL
rel.Add = 4 rel.Add = 4
if ld.Buildmode == ld.BuildmodePlugin { if ctxt.BuildMode == ld.BuildModePlugin {
ctxt.Textp = append(ctxt.Textp, addmoduledata) ctxt.Textp = append(ctxt.Textp, addmoduledata)
} }
ctxt.Textp = append(ctxt.Textp, initfunc) ctxt.Textp = append(ctxt.Textp, initfunc)
...@@ -464,10 +464,10 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) { ...@@ -464,10 +464,10 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
ld.Errorf(s, "odd offset in dynlink direct call: %v+%d", r.Sym, offset) ld.Errorf(s, "odd offset in dynlink direct call: %v+%d", r.Sym, offset)
} }
gentrampdyn(ctxt.Arch, tramp, r.Sym, int64(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)) gentramppic(ctxt.Arch, tramp, r.Sym, int64(offset))
} else { } 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 // modify reloc to point to tramp, which will be resolved later
...@@ -481,7 +481,7 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) { ...@@ -481,7 +481,7 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
} }
// generate a trampoline to target+offset // 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.Size = 12 // 3 instructions
tramp.P = make([]byte, tramp.Size) tramp.P = make([]byte, tramp.Size)
t := ld.Symaddr(target) + int64(offset) t := ld.Symaddr(target) + int64(offset)
...@@ -492,7 +492,7 @@ func gentramp(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) { ...@@ -492,7 +492,7 @@ func gentramp(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
arch.ByteOrder.PutUint32(tramp.P[4:], o2) arch.ByteOrder.PutUint32(tramp.P[4:], o2)
arch.ByteOrder.PutUint32(tramp.P[8:], o3) arch.ByteOrder.PutUint32(tramp.P[8:], o3)
if ld.Linkmode == ld.LinkExternal { if linkmode == ld.LinkExternal {
r := tramp.AddRel() r := tramp.AddRel()
r.Off = 8 r.Off = 8
r.Type = objabi.R_ADDR r.Type = objabi.R_ADDR
...@@ -564,7 +564,7 @@ func gentrampdyn(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) { ...@@ -564,7 +564,7 @@ func gentrampdyn(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { 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 { switch r.Type {
case objabi.R_CALLARM: case objabi.R_CALLARM:
r.Done = false r.Done = false
...@@ -819,7 +819,7 @@ func asmb(ctxt *ld.Link) { ...@@ -819,7 +819,7 @@ func asmb(ctxt *ld.Link) {
ctxt.Out.Flush() ctxt.Out.Flush()
ctxt.Out.Write(ld.Elfstrdat) ctxt.Out.Write(ld.Elfstrdat)
if ld.Linkmode == ld.LinkExternal { if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt) ld.Elfemitreloc(ctxt)
} }
} }
...@@ -836,7 +836,7 @@ func asmb(ctxt *ld.Link) { ...@@ -836,7 +836,7 @@ func asmb(ctxt *ld.Link) {
} }
case objabi.Hdarwin: case objabi.Hdarwin:
if ld.Linkmode == ld.LinkExternal { if ctxt.LinkMode == ld.LinkExternal {
ld.Machoemitreloc(ctxt) ld.Machoemitreloc(ctxt)
} }
} }
......
...@@ -217,7 +217,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se ...@@ -217,7 +217,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { 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 { switch r.Type {
default: default:
return false return false
...@@ -455,7 +455,7 @@ func asmb(ctxt *ld.Link) { ...@@ -455,7 +455,7 @@ func asmb(ctxt *ld.Link) {
ctxt.Out.Flush() ctxt.Out.Flush()
ctxt.Out.Write(ld.Elfstrdat) ctxt.Out.Write(ld.Elfstrdat)
if ld.Linkmode == ld.LinkExternal { if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt) ld.Elfemitreloc(ctxt)
} }
} }
...@@ -472,7 +472,7 @@ func asmb(ctxt *ld.Link) { ...@@ -472,7 +472,7 @@ func asmb(ctxt *ld.Link) {
} }
case objabi.Hdarwin: case objabi.Hdarwin:
if ld.Linkmode == ld.LinkExternal { if ctxt.LinkMode == ld.LinkExternal {
ld.Machoemitreloc(ctxt) ld.Machoemitreloc(ctxt)
} }
} }
......
...@@ -11,11 +11,6 @@ import ( ...@@ -11,11 +11,6 @@ import (
"log" "log"
) )
var (
Linkmode LinkMode
Buildmode BuildMode
)
// A BuildMode indicates the sort of object we are building. // A BuildMode indicates the sort of object we are building.
// //
// Possible build modes are the same as those for the -buildmode flag // Possible build modes are the same as those for the -buildmode flag
...@@ -23,13 +18,13 @@ var ( ...@@ -23,13 +18,13 @@ var (
type BuildMode uint8 type BuildMode uint8
const ( const (
BuildmodeUnset BuildMode = iota BuildModeUnset BuildMode = iota
BuildmodeExe BuildModeExe
BuildmodePIE BuildModePIE
BuildmodeCArchive BuildModeCArchive
BuildmodeCShared BuildModeCShared
BuildmodeShared BuildModeShared
BuildmodePlugin BuildModePlugin
) )
func (mode *BuildMode) Set(s string) error { func (mode *BuildMode) Set(s string) error {
...@@ -40,7 +35,7 @@ func (mode *BuildMode) Set(s string) error { ...@@ -40,7 +35,7 @@ func (mode *BuildMode) Set(s string) error {
default: default:
return fmt.Errorf("invalid buildmode: %q", s) return fmt.Errorf("invalid buildmode: %q", s)
case "exe": case "exe":
*mode = BuildmodeExe *mode = BuildModeExe
case "pie": case "pie":
switch objabi.GOOS { switch objabi.GOOS {
case "android", "linux": case "android", "linux":
...@@ -53,7 +48,7 @@ func (mode *BuildMode) Set(s string) error { ...@@ -53,7 +48,7 @@ func (mode *BuildMode) Set(s string) error {
default: default:
return badmode() return badmode()
} }
*mode = BuildmodePIE *mode = BuildModePIE
case "c-archive": case "c-archive":
switch objabi.GOOS { switch objabi.GOOS {
case "darwin", "linux": case "darwin", "linux":
...@@ -66,14 +61,14 @@ func (mode *BuildMode) Set(s string) error { ...@@ -66,14 +61,14 @@ func (mode *BuildMode) Set(s string) error {
default: default:
return badmode() return badmode()
} }
*mode = BuildmodeCArchive *mode = BuildModeCArchive
case "c-shared": case "c-shared":
switch objabi.GOARCH { switch objabi.GOARCH {
case "386", "amd64", "arm", "arm64", "ppc64le": case "386", "amd64", "arm", "arm64", "ppc64le":
default: default:
return badmode() return badmode()
} }
*mode = BuildmodeCShared *mode = BuildModeCShared
case "shared": case "shared":
switch objabi.GOOS { switch objabi.GOOS {
case "linux": case "linux":
...@@ -85,7 +80,7 @@ func (mode *BuildMode) Set(s string) error { ...@@ -85,7 +80,7 @@ func (mode *BuildMode) Set(s string) error {
default: default:
return badmode() return badmode()
} }
*mode = BuildmodeShared *mode = BuildModeShared
case "plugin": case "plugin":
switch objabi.GOOS { switch objabi.GOOS {
case "linux": case "linux":
...@@ -103,26 +98,26 @@ func (mode *BuildMode) Set(s string) error { ...@@ -103,26 +98,26 @@ func (mode *BuildMode) Set(s string) error {
default: default:
return badmode() return badmode()
} }
*mode = BuildmodePlugin *mode = BuildModePlugin
} }
return nil return nil
} }
func (mode *BuildMode) String() string { func (mode *BuildMode) String() string {
switch *mode { switch *mode {
case BuildmodeUnset: case BuildModeUnset:
return "" // avoid showing a default in usage message return "" // avoid showing a default in usage message
case BuildmodeExe: case BuildModeExe:
return "exe" return "exe"
case BuildmodePIE: case BuildModePIE:
return "pie" return "pie"
case BuildmodeCArchive: case BuildModeCArchive:
return "c-archive" return "c-archive"
case BuildmodeCShared: case BuildModeCShared:
return "c-shared" return "c-shared"
case BuildmodeShared: case BuildModeShared:
return "shared" return "shared"
case BuildmodePlugin: case BuildModePlugin:
return "plugin" return "plugin"
} }
return fmt.Sprintf("BuildMode(%d)", uint8(*mode)) return fmt.Sprintf("BuildMode(%d)", uint8(*mode))
...@@ -196,21 +191,21 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) { ...@@ -196,21 +191,21 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) {
} }
// Some build modes require work the internal linker cannot do (yet). // Some build modes require work the internal linker cannot do (yet).
switch Buildmode { switch ctxt.BuildMode {
case BuildmodeCArchive: case BuildModeCArchive:
return true, "buildmode=c-archive" return true, "buildmode=c-archive"
case BuildmodeCShared: case BuildModeCShared:
return true, "buildmode=c-shared" return true, "buildmode=c-shared"
case BuildmodePIE: case BuildModePIE:
switch objabi.GOOS + "/" + objabi.GOARCH { switch objabi.GOOS + "/" + objabi.GOARCH {
case "linux/amd64": case "linux/amd64":
default: default:
// Internal linking does not support TLS_IE. // Internal linking does not support TLS_IE.
return true, "buildmode=pie" return true, "buildmode=pie"
} }
case BuildmodePlugin: case BuildModePlugin:
return true, "buildmode=plugin" return true, "buildmode=plugin"
case BuildmodeShared: case BuildModeShared:
return true, "buildmode=shared" return true, "buildmode=shared"
} }
if *FlagLinkshared { if *FlagLinkshared {
...@@ -220,13 +215,13 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) { ...@@ -220,13 +215,13 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) {
return false, "" return false, ""
} }
// determineLinkMode sets Linkmode. // determineLinkMode sets ctxt.LinkMode.
// //
// It is called after flags are processed and inputs are processed, // 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. // flag and the iscgo externalobj variables are set.
func determineLinkMode(ctxt *Link) { func determineLinkMode(ctxt *Link) {
switch Linkmode { switch ctxt.LinkMode {
case LinkAuto: case LinkAuto:
// The environment variable GO_EXTLINK_ENABLED controls the // The environment variable GO_EXTLINK_ENABLED controls the
// default value of -linkmode. If it is not set when the // default value of -linkmode. If it is not set when the
...@@ -237,18 +232,18 @@ func determineLinkMode(ctxt *Link) { ...@@ -237,18 +232,18 @@ func determineLinkMode(ctxt *Link) {
if needed, reason := mustLinkExternal(ctxt); needed { if needed, reason := mustLinkExternal(ctxt); needed {
Exitf("internal linking requested via GO_EXTLINK_ENABLED, but external linking required: %s", reason) Exitf("internal linking requested via GO_EXTLINK_ENABLED, but external linking required: %s", reason)
} }
Linkmode = LinkInternal ctxt.LinkMode = LinkInternal
case "1": case "1":
Linkmode = LinkExternal ctxt.LinkMode = LinkExternal
default: default:
if needed, _ := mustLinkExternal(ctxt); needed { if needed, _ := mustLinkExternal(ctxt); needed {
Linkmode = LinkExternal ctxt.LinkMode = LinkExternal
} else if iscgo && externalobj { } else if iscgo && externalobj {
Linkmode = LinkExternal ctxt.LinkMode = LinkExternal
} else if Buildmode == BuildmodePIE { } else if ctxt.BuildMode == BuildModePIE {
Linkmode = LinkExternal // https://golang.org/issue/18968 ctxt.LinkMode = LinkExternal // https://golang.org/issue/18968
} else { } else {
Linkmode = LinkInternal ctxt.LinkMode = LinkInternal
} }
} }
case LinkInternal: case LinkInternal:
......
...@@ -202,7 +202,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) { ...@@ -202,7 +202,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) {
if r.Sym != nil && (r.Sym.Type&(sym.SMASK|sym.SHIDDEN) == 0 || r.Sym.Type&sym.SMASK == sym.SXREF) { 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 // When putting the runtime but not main into a shared library
// these symbols are undefined and that's OK. // 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" { if r.Sym.Name == "main.main" || r.Sym.Name == "main.init" {
r.Sym.Type = sym.SDYNIMPORT r.Sym.Type = sym.SDYNIMPORT
} else if strings.HasPrefix(r.Sym.Name, "go.info.") { } else if strings.HasPrefix(r.Sym.Name, "go.info.") {
...@@ -226,7 +226,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) { ...@@ -226,7 +226,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) {
// We need to be able to reference dynimport symbols when linking against // We need to be able to reference dynimport symbols when linking against
// shared libraries, and Solaris needs it always // shared libraries, and Solaris needs it always
if Headtype != objabi.Hsolaris && r.Sym != nil && r.Sym.Type == sym.SDYNIMPORT && !ctxt.DynlinkingGo() { 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)) 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))
} }
} }
...@@ -266,7 +266,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) { ...@@ -266,7 +266,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) {
case objabi.R_TLS_LE: case objabi.R_TLS_LE:
isAndroidX86 := objabi.GOOS == "android" && (ctxt.Arch.InFamily(sys.AMD64, sys.I386)) 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 r.Done = false
if r.Sym == nil { if r.Sym == nil {
r.Sym = ctxt.Tlsg r.Sym = ctxt.Tlsg
...@@ -299,7 +299,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) { ...@@ -299,7 +299,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) {
case objabi.R_TLS_IE: case objabi.R_TLS_IE:
isAndroidX86 := objabi.GOOS == "android" && (ctxt.Arch.InFamily(sys.AMD64, sys.I386)) 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 r.Done = false
if r.Sym == nil { if r.Sym == nil {
r.Sym = ctxt.Tlsg r.Sym = ctxt.Tlsg
...@@ -312,7 +312,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) { ...@@ -312,7 +312,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) {
} }
break break
} }
if Buildmode == BuildmodePIE && Iself { if ctxt.BuildMode == BuildModePIE && Iself {
// We are linking the final executable, so we // We are linking the final executable, so we
// can optimize any TLS IE relocation to LE. // can optimize any TLS IE relocation to LE.
if Thearch.TLSIEtoLE == nil { if Thearch.TLSIEtoLE == nil {
...@@ -327,7 +327,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) { ...@@ -327,7 +327,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) {
log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", s.Name) log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", s.Name)
} }
case objabi.R_ADDR: case objabi.R_ADDR:
if Linkmode == LinkExternal && r.Sym.Type != sym.SCONST { if ctxt.LinkMode == LinkExternal && r.Sym.Type != sym.SCONST {
r.Done = false r.Done = false
// set up addend for eventual relocation via outer symbol. // set up addend for eventual relocation via outer symbol.
...@@ -388,7 +388,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) { ...@@ -388,7 +388,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) {
Errorf(s, "missing DWARF section for relocation target %s", r.Sym.Name) Errorf(s, "missing DWARF section for relocation target %s", r.Sym.Name)
} }
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
r.Done = false r.Done = false
// PE code emits IMAGE_REL_I386_SECREL and IMAGE_REL_AMD64_SECREL // PE code emits IMAGE_REL_I386_SECREL and IMAGE_REL_AMD64_SECREL
// for R_DWARFREF relocations, while R_ADDR is replaced with // for R_DWARFREF relocations, while R_ADDR is replaced with
...@@ -438,7 +438,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) { ...@@ -438,7 +438,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) {
} }
fallthrough fallthrough
case objabi.R_CALL, objabi.R_PCREL: 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 r.Done = false
// set up addend for eventual relocation via outer symbol. // set up addend for eventual relocation via outer symbol.
...@@ -599,7 +599,7 @@ func windynrelocsym(ctxt *Link, s *sym.Symbol) { ...@@ -599,7 +599,7 @@ func windynrelocsym(ctxt *Link, s *sym.Symbol) {
func dynrelocsym(ctxt *Link, s *sym.Symbol) { func dynrelocsym(ctxt *Link, s *sym.Symbol) {
if Headtype == objabi.Hwindows { if Headtype == objabi.Hwindows {
if Linkmode == LinkInternal { if ctxt.LinkMode == LinkInternal {
windynrelocsym(ctxt, s) windynrelocsym(ctxt, s)
} }
return return
...@@ -607,7 +607,7 @@ func dynrelocsym(ctxt *Link, s *sym.Symbol) { ...@@ -607,7 +607,7 @@ func dynrelocsym(ctxt *Link, s *sym.Symbol) {
for ri := 0; ri < len(s.R); ri++ { for ri := 0; ri < len(s.R); ri++ {
r := &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 // It's expected that some relocations will be done
// later by relocsym (R_TLS_LE, R_ADDROFF), so // later by relocsym (R_TLS_LE, R_ADDROFF), so
// don't worry if Adddynrel returns false. // don't worry if Adddynrel returns false.
...@@ -804,7 +804,7 @@ func Datblk(ctxt *Link, addr int64, size int64) { ...@@ -804,7 +804,7 @@ func Datblk(ctxt *Link, addr int64, size int64) {
} }
ctxt.Logf("\n") ctxt.Logf("\n")
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
continue continue
} }
for _, r := range sym.R { for _, r := range sym.R {
...@@ -850,7 +850,7 @@ func addstrdata1(ctxt *Link, arg string) { ...@@ -850,7 +850,7 @@ func addstrdata1(ctxt *Link, arg string) {
Exitf("-X flag requires argument of the form importpath.name=value") Exitf("-X flag requires argument of the form importpath.name=value")
} }
pkg := objabi.PathToPrefix(arg[:dot]) pkg := objabi.PathToPrefix(arg[:dot])
if Buildmode == BuildmodePlugin && pkg == "main" { if ctxt.BuildMode == BuildModePlugin && pkg == "main" {
pkg = *flagPluginPath pkg = *flagPluginPath
} }
addstrdata(ctxt, pkg+arg[dot:eq], arg[eq+1:]) addstrdata(ctxt, pkg+arg[dot:eq], arg[eq+1:])
...@@ -931,8 +931,8 @@ func addinitarrdata(ctxt *Link, s *sym.Symbol) { ...@@ -931,8 +931,8 @@ func addinitarrdata(ctxt *Link, s *sym.Symbol) {
} }
func dosymtype(ctxt *Link) { func dosymtype(ctxt *Link) {
switch Buildmode { switch ctxt.BuildMode {
case BuildmodeCArchive, BuildmodeCShared: case BuildModeCArchive, BuildModeCShared:
for _, s := range ctxt.Syms.Allsym { for _, s := range ctxt.Syms.Allsym {
// Create a new entry in the .init_array section that points to the // Create a new entry in the .init_array section that points to the
// library initializer function. // library initializer function.
...@@ -1139,7 +1139,7 @@ func (ctxt *Link) dodata() { ...@@ -1139,7 +1139,7 @@ func (ctxt *Link) dodata() {
} }
dynreloc(ctxt, &data) dynreloc(ctxt, &data)
if UseRelro() { if ctxt.UseRelro() {
// "read only" data with relocations needs to go in its own section // "read only" data with relocations needs to go in its own section
// when building a shared library. We do this by boosting objects of // when building a shared library. We do this by boosting objects of
// type SXXX with relocations to type SXXXRELRO. // type SXXX with relocations to type SXXXRELRO.
...@@ -1276,8 +1276,8 @@ func (ctxt *Link) dodata() { ...@@ -1276,8 +1276,8 @@ func (ctxt *Link) dodata() {
hasinitarr := *FlagLinkshared hasinitarr := *FlagLinkshared
/* shared library initializer */ /* shared library initializer */
switch Buildmode { switch ctxt.BuildMode {
case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared, BuildmodePlugin: case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
hasinitarr = true hasinitarr = true
} }
if hasinitarr { if hasinitarr {
...@@ -1356,7 +1356,7 @@ func (ctxt *Link) dodata() { ...@@ -1356,7 +1356,7 @@ func (ctxt *Link) dodata() {
if len(data[sym.STLSBSS]) > 0 { if len(data[sym.STLSBSS]) > 0 {
var sect *sym.Section var sect *sym.Section
if Iself && (Linkmode == LinkExternal || !*FlagD) { if Iself && (ctxt.LinkMode == LinkExternal || !*FlagD) {
sect = addsection(ctxt.Arch, &Segdata, ".tbss", 06) sect = addsection(ctxt.Arch, &Segdata, ".tbss", 06)
sect.Align = int32(ctxt.Arch.PtrSize) sect.Align = int32(ctxt.Arch.PtrSize)
sect.Vaddr = 0 sect.Vaddr = 0
...@@ -1387,7 +1387,7 @@ func (ctxt *Link) dodata() { ...@@ -1387,7 +1387,7 @@ func (ctxt *Link) dodata() {
* segtext. * segtext.
*/ */
var segro *sym.Segment var segro *sym.Segment
if Iself && Linkmode == LinkInternal { if Iself && ctxt.LinkMode == LinkInternal {
segro = &Segrodata segro = &Segrodata
} else { } else {
segro = &Segtext segro = &Segtext
...@@ -1418,7 +1418,7 @@ func (ctxt *Link) dodata() { ...@@ -1418,7 +1418,7 @@ func (ctxt *Link) dodata() {
sect.Vaddr = 0 sect.Vaddr = 0
ctxt.Syms.Lookup("runtime.rodata", 0).Sect = sect ctxt.Syms.Lookup("runtime.rodata", 0).Sect = sect
ctxt.Syms.Lookup("runtime.erodata", 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.types", 0).Sect = sect
ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect ctxt.Syms.Lookup("runtime.etypes", 0).Sect = sect
} }
...@@ -1482,10 +1482,10 @@ func (ctxt *Link) dodata() { ...@@ -1482,10 +1482,10 @@ func (ctxt *Link) dodata() {
return addsection(ctxt.Arch, segro, suffix, 04) return addsection(ctxt.Arch, segro, suffix, 04)
} }
if UseRelro() { if ctxt.UseRelro() {
addrelrosection = func(suffix string) *sym.Section { addrelrosection = func(suffix string) *sym.Section {
seg := &Segrelrodata seg := &Segrelrodata
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
// Using a separate segment with an external // Using a separate segment with an external
// linker results in some programs moving // linker results in some programs moving
// their data sections unexpectedly, which // their data sections unexpectedly, which
...@@ -1799,7 +1799,7 @@ func dodataSect(ctxt *Link, symn sym.SymKind, syms []*sym.Symbol) (result []*sym ...@@ -1799,7 +1799,7 @@ func dodataSect(ctxt *Link, symn sym.SymKind, syms []*sym.Symbol) (result []*sym
// at the very beginning of the text segment. // at the very beginning of the text segment.
// This ``header'' is read by cmd/go. // This ``header'' is read by cmd/go.
func (ctxt *Link) textbuildid() { func (ctxt *Link) textbuildid() {
if Iself || Buildmode == BuildmodePlugin || *flagBuildid == "" { if Iself || ctxt.BuildMode == BuildModePlugin || *flagBuildid == "" {
return return
} }
...@@ -1907,7 +1907,7 @@ func assignAddress(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint6 ...@@ -1907,7 +1907,7 @@ func assignAddress(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint6
// Only break at outermost syms. // 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 // Set the length for the previous text section
sect.Length = va - sect.Vaddr sect.Length = va - sect.Vaddr
...@@ -2091,7 +2091,7 @@ func (ctxt *Link) address() { ...@@ -2091,7 +2091,7 @@ func (ctxt *Link) address() {
} }
} }
if Buildmode == BuildmodeShared { if ctxt.BuildMode == BuildModeShared {
s := ctxt.Syms.Lookup("go.link.abihashbytes", 0) s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
sectSym := ctxt.Syms.Lookup(".note.go.abihash", 0) sectSym := ctxt.Syms.Lookup(".note.go.abihash", 0)
s.Sect = sectSym.Sect s.Sect = sectSym.Sect
......
...@@ -108,9 +108,9 @@ func deadcode(ctxt *Link) { ...@@ -108,9 +108,9 @@ func deadcode(ctxt *Link) {
} }
} }
if Buildmode != BuildmodeShared { if ctxt.BuildMode != BuildModeShared {
// Keep a itablink if the symbol it points at is being kept. // 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 { for _, s := range ctxt.Syms.Allsym {
if strings.HasPrefix(s.Name, "go.itablink.") { if strings.HasPrefix(s.Name, "go.itablink.") {
s.Attr.Set(sym.AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable()) s.Attr.Set(sym.AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable())
...@@ -205,7 +205,7 @@ func (d *deadcodepass) init() { ...@@ -205,7 +205,7 @@ func (d *deadcodepass) init() {
names = append(names, "runtime.read_tls_fallback") 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 // Mark all symbols defined in this library as reachable when
// building a shared library. // building a shared library.
for _, s := range d.ctxt.Syms.Allsym { for _, s := range d.ctxt.Syms.Allsym {
...@@ -217,11 +217,11 @@ func (d *deadcodepass) init() { ...@@ -217,11 +217,11 @@ func (d *deadcodepass) init() {
// In a normal binary, start at main.main and the init // In a normal binary, start at main.main and the init
// functions and mark what is reachable from there. // 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") names = append(names, "main.main", "main.init")
} else { } else {
// The external linker refers main symbol directly. // 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 { if Headtype == objabi.Hwindows && d.ctxt.Arch.Family == sys.I386 {
*flagEntrySymbol = "_main" *flagEntrySymbol = "_main"
} else { } else {
...@@ -229,7 +229,7 @@ func (d *deadcodepass) init() { ...@@ -229,7 +229,7 @@ func (d *deadcodepass) init() {
} }
} }
names = append(names, *flagEntrySymbol) names = append(names, *flagEntrySymbol)
if Buildmode == BuildmodePlugin { if d.ctxt.BuildMode == BuildModePlugin {
names = append(names, *flagPluginPath+".init", *flagPluginPath+".main", "go.plugin.tabs") names = append(names, *flagPluginPath+".init", *flagPluginPath+".main", "go.plugin.tabs")
// We don't keep the go.plugin.exports symbol, // We don't keep the go.plugin.exports symbol,
......
...@@ -979,8 +979,8 @@ func importInfoSymbol(ctxt *Link, dsym *sym.Symbol) { ...@@ -979,8 +979,8 @@ func importInfoSymbol(ctxt *Link, dsym *sym.Symbol) {
dsym.Type = sym.SDWARFINFO dsym.Type = sym.SDWARFINFO
for _, r := range dsym.R { for _, r := range dsym.R {
if r.Type == objabi.R_DWARFREF && r.Sym.Size == 0 { if r.Type == objabi.R_DWARFREF && r.Sym.Size == 0 {
if Buildmode == BuildmodeShared { if ctxt.BuildMode == BuildModeShared {
// These type symbols may not be present in BuildmodeShared. Skip. // These type symbols may not be present in BuildModeShared. Skip.
continue continue
} }
n := nameFromDIESym(r.Sym) n := nameFromDIESym(r.Sym)
...@@ -1259,7 +1259,7 @@ func writeframes(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol { ...@@ -1259,7 +1259,7 @@ func writeframes(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
// ptrsize: initial location // ptrsize: initial location
// ptrsize: address range // ptrsize: address range
fs.AddUint32(ctxt.Arch, uint32(4+2*ctxt.Arch.PtrSize+len(deltaBuf))) // length (excludes itself) 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) adddwarfref(ctxt, fs, fs, 4)
} else { } else {
fs.AddUint32(ctxt.Arch, 0) // CIE offset fs.AddUint32(ctxt.Arch, 0) // CIE offset
...@@ -1454,7 +1454,7 @@ func writearanges(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol { ...@@ -1454,7 +1454,7 @@ func writearanges(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol {
} }
func writegdbscript(ctxt *Link, syms []*sym.Symbol) []*sym.Symbol { 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 // gcc on Windows places .debug_gdb_scripts in the wrong location, which
// causes the program not to run. See https://golang.org/issue/20183 // causes the program not to run. See https://golang.org/issue/20183
// Non c-archives can avoid this issue via a linker script // Non c-archives can avoid this issue via a linker script
...@@ -1497,7 +1497,7 @@ func dwarfgeneratedebugsyms(ctxt *Link) { ...@@ -1497,7 +1497,7 @@ func dwarfgeneratedebugsyms(ctxt *Link) {
return return
} }
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
switch { switch {
case Iself: case Iself:
case Headtype == objabi.Hdarwin: case Headtype == objabi.Hdarwin:
...@@ -1635,7 +1635,7 @@ func dwarfaddshstrings(ctxt *Link, shstrtab *sym.Symbol) { ...@@ -1635,7 +1635,7 @@ func dwarfaddshstrings(ctxt *Link, shstrtab *sym.Symbol) {
Addstring(shstrtab, ".debug_pubtypes") Addstring(shstrtab, ".debug_pubtypes")
Addstring(shstrtab, ".debug_gdb_scripts") Addstring(shstrtab, ".debug_gdb_scripts")
Addstring(shstrtab, ".debug_ranges") Addstring(shstrtab, ".debug_ranges")
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
Addstring(shstrtab, elfRelType+".debug_info") Addstring(shstrtab, elfRelType+".debug_info")
Addstring(shstrtab, elfRelType+".debug_loc") Addstring(shstrtab, elfRelType+".debug_loc")
Addstring(shstrtab, elfRelType+".debug_aranges") Addstring(shstrtab, elfRelType+".debug_aranges")
...@@ -1653,7 +1653,7 @@ func dwarfaddelfsectionsyms(ctxt *Link) { ...@@ -1653,7 +1653,7 @@ func dwarfaddelfsectionsyms(ctxt *Link) {
if *FlagW { // disable dwarf if *FlagW { // disable dwarf
return return
} }
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
return return
} }
s := ctxt.Syms.Lookup(".debug_info", 0) s := ctxt.Syms.Lookup(".debug_info", 0)
......
...@@ -1647,7 +1647,7 @@ func elfshalloc(sect *sym.Section) *ElfShdr { ...@@ -1647,7 +1647,7 @@ func elfshalloc(sect *sym.Section) *ElfShdr {
return sh return sh
} }
func elfshbits(sect *sym.Section) *ElfShdr { func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr {
var sh *ElfShdr var sh *ElfShdr
if sect.Name == ".text" { if sect.Name == ".text" {
...@@ -1662,7 +1662,7 @@ func elfshbits(sect *sym.Section) *ElfShdr { ...@@ -1662,7 +1662,7 @@ func elfshbits(sect *sym.Section) *ElfShdr {
// If this section has already been set up as a note, we assume type_ and // 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. // flags are already correct, but the other fields still need filling in.
if sh.type_ == SHT_NOTE { if sh.type_ == SHT_NOTE {
if Linkmode != LinkExternal { if linkmode != LinkExternal {
// TODO(mwhudson): the approach here will work OK when // TODO(mwhudson): the approach here will work OK when
// linking internally for notes that we want to be included // linking internally for notes that we want to be included
// in a loadable segment (e.g. the abihash note) but not for // in a loadable segment (e.g. the abihash note) but not for
...@@ -1701,7 +1701,7 @@ func elfshbits(sect *sym.Section) *ElfShdr { ...@@ -1701,7 +1701,7 @@ func elfshbits(sect *sym.Section) *ElfShdr {
sh.flags = 0 sh.flags = 0
} }
if Linkmode != LinkExternal { if linkmode != LinkExternal {
sh.addr = sect.Vaddr sh.addr = sect.Vaddr
} }
sh.addralign = uint64(sect.Align) sh.addralign = uint64(sect.Align)
...@@ -1881,7 +1881,7 @@ func (ctxt *Link) doelf() { ...@@ -1881,7 +1881,7 @@ func (ctxt *Link) doelf() {
// generate .tbss section for dynamic internal linker or external // generate .tbss section for dynamic internal linker or external
// linking, so that various binutils could correctly calculate // linking, so that various binutils could correctly calculate
// PT_TLS size. See https://golang.org/issue/5200. // PT_TLS size. See https://golang.org/issue/5200.
if !*FlagD || Linkmode == LinkExternal { if !*FlagD || ctxt.LinkMode == LinkExternal {
Addstring(shstrtab, ".tbss") Addstring(shstrtab, ".tbss")
} }
if Headtype == objabi.Hnetbsd { if Headtype == objabi.Hnetbsd {
...@@ -1900,7 +1900,7 @@ func (ctxt *Link) doelf() { ...@@ -1900,7 +1900,7 @@ func (ctxt *Link) doelf() {
Addstring(shstrtab, ".rodata") Addstring(shstrtab, ".rodata")
// See the comment about data.rel.ro.FOO section names in data.go. // See the comment about data.rel.ro.FOO section names in data.go.
relro_prefix := "" relro_prefix := ""
if UseRelro() { if ctxt.UseRelro() {
Addstring(shstrtab, ".data.rel.ro") Addstring(shstrtab, ".data.rel.ro")
relro_prefix = ".data.rel.ro" relro_prefix = ".data.rel.ro"
} }
...@@ -1909,7 +1909,7 @@ func (ctxt *Link) doelf() { ...@@ -1909,7 +1909,7 @@ func (ctxt *Link) doelf() {
Addstring(shstrtab, relro_prefix+".gosymtab") Addstring(shstrtab, relro_prefix+".gosymtab")
Addstring(shstrtab, relro_prefix+".gopclntab") Addstring(shstrtab, relro_prefix+".gopclntab")
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
*FlagD = true *FlagD = true
Addstring(shstrtab, elfRelType+".text") Addstring(shstrtab, elfRelType+".text")
...@@ -1920,14 +1920,14 @@ func (ctxt *Link) doelf() { ...@@ -1920,14 +1920,14 @@ func (ctxt *Link) doelf() {
Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab") Addstring(shstrtab, elfRelType+relro_prefix+".gopclntab")
Addstring(shstrtab, elfRelType+".noptrdata") Addstring(shstrtab, elfRelType+".noptrdata")
Addstring(shstrtab, elfRelType+".data") Addstring(shstrtab, elfRelType+".data")
if UseRelro() { if ctxt.UseRelro() {
Addstring(shstrtab, elfRelType+".data.rel.ro") Addstring(shstrtab, elfRelType+".data.rel.ro")
} }
// add a .note.GNU-stack section to mark the stack as non-executable // add a .note.GNU-stack section to mark the stack as non-executable
Addstring(shstrtab, ".note.GNU-stack") Addstring(shstrtab, ".note.GNU-stack")
if Buildmode == BuildmodeShared { if ctxt.BuildMode == BuildModeShared {
Addstring(shstrtab, ".note.go.abihash") Addstring(shstrtab, ".note.go.abihash")
Addstring(shstrtab, ".note.go.pkg-list") Addstring(shstrtab, ".note.go.pkg-list")
Addstring(shstrtab, ".note.go.deps") Addstring(shstrtab, ".note.go.deps")
...@@ -1937,8 +1937,8 @@ func (ctxt *Link) doelf() { ...@@ -1937,8 +1937,8 @@ func (ctxt *Link) doelf() {
hasinitarr := *FlagLinkshared hasinitarr := *FlagLinkshared
/* shared library initializer */ /* shared library initializer */
switch Buildmode { switch ctxt.BuildMode {
case BuildmodeCArchive, BuildmodeCShared, BuildmodeShared, BuildmodePlugin: case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePlugin:
hasinitarr = true hasinitarr = true
} }
...@@ -2099,7 +2099,7 @@ func (ctxt *Link) doelf() { ...@@ -2099,7 +2099,7 @@ func (ctxt *Link) doelf() {
Elfwritedynent(ctxt, s, DT_DEBUG, 0) Elfwritedynent(ctxt, s, DT_DEBUG, 0)
} }
if Buildmode == BuildmodeShared { if ctxt.BuildMode == BuildModeShared {
// The go.link.abihashbytes symbol will be pointed at the appropriate // The go.link.abihashbytes symbol will be pointed at the appropriate
// part of the .note.go.abihash section in data.go:func address(). // part of the .note.go.abihash section in data.go:func address().
s := ctxt.Syms.Lookup("go.link.abihashbytes", 0) s := ctxt.Syms.Lookup("go.link.abihashbytes", 0)
...@@ -2123,7 +2123,7 @@ func (ctxt *Link) doelf() { ...@@ -2123,7 +2123,7 @@ func (ctxt *Link) doelf() {
addgonote(ctxt, ".note.go.deps", ELF_NOTE_GODEPS_TAG, []byte(strings.Join(deplist, "\n"))) 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)) addgonote(ctxt, ".note.go.buildid", ELF_NOTE_GOBUILDID_TAG, []byte(*flagBuildid))
} }
} }
...@@ -2220,13 +2220,13 @@ func Asmbelf(ctxt *Link, symo int64) { ...@@ -2220,13 +2220,13 @@ func Asmbelf(ctxt *Link, symo int64) {
var pph *ElfPhdr var pph *ElfPhdr
var pnote *ElfPhdr var pnote *ElfPhdr
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
/* skip program headers */ /* skip program headers */
eh.phoff = 0 eh.phoff = 0
eh.phentsize = 0 eh.phentsize = 0
if Buildmode == BuildmodeShared { if ctxt.BuildMode == BuildModeShared {
sh := elfshname(".note.go.pkg-list") sh := elfshname(".note.go.pkg-list")
sh.type_ = SHT_NOTE sh.type_ = SHT_NOTE
sh = elfshname(".note.go.abihash") sh = elfshname(".note.go.abihash")
...@@ -2551,22 +2551,22 @@ elfobj: ...@@ -2551,22 +2551,22 @@ elfobj:
} }
for _, sect := range Segtext.Sections { for _, sect := range Segtext.Sections {
elfshbits(sect) elfshbits(ctxt.LinkMode, sect)
} }
for _, sect := range Segrodata.Sections { for _, sect := range Segrodata.Sections {
elfshbits(sect) elfshbits(ctxt.LinkMode, sect)
} }
for _, sect := range Segrelrodata.Sections { for _, sect := range Segrelrodata.Sections {
elfshbits(sect) elfshbits(ctxt.LinkMode, sect)
} }
for _, sect := range Segdata.Sections { for _, sect := range Segdata.Sections {
elfshbits(sect) elfshbits(ctxt.LinkMode, sect)
} }
for _, sect := range Segdwarf.Sections { for _, sect := range Segdwarf.Sections {
elfshbits(sect) elfshbits(ctxt.LinkMode, sect)
} }
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
for _, sect := range Segtext.Sections { for _, sect := range Segtext.Sections {
elfshreloc(ctxt.Arch, sect) elfshreloc(ctxt.Arch, sect)
} }
...@@ -2636,15 +2636,15 @@ elfobj: ...@@ -2636,15 +2636,15 @@ elfobj:
} }
eh.ident[EI_VERSION] = EV_CURRENT eh.ident[EI_VERSION] = EV_CURRENT
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
eh.type_ = ET_REL eh.type_ = ET_REL
} else if Buildmode == BuildmodePIE { } else if ctxt.BuildMode == BuildModePIE {
eh.type_ = ET_DYN eh.type_ = ET_DYN
} else { } else {
eh.type_ = ET_EXEC eh.type_ = ET_EXEC
} }
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
eh.entry = uint64(Entryvalue(ctxt)) eh.entry = uint64(Entryvalue(ctxt))
} }
...@@ -2663,7 +2663,7 @@ elfobj: ...@@ -2663,7 +2663,7 @@ elfobj:
if !*FlagD { if !*FlagD {
a += int64(elfwriteinterp(ctxt.Out)) a += int64(elfwriteinterp(ctxt.Out))
} }
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
if Headtype == objabi.Hnetbsd { if Headtype == objabi.Hnetbsd {
a += int64(elfwritenetbsdsig(ctxt.Out)) a += int64(elfwritenetbsdsig(ctxt.Out))
} }
......
...@@ -172,7 +172,7 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) { ...@@ -172,7 +172,7 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
havedynamic = 1 havedynamic = 1
if Headtype == objabi.Hdarwin { if Headtype == objabi.Hdarwin {
machoadddynlib(lib) machoadddynlib(lib, ctxt.LinkMode)
} else { } else {
dynlib = append(dynlib, lib) dynlib = append(dynlib, lib)
} }
...@@ -223,8 +223,8 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) { ...@@ -223,8 +223,8 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
local = expandpkg(local, pkg) local = expandpkg(local, pkg)
s = ctxt.Syms.Lookup(local, 0) s = ctxt.Syms.Lookup(local, 0)
switch Buildmode { switch ctxt.BuildMode {
case BuildmodeCShared, BuildmodeCArchive, BuildmodePlugin: case BuildModeCShared, BuildModeCArchive, BuildModePlugin:
if s == ctxt.Syms.Lookup("main", 0) { if s == ctxt.Syms.Lookup("main", 0) {
continue continue
} }
...@@ -293,7 +293,7 @@ err: ...@@ -293,7 +293,7 @@ err:
var seenlib = make(map[string]bool) var seenlib = make(map[string]bool)
func adddynlib(ctxt *Link, lib string) { func adddynlib(ctxt *Link, lib string) {
if seenlib[lib] || Linkmode == LinkExternal { if seenlib[lib] || ctxt.LinkMode == LinkExternal {
return return
} }
seenlib[lib] = true seenlib[lib] = true
...@@ -310,7 +310,7 @@ func adddynlib(ctxt *Link, lib string) { ...@@ -310,7 +310,7 @@ func adddynlib(ctxt *Link, lib string) {
} }
func Adddynsym(ctxt *Link, s *sym.Symbol) { func Adddynsym(ctxt *Link, s *sym.Symbol) {
if s.Dynid >= 0 || Linkmode == LinkExternal { if s.Dynid >= 0 || ctxt.LinkMode == LinkExternal {
return return
} }
......
This diff is collapsed.
...@@ -60,6 +60,9 @@ type Link struct { ...@@ -60,6 +60,9 @@ type Link struct {
Loaded bool // set after all inputs have been loaded as symbols Loaded bool // set after all inputs have been loaded as symbols
LinkMode LinkMode
BuildMode BuildMode
Tlsg *sym.Symbol Tlsg *sym.Symbol
Libdir []string Libdir []string
Library []*sym.Library Library []*sym.Library
......
...@@ -230,7 +230,7 @@ var dylib []string ...@@ -230,7 +230,7 @@ var dylib []string
var linkoff int64 var linkoff int64
func machowrite(arch *sys.Arch, out *OutBuf) int { func machowrite(arch *sys.Arch, out *OutBuf, linkmode LinkMode) int {
o1 := out.Offset() o1 := out.Offset()
loadsize := 4 * 4 * ndebug loadsize := 4 * 4 * ndebug
...@@ -252,7 +252,7 @@ func machowrite(arch *sys.Arch, out *OutBuf) int { ...@@ -252,7 +252,7 @@ func machowrite(arch *sys.Arch, out *OutBuf) int {
} }
out.Write32(machohdr.cpu) out.Write32(machohdr.cpu)
out.Write32(machohdr.subcpu) out.Write32(machohdr.subcpu)
if Linkmode == LinkExternal { if linkmode == LinkExternal {
out.Write32(MH_OBJECT) /* file type - mach object */ out.Write32(MH_OBJECT) /* file type - mach object */
} else { } else {
out.Write32(MH_EXECUTE) /* file type - mach executable */ out.Write32(MH_EXECUTE) /* file type - mach executable */
...@@ -356,7 +356,7 @@ func (ctxt *Link) domacho() { ...@@ -356,7 +356,7 @@ func (ctxt *Link) domacho() {
s.Type = sym.SMACHOSYMTAB s.Type = sym.SMACHOSYMTAB
s.Attr |= sym.AttrReachable s.Attr |= sym.AttrReachable
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
s := ctxt.Syms.Lookup(".plt", 0) // will be __symbol_stub s := ctxt.Syms.Lookup(".plt", 0) // will be __symbol_stub
s.Type = sym.SMACHOPLT s.Type = sym.SMACHOPLT
s.Attr |= sym.AttrReachable s.Attr |= sym.AttrReachable
...@@ -376,8 +376,8 @@ func (ctxt *Link) domacho() { ...@@ -376,8 +376,8 @@ func (ctxt *Link) domacho() {
} }
} }
func machoadddynlib(lib string) { func machoadddynlib(lib string, linkmode LinkMode) {
if seenlib[lib] || Linkmode == LinkExternal { if seenlib[lib] || linkmode == LinkExternal {
return return
} }
seenlib[lib] = true seenlib[lib] = true
...@@ -402,8 +402,8 @@ func machoshbits(ctxt *Link, mseg *MachoSeg, sect *sym.Section, segname string) ...@@ -402,8 +402,8 @@ func machoshbits(ctxt *Link, mseg *MachoSeg, sect *sym.Section, segname string)
var msect *MachoSect var msect *MachoSect
if sect.Rwx&1 == 0 && segname != "__DWARF" && (ctxt.Arch.Family == sys.ARM64 || if sect.Rwx&1 == 0 && segname != "__DWARF" && (ctxt.Arch.Family == sys.ARM64 ||
(ctxt.Arch.Family == sys.AMD64 && Buildmode != BuildmodeExe) || (ctxt.Arch.Family == sys.AMD64 && ctxt.BuildMode != BuildModeExe) ||
(ctxt.Arch.Family == sys.ARM && 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 // 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 // complains about absolute relocs in __TEXT, so if the section is not
// executable, put it in __DATA segment. // executable, put it in __DATA segment.
...@@ -488,12 +488,12 @@ func Asmbmacho(ctxt *Link) { ...@@ -488,12 +488,12 @@ func Asmbmacho(ctxt *Link) {
} }
var ms *MachoSeg var ms *MachoSeg
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
/* segment for entire file */ /* segment for entire file */
ms = newMachoSeg("", 40) ms = newMachoSeg("", 40)
ms.fileoffset = Segtext.Fileoff 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 ms.filesize = Segdata.Fileoff + Segdata.Filelen - Segtext.Fileoff
} else { } else {
ms.filesize = Segdwarf.Fileoff + Segdwarf.Filelen - Segtext.Fileoff ms.filesize = Segdwarf.Fileoff + Segdwarf.Filelen - Segtext.Fileoff
...@@ -502,7 +502,7 @@ func Asmbmacho(ctxt *Link) { ...@@ -502,7 +502,7 @@ func Asmbmacho(ctxt *Link) {
} }
/* segment for zero page */ /* segment for zero page */
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
ms = newMachoSeg("__PAGEZERO", 0) ms = newMachoSeg("__PAGEZERO", 0)
ms.vsize = uint64(va) ms.vsize = uint64(va)
} }
...@@ -510,7 +510,7 @@ func Asmbmacho(ctxt *Link) { ...@@ -510,7 +510,7 @@ func Asmbmacho(ctxt *Link) {
/* text */ /* text */
v := Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound)) v := Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound))
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
ms = newMachoSeg("__TEXT", 20) ms = newMachoSeg("__TEXT", 20)
ms.vaddr = uint64(va) ms.vaddr = uint64(va)
ms.vsize = uint64(v) ms.vsize = uint64(v)
...@@ -525,7 +525,7 @@ func Asmbmacho(ctxt *Link) { ...@@ -525,7 +525,7 @@ func Asmbmacho(ctxt *Link) {
} }
/* data */ /* data */
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
w := int64(Segdata.Length) w := int64(Segdata.Length)
ms = newMachoSeg("__DATA", 20) ms = newMachoSeg("__DATA", 20)
ms.vaddr = uint64(va) + uint64(v) ms.vaddr = uint64(va) + uint64(v)
...@@ -542,7 +542,7 @@ func Asmbmacho(ctxt *Link) { ...@@ -542,7 +542,7 @@ func Asmbmacho(ctxt *Link) {
/* dwarf */ /* dwarf */
if !*FlagW { if !*FlagW {
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
ms = newMachoSeg("__DWARF", 20) ms = newMachoSeg("__DWARF", 20)
ms.vaddr = Segdwarf.Vaddr ms.vaddr = Segdwarf.Vaddr
ms.vsize = 0 ms.vsize = 0
...@@ -554,7 +554,7 @@ func Asmbmacho(ctxt *Link) { ...@@ -554,7 +554,7 @@ func Asmbmacho(ctxt *Link) {
} }
} }
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
switch ctxt.Arch.Family { switch ctxt.Arch.Family {
default: default:
Exitf("unknown macho architecture: %v", ctxt.Arch.Family) Exitf("unknown macho architecture: %v", ctxt.Arch.Family)
...@@ -594,7 +594,7 @@ func Asmbmacho(ctxt *Link) { ...@@ -594,7 +594,7 @@ func Asmbmacho(ctxt *Link) {
s3 := ctxt.Syms.Lookup(".linkedit.got", 0) s3 := ctxt.Syms.Lookup(".linkedit.got", 0)
s4 := ctxt.Syms.Lookup(".machosymstr", 0) s4 := ctxt.Syms.Lookup(".machosymstr", 0)
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
ms := newMachoSeg("__LINKEDIT", 0) ms := newMachoSeg("__LINKEDIT", 0)
ms.vaddr = uint64(va) + uint64(v) + uint64(Rnd(int64(Segdata.Length), int64(*FlagRound))) 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) ms.vsize = uint64(s1.Size) + uint64(s2.Size) + uint64(s3.Size) + uint64(s4.Size)
...@@ -612,7 +612,7 @@ func Asmbmacho(ctxt *Link) { ...@@ -612,7 +612,7 @@ func Asmbmacho(ctxt *Link) {
machodysymtab(ctxt) machodysymtab(ctxt)
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
ml := newMachoLoad(ctxt.Arch, LC_LOAD_DYLINKER, 6) ml := newMachoLoad(ctxt.Arch, LC_LOAD_DYLINKER, 6)
ml.data[0] = 12 /* offset to string */ ml.data[0] = 12 /* offset to string */
stringtouint32(ml.data[1:], "/usr/lib/dyld") stringtouint32(ml.data[1:], "/usr/lib/dyld")
...@@ -628,7 +628,7 @@ func Asmbmacho(ctxt *Link) { ...@@ -628,7 +628,7 @@ func Asmbmacho(ctxt *Link) {
} }
} }
if Linkmode == LinkInternal { if ctxt.LinkMode == LinkInternal {
// For lldb, must say LC_VERSION_MIN_MACOSX or else // For lldb, must say LC_VERSION_MIN_MACOSX or else
// it won't know that this Mach-O binary is from OS X // it won't know that this Mach-O binary is from OS X
// (could be iOS or WatchOS instead). // (could be iOS or WatchOS instead).
...@@ -642,7 +642,7 @@ func Asmbmacho(ctxt *Link) { ...@@ -642,7 +642,7 @@ func Asmbmacho(ctxt *Link) {
ml.data[1] = 10<<16 | 7<<8 | 0<<0 // SDK 10.7.0 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 { if int32(a) > HEADR {
Exitf("HEADR too small: %d > %d", a, HEADR) Exitf("HEADR too small: %d > %d", a, HEADR)
} }
...@@ -738,7 +738,7 @@ func machoShouldExport(ctxt *Link, s *sym.Symbol) bool { ...@@ -738,7 +738,7 @@ func machoShouldExport(ctxt *Link, s *sym.Symbol) bool {
if !ctxt.DynlinkingGo() || s.Attr.Local() { if !ctxt.DynlinkingGo() || s.Attr.Local() {
return false 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 return true
} }
if strings.HasPrefix(s.Name, "go.itab.") { if strings.HasPrefix(s.Name, "go.itab.") {
...@@ -773,7 +773,7 @@ func machosymtab(ctxt *Link) { ...@@ -773,7 +773,7 @@ func machosymtab(ctxt *Link) {
// symbols like crosscall2 are in pclntab and end up // symbols like crosscall2 are in pclntab and end up
// pointing at the host binary, breaking unwinding. // pointing at the host binary, breaking unwinding.
// See Issue #18190. // 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 { if cexport || export {
symstr.AddUint8('_') symstr.AddUint8('_')
} }
......
...@@ -91,7 +91,7 @@ func (r loadCmdReader) WriteAt(offset int64, data interface{}) error { ...@@ -91,7 +91,7 @@ func (r loadCmdReader) WriteAt(offset int64, data interface{}) error {
// header to add the DWARF sections. (Use ld's -headerpad option) // header to add the DWARF sections. (Use ld's -headerpad option)
// dsym is the path to the macho file containing DWARF from dsymutil. // dsym is the path to the macho file containing DWARF from dsymutil.
// outexe is the path where the combined executable should be saved. // 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) exef, err := os.Open(inexe)
if err != nil { if err != nil {
return err return err
...@@ -230,7 +230,7 @@ func machoCombineDwarf(inexe, dsym, outexe string) error { ...@@ -230,7 +230,7 @@ func machoCombineDwarf(inexe, dsym, outexe string) error {
return err return err
} }
} }
return machoUpdateDwarfHeader(&reader) return machoUpdateDwarfHeader(&reader, buildmode)
} }
// machoUpdateSegment updates the load command for a moved segment. // machoUpdateSegment updates the load command for a moved segment.
...@@ -291,7 +291,7 @@ func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, deltaOffset, ...@@ -291,7 +291,7 @@ func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, deltaOffset,
} }
// machoUpdateDwarfHeader updates the DWARF segment load command. // machoUpdateDwarfHeader updates the DWARF segment load command.
func machoUpdateDwarfHeader(r *loadCmdReader) error { func machoUpdateDwarfHeader(r *loadCmdReader, buildmode BuildMode) error {
var seg, sect interface{} var seg, sect interface{}
cmd, err := r.Next() cmd, err := r.Next()
if err != nil { if err != nil {
...@@ -321,7 +321,7 @@ func machoUpdateDwarfHeader(r *loadCmdReader) error { ...@@ -321,7 +321,7 @@ func machoUpdateDwarfHeader(r *loadCmdReader) error {
// We don't need the DWARF information actually available in memory. // We don't need the DWARF information actually available in memory.
// But if we do this for buildmode=c-shared then the user-space // But if we do this for buildmode=c-shared then the user-space
// dynamic loader complains about memsz < filesz. Sigh. // dynamic loader complains about memsz < filesz. Sigh.
if Buildmode != BuildmodeCShared { if buildmode != BuildModeCShared {
segv.FieldByName("Addr").SetUint(0) segv.FieldByName("Addr").SetUint(0)
segv.FieldByName("Memsz").SetUint(0) segv.FieldByName("Memsz").SetUint(0)
deltaAddr = 0 deltaAddr = 0
......
...@@ -48,8 +48,6 @@ var ( ...@@ -48,8 +48,6 @@ var (
) )
func init() { 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:...") flag.Var(&rpath, "r", "set the ELF dynamic linker search `path` to dir1:dir2:...")
} }
...@@ -118,6 +116,8 @@ func Main(arch *sys.Arch, theArch Arch) { ...@@ -118,6 +116,8 @@ func Main(arch *sys.Arch, theArch Arch) {
if ctxt.Arch.Family == sys.AMD64 && objabi.GOOS == "plan9" { if ctxt.Arch.Family == sys.AMD64 && objabi.GOOS == "plan9" {
flag.BoolVar(&Flag8, "8", false, "use 64-bit addresses in symbol table") 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("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.Flagfn1("L", "add specified `directory` to library path", func(a string) { Lflag(ctxt, a) })
objabi.Flagfn0("V", "print version and exit", doversion) objabi.Flagfn0("V", "print version and exit", doversion)
...@@ -140,11 +140,11 @@ func Main(arch *sys.Arch, theArch Arch) { ...@@ -140,11 +140,11 @@ func Main(arch *sys.Arch, theArch Arch) {
} }
startProfile() startProfile()
if Buildmode == BuildmodeUnset { if ctxt.BuildMode == BuildModeUnset {
Buildmode = BuildmodeExe ctxt.BuildMode = BuildModeExe
} }
if Buildmode != BuildmodeShared && flag.NArg() != 1 { if ctxt.BuildMode != BuildModeShared && flag.NArg() != 1 {
usage() usage()
} }
...@@ -174,8 +174,8 @@ func Main(arch *sys.Arch, theArch Arch) { ...@@ -174,8 +174,8 @@ func Main(arch *sys.Arch, theArch Arch) {
ctxt.Logf("HEADER = -H%d -T0x%x -D0x%x -R0x%x\n", Headtype, uint64(*FlagTextAddr), uint64(*FlagDataAddr), uint32(*FlagRound)) ctxt.Logf("HEADER = -H%d -T0x%x -D0x%x -R0x%x\n", Headtype, uint64(*FlagTextAddr), uint64(*FlagDataAddr), uint32(*FlagRound))
} }
switch Buildmode { switch ctxt.BuildMode {
case BuildmodeShared: case BuildModeShared:
for i := 0; i < flag.NArg(); i++ { for i := 0; i < flag.NArg(); i++ {
arg := flag.Arg(i) arg := flag.Arg(i)
parts := strings.SplitN(arg, "=", 2) parts := strings.SplitN(arg, "=", 2)
...@@ -189,7 +189,7 @@ func Main(arch *sys.Arch, theArch Arch) { ...@@ -189,7 +189,7 @@ func Main(arch *sys.Arch, theArch Arch) {
pkglistfornote = append(pkglistfornote, '\n') pkglistfornote = append(pkglistfornote, '\n')
addlibpath(ctxt, "command line", "command line", file, pkgpath, "") addlibpath(ctxt, "command line", "command line", file, pkgpath, "")
} }
case BuildmodePlugin: case BuildModePlugin:
addlibpath(ctxt, "command line", "command line", flag.Arg(0), *flagPluginPath, "") addlibpath(ctxt, "command line", "command line", flag.Arg(0), *flagPluginPath, "")
default: default:
addlibpath(ctxt, "command line", "command line", flag.Arg(0), "main", "") addlibpath(ctxt, "command line", "command line", flag.Arg(0), "main", "")
......
...@@ -172,11 +172,11 @@ func onlycsymbol(s *sym.Symbol) bool { ...@@ -172,11 +172,11 @@ func onlycsymbol(s *sym.Symbol) bool {
return false return false
} }
func emitPcln(s *sym.Symbol) bool { func emitPcln(ctxt *Link, s *sym.Symbol) bool {
if s == nil { if s == nil {
return true return true
} }
if Buildmode == BuildmodePlugin && Headtype == objabi.Hdarwin && onlycsymbol(s) { if ctxt.BuildMode == BuildModePlugin && Headtype == objabi.Hdarwin && onlycsymbol(s) {
return false return false
} }
// We want to generate func table entries only for the "lowest level" symbols, // We want to generate func table entries only for the "lowest level" symbols,
...@@ -221,7 +221,7 @@ func (ctxt *Link) pclntab() { ...@@ -221,7 +221,7 @@ func (ctxt *Link) pclntab() {
} }
for _, s := range ctxt.Textp { for _, s := range ctxt.Textp {
if emitPcln(s) { if emitPcln(ctxt, s) {
nfunc++ nfunc++
} }
} }
...@@ -248,7 +248,7 @@ func (ctxt *Link) pclntab() { ...@@ -248,7 +248,7 @@ func (ctxt *Link) pclntab() {
var last *sym.Symbol var last *sym.Symbol
for _, s := range ctxt.Textp { for _, s := range ctxt.Textp {
last = s last = s
if !emitPcln(s) { if !emitPcln(ctxt, s) {
continue continue
} }
pcln := s.FuncInfo pcln := s.FuncInfo
...@@ -465,7 +465,7 @@ func (ctxt *Link) findfunctab() { ...@@ -465,7 +465,7 @@ func (ctxt *Link) findfunctab() {
} }
idx := int32(0) idx := int32(0)
for i, s := range ctxt.Textp { for i, s := range ctxt.Textp {
if !emitPcln(s) { if !emitPcln(ctxt, s) {
continue continue
} }
p := s.Value p := s.Value
...@@ -474,7 +474,7 @@ func (ctxt *Link) findfunctab() { ...@@ -474,7 +474,7 @@ func (ctxt *Link) findfunctab() {
if i < len(ctxt.Textp) { if i < len(ctxt.Textp) {
e = ctxt.Textp[i] e = ctxt.Textp[i]
} }
for !emitPcln(e) && i < len(ctxt.Textp) { for !emitPcln(ctxt, e) && i < len(ctxt.Textp) {
e = ctxt.Textp[i] e = ctxt.Textp[i]
i++ i++
} }
......
...@@ -328,7 +328,7 @@ func (sect *peSection) pad(out *OutBuf, n uint32) { ...@@ -328,7 +328,7 @@ func (sect *peSection) pad(out *OutBuf, n uint32) {
} }
// write writes COFF section sect into the output file. // 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{ h := pe.SectionHeader32{
VirtualSize: sect.virtualSize, VirtualSize: sect.virtualSize,
SizeOfRawData: sect.sizeOfRawData, SizeOfRawData: sect.sizeOfRawData,
...@@ -337,7 +337,7 @@ func (sect *peSection) write(out *OutBuf) error { ...@@ -337,7 +337,7 @@ func (sect *peSection) write(out *OutBuf) error {
NumberOfRelocations: sect.numberOfRelocations, NumberOfRelocations: sect.numberOfRelocations,
Characteristics: sect.characteristics, Characteristics: sect.characteristics,
} }
if Linkmode != LinkExternal { if linkmode != LinkExternal {
h.VirtualAddress = sect.virtualAddress h.VirtualAddress = sect.virtualAddress
} }
copy(h.Name[:], sect.shortName) copy(h.Name[:], sect.shortName)
...@@ -595,7 +595,7 @@ func (f *peFile) writeSymbol(out *OutBuf, s *sym.Symbol, value int64, sectidx in ...@@ -595,7 +595,7 @@ func (f *peFile) writeSymbol(out *OutBuf, s *sym.Symbol, value int64, sectidx in
// mapToPESection searches peFile f for s symbol's location. // mapToPESection searches peFile f for s symbol's location.
// It returns PE section index, and offset within that section. // 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 { 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 no section", s.Name)
} }
...@@ -606,7 +606,7 @@ func (f *peFile) mapToPESection(s *sym.Symbol) (pesectidx int, offset int64, err ...@@ -606,7 +606,7 @@ func (f *peFile) mapToPESection(s *sym.Symbol) (pesectidx int, offset int64, err
return 0, 0, fmt.Errorf("could not map %s symbol with non .text or .data 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 v := uint64(s.Value) - Segdata.Vaddr
if Linkmode != LinkExternal { if linkmode != LinkExternal {
return f.dataSect.index, int64(v), nil return f.dataSect.index, int64(v), nil
} }
if s.Type == sym.SDATA { if s.Type == sym.SDATA {
...@@ -638,20 +638,20 @@ func (f *peFile) writeSymbols(ctxt *Link) { ...@@ -638,20 +638,20 @@ func (f *peFile) writeSymbols(ctxt *Link) {
// Only windows/386 requires underscore prefix on external symbols. // Only windows/386 requires underscore prefix on external symbols.
if ctxt.Arch.Family == sys.I386 && if ctxt.Arch.Family == sys.I386 &&
Linkmode == LinkExternal && ctxt.LinkMode == LinkExternal &&
(s.Type == sym.SHOSTOBJ || s.Attr.CgoExport()) { (s.Type == sym.SHOSTOBJ || s.Attr.CgoExport()) {
s.Name = "_" + s.Name s.Name = "_" + s.Name
} }
var typ uint16 var typ uint16
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
typ = IMAGE_SYM_TYPE_NULL typ = IMAGE_SYM_TYPE_NULL
} else { } else {
// TODO: fix IMAGE_SYM_DTYPE_ARRAY value and use following expression, instead of 0x0308 // 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 = IMAGE_SYM_DTYPE_ARRAY<<8 + IMAGE_SYM_TYPE_STRUCT
typ = 0x0308 // "array of structs" typ = 0x0308 // "array of structs"
} }
sect, value, err := f.mapToPESection(s) sect, value, err := f.mapToPESection(s, ctxt.LinkMode)
if err != nil { if err != nil {
if type_ == UndefinedSym { if type_ == UndefinedSym {
typ = IMAGE_SYM_DTYPE_FUNCTION typ = IMAGE_SYM_DTYPE_FUNCTION
...@@ -666,7 +666,7 @@ func (f *peFile) writeSymbols(ctxt *Link) { ...@@ -666,7 +666,7 @@ func (f *peFile) writeSymbols(ctxt *Link) {
f.writeSymbol(ctxt.Out, s, value, sect, typ, uint8(class)) f.writeSymbol(ctxt.Out, s, value, sect, typ, uint8(class))
} }
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
// Include section symbols as external, because // Include section symbols as external, because
// .ctors and .debug_* section relocations refer to it. // .ctors and .debug_* section relocations refer to it.
for _, pesect := range f.sections { for _, pesect := range f.sections {
...@@ -683,14 +683,14 @@ func (f *peFile) writeSymbolTableAndStringTable(ctxt *Link) { ...@@ -683,14 +683,14 @@ func (f *peFile) writeSymbolTableAndStringTable(ctxt *Link) {
f.symtabOffset = ctxt.Out.Offset() f.symtabOffset = ctxt.Out.Offset()
// write COFF symbol table // write COFF symbol table
if !*FlagS || Linkmode == LinkExternal { if !*FlagS || ctxt.LinkMode == LinkExternal {
f.writeSymbols(ctxt) f.writeSymbols(ctxt)
} }
// update COFF file header and section table // update COFF file header and section table
size := f.stringTable.size() + 18*f.symbolCount size := f.stringTable.size() + 18*f.symbolCount
var h *peSection 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 // 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. // will also include it in the exe, and that will confuse windows.
h = f.addSection(".symtab", size, size) h = f.addSection(".symtab", size, size)
...@@ -700,13 +700,13 @@ func (f *peFile) writeSymbolTableAndStringTable(ctxt *Link) { ...@@ -700,13 +700,13 @@ func (f *peFile) writeSymbolTableAndStringTable(ctxt *Link) {
// write COFF string table // write COFF string table
f.stringTable.write(ctxt.Out) f.stringTable.write(ctxt.Out)
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
h.pad(ctxt.Out, uint32(size)) h.pad(ctxt.Out, uint32(size))
} }
} }
// writeFileHeader writes COFF file header for peFile f. // 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 var fh pe.FileHeader
switch arch.Family { switch arch.Family {
...@@ -724,7 +724,7 @@ func (f *peFile) writeFileHeader(arch *sys.Arch, out *OutBuf) { ...@@ -724,7 +724,7 @@ func (f *peFile) writeFileHeader(arch *sys.Arch, out *OutBuf) {
// much more beneficial than having build timestamp in the header. // much more beneficial than having build timestamp in the header.
fh.TimeDateStamp = 0 fh.TimeDateStamp = 0
if Linkmode == LinkExternal { if linkmode == LinkExternal {
fh.Characteristics = IMAGE_FILE_LINE_NUMS_STRIPPED fh.Characteristics = IMAGE_FILE_LINE_NUMS_STRIPPED
} else { } else {
fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DEBUG_STRIPPED fh.Characteristics = IMAGE_FILE_RELOCS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DEBUG_STRIPPED
...@@ -768,7 +768,7 @@ func (f *peFile) writeOptionalHeader(ctxt *Link) { ...@@ -768,7 +768,7 @@ func (f *peFile) writeOptionalHeader(ctxt *Link) {
oh.SizeOfInitializedData = f.dataSect.sizeOfRawData oh.SizeOfInitializedData = f.dataSect.sizeOfRawData
oh64.SizeOfUninitializedData = 0 oh64.SizeOfUninitializedData = 0
oh.SizeOfUninitializedData = 0 oh.SizeOfUninitializedData = 0
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
oh64.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE) oh64.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE)
oh.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE) oh.AddressOfEntryPoint = uint32(Entryvalue(ctxt) - PEBASE)
} }
...@@ -880,7 +880,7 @@ func Peinit(ctxt *Link) { ...@@ -880,7 +880,7 @@ func Peinit(ctxt *Link) {
} }
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
PESECTALIGN = 0 PESECTALIGN = 0
PEFILEALIGN = 0 PEFILEALIGN = 0
} }
...@@ -888,7 +888,7 @@ func Peinit(ctxt *Link) { ...@@ -888,7 +888,7 @@ func Peinit(ctxt *Link) {
var sh [16]pe.SectionHeader32 var sh [16]pe.SectionHeader32
var fh pe.FileHeader var fh pe.FileHeader
PEFILEHEADR = int32(Rnd(int64(len(dosstub)+binary.Size(&fh)+l+binary.Size(&sh)), PEFILEALIGN)) 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)) PESECTHEADR = int32(Rnd(int64(PEFILEHEADR), PESECTALIGN))
} else { } else {
PESECTHEADR = 0 PESECTHEADR = 0
...@@ -896,7 +896,7 @@ func Peinit(ctxt *Link) { ...@@ -896,7 +896,7 @@ func Peinit(ctxt *Link) {
pefile.nextSectOffset = uint32(PESECTHEADR) pefile.nextSectOffset = uint32(PESECTHEADR)
pefile.nextFileOffset = uint32(PEFILEHEADR) pefile.nextFileOffset = uint32(PEFILEHEADR)
if Linkmode == LinkInternal { if ctxt.LinkMode == LinkInternal {
// some mingw libs depend on this symbol, for example, FindPESectionByName // some mingw libs depend on this symbol, for example, FindPESectionByName
ctxt.xdefine("__image_base__", sym.SDATA, PEBASE) ctxt.xdefine("__image_base__", sym.SDATA, PEBASE)
ctxt.xdefine("_image_base__", sym.SDATA, PEBASE) ctxt.xdefine("_image_base__", sym.SDATA, PEBASE)
...@@ -919,17 +919,17 @@ func Peinit(ctxt *Link) { ...@@ -919,17 +919,17 @@ func Peinit(ctxt *Link) {
func pewrite(ctxt *Link) { func pewrite(ctxt *Link) {
ctxt.Out.SeekSet(0) ctxt.Out.SeekSet(0)
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
ctxt.Out.Write(dosstub) ctxt.Out.Write(dosstub)
ctxt.Out.WriteStringN("PE", 4) ctxt.Out.WriteStringN("PE", 4)
} }
pefile.writeFileHeader(ctxt.Arch, ctxt.Out) pefile.writeFileHeader(ctxt.Arch, ctxt.Out, ctxt.LinkMode)
pefile.writeOptionalHeader(ctxt) pefile.writeOptionalHeader(ctxt)
for _, sect := range pefile.sections { for _, sect := range pefile.sections {
sect.write(ctxt.Out) sect.write(ctxt.Out, ctxt.LinkMode)
} }
} }
...@@ -986,7 +986,7 @@ func initdynimport(ctxt *Link) *Dll { ...@@ -986,7 +986,7 @@ func initdynimport(ctxt *Link) *Dll {
d.ms = m d.ms = m
} }
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
// Add real symbol name // Add real symbol name
for d := dr; d != nil; d = d.next { for d := dr; d != nil; d = d.next {
for m = d.ms; m != nil; m = m.next { for m = d.ms; m != nil; m = m.next {
...@@ -1297,7 +1297,7 @@ func Asmbpe(ctxt *Link) { ...@@ -1297,7 +1297,7 @@ func Asmbpe(ctxt *Link) {
t := pefile.addSection(".text", int(Segtext.Length), int(Segtext.Length)) 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 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 // 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. // expect larger alignment requirement than the default text section alignment.
t.characteristics |= IMAGE_SCN_ALIGN_32BYTES t.characteristics |= IMAGE_SCN_ALIGN_32BYTES
...@@ -1306,7 +1306,7 @@ func Asmbpe(ctxt *Link) { ...@@ -1306,7 +1306,7 @@ func Asmbpe(ctxt *Link) {
pefile.textSect = t pefile.textSect = t
var d *peSection var d *peSection
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
d = pefile.addSection(".data", int(Segdata.Length), int(Segdata.Filelen)) 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.characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
d.checkSegment(&Segdata) d.checkSegment(&Segdata)
...@@ -1325,18 +1325,18 @@ func Asmbpe(ctxt *Link) { ...@@ -1325,18 +1325,18 @@ func Asmbpe(ctxt *Link) {
pefile.addDWARF() pefile.addDWARF()
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
pefile.ctorsSect = pefile.addInitArray(ctxt) pefile.ctorsSect = pefile.addInitArray(ctxt)
} }
ctxt.Out.SeekSet(int64(pefile.nextFileOffset)) ctxt.Out.SeekSet(int64(pefile.nextFileOffset))
if Linkmode != LinkExternal { if ctxt.LinkMode != LinkExternal {
addimports(ctxt, d) addimports(ctxt, d)
addexports(ctxt) addexports(ctxt)
} }
pefile.writeSymbolTableAndStringTable(ctxt) pefile.writeSymbolTableAndStringTable(ctxt)
addpersrc(ctxt) addpersrc(ctxt)
if Linkmode == LinkExternal { if ctxt.LinkMode == LinkExternal {
pefile.emitRelocations(ctxt) pefile.emitRelocations(ctxt)
} }
......
...@@ -137,11 +137,11 @@ func putelfsym(ctxt *Link, x *sym.Symbol, s string, t SymbolType, addr int64, go ...@@ -137,11 +137,11 @@ func putelfsym(ctxt *Link, x *sym.Symbol, s string, t SymbolType, addr int64, go
// To avoid filling the dynamic table with lots of unnecessary symbols, // To avoid filling the dynamic table with lots of unnecessary symbols,
// mark all Go symbols local (not global) in the final executable. // mark all Go symbols local (not global) in the final executable.
// But when we're dynamically linking, we need all those global symbols. // 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 bind = STB_LOCAL
} }
if Linkmode == LinkExternal && elfshnum != SHN_UNDEF { if ctxt.LinkMode == LinkExternal && elfshnum != SHN_UNDEF {
addr -= int64(xo.Sect.Vaddr) addr -= int64(xo.Sect.Vaddr)
} }
other := STV_DEFAULT other := STV_DEFAULT
...@@ -363,7 +363,7 @@ func (ctxt *Link) symtab() { ...@@ -363,7 +363,7 @@ func (ctxt *Link) symtab() {
// pseudo-symbols to mark locations of type, string, and go string data. // pseudo-symbols to mark locations of type, string, and go string data.
var symtype *sym.Symbol var symtype *sym.Symbol
var symtyperel *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 = ctxt.Syms.Lookup("type.*", 0)
s.Type = sym.STYPE s.Type = sym.STYPE
...@@ -402,7 +402,7 @@ func (ctxt *Link) symtab() { ...@@ -402,7 +402,7 @@ func (ctxt *Link) symtab() {
var symgofuncrel *sym.Symbol var symgofuncrel *sym.Symbol
if !ctxt.DynlinkingGo() { if !ctxt.DynlinkingGo() {
if UseRelro() { if ctxt.UseRelro() {
symgofuncrel = groupSym("go.funcrel.*", sym.SGOFUNCRELRO) symgofuncrel = groupSym("go.funcrel.*", sym.SGOFUNCRELRO)
} else { } else {
symgofuncrel = symgofunc symgofuncrel = symgofunc
...@@ -434,7 +434,7 @@ func (ctxt *Link) symtab() { ...@@ -434,7 +434,7 @@ func (ctxt *Link) symtab() {
if !ctxt.DynlinkingGo() { if !ctxt.DynlinkingGo() {
s.Attr |= sym.AttrNotInSymbolTable s.Attr |= sym.AttrNotInSymbolTable
} }
if UseRelro() { if ctxt.UseRelro() {
s.Type = sym.STYPERELRO s.Type = sym.STYPERELRO
s.Outer = symtyperel s.Outer = symtyperel
} else { } else {
...@@ -442,7 +442,7 @@ func (ctxt *Link) symtab() { ...@@ -442,7 +442,7 @@ func (ctxt *Link) symtab() {
s.Outer = symtype 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 // Keep go.importpath symbols in the same section as types and
// names, as they can be referred to by a section offset. // names, as they can be referred to by a section offset.
s.Type = sym.STYPERELRO s.Type = sym.STYPERELRO
...@@ -467,7 +467,7 @@ func (ctxt *Link) symtab() { ...@@ -467,7 +467,7 @@ func (ctxt *Link) symtab() {
if !ctxt.DynlinkingGo() { if !ctxt.DynlinkingGo() {
s.Attr |= sym.AttrNotInSymbolTable s.Attr |= sym.AttrNotInSymbolTable
} }
if UseRelro() { if ctxt.UseRelro() {
s.Type = sym.SGOFUNCRELRO s.Type = sym.SGOFUNCRELRO
s.Outer = symgofuncrel s.Outer = symgofuncrel
} else { } else {
...@@ -487,7 +487,7 @@ func (ctxt *Link) symtab() { ...@@ -487,7 +487,7 @@ func (ctxt *Link) symtab() {
} }
} }
if Buildmode == BuildmodeShared { if ctxt.BuildMode == BuildModeShared {
abihashgostr := ctxt.Syms.Lookup("go.link.abihash."+filepath.Base(*flagOutfile), 0) abihashgostr := ctxt.Syms.Lookup("go.link.abihash."+filepath.Base(*flagOutfile), 0)
abihashgostr.Attr |= sym.AttrReachable abihashgostr.Attr |= sym.AttrReachable
abihashgostr.Type = sym.SRODATA abihashgostr.Type = sym.SRODATA
...@@ -495,7 +495,7 @@ func (ctxt *Link) symtab() { ...@@ -495,7 +495,7 @@ func (ctxt *Link) symtab() {
abihashgostr.AddAddr(ctxt.Arch, hashsym) abihashgostr.AddAddr(ctxt.Arch, hashsym)
abihashgostr.AddUint(ctxt.Arch, uint64(hashsym.Size)) 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 { for _, l := range ctxt.Library {
s := ctxt.Syms.Lookup("go.link.pkghashbytes."+l.Pkg, 0) s := ctxt.Syms.Lookup("go.link.pkghashbytes."+l.Pkg, 0)
s.Attr |= sym.AttrReachable s.Attr |= sym.AttrReachable
...@@ -580,7 +580,7 @@ func (ctxt *Link) symtab() { ...@@ -580,7 +580,7 @@ func (ctxt *Link) symtab() {
moduledata.AddUint(ctxt.Arch, 0) moduledata.AddUint(ctxt.Arch, 0)
moduledata.AddUint(ctxt.Arch, 0) moduledata.AddUint(ctxt.Arch, 0)
} }
if Buildmode == BuildmodePlugin { if ctxt.BuildMode == BuildModePlugin {
addgostring(ctxt, moduledata, "go.link.thispluginpath", *flagPluginPath) addgostring(ctxt, moduledata, "go.link.thispluginpath", *flagPluginPath)
pkghashes := ctxt.Syms.Lookup("go.link.pkghashes", 0) pkghashes := ctxt.Syms.Lookup("go.link.pkghashes", 0)
...@@ -609,8 +609,8 @@ func (ctxt *Link) symtab() { ...@@ -609,8 +609,8 @@ func (ctxt *Link) symtab() {
} }
if len(ctxt.Shlibs) > 0 { if len(ctxt.Shlibs) > 0 {
thismodulename := filepath.Base(*flagOutfile) thismodulename := filepath.Base(*flagOutfile)
switch Buildmode { switch ctxt.BuildMode {
case BuildmodeExe, BuildmodePIE: case BuildModeExe, BuildModePIE:
// When linking an executable, outfile is just "a.out". Make // When linking an executable, outfile is just "a.out". Make
// it something slightly more comprehensible. // it something slightly more comprehensible.
thismodulename = "the executable" thismodulename = "the executable"
......
...@@ -94,7 +94,7 @@ func applyrel(arch *sys.Arch, r *sym.Reloc, s *sym.Symbol, val *int64, t int64) ...@@ -94,7 +94,7 @@ func applyrel(arch *sys.Arch, r *sym.Reloc, s *sym.Symbol, val *int64, t int64)
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { 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 { switch r.Type {
default: default:
return false return false
...@@ -229,7 +229,7 @@ func asmb(ctxt *ld.Link) { ...@@ -229,7 +229,7 @@ func asmb(ctxt *ld.Link) {
ctxt.Logf("%5.2f dwarf\n", ld.Cputime()) ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
} }
if ld.Linkmode == ld.LinkExternal { if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt) ld.Elfemitreloc(ctxt)
} }
} }
......
...@@ -99,7 +99,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se ...@@ -99,7 +99,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { 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 { switch r.Type {
default: default:
return false return false
...@@ -247,7 +247,7 @@ func asmb(ctxt *ld.Link) { ...@@ -247,7 +247,7 @@ func asmb(ctxt *ld.Link) {
ctxt.Out.Flush() ctxt.Out.Flush()
ctxt.Out.Write(ld.Elfstrdat) ctxt.Out.Write(ld.Elfstrdat)
if ld.Linkmode == ld.LinkExternal { if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt) ld.Elfemitreloc(ctxt)
} }
} }
......
...@@ -133,7 +133,7 @@ func genplt(ctxt *ld.Link) { ...@@ -133,7 +133,7 @@ func genplt(ctxt *ld.Link) {
func genaddmoduledata(ctxt *ld.Link) { func genaddmoduledata(ctxt *ld.Link) {
addmoduledata := ctxt.Syms.ROLookup("runtime.addmoduledata", 0) 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 return
} }
addmoduledata.Attr |= sym.AttrReachable addmoduledata.Attr |= sym.AttrReachable
...@@ -191,7 +191,7 @@ func genaddmoduledata(ctxt *ld.Link) { ...@@ -191,7 +191,7 @@ func genaddmoduledata(ctxt *ld.Link) {
// blr // blr
o(0x4e800020) o(0x4e800020)
if ld.Buildmode == ld.BuildmodePlugin { if ctxt.BuildMode == ld.BuildModePlugin {
ctxt.Textp = append(ctxt.Textp, addmoduledata) ctxt.Textp = append(ctxt.Textp, addmoduledata)
} }
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0) initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
...@@ -207,7 +207,7 @@ func gentext(ctxt *ld.Link) { ...@@ -207,7 +207,7 @@ func gentext(ctxt *ld.Link) {
genaddmoduledata(ctxt) genaddmoduledata(ctxt)
} }
if ld.Linkmode == ld.LinkInternal { if ctxt.LinkMode == ld.LinkInternal {
genplt(ctxt) genplt(ctxt)
} }
} }
...@@ -525,7 +525,7 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) { ...@@ -525,7 +525,7 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
// For internal linking, trampolines are always created for long calls. // 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 // 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. // 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 // No trampolines needed since r2 contains the TOC
return return
} }
...@@ -536,7 +536,7 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) { ...@@ -536,7 +536,7 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
// If branch offset is too far then create a trampoline. // 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 var tramp *sym.Symbol
for i := 0; ; i++ { for i := 0; ; i++ {
...@@ -562,17 +562,17 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) { ...@@ -562,17 +562,17 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
// With internal linking, the trampoline can be used if it is not too far. // 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. // 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 break
} }
} }
if tramp.Type == 0 { 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 // Should have returned for above cases
ld.Errorf(s, "unexpected trampoline for shared or dynamic linking\n") ld.Errorf(s, "unexpected trampoline for shared or dynamic linking\n")
} else { } else {
ctxt.AddTramp(tramp) 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 r.Sym = tramp
...@@ -584,7 +584,7 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) { ...@@ -584,7 +584,7 @@ func trampoline(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol) {
} }
} }
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 // Used for default build mode for an executable
// Address of the call target is generated using // Address of the call target is generated using
// relocation and doesn't depend on r2 (TOC). // relocation and doesn't depend on r2 (TOC).
...@@ -595,7 +595,7 @@ func gentramp(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) { ...@@ -595,7 +595,7 @@ func gentramp(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
o2 := uint32(0x3bff0000) // addi r31,targetaddr lo o2 := uint32(0x3bff0000) // addi r31,targetaddr lo
// With external linking, the target address must be // With external linking, the target address must be
// relocated using LO and HA // relocated using LO and HA
if ld.Linkmode == ld.LinkExternal { if linkmode == ld.LinkExternal {
tr := tramp.AddRel() tr := tramp.AddRel()
tr.Off = 0 tr.Off = 0
tr.Type = objabi.R_ADDRPOWER tr.Type = objabi.R_ADDRPOWER
...@@ -621,7 +621,7 @@ func gentramp(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) { ...@@ -621,7 +621,7 @@ func gentramp(arch *sys.Arch, tramp, target *sym.Symbol, offset int64) {
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { 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 { switch r.Type {
default: default:
return false return false
...@@ -977,7 +977,7 @@ func asmb(ctxt *ld.Link) { ...@@ -977,7 +977,7 @@ func asmb(ctxt *ld.Link) {
ctxt.Out.Flush() ctxt.Out.Flush()
ctxt.Out.Write(ld.Elfstrdat) ctxt.Out.Write(ld.Elfstrdat)
if ld.Linkmode == ld.LinkExternal { if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt) ld.Elfemitreloc(ctxt)
} }
} }
......
...@@ -54,7 +54,7 @@ func gentext(ctxt *ld.Link) { ...@@ -54,7 +54,7 @@ func gentext(ctxt *ld.Link) {
return return
} }
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0) 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 // we're linking a module containing the runtime -> no need for
// an init function // an init function
return return
...@@ -91,7 +91,7 @@ func gentext(ctxt *ld.Link) { ...@@ -91,7 +91,7 @@ func gentext(ctxt *ld.Link) {
// undef (for debugging) // undef (for debugging)
initfunc.AddUint32(ctxt.Arch, 0) 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, addmoduledata)
} }
ctxt.Textp = append(ctxt.Textp, initfunc) ctxt.Textp = append(ctxt.Textp, initfunc)
...@@ -383,7 +383,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se ...@@ -383,7 +383,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, se
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { 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 return false
} }
...@@ -568,7 +568,7 @@ func asmb(ctxt *ld.Link) { ...@@ -568,7 +568,7 @@ func asmb(ctxt *ld.Link) {
ctxt.Logf("%5.2f dwarf\n", ld.Cputime()) ctxt.Logf("%5.2f dwarf\n", ld.Cputime())
} }
if ld.Linkmode == ld.LinkExternal { if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt) ld.Elfemitreloc(ctxt)
} }
} }
......
...@@ -55,12 +55,12 @@ func gentext(ctxt *ld.Link) { ...@@ -55,12 +55,12 @@ func gentext(ctxt *ld.Link) {
if ctxt.DynlinkingGo() { if ctxt.DynlinkingGo() {
// We need get_pc_thunk. // We need get_pc_thunk.
} else { } else {
switch ld.Buildmode { switch ctxt.BuildMode {
case ld.BuildmodeCArchive: case ld.BuildModeCArchive:
if !ld.Iself { if !ld.Iself {
return return
} }
case ld.BuildmodePIE, ld.BuildmodeCShared, ld.BuildmodePlugin: case ld.BuildModePIE, ld.BuildModeCShared, ld.BuildModePlugin:
// We need get_pc_thunk. // We need get_pc_thunk.
default: default:
return return
...@@ -102,7 +102,7 @@ func gentext(ctxt *ld.Link) { ...@@ -102,7 +102,7 @@ func gentext(ctxt *ld.Link) {
ctxt.Textp = append(thunks, ctxt.Textp...) // keep Textp in dependency order ctxt.Textp = append(thunks, ctxt.Textp...) // keep Textp in dependency order
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0) 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 // we're linking a module containing the runtime -> no need for
// an init function // an init function
return return
...@@ -155,7 +155,7 @@ func gentext(ctxt *ld.Link) { ...@@ -155,7 +155,7 @@ func gentext(ctxt *ld.Link) {
o(0xc3) o(0xc3)
if ld.Buildmode == ld.BuildmodePlugin { if ctxt.BuildMode == ld.BuildModePlugin {
ctxt.Textp = append(ctxt.Textp, addmoduledata) ctxt.Textp = append(ctxt.Textp, addmoduledata)
} }
ctxt.Textp = append(ctxt.Textp, initfunc) ctxt.Textp = append(ctxt.Textp, initfunc)
...@@ -484,7 +484,7 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, secto ...@@ -484,7 +484,7 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, secto
} }
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool { 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 return false
} }
switch r.Type { switch r.Type {
...@@ -699,7 +699,7 @@ func asmb(ctxt *ld.Link) { ...@@ -699,7 +699,7 @@ func asmb(ctxt *ld.Link) {
ctxt.Out.Flush() ctxt.Out.Flush()
ctxt.Out.Write(ld.Elfstrdat) ctxt.Out.Write(ld.Elfstrdat)
if ld.Linkmode == ld.LinkExternal { if ctxt.LinkMode == ld.LinkExternal {
ld.Elfemitreloc(ctxt) ld.Elfemitreloc(ctxt)
} }
} }
...@@ -721,7 +721,7 @@ func asmb(ctxt *ld.Link) { ...@@ -721,7 +721,7 @@ func asmb(ctxt *ld.Link) {
} }
case objabi.Hdarwin: case objabi.Hdarwin:
if ld.Linkmode == ld.LinkExternal { if ctxt.LinkMode == ld.LinkExternal {
ld.Machoemitreloc(ctxt) ld.Machoemitreloc(ctxt)
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment