PR 32507, PRIx64 in error messages on 32-bit mingw
Commit Message
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.
@@ -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)