From e6b00f67c519d6a39a05343436462860d393b078 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= <chigot@adacore.com>
Date: Fri, 10 Jun 2022 09:36:43 +0200
Subject: [PATCH] bfd: handle codepage when opening files on MinGW

Even if MS docs say that CP_UTF8 should always be used on newer
applications, forcing it might produce undefined filename if the
encoding isn't UTF-8.
MinGW seems to call ___lc_codepage_func() in order to retrieve the
current thread codepage.

bfd/ChangeLog:

	* bfdio.c (_bfd_real_fopen): Retrieve codepage with
	___lc_codepage_func() on MinGW.

TN: V603-028
Change-Id: Ica6062aedf7a46c3d0c6ef8ff379926cfa4fcd75
---
 bfd/bfdio.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/bfd/bfdio.c b/bfd/bfdio.c
index 5c9a6555894..58245972f0c 100644
--- a/bfd/bfdio.c
+++ b/bfd/bfdio.c
@@ -28,6 +28,7 @@
 #include "aout/ar.h"
 #if defined (_WIN32)
 #include <windows.h>
+#include <locale.h>
 #endif
 
 #ifndef S_IXUSR
@@ -121,15 +122,21 @@ _bfd_real_fopen (const char *filename, const char *modes)
    const wchar_t  prefix[] = L"\\\\?\\";
    const wchar_t  ccs[] = L", ccs=UNICODE";
    const size_t   partPathLen = strlen (filename) + 1;
+#ifdef __MINGW32__
+   const unsigned int cp = ___lc_codepage_func();
+#else
+   const unsigned int cp = CP_UTF8;
+#endif
+
 
    /* Converting the partial path from ascii to unicode.
       1) Get the length: Calling with lpWideCharStr set to null returns the length.
       2) Convert the string: Calling with cbMultiByte set to -1 includes the terminating null.  */
-   size_t         partPathWSize = MultiByteToWideChar (CP_UTF8, 0, filename, -1, NULL, 0);
+   size_t         partPathWSize = MultiByteToWideChar (cp, 0, filename, -1, NULL, 0);
    wchar_t *      partPath = calloc (partPathWSize, sizeof(wchar_t));
    size_t         ix;
 
-   MultiByteToWideChar (CP_UTF8, 0, filename, -1, partPath, partPathWSize);
+   MultiByteToWideChar (cp, 0, filename, -1, partPath, partPathWSize);
 
    /* Convert any UNIX style path separators into the DOS i.e. backslash separator.  */
    for (ix = 0; ix < partPathLen; ix++)
@@ -153,7 +160,7 @@ _bfd_real_fopen (const char *filename, const char *modes)
    /* It is non-standard for modes to exceed 16 characters.  */
    wchar_t    modesW[16 + sizeof(ccs)];
 
-   MultiByteToWideChar (CP_UTF8, 0, modes, -1, modesW, sizeof(modesW));
+   MultiByteToWideChar (cp, 0, modes, -1, modesW, sizeof(modesW));
    wcscat (modesW, ccs);
 
    FILE *     file = _wfopen (fullPath, modesW);
-- 
2.25.1