cmd/link/internal/ld: consider alternative linkers in linkerFlagSupported

CL 235017 is about to change the default Android linker to lld. lld doesn't
support the --compress-debug-sections=zlib-gnu flag, but linkerFlagSupported
doesn't take any alternative linkers specified with -fuse-ld into account.

Updates #38838

Change-Id: I5f7422c06d40dedde2e4b070fc48398e8f822190
Reviewed-on: https://go-review.googlesource.com/c/go/+/235157
Run-TryBot: Elias Naur <mail@eliasnaur.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Elias Naur 2020-05-25 15:27:05 +02:00
parent f65ad0dda7
commit bcda68447b

View file

@ -1466,6 +1466,7 @@ func (ctxt *Link) hostlink() {
} }
} }
var altLinker string
if ctxt.IsELF && ctxt.DynlinkingGo() { if ctxt.IsELF && ctxt.DynlinkingGo() {
// We force all symbol resolution to be done at program startup // We force all symbol resolution to be done at program startup
// because lazy PLT resolution can use large amounts of stack at // because lazy PLT resolution can use large amounts of stack at
@ -1486,7 +1487,7 @@ func (ctxt *Link) hostlink() {
// generating COPY relocations. // generating COPY relocations.
// //
// In both cases, switch to gold. // In both cases, switch to gold.
argv = append(argv, "-fuse-ld=gold") altLinker = "gold"
// If gold is not installed, gcc will silently switch // If gold is not installed, gcc will silently switch
// back to ld.bfd. So we parse the version information // back to ld.bfd. So we parse the version information
@ -1499,10 +1500,9 @@ func (ctxt *Link) hostlink() {
} }
} }
} }
if ctxt.Arch.Family == sys.ARM64 && objabi.GOOS == "freebsd" { if ctxt.Arch.Family == sys.ARM64 && objabi.GOOS == "freebsd" {
// Switch to ld.bfd on freebsd/arm64. // Switch to ld.bfd on freebsd/arm64.
argv = append(argv, "-fuse-ld=bfd") altLinker = "bfd"
// Provide a useful error if ld.bfd is missing. // Provide a useful error if ld.bfd is missing.
cmd := exec.Command(*flagExtld, "-fuse-ld=bfd", "-Wl,--version") cmd := exec.Command(*flagExtld, "-fuse-ld=bfd", "-Wl,--version")
@ -1512,6 +1512,9 @@ func (ctxt *Link) hostlink() {
} }
} }
} }
if altLinker != "" {
argv = append(argv, "-fuse-ld="+altLinker)
}
if ctxt.IsELF && len(buildinfo) > 0 { if ctxt.IsELF && len(buildinfo) > 0 {
argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo)) argv = append(argv, fmt.Sprintf("-Wl,--build-id=0x%x", buildinfo))
@ -1548,7 +1551,7 @@ func (ctxt *Link) hostlink() {
} }
const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu" const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu"
if ctxt.compressDWARF && linkerFlagSupported(argv[0], compressDWARF) { if ctxt.compressDWARF && linkerFlagSupported(argv[0], altLinker, compressDWARF) {
argv = append(argv, compressDWARF) argv = append(argv, compressDWARF)
} }
@ -1638,7 +1641,7 @@ func (ctxt *Link) hostlink() {
if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared { if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared {
// GCC uses -no-pie, clang uses -nopie. // GCC uses -no-pie, clang uses -nopie.
for _, nopie := range []string{"-no-pie", "-nopie"} { for _, nopie := range []string{"-no-pie", "-nopie"} {
if linkerFlagSupported(argv[0], nopie) { if linkerFlagSupported(argv[0], altLinker, nopie) {
argv = append(argv, nopie) argv = append(argv, nopie)
break break
} }
@ -1739,7 +1742,7 @@ func (ctxt *Link) hostlink() {
var createTrivialCOnce sync.Once var createTrivialCOnce sync.Once
func linkerFlagSupported(linker, flag string) bool { func linkerFlagSupported(linker, altLinker, flag string) bool {
createTrivialCOnce.Do(func() { createTrivialCOnce.Do(func() {
src := filepath.Join(*flagTmpdir, "trivial.c") src := filepath.Join(*flagTmpdir, "trivial.c")
if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil { if err := ioutil.WriteFile(src, []byte("int main() { return 0; }"), 0666); err != nil {
@ -1799,6 +1802,9 @@ func linkerFlagSupported(linker, flag string) bool {
} }
} }
if altLinker != "" {
flags = append(flags, "-fuse-ld="+altLinker)
}
flags = append(flags, flag, "trivial.c") flags = append(flags, flag, "trivial.c")
cmd := exec.Command(linker, flags...) cmd := exec.Command(linker, flags...)