Re: [PATCH v4 16/23] perf annotate-data: Expand type_state_reg imm_value to u64

Tengda Wu <[email protected]>
Newsgroups dev.linux.lists.llvm,org.kernel.vger.linux-kernel,org.kernel.vger.linux-perf-users
Message-ID <[email protected]>

On 2026/8/11 16:10, Shuai Xue wrote:
> 
> 
> On 8/8/26 8:23 PM, Tengda Wu wrote:
>> The imm_value in struct type_state_reg is defined as u32, which limits
>> the size of values it can pass.
>>
>> Promote imm_value from u32 to u64 and adjust the print format specifier
>> in pr_debug_dtp() accordingly.
>>
>> Signed-off-by: Tengda Wu <[email protected]>
>> ---
>>   tools/perf/util/annotate-arch/annotate-x86.c | 2 +-
>>   tools/perf/util/annotate-data.h              | 2 +-
>>   2 files changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/tools/perf/util/annotate-arch/annotate-x86.c b/tools/perf/util/annotate-arch/annotate-x86.c
>> index ee4e3e7f3209..eec3d8ce00b8 100644
>> --- a/tools/perf/util/annotate-arch/annotate-x86.c
>> +++ b/tools/perf/util/annotate-arch/annotate-x86.c
>> @@ -540,7 +540,7 @@ static void update_insn_state_x86(struct type_state *state,
>>               tsr->offset = 0;
>>               tsr->ok = true;
>>   -            pr_debug_dtp("mov [%x] imm=%#x -> reg%d\n",
>> +            pr_debug_dtp("mov [%x] imm=%#"PRIx64" -> reg%d\n",
>>                        insn_offset, tsr->imm_value, dst->reg1);
>>               return;
>>           }
>> diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h
>> index 453e13bbe3e2..91b83e94c51b 100644
>> --- a/tools/perf/util/annotate-data.h
>> +++ b/tools/perf/util/annotate-data.h
>> @@ -173,7 +173,7 @@ extern struct annotated_data_stat ann_data_stat;
>>    */
>>   struct type_state_reg {
>>       Dwarf_Die type;
>> -    u32 imm_value;
>> +    u64 imm_value;
>>       /*
> One subtlety this introduces: annotated_op_loc.offset is an int, and
> immediates are parsed into it via strtol(), so assignments like
> tsr->imm_value = src->offset now sign-extend instead of preserving
> the 32-bit bit pattern. mov $0xdeadbeef used to track 0xdeadbeef,
> now it tracks 0xffffffffdeadbeef, while the register actually holds
> the zero-extended value. (Canonical kernel addresses happen to
> sign-extend back to the right value, which masks this in the common
> case.)
> 

It appears that assignments from offset to imm_value occur in only a few places:

add/sub: (already existing)
  u64 imm_value = -1ULL;
  imm_value = src->offset;  // int to u64

mov immediate: (newly introduced)
  tsr->imm_value = src->offset;  // int to u64


> Relatedly, this widening doesn't actually help 64-bit immediates on
> the strtol() path - movabs is still truncated to int at parse time.

Indeed, for movabs instructions, the immediate value is truncated due to
the width of offset and strtol() as well.

> The real consumers that need u64 are the arm64 adrp and stack paths,
> which feed imm_value from ops.source.addr / stack state directly, so
> the change is justified. But maybe worth spelling that out, and
> considering a follow-up that parses immediates with strtoull() into a
> dedicated u64 field instead of overloading the signed offset field.
> 
> Thanks,

To summarize, there are three issues:

1. Sign-extension issue in add/sub (pre-existing)
2. Sign-extension issue in mov immediate (newly introduced)
3. Truncation issue in movabs (pre-existing)

In this patch, I'd like to fix issue #2 first by adding a type cast to
avoid the sign-extension problem:

  tsr->imm_value = (s64)src->offset;

As for issues #1 and #3, which are pre-existing, a possible solution would
be to promote offset to 64-bit as well. I'm thinking of addressing those in
a separate patch series, since it involves multiple architectures and would
need careful review.

Thanks,
Tengda
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.