[PATCH] bfd: fix filename encoding for Win32
Jan Beulich
jbeulich@suse.com
Mon Mar 2 07:36:27 GMT 2026
On 02.03.2026 07:12, ZENG Hao wrote:
> MSVCRT's ___lc_codepage_func() returns "default ACP for Windows display
> language". i.e. 1252 for English, no matter how "Language for non-Unicode
> programs" (system code page) is set, or whether the application manifest sets
> activeCodePage to UTF-8. Thus non-ASCII path would get corrupted if user's
> Windows display language does not match system code page, or downstream adds
> UTF-8 manifest.
>
> In our use case, the filename is encoded in CP_ACP.
>
> There are some conner cases that are impossible to handle on our side (read
> from file, console, pipe, socket, etc.). It is possible for downstream
> distributor to ensure all tools are consistently encoded, by removing UTF-8
> manifest from GCC, or adding it to all tools.
> ---
>
> Note: here are some detailed comparation of MSVCRT and UCRT
> ___lc_codepage_func(): https://github.com/niXman/mingw-builds/issues/649
>
> bfd/bfdio.c | 19 ++++++++++++++-----
> bfd/config.in | 4 ----
> bfd/configure | 12 ------------
> bfd/configure.ac | 1 -
> 4 files changed, 14 insertions(+), 22 deletions(-)
>
> diff --git a/bfd/bfdio.c b/bfd/bfdio.c
> index ea0d1389cd1..2d8d1d90989 100644
> --- a/bfd/bfdio.c
> +++ b/bfd/bfdio.c
> @@ -189,11 +189,20 @@ _bfd_real_fopen (const char *filename, const char *modes)
> }
>
> #ifdef __MINGW32__
> -#if !HAVE_DECL____LC_CODEPAGE_FUNC
> - /* This prototype was added to locale.h in version 9.0 of MinGW-w64. */
> - _CRTIMP unsigned int __cdecl ___lc_codepage_func (void);
> -#endif
> - const unsigned int cp = ___lc_codepage_func ();
> + /* The filename is retrieved from argv, Win32 API, CRT function, or files
> + (incl. console, pipe, socket, etc.).
> + 1) argv is always encoded in ACP.
Aren't there also cases where we read a text-ish file to fetch, among other
things, filenames from it? Their encoding won't necessarily be ACP. That
could easily be UTF-8, for example. IOW ...
> + 2) Win32 file APIs uses ACP or OEMCP, depending on return value of
> + AreFileApisANSI().
> + 3) UCRT filesystem functions internally converts strings from/to wchar_t
> + and call wide variants. It uses CP_UTF8 (if C locale set to ".utf8"),
> + CP_ACP or CP_OEMCP (depending on AreFileApisANSI()).
> + 4) MSVCRT filesystem functions simply pass strings to Win32 file APIs.
> + 5) file can be encoded in any encoding, depending on the writer.
> +
> + Ignoring case 5, which is impossible to handle, CP_ACP is the only choice
> + (and don't call SetFileApisToOEM() or setlocale(".utf8")). */
> + const unsigned int cp = CP_ACP;
... there may not be a single, uniform code page that we can use. Which
effectively looks to mean that case 5 needs handling, one way or another.
Jan
More information about the Binutils
mailing list