[binutils-gdb/gdb-16-branch] PR 32507, PRIx64 in error messages on 32-bit mingw
Eli Zaretskii
eliz@sourceware.org
Thu Jan 2 17:32:52 GMT 2025
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=97078538d6fe6269951dccd5c85f1b979bd356c3
commit 97078538d6fe6269951dccd5c85f1b979bd356c3
Author: Alan Modra <amodra@gmail.com>
Date: Wed Jan 1 22:31:50 2025 +1030
PR 32507, PRIx64 in error messages on 32-bit mingw
People, including me, had forgotten that the bfd_error_handler just
handled standard printf format strings, not MSC %I64 and suchlike.
Using PRIx64 and similar in errors does not work if the host compiler
headers define those formats as the Microsoft %I64 variety. (We
handled %ll OK, editing it to %I64 on such hosts.)
PR 32507
* bfd.c (_bfd_doprnt, _bfd_doprnt_scan): Handle %I64 and %I32
in input strings if the host defines PRId64 as "I64d".
Edit %ll to %I64 on detecting PRId64 as "I64d" rather than on
a preprocessor define.
(cherry picked from commit b38cf91f230bc3892ab9c3deb4f1b6639c657c47)
Diff:
---
bfd/bfd.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 51 insertions(+), 9 deletions(-)
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 1eef9ecdacc..7db438e26e8 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1090,8 +1090,14 @@ _bfd_doprnt (bfd_print_callback print, void *stream, const char *format,
ptr += 2;
}
+ /* There is a clash between Microsoft's non-standard I64
+ and I32 integer length modifiers and glibc's
+ non-standard I flag. */
+ const char *printf_flag_chars
+ = sizeof PRId64 == sizeof "I64d" ? "-+ #0'" : "-+ #0'I";
+
/* Move past flags. */
- while (strchr ("-+ #0'I", *ptr))
+ while (strchr (printf_flag_chars, *ptr))
*sptr++ = *ptr++;
if (*ptr == '*')
@@ -1141,6 +1147,22 @@ _bfd_doprnt (bfd_print_callback print, void *stream, const char *format,
while (ISDIGIT (*ptr))
*sptr++ = *ptr++;
}
+ if (sizeof PRId64 == sizeof "I64d" && *ptr =='I')
+ {
+ if (ptr[1] == '6' && ptr[2] == '4')
+ {
+ wide_width = 3;
+ *sptr++ = *ptr++;
+ *sptr++ = *ptr++;
+ *sptr++ = *ptr++;
+ }
+ else if (ptr[1] == '3' && ptr[2] == '2')
+ {
+ *sptr++ = *ptr++;
+ *sptr++ = *ptr++;
+ *sptr++ = *ptr++;
+ }
+ }
while (strchr ("hlL", *ptr))
{
switch (*ptr)
@@ -1192,14 +1214,17 @@ _bfd_doprnt (bfd_print_callback print, void *stream, const char *format,
PRINT_TYPE (long, l);
break;
case 2:
+ if (sizeof PRId64 == sizeof "I64d")
+ {
+ /* Convert any %ll to %I64. */
+ sptr[-3] = 'I';
+ sptr[-2] = '6';
+ sptr[-1] = '4';
+ *sptr++ = ptr[-1];
+ *sptr = '\0';
+ }
+ /* Fall through. */
default:
-#if defined (__MSVCRT__)
- sptr[-3] = 'I';
- sptr[-2] = '6';
- sptr[-1] = '4';
- *sptr++ = ptr[-1];
- *sptr = '\0';
-#endif
PRINT_TYPE (long long, ll);
break;
}
@@ -1322,8 +1347,14 @@ _bfd_doprnt_scan (const char *format, va_list ap, union _bfd_doprnt_args *args)
ptr += 2;
}
+ /* There is a clash between Microsoft's non-standard I64
+ and I32 integer length modifiers and glibc's
+ non-standard I flag. */
+ const char *printf_flag_chars
+ = sizeof PRId64 == sizeof "I64d" ? "-+ #0'" : "-+ #0'I";
+
/* Move past flags. */
- while (strchr ("-+ #0'I", *ptr))
+ while (strchr (printf_flag_chars, *ptr))
ptr++;
if (*ptr == '*')
@@ -1372,6 +1403,17 @@ _bfd_doprnt_scan (const char *format, va_list ap, union _bfd_doprnt_args *args)
while (ISDIGIT (*ptr))
ptr++;
}
+
+ if (sizeof PRId64 == sizeof "I64d" && *ptr =='I')
+ {
+ if (ptr[1] == '6' && ptr[2] == '4')
+ {
+ wide_width = 3;
+ ptr += 3;
+ }
+ else if (ptr[1] == '3' && ptr[2] == '2')
+ ptr += 3;
+ }
while (strchr ("hlL", *ptr))
{
switch (*ptr)
More information about the Binutils-cvs
mailing list