cmd/link: flush file mapping before unmapping

Call FlushViewOfFile before unmapping the output file, for extra
safety. The documentation says the function does not wait for
the data to be written to disk, so it should be cheap.

Fixes #38440.

Change-Id: I05352f15d9305e6e7086a002f61802f74036b710
Reviewed-on: https://go-review.googlesource.com/c/go/+/235639
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Jason A. Donenfeld <Jason@zx2c4.com>
diff --git a/src/cmd/link/internal/ld/outbuf_windows.go b/src/cmd/link/internal/ld/outbuf_windows.go
index a7140cc..807c0e2 100644
--- a/src/cmd/link/internal/ld/outbuf_windows.go
+++ b/src/cmd/link/internal/ld/outbuf_windows.go
@@ -35,7 +35,13 @@
 	if out.buf == nil {
 		return
 	}
-	err := syscall.UnmapViewOfFile(uintptr(unsafe.Pointer(&out.buf[0])))
+	// Apparently unmapping without flush may cause ACCESS_DENIED error
+	// (see issue 38440).
+	err := syscall.FlushViewOfFile(uintptr(unsafe.Pointer(&out.buf[0])), 0)
+	if err != nil {
+		Exitf("FlushViewOfFile failed: %v", err)
+	}
+	err = syscall.UnmapViewOfFile(uintptr(unsafe.Pointer(&out.buf[0])))
 	out.buf = nil
 	if err != nil {
 		Exitf("UnmapViewOfFile failed: %v", err)