[PATCH v1] ld: bring vfinfo() in parity with printf() for format specifiers ll[d|i|x]
Matthieu Longo
matthieu.longo@arm.com
Thu Jan 22 17:51:46 GMT 2026
vfinfo() does not currently support the double-'l' ('ll') length
modifier for 'd', 'u', and 'x' conversion specifiers. This caused
incorrect behavior when using PRI[d|u|x][32|64] on some platforms,
and is error-prone for developers who reasonably expect
printf-compatible semantics.
This patch adds support for ll[d|u|x] to align vfinfo() with printf()
and improve portability and robustness.
---
ld/ldmisc.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/ld/ldmisc.c b/ld/ldmisc.c
index 8668e55f06d..f74216658cf 100644
--- a/ld/ldmisc.c
+++ b/ld/ldmisc.c
@@ -98,6 +98,7 @@ vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning)
{
int i;
long l;
+ long long ll;
void *p;
bfd_vma v;
struct {
@@ -110,6 +111,7 @@ vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning)
Bad,
Int,
Long,
+ LongLong,
Ptr,
Vma,
RelAddr
@@ -181,10 +183,16 @@ vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning)
break;
case 'l':
+ bool ll_type = false;
+ if (*scan == 'l')
+ {
+ ll_type = true;
+ ++scan;
+ }
if (*scan == 'd' || *scan == 'u' || *scan == 'x')
{
++scan;
- arg_type = Long;
+ arg_type = (ll_type ? LongLong : Long);
}
break;
@@ -211,6 +219,9 @@ vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning)
case Long:
args[arg_no].l = va_arg (ap, long);
break;
+ case LongLong:
+ args[arg_no].ll = va_arg (ap, long long);
+ break;
case Ptr:
args[arg_no].p = va_arg (ap, void *);
break;
@@ -567,10 +578,20 @@ vfinfo (FILE *fp, const char *fmt, va_list ap, bool is_warning)
break;
case 'l': /* (Unsigned) long integer, like printf(). */
+ bool ll_type = false;
+ if (*fmt == 'l')
+ {
+ fmt++;
+ ll_type = true;
+ }
if (*fmt == 'd' || *fmt == 'u' || *fmt == 'x')
{
- cfmt = make_cfmt (fmt - 1 - mods, mods + 2);
- fprintf (fp, cfmt, args[arg_no].l);
+ unsigned int mods_len = (ll_type ? 2 : 1);
+ cfmt = make_cfmt (fmt - mods_len - mods, mods + mods_len + 1);
+ if (ll_type)
+ fprintf (fp, cfmt, args[arg_no].ll);
+ else
+ fprintf (fp, cfmt, args[arg_no].l);
free (cfmt);
++arg_count;
++fmt;
--
2.52.0
More information about the Binutils
mailing list