[release-branch.go1.18] misc/cgo/testcshared: handle unsuffixed dlltool path

Adapt the testcshared tests to handle the case where the path output
by invoking

  gcc -print-prog-name=dlltool

is a path lacking the final ".exe" suffix (this seems to be what clang
is doing); tack it on before using if this is the case.

Updates #57704.
Fixes #57705.

Change-Id: I04fb7b9fc90677880b1ced4a4ad2a8867a3f5f86
Reviewed-on: https://go-review.googlesource.com/c/go/+/451816
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
(cherry picked from commit 771a98d6b19c9ca4bbd3fbeba03d7d512f77c166)
Reviewed-on: https://go-review.googlesource.com/c/go/+/461176
Reviewed-by: Heschi Kreinick <heschi@google.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
diff --git a/misc/cgo/testcshared/cshared_test.go b/misc/cgo/testcshared/cshared_test.go
index c9e9e5f..1cd8c2a 100644
--- a/misc/cgo/testcshared/cshared_test.go
+++ b/misc/cgo/testcshared/cshared_test.go
@@ -317,30 +317,46 @@
 		if err != nil {
 			return fmt.Errorf("unable to find dlltool path: %v\n%s\n", err, out)
 		}
-		args := []string{strings.TrimSpace(string(out)), "-D", args[6], "-l", libgoname, "-d", "libgo.def"}
-
-		// This is an unfortunate workaround for https://github.com/mstorsjo/llvm-mingw/issues/205 in which
-		// we basically reimplement the contents of the dlltool.sh wrapper: https://git.io/JZFlU
-		dlltoolContents, err := os.ReadFile(args[0])
-		if err != nil {
-			return fmt.Errorf("unable to read dlltool: %v\n", err)
-		}
-		if bytes.HasPrefix(dlltoolContents, []byte("#!/bin/sh")) && bytes.Contains(dlltoolContents, []byte("llvm-dlltool")) {
-			base, name := filepath.Split(args[0])
-			args[0] = filepath.Join(base, "llvm-dlltool")
-			var machine string
-			switch prefix, _, _ := strings.Cut(name, "-"); prefix {
-			case "i686":
-				machine = "i386"
-			case "x86_64":
-				machine = "i386:x86-64"
-			case "armv7":
-				machine = "arm"
-			case "aarch64":
-				machine = "arm64"
+		dlltoolpath := strings.TrimSpace(string(out))
+		if filepath.Ext(dlltoolpath) == "" {
+			// Some compilers report slash-separated paths without extensions
+			// instead of ordinary Windows paths.
+			// Try to find the canonical name for the path.
+			if lp, err := exec.LookPath(dlltoolpath); err == nil {
+				dlltoolpath = lp
 			}
-			if len(machine) > 0 {
-				args = append(args, "-m", machine)
+		}
+
+		args := []string{dlltoolpath, "-D", args[6], "-l", libgoname, "-d", "libgo.def"}
+
+		if filepath.Ext(dlltoolpath) == "" {
+			// This is an unfortunate workaround for
+			// https://github.com/mstorsjo/llvm-mingw/issues/205 in which
+			// we basically reimplement the contents of the dlltool.sh
+			// wrapper: https://git.io/JZFlU.
+			// TODO(thanm): remove this workaround once we can upgrade
+			// the compilers on the windows-arm64 builder.
+			dlltoolContents, err := os.ReadFile(args[0])
+			if err != nil {
+				return fmt.Errorf("unable to read dlltool: %v\n", err)
+			}
+			if bytes.HasPrefix(dlltoolContents, []byte("#!/bin/sh")) && bytes.Contains(dlltoolContents, []byte("llvm-dlltool")) {
+				base, name := filepath.Split(args[0])
+				args[0] = filepath.Join(base, "llvm-dlltool")
+				var machine string
+				switch prefix, _, _ := strings.Cut(name, "-"); prefix {
+				case "i686":
+					machine = "i386"
+				case "x86_64":
+					machine = "i386:x86-64"
+				case "armv7":
+					machine = "arm"
+				case "aarch64":
+					machine = "arm64"
+				}
+				if len(machine) > 0 {
+					args = append(args, "-m", machine)
+				}
 			}
 		}