]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
ld: support most modifiers for printf() like vfinfo() format specifiers
authorJan Beulich <jbeulich@suse.com>
Fri, 28 Nov 2025 08:48:18 +0000 (09:48 +0100)
committerJan Beulich <jbeulich@suse.com>
Fri, 28 Nov 2025 08:48:18 +0000 (09:48 +0100)
Not doing so is pretty error prone: One needs to distinguish e.g.
->einfo() and alike invocations out of libbfd from _bfd_error_handler()
ones. Omit support for * though for now, as that would be more intrusive
to implement.

Use this then to disambiguate x86'es ISA level diagnostic of unknown bits,
where decimal vs hex isn't immediately clear.

bfd/elfxx-x86.c
ld/ldmisc.c
ld/testsuite/ld-x86-64/pr31868a.l
ld/testsuite/ld-x86-64/pr31868b.l
ld/testsuite/ld-x86-64/pr31868c.l

index 215a1569e9d4774c3272259b917052ab29487b53..24894193c86d9f584694654dea280c6550b1bf94 100644 (file)
@@ -4247,7 +4247,7 @@ report_isa_level (struct bfd_link_info *info, bfd *abfd,
          info->callbacks->einfo ("x86-64-v4");
          break;
        default:
-         info->callbacks->einfo (_("<unknown: %x>"), bit);
+         info->callbacks->einfo (_("<unknown: %#x>"), bit);
          break;
        }
       if (bitmask)
index 3f305fa457ee6883d6880a767cdce01d7a16e35c..38cc7ff3a287789318742dbf6fd7d98cf3bc4063 100644 (file)
 #include "ldmain.h"
 #include "ldfile.h"
 
+static size_t
+count_modifiers (const char *scan)
+{
+  size_t mods = strspn (scan, "-+ #0");
+
+  while (scan[mods] != '0' && ISDIGIT (scan[mods]))
+    ++mods;
+  if (scan[mods] == '.')
+    ++mods;
+  while (scan[mods] != '0' && ISDIGIT (scan[mods]))
+    ++mods;
+
+  return mods;
+}
+
+static char *
+make_cfmt (const char *fmt, int nr)
+{
+  return xasprintf ("%%%.*s", nr, fmt);
+}
+
 /*
  %% literal %
  %C clever filename:linenumber with function
@@ -119,6 +140,9 @@ vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning)
              scan += 2;
            }
 
+         /* Skip most modifiers that printf() permits.  */
+         scan += count_modifiers (scan);
+
          arg_type = Bad;
          switch (*scan++)
            {
@@ -217,6 +241,8 @@ vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning)
 
       if (*fmt == '%')
        {
+         size_t mods;
+
          fmt++;
 
          arg_no = arg_count;
@@ -226,8 +252,14 @@ vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning)
              fmt += 2;
            }
 
+         /* Record modifiers that printf() permits and that we support.  */
+         mods = count_modifiers (fmt);
+         fmt += mods;
+
          switch (*fmt++)
            {
+             char *cfmt;
+
            case '\0':
              --fmt;
              /* Fall through.  */
@@ -514,56 +546,32 @@ vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning)
                    }
                  fprintf (fp, "%s", name);
                }
-             else
+             else /* Native (host) void* pointer, like printf().  */
                {
-                 /* native (host) void* pointer, like printf */
-                 fprintf (fp, "%p", args[arg_no].p);
+                 /* Fallthru */
+           case 's': /* Arbitrary string, like printf().  */
+                 cfmt = make_cfmt (fmt - 1 - mods, mods + 1);
+                 fprintf (fp, cfmt, args[arg_no].p);
+                 free (cfmt);
                  ++arg_count;
                }
              break;
 
