package ssa_test
import (
+ cmddwarf "cmd/internal/dwarf"
"debug/dwarf"
"debug/elf"
"debug/macho"
"internal/testenv"
"internal/xcoff"
"io"
+ "os"
"runtime"
"testing"
)
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)
package dwarf
import (
+ "bytes"
"cmd/internal/objabi"
"errors"
"fmt"
+ "os/exec"
"sort"
+ "strconv"
"strings"
)
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
+}
package main
import (
+ cmddwarf "cmd/internal/dwarf"
"cmd/internal/objfile"
"debug/dwarf"
"internal/testenv"
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()
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
}
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)
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 {