From nobody Wed Dec 17 12:56:00 2025 Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2DE112D24AB for ; Mon, 13 Oct 2025 18:16:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379381; cv=none; b=mX6Q+90X6XA/fYTwBxQBhG25qoY4ocfrkSZAOee9Y4FFcqnt8JIFAZKbc+0L6ubXXuseyY9mgmnTnNxLYWy2B6/nBazlvnpLK5okduwBeu38ckcsDKwUwQI5/ohzQrBDOMw1xUtzQFOzsFUJV8+q88etmXAuW/UTeaIsLKWiBUw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379381; c=relaxed/simple; bh=yHC8CVWMZLFswZB5BZnl64Jv+qo1EVgYh/6mmRz9jq0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=mOlYK3eH5SDIkoxFR/IRl4/9inudUwRo2hWLi6jxIPpfgqqCZ9SmT35A9a1S/xd8RmfDqIrakB0PtXfqeO5Wdq84nKphMah3Pc/I5TMHx5cy93FYe7btWzFShqgJBR0pD6KOf22TReOlfdWA831DpXBaG0iP5qHMv0qAZnHf8j4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=WZ6putqW; arc=none smtp.client-ip=209.85.128.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="WZ6putqW" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-77f7181dd64so76662247b3.1 for ; Mon, 13 Oct 2025 11:16:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1760379378; x=1760984178; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=8hkslBj9QnenKFXYBHLOJRKHFsiaTZNhKphNQFAB+kY=; b=WZ6putqWTKCSbTcvBHkjatrKgbaB8Ici1Nnej7W01WrS41WUzlH+X66aaHMQ9gdhX6 bErECYRJk0WOXnE32A6ebXZZAS2Cx4HrM9Aocjjz5KhPaCA/+MQY+qgCfUAGepXP75qs 0Yz7IqW2xB23pTSXrqoCbGYTozgevbxS7JuCaU4vKvE5i5pxtdLrqNBR8b5KKBK/tIrS 4X787CXXLUN4Tk1s6iCMSOkV80ZYxHf1RWgYGK1CQC/XTXuAoJqTrGkMbRZUsKjuvMLl jd++CS4wBwHoPZgtuDtXKHPhFn+5okojVQSFKWXPNUUqALC29PkrnmOF1pkZUVEdoKzj CO1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760379378; x=1760984178; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=8hkslBj9QnenKFXYBHLOJRKHFsiaTZNhKphNQFAB+kY=; b=mvAYC+XeImdIdLr1lxY55tesroLsZV+qpeprTRZW/fF2jstj5ZF1bnKqfaajj/5pKa 3sgEZTfjAo5Hbis2Bnk/HN+lgBfgnrLb0444Ez3zIU9EgvAaMUk8khqfO866y/l9m8MM ESf5Pjb1zLhNEnp91s7itOzjTyARpdmdA1GNm3FE75Nfiq0s3uA3ioaQ+Xxuyzs6pUJi lZqKeznzwM2iHGUUcyda56LpzznSrFM1cbrSrCfT48lhvyRG/zJhIzfV4iUyqLG8JLSb sH8CMx+SrJhT6eaJqNPnfe7YCXxMxJ35vYW9bVEom3JfT3zZUPxVI+lkzPGAl+En8QUZ SSQw== X-Forwarded-Encrypted: i=1; AJvYcCXXDvSzRmugjZeCEuKrizVTmXbbzzt3UOpqdxg9DRG5B+eXXKkvHL7JMK9yiZDsm9LEf+MVxI7kWYIdLgk=@vger.kernel.org X-Gm-Message-State: AOJu0YzkKPEEtQiUYuZ69fpnCnXkIN8rT/a4XGLMzoUWLdBtQ0X2TXUx dDQ+jOOPaUvDs/QJuunU1qmmTFz12frNKiyObCoZPi+Nljs7epRTY+YcX3BS11gSwzogOLgNBbu Bt7Rx5qhTKw== X-Google-Smtp-Source: AGHT+IHNvYc4EnpQJDa/W9ZUqFHuWghaPl58/if45oZ40Yx07rPWgPRHJhoLLoxjiElcUGodjsLfcoxze2r7 X-Received: from ybbfx3.prod.google.com ([2002:a05:6902:2ec3:b0:ea5:d578:cf1d]) (user=zecheng job=prod-delivery.src-stubby-dispatcher) by 2002:a05:690e:2145:b0:63c:f5a6:f2f6 with SMTP id 956f58d0204a3-63cf5a706d2mr6966696d50.56.1760379378159; Mon, 13 Oct 2025 11:16:18 -0700 (PDT) Date: Mon, 13 Oct 2025 18:15:58 +0000 In-Reply-To: <20251013181607.2745653-1-zecheng@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251013181607.2745653-1-zecheng@google.com> X-Mailer: git-send-email 2.51.0.788.g6d19910ace-goog Message-ID: <20251013181607.2745653-2-zecheng@google.com> Subject: [PATCH v4 1/9] perf annotate: Skip annotating data types to lea instructions From: Zecheng Li To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Masami Hiramatsu Cc: Xu Liu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Zecheng Li Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduce a helper function is_address_gen_insn() to check arch-dependent address generation instructions like lea in x86. Remove type annotation on these instructions since they are not accessing memory. It should be counted as `no_mem_ops`. Signed-off-by: Zecheng Li --- tools/perf/util/annotate.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index a2e34f149a07..fb60467fa877 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -2698,6 +2698,20 @@ static bool is_stack_canary(struct arch *arch, struc= t annotated_op_loc *loc) return false; } =20 +/** + * Returns true if the instruction has a memory operand without + * performing a load/store + */ +static bool is_address_gen_insn(struct arch *arch, struct disasm_line *dl) +{ + if (arch__is(arch, "x86")) { + if (!strncmp(dl->ins.name, "lea", 3)) + return true; + } + + return false; +} + static struct disasm_line * annotation__prev_asm_line(struct annotation *notes, struct disasm_line *cu= rr) { @@ -2806,6 +2820,12 @@ __hist_entry__get_data_type(struct hist_entry *he, s= truct arch *arch, return &stackop_type; } =20 + if (is_address_gen_insn(arch, dl)) { + istat->bad++; + ann_data_stat.no_mem_ops++; + return NO_TYPE; + } + for_each_insn_op_loc(&loc, i, op_loc) { struct data_loc_info dloc =3D { .arch =3D arch, --=20 2.51.0.788.g6d19910ace-goog From nobody Wed Dec 17 12:56:00 2025 Received: from mail-qk1-f202.google.com (mail-qk1-f202.google.com [209.85.222.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 79FE82D3731 for ; Mon, 13 Oct 2025 18:16:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379382; cv=none; b=Ctdx5wWPU4Gx6REA7F5VOhtviQNc0QllfTDb15dghe7wx53NW/EB9iX1YaTsWms3hxPfEl699JSEYH8s0pRDlPC6VvBuZ9y4v6XuZ03rVQLrR0y6n2sxBZG0FxKhLVM05nmJsBf/dBgHkfAumBxCFuhiF/ixQVqr2pXQ+8WIVCQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379382; c=relaxed/simple; bh=hdQwasz3k/8aVmkaktfyahi7bymSRNa+aUUKjsQm7jk=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=DXhz0jeNXeOiVBjUP90hXnoNjZ9hGDtfX7dfPNJGTvvio9jssX30v08TySd5mRRHKlytPpmVcTaA5oSTU1wiVqUCkV0fdPCSE9d62F5ZQU2rnj+J5Z/0SvTd3jtDNW9S+DTZxqCs22dD7fNSKVyZ2qCJX/ml6VinFxJBwnd93ec= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=dDYDMhsR; arc=none smtp.client-ip=209.85.222.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dDYDMhsR" Received: by mail-qk1-f202.google.com with SMTP id af79cd13be357-871614ad3efso2301169585a.0 for ; Mon, 13 Oct 2025 11:16:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1760379379; x=1760984179; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=iK3U66KVI+sJzm09jDANDs7sR4Zyydo9qXm47VNoMW8=; b=dDYDMhsRuF+DacdAs1t4qgAAQ2MeiqJFvvAgLVPgYd8v1SO/HqWfM3sDkQnJapq+S7 DoGPC4Uua4YiOdMC2ofGuLTcDM/by4kstq50hEFQt/AYlTtCAYF5bVIEz44QxSwyCXqy r26Zw+/P3c7FjhIzhcxNi1GDp+6WR7jn82Pagp2CMtzG1LTQYfp6UEO12WcPKiD2McMV JlIQZAYhxKepSID8XzYmctSE1dCOwuh/T3VS2Mvg7Vld1Ea5rrmDHTT4+ETRQNKufl+U 4t/6/YOiIJn1oX2l3vsVbHpc+bvRA0UNZiUoLVbZ+IL7V0y3XIyJWunPmNvhehKW55PB AGBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760379379; x=1760984179; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=iK3U66KVI+sJzm09jDANDs7sR4Zyydo9qXm47VNoMW8=; b=INdz+GaVR41jVxODKJH/O4CeoyaGO3OO/9LUUHDVU53HbQFbEWOLzP4T5ALPDR7Xq6 qUo9KALUyv7LYPo72L9ky45/ocBnKyqRyyeuKlLwSy2hoEpXPgR4lWGA1+kCNJzi6rcy gWp2m4hX3BMu5p02TIG1rXx5VlCnY65DILnigT/FmWLE4dP9U1fBqf/g60OwiT7/FTYh 6tjuaqyWO6xbaCEtgg830fgzkvwxcMoC4KdoooMvilZJeBCWeKV7IEvjuiD8ODI0f1sk Ivayv5wGU5s7/vNavVCx9ppRh8YLARiB29PHXH6OqKZvMUE9rY4SRxBg/zFwLvcGZJC3 qi1w== X-Forwarded-Encrypted: i=1; AJvYcCV7nnezlNSwtKu+EA3hobVTJF3pQ5F7q3otAfqimVQN8yw/QayWdERNs1DcTFOWp4Z6H22oxqKYoYOHCfg=@vger.kernel.org X-Gm-Message-State: AOJu0Yx3JsAv/mZ43lWC9zF4pNETsMOgbmlM9E95ilkTMfufNyj66ibH BPZjYDFHb8MoSvy7Z9atW7T/PW2TalYdRVx8x6FxTS9Noeu+UWIWfB1aW4pjc2Z1RvBy8VrwSUW c0U2b6BjUgw== X-Google-Smtp-Source: AGHT+IGc7udGKdQSdqQpU6ffFJjcbRcWgNJSXeL3L1GG7uXlpOZlJUqm14HGDZ5C/ApD9XNKSMgMASNedSBB X-Received: from qknrd8.prod.google.com ([2002:a05:620a:8dc8:b0:884:932e:e4b0]) (user=zecheng job=prod-delivery.src-stubby-dispatcher) by 2002:a05:620a:4042:b0:878:4b36:bd2f with SMTP id af79cd13be357-88354013e59mr3226060385a.73.1760379379323; Mon, 13 Oct 2025 11:16:19 -0700 (PDT) Date: Mon, 13 Oct 2025 18:15:59 +0000 In-Reply-To: <20251013181607.2745653-1-zecheng@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251013181607.2745653-1-zecheng@google.com> X-Mailer: git-send-email 2.51.0.788.g6d19910ace-goog Message-ID: <20251013181607.2745653-3-zecheng@google.com> Subject: [PATCH v4 2/9] perf annotate: Track address registers via TSR_KIND_POINTER From: Zecheng Li To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Masami Hiramatsu Cc: Xu Liu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Zecheng Li Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduce TSR_KIND_POINTER to improve the data type profiler's ability to track pointer-based memory accesses and address register variables. TSR_KIND_POINTER represents that the location holds a pointer type to the type in the type state. The semantics match the `breg` registers that describe a memory location. This change implements handling for this new kind in mov instructions and in the check_matching_type() function. When a TSR_KIND_POINTER is moved to the stack, the stack state size is set to the architecture's pointer size. Signed-off-by: Zecheng Li --- tools/perf/arch/x86/annotate/instructions.c | 15 ++++- tools/perf/util/annotate-data.c | 63 ++++++++++++++++++--- tools/perf/util/annotate-data.h | 1 + 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/arch/= x86/annotate/instructions.c index da98a4e3c52c..746443e04089 100644 --- a/tools/perf/arch/x86/annotate/instructions.c +++ b/tools/perf/arch/x86/annotate/instructions.c @@ -391,7 +391,7 @@ static void update_insn_state_x86(struct type_state *st= ate, tsr->ok =3D true; =20 /* To copy back the variable type later (hopefully) */ - if (tsr->kind =3D=3D TSR_KIND_TYPE) + if (tsr->kind =3D=3D TSR_KIND_TYPE || tsr->kind =3D=3D TSR_KIND_POINTER) tsr->copied_from =3D src->reg1; =20 pr_debug_dtp("mov [%x] reg%d -> reg%d", @@ -455,6 +455,19 @@ static void update_insn_state_x86(struct type_state *s= tate, insn_offset, src->offset, sreg, dst->reg1); pr_debug_type_name(&tsr->type, tsr->kind); } + /* Handle dereference of TSR_KIND_POINTER registers */ + else if (has_reg_type(state, sreg) && state->regs[sreg].ok && + state->regs[sreg].kind =3D=3D TSR_KIND_POINTER && + die_get_member_type(&state->regs[sreg].type, + src->offset, &type_die)) { + tsr->type =3D state->regs[sreg].type; + tsr->kind =3D TSR_KIND_TYPE; + tsr->ok =3D true; + + pr_debug_dtp("mov [%x] addr %#x(reg%d) -> reg%d", + insn_offset, src->offset, sreg, dst->reg1); + pr_debug_type_name(&tsr->type, tsr->kind); + } /* Or check if it's a global variable */ else if (sreg =3D=3D DWARF_REG_PC) { struct map_symbol *ms =3D dloc->ms; diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 903027a6fb7d..48f3bf20070f 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -59,6 +59,10 @@ void pr_debug_type_name(Dwarf_Die *die, enum type_state_= kind kind) pr_info(" constant\n"); return; case TSR_KIND_PERCPU_POINTER: + pr_info(" percpu pointer"); + /* it also prints the type info */ + break; + case TSR_KIND_POINTER: pr_info(" pointer"); /* it also prints the type info */ break; @@ -578,16 +582,25 @@ void set_stack_state(struct type_state_stack *stack, = int offset, u8 kind, int tag; Dwarf_Word size; =20 - if (dwarf_aggregate_size(type_die, &size) < 0) + if (kind =3D=3D TSR_KIND_POINTER) { + /* TODO: arch-dependent pointer size */ + size =3D sizeof(void *); + } + else if (dwarf_aggregate_size(type_die, &size) < 0) size =3D 0; =20 - tag =3D dwarf_tag(type_die); - stack->type =3D *type_die; stack->size =3D size; stack->offset =3D offset; stack->kind =3D kind; =20 + if (kind =3D=3D TSR_KIND_POINTER) { + stack->compound =3D false; + return; + } + + tag =3D dwarf_tag(type_die); + switch (tag) { case DW_TAG_structure_type: case DW_TAG_union_type: @@ -898,13 +911,25 @@ static void update_var_state(struct type_state *state= , struct data_loc_info *dlo =20 reg =3D &state->regs[var->reg]; =20 - /* For gp registers, skip the address registers for now */ - if (var->is_reg_var_addr) + if (reg->ok && reg->kind =3D=3D TSR_KIND_TYPE && + (!is_better_type(®->type, &mem_die) || var->is_reg_var_addr)) continue; =20 - if (reg->ok && reg->kind =3D=3D TSR_KIND_TYPE && - !is_better_type(®->type, &mem_die)) + /* Handle address registers with TSR_KIND_POINTER */ + if (var->is_reg_var_addr) { + if (reg->ok && reg->kind =3D=3D TSR_KIND_POINTER && + !is_better_type(®->type, &mem_die)) + continue; + + reg->type =3D mem_die; + reg->kind =3D TSR_KIND_POINTER; + reg->ok =3D true; + + pr_debug_dtp("var [%"PRIx64"] reg%d addr offset %x", + insn_offset, var->reg, var->offset); + pr_debug_type_name(&mem_die, TSR_KIND_POINTER); continue; + } =20 orig_type =3D reg->type; =20 @@ -1116,6 +1141,30 @@ static enum type_match_result check_matching_type(st= ruct type_state *state, return PERF_TMR_OK; } =20 + if (state->regs[reg].kind =3D=3D TSR_KIND_POINTER) { + struct strbuf sb; + + strbuf_init(&sb, 32); + die_get_typename_from_type(&state->regs[reg].type, &sb); + pr_debug_dtp("(ptr->%s)", sb.buf); + strbuf_release(&sb); + + /* + * Register holds a pointer (address) to the target variable. + * The type is the type of the variable it points to. + */ + *type_die =3D state->regs[reg].type; + + dloc->type_offset =3D dloc->op->offset; + + /* Get the size of the actual type */ + if (dwarf_aggregate_size(type_die, &size) < 0 || + (unsigned)dloc->type_offset >=3D size) + return PERF_TMR_BAD_OFFSET; + + return PERF_TMR_OK; + } + if (state->regs[reg].kind =3D=3D TSR_KIND_PERCPU_POINTER) { pr_debug_dtp("percpu ptr"); =20 diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-dat= a.h index df52a0a1f496..026783442056 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -35,6 +35,7 @@ enum type_state_kind { TSR_KIND_PERCPU_BASE, TSR_KIND_CONST, TSR_KIND_PERCPU_POINTER, + TSR_KIND_POINTER, TSR_KIND_CANARY, }; =20 --=20 2.51.0.788.g6d19910ace-goog From nobody Wed Dec 17 12:56:00 2025 Received: from mail-qk1-f202.google.com (mail-qk1-f202.google.com [209.85.222.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 64ADA2D46BB for ; Mon, 13 Oct 2025 18:16:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379384; cv=none; b=c2vtv4U9w2rheKMlDI2BeGZ3MOUT9zCcvg5pIupxL5Wk+CWUZvTQ/YmNEchxoGeVb+CtBx6ziB9Fr1LQZBcsjkFIoVpU/wNBYUAD8ae2pILJDR8pkU+cNXaOm15uW6QUR6YbHtj0+qEPFlfOsC+/M0ePfsS6MTR+vAF41eNbsL8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379384; c=relaxed/simple; bh=Pndkd/QRACpQhHZvNSqPSCccdoNfqhD3e1jXWeUw25w=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=kK+A5zcukz/qpfYARWrtnGHPTJ4P90SZxsuIgptFa2T8RVSTANuQgy2fHEY1H6C7JxHoD+3vi95MFV5lfrplXILsfTgUS181fiHO6xPrO1TwXtotqZPIlNbQfLtXYr8euaNaqMMMa1f35wdPyM5kHLoo9DBftHwEyXjx7TbwJXM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Ck8wTArj; arc=none smtp.client-ip=209.85.222.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Ck8wTArj" Received: by mail-qk1-f202.google.com with SMTP id af79cd13be357-870d82c566fso2187365685a.1 for ; Mon, 13 Oct 2025 11:16:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1760379380; x=1760984180; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=0RUxP/XaBdW28mZoZIkW0DCSwwfDLYDj8cuLBEMmf/U=; b=Ck8wTArjZwgZucbMfDCz/inoRN/JWeBzk6Zy8SBOQoOXKmL78IEMW5uF8ERO0MONGt SKtdoYYLH5/DdZTGh7N8rxFMvusf5KGRVFdiH5CmGZ++dkuA1zsVvyagZz69tMRqSSsX M3qqd/soEViN4gYxMXlmeMy9MzZZemoam0RXaiE961lwiOHZemq57rU91hGzbVz79fuY wHZcWIZdNf1H/EBurTIolI++K/R2o+CCxfjP0D5pJu4RVHXIt1biy3JG4Fez2rGPL5KQ ko+oORIR3UboLl/f9UpEDc27OVKCJRpGTZ8i1gPfShhhQnrAfswx9F7VS8hHN0FVSPaY cUUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760379380; x=1760984180; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=0RUxP/XaBdW28mZoZIkW0DCSwwfDLYDj8cuLBEMmf/U=; b=PiubSdWul4qOMibOtgvF66Ab3YKSXUJM3iHZDd5BlF+pffnuU4t5ZkWCcJc5JVywYr 8sijPOEXrwsThWCe6PyAAEDRwzerZNzAiizNbIlgndsYGkXgI5dbSMER3z2nOSDcNFd7 w391AijO4LN1Ln5bfhj3s114PcdnlKXFDkgtb754HIx9TLfB2A0Dzg13Ondlr3I5kmhS cwOfEFTZWRSyNR1kiE59OX//onFqX62iO/D4XZz63PLzTQJxt1W9+bvWeudmKEy3375Q Gy0HiwJVsfJpDGdMtJKcqgCFvTesYbWHHiNT0FCsXSSRQyrJgR9xcGYn/AmRjBoQh04a Ytog== X-Forwarded-Encrypted: i=1; AJvYcCWBgBTCaFEHT4L8iBOHffQuFvEw2QzWQnRqt6dZ+MQUppnskdL+1gmMO1inKTaOe8SeoNFW4lBbCtecVaA=@vger.kernel.org X-Gm-Message-State: AOJu0YxPMQgAyXSnDG8iqu5E49T2R1iCAh4w+O9CeZWb45EQgBHQ9u66 WAr98eLTnA5PRwwWzwe1yejtPGIEGCcFevaw8O2u1WOe1QNjA9CPAUIg3uHc4ElLZYrnYWQC4z4 uQc+vpdFL3Q== X-Google-Smtp-Source: AGHT+IHeQsITfvXzHll7K9FXqGqc6QQfE8GqFWhdrcuka1rjjaXsIdehpA6SOPPl0l7aEG+4RgWv/e8/bBRq X-Received: from qknb19.prod.google.com ([2002:a05:620a:f93:b0:883:5f20:4151]) (user=zecheng job=prod-delivery.src-stubby-dispatcher) by 2002:a05:620a:290f:b0:80a:99c3:54b8 with SMTP id af79cd13be357-8820aeadb7cmr3042982185a.5.1760379380358; Mon, 13 Oct 2025 11:16:20 -0700 (PDT) Date: Mon, 13 Oct 2025 18:16:00 +0000 In-Reply-To: <20251013181607.2745653-1-zecheng@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251013181607.2745653-1-zecheng@google.com> X-Mailer: git-send-email 2.51.0.788.g6d19910ace-goog Message-ID: <20251013181607.2745653-4-zecheng@google.com> Subject: [PATCH v4 3/9] perf annotate: Track arithmetic instructions on pointers From: Zecheng Li To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Masami Hiramatsu Cc: Xu Liu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Zecheng Li Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Track the arithmetic operations on registers with pointer types. We handle only add, sub and lea instructions. The original pointer information needs to be preserved for getting outermost struct types. For example, reg0 points to a struct cfs_rq, when we add 0x10 to reg0, it should preserve the information of struct cfs_rq + 0x10 in the register instead of a pointer type to the child field at 0x10. Details: 1. struct type_state_reg now includes an offset, indicating if the register points to the start or an internal part of its associated type. This offset is used in mem to reg and reg to stack mem transfers, and also applied to the final type offset. 2. lea offset(%sp/%fp), reg is now treated as taking the address of a stack variable. It worked fine in most cases, but an issue with this approach is the pointer type may not exist. 3. lea offset(%base), reg is handled by moving the type from %base and adding an offset, similar to an add operation followed by a mov reg to reg. 4. Non-stack variables from DWARF with non-zero offsets in their location expressions are now accepted with register offset tracking. Multi-register addressing modes in LEA are not supported. Signed-off-by: Zecheng Li --- tools/perf/arch/x86/annotate/instructions.c | 137 +++++++++++++++++++- tools/perf/util/annotate-data.c | 17 ++- tools/perf/util/annotate-data.h | 6 + 3 files changed, 152 insertions(+), 8 deletions(-) diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/arch/= x86/annotate/instructions.c index 746443e04089..def7729a394c 100644 --- a/tools/perf/arch/x86/annotate/instructions.c +++ b/tools/perf/arch/x86/annotate/instructions.c @@ -248,6 +248,7 @@ static void update_insn_state_x86(struct type_state *st= ate, tsr =3D &state->regs[state->ret_reg]; tsr->type =3D type_die; tsr->kind =3D TSR_KIND_TYPE; + tsr->offset =3D 0; tsr->ok =3D true; =20 pr_debug_dtp("call [%x] return -> reg%d", @@ -284,6 +285,7 @@ static void update_insn_state_x86(struct type_state *st= ate, !strcmp(var_name, "this_cpu_off") && tsr->kind =3D=3D TSR_KIND_CONST) { tsr->kind =3D TSR_KIND_PERCPU_BASE; + tsr->offset =3D 0; tsr->ok =3D true; imm_value =3D tsr->imm_value; } @@ -291,6 +293,19 @@ static void update_insn_state_x86(struct type_state *s= tate, else return; =20 + /* Ignore add to non-pointer or non-const types */ + if (tsr->kind =3D=3D TSR_KIND_POINTER || + (dwarf_tag(&tsr->type) =3D=3D DW_TAG_pointer_type && + src->reg1 !=3D DWARF_REG_PC && tsr->kind =3D=3D TSR_KIND_TYPE && !d= st->mem_ref)) { + tsr->offset +=3D imm_value; + pr_debug_dtp("add [%x] offset %#"PRIx64" to reg%d", + insn_offset, imm_value, dst->reg1); + pr_debug_type_name(&tsr->type, tsr->kind); + } + + if (tsr->kind =3D=3D TSR_KIND_CONST) + tsr->imm_value +=3D imm_value; + if (tsr->kind !=3D TSR_KIND_PERCPU_BASE) return; =20 @@ -302,6 +317,7 @@ static void update_insn_state_x86(struct type_state *st= ate, */ tsr->type =3D type_die; tsr->kind =3D TSR_KIND_PERCPU_POINTER; + tsr->offset =3D 0; tsr->ok =3D true; =20 pr_debug_dtp("add [%x] percpu %#"PRIx64" -> reg%d", @@ -311,6 +327,106 @@ static void update_insn_state_x86(struct type_state *= state, return; } =20 + if (!strncmp(dl->ins.name, "sub", 3)) { + u64 imm_value =3D -1ULL; + + if (!has_reg_type(state, dst->reg1)) + return; + + tsr =3D &state->regs[dst->reg1]; + tsr->copied_from =3D -1; + + if (src->imm) + imm_value =3D src->offset; + else if (has_reg_type(state, src->reg1) && + state->regs[src->reg1].kind =3D=3D TSR_KIND_CONST) + imm_value =3D state->regs[src->reg1].imm_value; + + if (tsr->kind =3D=3D TSR_KIND_POINTER || + (dwarf_tag(&tsr->type) =3D=3D DW_TAG_pointer_type && + src->reg1 !=3D DWARF_REG_PC && tsr->kind =3D=3D TSR_KIND_TYPE && !d= st->mem_ref)) { + tsr->offset -=3D imm_value; + pr_debug_dtp("sub [%x] offset %#"PRIx64" to reg%d", + insn_offset, imm_value, dst->reg1); + pr_debug_type_name(&tsr->type, tsr->kind); + } + + if (tsr->kind =3D=3D TSR_KIND_CONST) + tsr->imm_value -=3D imm_value; + + return; + } + + if (!strncmp(dl->ins.name, "lea", 3)) { + int sreg =3D src->reg1; + struct type_state_reg src_tsr; + + if (!has_reg_type(state, sreg) || + !has_reg_type(state, dst->reg1) || + !src->mem_ref) + return; + + src_tsr =3D state->regs[sreg]; + tsr =3D &state->regs[dst->reg1]; + + tsr->copied_from =3D -1; + tsr->ok =3D false; + + /* Case 1: Based on stack pointer or frame pointer */ + if (sreg =3D=3D fbreg || sreg =3D=3D state->stack_reg) { + struct type_state_stack *stack; + int offset =3D src->offset - fboff; + + stack =3D find_stack_state(state, offset); + if (!stack) + return; + + tsr->type =3D stack->type; + tsr->kind =3D TSR_KIND_POINTER; + tsr->offset =3D offset - stack->offset; + tsr->ok =3D true; + + if (sreg =3D=3D fbreg) { + pr_debug_dtp("lea [%x] address of -%#x(stack) -> reg%d", + insn_offset, -src->offset, dst->reg1); + } else { + pr_debug_dtp("lea [%x] address of %#x(reg%d) -> reg%d", + insn_offset, src->offset, sreg, dst->reg1); + } + + pr_debug_type_name(&tsr->type, tsr->kind); + } + /* Case 2: Based on a register holding a typed pointer */ + else if (src_tsr.ok && (src_tsr.kind =3D=3D TSR_KIND_POINTER || + (dwarf_tag(&src_tsr.type) =3D=3D DW_TAG_pointer_type && + src_tsr.kind =3D=3D TSR_KIND_TYPE))) { + + if (src_tsr.kind =3D=3D TSR_KIND_TYPE && + __die_get_real_type(&state->regs[sreg].type, &type_die) =3D=3D NULL) + return; + + if (src_tsr.kind =3D=3D TSR_KIND_POINTER) + type_die =3D state->regs[sreg].type; + + /* Check if the target type has a member at the new offset */ + if (die_get_member_type(&type_die, + src->offset + src_tsr.offset, &type_die) =3D=3D NULL) + return; + + tsr->type =3D src_tsr.type; + tsr->kind =3D src_tsr.kind; + tsr->offset =3D src->offset + src_tsr.offset; + tsr->ok =3D true; + + pr_debug_dtp("lea [%x] address of %s%#x(reg%d) -> reg%d", + insn_offset, src->offset < 0 ? "-" : "", + abs(src->offset), sreg, dst->reg1); + + pr_debug_type_name(&tsr->type, tsr->kind); + } + return; + } + if (strncmp(dl->ins.name, "mov", 3)) return; =20 @@ -345,6 +461,7 @@ static void update_insn_state_x86(struct type_state *st= ate, =20 if (var_addr =3D=3D 40) { tsr->kind =3D TSR_KIND_CANARY; + tsr->offset =3D 0; tsr->ok =3D true; =20 pr_debug_dtp("mov [%x] stack canary -> reg%d\n", @@ -361,6 +478,7 @@ static void update_insn_state_x86(struct type_state *st= ate, =20 tsr->type =3D type_die; tsr->kind =3D TSR_KIND_TYPE; + tsr->offset =3D 0; tsr->ok =3D true; =20 pr_debug_dtp("mov [%x] this-cpu addr=3D%#"PRIx64" -> reg%d", @@ -372,6 +490,7 @@ static void update_insn_state_x86(struct type_state *st= ate, if (src->imm) { tsr->kind =3D TSR_KIND_CONST; tsr->imm_value =3D src->offset; + tsr->offset =3D 0; tsr->ok =3D true; =20 pr_debug_dtp("mov [%x] imm=3D%#x -> reg%d\n", @@ -388,6 +507,7 @@ static void update_insn_state_x86(struct type_state *st= ate, tsr->type =3D state->regs[src->reg1].type; tsr->kind =3D state->regs[src->reg1].kind; tsr->imm_value =3D state->regs[src->reg1].imm_value; + tsr->offset =3D state->regs[src->reg1].offset; tsr->ok =3D true; =20 /* To copy back the variable type later (hopefully) */ @@ -421,12 +541,14 @@ static void update_insn_state_x86(struct type_state *= state, } else if (!stack->compound) { tsr->type =3D stack->type; tsr->kind =3D stack->kind; + tsr->offset =3D 0; tsr->ok =3D true; } else if (die_get_member_type(&stack->type, offset - stack->offset, &type_die)) { tsr->type =3D type_die; tsr->kind =3D TSR_KIND_TYPE; + tsr->offset =3D 0; tsr->ok =3D true; } else { tsr->ok =3D false; @@ -446,9 +568,10 @@ static void update_insn_state_x86(struct type_state *s= tate, else if (has_reg_type(state, sreg) && state->regs[sreg].ok && state->regs[sreg].kind =3D=3D TSR_KIND_TYPE && die_deref_ptr_type(&state->regs[sreg].type, - src->offset, &type_die)) { + src->offset + state->regs[sreg].offset, &type_die)) { tsr->type =3D type_die; tsr->kind =3D TSR_KIND_TYPE; + tsr->offset =3D 0; tsr->ok =3D true; =20 pr_debug_dtp("mov [%x] %#x(reg%d) -> reg%d", @@ -459,9 +582,10 @@ static void update_insn_state_x86(struct type_state *s= tate, else if (has_reg_type(state, sreg) && state->regs[sreg].ok && state->regs[sreg].kind =3D=3D TSR_KIND_POINTER && die_get_member_type(&state->regs[sreg].type, - src->offset, &type_die)) { + src->offset + state->regs[sreg].offset, &type_die)) { tsr->type =3D state->regs[sreg].type; tsr->kind =3D TSR_KIND_TYPE; + tsr->offset =3D src->offset + state->regs[sreg].offset; tsr->ok =3D true; =20 pr_debug_dtp("mov [%x] addr %#x(reg%d) -> reg%d", @@ -486,6 +610,7 @@ static void update_insn_state_x86(struct type_state *st= ate, =20 tsr->type =3D type_die; tsr->kind =3D TSR_KIND_TYPE; + tsr->offset =3D 0; tsr->ok =3D true; =20 pr_debug_dtp("mov [%x] global addr=3D%"PRIx64" -> reg%d", @@ -517,6 +642,7 @@ static void update_insn_state_x86(struct type_state *st= ate, die_get_member_type(&type_die, offset, &type_die)) { tsr->type =3D type_die; tsr->kind =3D TSR_KIND_TYPE; + tsr->offset =3D 0; tsr->ok =3D true; =20 if (src->multi_regs) { @@ -539,6 +665,7 @@ static void update_insn_state_x86(struct type_state *st= ate, src->offset, &type_die)) { tsr->type =3D type_die; tsr->kind =3D TSR_KIND_TYPE; + tsr->offset =3D 0; tsr->ok =3D true; =20 pr_debug_dtp("mov [%x] pointer %#x(reg%d) -> reg%d", @@ -561,6 +688,7 @@ static void update_insn_state_x86(struct type_state *st= ate, &var_name, &offset) && !strcmp(var_name, "__per_cpu_offset")) { tsr->kind =3D TSR_KIND_PERCPU_BASE; + tsr->offset =3D 0; tsr->ok =3D true; =20 pr_debug_dtp("mov [%x] percpu base reg%d\n", @@ -609,6 +737,11 @@ static void update_insn_state_x86(struct type_state *s= tate, pr_debug_dtp("mov [%x] reg%d -> %#x(reg%d)", insn_offset, src->reg1, offset, dst->reg1); } + if (tsr->offset !=3D 0) { + pr_debug_dtp(" reg%d offset %#x ->", + src->reg1, tsr->offset); + } + pr_debug_type_name(&tsr->type, tsr->kind); } /* diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 48f3bf20070f..4204a7956ee5 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -905,7 +905,7 @@ static void update_var_state(struct type_state *state, = struct data_loc_info *dlo insn_offset, -offset); } pr_debug_type_name(&mem_die, TSR_KIND_TYPE); - } else if (has_reg_type(state, var->reg) && var->offset =3D=3D 0) { + } else if (has_reg_type(state, var->reg)) { struct type_state_reg *reg; Dwarf_Die orig_type; =20 @@ -921,6 +921,7 @@ static void update_var_state(struct type_state *state, = struct data_loc_info *dlo !is_better_type(®->type, &mem_die)) continue; =20 + reg->offset =3D -var->offset; reg->type =3D mem_die; reg->kind =3D TSR_KIND_POINTER; reg->ok =3D true; @@ -932,13 +933,17 @@ static void update_var_state(struct type_state *state= , struct data_loc_info *dlo } =20 orig_type =3D reg->type; - + /* + * var->offset + reg value is the beginning of the struct + * reg->offset is the offset the reg points + */ + reg->offset =3D -var->offset; reg->type =3D mem_die; reg->kind =3D TSR_KIND_TYPE; reg->ok =3D true; =20 - pr_debug_dtp("var [%"PRIx64"] reg%d", - insn_offset, var->reg); + pr_debug_dtp("var [%"PRIx64"] reg%d offset %x", + insn_offset, var->reg, var->offset); pr_debug_type_name(&mem_die, TSR_KIND_TYPE); =20 /* @@ -1126,7 +1131,7 @@ static enum type_match_result check_matching_type(str= uct type_state *state, if (__die_get_real_type(&state->regs[reg].type, type_die) =3D=3D NULL) return PERF_TMR_NO_POINTER; =20 - dloc->type_offset =3D dloc->op->offset; + dloc->type_offset =3D dloc->op->offset + state->regs[reg].offset; =20 if (dwarf_tag(type_die) =3D=3D DW_TAG_typedef) die_get_real_type(type_die, &sized_type); @@ -1155,7 +1160,7 @@ static enum type_match_result check_matching_type(str= uct type_state *state, */ *type_die =3D state->regs[reg].type; =20 - dloc->type_offset =3D dloc->op->offset; + dloc->type_offset =3D dloc->op->offset + state->regs[reg].offset; =20 /* Get the size of the actual type */ if (dwarf_aggregate_size(type_die, &size) < 0 || diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-dat= a.h index 026783442056..14655b76db65 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -174,6 +174,12 @@ extern struct annotated_data_stat ann_data_stat; struct type_state_reg { Dwarf_Die type; u32 imm_value; + /* + * The offset within the struct that the register points to. + * A value of 0 means the register points to the beginning. + * type_offset =3D op->offset + reg->offset + */ + s32 offset; bool ok; bool caller_saved; u8 kind; --=20 2.51.0.788.g6d19910ace-goog From nobody Wed Dec 17 12:56:00 2025 Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A31152D47E2 for ; Mon, 13 Oct 2025 18:16:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379384; cv=none; b=VdxhYRVjVivC00qDLvDzDWwNewAG7Nux64h9xf0vZU/5rSqebfFJoSAIVndkSXnoWBGQgOLw9MfvKtN/ArqwC1ofpiGlMmmp8TN6lmkdVLdbYmaWSE2MIg82x+S5nlzciPJlpK6u/ktObkJnPo8e10el3mWck3J1mqBt6XklriE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379384; c=relaxed/simple; bh=TW2+el9yNuk9f/3nbdJrFQ3CeLiqhnujDCbN9J71ZbI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=KxjU1lEcGVDlYVmpx//FiKS8/Qbml4f7Bg4D5abXaSO7Zwss+jUUDh6Xl4GnZt3eYYWLC2/j0QlhJQFPbpl+1sfKuHhz0TzD0iq1/YGZ/3CM0bAq/fcJCfHig/MVKAST4Wq5HqnOyJpluXPtOQzAMz/I5vlGzZ6oL5Dj6LqBXGg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=1UaUWoCi; arc=none smtp.client-ip=209.85.128.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="1UaUWoCi" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-78103962c97so61961937b3.0 for ; Mon, 13 Oct 2025 11:16:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1760379381; x=1760984181; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=htIExVjnWIYNSVX11cfBQU24Fufomr+QvCn5zD7R72g=; b=1UaUWoCi4Fy/Dkls13cIC2cTskV6XljXsPtkm/H7UKPDwfblLlqQKO4XYsbgjm2R/O jbciNxt52l/OcghwhAhhPD5x3ClUPllmu03CAt/yNjR1668wdDtk/bXOI1+r6IZ2Jt5C W8vt5/drmPg9WHIAg0BGTtmhlEoJQtNNx4xn0a+May0aKL+Xekd4zRMmyrk/pL1kikR5 vxWihq/KLyFi8fSYThW567tGyo1Em6+lp5kwUNH7FhzGOkc6h4CtNCHtgpAxnRd9KNr5 4bTYcjWUSOhcwQRPVnMelinEzHz7q8wPVP8t888nlwi2ff+W1Y/EJaLiOo+Bhccat89q jKaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760379381; x=1760984181; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=htIExVjnWIYNSVX11cfBQU24Fufomr+QvCn5zD7R72g=; b=Ew2Wu47bIzfNfgzcKraaiWF1MGHBkU3qlTfNA8hya/iy/k5/NJ/fstvlkbQVpdlf1+ o7Fi4rQisx4xtA3Hr7RwGYFhDZw7fu3wd74s39I1Bcmq91yf6jpoYPrGFKtMG/RzdVuY WaMZgdfYiXCbhPXpMr93e2fKcxbakwtcRWltu2IQwCXmULxBkMtwvBtmKgVHzuQQbTch 6u8t0lHB0PenNMjaTnQjKa6/krplXPCgIG4NRvzpRp0xHybgbqEwNoEpwfdbVgg2bNl5 3BFF/RSLVAidkipuOyeCq6SHx02LKwNV6duSI0CpctDC6xpv/0dUO9Kwp3U2Fza1P7lg M7VQ== X-Forwarded-Encrypted: i=1; AJvYcCVnFdizQ3hP98pPH0jP8eDvdFRZBBGFNChpEwizd9/x5rQCgNqbdpSIK7QTEwHmHB9dFXex+tj4+7MzJbo=@vger.kernel.org X-Gm-Message-State: AOJu0Ywm6Xc4oRy47Pt4//ahDlkxrp/LTa+Y3WyHZqCiIvQXGe7qLxnA 7FIxuh70H2oW/iQ9+Xlp7f3PbP6vVJ3CvDwY/XDvCo/96VnQxyoxn/4sZS776EC7AjdfgTZzb+G kSSSIYru/uw== X-Google-Smtp-Source: AGHT+IEsnXhMlX9BpnaaungUNiYI9un/3vKd7EaW3I1cjNyt2UVnhfya7NNwTDiFZpEnDvq5ofL5Juc8ja0s X-Received: from ybbew5.prod.google.com ([2002:a05:6902:2985:b0:eb3:7397:f4b]) (user=zecheng job=prod-delivery.src-stubby-dispatcher) by 2002:a05:690e:1583:20b0:63c:f5a7:3d1 with SMTP id 956f58d0204a3-63cf5a70abdmr6881943d50.61.1760379381367; Mon, 13 Oct 2025 11:16:21 -0700 (PDT) Date: Mon, 13 Oct 2025 18:16:01 +0000 In-Reply-To: <20251013181607.2745653-1-zecheng@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251013181607.2745653-1-zecheng@google.com> X-Mailer: git-send-email 2.51.0.788.g6d19910ace-goog Message-ID: <20251013181607.2745653-5-zecheng@google.com> Subject: [PATCH v4 4/9] perf annotate: Save pointer offset in stack state From: Zecheng Li To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Masami Hiramatsu Cc: Xu Liu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Zecheng Li Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The tracked pointer offset was not being preserved in the stack state, which could lead to incorrect type analysis. This change adds a ptr_offset field to the type_state_stack struct and passes it to set_stack_state and findnew_stack_state to ensure the offset is preserved after the pointer is loaded from a stack location. It improves the type annotation coverage and quality. Signed-off-by: Zecheng Li --- tools/perf/arch/x86/annotate/instructions.c | 6 +++--- tools/perf/util/annotate-data.c | 12 +++++++----- tools/perf/util/annotate-data.h | 7 +++++-- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/arch/= x86/annotate/instructions.c index def7729a394c..0c87e42ca3dc 100644 --- a/tools/perf/arch/x86/annotate/instructions.c +++ b/tools/perf/arch/x86/annotate/instructions.c @@ -541,7 +541,7 @@ static void update_insn_state_x86(struct type_state *st= ate, } else if (!stack->compound) { tsr->type =3D stack->type; tsr->kind =3D stack->kind; - tsr->offset =3D 0; + tsr->offset =3D stack->ptr_offset; tsr->ok =3D true; } else if (die_get_member_type(&stack->type, offset - stack->offset, @@ -724,10 +724,10 @@ static void update_insn_state_x86(struct type_state *= state, */ if (!stack->compound) set_stack_state(stack, offset, tsr->kind, - &tsr->type); + &tsr->type, tsr->offset); } else { findnew_stack_state(state, offset, tsr->kind, - &tsr->type); + &tsr->type, tsr->offset); } =20 if (dst->reg1 =3D=3D fbreg) { diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 4204a7956ee5..e183c6104d59 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -577,7 +577,7 @@ struct type_state_stack *find_stack_state(struct type_s= tate *state, } =20 void set_stack_state(struct type_state_stack *stack, int offset, u8 kind, - Dwarf_Die *type_die) + Dwarf_Die *type_die, int ptr_offset) { int tag; Dwarf_Word size; @@ -592,6 +592,7 @@ void set_stack_state(struct type_state_stack *stack, in= t offset, u8 kind, stack->type =3D *type_die; stack->size =3D size; stack->offset =3D offset; + stack->ptr_offset =3D ptr_offset; stack->kind =3D kind; =20 if (kind =3D=3D TSR_KIND_POINTER) { @@ -614,18 +615,19 @@ void set_stack_state(struct type_state_stack *stack, = int offset, u8 kind, =20 struct type_state_stack *findnew_stack_state(struct type_state *state, int offset, u8 kind, - Dwarf_Die *type_die) + Dwarf_Die *type_die, + int ptr_offset) { struct type_state_stack *stack =3D find_stack_state(state, offset); =20 if (stack) { - set_stack_state(stack, offset, kind, type_die); + set_stack_state(stack, offset, kind, type_die, ptr_offset); return stack; } =20 stack =3D malloc(sizeof(*stack)); if (stack) { - set_stack_state(stack, offset, kind, type_die); + set_stack_state(stack, offset, kind, type_die, ptr_offset); list_add(&stack->list, &state->stack_vars); } return stack; @@ -895,7 +897,7 @@ static void update_var_state(struct type_state *state, = struct data_loc_info *dlo continue; =20 findnew_stack_state(state, offset, TSR_KIND_TYPE, - &mem_die); + &mem_die, /*ptr_offset=3D*/0); =20 if (var->reg =3D=3D state->stack_reg) { pr_debug_dtp("var [%"PRIx64"] %#x(reg%d)", diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-dat= a.h index 14655b76db65..869307c7f130 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -191,6 +191,8 @@ struct type_state_stack { struct list_head list; Dwarf_Die type; int offset; + /* pointer offset, saves tsr->offset on the stack state */ + int ptr_offset; int size; bool compound; u8 kind; @@ -247,9 +249,10 @@ int annotated_data_type__get_member_name(struct annota= ted_data_type *adt, bool has_reg_type(struct type_state *state, int reg); struct type_state_stack *findnew_stack_state(struct type_state *state, int offset, u8 kind, - Dwarf_Die *type_die); + Dwarf_Die *type_die, + int ptr_offset); void set_stack_state(struct type_state_stack *stack, int offset, u8 kind, - Dwarf_Die *type_die); + Dwarf_Die *type_die, int ptr_offset); struct type_state_stack *find_stack_state(struct type_state *state, int offset); bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *dloc, --=20 2.51.0.788.g6d19910ace-goog From nobody Wed Dec 17 12:56:00 2025 Received: from mail-qk1-f202.google.com (mail-qk1-f202.google.com [209.85.222.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A0E812D540D for ; Mon, 13 Oct 2025 18:16:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379385; cv=none; b=bNBXyw+U8mNifPohntuYwVYDZqxh7K609bfQ9IbyyI3OO0zMvd9RhO/jrOpG19BhHOJsujLlTWmjWHIvpATnujaHW9d4t349BWQ8VgZpsvDDxXcL8LTBvcGrKlG7zOExhL9A70louFWd5PqqQoXG/fr4P1AubMJEK+BAudTDYEM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379385; c=relaxed/simple; bh=ToPviQ3pz8O+6ktaQwLB74UbmlwvmLMLepaXaXplunU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=SCHvSyMF4Pk9JGbWXVvOxN/6cc5x1vfT3BaeRF9CJCoGC+fXhHodjKtDAhqGnYDmZOYSRZv2R3dBnqCYRWvlc1eRRQtHdt0m8rS0PxcAGMbFDPAzEaXUbnQ+RrtJTi6Z358wQIKieDoIxK6WT8NmwAGVlZXpZzL4w9dAcl5YCys= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=cn00r3Or; arc=none smtp.client-ip=209.85.222.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="cn00r3Or" Received: by mail-qk1-f202.google.com with SMTP id af79cd13be357-8589058c6d1so1013430485a.3 for ; Mon, 13 Oct 2025 11:16:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1760379382; x=1760984182; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=6Rfb8JCowzLJ5r2jCLPuYLaJw/PBH58RHTWh8vQaR8g=; b=cn00r3Or+0DYv/REVUn5NuRLRLwT5E1ymHfl7z/XY7qQ52TCopi3bM7ZEgoxW+4R8h FYsAo9YP1G7iT/Rh1Zc+o4VmLfA2XxHZ21dWgphikCNf6XEoWxIZkP0HH4Dy1ol0tDtA gSWgh67ldQUMES5QV0KCrzpc3dg8mjNefHWn73kQDwENyvvX6nmpkWUQ7z4bIhd3EZLP AIKhZbenXwve6UK77VesEMI5DB4ad/eAC/Jti/RWUEQOZp++WWzepku66seg01Tfw9QM nZ+PpE7nMTx0QzaJhgeEYLfoJRH0Jdurq1fjw9LbEApLhpfcTaKaPYKAzMZXZpQx9h0z eHUg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760379382; x=1760984182; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=6Rfb8JCowzLJ5r2jCLPuYLaJw/PBH58RHTWh8vQaR8g=; b=R3agtiPj6rLI1R6d6jLEeZ4YA5DHlXefSqWOAQkbn2DA6ZhTkPcXAAHw8ZYgAkcMmk evJ0D2CcwNrqgth8+mkIGW71E9PLD4oj5kq4/w3hMvAURkGp/sQPXNy/3UyTx64RS9A6 /4vv3jwrAT7BF64fFh2Szua12VyYmM8rFyJasNRnf0CgFhMH5oN0iLvJ/0AxyFqtC6n3 UsXPFgV0cmCwz6K1bBBB8eUyOVSANdKa07B+8oQcpPltJnmEbM80F5XHzABVBGWbIRWF T16LTe7XFK2dWRO6iXiOWSIEdYYlcASU8wHrd1XmCz0e/YX/JApopRd9HHlvJJ1xfsrY 86Xg== X-Forwarded-Encrypted: i=1; AJvYcCVqAuG9Y8DBOHPIh1utr/qHhIBpLiocQxQCYPt/Fvnj+IyLM4JGbcjMAEa7mhqc+Vx36FdUsqyONvYJSvE=@vger.kernel.org X-Gm-Message-State: AOJu0YwgaxdnX4/3ChMHsHpsGudQXkUxhqTL7Nw7fBMzWxeUan/maJgc CaiG4qZ5i8Kr3Ve7Fqwl/8BaITrRDuRS6siYmlIgV5z4+QiFFJmrYv828cHlTYyDhJzbRBhVHte TDxY1t8QkjQ== X-Google-Smtp-Source: AGHT+IE0IBOLOB58QpKoosKX/MQwaFpEjAcCa4XOBgT+8H584tpOOlLyfMkLMZuMbnVqng4IDrVLjAwL8Qam X-Received: from qknvl4.prod.google.com ([2002:a05:620a:7104:b0:828:a22b:ec45]) (user=zecheng job=prod-delivery.src-stubby-dispatcher) by 2002:a05:620a:1a90:b0:827:d83e:a64d with SMTP id af79cd13be357-88354ac524cmr2715680985a.27.1760379382489; Mon, 13 Oct 2025 11:16:22 -0700 (PDT) Date: Mon, 13 Oct 2025 18:16:02 +0000 In-Reply-To: <20251013181607.2745653-1-zecheng@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251013181607.2745653-1-zecheng@google.com> X-Mailer: git-send-email 2.51.0.788.g6d19910ace-goog Message-ID: <20251013181607.2745653-6-zecheng@google.com> Subject: [PATCH v4 5/9] perf annotate: Invalidate register states for untracked instructions From: Zecheng Li To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Masami Hiramatsu Cc: Xu Liu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Zecheng Li Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When tracking variable types, instructions that modify a pointer value in an untracked way can lead to incorrect type propagation. To prevent this, invalidate the register state when encountering such instructions. This change invalidates pointer types for various arithmetic and bitwise operations that current pointer offset tracking doesn't support, like imul, shl, and, inc, etc. A special case is added for 'xor reg, reg', which is a common idiom for zeroing a register. For this, the register state is updated to be a constant with a value of 0. This could introduce slight regressions if a variable is zeroed and then reused. This can be addressed in the future by using all DWARF locations for instruction tracking instead of only the first one. Signed-off-by: Zecheng Li --- tools/perf/arch/x86/annotate/instructions.c | 29 +++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/arch/= x86/annotate/instructions.c index 0c87e42ca3dc..803f9351a3fb 100644 --- a/tools/perf/arch/x86/annotate/instructions.c +++ b/tools/perf/arch/x86/annotate/instructions.c @@ -427,6 +427,35 @@ static void update_insn_state_x86(struct type_state *s= tate, return; } =20 + /* Invalidate register states for other ops which may change pointers */ + if (has_reg_type(state, dst->reg1) && !dst->mem_ref && + dwarf_tag(&state->regs[dst->reg1].type) =3D=3D DW_TAG_pointer_type) { + if (!strncmp(dl->ins.name, "imul", 4) || !strncmp(dl->ins.name, "mul", 3= ) || + !strncmp(dl->ins.name, "idiv", 4) || !strncmp(dl->ins.name, "div", 3= ) || + !strncmp(dl->ins.name, "shl", 3) || !strncmp(dl->ins.name, "shr", 3= ) || + !strncmp(dl->ins.name, "sar", 3) || !strncmp(dl->ins.name, "and", 3= ) || + !strncmp(dl->ins.name, "or", 2) || !strncmp(dl->ins.name, "neg", 3= ) || + !strncmp(dl->ins.name, "inc", 3) || !strncmp(dl->ins.name, "dec", 3= )) { + pr_debug_dtp("%s [%x] invalidate reg%d\n", + dl->ins.name, insn_offset, dst->reg1); + state->regs[dst->reg1].ok =3D false; + state->regs[dst->reg1].copied_from =3D -1; + return; + } + + if (!strncmp(dl->ins.name, "xor", 3) && dst->reg1 =3D=3D src->reg1) { + /* xor reg, reg clears the register */ + pr_debug_dtp("xor [%x] clear reg%d\n", + insn_offset, dst->reg1); + + state->regs[dst->reg1].kind =3D TSR_KIND_CONST; + state->regs[dst->reg1].imm_value =3D 0; + state->regs[dst->reg1].ok =3D true; + state->regs[dst->reg1].copied_from =3D -1; + return; + } + } + if (strncmp(dl->ins.name, "mov", 3)) return; =20 --=20 2.51.0.788.g6d19910ace-goog From nobody Wed Dec 17 12:56:00 2025 Received: from mail-qk1-f202.google.com (mail-qk1-f202.google.com [209.85.222.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A225D2D595D for ; Mon, 13 Oct 2025 18:16:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379386; cv=none; b=bvneiUCqBfmX61G/FNGTQluOJ1YsGD2rEUoYlZz4fTE5+R2rVkmANJdifyAJ08fcAScRT2a1Mks4vH3JCUPDMdzilfi5BX/prV6RV/Q/F9UTAr6HlEbUKf061/aV9g1OA7lpbnsreEJQO6jtZIPVBCZdhaLDnK967rLOeK9gfWI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379386; c=relaxed/simple; bh=WCMovf1Hp3z/2wqmOlu9KCY6h/OjWugr9o717BGY0T8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=R2uMqBI5cNo05VxP1L13Fu8xlAdvAGh/hsv5Tm8FJ7Avbem4tllOBGgxE89d0FRbZDYOJ1sKEQ8FtA5W5xoAaWSH8n46pD6CrLXkHvWYhnsOADYxjJKs77TPNL7uthSVQdROfKaa3O1+KVAaGo7OFKOpCSl89tGN+Q3VNYul+CI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=tlafQ1as; arc=none smtp.client-ip=209.85.222.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="tlafQ1as" Received: by mail-qk1-f202.google.com with SMTP id af79cd13be357-8635d475527so3090947085a.0 for ; Mon, 13 Oct 2025 11:16:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1760379384; x=1760984184; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=9/Q4qrmylQ0ZahaRzO6Ct5R5403rZDLx7xSWotYEXoA=; b=tlafQ1asDhcMrC6zMHnbGppdhxT/Gmo/LasMRUcofEiwXC9VC5YUOn+IDhfiunGKT6 l3ADpX5hJ6P3hRau4oNH3iQNBugUFCU9KGhYF4b/wamZYvB19tBxnfaB/J/hSmld2MiA +VDZlRT1tc4Mzp8lMLYkOWR8RFxSnyi3PCBAcN6gQyUTTakssy4UY/phfXBS0TR8+3ty 2L+8tqs7ZMZq8teO3Hv2JYzlcLOc/MgX/kFzxIscnbQHdCgFscNdbTRePhOBAvRtXdJL 4RucPnyFxPWDC6oWRFTFTeA1gaL3yWJFrRDcyDxWjGxnYY0bmPj/0RibtfJN5UqIFQ68 LGVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760379384; x=1760984184; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=9/Q4qrmylQ0ZahaRzO6Ct5R5403rZDLx7xSWotYEXoA=; b=qkrqcLvrJVa/pm7PtZfZj/66s0MZRt4g2kwq9/eqnPxuI0tii+oMikghnGK+Vvk6EW NlSvxeqRH3azAFx2V/GJlTCmNG3SWQd5Ai8W2kPea5HLX8tw/LK6Le4j+LoEgKD4v7Iz qCN3VYIhmU3wJVHlYnd7Wn849RP2fjfd4WkwsAWuRZvScxBLqLBmNYp+VMGa8+iFm+Dj 22HEBDO2Oa9ohRUgmPN+PPFIS65SycR6kfTXCgWMWi4II3yVOWT8il9GkVsVY/Ijl2xJ de8/JQ/TwaLQAIB3ti2AGkiNE8LurEXxBj4h49aNkIDldVmc8RxcgHmjSgeDhESVkj+t fxnA== X-Forwarded-Encrypted: i=1; AJvYcCWcRKchXCQ52gofPVIoWQDRxJRA58UaXvnlW8oDQxbThJ835VTkyPTCHmwF46+n3F+OY7f8VQNQN5VYcgM=@vger.kernel.org X-Gm-Message-State: AOJu0YzUYoczOMjgPMEegNPT4Ri4vmu8rMShLieNkzYkSRKrZ2JHY2z9 OsxBl4VX0Z+nE7MOyEBMB1y2qZ+fNloFxrSDURiG/62QJfRNfVPTWrxQAEszZsM149CNFgiypQD TP/iD6LVP+g== X-Google-Smtp-Source: AGHT+IGM2AoaSd3nDrndaQjFdiYhooI9Py/X2tre2/qsfMZIxxhQcfC3sDhJx0tB1eNWuUGf+Ey469hBnirw X-Received: from qkox14.prod.google.com ([2002:a05:620a:258e:b0:845:8e5b:c8a4]) (user=zecheng job=prod-delivery.src-stubby-dispatcher) by 2002:a05:620a:458c:b0:868:54ba:7c42 with SMTP id af79cd13be357-88352f83d61mr3042209185a.25.1760379383634; Mon, 13 Oct 2025 11:16:23 -0700 (PDT) Date: Mon, 13 Oct 2025 18:16:03 +0000 In-Reply-To: <20251013181607.2745653-1-zecheng@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251013181607.2745653-1-zecheng@google.com> X-Mailer: git-send-email 2.51.0.788.g6d19910ace-goog Message-ID: <20251013181607.2745653-7-zecheng@google.com> Subject: [PATCH v4 6/9] perf dwarf-aux: Skip check_variable for die_find_variable_by_reg From: Zecheng Li To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Masami Hiramatsu Cc: Xu Liu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Zecheng Li Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In die_find_variable_by_reg, match_var_offset already performs sufficient checking and type matching. The additional check_variable call is redundant, and its need_pointer logic is only a heuristic. Since DWARF encodes accurate type information, which match_var_offset verifies, skipping check_variable improves both coverage and accuracy. Return type from die_find_variable_by_reg via a new `type` field in find_var_data. Signed-off-by: Zecheng Li --- tools/perf/util/annotate-data.c | 8 +++++--- tools/perf/util/dwarf-aux.c | 18 +++++++++++------- tools/perf/util/dwarf-aux.h | 2 +- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index e183c6104d59..4b08331b9dd3 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -1603,19 +1603,21 @@ static int find_data_type_die(struct data_loc_info = *dloc, Dwarf_Die *type_die) if (!die_find_variable_by_addr(&scopes[i], dloc->var_addr, &var_die, &type_offset)) continue; + /* Found a variable, see if it's correct */ + result =3D check_variable(dloc, &var_die, &mem_die, reg, + type_offset, is_fbreg); } else { /* Look up variables/parameters in this scope */ if (!die_find_variable_by_reg(&scopes[i], pc, reg, - &type_offset, is_fbreg, &var_die)) + &mem_die, &type_offset, is_fbreg, &var_die)) continue; + result =3D PERF_TMR_OK; } =20 pr_debug_dtp("found \"%s\" (die: %#lx) in scope=3D%d/%d (die: %#lx) ", dwarf_diename(&var_die), (long)dwarf_dieoffset(&var_die), i+1, nr_scopes, (long)dwarf_dieoffset(&scopes[i])); =20 - /* Found a variable, see if it's correct */ - result =3D check_variable(dloc, &var_die, &mem_die, reg, type_offset, is= _fbreg); if (result =3D=3D PERF_TMR_OK) { if (reg =3D=3D DWARF_REG_PC) { pr_debug_dtp("addr=3D%#"PRIx64" type_offset=3D%#x\n", diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 9267af204c7d..b57cdc8860f0 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -1378,6 +1378,8 @@ struct find_var_data { Dwarf_Addr addr; /* Target register */ unsigned reg; + /* Access data type */ + Dwarf_Die type; /* Access offset, set for global data */ int offset; /* True if the current register is the frame base */ @@ -1390,7 +1392,6 @@ struct find_var_data { static bool match_var_offset(Dwarf_Die *die_mem, struct find_var_data *dat= a, s64 addr_offset, s64 addr_type, bool is_pointer) { - Dwarf_Die type_die; Dwarf_Word size; s64 offset =3D addr_offset - addr_type; =20 @@ -1403,16 +1404,16 @@ static bool match_var_offset(Dwarf_Die *die_mem, st= ruct find_var_data *data, if (offset < 0) return false; =20 - if (die_get_real_type(die_mem, &type_die) =3D=3D NULL) + if (die_get_real_type(die_mem, &data->type) =3D=3D NULL) return false; =20 - if (is_pointer && dwarf_tag(&type_die) =3D=3D DW_TAG_pointer_type) { + if (is_pointer && dwarf_tag(&data->type) =3D=3D DW_TAG_pointer_type) { /* Get the target type of the pointer */ - if (die_get_real_type(&type_die, &type_die) =3D=3D NULL) + if (die_get_real_type(&data->type, &data->type) =3D=3D NULL) return false; } =20 - if (dwarf_aggregate_size(&type_die, &size) < 0) + if (dwarf_aggregate_size(&data->type, &size) < 0) return false; =20 if ((u64)offset >=3D size) @@ -1529,7 +1530,7 @@ static int __die_find_var_reg_cb(Dwarf_Die *die_mem, = void *arg) * when the variable is in the stack. */ Dwarf_Die *die_find_variable_by_reg(Dwarf_Die *sc_die, Dwarf_Addr pc, int = reg, - int *poffset, bool is_fbreg, + Dwarf_Die *type_die, int *poffset, bool is_fbreg, Dwarf_Die *die_mem) { struct find_var_data data =3D { @@ -1541,8 +1542,11 @@ Dwarf_Die *die_find_variable_by_reg(Dwarf_Die *sc_di= e, Dwarf_Addr pc, int reg, Dwarf_Die *result; =20 result =3D die_find_child(sc_die, __die_find_var_reg_cb, &data, die_mem); - if (result) + if (result) { *poffset =3D data.offset; + *type_die =3D data.type; + } + return result; } =20 diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index cd481ec9c5a1..b3ee5df0b6be 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h @@ -163,7 +163,7 @@ int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_= die, struct strbuf *buf); =20 /* Find a variable saved in the 'reg' at given address */ Dwarf_Die *die_find_variable_by_reg(Dwarf_Die *sc_die, Dwarf_Addr pc, int = reg, - int *poffset, bool is_fbreg, + Dwarf_Die *type_die, int *poffset, bool is_fbreg, Dwarf_Die *die_mem); =20 /* Find a (global) variable located in the 'addr' */ --=20 2.51.0.788.g6d19910ace-goog From nobody Wed Dec 17 12:56:00 2025 Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BB42A2D6E6A for ; Mon, 13 Oct 2025 18:16:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379387; cv=none; b=I1F3/Xgr3YfBeS9z5ucGaWaW5FvXzOd0eA1w2qaNBMv0jJkNmCYhj165S2cgoMGawYVfHLOdSmVIZHvtZBAjrp/mTz4yvopd1hmbuxWO/55xWUJ5VPSZXihq6Des33vNK0FH454BoPbFf3Q3KdPauiaKTyMnZk5qKIQYX2gLyUM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379387; c=relaxed/simple; bh=ryWqvrtpoI8zwr5POQ8nx6hMsPTafW2LqQ4qX80CymM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=vD9aijmMD3eMvX5eAzLZadh9oqzTwTHpGxYTqOKCwaNZsVpqjKiAaJ36vj0jpkiv+x1MsFYB/3BEWX+9GMwDkCFSVXn0ZyG82xh0TVAYqxneqeP+7af7+RyMIZaAJG6hjP2QXLt6ldxxhwmvkI3PV3RDDHEdWJNVfdh2VuGVk/g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=R9PW0g43; arc=none smtp.client-ip=209.85.128.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="R9PW0g43" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-780e7b8460bso85976347b3.3 for ; Mon, 13 Oct 2025 11:16:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1760379385; x=1760984185; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=yerxi3Sb9FrMPViGFoPF1bYtDZcJCUN3klWtfA5sPKw=; b=R9PW0g43JZMZ+xBgP8SAhO6/q7BCmfVHmm2zmaJFufE4drusqbWHA6DCyU8EyQn/ks t6+jvqnOMZBaEJbnIOU0c7LKEOEKeX2k6OXzAaoJI9nwOs74D8huIJQfWAJGU9/mbahS Y+UIGyVs1r9NYxgVXKTgWTPx6GjM4edRPDTs8d9yXxAZMKyAm2+dnS+jHDJjcWSuZPS3 E2duimmRUR6lUJVcfSPlzUKgVRL8wfpC9xoqUAB8t9AwODIxTuEMHWRDNLjri1AIPWxb hEXsCtdfE4U9sLSl5t64+lvYMKz45UMAwLk53tSKqjzguA3uIJ47Glb1bwENQ8QE4TjC eOCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760379385; x=1760984185; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=yerxi3Sb9FrMPViGFoPF1bYtDZcJCUN3klWtfA5sPKw=; b=XWi62zmuxmMxNgnbY1KoHWoUI1ZpEIhGpERylAOVIwpCVPyk9tIjnQHJSfkQL82K5c B+pV0tBNDg+fzdq38GmzlmRyXIprDNHw/TiDy8CSTjbUC51V6C4MmlixOIzu+i2Jfinl hYQnMTkyc/SZZA4NHBRJQLxBXJsiUcjRdyfqbpOK05tDK83y5FKX+Q8ZdzY+Qkxn65Rc UDizuAtVJadtRN2MZyNJMWSpzZd9eg8TDTsLGYhrDc1Dnv441SwU3RK2n0lJq5+sBLtW G5PmQRjTyyovmHA+U3DR1+0ud287Fvqtv2eVTQgQ1vpoqA1YWWZmVj6YoIKXgIFn3FUa 8tmw== X-Forwarded-Encrypted: i=1; AJvYcCXJkhvh/bHH48CPpZEA/vqY9A6bk0lY30XeXZnKucSrrXmuZZ2JhuFPy04vrZuAclLVlECbBkfytI5Izs8=@vger.kernel.org X-Gm-Message-State: AOJu0YwmjbRAhcMrBMMcmb8lOFV15cpK3OUmPVDF2WnIVkrtpddGNca0 tmAO6dUuVBc0rIGRU99raOMJaGaThfnsKTV7Hdd9FPLQgkxhKgkl67TAycQbi1snKFJbGcqixu3 xvZgB/CUHPQ== X-Google-Smtp-Source: AGHT+IH8wNTHsKtdr+Ws5rHHvJKzhFXtFqipPxtDdHXZpOw0LksXCSiXUW1mP4kDR0TY9JA/NdxF8VkMUyOx X-Received: from ybbdf8.prod.google.com ([2002:a05:6902:e08:b0:eb8:89e0:b8a8]) (user=zecheng job=prod-delivery.src-stubby-dispatcher) by 2002:a53:ef11:0:b0:63c:bebc:5e67 with SMTP id 956f58d0204a3-63ccb8d834amr16628011d50.33.1760379384861; Mon, 13 Oct 2025 11:16:24 -0700 (PDT) Date: Mon, 13 Oct 2025 18:16:04 +0000 In-Reply-To: <20251013181607.2745653-1-zecheng@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251013181607.2745653-1-zecheng@google.com> X-Mailer: git-send-email 2.51.0.788.g6d19910ace-goog Message-ID: <20251013181607.2745653-8-zecheng@google.com> Subject: [PATCH v4 7/9] perf dwarf-aux: Preserve typedefs in match_var_offset From: Zecheng Li To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Masami Hiramatsu Cc: Xu Liu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Zecheng Li Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Since we are skipping the check_variable, we need to preserve typedefs in match_var_offset to match the results by __die_get_real_type. Also move the (offset =3D=3D 0) branch after the is_pointer check to ensure the correct type is used, fixing cases where an incorrect pointer type was chosen when the access offset was 0. Signed-off-by: Zecheng Li --- tools/perf/util/dwarf-aux.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index b57cdc8860f0..b2189de07daf 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -1395,24 +1395,24 @@ static bool match_var_offset(Dwarf_Die *die_mem, st= ruct find_var_data *data, Dwarf_Word size; s64 offset =3D addr_offset - addr_type; =20 - if (offset =3D=3D 0) { - /* Update offset relative to the start of the variable */ - data->offset =3D 0; - return true; - } - if (offset < 0) return false; =20 - if (die_get_real_type(die_mem, &data->type) =3D=3D NULL) + if (__die_get_real_type(die_mem, &data->type) =3D=3D NULL) return false; =20 if (is_pointer && dwarf_tag(&data->type) =3D=3D DW_TAG_pointer_type) { /* Get the target type of the pointer */ - if (die_get_real_type(&data->type, &data->type) =3D=3D NULL) + if (__die_get_real_type(&data->type, &data->type) =3D=3D NULL) return false; } =20 + if (offset =3D=3D 0) { + /* Update offset relative to the start of the variable */ + data->offset =3D 0; + return true; + } + if (dwarf_aggregate_size(&data->type, &size) < 0) return false; =20 --=20 2.51.0.788.g6d19910ace-goog From nobody Wed Dec 17 12:56:00 2025 Received: from mail-qk1-f201.google.com (mail-qk1-f201.google.com [209.85.222.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0A4202D77F1 for ; Mon, 13 Oct 2025 18:16:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379389; cv=none; b=jgv1iKSUhdjJ6QLuO4OBXwGON+P+7TvCY9nY1zSxapr0T78N5EeO37a7xNq0kWqG0uRO3h6fnChzvAWqS+Lo67AhtcKQ3szV28vU3bhvnhQ9gb43QXYE9R4p/70cwWOvOsoCOUFcIr8WL17Z7pwz5rk7fonxsJhLSmDY7Yr+4r0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379389; c=relaxed/simple; bh=3BrbxhGE4yqjfkMIrwpUID8JM2NrZJ3o8ooF589Xsjs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=cX7HeI8cztxMX/Zet+ZFKKbqp/CLHQ3pwaV2Sq5udNFUoSMuXGtFjWQJs+GFIyjzZBkWhwcItZH0nMMo+NAy0/mdXO2+1yDTlqFLQgMfVjWn9E846bQMUDn1Vkkm68YVOLQM9RlmRD5XciTTXNfVInwbDHjMSlm4Ysq8ljF0UNg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=CK+DZNfS; arc=none smtp.client-ip=209.85.222.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="CK+DZNfS" Received: by mail-qk1-f201.google.com with SMTP id af79cd13be357-87ae13cc97cso2718344785a.1 for ; Mon, 13 Oct 2025 11:16:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1760379386; x=1760984186; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=aKOoHqMAU4k1gwIwyn/I5QYGpjwICe+6Dwq5OwyxdxA=; b=CK+DZNfSZVyu6Ohnb8WjbASIux5ClzkoIvA9BXrQpMv5qe6v3nW4fTXG8F9az0XMWI fzayDqYNZ/1ctAmrt596lPGQLV86Jlkf+Z9qWTFirEeZyU8L9VySSRRpwGvZIiQ3SG+y HTM7CiGA9s0nrgsIeXCTWxz0A8ND0Dmt+eL/12RSicEZtfLoQSwrm7HPAI/cCOh4/ESl T59b4WCFMsh7jWrDm7UiK1o1uaCyKVLpne0m6w3P8TQCzMjB8c8NEwWmugI0Me1BmlSR Odxcd0VjXXulQgIJ7O5s6xbBfGo6WLHSiBL4w4lrbXHqXpAPPvT7BVk+TvPaLQfLKEgf U5uw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760379386; x=1760984186; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=aKOoHqMAU4k1gwIwyn/I5QYGpjwICe+6Dwq5OwyxdxA=; b=CdeIgCVp2K53QGREwnJ80WWtmhb0duBaqtfDN0qclwmqMBCnjJxiwPxRbEs4dAnchE 3laRp70ohU2n8fsGaBWtrKGnzMXtVdMfnzCm2w5M3NhtU1QPIkcTz8ac8pN5kTc6rPDH h+pR4xzfF6IgXwSCSGQID8A5Q5KZp8SsfeTJdslDncPnYUwJrFLMc7zaPoe6Sl77mdlX nu6tEpBYKvaqFlR9wyF+nyieqg/cOBpPC7d5cpO7WZQT9gaZqtiKHi2YHkw21IaZnls5 W4NN/d2vftRxoO5I2e+P9x6nuGp6sGhENXsJqMd3JQajSJL9jDdP2cBgci3AJWhLA77J I0BA== X-Forwarded-Encrypted: i=1; AJvYcCVy8urcXwpoRMaL8jJCFVm6L/DCIW2RJxp/ypwz/kOWYUUpYVGYA+4bVQYfUSRoB9up8sDwU6eOw82p+iI=@vger.kernel.org X-Gm-Message-State: AOJu0YxpihhK/zgNJsN3cINf9hRbSCTXtM1zyPx7G7OSHUwGoIEf0Gkj U0WjpG6QUJ6YiVX+hfwuoaVEyfQPjvl4BellTwxXqZ2tAqwtlRARjyGwprHBsiHjMHdlEIvbwKJ yL7+YJ9lN4A== X-Google-Smtp-Source: AGHT+IFtj5TmlV8iuUhz1jUNMXRrn+Em++O/km8PRo7zhXilShSzUHGovoDLR+AuQa9habqMXi0sBvR21TrE X-Received: from qknsw10.prod.google.com ([2002:a05:620a:4bca:b0:865:eaed:1168]) (user=zecheng job=prod-delivery.src-stubby-dispatcher) by 2002:a05:620a:1917:b0:7e3:397c:8c24 with SMTP id af79cd13be357-883521dc1a0mr2886568285a.48.1760379385985; Mon, 13 Oct 2025 11:16:25 -0700 (PDT) Date: Mon, 13 Oct 2025 18:16:05 +0000 In-Reply-To: <20251013181607.2745653-1-zecheng@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251013181607.2745653-1-zecheng@google.com> X-Mailer: git-send-email 2.51.0.788.g6d19910ace-goog Message-ID: <20251013181607.2745653-9-zecheng@google.com> Subject: [PATCH v4 8/9] perf annotate: Improve type comparison from different scopes From: Zecheng Li To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Masami Hiramatsu Cc: Xu Liu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Zecheng Li Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When comparing types from different scopes, first compare their type offsets. A larger offset means the field belongs to an outer (enclosing) struct. This helps resolve cases where a pointer is found in an inner scope, but a struct containing that pointer exists in an outer scope. Previously, is_better_type would prefer the pointer type, but the struct type is actually more complete and should be chosen. Prefer types from outer scopes when is_better_type cannot determine a better type. This sometimes helps pick a more complete type. Signed-off-by: Zecheng Li --- tools/perf/util/annotate-data.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 4b08331b9dd3..4b510eb29a5f 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -1629,7 +1629,9 @@ static int find_data_type_die(struct data_loc_info *d= loc, Dwarf_Die *type_die) pr_debug_dtp("type_offset=3D%#x\n", type_offset); } =20 - if (!found || is_better_type(type_die, &mem_die)) { + if (!found || dloc->type_offset < type_offset || + (dloc->type_offset =3D=3D type_offset && + !is_better_type(&mem_die, type_die))) { *type_die =3D mem_die; dloc->type_offset =3D type_offset; found =3D true; --=20 2.51.0.788.g6d19910ace-goog From nobody Wed Dec 17 12:56:00 2025 Received: from mail-qk1-f202.google.com (mail-qk1-f202.google.com [209.85.222.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 97D7B2D46A7 for ; Mon, 13 Oct 2025 18:16:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.222.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379390; cv=none; b=u2igZj52mgo9OmNxtkCn+7jCqXLq1BrsuJhxaetV6ywyrc8y4p4Rlx2uzt19689liNUtlq1iOYobeYy6H4ym3pqL0SBPwS/yuf0TK72Dt2Akxx5ujmY62qSR0/KK4T4DywaCzB7OxRYmKlk1qNy3VIOh2zbMkncN957zsIrd+l0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760379390; c=relaxed/simple; bh=km+x/l9OuRvmAVtEY/VVVCCFg/60Nnj0kRqUQrGjI3g=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=YExS/7TVR4/Z+I7iv09rCIaN82dUQ3oWs6VJZ3xz7ewvOJrwQitfZi1CcRus80Wk7CiIw1MnvxqdnvP+IwT2T+n8vPoYThLOGDT7ZSFGuGLWm4JKG7Gabgujm5S84w7cqF3FTz9eG06VY/9VzesSNoHmXgk3zxXWGlkL0xd13ig= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=1AREl4wq; arc=none smtp.client-ip=209.85.222.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--zecheng.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="1AREl4wq" Received: by mail-qk1-f202.google.com with SMTP id af79cd13be357-88375756116so414717285a.3 for ; Mon, 13 Oct 2025 11:16:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1760379387; x=1760984187; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=6J61GzyOstp2o8ceWzOK3Rztjz5W0zyCiAn7qdxxa6o=; b=1AREl4wqhyse7gNeBmz4K/0MC2xZgsnO5aNpYInlPoiox4gXjma6xkzLRFfVtCB9U8 TbL3jfv0L5QMO7GdOUjJdZE8wZQznmZmmEwrcFHZvM23GrGjz2erhrzcgXKqLqxEx+t1 qdZn7+uwX1uORYIduShZlUg8r6pP1cDBL6rpXlYcYjRLgpLQtI6OPeTEJ0WZacbkQeQd ZwZHqIb+GisEmUZ2H0CyST0HQVQyMD/trKPj+e0lmhzqLGW3tCNjrpuoFGKc5BqVaRWc Ij8IPqlathRLXLc+5D5pmt7fBLH3ztFU0Jzp4j/m/UiLZQLsNe/9+Km2DJxa6/vLzE0O zE1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1760379387; x=1760984187; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=6J61GzyOstp2o8ceWzOK3Rztjz5W0zyCiAn7qdxxa6o=; b=uDaIhx+96YUyAVo9XlNVekTqHJDDsyairqcXTFLEkBChzGkMmDJJf58PMBXVTM4FSX btMNT/FJky4JRl6KampO5DP81xIcorhq1lzmnCkP13r0cMOMt6u56b/KW0pmjt2Q9IpI JbY6vpU+9y5eSZJyhWgqAQMcYL0L/E09q7dOcPocNDIEC0MZxgjePiH/nrBbGr++4Ycb tvbn43M+kx66ZmgbtL4CWdBuJQumNi1yKSfTmEuE0N/x2ynHMdmzf3slfsr/0T8nb7im 9i6DqaepvBQotnDtClfawqqol78vqMTCZA6LoSIZT9fBm/VQYOrA9t6eARvJ3m1RgSlz GS0g== X-Forwarded-Encrypted: i=1; AJvYcCWO5IWY6x8N+aH1ruZRgTFwEwy/JTbmQfdF0Hxhzx4FrCw5/YvCuOPZDr32v+VOSxdao2GF+aJAKyIkveQ=@vger.kernel.org X-Gm-Message-State: AOJu0Ywyhiks3G+cZmm14twsUs2J1SLTZTlDCLEB+w+xetSY2ZKxHUaI rZNRBVfzs1fvZWJBbsYqDVdVURwmA1LZcqEVre7Wt90nsNmWS1Y+mK9E3cTQbtns6n+ilL5ApMP i21er3XwMyA== X-Google-Smtp-Source: AGHT+IE0k1TSDXGxTv1wD9ZYo1/j9WrF/5H3lBnJX4XSFxRDYKecjfAj7wH/but3Mv6CU1iTf6J7uazFY3E5 X-Received: from qkjc20.prod.google.com ([2002:a05:620a:cf4:b0:870:6b05:e13f]) (user=zecheng job=prod-delivery.src-stubby-dispatcher) by 2002:a05:620a:17ac:b0:85e:5022:33a2 with SMTP id af79cd13be357-88353c28688mr3550093185a.39.1760379387072; Mon, 13 Oct 2025 11:16:27 -0700 (PDT) Date: Mon, 13 Oct 2025 18:16:06 +0000 In-Reply-To: <20251013181607.2745653-1-zecheng@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251013181607.2745653-1-zecheng@google.com> X-Mailer: git-send-email 2.51.0.788.g6d19910ace-goog Message-ID: <20251013181607.2745653-10-zecheng@google.com> Subject: [PATCH v4 9/9] perf dwarf-aux: Support DW_OP_piece expressions From: Zecheng Li To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Masami Hiramatsu Cc: Xu Liu , linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org, Zecheng Li Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Support variables split across multiple registers or stack locations by handling DW_OP_piece in DWARF expressions. This enables correct matching of such variables by iterating over all pieces in the expression. There are two cases for matching memory access on the target register: 1. Accessing a struct member: - The type is the original variable's type. - The offset is the sum of the piece's offset and the operand's offset. 2. Dereferencing a member: - The type is the member of the original variable (the member must be a pointer). - The size must match the piece size. - The access offset is the operand's offset. This change improves support for piece-wise variable locations in DWARF expressions. Signed-off-by: Zecheng Li --- tools/perf/util/dwarf-aux.c | 244 +++++++++++++++++++++++++++--------- 1 file changed, 187 insertions(+), 57 deletions(-) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index b2189de07daf..aae15a2cb7d0 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -1390,21 +1390,44 @@ struct find_var_data { #define DWARF_OP_DIRECT_REGS 32 =20 static bool match_var_offset(Dwarf_Die *die_mem, struct find_var_data *dat= a, - s64 addr_offset, s64 addr_type, bool is_pointer) + s64 addr_offset, s64 addr_type, s64 piece_offset, + s64 piece_size, bool is_pointer) { - Dwarf_Word size; + Dwarf_Word size =3D 0; s64 offset =3D addr_offset - addr_type; =20 - if (offset < 0) + if (piece_size =3D=3D 0 || offset < 0) return false; =20 + if (piece_size > 0 && !is_pointer) { + offset +=3D piece_offset; + size =3D piece_offset + piece_size; + } + if (__die_get_real_type(die_mem, &data->type) =3D=3D NULL) return false; =20 - if (is_pointer && dwarf_tag(&data->type) =3D=3D DW_TAG_pointer_type) { - /* Get the target type of the pointer */ - if (__die_get_real_type(&data->type, &data->type) =3D=3D NULL) - return false; + if (is_pointer) { + if (piece_size < 0 && dwarf_tag(&data->type) =3D=3D DW_TAG_pointer_type)= { + /* Get the target type of the pointer */ + if (__die_get_real_type(&data->type, &data->type) =3D=3D NULL) + return false; + } + + if (piece_size > 0) { + Dwarf_Die member_die; + + if (die_get_member_type(&data->type, piece_offset, &member_die) =3D=3D = NULL) + return false; + + if (dwarf_aggregate_size(&member_die, &size) < 0) + return false; + + if (size =3D=3D (u64)piece_size && + dwarf_tag(&data->type) =3D=3D DW_TAG_pointer_type) + if (__die_get_real_type(&member_die, &data->type) =3D=3D NULL) + return false; + } } =20 if (offset =3D=3D 0) { @@ -1413,7 +1436,7 @@ static bool match_var_offset(Dwarf_Die *die_mem, stru= ct find_var_data *data, return true; } =20 - if (dwarf_aggregate_size(&data->type, &size) < 0) + if (size =3D=3D 0 && dwarf_aggregate_size(&data->type, &size) < 0) return false; =20 if ((u64)offset >=3D size) @@ -1452,6 +1475,67 @@ static bool is_breg_access_indirect(Dwarf_Op *ops, s= ize_t nops) return false; } =20 +struct op_piece_iter { + /* Pointer to the beginning of the op array */ + Dwarf_Op *ops; + size_t nops; + /* The index where the next search will begin */ + size_t current_idx; + size_t next_offset; + + /* Pointer to the start of the current piece's ops */ + Dwarf_Op *piece_ops; + /* The number of ops in the current piece */ + size_t num_piece_ops; + size_t piece_offset; +}; + +static void op_piece_iter_init(struct op_piece_iter *it, Dwarf_Op *ops, si= ze_t nops) +{ + it->ops =3D ops; + it->nops =3D nops; + it->current_idx =3D 0; + it->next_offset =3D 0; + it->piece_ops =3D NULL; + it->num_piece_ops =3D 0; + it->piece_offset =3D 0; +} + +/* Finds the next non-empty piece segment. */ +static bool op_piece_iter_next(struct op_piece_iter *it) +{ + /* Loop until a non-empty piece is found */ + while (it->current_idx < it->nops) { + size_t start; + size_t end; + + start =3D it->current_idx; + end =3D start; + + while (end < it->nops && it->ops[end].atom !=3D DW_OP_piece) + end++; + + /* The number of ops in this segment, including DW_OP_piece */ + it->num_piece_ops =3D min(end - start + 1, it->nops - start); + it->piece_ops =3D &it->ops[start]; + it->piece_offset =3D it->next_offset; + + it->current_idx =3D end; + if (it->current_idx < it->nops) { + const Dwarf_Op *piece_op =3D &it->ops[it->current_idx]; + size_t piece_size =3D (size_t)piece_op->number; + + it->next_offset +=3D piece_size; + it->current_idx++; + } + + if (end > start) + return true; + } + + return false; +} + /* Only checks direct child DIEs in the given scope. */ static int __die_find_var_reg_cb(Dwarf_Die *die_mem, void *arg) { @@ -1470,48 +1554,65 @@ static int __die_find_var_reg_cb(Dwarf_Die *die_mem= , void *arg) return DIE_FIND_CB_SIBLING; =20 while ((off =3D dwarf_getlocations(&attr, off, &base, &start, &end, &ops,= &nops)) > 0) { + struct op_piece_iter piece_iter; /* Assuming the location list is sorted by address */ if (end <=3D data->pc) continue; if (start > data->pc) break; =20 - /* Local variables accessed using frame base register */ - if (data->is_fbreg && ops->atom =3D=3D DW_OP_fbreg && - check_allowed_ops(ops, nops) && - match_var_offset(die_mem, data, data->offset, ops->number, - is_breg_access_indirect(ops, nops))) - return DIE_FIND_CB_END; + op_piece_iter_init(&piece_iter, ops, nops); + while (op_piece_iter_next(&piece_iter)) { + Dwarf_Op *pops =3D piece_iter.piece_ops; + size_t pnops =3D piece_iter.num_piece_ops; + size_t piece_offset =3D piece_iter.piece_offset; + int piece_size =3D -1; + bool is_pointer =3D true; + int access_offset =3D data->offset; =20 - /* Only match with a simple case */ - if (data->reg < DWARF_OP_DIRECT_REGS) { - /* pointer variables saved in a register 0 to 31 */ - if (ops->atom =3D=3D (DW_OP_reg0 + data->reg) && - check_allowed_ops(ops, nops) && - match_var_offset(die_mem, data, data->offset, 0, - /*is_pointer=3D*/true)) - return DIE_FIND_CB_END; + if (pops[pnops - 1].atom =3D=3D DW_OP_piece) + piece_size =3D (int)pops[pnops - 1].number; =20 - /* variables accessed by a register + offset */ - if (ops->atom =3D=3D (DW_OP_breg0 + data->reg) && - check_allowed_ops(ops, nops) && - match_var_offset(die_mem, data, data->offset, ops->number, - is_breg_access_indirect(ops, nops))) - return DIE_FIND_CB_END; - } else { - /* pointer variables saved in a register 32 or above */ - if (ops->atom =3D=3D DW_OP_regx && ops->number =3D=3D data->reg && - check_allowed_ops(ops, nops) && - match_var_offset(die_mem, data, data->offset, 0, - /*is_pointer=3D*/true)) - return DIE_FIND_CB_END; + if (!check_allowed_ops(pops, pnops)) + continue; =20 - /* variables accessed by a register + offset */ - if (ops->atom =3D=3D DW_OP_bregx && data->reg =3D=3D ops->number && - check_allowed_ops(ops, nops) && - match_var_offset(die_mem, data, data->offset, ops->number2, - is_breg_access_indirect(ops, nops))) + if ((data->is_fbreg && pops->atom =3D=3D DW_OP_fbreg) || + (pops->atom =3D=3D DW_OP_breg0 + data->reg) || + (pops->atom =3D=3D DW_OP_bregx && data->reg =3D=3D pops->number)) + is_pointer =3D is_breg_access_indirect(pops, pnops); + + /* Local variables accessed using frame base register */ + if (data->is_fbreg && pops->atom =3D=3D DW_OP_fbreg && + match_var_offset(die_mem, data, access_offset, + pops->number, piece_offset, piece_size, is_pointer)) return DIE_FIND_CB_END; + + /* Only match with a simple case */ + if (data->reg < DWARF_OP_DIRECT_REGS) { + /* pointer variables saved in a register 0 to 31 */ + if (pops->atom =3D=3D (DW_OP_reg0 + data->reg) && + match_var_offset(die_mem, data, access_offset, + 0, piece_offset, piece_size, is_pointer)) + return DIE_FIND_CB_END; + + /* variables accessed by a register + offset */ + if (pops->atom =3D=3D (DW_OP_breg0 + data->reg) && + match_var_offset(die_mem, data, access_offset, + pops->number, piece_offset, piece_size, is_pointer)) + return DIE_FIND_CB_END; + } else { + /* pointer variables saved in a register 32 or above */ + if (pops->atom =3D=3D DW_OP_regx && pops->number =3D=3D data->reg && + match_var_offset(die_mem, data, access_offset, + 0, piece_offset, piece_size, is_pointer)) + return DIE_FIND_CB_END; + + /* variables accessed by a register + offset */ + if (pops->atom =3D=3D DW_OP_bregx && data->reg =3D=3D pops->number && + match_var_offset(die_mem, data, access_offset, + pops->number2, piece_offset, piece_size, is_pointer)) + return DIE_FIND_CB_END; + } } } return DIE_FIND_CB_SIBLING; @@ -1572,7 +1673,7 @@ static int __die_find_var_addr_cb(Dwarf_Die *die_mem,= void *arg) continue; =20 if (check_allowed_ops(ops, nops) && - match_var_offset(die_mem, data, data->addr, ops->number, + match_var_offset(die_mem, data, data->addr, ops->number, 0, -1, /*is_pointer=3D*/false)) return DIE_FIND_CB_END; } @@ -1613,6 +1714,7 @@ static int __die_collect_vars_cb(Dwarf_Die *die_mem, = void *arg) Dwarf_Op *ops; size_t nops; struct die_var_type *vt; + struct op_piece_iter piece_iter; =20 if (tag !=3D DW_TAG_variable && tag !=3D DW_TAG_formal_parameter) return DIE_FIND_CB_SIBLING; @@ -1634,25 +1736,53 @@ static int __die_collect_vars_cb(Dwarf_Die *die_mem= , void *arg) if (__die_get_real_type(die_mem, &type_die) =3D=3D NULL) return DIE_FIND_CB_SIBLING; =20 - vt =3D malloc(sizeof(*vt)); - if (vt =3D=3D NULL) - return DIE_FIND_CB_END; + op_piece_iter_init(&piece_iter, ops, nops); + while (op_piece_iter_next(&piece_iter)) { + Dwarf_Op *pops =3D piece_iter.ops; + size_t pnops =3D piece_iter.num_piece_ops; + size_t piece_offset =3D piece_iter.piece_offset; + size_t offset =3D offset_from_dwarf_op(pops); + s64 piece_size =3D -1; + /* Usually a register holds the value of the variable */ + bool is_reg_var_addr =3D false; + + if (((pops->atom >=3D DW_OP_breg0 && pops->atom <=3D DW_OP_breg31) || + pops->atom =3D=3D DW_OP_bregx || pops->atom =3D=3D DW_OP_fbreg) && + !is_breg_access_indirect(pops, pnops)) + /* The register holds the address of the variable. */ + is_reg_var_addr =3D true; + + if (pops[pnops - 1].atom =3D=3D DW_OP_piece) + piece_size =3D (s64)pops[pnops - 1].number; + + if (piece_size > 0) { + if (!is_reg_var_addr) { + size_t size; + + if (die_get_member_type(&type_die, piece_offset, &type_die) =3D=3D NUL= L) + continue; =20 - /* Usually a register holds the value of a variable */ - vt->is_reg_var_addr =3D false; + if (dwarf_aggregate_size(&type_die, &size) < 0) + continue; =20 - if (((ops->atom >=3D DW_OP_breg0 && ops->atom <=3D DW_OP_breg31) || - ops->atom =3D=3D DW_OP_bregx || ops->atom =3D=3D DW_OP_fbreg) && - !is_breg_access_indirect(ops, nops)) - /* The register contains an address of the variable. */ - vt->is_reg_var_addr =3D true; + if (size !=3D (u64)piece_size) + continue; + } else + offset +=3D piece_offset; + } =20 - vt->die_off =3D dwarf_dieoffset(&type_die); - vt->addr =3D start; - vt->reg =3D reg_from_dwarf_op(ops); - vt->offset =3D offset_from_dwarf_op(ops); - vt->next =3D *var_types; - *var_types =3D vt; + vt =3D malloc(sizeof(*vt)); + if (vt =3D=3D NULL) + return DIE_FIND_CB_END; + + vt->is_reg_var_addr =3D is_reg_var_addr; + vt->die_off =3D dwarf_dieoffset(&type_die); + vt->addr =3D start; + vt->reg =3D reg_from_dwarf_op(pops); + vt->offset =3D offset; + vt->next =3D *var_types; + *var_types =3D vt; + } =20 return DIE_FIND_CB_SIBLING; } --=20 2.51.0.788.g6d19910ace-goog