[PATCH v1] ld: bring vfinfo() in parity with printf() for format specifiers ll[d|i|x]
Matthieu Longo
matthieu.longo@arm.com
Fri Jan 23 10:44:20 GMT 2026
On 23/01/2026 08:55, Jan Beulich wrote:
> On 22.01.2026 18:51, Matthieu Longo wrote:
>> 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.
>
> Okay with ...
>
>> --- 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(). */
>
> ... this comment also adjusted, to e.g.
>
> case 'l': /* (Unsigned) (long) long integer, like printf(). */
>
Fixed and merged.
> Just to mention, since you weren't explicitly Cc-ed: Did you see Alan's report
> from earlier this morning?
>
> Jan
>
Do you mean "object attributes v2 test woes" ?
Matthieu
>> + 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;
>
More information about the Binutils
mailing list