Skip to content

Commit 0ff9df6

Browse files
Clément Chigotianlancetaylor
Clément Chigot
authored andcommitted
cmd: disable DWARF with old ld on aix/ppc64
DWARF relocations isn't working with some older ld, because of -Wl,-bnoobjreorder which is needed on Go. This commit checks ld's version and disable DWARF generation in cmd/link if it's too old. Some tests must therefore be skipped. Change-Id: I2e794c263eb0dfe0b42e7062fb80c26f086b44d1 Reviewed-on: https://go-review.googlesource.com/c/go/+/164007 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent bea58ef commit 0ff9df6

File tree

5 files changed

+89
-10
lines changed

5 files changed

+89
-10
lines changed

src/cmd/compile/internal/ssa/stmtlines_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package ssa_test
22

33
import (
4+
cmddwarf "cmd/internal/dwarf"
45
"debug/dwarf"
56
"debug/elf"
67
"debug/macho"
@@ -9,6 +10,7 @@ import (
910
"internal/testenv"
1011
"internal/xcoff"
1112
"io"
13+
"os"
1214
"runtime"
1315
"testing"
1416
)
@@ -49,6 +51,20 @@ func TestStmtLines(t *testing.T) {
4951
t.Skip("skipping on plan9; no DWARF symbol table in executables")
5052
}
5153

54+
if runtime.GOOS == "aix" {
55+
extld := os.Getenv("CC")
56+
if extld == "" {
57+
extld = "gcc"
58+
}
59+
enabled, err := cmddwarf.IsDWARFEnabledOnAIXLd(extld)
60+
if err != nil {
61+
t.Fatal(err)
62+
}
63+
if !enabled {
64+
t.Skip("skipping on aix: no DWARF with ld version < 7.2.2 ")
65+
}
66+
}
67+
5268
lines := map[Line]bool{}
5369
dw, err := open(testenv.GoToolPath(t))
5470
must(err)

src/cmd/internal/dwarf/dwarf.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88
package dwarf
99

1010
import (
11+
"bytes"
1112
"cmd/internal/objabi"
1213
"errors"
1314
"fmt"
15+
"os/exec"
1416
"sort"
17+
"strconv"
1518
"strings"
1619
)
1720

@@ -1526,3 +1529,42 @@ type byChildIndex []*Var
15261529
func (s byChildIndex) Len() int { return len(s) }
15271530
func (s byChildIndex) Less(i, j int) bool { return s[i].ChildIndex < s[j].ChildIndex }
15281531
func (s byChildIndex) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
1532+
1533+
// IsDWARFEnabledOnAIX returns true if DWARF is possible on the
1534+
// current extld.
1535+
// AIX ld doesn't support DWARF with -bnoobjreorder with version
1536+
// prior to 7.2.2.
1537+
func IsDWARFEnabledOnAIXLd(extld string) (bool, error) {
1538+
out, err := exec.Command(extld, "-Wl,-V").CombinedOutput()
1539+
if err != nil {
1540+
// The normal output should display ld version and
1541+
// then fails because ".main" is not defined:
1542+
// ld: 0711-317 ERROR: Undefined symbol: .main
1543+
if !bytes.Contains(out, []byte("0711-317")) {
1544+
return false, fmt.Errorf("%s -Wl,-V failed: %v\n%s", extld, err, out)
1545+
}
1546+
}
1547+
// gcc -Wl,-V output should be:
1548+
// /usr/bin/ld: LD X.X.X(date)
1549+
// ...
1550+
out = bytes.TrimPrefix(out, []byte("/usr/bin/ld: LD "))
1551+
vers := string(bytes.Split(out, []byte("("))[0])
1552+
subvers := strings.Split(vers, ".")
1553+
if len(subvers) != 3 {
1554+
return false, fmt.Errorf("cannot parse %s -Wl,-V (%s): %v\n", extld, out, err)
1555+
}
1556+
if v, err := strconv.Atoi(subvers[0]); err != nil || v < 7 {
1557+
return false, nil
1558+
} else if v > 7 {
1559+
return true, nil
1560+
}
1561+
if v, err := strconv.Atoi(subvers[1]); err != nil || v < 2 {
1562+
return false, nil
1563+
} else if v > 2 {
1564+
return true, nil
1565+
}
1566+
if v, err := strconv.Atoi(subvers[2]); err != nil || v < 2 {
1567+
return false, nil
1568+
}
1569+
return true, nil
1570+
}

src/cmd/link/dwarf_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package main
66

77
import (
8+
cmddwarf "cmd/internal/dwarf"
89
"cmd/internal/objfile"
910
"debug/dwarf"
1011
"internal/testenv"
@@ -39,6 +40,19 @@ func testDWARF(t *testing.T, buildmode string, expectDWARF bool, env ...string)
3940

4041
for _, prog := range []string{"testprog", "testprogcgo"} {
4142
prog := prog
43+
expectDWARF := expectDWARF
44+
if runtime.GOOS == "aix" && prog == "testprogcgo" {
45+
extld := os.Getenv("CC")
46+
if extld == "" {
47+
extld = "gcc"
48+
}
49+
expectDWARF, err = cmddwarf.IsDWARFEnabledOnAIXLd(extld)
50+
if err != nil {
51+
t.Fatal(err)
52+
}
53+
54+
}
55+
4256
t.Run(prog, func(t *testing.T) {
4357
t.Parallel()
4458

src/cmd/link/internal/ld/dwarf.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,6 +1721,11 @@ func dwarfEnabled(ctxt *Link) bool {
17211721
case ctxt.HeadType == objabi.Hdarwin:
17221722
case ctxt.HeadType == objabi.Hwindows:
17231723
case ctxt.HeadType == objabi.Haix:
1724+
res, err := dwarf.IsDWARFEnabledOnAIXLd(ctxt.extld())
1725+
if err != nil {
1726+
Exitf("%v", err)
1727+
}
1728+
return res
17241729
default:
17251730
return false
17261731
}

src/cmd/link/internal/ld/lib.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -322,18 +322,24 @@ func loadinternal(ctxt *Link, name string) *sym.Library {
322322
return nil
323323
}
324324

325-
// findLibPathCmd uses cmd command to find gcc library libname.
326-
// It returns library full path if found, or "none" if not found.
327-
func (ctxt *Link) findLibPathCmd(cmd, libname string) string {
325+
// extld returns the current external linker.
326+
func (ctxt *Link) extld() string {
328327
if *flagExtld == "" {
329328
*flagExtld = "gcc"
330329
}
330+
return *flagExtld
331+
}
332+
333+
// findLibPathCmd uses cmd command to find gcc library libname.
334+
// It returns library full path if found, or "none" if not found.
335+
func (ctxt *Link) findLibPathCmd(cmd, libname string) string {
336+
extld := ctxt.extld()
331337
args := hostlinkArchArgs(ctxt.Arch)
332338
args = append(args, cmd)
333339
if ctxt.Debugvlog != 0 {
334-
ctxt.Logf("%s %v\n", *flagExtld, args)
340+
ctxt.Logf("%s %v\n", extld, args)
335341
}
336-
out, err := exec.Command(*flagExtld, args...).Output()
342+
out, err := exec.Command(extld, args...).Output()
337343
if err != nil {
338344
if ctxt.Debugvlog != 0 {
339345
ctxt.Logf("not using a %s file because compiler failed\n%v\n%s\n", libname, err, out)
@@ -1111,12 +1117,8 @@ func (ctxt *Link) hostlink() {
11111117
return
11121118
}
11131119

1114-
if *flagExtld == "" {
1115-
*flagExtld = "gcc"
1116-
}
1117-
11181120
var argv []string
1119-
argv = append(argv, *flagExtld)
1121+
argv = append(argv, ctxt.extld())
11201122
argv = append(argv, hostlinkArchArgs(ctxt.Arch)...)
11211123

11221124
if *FlagS || debug_s {

0 commit comments

Comments
 (0)