]> Cypherpunks repositories - gostls13.git/commitdiff
cmd: disable DWARF with old ld on aix/ppc64
authorClément Chigot <clement.chigot@atos.net>
Wed, 20 Feb 2019 15:39:09 +0000 (16:39 +0100)
committerIan Lance Taylor <iant@golang.org>
Wed, 13 Mar 2019 02:33:58 +0000 (02:33 +0000)
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 <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/compile/internal/ssa/stmtlines_test.go
src/cmd/internal/dwarf/dwarf.go
src/cmd/link/dwarf_test.go
src/cmd/link/internal/ld/dwarf.go
src/cmd/link/internal/ld/lib.go

index c71f8befd9d295df3e0c20a780166595ac3e9d69..b8a9388b6143f67a85a615b8ff94d40bb414f173 100644 (file)
@@ -1,6 +1,7 @@
 package ssa_test
 
 import (
+       cmddwarf "cmd/internal/dwarf"
        "debug/dwarf"
        "debug/elf"
        "debug/macho"
@@ -9,6 +10,7 @@ import (
        "internal/testenv"
        "internal/xcoff"
        "io"
+       "os"
        "runtime"
        "testing"
 )
@@ -49,6 +51,20 @@ func TestStmtLines(t *testing.T) {
                t.Skip("skipping on plan9; no DWARF symbol table in executables")
        }
 
+       if runtime.GOOS == "aix" {
+               extld := os.Getenv("CC")
+               if extld == "" {
+                       extld = "gcc"
+               }
+               enabled, err := cmddwarf.IsDWARFEnabledOnAIXLd(extld)
+               if err != nil {
+                       t.Fatal(err)
+               }
+               if !enabled {
+                       t.Skip("skipping on aix: no DWARF with ld version < 7.2.2 ")
+               }
+       }
+
        lines := map[Line]bool{}
        dw, err := open(testenv.GoToolPath(t))
        must(err)
index 8ad84105a4814bbfe7648b51305d94fd2d31fab9..7f37cf059d4a946c737dba389c9c28f1345f576d 100644 (file)
@@ -8,10 +8,13 @@
 package dwarf
 
 import (
+       "bytes"
        "cmd/internal/objabi"
        "errors"
        "fmt"
+       "os/exec"
        "sort"
+       "strconv"
        "strings"
 )
 
@@ -1526,3 +1529,42 @@ type byChildIndex []*Var
 func (s byChildIndex) Len() int           { return len(s) }
 func (s byChildIndex) Less(i, j int) bool { return s[i].ChildIndex < s[j].ChildIndex }
 func (s byChildIndex) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
+
+// IsDWARFEnabledOnAIX returns true if DWARF is possible on the
+// current extld.
+// AIX ld doesn't support DWARF with -bnoobjreorder with version
+// prior to 7.2.2.
+func IsDWARFEnabledOnAIXLd(extld string) (bool, error) {
+       out, err := exec.Command(extld, "-Wl,-V").CombinedOutput()
+       if err != nil {
+               // The normal output should display ld version and
+               // then fails because ".main" is not defined:
+               // ld: 0711-317 ERROR: Undefined symbol: .main
+               if !bytes.Contains(out, []byte("0711-317")) {
+                       return false, fmt.Errorf("%s -Wl,-V failed: %v\n%s", extld, err, out)
+               }
+       }
+       // gcc -Wl,-V output should be:
+       //   /usr/bin/ld: LD X.X.X(date)
+       //   ...
+       out = bytes.TrimPrefix(out, []byte("/usr/bin/ld: LD "))
+       vers := string(bytes.Split(out, []byte("("))[0])
+       subvers := strings.Split(vers, ".")
+       if len(subvers) != 3 {
+               return false, fmt.Errorf("cannot parse %s -Wl,-V (%s): %v\n", extld, out, err)
+       }
+       if v, err := strconv.Atoi(subvers[0]); err != nil || v < 7 {
+               return false, nil
+       } else if v > 7 {
+               return true, nil
+       }
+       if v, err := strconv.Atoi(subvers[1]); err != nil || v < 2 {
+               return false, nil
+       } else if v > 2 {
+               return true, nil
+       }
+       if v, err := strconv.Atoi(subvers[2]); err != nil || v < 2 {
+               return false, nil
+       }
+       return true, nil
+}
index 9c3bc624ef9234b139aad66dce9411e3e8b49055..ecc96019befe07489a6db091306e9341d22a5576 100644 (file)
@@ -5,6 +5,7 @@
 package main
 
 import (
+       cmddwarf "cmd/internal/dwarf"
        "cmd/internal/objfile"
        "debug/dwarf"
        "internal/testenv"
@@ -39,6 +40,19 @@ func testDWARF(t *testing.T, buildmode string, expectDWARF bool, env ...string)
 
        for _, prog := range []string{"testprog", "testprogcgo"} {
                prog := prog
+               expectDWARF := expectDWARF
+               if runtime.GOOS == "aix" && prog == "testprogcgo" {
+                       extld := os.Getenv("CC")
+                       if extld == "" {
+                               extld = "gcc"
+                       }
+                       expectDWARF, err = cmddwarf.IsDWARFEnabledOnAIXLd(extld)
+                       if err != nil {
+                               t.Fatal(err)
+                       }
+
+               }
+
                t.Run(prog, func(t *testing.T) {
                        t.Parallel()
 
index 446fd572ac7f9c21be0b263dce8f860b08beb9df..d923b7599d68ffeef133d191f395051fddead87b 100644 (file)
@@ -1721,6 +1721,11 @@ func dwarfEnabled(ctxt *Link) bool {
                case ctxt.HeadType == objabi.Hdarwin:
                case ctxt.HeadType == objabi.Hwindows:
                case ctxt.HeadType == objabi.Haix:
+                       res, err := dwarf.IsDWARFEnabledOnAIXLd(ctxt.extld())
+                       if err != nil {
+                               Exitf("%v", err)
+                       }
+                       return res
                default:
                        return false
                }
index 44befc96372334e6f3039ebdf6c1815c1a19801a..d5efcee34b89d8236f1ba4dc52bd6b48c22d5a48 100644 (file)
@@ -322,18 +322,24 @@ func loadinternal(ctxt *Link, name string) *sym.Library {
        return nil
 }
 
-// findLibPathCmd uses cmd command to find gcc library libname.
-// It returns library full path if found, or "none" if not found.
-func (ctxt *Link) findLibPathCmd(cmd, libname string) string {
+// extld returns the current external linker.
+func (ctxt *Link) extld() string {
        if *flagExtld == "" {
                *flagExtld = "gcc"
        }
+       return *flagExtld
+}
+
+// findLibPathCmd uses cmd command to find gcc library libname.
+// It returns library full path if found, or "none" if not found.
+func (ctxt *Link) findLibPathCmd(cmd, libname string) string {
+       extld := ctxt.extld()
        args := hostlinkArchArgs(ctxt.Arch)
        args = append(args, cmd)
        if ctxt.Debugvlog != 0 {
-               ctxt.Logf("%s %v\n", *flagExtld, args)
+               ctxt.Logf("%s %v\n", extld, args)
        }
-       out, err := exec.Command(*flagExtld, args...).Output()
+       out, err := exec.Command(extld, args...).Output()
        if err != nil {
                if ctxt.Debugvlog != 0 {
                        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() {
                return
        }
 
-       if *flagExtld == "" {
-               *flagExtld = "gcc"
-       }
-
        var argv []string
-       argv = append(argv, *flagExtld)
+       argv = append(argv, ctxt.extld())
        argv = append(argv, hostlinkArchArgs(ctxt.Arch)...)
 
        if *FlagS || debug_s {