-           case 's':
-             /* arbitrary string, like printf */
-             fprintf (fp, "%s", (char *) args[arg_no].p);
-             ++arg_count;
-             break;
-
-           case 'd':
-             /* integer, like printf */
-             fprintf (fp, "%d", args[arg_no].i);
-             ++arg_count;
-             break;
-
-           case 'u':
-             /* unsigned integer, like printf */
-             fprintf (fp, "%u", args[arg_no].i);
+           case 'd': /* Integer, like printf().  */
+           case 'u': /* Unsigned integer, like printf().  */
+           case 'x': /* Unsigned integer, like printf().  */
+             cfmt = make_cfmt (fmt - 1 - mods, mods + 1);
+             fprintf (fp, cfmt, args[arg_no].i);
+             free (cfmt);
              ++arg_count;
              break;
 
-           case 'x':
-             /* unsigned integer, like printf */
-             fprintf (fp, "%x", args[arg_no].i);
-             ++arg_count;
-             break;
-
-           case 'l':
-             if (*fmt == 'd')
-               {
-                 fprintf (fp, "%ld", args[arg_no].l);
-                 ++arg_count;
-                 ++fmt;
-                 break;
-               }
-             else if (*fmt == 'u')
-               {
-                 fprintf (fp, "%lu", args[arg_no].l);
-                 ++arg_count;
-                 ++fmt;
-                 break;
-               }
-             else if (*fmt == 'x')
+           case 'l': /* (Unsigned) long integer, like printf().  */
+             if (*fmt == 'd' || *fmt == 'u' || *fmt == 'x')
                {
-                 fprintf (fp, "%lx", args[arg_no].l);
+                 cfmt = make_cfmt (fmt - 1 - mods, mods + 2);
+                 fprintf (fp, cfmt, args[arg_no].l);
+                 free (cfmt);
                  ++arg_count;
                  ++fmt;
                  break;
index 1244dfd1a57fcb369bef37fcd665bbd6131c1d69..26872bccce55905e62d10733a2a60f2887561090 100644 (file)
@@ -1,4 +1,4 @@
-tmpdir/pr31868a.o: x86 ISA needed: x86-64-baseline, x86-64-v3, <unknown: 10>, <unknown: 20>
-tmpdir/pr31868a.o: x86 ISA used: x86-64-v3, x86-64-v4, <unknown: 40>
+tmpdir/pr31868a.o: x86 ISA needed: x86-64-baseline, x86-64-v3, <unknown: 0x10>, <unknown: 0x20>
+tmpdir/pr31868a.o: x86 ISA used: x86-64-v3, x86-64-v4, <unknown: 0x40>
 tmpdir/pr31868b.o: x86 ISA needed: x86-64-baseline, x86-64-v2, x86-64-v3
-tmpdir/pr31868b.o: x86 ISA used: x86-64-baseline, x86-64-v2, x86-64-v4, <unknown: 10>
+tmpdir/pr31868b.o: x86 ISA used: x86-64-baseline, x86-64-v2, x86-64-v4, <unknown: 0x10>
index 1380befde4880324f3a79e9bfdc7fb8cc8ba1f77..3ccf03c1e3c1c21445f25c9c55d7dfbfe59dd764 100644 (file)
@@ -1,2 +1,2 @@
-tmpdir/pr31868a.o: x86 ISA needed: x86-64-baseline, x86-64-v3, <unknown: 10>, <unknown: 20>
+tmpdir/pr31868a.o: x86 ISA needed: x86-64-baseline, x86-64-v3, <unknown: 0x10>, <unknown: 0x20>
 tmpdir/pr31868b.o: x86 ISA needed: x86-64-baseline, x86-64-v2, x86-64-v3
index 7de0be6c2b19980d4ad8c2ab6c098de195fa49cc..65c390c5e16cf6d6abc39afc2cec012831d8d781 100644 (file)
@@ -1,2 +1,2 @@
-tmpdir/pr31868a.o: x86 ISA used: x86-64-v3, x86-64-v4, <unknown: 40>
-tmpdir/pr31868b.o: x86 ISA used: x86-64-baseline, x86-64-v2, x86-64-v4, <unknown: 10>
+tmpdir/pr31868a.o: x86 ISA used: x86-64-v3, x86-64-v4, <unknown: 0x40>
+tmpdir/pr31868b.o: x86 ISA used: x86-64-baseline, x86-64-v2, x86-64-v4, <unknown: 0x10>