From nobody Wed Dec 17 17:23:50 2025 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77079143C50; Mon, 6 May 2024 12:19:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714997985; cv=none; b=YkJKCI626QW52pkDbnwMVHCzYD8z+VndS90JA6MHGjUtcO+RFQ+KoP0u1MPBPbe0RjtP0ttXq1f2p5L3+kxJ55CrS8sgqgGjSDc25AVHiTGr9HrwSJcVIJJ6UksBNm4A1oe9BX+wDkjdStYqzgrw4sWM8eCYHPZZS2hihDZp6nQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714997985; c=relaxed/simple; bh=+t73GbzopA74r4PbVpbTRktnXzuW3uHISnJX2laC4wA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=EIf+dVxwnlT96OutudT8+Qifro+gP862alkSSk8BUV2AMPkVPFwyiC7uprqxPf/8OX90mtbbQanVeXh8wh6YU1ys/q0JrG0Xtcb1HKu94V9mpFY4aXU7Ktkqb1/dl6JCmsTvO/QosTmZVHHViZny4g6EvkoIffkcewkemqi+sus= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com; spf=none smtp.mailfrom=linux.vnet.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=J1II07+m; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="J1II07+m" Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 446Arb4q020821; Mon, 6 May 2024 12:19:28 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=gSGdGqLNePCs3Ej/AqCwp17nX5/Q3Dt39eOfXgqNevw=; b=J1II07+mz7kOOCChPd4En8BQNeFPCa7r2x4E6XJ9GeVO/Siz8xZKnvGb5YmPhYgmgXxo i0sAhuG2nh3msIwaAT2/YuoUP2dwVRqP7I2fGh96GUwbIcXM0aT7NnPLm5b+eXspTwxI k2TvZ+OnIGqdfWLry8S83XjAvXChq5W7tq1tQ7w9cvOyKj/UWTM8rYrG5LqcEGvteZwt kjacLoyNjxdepBn/QGYYw6SluRclfZVfusWvTJIQypKZ8+0wdQXsRGQXQ1rwW9+YZSft sSU+FNRWfh6H5rMmIWg4y0bE4yThcqbh+7FmNLeNuyKSjj7yG9vNA12N1vzqfsnboB0S hw== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxwu5r67s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:27 +0000 Received: from m0353729.ppops.net (m0353729.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 446CJRRq021976; Mon, 6 May 2024 12:19:27 GMT Received: from ppma12.dal12v.mail.ibm.com (dc.9e.1632.ip4.static.sl-reverse.com [50.22.158.220]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxwu5r67n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:27 +0000 Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 446BfNVq030881; Mon, 6 May 2024 12:19:26 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 3xwybtr29u-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:26 +0000 Received: from smtpav06.fra02v.mail.ibm.com (smtpav06.fra02v.mail.ibm.com [10.20.54.105]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 446CJK9d22151554 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 May 2024 12:19:22 GMT Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B2F0F2004D; Mon, 6 May 2024 12:19:20 +0000 (GMT) Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E978C20040; Mon, 6 May 2024 12:19:17 +0000 (GMT) Received: from localhost.localdomain (unknown [9.43.103.211]) by smtpav06.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 6 May 2024 12:19:17 +0000 (GMT) From: Athira Rajeev To: acme@kernel.org, jolsa@kernel.org, adrian.hunter@intel.com, irogers@google.com, namhyung@kernel.org, segher@kernel.crashing.org, christophe.leroy@csgroup.eu Cc: linux-perf-users@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, maddy@linux.ibm.com, atrajeev@linux.vnet.ibm.com, kjain@linux.ibm.com, disgoel@linux.vnet.ibm.com, linux-kernel@vger.kernel.org, akanksha@linux.ibm.com Subject: [PATCH V2 1/9] tools/perf: Move the data structures related to register type to header file Date: Mon, 6 May 2024 17:48:58 +0530 Message-Id: <20240506121906.76639-2-atrajeev@linux.vnet.ibm.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> References: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: 6-Dw7ekIEr2-o_7zVJBe_2swFKYLpT4A X-Proofpoint-ORIG-GUID: 6JTIeUsf9WTB2RMy8soqVSBLRPWRaIgH X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1011,Hydra:6.0.650,FMLib:17.11.176.26 definitions=2024-05-06_07,2024-05-06_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 spamscore=0 bulkscore=0 impostorscore=0 suspectscore=0 phishscore=0 mlxlogscore=999 mlxscore=0 adultscore=0 clxscore=1015 malwarescore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2404010000 definitions=main-2405060085 Content-Type: text/plain; charset="utf-8" Data type profiling uses instruction tracking by checking each instruction and updating the register type state in some data structures. This is useful to find the data type in cases when the register state gets transferred from one reg to another. Example, in x86, "mov" instruction and in powerpc, "mr" instruction. Currently these structures are defined in annotate-data.c and instruction tracking is implemented only for x86. Move these data structures to "annotate-data.h" header file so that other arch implementations can use it in arch specific files as well. Signed-off-by: Athira Rajeev --- tools/perf/util/annotate-data.c | 53 +------------------------------ tools/perf/util/annotate-data.h | 55 +++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 52 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 2c98813f95cd..e812dec09c99 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -30,15 +30,6 @@ =20 static void delete_var_types(struct die_var_type *var_types); =20 -enum type_state_kind { - TSR_KIND_INVALID =3D 0, - TSR_KIND_TYPE, - TSR_KIND_PERCPU_BASE, - TSR_KIND_CONST, - TSR_KIND_POINTER, - TSR_KIND_CANARY, -}; - #define pr_debug_dtp(fmt, ...) \ do { \ if (debug_type_profile) \ @@ -139,49 +130,7 @@ static void pr_debug_location(Dwarf_Die *die, u64 pc, = int reg) } } =20 -/* - * Type information in a register, valid when @ok is true. - * The @caller_saved registers are invalidated after a function call. - */ -struct type_state_reg { - Dwarf_Die type; - u32 imm_value; - bool ok; - bool caller_saved; - u8 kind; -}; - -/* Type information in a stack location, dynamically allocated */ -struct type_state_stack { - struct list_head list; - Dwarf_Die type; - int offset; - int size; - bool compound; - u8 kind; -}; - -/* FIXME: This should be arch-dependent */ -#define TYPE_STATE_MAX_REGS 16 - -/* - * State table to maintain type info in each register and stack location. - * It'll be updated when new variable is allocated or type info is moved - * to a new location (register or stack). As it'd be used with the - * shortest path of basic blocks, it only maintains a single table. - */ -struct type_state { - /* state of general purpose registers */ - struct type_state_reg regs[TYPE_STATE_MAX_REGS]; - /* state of stack location */ - struct list_head stack_vars; - /* return value register */ - int ret_reg; - /* stack pointer register */ - int stack_reg; -}; - -static bool has_reg_type(struct type_state *state, int reg) +bool has_reg_type(struct type_state *state, int reg) { return (unsigned)reg < ARRAY_SIZE(state->regs); } diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-dat= a.h index 0a57d9f5ee78..ef235b1b15e1 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -6,6 +6,9 @@ #include #include #include +#include "dwarf-aux.h" +#include "annotate.h" +#include "debuginfo.h" =20 struct annotated_op_loc; struct debuginfo; @@ -15,6 +18,15 @@ struct hist_entry; struct map_symbol; struct thread; =20 +enum type_state_kind { + TSR_KIND_INVALID =3D 0, + TSR_KIND_TYPE, + TSR_KIND_PERCPU_BASE, + TSR_KIND_CONST, + TSR_KIND_POINTER, + TSR_KIND_CANARY, +}; + /** * struct annotated_member - Type of member field * @node: List entry in the parent list @@ -142,6 +154,48 @@ struct annotated_data_stat { }; extern struct annotated_data_stat ann_data_stat; =20 +/* + * Type information in a register, valid when @ok is true. + * The @caller_saved registers are invalidated after a function call. + */ +struct type_state_reg { + Dwarf_Die type; + u32 imm_value; + bool ok; + bool caller_saved; + u8 kind; +}; + +/* Type information in a stack location, dynamically allocated */ +struct type_state_stack { + struct list_head list; + Dwarf_Die type; + int offset; + int size; + bool compound; + u8 kind; +}; + +/* FIXME: This should be arch-dependent */ +#define TYPE_STATE_MAX_REGS 32 + +/* + * State table to maintain type info in each register and stack location. + * It'll be updated when new variable is allocated or type info is moved + * to a new location (register or stack). As it'd be used with the + * shortest path of basic blocks, it only maintains a single table. + */ +struct type_state { + /* state of general purpose registers */ + struct type_state_reg regs[TYPE_STATE_MAX_REGS]; + /* state of stack location */ + struct list_head stack_vars; + /* return value register */ + int ret_reg; + /* stack pointer register */ + int stack_reg; +}; + #ifdef HAVE_DWARF_SUPPORT =20 /* Returns data type at the location (ip, reg, offset) */ @@ -160,6 +214,7 @@ void global_var_type__tree_delete(struct rb_root *root); =20 int hist_entry__annotate_data_tty(struct hist_entry *he, struct evsel *evs= el); =20 +bool has_reg_type(struct type_state *state, int reg); #else /* HAVE_DWARF_SUPPORT */ =20 static inline struct annotated_data_type * --=20 2.43.0 From nobody Wed Dec 17 17:23:50 2025 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4F17B143C65; Mon, 6 May 2024 12:19:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714997987; cv=none; b=T5qjUdhq1XzPAV7ZZN+VQRqrQhlcVEXr+P65URgbPc7hFIyasLy0y+ZCfHqzJJG0awa1s9QrYJKPhspi0nE526h0cmb5OGjk43MhC90K2qxSq7b14CtWSCKgkStDeCqgrFrr1RZdTl7oKg6eZPgWns+Ciz5ynXReqOhPGRmJLbM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714997987; c=relaxed/simple; bh=UyjgwKGl4IrCF+2+cQuiQqx3LjpB/kCvakGroYwjTQQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=IDVI1w/n6BcWKMCBMOMCkLaBnsUromR+i5SQgaaMF0/R+tK/fYQYPIT1ahhjWgS9BHCyOpKb+WE5kao6fKx18WBoKbynOE+mMoFbHA1zrRj1ApNH9wLA+fSZo7au4gyP/COR9WSxy1VCektN4auNsiMCT8LxFo/d2QiKBt/Ed+A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com; spf=none smtp.mailfrom=linux.vnet.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=Xs8tJ1SC; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="Xs8tJ1SC" Received: from pps.filterd (m0353724.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 446CF411002556; Mon, 6 May 2024 12:19:32 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=ol9DHydcLUMK0Ue+h+J4cJn06ajLv2tkSstwQBnFc9s=; b=Xs8tJ1SCFo0RprFiFjB4Nvx8M2apT0JH78HcW55Ucbci0TYx0Kgr3/vW5VpYbmAkGIF+ 6PCWTmDdWbAEqoBjKx+uaC6K2FdNb3/yNppqho8rdG0tpq4rGfsRMHkM+oIbgbJ78H7k weW3q3ycbKOA5//CJsJ8Pjzpwa7LIxMSNKpcskP/m4DCS6YOgbl8Kz3EVMOH2az97Vdj JzfBBNQj3Ciz74a+O6CHJvmyUZcIOjka1GUu3PNcXcMDEN8yDZNYP7u+kFAg32/Rzn0h LhemLcarnrmE2zZDFsQDjHi4UWURXhnsm/WoYlezvPknEQ7HA0B8Ysf47aliE4Q75lm1 aw== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxy1ug0aa-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:31 +0000 Received: from m0353724.ppops.net (m0353724.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 446CJUKk010022; Mon, 6 May 2024 12:19:30 GMT Received: from ppma23.wdc07v.mail.ibm.com (5d.69.3da9.ip4.static.sl-reverse.com [169.61.105.93]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxy1ug0a6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:30 +0000 Received: from pps.filterd (ppma23.wdc07v.mail.ibm.com [127.0.0.1]) by ppma23.wdc07v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 446BQP8k004709; Mon, 6 May 2024 12:19:30 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma23.wdc07v.mail.ibm.com (PPS) with ESMTPS id 3xx5ygxefn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:29 +0000 Received: from smtpav06.fra02v.mail.ibm.com (smtpav06.fra02v.mail.ibm.com [10.20.54.105]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 446CJOeu52822402 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 May 2024 12:19:26 GMT Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 097C32005A; Mon, 6 May 2024 12:19:24 +0000 (GMT) Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 1470C2004E; Mon, 6 May 2024 12:19:21 +0000 (GMT) Received: from localhost.localdomain (unknown [9.43.103.211]) by smtpav06.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 6 May 2024 12:19:20 +0000 (GMT) From: Athira Rajeev To: acme@kernel.org, jolsa@kernel.org, adrian.hunter@intel.com, irogers@google.com, namhyung@kernel.org, segher@kernel.crashing.org, christophe.leroy@csgroup.eu Cc: linux-perf-users@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, maddy@linux.ibm.com, atrajeev@linux.vnet.ibm.com, kjain@linux.ibm.com, disgoel@linux.vnet.ibm.com, linux-kernel@vger.kernel.org, akanksha@linux.ibm.com Subject: [PATCH V2 2/9] tools/perf: Add "update_insn_state" callback function to handle arch specific instruction tracking Date: Mon, 6 May 2024 17:48:59 +0530 Message-Id: <20240506121906.76639-3-atrajeev@linux.vnet.ibm.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> References: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: EIzrSr1obIHdK7okG2g0HAj8Bl14lLqw X-Proofpoint-GUID: WbMni7Ebj-K2yxef_gWbzxIsDTjxvHXr X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1011,Hydra:6.0.650,FMLib:17.11.176.26 definitions=2024-05-06_07,2024-05-06_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 lowpriorityscore=0 phishscore=0 mlxlogscore=999 malwarescore=0 suspectscore=0 impostorscore=0 clxscore=1015 adultscore=0 mlxscore=0 spamscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2404010000 definitions=main-2405060085 Content-Type: text/plain; charset="utf-8" Add "update_insn_state" callback to "struct arch" to handle instruction tracking. Currently updating instruction state is handled by static function "update_insn_state_x86" which is defined in "annotate-data.c". Make this as a callback for specific arch and move to archs specific file "arch/x86/annotate/instructions.c" . This will help to add helper function for other platforms in file: "arch//annotate/instructions.c and make changes/updates easier. Define callback "update_insn_state" as part of "struct arch", also make some of the debug functions non-static so that it can be referenced from other places. Signed-off-by: Athira Rajeev --- tools/perf/arch/x86/annotate/instructions.c | 383 +++++++++++++++++++ tools/perf/util/annotate-data.c | 391 +------------------- tools/perf/util/annotate-data.h | 23 ++ tools/perf/util/disasm.c | 2 + tools/perf/util/disasm.h | 7 + 5 files changed, 423 insertions(+), 383 deletions(-) diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/arch/= x86/annotate/instructions.c index 5cdf457f5cbe..cd2fa59a8034 100644 --- a/tools/perf/arch/x86/annotate/instructions.c +++ b/tools/perf/arch/x86/annotate/instructions.c @@ -206,3 +206,386 @@ static int x86__annotate_init(struct arch *arch, char= *cpuid) arch->initialized =3D true; return err; } + +#ifdef HAVE_DWARF_SUPPORT +static void update_insn_state_x86(struct type_state *state, + struct data_loc_info *dloc, Dwarf_Die *cu_die, + struct disasm_line *dl) +{ + struct annotated_insn_loc loc; + struct annotated_op_loc *src =3D &loc.ops[INSN_OP_SOURCE]; + struct annotated_op_loc *dst =3D &loc.ops[INSN_OP_TARGET]; + struct type_state_reg *tsr; + Dwarf_Die type_die; + u32 insn_offset =3D dl->al.offset; + int fbreg =3D dloc->fbreg; + int fboff =3D 0; + + if (annotate_get_insn_location(dloc->arch, dl, &loc) < 0) + return; + + if (ins__is_call(&dl->ins)) { + struct symbol *func =3D dl->ops.target.sym; + + if (func =3D=3D NULL) + return; + + /* __fentry__ will preserve all registers */ + if (!strcmp(func->name, "__fentry__")) + return; + + pr_debug_dtp("call [%x] %s\n", insn_offset, func->name); + + /* Otherwise invalidate caller-saved registers after call */ + for (unsigned i =3D 0; i < ARRAY_SIZE(state->regs); i++) { + if (state->regs[i].caller_saved) + state->regs[i].ok =3D false; + } + + /* Update register with the return type (if any) */ + if (die_find_func_rettype(cu_die, func->name, &type_die)) { + tsr =3D &state->regs[state->ret_reg]; + tsr->type =3D type_die; + tsr->kind =3D TSR_KIND_TYPE; + tsr->ok =3D true; + + pr_debug_dtp("call [%x] return -> reg%d", + insn_offset, state->ret_reg); + pr_debug_type_name(&type_die, tsr->kind); + } + return; + } + + if (!strncmp(dl->ins.name, "add", 3)) { + u64 imm_value =3D -1ULL; + int offset; + const char *var_name =3D NULL; + struct map_symbol *ms =3D dloc->ms; + u64 ip =3D ms->sym->start + dl->al.offset; + + if (!has_reg_type(state, dst->reg1)) + return; + + tsr =3D &state->regs[dst->reg1]; + + 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; + else if (src->reg1 =3D=3D DWARF_REG_PC) { + u64 var_addr =3D annotate_calc_pcrel(dloc->ms, ip, + src->offset, dl); + + if (get_global_var_info(dloc, var_addr, + &var_name, &offset) && + !strcmp(var_name, "this_cpu_off") && + tsr->kind =3D=3D TSR_KIND_CONST) { + tsr->kind =3D TSR_KIND_PERCPU_BASE; + imm_value =3D tsr->imm_value; + } + } + else + return; + + if (tsr->kind !=3D TSR_KIND_PERCPU_BASE) + return; + + if (get_global_var_type(cu_die, dloc, ip, imm_value, &offset, + &type_die) && offset =3D=3D 0) { + /* + * This is not a pointer type, but it should be treated + * as a pointer. + */ + tsr->type =3D type_die; + tsr->kind =3D TSR_KIND_POINTER; + tsr->ok =3D true; + + pr_debug_dtp("add [%x] percpu %#"PRIx64" -> reg%d", + insn_offset, imm_value, dst->reg1); + pr_debug_type_name(&tsr->type, tsr->kind); + } + return; + } + + if (strncmp(dl->ins.name, "mov", 3)) + return; + + if (dloc->fb_cfa) { + u64 ip =3D dloc->ms->sym->start + dl->al.offset; + u64 pc =3D map__rip_2objdump(dloc->ms->map, ip); + + if (die_get_cfa(dloc->di->dbg, pc, &fbreg, &fboff) < 0) + fbreg =3D -1; + } + + /* Case 1. register to register or segment:offset to register transfers */ + if (!src->mem_ref && !dst->mem_ref) { + if (!has_reg_type(state, dst->reg1)) + return; + + tsr =3D &state->regs[dst->reg1]; + if (map__dso(dloc->ms->map)->kernel && + src->segment =3D=3D INSN_SEG_X86_GS && src->imm) { + u64 ip =3D dloc->ms->sym->start + dl->al.offset; + u64 var_addr; + int offset; + + /* + * In kernel, %gs points to a per-cpu region for the + * current CPU. Access with a constant offset should + * be treated as a global variable access. + */ + var_addr =3D src->offset; + + if (var_addr =3D=3D 40) { + tsr->kind =3D TSR_KIND_CANARY; + tsr->ok =3D true; + + pr_debug_dtp("mov [%x] stack canary -> reg%d\n", + insn_offset, dst->reg1); + return; + } + + if (!get_global_var_type(cu_die, dloc, ip, var_addr, + &offset, &type_die) || + !die_get_member_type(&type_die, offset, &type_die)) { + tsr->ok =3D false; + return; + } + + tsr->type =3D type_die; + tsr->kind =3D TSR_KIND_TYPE; + tsr->ok =3D true; + + pr_debug_dtp("mov [%x] this-cpu addr=3D%#"PRIx64" -> reg%d", + insn_offset, var_addr, dst->reg1); + pr_debug_type_name(&tsr->type, tsr->kind); + return; + } + + if (src->imm) { + tsr->kind =3D TSR_KIND_CONST; + tsr->imm_value =3D src->offset; + tsr->ok =3D true; + + pr_debug_dtp("mov [%x] imm=3D%#x -> reg%d\n", + insn_offset, tsr->imm_value, dst->reg1); + return; + } + + if (!has_reg_type(state, src->reg1) || + !state->regs[src->reg1].ok) { + tsr->ok =3D false; + return; + } + + tsr->type =3D state->regs[src->reg1].type; + tsr->kind =3D state->regs[src->reg1].kind; + tsr->ok =3D true; + + pr_debug_dtp("mov [%x] reg%d -> reg%d", + insn_offset, src->reg1, dst->reg1); + pr_debug_type_name(&tsr->type, tsr->kind); + } + /* Case 2. memory to register transers */ + if (src->mem_ref && !dst->mem_ref) { + int sreg =3D src->reg1; + + if (!has_reg_type(state, dst->reg1)) + return; + + tsr =3D &state->regs[dst->reg1]; + +retry: + /* Check stack variables with offset */ + if (sreg =3D=3D fbreg) { + struct type_state_stack *stack; + int offset =3D src->offset - fboff; + + stack =3D find_stack_state(state, offset); + if (stack =3D=3D NULL) { + tsr->ok =3D false; + return; + } else if (!stack->compound) { + tsr->type =3D stack->type; + tsr->kind =3D stack->kind; + 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->ok =3D true; + } else { + tsr->ok =3D false; + return; + } + + pr_debug_dtp("mov [%x] -%#x(stack) -> reg%d", + insn_offset, -offset, dst->reg1); + pr_debug_type_name(&tsr->type, tsr->kind); + } + /* And then dereference the pointer if it has one */ + 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)) { + tsr->type =3D type_die; + tsr->kind =3D TSR_KIND_TYPE; + tsr->ok =3D true; + + pr_debug_dtp("mov [%x] %#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; + u64 ip =3D ms->sym->start + dl->al.offset; + u64 addr; + int offset; + + addr =3D annotate_calc_pcrel(ms, ip, src->offset, dl); + + if (!get_global_var_type(cu_die, dloc, ip, addr, &offset, + &type_die) || + !die_get_member_type(&type_die, offset, &type_die)) { + tsr->ok =3D false; + return; + } + + tsr->type =3D type_die; + tsr->kind =3D TSR_KIND_TYPE; + tsr->ok =3D true; + + pr_debug_dtp("mov [%x] global addr=3D%"PRIx64" -> reg%d", + insn_offset, addr, dst->reg1); + pr_debug_type_name(&type_die, tsr->kind); + } + /* And check percpu access with base register */ + else if (has_reg_type(state, sreg) && + state->regs[sreg].kind =3D=3D TSR_KIND_PERCPU_BASE) { + u64 ip =3D dloc->ms->sym->start + dl->al.offset; + u64 var_addr =3D src->offset; + int offset; + + if (src->multi_regs) { + int reg2 =3D (sreg =3D=3D src->reg1) ? src->reg2 : src->reg1; + + if (has_reg_type(state, reg2) && state->regs[reg2].ok && + state->regs[reg2].kind =3D=3D TSR_KIND_CONST) + var_addr +=3D state->regs[reg2].imm_value; + } + + /* + * In kernel, %gs points to a per-cpu region for the + * current CPU. Access with a constant offset should + * be treated as a global variable access. + */ + if (get_global_var_type(cu_die, dloc, ip, var_addr, + &offset, &type_die) && + die_get_member_type(&type_die, offset, &type_die)) { + tsr->type =3D type_die; + tsr->kind =3D TSR_KIND_TYPE; + tsr->ok =3D true; + + if (src->multi_regs) { + pr_debug_dtp("mov [%x] percpu %#x(reg%d,reg%d) -> reg%d", + insn_offset, src->offset, src->reg1, + src->reg2, dst->reg1); + } else { + pr_debug_dtp("mov [%x] percpu %#x(reg%d) -> reg%d", + insn_offset, src->offset, sreg, dst->reg1); + } + pr_debug_type_name(&tsr->type, tsr->kind); + } else { + tsr->ok =3D false; + } + } + /* And then dereference the calculated pointer if it has one */ + 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 type_die; + tsr->kind =3D TSR_KIND_TYPE; + tsr->ok =3D true; + + pr_debug_dtp("mov [%x] pointer %#x(reg%d) -> reg%d", + insn_offset, src->offset, sreg, dst->reg1); + pr_debug_type_name(&tsr->type, tsr->kind); + } + /* Or try another register if any */ + else if (src->multi_regs && sreg =3D=3D src->reg1 && + src->reg1 !=3D src->reg2) { + sreg =3D src->reg2; + goto retry; + } + else { + int offset; + const char *var_name =3D NULL; + + /* it might be per-cpu variable (in kernel) access */ + if (src->offset < 0) { + if (get_global_var_info(dloc, (s64)src->offset, + &var_name, &offset) && + !strcmp(var_name, "__per_cpu_offset")) { + tsr->kind =3D TSR_KIND_PERCPU_BASE; + + pr_debug_dtp("mov [%x] percpu base reg%d\n", + insn_offset, dst->reg1); + } + } + + tsr->ok =3D false; + } + } + /* Case 3. register to memory transfers */ + if (!src->mem_ref && dst->mem_ref) { + if (!has_reg_type(state, src->reg1) || + !state->regs[src->reg1].ok) + return; + + /* Check stack variables with offset */ + if (dst->reg1 =3D=3D fbreg) { + struct type_state_stack *stack; + int offset =3D dst->offset - fboff; + + tsr =3D &state->regs[src->reg1]; + + stack =3D find_stack_state(state, offset); + if (stack) { + /* + * The source register is likely to hold a type + * of member if it's a compound type. Do not + * update the stack variable type since we can + * get the member type later by using the + * die_get_member_type(). + */ + if (!stack->compound) + set_stack_state(stack, offset, tsr->kind, + &tsr->type); + } else { + findnew_stack_state(state, offset, tsr->kind, + &tsr->type); + } + + pr_debug_dtp("mov [%x] reg%d -> -%#x(stack)", + insn_offset, src->reg1, -offset); + pr_debug_type_name(&tsr->type, tsr->kind); + } + /* + * Ignore other transfers since it'd set a value in a struct + * and won't change the type. + */ + } + /* Case 4. memory to memory transfers (not handled for now) */ +} +#else /* HAVE_DWARF_SUPPORT */ +static void update_insn_state_x86(struct type_state *state __maybe_unused,= struct data_loc_info *dloc __maybe_unused, + Dwarf_Die *cu_die __maybe_unused, struct disasm_line *dl __maybe_unused) +{ + return; +} +#endif /* HAVE_DWARF_SUPPORT */ diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index e812dec09c99..9d6d4f472c85 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -38,7 +38,7 @@ do { \ pr_debug3(fmt, ##__VA_ARGS__); \ } while (0) =20 -static void pr_debug_type_name(Dwarf_Die *die, enum type_state_kind kind) +void pr_debug_type_name(Dwarf_Die *die, enum type_state_kind kind) { struct strbuf sb; char *str; @@ -389,7 +389,7 @@ static int check_variable(struct data_loc_info *dloc, D= warf_Die *var_die, return 0; } =20 -static struct type_state_stack *find_stack_state(struct type_state *state, +struct type_state_stack *find_stack_state(struct type_state *state, int offset) { struct type_state_stack *stack; @@ -405,7 +405,7 @@ static struct type_state_stack *find_stack_state(struct= type_state *state, return NULL; } =20 -static void set_stack_state(struct type_state_stack *stack, int offset, u8= kind, +void set_stack_state(struct type_state_stack *stack, int offset, u8 kind, Dwarf_Die *type_die) { int tag; @@ -432,7 +432,7 @@ static void set_stack_state(struct type_state_stack *st= ack, int offset, u8 kind, } } =20 -static struct type_state_stack *findnew_stack_state(struct type_state *sta= te, +struct type_state_stack *findnew_stack_state(struct type_state *state, int offset, u8 kind, Dwarf_Die *type_die) { @@ -536,7 +536,7 @@ void global_var_type__tree_delete(struct rb_root *root) } } =20 -static bool get_global_var_info(struct data_loc_info *dloc, u64 addr, +bool get_global_var_info(struct data_loc_info *dloc, u64 addr, const char **var_name, int *var_offset) { struct addr_location al; @@ -610,7 +610,7 @@ static void global_var__collect(struct data_loc_info *d= loc) } } =20 -static bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *d= loc, +bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *dloc, u64 ip, u64 var_addr, int *var_offset, Dwarf_Die *type_die) { @@ -721,381 +721,6 @@ static void update_var_state(struct type_state *state= , struct data_loc_info *dlo } } =20 -static void update_insn_state_x86(struct type_state *state, - struct data_loc_info *dloc, Dwarf_Die *cu_die, - struct disasm_line *dl) -{ - struct annotated_insn_loc loc; - struct annotated_op_loc *src =3D &loc.ops[INSN_OP_SOURCE]; - struct annotated_op_loc *dst =3D &loc.ops[INSN_OP_TARGET]; - struct type_state_reg *tsr; - Dwarf_Die type_die; - u32 insn_offset =3D dl->al.offset; - int fbreg =3D dloc->fbreg; - int fboff =3D 0; - - if (annotate_get_insn_location(dloc->arch, dl, &loc) < 0) - return; - - if (ins__is_call(&dl->ins)) { - struct symbol *func =3D dl->ops.target.sym; - - if (func =3D=3D NULL) - return; - - /* __fentry__ will preserve all registers */ - if (!strcmp(func->name, "__fentry__")) - return; - - pr_debug_dtp("call [%x] %s\n", insn_offset, func->name); - - /* Otherwise invalidate caller-saved registers after call */ - for (unsigned i =3D 0; i < ARRAY_SIZE(state->regs); i++) { - if (state->regs[i].caller_saved) - state->regs[i].ok =3D false; - } - - /* Update register with the return type (if any) */ - if (die_find_func_rettype(cu_die, func->name, &type_die)) { - tsr =3D &state->regs[state->ret_reg]; - tsr->type =3D type_die; - tsr->kind =3D TSR_KIND_TYPE; - tsr->ok =3D true; - - pr_debug_dtp("call [%x] return -> reg%d", - insn_offset, state->ret_reg); - pr_debug_type_name(&type_die, tsr->kind); - } - return; - } - - if (!strncmp(dl->ins.name, "add", 3)) { - u64 imm_value =3D -1ULL; - int offset; - const char *var_name =3D NULL; - struct map_symbol *ms =3D dloc->ms; - u64 ip =3D ms->sym->start + dl->al.offset; - - if (!has_reg_type(state, dst->reg1)) - return; - - tsr =3D &state->regs[dst->reg1]; - - 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; - else if (src->reg1 =3D=3D DWARF_REG_PC) { - u64 var_addr =3D annotate_calc_pcrel(dloc->ms, ip, - src->offset, dl); - - if (get_global_var_info(dloc, var_addr, - &var_name, &offset) && - !strcmp(var_name, "this_cpu_off") && - tsr->kind =3D=3D TSR_KIND_CONST) { - tsr->kind =3D TSR_KIND_PERCPU_BASE; - imm_value =3D tsr->imm_value; - } - } - else - return; - - if (tsr->kind !=3D TSR_KIND_PERCPU_BASE) - return; - - if (get_global_var_type(cu_die, dloc, ip, imm_value, &offset, - &type_die) && offset =3D=3D 0) { - /* - * This is not a pointer type, but it should be treated - * as a pointer. - */ - tsr->type =3D type_die; - tsr->kind =3D TSR_KIND_POINTER; - tsr->ok =3D true; - - pr_debug_dtp("add [%x] percpu %#"PRIx64" -> reg%d", - insn_offset, imm_value, dst->reg1); - pr_debug_type_name(&tsr->type, tsr->kind); - } - return; - } - - if (strncmp(dl->ins.name, "mov", 3)) - return; - - if (dloc->fb_cfa) { - u64 ip =3D dloc->ms->sym->start + dl->al.offset; - u64 pc =3D map__rip_2objdump(dloc->ms->map, ip); - - if (die_get_cfa(dloc->di->dbg, pc, &fbreg, &fboff) < 0) - fbreg =3D -1; - } - - /* Case 1. register to register or segment:offset to register transfers */ - if (!src->mem_ref && !dst->mem_ref) { - if (!has_reg_type(state, dst->reg1)) - return; - - tsr =3D &state->regs[dst->reg1]; - if (map__dso(dloc->ms->map)->kernel && - src->segment =3D=3D INSN_SEG_X86_GS && src->imm) { - u64 ip =3D dloc->ms->sym->start + dl->al.offset; - u64 var_addr; - int offset; - - /* - * In kernel, %gs points to a per-cpu region for the - * current CPU. Access with a constant offset should - * be treated as a global variable access. - */ - var_addr =3D src->offset; - - if (var_addr =3D=3D 40) { - tsr->kind =3D TSR_KIND_CANARY; - tsr->ok =3D true; - - pr_debug_dtp("mov [%x] stack canary -> reg%d\n", - insn_offset, dst->reg1); - return; - } - - if (!get_global_var_type(cu_die, dloc, ip, var_addr, - &offset, &type_die) || - !die_get_member_type(&type_die, offset, &type_die)) { - tsr->ok =3D false; - return; - } - - tsr->type =3D type_die; - tsr->kind =3D TSR_KIND_TYPE; - tsr->ok =3D true; - - pr_debug_dtp("mov [%x] this-cpu addr=3D%#"PRIx64" -> reg%d", - insn_offset, var_addr, dst->reg1); - pr_debug_type_name(&tsr->type, tsr->kind); - return; - } - - if (src->imm) { - tsr->kind =3D TSR_KIND_CONST; - tsr->imm_value =3D src->offset; - tsr->ok =3D true; - - pr_debug_dtp("mov [%x] imm=3D%#x -> reg%d\n", - insn_offset, tsr->imm_value, dst->reg1); - return; - } - - if (!has_reg_type(state, src->reg1) || - !state->regs[src->reg1].ok) { - tsr->ok =3D false; - return; - } - - tsr->type =3D state->regs[src->reg1].type; - tsr->kind =3D state->regs[src->reg1].kind; - tsr->ok =3D true; - - pr_debug_dtp("mov [%x] reg%d -> reg%d", - insn_offset, src->reg1, dst->reg1); - pr_debug_type_name(&tsr->type, tsr->kind); - } - /* Case 2. memory to register transers */ - if (src->mem_ref && !dst->mem_ref) { - int sreg =3D src->reg1; - - if (!has_reg_type(state, dst->reg1)) - return; - - tsr =3D &state->regs[dst->reg1]; - -retry: - /* Check stack variables with offset */ - if (sreg =3D=3D fbreg) { - struct type_state_stack *stack; - int offset =3D src->offset - fboff; - - stack =3D find_stack_state(state, offset); - if (stack =3D=3D NULL) { - tsr->ok =3D false; - return; - } else if (!stack->compound) { - tsr->type =3D stack->type; - tsr->kind =3D stack->kind; - 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->ok =3D true; - } else { - tsr->ok =3D false; - return; - } - - pr_debug_dtp("mov [%x] -%#x(stack) -> reg%d", - insn_offset, -offset, dst->reg1); - pr_debug_type_name(&tsr->type, tsr->kind); - } - /* And then dereference the pointer if it has one */ - 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)) { - tsr->type =3D type_die; - tsr->kind =3D TSR_KIND_TYPE; - tsr->ok =3D true; - - pr_debug_dtp("mov [%x] %#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; - u64 ip =3D ms->sym->start + dl->al.offset; - u64 addr; - int offset; - - addr =3D annotate_calc_pcrel(ms, ip, src->offset, dl); - - if (!get_global_var_type(cu_die, dloc, ip, addr, &offset, - &type_die) || - !die_get_member_type(&type_die, offset, &type_die)) { - tsr->ok =3D false; - return; - } - - tsr->type =3D type_die; - tsr->kind =3D TSR_KIND_TYPE; - tsr->ok =3D true; - - pr_debug_dtp("mov [%x] global addr=3D%"PRIx64" -> reg%d", - insn_offset, addr, dst->reg1); - pr_debug_type_name(&type_die, tsr->kind); - } - /* And check percpu access with base register */ - else if (has_reg_type(state, sreg) && - state->regs[sreg].kind =3D=3D TSR_KIND_PERCPU_BASE) { - u64 ip =3D dloc->ms->sym->start + dl->al.offset; - u64 var_addr =3D src->offset; - int offset; - - if (src->multi_regs) { - int reg2 =3D (sreg =3D=3D src->reg1) ? src->reg2 : src->reg1; - - if (has_reg_type(state, reg2) && state->regs[reg2].ok && - state->regs[reg2].kind =3D=3D TSR_KIND_CONST) - var_addr +=3D state->regs[reg2].imm_value; - } - - /* - * In kernel, %gs points to a per-cpu region for the - * current CPU. Access with a constant offset should - * be treated as a global variable access. - */ - if (get_global_var_type(cu_die, dloc, ip, var_addr, - &offset, &type_die) && - die_get_member_type(&type_die, offset, &type_die)) { - tsr->type =3D type_die; - tsr->kind =3D TSR_KIND_TYPE; - tsr->ok =3D true; - - if (src->multi_regs) { - pr_debug_dtp("mov [%x] percpu %#x(reg%d,reg%d) -> reg%d", - insn_offset, src->offset, src->reg1, - src->reg2, dst->reg1); - } else { - pr_debug_dtp("mov [%x] percpu %#x(reg%d) -> reg%d", - insn_offset, src->offset, sreg, dst->reg1); - } - pr_debug_type_name(&tsr->type, tsr->kind); - } else { - tsr->ok =3D false; - } - } - /* And then dereference the calculated pointer if it has one */ - 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 type_die; - tsr->kind =3D TSR_KIND_TYPE; - tsr->ok =3D true; - - pr_debug_dtp("mov [%x] pointer %#x(reg%d) -> reg%d", - insn_offset, src->offset, sreg, dst->reg1); - pr_debug_type_name(&tsr->type, tsr->kind); - } - /* Or try another register if any */ - else if (src->multi_regs && sreg =3D=3D src->reg1 && - src->reg1 !=3D src->reg2) { - sreg =3D src->reg2; - goto retry; - } - else { - int offset; - const char *var_name =3D NULL; - - /* it might be per-cpu variable (in kernel) access */ - if (src->offset < 0) { - if (get_global_var_info(dloc, (s64)src->offset, - &var_name, &offset) && - !strcmp(var_name, "__per_cpu_offset")) { - tsr->kind =3D TSR_KIND_PERCPU_BASE; - - pr_debug_dtp("mov [%x] percpu base reg%d\n", - insn_offset, dst->reg1); - } - } - - tsr->ok =3D false; - } - } - /* Case 3. register to memory transfers */ - if (!src->mem_ref && dst->mem_ref) { - if (!has_reg_type(state, src->reg1) || - !state->regs[src->reg1].ok) - return; - - /* Check stack variables with offset */ - if (dst->reg1 =3D=3D fbreg) { - struct type_state_stack *stack; - int offset =3D dst->offset - fboff; - - tsr =3D &state->regs[src->reg1]; - - stack =3D find_stack_state(state, offset); - if (stack) { - /* - * The source register is likely to hold a type - * of member if it's a compound type. Do not - * update the stack variable type since we can - * get the member type later by using the - * die_get_member_type(). - */ - if (!stack->compound) - set_stack_state(stack, offset, tsr->kind, - &tsr->type); - } else { - findnew_stack_state(state, offset, tsr->kind, - &tsr->type); - } - - pr_debug_dtp("mov [%x] reg%d -> -%#x(stack)", - insn_offset, src->reg1, -offset); - pr_debug_type_name(&tsr->type, tsr->kind); - } - /* - * Ignore other transfers since it'd set a value in a struct - * and won't change the type. - */ - } - /* Case 4. memory to memory transfers (not handled for now) */ -} - /** * update_insn_state - Update type state for an instruction * @state: type state table @@ -1114,8 +739,8 @@ static void update_insn_state_x86(struct type_state *s= tate, static void update_insn_state(struct type_state *state, struct data_loc_in= fo *dloc, Dwarf_Die *cu_die, struct disasm_line *dl) { - if (arch__is(dloc->arch, "x86")) - update_insn_state_x86(state, dloc, cu_die, dl); + if (dloc->arch->update_insn_state) + dloc->arch->update_insn_state(state, dloc, cu_die, dl); } =20 /* diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-dat= a.h index ef235b1b15e1..2bc870e61c74 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -7,6 +7,7 @@ #include #include #include "dwarf-aux.h" +#include "dwarf-regs.h" #include "annotate.h" #include "debuginfo.h" =20 @@ -18,6 +19,14 @@ struct hist_entry; struct map_symbol; struct thread; =20 +#define pr_debug_dtp(fmt, ...) \ +do { \ + if (debug_type_profile) \ + pr_info(fmt, ##__VA_ARGS__); \ + else \ + pr_debug3(fmt, ##__VA_ARGS__); \ +} while (0) + enum type_state_kind { TSR_KIND_INVALID =3D 0, TSR_KIND_TYPE, @@ -215,6 +224,20 @@ void global_var_type__tree_delete(struct rb_root *root= ); int hist_entry__annotate_data_tty(struct hist_entry *he, struct evsel *evs= el); =20 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); +void set_stack_state(struct type_state_stack *stack, int offset, u8 kind, + Dwarf_Die *type_die); +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, + u64 ip, u64 var_addr, int *var_offset, + Dwarf_Die *type_die); +bool get_global_var_info(struct data_loc_info *dloc, u64 addr, + const char **var_name, int *var_offset); +void pr_debug_type_name(Dwarf_Die *die, enum type_state_kind kind); + #else /* HAVE_DWARF_SUPPORT */ =20 static inline struct annotated_data_type * diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index 6d1125e687b7..2de66a092cab 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -12,6 +12,7 @@ #include =20 #include "annotate.h" +#include "annotate-data.h" #include "build-id.h" #include "debug.h" #include "disasm.h" @@ -145,6 +146,7 @@ static struct arch architectures[] =3D { .memory_ref_char =3D '(', .imm_char =3D '$', }, + .update_insn_state =3D update_insn_state_x86, }, { .name =3D "powerpc", diff --git a/tools/perf/util/disasm.h b/tools/perf/util/disasm.h index 3d381a043520..718177fa4775 100644 --- a/tools/perf/util/disasm.h +++ b/tools/perf/util/disasm.h @@ -3,12 +3,16 @@ #define __PERF_UTIL_DISASM_H =20 #include "map_symbol.h" +#include "dwarf-aux.h" =20 struct annotation_options; struct disasm_line; struct ins; struct evsel; struct symbol; +struct data_loc_info; +struct type_state; +struct disasm_line; =20 struct arch { const char *name; @@ -32,6 +36,9 @@ struct arch { char memory_ref_char; char imm_char; } objdump; + void (*update_insn_state)(struct type_state *state, + struct data_loc_info *dloc, Dwarf_Die *cu_die, + struct disasm_line *dl); }; =20 struct ins { --=20 2.43.0 From nobody Wed Dec 17 17:23:50 2025 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 22571143C5D; Mon, 6 May 2024 12:19:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714997986; cv=none; b=OW9JeOj9TlwaY7y+ClXNR8AfaLjuT0dk2CK2me/xaaiEyAcYj/Fh9S2ev7t59cNEOGVoZuybN/kP88LIJ5RMD43phhLsRs5RLdZ8PFZazziUcGHDSCFkQMuMHprpCGZVbk1ynTFt7JqCbQV1RxLocaotSMns2Oe88hBjRiJQOsI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714997986; c=relaxed/simple; bh=slI7+hMHmf5MK81bviY1FkUShDHJeeBOoht9m5x6mnk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=UBLqLnSE3yyGc7M1anb2mPiNLhsMGEMI74TpY0vaQJ9zU6av9uVenq6MkRiucP5zjHfcSZtSq8NCsR0v/Up6ctXyA4sAWx1Hnc4nFS1WdjYQxSav+4G+d4C9xeFkdSo+LB99JiY7DF41qSIlcWAdOZ05ULxZMqk3ueCCNq/U2a8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com; spf=none smtp.mailfrom=linux.vnet.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=BeW44xRG; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="BeW44xRG" Received: from pps.filterd (m0353724.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 446CFCu4002631; Mon, 6 May 2024 12:19:34 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=wLkTMnfbJqr5IAUHKH+kVU3WzXA6M6RgRrTO4HDUZsE=; b=BeW44xRG9mJWVSGfw4bOiumaMVTAuB+6QZ8vFweAXHaJzvZG6zKOslXVQg4gWzFevfE9 copRnLvCEPonEK3JpKsZsRgOZh0U4onUd68m9HY6thvfZeYAxdM7T18EW2aR1Mgb16Ma uSKVrcG1V5y0UmGL8ikYD1DAJGHgzie4cP3tTMRxTega+DyqAJgImXzAEaCEzES8GC/G 4Zh8VVPhmbqBOVarahj2OPfHfCQpKsDbxlFV2xhLJhatd8OoLyTR9tWNe+uPEUykNdGW YOgVoJvVMulRJlP4rkBBWTFhC4TvphTPaQVKiwi10ofhTQPc7MzzbK419xXVDNo0zYd5 /Q== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxy1ug0ah-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:34 +0000 Received: from m0353724.ppops.net (m0353724.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 446CJXPf010045; Mon, 6 May 2024 12:19:33 GMT Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxy1ug0ac-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:33 +0000 Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 446C55o5028582; Mon, 6 May 2024 12:19:32 GMT Received: from smtprelay06.fra02v.mail.ibm.com ([9.218.2.230]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 3xwyqyyy5n-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:32 +0000 Received: from smtpav06.fra02v.mail.ibm.com (smtpav06.fra02v.mail.ibm.com [10.20.54.105]) by smtprelay06.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 446CJRTF22806958 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 May 2024 12:19:29 GMT Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 17F0520049; Mon, 6 May 2024 12:19:27 +0000 (GMT) Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 57AC820063; Mon, 6 May 2024 12:19:24 +0000 (GMT) Received: from localhost.localdomain (unknown [9.43.103.211]) by smtpav06.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 6 May 2024 12:19:24 +0000 (GMT) From: Athira Rajeev To: acme@kernel.org, jolsa@kernel.org, adrian.hunter@intel.com, irogers@google.com, namhyung@kernel.org, segher@kernel.crashing.org, christophe.leroy@csgroup.eu Cc: linux-perf-users@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, maddy@linux.ibm.com, atrajeev@linux.vnet.ibm.com, kjain@linux.ibm.com, disgoel@linux.vnet.ibm.com, linux-kernel@vger.kernel.org, akanksha@linux.ibm.com Subject: [PATCH V2 3/9] tools/perf: Fix a comment about multi_regs in extract_reg_offset function Date: Mon, 6 May 2024 17:49:00 +0530 Message-Id: <20240506121906.76639-4-atrajeev@linux.vnet.ibm.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> References: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: na_SX7JEzg2wGQrFuvtCeGq-7ivyExN1 X-Proofpoint-GUID: sWefmXAxa8eIKz0TqP702VLL31CgKUx4 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1011,Hydra:6.0.650,FMLib:17.11.176.26 definitions=2024-05-06_07,2024-05-06_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 lowpriorityscore=0 phishscore=0 mlxlogscore=999 malwarescore=0 suspectscore=0 impostorscore=0 clxscore=1015 adultscore=0 mlxscore=0 spamscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2404010000 definitions=main-2405060085 Content-Type: text/plain; charset="utf-8" Fix a comment in function which explains how multi_regs field gets set for an instruction. In the example, "mov %rsi, 8(%rbx,%rcx,4)", the comment mistakenly referred to "dst_multi_regs =3D 0". Correct it to use "src_multi_regs =3D 0" Signed-off-by: Athira Rajeev Acked-by: Namhyung Kim --- tools/perf/util/annotate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index f5b6b5e5e757..0f5e10654d09 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -2093,7 +2093,7 @@ static int extract_reg_offset(struct arch *arch, cons= t char *str, * mov 0x18, %r8 # src_reg1 =3D -1, src_mem =3D 0 * # dst_reg1 =3D r8, dst_mem =3D 0 * - * mov %rsi, 8(%rbx,%rcx,4) # src_reg1 =3D rsi, src_mem =3D 0, dst_mul= ti_regs =3D 0 + * mov %rsi, 8(%rbx,%rcx,4) # src_reg1 =3D rsi, src_mem =3D 0, src_mul= ti_regs =3D 0 * # dst_reg1 =3D rbx, dst_reg2 =3D rcx, dst_= mem =3D 1 * # dst_multi_regs =3D 1, dst_offset =3D 8 */ --=20 2.43.0 From nobody Wed Dec 17 17:23:50 2025 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 57CE314389D; Mon, 6 May 2024 12:21:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714998095; cv=none; b=ZcCAzXOxmr//7JmTGs9O6Kn+MIcIau5uZDUrbzeHecAK5v1M7LgeJRetzEqh81AOsd0ehyRcqlxg/DWN7lQ5DH7NxKYZgMtIIs3szS/ucEZ2g/8Lafrr6/nQ0K8lVls1aajbpyEInitFxHqHVTUlNPcxRNJhavZEGq92gj4mWHI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714998095; c=relaxed/simple; bh=ChqIk8gWP941vOkCqIyQXW1Z7QPOFEbtVveIm7aYWg0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=O2LYBjaVGCCci+mTyKoSSrAdZBPyLbKA4ycbvzPp+OfItGwS/gRU8TR/2/Iq9woJxI0WCgMrDmBUT+o48/FXh1jM744yzdc3cs4ofO/rwSZ9lQQFLRlwkPMow8/38/YxFp9f/eMLNrxyJoEeZtI1UV7wFKnwDUfrmTEjALDn1YQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com; spf=none smtp.mailfrom=linux.vnet.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=R3LdgPiA; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="R3LdgPiA" Received: from pps.filterd (m0353725.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 446B4FnX014509; Mon, 6 May 2024 12:21:23 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=0Nn3bWvynJWro2iLFEALu91KWiH53m7FTZBeOTU5hAM=; b=R3LdgPiANP3nHi4kD2F0Jn5rKghRFRTTAjOkZsIrQgDe1mpTC2mzLH15l8j5T5v1+8AO vcMGP/ncApIIsrEEVeEQxxVFnkY9K3mes5+wAW0k49lM1UaGDohXr2LRsgixpc8ffPIl nSmHU7cXmwl1lupPABtrgRWL7r5nvj+bmH7RO2g06FujAk3CuJWhOiR6yUn8mAj0aAvf JNgGhidUX5dsf+ttqRopa/vxVON087I9r9R/17aFYB3l263b2+hsqlkNzntAnEKqJR/J X08qD4UyF413SCtB6y1f3TLlXT3Qo5eCGLNCf4C5xe6Z3/s3Dc8Gi+nppZzW3frpBEOd sw== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxx0eg68p-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:21:23 +0000 Received: from m0353725.ppops.net (m0353725.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 446CLMcF004451; Mon, 6 May 2024 12:21:22 GMT Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxx0eg678-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:21:22 +0000 Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 4468tY1F010624; Mon, 6 May 2024 12:19:36 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 3xx0bnyts6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:36 +0000 Received: from smtpav06.fra02v.mail.ibm.com (smtpav06.fra02v.mail.ibm.com [10.20.54.105]) by smtprelay01.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 446CJUhL50070004 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 May 2024 12:19:32 GMT Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7E7832004D; Mon, 6 May 2024 12:19:30 +0000 (GMT) Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 669842004B; Mon, 6 May 2024 12:19:27 +0000 (GMT) Received: from localhost.localdomain (unknown [9.43.103.211]) by smtpav06.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 6 May 2024 12:19:27 +0000 (GMT) From: Athira Rajeev To: acme@kernel.org, jolsa@kernel.org, adrian.hunter@intel.com, irogers@google.com, namhyung@kernel.org, segher@kernel.crashing.org, christophe.leroy@csgroup.eu Cc: linux-perf-users@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, maddy@linux.ibm.com, atrajeev@linux.vnet.ibm.com, kjain@linux.ibm.com, disgoel@linux.vnet.ibm.com, linux-kernel@vger.kernel.org, akanksha@linux.ibm.com Subject: [PATCH V2 4/9] tools/perf: Add support to capture and parse raw instruction in objdump Date: Mon, 6 May 2024 17:49:01 +0530 Message-Id: <20240506121906.76639-5-atrajeev@linux.vnet.ibm.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> References: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: 9kBmwt75xGKLrLEfGYpgi1JzI1MQhIV7 X-Proofpoint-GUID: G0wHARXoC0jYWNJuIqZ-YWXW1Bg9e9u7 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1011,Hydra:6.0.650,FMLib:17.11.176.26 definitions=2024-05-06_07,2024-05-06_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 clxscore=1015 mlxscore=0 malwarescore=0 adultscore=0 phishscore=0 mlxlogscore=999 spamscore=0 lowpriorityscore=0 priorityscore=1501 impostorscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2404010000 definitions=main-2405060085 Content-Type: text/plain; charset="utf-8" Add support to capture and parse raw instruction in objdump. Currently, the perf tool infrastructure uses "--no-show-raw-insn" option with "objdump" while disassemble. Example from powerpc with this option for an instruction address is: Snippet from: objdump --start-address=3D
--stop-address=3D
-d --no-sh= ow-raw-insn -C c0000000010224b4: lwz r10,0(r9) This line "lwz r10,0(r9)" is parsed to extract instruction name, registers names and offset. Also to find whether there is a memory reference in the operands, "memory_ref_char" field of objdump is used. For x86, "(" is used as memory_ref_char to tackle instructions of the form "mov (%rax), %rcx". In case of powerpc, not all instructions using "(" are the only memory instructions. Example, above instruction can also be of extended form (X form) "lwzx r10,0,r19". Inorder to easy identify the instruction category and extract the source/target registers, patch adds support to use raw instruction. With raw instruction, macros are added to extract opcode and register fields. "struct ins_operands" and "struct ins" is updated to carry opcode and raw instruction binary code (raw_insn). Function "disasm_line__parse" is updated to fill the raw instruction hex value and opcode in newly added fields. There is no changes in existing code paths, which parses the disassembled code. The architecture using the instruction name and present approach is not altered. Since this approach targets powerpc, the macro implementation is added for powerpc as of now. Example: representation using --show-raw-insn in objdump gives result: 38 01 81 e8 ld r4,312(r1) Here "38 01 81 e8" is the raw instruction representation. In powerpc, this translates to instruction form: "ld RT,DS(RA)" and binary code as: _____________________________________ | 58 | RT | RA | DS | | ------------------------------------- 0 6 11 16 30 31 Function "disasm_line__parse" is updated to capture: line: 38 01 81 e8 ld r4,312(r1) opcode and raw instruction "38 01 81 e8" Raw instruction is used later to extract the reg/offset fields. Signed-off-by: Athira Rajeev --- tools/include/linux/string.h | 2 + tools/lib/string.c | 13 +++++++ tools/perf/arch/powerpc/util/dwarf-regs.c | 19 ++++++++++ tools/perf/util/disasm.c | 46 +++++++++++++++++++---- tools/perf/util/disasm.h | 6 +++ tools/perf/util/include/dwarf-regs.h | 9 +++++ 6 files changed, 88 insertions(+), 7 deletions(-) diff --git a/tools/include/linux/string.h b/tools/include/linux/string.h index db5c99318c79..0acb1fc14e19 100644 --- a/tools/include/linux/string.h +++ b/tools/include/linux/string.h @@ -46,5 +46,7 @@ extern char * __must_check skip_spaces(const char *); =20 extern char *strim(char *); =20 +extern void remove_spaces(char *s); + extern void *memchr_inv(const void *start, int c, size_t bytes); #endif /* _TOOLS_LINUX_STRING_H_ */ diff --git a/tools/lib/string.c b/tools/lib/string.c index 8b6892f959ab..21d273e69951 100644 --- a/tools/lib/string.c +++ b/tools/lib/string.c @@ -153,6 +153,19 @@ char *strim(char *s) return skip_spaces(s); } =20 +/* + * remove_spaces - Removes whitespaces from @s + */ +void remove_spaces(char *s) +{ + char *d =3D s; + do { + while (*d =3D=3D ' ') { + ++d; + } + } while ((*s++ =3D *d++)); +} + /** * strreplace - Replace all occurrences of character in string. * @s: The string to operate on. diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c b/tools/perf/arch/po= werpc/util/dwarf-regs.c index 0c4f4caf53ac..e60a71fd846e 100644 --- a/tools/perf/arch/powerpc/util/dwarf-regs.c +++ b/tools/perf/arch/powerpc/util/dwarf-regs.c @@ -98,3 +98,22 @@ int regs_query_register_offset(const char *name) return roff->ptregs_offset; return -EINVAL; } + +#define PPC_OP(op) (((op) >> 26) & 0x3F) +#define PPC_RA(a) (((a) >> 16) & 0x1f) +#define PPC_RT(t) (((t) >> 21) & 0x1f) + +int get_opcode_insn(unsigned int raw_insn) +{ + return PPC_OP(raw_insn); +} + +int get_source_reg(unsigned int raw_insn) +{ + return PPC_RA(raw_insn); +} + +int get_target_reg(unsigned int raw_insn) +{ + return PPC_RT(raw_insn); +} diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index 2de66a092cab..85692f73e78f 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -43,7 +43,7 @@ static int call__scnprintf(struct ins *ins, char *bf, siz= e_t size, struct ins_operands *ops, int max_ins_name); =20 static void ins__sort(struct arch *arch); -static int disasm_line__parse(char *line, const char **namep, char **rawp); +static int disasm_line__parse(char *line, const char **namep, char **rawp,= int *opcode, int *rawp_insn); =20 static __attribute__((constructor)) void symbol__init_regexpr(void) { @@ -512,7 +512,7 @@ static int lock__parse(struct arch *arch, struct ins_op= erands *ops, struct map_s if (ops->locked.ops =3D=3D NULL) return 0; =20 - if (disasm_line__parse(ops->raw, &ops->locked.ins.name, &ops->locked.ops-= >raw) < 0) + if (disasm_line__parse(ops->raw, &ops->locked.ins.name, &ops->locked.ops-= >raw, &ops->locked.ins.opcode, &ops->locked.ops->raw_insn) < 0) goto out_free_ops; =20 ops->locked.ins.ops =3D ins__find(arch, ops->locked.ins.name); @@ -815,11 +815,38 @@ static void disasm_line__init_ins(struct disasm_line = *dl, struct arch *arch, str dl->ins.ops =3D NULL; } =20 -static int disasm_line__parse(char *line, const char **namep, char **rawp) +int __weak get_opcode_insn(unsigned int raw_insn __maybe_unused) { - char tmp, *name =3D skip_spaces(line); + return -1; +} + +int __weak get_source_reg(unsigned int raw_insn __maybe_unused) +{ + return -1; +} + +int __weak get_target_reg(unsigned int raw_insn __maybe_unused) +{ + return -1; +} + +/* + * Parses the objdump result captured with --show-raw-insn. + * Example, objdump line from powerpc: + * line: 38 01 81 e8 ld r4,312(r1) + * namep : ld + * rawp : "ld r4,312(r1)" + * opcode: fetched from arch specific get_opcode_insn + * rawp_insn: e8810138 + * + * rawp_insn is used later to extract the reg/offset fields + */ +static int disasm_line__parse(char *line, const char **namep, char **rawp,= int *opcode, int *rawp_insn) +{ + char tmp, *tmp_opcode, *name_opcode =3D skip_spaces(line); + char *name =3D skip_spaces(name_opcode + 11); =20 - if (name[0] =3D=3D '\0') + if (name_opcode[0] =3D=3D '\0') return -1; =20 *rawp =3D name + 1; @@ -829,13 +856,18 @@ static int disasm_line__parse(char *line, const char = **namep, char **rawp) =20 tmp =3D (*rawp)[0]; (*rawp)[0] =3D '\0'; + tmp_opcode =3D strdup(name_opcode); + tmp_opcode[11] =3D '\0'; + remove_spaces(tmp_opcode); *namep =3D strdup(name); + *opcode =3D get_opcode_insn(be32_to_cpu(strtol(tmp_opcode, NULL, 16))); =20 if (*namep =3D=3D NULL) goto out; =20 (*rawp)[0] =3D tmp; *rawp =3D strim(*rawp); + *rawp_insn =3D be32_to_cpu(strtol(tmp_opcode, NULL, 16)); =20 return 0; =20 @@ -896,7 +928,7 @@ struct disasm_line *disasm_line__new(struct annotate_ar= gs *args) goto out_delete; =20 if (args->offset !=3D -1) { - if (disasm_line__parse(dl->al.line, &dl->ins.name, &dl->ops.raw) < 0) + if (disasm_line__parse(dl->al.line, &dl->ins.name, &dl->ops.raw, &dl->in= s.opcode, &dl->ops.raw_insn) < 0) goto out_free_line; =20 disasm_line__init_ins(dl, args->arch, &args->ms); @@ -1726,7 +1758,7 @@ int symbol__disassemble(struct symbol *sym, struct an= notate_args *args) map__rip_2objdump(map, sym->start), map__rip_2objdump(map, sym->end), opts->show_linenr ? "-l" : "", - opts->show_asm_raw ? "" : "--no-show-raw-insn", + opts->show_asm_raw ? "" : "--show-raw-insn", opts->annotate_src ? "-S" : "", opts->prefix ? "--prefix " : "", opts->prefix ? '"' : ' ', diff --git a/tools/perf/util/disasm.h b/tools/perf/util/disasm.h index 718177fa4775..5c1520010ca7 100644 --- a/tools/perf/util/disasm.h +++ b/tools/perf/util/disasm.h @@ -43,14 +43,18 @@ struct arch { =20 struct ins { const char *name; + int opcode; struct ins_ops *ops; }; =20 struct ins_operands { char *raw; + int raw_insn; struct { char *raw; char *name; + int opcode; + int raw_insn; struct symbol *sym; u64 addr; s64 offset; @@ -62,6 +66,8 @@ struct ins_operands { struct { char *raw; char *name; + int opcode; + int raw_insn; u64 addr; bool multi_regs; } source; diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include= /dwarf-regs.h index 01fb25a1150a..2a4e1e16e52c 100644 --- a/tools/perf/util/include/dwarf-regs.h +++ b/tools/perf/util/include/dwarf-regs.h @@ -31,6 +31,15 @@ static inline int get_dwarf_regnum(const char *name __ma= ybe_unused, } #endif =20 +/* + * get_opcode_insn - Return opcode from raw instruction + * get_source_reg - Return source reg from raw instruction + * get_target_reg - Return target reg from raw instruction + */ +int get_opcode_insn(unsigned int raw_insn); +int get_source_reg(unsigned int raw_insn); +int get_target_reg(unsigned int raw_insn); + #ifdef HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET /* * Arch should support fetching the offset of a register in pt_regs --=20 2.43.0 From nobody Wed Dec 17 17:23:50 2025 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 837191448D3; Mon, 6 May 2024 12:19:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714997991; cv=none; b=iW48vOkbWle+yrwl0t8v3Sznimn5xGVRzi81PWF2TwY6+BaaZeS+PszknZ/B186Ael+hfJfoTXekjMH2QVuY5ysY10rRLA0flod6QmTryjl1osOOxSnVt9PWcs5lcErWkjoka0oZfoSEnMAGioLGUrQmzPTod+2jz7MDz8osu/Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714997991; c=relaxed/simple; bh=T7+NJh+d+hef/6vA4ZLswN/q3/VYQ3gghMmi3gO54XA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tTt9ANWuEiU4zXoJL/Ip56aFvNUiPy+4agQrq/8waISzkxteA6PGk4woWGBXvWisvKZG5t7XjMPeIBhCS74QRJi1txsYzzXnc/jn20AB+a9fYEWnPi96HByIPRcWguoztyHJQuq/gdDGEblgPBvymCfXUjA7cV1SsAA1swnAEV4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com; spf=none smtp.mailfrom=linux.vnet.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=LzuSjMJk; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="LzuSjMJk" Received: from pps.filterd (m0353729.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 446Arb4r020821; Mon, 6 May 2024 12:19:41 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=wDpktLVm5+ku46M9E50BOWbv1+PB4Wh7qCErtPDV/RQ=; b=LzuSjMJkKl9r4IgFLliTiaZQWPaBr+4M1F27htEdLs5zNDtW4NxoeUk/jO5ciW2Yt1tg eEq5vkZNJVdXEafvIovBoV4zksRIbQxf/nUIviJl7ROdYFTsXhL49KSW/IWV5uajZcdB l7JNgYxXOIOZLOOXER1E06+5cGz698eVljyqhGoTEw5IuhnP4rO0qBudVqNiU/pi6ski IjuZduk/Gqdj8GpD/6/UvOQ4N8sJq42DodJA0AgendO2NXudIcBdAbWC0wXG88F/4LBh Mow2wtmrzrNEhqM+Quz4jjq7J1Wghv4HtFNy3Z+pFVb3zL/Jq11nGCj9XBJeA7N5VKQC HA== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxwu5r68e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:41 +0000 Received: from m0353729.ppops.net (m0353729.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 446CJeRI022518; Mon, 6 May 2024 12:19:40 GMT Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxwu5r689-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:40 +0000 Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 44696kFx010581; Mon, 6 May 2024 12:19:39 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 3xx0bnytsc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:39 +0000 Received: from smtpav06.fra02v.mail.ibm.com (smtpav06.fra02v.mail.ibm.com [10.20.54.105]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 446CJXf350856266 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 May 2024 12:19:35 GMT Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 8D5202004E; Mon, 6 May 2024 12:19:33 +0000 (GMT) Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id CC6DA2004B; Mon, 6 May 2024 12:19:30 +0000 (GMT) Received: from localhost.localdomain (unknown [9.43.103.211]) by smtpav06.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 6 May 2024 12:19:30 +0000 (GMT) From: Athira Rajeev To: acme@kernel.org, jolsa@kernel.org, adrian.hunter@intel.com, irogers@google.com, namhyung@kernel.org, segher@kernel.crashing.org, christophe.leroy@csgroup.eu Cc: linux-perf-users@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, maddy@linux.ibm.com, atrajeev@linux.vnet.ibm.com, kjain@linux.ibm.com, disgoel@linux.vnet.ibm.com, linux-kernel@vger.kernel.org, akanksha@linux.ibm.com Subject: [PATCH V2 5/9] tools/perf: Update parameters for reg extract functions to use raw instruction on powerpc Date: Mon, 6 May 2024 17:49:02 +0530 Message-Id: <20240506121906.76639-6-atrajeev@linux.vnet.ibm.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> References: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: 9rrM4wwGdWiNNomvsN4LeBRlWqsHd3ts X-Proofpoint-ORIG-GUID: laSiEzdi6pM48hzDLlmc54HOt8WzG1xQ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1011,Hydra:6.0.650,FMLib:17.11.176.26 definitions=2024-05-06_07,2024-05-06_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 spamscore=0 bulkscore=0 impostorscore=0 suspectscore=0 phishscore=0 mlxlogscore=999 mlxscore=0 adultscore=0 clxscore=1015 malwarescore=0 lowpriorityscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2404010000 definitions=main-2405060085 Content-Type: text/plain; charset="utf-8" Use the raw instruction code and macros to identify memory instructions, extract register fields and also offset. The implementation addresses the D-form, X-form, DS-form instructions. Two main functions are added. New parse function "load_store__parse" as instruction ops parser for memory instructions. Unlink other parser (like mov__parse), this parser fills in only the "raw" field for source/target and new added "mem_ref" field. This is because, here there is no need to parse the disassembled code and arch specific macros will take care of extracting offset and regs which is easier and will be precise. In powerpc, all instructions with a primary opcode from 32 to 63 are memory instructions. Update "ins__find" function to have "opcode" also as a parameter. Don't use the "extract_reg_offset", instead use newly added function "get_arch_regs" which will set these fields: reg1, reg2, offset depending of where it is source or target ops. Signed-off-by: Athira Rajeev --- tools/perf/arch/powerpc/util/dwarf-regs.c | 33 +++++++++++++ tools/perf/util/annotate.c | 22 ++++++++- tools/perf/util/disasm.c | 59 +++++++++++++++++++++-- tools/perf/util/disasm.h | 4 +- tools/perf/util/include/dwarf-regs.h | 4 +- 5 files changed, 114 insertions(+), 8 deletions(-) diff --git a/tools/perf/arch/powerpc/util/dwarf-regs.c b/tools/perf/arch/po= werpc/util/dwarf-regs.c index e60a71fd846e..3121c70dc0d3 100644 --- a/tools/perf/arch/powerpc/util/dwarf-regs.c +++ b/tools/perf/arch/powerpc/util/dwarf-regs.c @@ -102,6 +102,9 @@ int regs_query_register_offset(const char *name) #define PPC_OP(op) (((op) >> 26) & 0x3F) #define PPC_RA(a) (((a) >> 16) & 0x1f) #define PPC_RT(t) (((t) >> 21) & 0x1f) +#define PPC_RB(b) (((b) >> 11) & 0x1f) +#define PPC_D(D) ((D) & 0xfffe) +#define PPC_DS(DS) ((DS) & 0xfffc) =20 int get_opcode_insn(unsigned int raw_insn) { @@ -117,3 +120,33 @@ int get_target_reg(unsigned int raw_insn) { return PPC_RT(raw_insn); } + +int get_offset_opcode(int raw_insn __maybe_unused) +{ + int opcode =3D PPC_OP(raw_insn); + + /* DS- form */ + if ((opcode =3D=3D 58) || (opcode =3D=3D 62)) + return PPC_DS(raw_insn); + else + return PPC_D(raw_insn); +} + +/* + * Fills the required fields for op_loc depending on if it + * is a source of target. + * D form: ins RT,D(RA) -> src_reg1 =3D RA, offset =3D D, dst_reg1 =3D RT + * DS form: ins RT,DS(RA) -> src_reg1 =3D RA, offset =3D DS, dst_reg1 =3D = RT + * X form: ins RT,RA,RB -> src_reg1 =3D RA, src_reg2 =3D RB, dst_reg1 =3D = RT + */ +void get_arch_regs(int raw_insn __maybe_unused, int is_source __maybe_unus= ed, struct annotated_op_loc *op_loc __maybe_unused) +{ + if (is_source) + op_loc->reg1 =3D get_source_reg(raw_insn); + else + op_loc->reg1 =3D get_target_reg(raw_insn); + if (op_loc->multi_regs) + op_loc->reg2 =3D PPC_RB(raw_insn); + if (op_loc->mem_ref) + op_loc->offset =3D get_offset_opcode(raw_insn); +} diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 0f5e10654d09..48739c7ffdc7 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -2073,6 +2073,12 @@ static int extract_reg_offset(struct arch *arch, con= st char *str, return 0; } =20 +__weak void get_arch_regs(int raw_insn __maybe_unused, int is_source __may= be_unused, + struct annotated_op_loc *op_loc __maybe_unused) +{ + return; +} + /** * annotate_get_insn_location - Get location of instruction * @arch: the architecture info @@ -2117,10 +2123,12 @@ int annotate_get_insn_location(struct arch *arch, s= truct disasm_line *dl, for_each_insn_op_loc(loc, i, op_loc) { const char *insn_str =3D ops->source.raw; bool multi_regs =3D ops->source.multi_regs; + bool mem_ref =3D ops->source.mem_ref; =20 if (i =3D=3D INSN_OP_TARGET) { insn_str =3D ops->target.raw; multi_regs =3D ops->target.multi_regs; + mem_ref =3D ops->target.mem_ref; } =20 /* Invalidate the register by default */ @@ -2130,7 +2138,19 @@ int annotate_get_insn_location(struct arch *arch, st= ruct disasm_line *dl, if (insn_str =3D=3D NULL) continue; =20 - if (strchr(insn_str, arch->objdump.memory_ref_char)) { + /* + * For powerpc, call get_arch_regs function which extracts the + * required fields for op_loc, ie reg1, reg2, offset from the + * raw instruction. + */ + if (arch__is(arch, "powerpc")) { + op_loc->mem_ref =3D mem_ref; + if ((!strchr(insn_str, '(')) && (i =3D=3D INSN_OP_SOURCE)) + op_loc->multi_regs =3D true; + get_arch_regs(ops->raw_insn, !i, op_loc); + if (op_loc->multi_regs) + op_loc->offset =3D 0; + } else if (strchr(insn_str, arch->objdump.memory_ref_char)) { op_loc->mem_ref =3D true; op_loc->multi_regs =3D multi_regs; extract_reg_offset(arch, insn_str, op_loc); diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index 85692f73e78f..f41a0fadeab4 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -515,7 +515,7 @@ static int lock__parse(struct arch *arch, struct ins_op= erands *ops, struct map_s if (disasm_line__parse(ops->raw, &ops->locked.ins.name, &ops->locked.ops-= >raw, &ops->locked.ins.opcode, &ops->locked.ops->raw_insn) < 0) goto out_free_ops; =20 - ops->locked.ins.ops =3D ins__find(arch, ops->locked.ins.name); + ops->locked.ins.ops =3D ins__find(arch, ops->locked.ins.name, 0); =20 if (ops->locked.ins.ops =3D=3D NULL) goto out_free_ops; @@ -670,6 +670,46 @@ static struct ins_ops mov_ops =3D { .scnprintf =3D mov__scnprintf, }; =20 +static int load_store__scnprintf(struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name) +{ + return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, + ops->raw); +} + +/* + * Sets only two fields "raw" and "mem_ref". + * "mem_ref" is set for ops->source which is later used to + * fill the objdump->memory_ref-char field. This ops is currently + * used by powerpc and since binary instruction code is used to + * extract opcode, regs and offset, no other parsing is needed here + */ +static int load_store__parse(struct arch *arch __maybe_unused, struct ins_= operands *ops, struct map_symbol *ms __maybe_unused) +{ + ops->source.raw =3D strdup(ops->raw); + ops->source.mem_ref =3D true; + + if (ops->source.raw =3D=3D NULL) + return -1; + + ops->target.raw =3D strdup(ops->raw); + ops->target.mem_ref =3D false; + + if (ops->target.raw =3D=3D NULL) + goto out_free_source; + + return 0; + +out_free_source: + zfree(&ops->source.raw); + return -1; +} + +static struct ins_ops load_store_ops =3D { + .parse =3D load_store__parse, + .scnprintf =3D load_store__scnprintf, +}; + static int dec__parse(struct arch *arch __maybe_unused, struct ins_operand= s *ops, struct map_symbol *ms __maybe_unused) { char *target, *comment, *s, prev; @@ -760,11 +800,20 @@ static void ins__sort(struct arch *arch) qsort(arch->instructions, nmemb, sizeof(struct ins), ins__cmp); } =20 -static struct ins_ops *__ins__find(struct arch *arch, const char *name) +static struct ins_ops *__ins__find(struct arch *arch, const char *name, in= t opcode) { struct ins *ins; const int nmemb =3D arch->nr_instructions; =20 + if (arch__is(arch, "powerpc")) { + /* + * Instructions with a primary opcode from 32 to 63 + * are memory instructions in powerpc. + */ + if ((opcode >=3D 31) && (opcode <=3D 63)) + return &load_store_ops; + } + if (!arch->sorted_instructions) { ins__sort(arch); arch->sorted_instructions =3D true; @@ -794,9 +843,9 @@ static struct ins_ops *__ins__find(struct arch *arch, c= onst char *name) return ins ? ins->ops : NULL; } =20 -struct ins_ops *ins__find(struct arch *arch, const char *name) +struct ins_ops *ins__find(struct arch *arch, const char *name, int opcode) { - struct ins_ops *ops =3D __ins__find(arch, name); + struct ins_ops *ops =3D __ins__find(arch, name, opcode); =20 if (!ops && arch->associate_instruction_ops) ops =3D arch->associate_instruction_ops(arch, name); @@ -806,7 +855,7 @@ struct ins_ops *ins__find(struct arch *arch, const char= *name) =20 static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arc= h, struct map_symbol *ms) { - dl->ins.ops =3D ins__find(arch, dl->ins.name); + dl->ins.ops =3D ins__find(arch, dl->ins.name, dl->ins.opcode); =20 if (!dl->ins.ops) return; diff --git a/tools/perf/util/disasm.h b/tools/perf/util/disasm.h index 5c1520010ca7..ed8875b35bfe 100644 --- a/tools/perf/util/disasm.h +++ b/tools/perf/util/disasm.h @@ -61,6 +61,7 @@ struct ins_operands { bool offset_avail; bool outside; bool multi_regs; + bool mem_ref; } target; union { struct { @@ -70,6 +71,7 @@ struct ins_operands { int raw_insn; u64 addr; bool multi_regs; + bool mem_ref; } source; struct { struct ins ins; @@ -103,7 +105,7 @@ struct annotate_args { struct arch *arch__find(const char *name); bool arch__is(struct arch *arch, const char *name); =20 -struct ins_ops *ins__find(struct arch *arch, const char *name); +struct ins_ops *ins__find(struct arch *arch, const char *name, int opcode); int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops, int max_ins_name); =20 diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include= /dwarf-regs.h index 2a4e1e16e52c..d691245dd703 100644 --- a/tools/perf/util/include/dwarf-regs.h +++ b/tools/perf/util/include/dwarf-regs.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ #ifndef _PERF_DWARF_REGS_H_ #define _PERF_DWARF_REGS_H_ +#include "annotate.h" =20 #define DWARF_REG_PC 0xd3af9c /* random number */ #define DWARF_REG_FB 0xd3affb /* random number */ @@ -39,7 +40,8 @@ static inline int get_dwarf_regnum(const char *name __may= be_unused, int get_opcode_insn(unsigned int raw_insn); int get_source_reg(unsigned int raw_insn); int get_target_reg(unsigned int raw_insn); - +int get_offset_opcode(int raw_insn); +void get_arch_regs(int raw_insn, int is_source, struct annotated_op_loc *o= p_loc); #ifdef HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET /* * Arch should support fetching the offset of a register in pt_regs --=20 2.43.0 From nobody Wed Dec 17 17:23:50 2025 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DC526144D1C; Mon, 6 May 2024 12:19:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714997996; cv=none; b=PqaE8JenjW3r0q6RmFAqRQUrOj9NMMyyPQBLBm8zrQozJr2haihBaoUMric4hDWKS0fjHhBHvHr4LXf3nyoqna9gbn6bXlrovQigy9xGTZ3mZcKLUiTbeb/q6Oye7cFeRZE6ljYU3TIN/qR/xJkMJrGbHBMjVFOxiQhLrh/q8/M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714997996; c=relaxed/simple; bh=SB2VA1P4bv4DS15Y0HT38Tbki6939Bp1Qo5lZr1Agy8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Wqr3Qxm3NWtqSPgLOCuLeVB/WwAXiJCSXiQDE6bJ3diZ2hfTWTk3I4SDIi2XDakglGNoSCzQSCxYurFYnF05s1aMhPX946BzVfvtBZYyZVuuvgrApniTvqYGitzdmmMhL8wjdZNN6vNaADy/mpbpJxyQ4KZMLvuH5L47RzNblHI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com; spf=none smtp.mailfrom=linux.vnet.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=F8Vw2lMy; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="F8Vw2lMy" Received: from pps.filterd (m0360083.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 446AbadS002778; Mon, 6 May 2024 12:19:45 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=YW78lvVCVaTqDYt7Bzr2fQo5nYbxoax9c/H3v+dE/5M=; b=F8Vw2lMyjqzOnfDGjycXJr71HDSUQg8A1I3sfMuyOx9Bq7EafcjRyEpoa06UJYEudt/U qY/1rFPhSBU0vnOSDmoGSt/CP9sxX17MmrhqHh40clDYvANtlGNcjTRUG34OlDjvALeg aS2kGbIiqDZvlvx9yQvhGXxPYev7DBPib6nNibE7cyUS+xGqkY6CbeZ5I7Kid61Y4/VS 7oxCOI41yxVckV2aThiKHK3JxELKf6cyocoC5IoTmKo9yTZz7eWwDMjGenZMLDUwAuY7 Yj0jkLx8VSQ+MptWB0rClFkvnRZRkGVMUUPMNsVVnlxs2xjoC9QrtmdSuhoxaupMrvdX +g== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxwky08ch-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:44 +0000 Received: from m0360083.ppops.net (m0360083.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 446CJi19016015; Mon, 6 May 2024 12:19:44 GMT Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxwky08cd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:44 +0000 Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 446Bm9dY028576; Mon, 6 May 2024 12:19:43 GMT Received: from smtprelay01.fra02v.mail.ibm.com ([9.218.2.227]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 3xwyqyyy61-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:42 +0000 Received: from smtpav06.fra02v.mail.ibm.com (smtpav06.fra02v.mail.ibm.com [10.20.54.105]) by smtprelay01.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 446CJb2857541104 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 May 2024 12:19:39 GMT Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 260E32005A; Mon, 6 May 2024 12:19:37 +0000 (GMT) Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id EE91D20040; Mon, 6 May 2024 12:19:33 +0000 (GMT) Received: from localhost.localdomain (unknown [9.43.103.211]) by smtpav06.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 6 May 2024 12:19:33 +0000 (GMT) From: Athira Rajeev To: acme@kernel.org, jolsa@kernel.org, adrian.hunter@intel.com, irogers@google.com, namhyung@kernel.org, segher@kernel.crashing.org, christophe.leroy@csgroup.eu Cc: linux-perf-users@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, maddy@linux.ibm.com, atrajeev@linux.vnet.ibm.com, kjain@linux.ibm.com, disgoel@linux.vnet.ibm.com, linux-kernel@vger.kernel.org, akanksha@linux.ibm.com Subject: [PATCH V2 6/9] tools/perf: Update instruction tracking for powerpc Date: Mon, 6 May 2024 17:49:03 +0530 Message-Id: <20240506121906.76639-7-atrajeev@linux.vnet.ibm.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> References: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: bzuOl7uyKSHwtrAJcs86RTPfnmbmdjnc X-Proofpoint-GUID: PbMHOX6P54mF6CMgsxpDNLh_npRFPBeu X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1011,Hydra:6.0.650,FMLib:17.11.176.26 definitions=2024-05-06_07,2024-05-06_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 clxscore=1015 malwarescore=0 suspectscore=0 bulkscore=0 mlxlogscore=999 spamscore=0 impostorscore=0 priorityscore=1501 mlxscore=0 lowpriorityscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2404010000 definitions=main-2405060085 Content-Type: text/plain; charset="utf-8" Add instruction tracking function "update_insn_state_powerpc" for powerpc. Example sequence in powerpc: ld r10,264(r3) mr r31,r3 < ld r9,312(r31) Consider ithe sample is pointing to: "ld r9,312(r31)". Here the memory reference is hit at "312(r31)" where 312 is the offset and r31 is the source register. Previous instruction sequence shows that register state of r3 is moved to r31. So to identify the data type for r31 access, the previous instruction ("mr") needs to be tracked and the state type entry has to be updated. Current instruction tracking support in perf tools infrastructure is specific to x86. Patch adds this for powerpc and adds "mr" instruction to be tracked. Signed-off-by: Athira Rajeev --- .../perf/arch/powerpc/annotate/instructions.c | 63 +++++++++++++++++++ tools/perf/util/annotate-data.c | 9 ++- tools/perf/util/disasm.c | 1 + 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/tools/perf/arch/powerpc/annotate/instructions.c b/tools/perf/a= rch/powerpc/annotate/instructions.c index a3f423c27cae..cce7023951fe 100644 --- a/tools/perf/arch/powerpc/annotate/instructions.c +++ b/tools/perf/arch/powerpc/annotate/instructions.c @@ -49,6 +49,69 @@ static struct ins_ops *powerpc__associate_instruction_op= s(struct arch *arch, con return ops; } =20 +/* + * Instruction tracking function to track register state moves. + * Example sequence: + * ld r10,264(r3) + * mr r31,r3 + * < + * ld r9,312(r31) + * + * Previous instruction sequence shows that register state of r3 + * is moved to r31. update_insn_state_powerpc tracks these state + * changes + */ +#ifdef HAVE_DWARF_SUPPORT +static void update_insn_state_powerpc(struct type_state *state, + struct data_loc_info *dloc, Dwarf_Die *cu_die __maybe_unused, + struct disasm_line *dl) +{ + struct annotated_insn_loc loc; + struct annotated_op_loc *src =3D &loc.ops[INSN_OP_SOURCE]; + struct annotated_op_loc *dst =3D &loc.ops[INSN_OP_TARGET]; + struct type_state_reg *tsr; + u32 insn_offset =3D dl->al.offset; + + if (annotate_get_insn_location(dloc->arch, dl, &loc) < 0) + return; + + if (strncmp(dl->ins.name, "mr", 2)) + return; + + if (!strncmp(dl->ins.name, "mr", 2)) { + int src_reg =3D src->reg1; + + src->reg1 =3D dst->reg1; + dst->reg1 =3D src_reg; + } + + if (!has_reg_type(state, dst->reg1)) + return; + + tsr =3D &state->regs[dst->reg1]; + + if (!has_reg_type(state, src->reg1) || + !state->regs[src->reg1].ok) { + tsr->ok =3D false; + return; + } + + tsr->type =3D state->regs[src->reg1].type; + tsr->kind =3D state->regs[src->reg1].kind; + tsr->ok =3D true; + + pr_debug("mov [%x] reg%d -> reg%d", + insn_offset, src->reg1, dst->reg1); + pr_debug_type_name(&tsr->type, tsr->kind); +} +#else /* HAVE_DWARF_SUPPORT */ +static void update_insn_state_powerpc(struct type_state *state __maybe_unu= sed, struct data_loc_info *dloc __maybe_unused, + Dwarf_Die *cu_die __maybe_unused, struct disasm_line *dl __maybe_unused) +{ + return; +} +#endif /* HAVE_DWARF_SUPPORT */ + static int powerpc__annotate_init(struct arch *arch, char *cpuid __maybe_u= nused) { if (!arch->initialized) { diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index 9d6d4f472c85..e22ba35c93b2 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -1079,6 +1079,13 @@ static int find_data_type_insn(struct data_loc_info = *dloc, return ret; } =20 +static int arch_supports_insn_tracking(struct data_loc_info *dloc) +{ + if ((arch__is(dloc->arch, "x86")) || (arch__is(dloc->arch, "powerpc"))) + return 1; + return 0; +} + /* * Construct a list of basic blocks for each scope with variables and try = to find * the data type by updating a type state table through instructions. @@ -1093,7 +1100,7 @@ static int find_data_type_block(struct data_loc_info = *dloc, int ret =3D -1; =20 /* TODO: other architecture support */ - if (!arch__is(dloc->arch, "x86")) + if (!arch_supports_insn_tracking(dloc)) return -1; =20 prev_dst_ip =3D dst_ip =3D dloc->ip; diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index f41a0fadeab4..ac6b8b8da38a 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -151,6 +151,7 @@ static struct arch architectures[] =3D { { .name =3D "powerpc", .init =3D powerpc__annotate_init, + .update_insn_state =3D update_insn_state_powerpc, }, { .name =3D "riscv64", --=20 2.43.0 From nobody Wed Dec 17 17:23:50 2025 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EAB6B144D28; Mon, 6 May 2024 12:19:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714997997; cv=none; b=COyUj5NZQL2CklsOKs+N1nCp8eWSqQo65vTM/1Y+PT9iXNHUP7/gPUSf4QrfEvuhpMkua7qCy8R6PHMSQoRSqQodqe7H4EVQMp4KxE1McYQJr54PTHD7lW8aYe/kXDfElbzdiVu+jrMbAcuxBRD7BJ3Fg2EfpsinBnSFsz7JcpU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714997997; c=relaxed/simple; bh=zNJ1k5ybcgNHKBArFWXYsOLguPq8qo+EWFdarx7ochY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=KCWJC3X8mHPbDOFv0IOon4bGMJrwz+knLv5OAfbFfk5SwkXfR0b8btGRh3wjYRlS1ygC9kmYpylv+6KKXTSeZWavor2lMidqSdw3PVc0jo8FH099KpXFH/z8nilX6al22Ei4YlMZ/DoKLPkj8uKzHPoCIoL9nWag6KiIRMor+Xs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com; spf=none smtp.mailfrom=linux.vnet.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=ZGApZSZo; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="ZGApZSZo" Received: from pps.filterd (m0353728.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 446BlZfA011547; Mon, 6 May 2024 12:19:47 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=iHTUeZ0T/IUAIn09/t+OMcvI8S2itkKjhzjC2IDYdIQ=; b=ZGApZSZo1hSk4xnXEa2DFpGLUp4RH3Lu47IlF4IrNySuGSWMPnt7yo4HgSxVaV5AJmSQ 0gUFd38hoWaAcukD23OrCifT2X7Pf+mrj+wTOnPQ2qEiCNK4Lf/9c3JkAXvZgtfRqAa6 6wtySAVrYLzE8khbJnWWr8IIjekH9CNbIjO+aH0SarvDSjoSysyXfogLpnW953zXKuFp B95Ll9biQqZO6gtYm4as6zJRL6Mth+8rvGAlys7NlD6MzbS72LLGqp7Qc8OlLQwppNZA O756hvbhdXc0sGzLxZO49nvrwfMSMnI0LDRb5fHNmMI/uTv6KuOB2U147rVF2CqXoLe8 gg== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxxmt82yp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:47 +0000 Received: from m0353728.ppops.net (m0353728.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 446CJkQZ005665; Mon, 6 May 2024 12:19:46 GMT Received: from ppma12.dal12v.mail.ibm.com (dc.9e.1632.ip4.static.sl-reverse.com [50.22.158.220]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxxmt82ym-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:46 +0000 Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 446BfLV4031316; Mon, 6 May 2024 12:19:45 GMT Received: from smtprelay05.fra02v.mail.ibm.com ([9.218.2.225]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 3xwybtr2ag-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:45 +0000 Received: from smtpav06.fra02v.mail.ibm.com (smtpav06.fra02v.mail.ibm.com [10.20.54.105]) by smtprelay05.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 446CJewn40108518 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 May 2024 12:19:42 GMT Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 439F120049; Mon, 6 May 2024 12:19:40 +0000 (GMT) Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 7345F20040; Mon, 6 May 2024 12:19:37 +0000 (GMT) Received: from localhost.localdomain (unknown [9.43.103.211]) by smtpav06.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 6 May 2024 12:19:37 +0000 (GMT) From: Athira Rajeev To: acme@kernel.org, jolsa@kernel.org, adrian.hunter@intel.com, irogers@google.com, namhyung@kernel.org, segher@kernel.crashing.org, christophe.leroy@csgroup.eu Cc: linux-perf-users@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, maddy@linux.ibm.com, atrajeev@linux.vnet.ibm.com, kjain@linux.ibm.com, disgoel@linux.vnet.ibm.com, linux-kernel@vger.kernel.org, akanksha@linux.ibm.com Subject: [PATCH V2 7/9] tools/perf: Update instruction tracking with add instruction Date: Mon, 6 May 2024 17:49:04 +0530 Message-Id: <20240506121906.76639-8-atrajeev@linux.vnet.ibm.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> References: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: 2k4ly3FmCmI4WVbNYzBIFkjqTnlVDspR X-Proofpoint-GUID: Y42foEVAob09gcOwenFX9W6oVukdxgF- X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1011,Hydra:6.0.650,FMLib:17.11.176.26 definitions=2024-05-06_07,2024-05-06_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 adultscore=0 clxscore=1015 mlxscore=0 bulkscore=0 priorityscore=1501 spamscore=0 suspectscore=0 lowpriorityscore=0 impostorscore=0 malwarescore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2404010000 definitions=main-2405060085 Content-Type: text/plain; charset="utf-8" Update instruction tracking with add instruction. Apart from "mr" instruction, the register state is carried on by other insns, ie, "add, addi, addis". Since these are not memory instructions and doesn't fall in the range of (32 to 63), add these as part of nmemonic table. For now, add* instructions are added. There is possibility of getting more added here. But to extract regs, still the binary code will be used. So associate this with "load_store_ops" itself and no other changes required. Signed-off-by: Athira Rajeev --- .../perf/arch/powerpc/annotate/instructions.c | 21 +++++++++++++++++++ tools/perf/util/disasm.c | 1 + 2 files changed, 22 insertions(+) diff --git a/tools/perf/arch/powerpc/annotate/instructions.c b/tools/perf/a= rch/powerpc/annotate/instructions.c index cce7023951fe..1f35d8a65bb4 100644 --- a/tools/perf/arch/powerpc/annotate/instructions.c +++ b/tools/perf/arch/powerpc/annotate/instructions.c @@ -1,6 +1,17 @@ // SPDX-License-Identifier: GPL-2.0 #include =20 +/* + * powerpc instruction nmemonic table to associate load/store instructions= with + * move_ops. mov_ops is used to identify add/mr to do instruction tracking. + */ +static struct ins powerpc__instructions[] =3D { + { .name =3D "mr", .ops =3D &load_store_ops, }, + { .name =3D "addi", .ops =3D &load_store_ops, }, + { .name =3D "addis", .ops =3D &load_store_ops, }, + { .name =3D "add", .ops =3D &load_store_ops, }, +}; + static struct ins_ops *powerpc__associate_instruction_ops(struct arch *arc= h, const char *name) { int i; @@ -75,6 +86,9 @@ static void update_insn_state_powerpc(struct type_state *= state, if (annotate_get_insn_location(dloc->arch, dl, &loc) < 0) return; =20 + if (!strncmp(dl->ins.name, "add", 3)) + goto regs_check; + if (strncmp(dl->ins.name, "mr", 2)) return; =20 @@ -85,6 +99,7 @@ static void update_insn_state_powerpc(struct type_state *= state, dst->reg1 =3D src_reg; } =20 +regs_check: if (!has_reg_type(state, dst->reg1)) return; =20 @@ -115,6 +130,12 @@ static void update_insn_state_powerpc(struct type_stat= e *state __maybe_unused, s static int powerpc__annotate_init(struct arch *arch, char *cpuid __maybe_u= nused) { if (!arch->initialized) { + arch->nr_instructions =3D ARRAY_SIZE(powerpc__instructions); + arch->instructions =3D calloc(arch->nr_instructions, sizeof(struct ins)); + if (!arch->instructions) + return -ENOMEM; + memcpy(arch->instructions, powerpc__instructions, sizeof(struct ins) * a= rch->nr_instructions); + arch->nr_instructions_allocated =3D arch->nr_instructions; arch->initialized =3D true; arch->associate_instruction_ops =3D powerpc__associate_instruction_ops; arch->objdump.comment_char =3D '#'; diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index ac6b8b8da38a..32cf506a9010 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -36,6 +36,7 @@ static struct ins_ops mov_ops; static struct ins_ops nop_ops; static struct ins_ops lock_ops; static struct ins_ops ret_ops; +static struct ins_ops load_store_ops; =20 static int jump__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops, int max_ins_name); --=20 2.43.0 From nobody Wed Dec 17 17:23:50 2025 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 868B1145354; Mon, 6 May 2024 12:20:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714998002; cv=none; b=ZTo+AbqSQhg9M8PC5T+N8VF/BMrKfHN27mPqNHqBVmZ8tMIwRp+SIqv0B7MquY4AZAy6jsXRRt5mTGEgUJ4+90ZCA4skxgGxwUF77zI75Som2vMIWKRc9EPm6LlPGur5A9twaeObFI1i3hjH+CLmvDiQTuxLffpG6+fMXo6Ges0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714998002; c=relaxed/simple; bh=CgjepDO5M96RkBahteiyOXETIpeBYyi/cQSkC3dP9SQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=hMhjJLji9AvX92gcQYEpnm0JJaeEanqBE1h12iRdnNq9SytZUz5LM1va6ZANjHOtNj8Dazh4sYWj/4NRoSNRG7aEd34fUh4foOYMpk/hiX+ECxNQxfZWVWHWKcmYyzJZ0oiRoslQCnW9jEThkfJ31RZmXizjv3kUTZcxs3yIbg8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com; spf=none smtp.mailfrom=linux.vnet.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=XGzBaggW; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="XGzBaggW" Received: from pps.filterd (m0353728.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 446BlEVF011184; Mon, 6 May 2024 12:19:51 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=XaIvg3taXF68ek0OaAJ9nmQVZuVqNS5etVkdAVQM2WQ=; b=XGzBaggWeYs3pliFs+my6MVExV51C4UalvPrrpwAxNkTZvft7mqLAStUnnu3K/aDK+ic uRiQopuvw8Li0Z2N22lZ3MebtNABJxh1Cksrih2Ai0gzfVvBrsXOc+Nd07HkEG0lbh4Q TYexoaizu+5cZWBdBTOU+xxYPli26Jc9NIpY3l/Z2qyv6RO6cwZH8Gq0Xr/TA2BUGUbV 6HU7loCE0ZUjC080HfCK/hHcPSUH3ojI3Jn31fV5ynQfAj1D+RQXig4ka+85poBUh0A1 5MviHBPZsbZLta85QI1y0A8IoF3K66VeD2UFeMuCfmWbtrxJVgqGtNBt8xo47/yjBC0m HA== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxxmt82yv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:50 +0000 Received: from m0353728.ppops.net (m0353728.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 446CJo92005730; Mon, 6 May 2024 12:19:50 GMT Received: from ppma22.wdc07v.mail.ibm.com (5c.69.3da9.ip4.static.sl-reverse.com [169.61.105.92]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxxmt82ys-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:50 +0000 Received: from pps.filterd (ppma22.wdc07v.mail.ibm.com [127.0.0.1]) by ppma22.wdc07v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 446C7Zxu028617; Mon, 6 May 2024 12:19:49 GMT Received: from smtprelay02.fra02v.mail.ibm.com ([9.218.2.226]) by ppma22.wdc07v.mail.ibm.com (PPS) with ESMTPS id 3xwyqyyy68-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:48 +0000 Received: from smtpav06.fra02v.mail.ibm.com (smtpav06.fra02v.mail.ibm.com [10.20.54.105]) by smtprelay02.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 446CJhwE38863322 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 May 2024 12:19:45 GMT Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 4E9A12004B; Mon, 6 May 2024 12:19:43 +0000 (GMT) Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 9056420040; Mon, 6 May 2024 12:19:40 +0000 (GMT) Received: from localhost.localdomain (unknown [9.43.103.211]) by smtpav06.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 6 May 2024 12:19:40 +0000 (GMT) From: Athira Rajeev To: acme@kernel.org, jolsa@kernel.org, adrian.hunter@intel.com, irogers@google.com, namhyung@kernel.org, segher@kernel.crashing.org, christophe.leroy@csgroup.eu Cc: linux-perf-users@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, maddy@linux.ibm.com, atrajeev@linux.vnet.ibm.com, kjain@linux.ibm.com, disgoel@linux.vnet.ibm.com, linux-kernel@vger.kernel.org, akanksha@linux.ibm.com Subject: [PATCH V2 8/9] tools/perf: Add support to find global register variables using find_data_type_global_reg Date: Mon, 6 May 2024 17:49:05 +0530 Message-Id: <20240506121906.76639-9-atrajeev@linux.vnet.ibm.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> References: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: nnTHVa2sMr69XQ6Hk8pqmpYq-BfVcRxB X-Proofpoint-GUID: l34jEA8ezFTHWpBRJzaf4iPfieHGYKVn X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1011,Hydra:6.0.650,FMLib:17.11.176.26 definitions=2024-05-06_07,2024-05-06_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxlogscore=999 adultscore=0 clxscore=1015 mlxscore=0 bulkscore=0 priorityscore=1501 spamscore=0 suspectscore=0 lowpriorityscore=0 impostorscore=0 malwarescore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2404010000 definitions=main-2405060085 Content-Type: text/plain; charset="utf-8" There are cases where define a global register variable and associate it with a specified register. Example, in powerpc, two registers are defined to represent variable: 1. r13: represents local_paca register struct paca_struct *local_paca asm("r13"); 2. r1: represents stack_pointer register void *__stack_pointer asm("r1"); These regs are present in dwarf debug as DW_OP_reg as part of variables in the cu_die (compile unit). These are not present in die search done in the list of nested scopes since these are global register variables. Example for local_paca represented by r13: <<>> <1><18dc6b4>: Abbrev Number: 128 (DW_TAG_variable) <18dc6b6> DW_AT_name : (indirect string, offset: 0x3861): loca= l_paca <18dc6ba> DW_AT_decl_file : 48 <18dc6bb> DW_AT_decl_line : 36 <18dc6bc> DW_AT_decl_column : 30 <18dc6bd> DW_AT_type : <0x18dc6c3> <18dc6c1> DW_AT_external : 1 <18dc6c1> DW_AT_location : 1 byte block: 5d (DW_OP_reg13 (r13)) <1><18dc6c3>: Abbrev Number: 3 (DW_TAG_pointer_type) <18dc6c4> DW_AT_byte_size : 8 <18dc6c4> DW_AT_type : <0x18dc353> Where DW_AT_type : <0x18dc6c3> further points to : <1><18dc6c3>: Abbrev Number: 3 (DW_TAG_pointer_type) <18dc6c4> DW_AT_byte_size : 8 <18dc6c4> DW_AT_type : <0x18dc353> which belongs to: <1><18dc353>: Abbrev Number: 67 (DW_TAG_structure_type) <18dc354> DW_AT_name : (indirect string, offset: 0x56cd): paca= _struct <18dc358> DW_AT_byte_size : 2944 <18dc35a> DW_AT_alignment : 128 <18dc35b> DW_AT_decl_file : 48 <18dc35c> DW_AT_decl_line : 61 <18dc35d> DW_AT_decl_column : 8 <18dc35d> DW_AT_sibling : <0x18dc6b4> <<>> Similar is case with "r1". <<>> <1><18dd772>: Abbrev Number: 129 (DW_TAG_variable) <18dd774> DW_AT_name : (indirect string, offset: 0x11ba): curr= ent_stack_pointer <18dd778> DW_AT_decl_file : 51 <18dd779> DW_AT_decl_line : 1468 <18dd77b> DW_AT_decl_column : 24 <18dd77c> DW_AT_type : <0x18da5cd> <18dd780> DW_AT_external : 1 <18dd780> DW_AT_location : 1 byte block: 51 (DW_OP_reg1 (r1)) where 18da5cd is: <1><18da5cd>: Abbrev Number: 47 (DW_TAG_base_type) <18da5ce> DW_AT_byte_size : 8 <18da5cf> DW_AT_encoding : 7 (unsigned) <18da5d0> DW_AT_name : (indirect string, offset: 0x55c7): long= unsigned int <<>> To identify data type for these two special cases, iterate over variables in the CU die (Compile Unit) and match it with the register. If the variable is a base type, ie die_get_real_type will return NULL here, set offset to zero. With the changes, data type for "paca_struct" and "long unsigned int" for r1 is identified. Snippet from ./perf report -s type,type_off 12.85% long unsigned int long unsigned int +0 (no field) 4.68% struct paca_struct struct paca_struct +2312 (__current) 4.57% struct paca_struct struct paca_struct +2354 (irq_soft_mask) Signed-off-by: Athira Rajeev --- tools/perf/util/annotate-data.c | 40 ++++++++++++++++++++++++++++ tools/perf/util/annotate.c | 8 ++++++ tools/perf/util/annotate.h | 1 + tools/perf/util/include/dwarf-regs.h | 1 + 4 files changed, 50 insertions(+) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index e22ba35c93b2..ab2168c4ef41 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -1169,6 +1169,40 @@ static int find_data_type_block(struct data_loc_info= *dloc, return ret; } =20 +/* + * Handle cases where define a global register variable and + * associate it with a specified register. These regs are + * present in dwarf debug as DW_OP_reg as part of variables + * in the cu_die (compile unit). Iterate over variables in the + * cu_die and match with reg to identify data type die. + */ +static int find_data_type_global_reg(struct data_loc_info *dloc, int reg, = Dwarf_Die *cu_die, + Dwarf_Die *type_die) +{ + Dwarf_Die vr_die; + int ret =3D -1; + struct die_var_type *var_types =3D NULL; + + die_collect_vars(cu_die, &var_types); + while (var_types) { + if (var_types->reg =3D=3D reg) { + if (dwarf_offdie(dloc->di->dbg, var_types->die_off, &vr_die)) { + if (die_get_real_type(&vr_die, type_die) =3D=3D NULL) { + dloc->type_offset =3D 0; + dwarf_offdie(dloc->di->dbg, var_types->die_off, type_die); + } + pr_debug_type_name(type_die, TSR_KIND_TYPE); + ret =3D 0; + pr_debug_dtp("found by CU for %s (die:%#lx)\n", + dwarf_diename(type_die), (long)dwarf_dieoffset(type_die)); + } + break; + } + var_types =3D var_types->next; + } + return ret; +} + /* The result will be saved in @type_die */ static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_= die) { @@ -1216,6 +1250,12 @@ static int find_data_type_die(struct data_loc_info *= dloc, Dwarf_Die *type_die) pr_debug_dtp("CU for %s (die:%#lx)\n", dwarf_diename(&cu_die), (long)dwarf_dieoffset(&cu_die)); =20 + if (loc->reg_type =3D=3D DWARF_REG_GLOBAL) { + ret =3D find_data_type_global_reg(dloc, reg, &cu_die, type_die); + if (!ret) + goto out; + } + if (reg =3D=3D DWARF_REG_PC) { if (get_global_var_type(&cu_die, dloc, dloc->ip, dloc->var_addr, &offset, type_die)) { diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 48739c7ffdc7..2b0b5279f86d 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -2426,6 +2426,14 @@ struct annotated_data_type *hist_entry__get_data_typ= e(struct hist_entry *he) op_loc->reg1 =3D DWARF_REG_PC; } =20 + /* Global reg variable 13 and 1 + * assign to DWARF_REG_GLOBAL + */ + if (arch__is(arch, "powerpc")) { + if ((op_loc->reg1 =3D=3D 13) || (op_loc->reg1 =3D=3D 1)) + op_loc->reg_type =3D DWARF_REG_GLOBAL; + } + mem_type =3D find_data_type(&dloc); =20 if (mem_type =3D=3D NULL && is_stack_canary(arch, op_loc)) { diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index d5c821c22f79..43ae75d8356b 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -472,6 +472,7 @@ struct annotated_op_loc { bool mem_ref; bool multi_regs; bool imm; + int reg_type; }; =20 enum annotated_insn_ops { diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include= /dwarf-regs.h index d691245dd703..adcce167d9ca 100644 --- a/tools/perf/util/include/dwarf-regs.h +++ b/tools/perf/util/include/dwarf-regs.h @@ -5,6 +5,7 @@ =20 #define DWARF_REG_PC 0xd3af9c /* random number */ #define DWARF_REG_FB 0xd3affb /* random number */ +#define DWARF_REG_GLOBAL 0xd3affc /* random number */ =20 #ifdef HAVE_DWARF_SUPPORT const char *get_arch_regstr(unsigned int n); --=20 2.43.0 From nobody Wed Dec 17 17:23:50 2025 Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8FC96143C67; Mon, 6 May 2024 12:20:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.156.1 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714998003; cv=none; b=Sj+PtVkP10r9cKbywA8kmMB16S16BLvr6iQP3jOC8ao/IiVUUCvPvbs4pUkMW5gjxdkkjBL0NilhL+OxO78blLhHvbJ9LAAdKPWcUZOpA041S1MDdnlsFzJoJSwzkO5ZmtBeeAW6qf28tn8IDgRrnv7VdmX8vHEREuGNQAmbSPc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714998003; c=relaxed/simple; bh=DilNUiGez+kodbzvR2YoBFyms4jFHleUjm/Uwdyw0O8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OmOHBQ3kFnbV9VqmJ9FNdjOanowxriZml/qA4Z7WOPvKHdGWRhGHqZuk9u9h88KJ9v0maimkZUEhMlLa9KGptYinWcarIZrl5gZ+gy6dpKxzbNMBeIIYoMcTmRlD/tq1LxBv+6zQu4hELTQD06cEX3LE3qjDiqgO0SLbb6g32AU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com; spf=none smtp.mailfrom=linux.vnet.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=kpUrBSYa; arc=none smtp.client-ip=148.163.156.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.vnet.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="kpUrBSYa" Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 446C87Dw021500; Mon, 6 May 2024 12:19:54 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=pp1; bh=lU4xGv8LwTNcjnMqINUw3JPV+5beaiB5CiA/d2/iPts=; b=kpUrBSYatbByvs4aXNONSNKdIKTS0b4bgbo8wkYz1+jJIkbxeFhL7i8NjKRgcIeLImQY YLchkGdT1skjNBsTNrMSSGuABhIwicpXIXXNBvPH6y+1sylJ75kdJz51ZVLLb4891+j3 uo521bXfw9YyuPP9vX7MUiomnoztQqydccGeLLy9tRfnotnZYCPulQGdTUlzRgSOsfAP eYV0SDBdQWLMOqdNUFjaypw0SN08c1BSUmOrlYmyRPZ447R8WxD/fkvBScOdmMxpa0Mk Lvsu6dzHmaeTdkiYdRR+dhQ9xYekG8n16xMOVV56AIAnCd9YYZQstMZM/BLV8cEcLnhI YQ== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxxx9r0uq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:53 +0000 Received: from m0356517.ppops.net (m0356517.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 446CHKQf002943; Mon, 6 May 2024 12:19:52 GMT Received: from ppma12.dal12v.mail.ibm.com (dc.9e.1632.ip4.static.sl-reverse.com [50.22.158.220]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3xxxx9r0um-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:52 +0000 Received: from pps.filterd (ppma12.dal12v.mail.ibm.com [127.0.0.1]) by ppma12.dal12v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 446BfLV6031316; Mon, 6 May 2024 12:19:51 GMT Received: from smtprelay04.fra02v.mail.ibm.com ([9.218.2.228]) by ppma12.dal12v.mail.ibm.com (PPS) with ESMTPS id 3xwybtr2aq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 06 May 2024 12:19:51 +0000 Received: from smtpav06.fra02v.mail.ibm.com (smtpav06.fra02v.mail.ibm.com [10.20.54.105]) by smtprelay04.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 446CJkCx28836464 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 6 May 2024 12:19:48 GMT Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 81E0A2004B; Mon, 6 May 2024 12:19:46 +0000 (GMT) Received: from smtpav06.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C9FC820049; Mon, 6 May 2024 12:19:43 +0000 (GMT) Received: from localhost.localdomain (unknown [9.43.103.211]) by smtpav06.fra02v.mail.ibm.com (Postfix) with ESMTP; Mon, 6 May 2024 12:19:43 +0000 (GMT) From: Athira Rajeev To: acme@kernel.org, jolsa@kernel.org, adrian.hunter@intel.com, irogers@google.com, namhyung@kernel.org, segher@kernel.crashing.org, christophe.leroy@csgroup.eu Cc: linux-perf-users@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, maddy@linux.ibm.com, atrajeev@linux.vnet.ibm.com, kjain@linux.ibm.com, disgoel@linux.vnet.ibm.com, linux-kernel@vger.kernel.org, akanksha@linux.ibm.com Subject: [PATCH V2 9/9] tools/perf: Add support for global_die to capture name of variable in case of register defined variable Date: Mon, 6 May 2024 17:49:06 +0530 Message-Id: <20240506121906.76639-10-atrajeev@linux.vnet.ibm.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> References: <20240506121906.76639-1-atrajeev@linux.vnet.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-TM-AS-GCONF: 00 X-Proofpoint-GUID: y7IIdC-JjZ9vhSTebCkpcVtX3VwPQqKt X-Proofpoint-ORIG-GUID: 8GOgWMLtuWPI4BUi92zdJBk5CshixcOA X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1011,Hydra:6.0.650,FMLib:17.11.176.26 definitions=2024-05-06_07,2024-05-06_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 lowpriorityscore=0 spamscore=0 suspectscore=0 bulkscore=0 phishscore=0 adultscore=0 mlxlogscore=999 priorityscore=1501 impostorscore=0 malwarescore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2404010000 definitions=main-2405060085 Content-Type: text/plain; charset="utf-8" In case of register defined variable (found using find_data_type_global_reg), if the type of variable happens to be base type (example, long unsigned int), perf report captures it as: 12.85% long unsigned int long unsigned int +0 (no field) The above data type is actually referring to samples captured while accessing "r1" which represents current stack pointer in powerpc. register void *__stack_pointer asm("r1"); The dwarf debug contains this as: <<>> <1><18dd772>: Abbrev Number: 129 (DW_TAG_variable) <18dd774> DW_AT_name : (indirect string, offset: 0x11ba): curr= ent_stack_pointer <18dd778> DW_AT_decl_file : 51 <18dd779> DW_AT_decl_line : 1468 <18dd77b> DW_AT_decl_column : 24 <18dd77c> DW_AT_type : <0x18da5cd> <18dd780> DW_AT_external : 1 <18dd780> DW_AT_location : 1 byte block: 51 (DW_OP_reg1 (r1)) where 18da5cd is: <1><18da5cd>: Abbrev Number: 47 (DW_TAG_base_type) <18da5ce> DW_AT_byte_size : 8 <18da5cf> DW_AT_encoding : 7 (unsigned) <18da5d0> DW_AT_name : (indirect string, offset: 0x55c7): long= unsigned int <<>> To make it more clear to the user, capture the DW_AT_name of the variable and save it as part of Dwarf_Global. Dwarf_Global is used so that it can be used and retrieved while presenting the result. Update "dso__findnew_data_type" function to set "var_name" if variable name is set as part of Dwarf_Global. Updated "hist_entry__typeoff_snprintf" to print var_name if it is set. With the changes, along with "long unsigned int" report also says the variable name as current_stack_pointer Snippet of result: 12.85% long unsigned int long unsigned int +0 (current_stack_pointer) 4.68% struct paca_struct struct paca_struct +2312 (__current) 4.57% struct paca_struct struct paca_struct +2354 (irq_soft_mask) Signed-off-by: Athira Rajeev --- tools/perf/util/annotate-data.c | 30 ++++++++++++++++++++++++------ tools/perf/util/dwarf-aux.c | 1 + tools/perf/util/dwarf-aux.h | 1 + tools/perf/util/sort.c | 7 +++++-- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-dat= a.c index ab2168c4ef41..9f72d4b6a5f4 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -267,23 +267,32 @@ static void delete_members(struct annotated_member *m= ember) } =20 static struct annotated_data_type *dso__findnew_data_type(struct dso *dso, - Dwarf_Die *type_die) + Dwarf_Die *type_die, Dwarf_Global *global_die) { struct annotated_data_type *result =3D NULL; struct annotated_data_type key; struct rb_node *node; struct strbuf sb; + struct strbuf sb_var_name; char *type_name; + char *var_name; Dwarf_Word size; =20 strbuf_init(&sb, 32); + strbuf_init(&sb_var_name, 32); if (die_get_typename_from_type(type_die, &sb) < 0) strbuf_add(&sb, "(unknown type)", 14); + if (global_die->name) { + strbuf_addstr(&sb_var_name, global_die->name); + var_name =3D strbuf_detach(&sb_var_name, NULL); + } type_name =3D strbuf_detach(&sb, NULL); dwarf_aggregate_size(type_die, &size); =20 /* Check existing nodes in dso->data_types tree */ key.self.type_name =3D type_name; + if (global_die->name) + key.self.var_name =3D var_name; key.self.size =3D size; node =3D rb_find(&key, &dso->data_types, data_type_cmp); if (node) { @@ -300,6 +309,8 @@ static struct annotated_data_type *dso__findnew_data_ty= pe(struct dso *dso, } =20 result->self.type_name =3D type_name; + if (global_die->name) + result->self.var_name =3D var_name; result->self.size =3D size; INIT_LIST_HEAD(&result->self.children); =20 @@ -1177,7 +1188,7 @@ static int find_data_type_block(struct data_loc_info = *dloc, * cu_die and match with reg to identify data type die. */ static int find_data_type_global_reg(struct data_loc_info *dloc, int reg, = Dwarf_Die *cu_die, - Dwarf_Die *type_die) + Dwarf_Die *type_die, Dwarf_Global *global_die) { Dwarf_Die vr_die; int ret =3D -1; @@ -1189,8 +1200,11 @@ static int find_data_type_global_reg(struct data_loc= _info *dloc, int reg, Dwarf_ if (dwarf_offdie(dloc->di->dbg, var_types->die_off, &vr_die)) { if (die_get_real_type(&vr_die, type_die) =3D=3D NULL) { dloc->type_offset =3D 0; + global_die->name =3D var_types->name; dwarf_offdie(dloc->di->dbg, var_types->die_off, type_die); } + global_die->die_offset =3D (long)dwarf_dieoffset(type_die); + global_die->cu_offset =3D (long)dwarf_dieoffset(cu_die); pr_debug_type_name(type_die, TSR_KIND_TYPE); ret =3D 0; pr_debug_dtp("found by CU for %s (die:%#lx)\n", @@ -1204,7 +1218,8 @@ static int find_data_type_global_reg(struct data_loc_= info *dloc, int reg, Dwarf_ } =20 /* The result will be saved in @type_die */ -static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_= die) +static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_= die, + Dwarf_Global *global_die) { struct annotated_op_loc *loc =3D dloc->op; Dwarf_Die cu_die, var_die; @@ -1218,6 +1233,8 @@ static int find_data_type_die(struct data_loc_info *d= loc, Dwarf_Die *type_die) u64 pc; char buf[64]; =20 + memset(global_die, 0, sizeof(Dwarf_Global)); + if (dloc->op->multi_regs) snprintf(buf, sizeof(buf), "reg%d, reg%d", dloc->op->reg1, dloc->op->reg= 2); else if (dloc->op->reg1 =3D=3D DWARF_REG_PC) @@ -1251,7 +1268,7 @@ static int find_data_type_die(struct data_loc_info *d= loc, Dwarf_Die *type_die) dwarf_diename(&cu_die), (long)dwarf_dieoffset(&cu_die)); =20 if (loc->reg_type =3D=3D DWARF_REG_GLOBAL) { - ret =3D find_data_type_global_reg(dloc, reg, &cu_die, type_die); + ret =3D find_data_type_global_reg(dloc, reg, &cu_die, type_die, global_d= ie); if (!ret) goto out; } @@ -1387,6 +1404,7 @@ struct annotated_data_type *find_data_type(struct dat= a_loc_info *dloc) struct annotated_data_type *result =3D NULL; struct dso *dso =3D map__dso(dloc->ms->map); Dwarf_Die type_die; + Dwarf_Global global_die; =20 dloc->di =3D debuginfo__new(dso->long_name); if (dloc->di =3D=3D NULL) { @@ -1402,10 +1420,10 @@ struct annotated_data_type *find_data_type(struct d= ata_loc_info *dloc) =20 dloc->fbreg =3D -1; =20 - if (find_data_type_die(dloc, &type_die) < 0) + if (find_data_type_die(dloc, &type_die, &global_die) < 0) goto out; =20 - result =3D dso__findnew_data_type(dso, &type_die); + result =3D dso__findnew_data_type(dso, &type_die, &global_die); =20 out: debuginfo__delete(dloc->di); diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index c0a492e65388..d0478d4407d9 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -1608,6 +1608,7 @@ static int __die_collect_vars_cb(Dwarf_Die *die_mem, = void *arg) vt->reg =3D reg_from_dwarf_op(ops); vt->offset =3D offset_from_dwarf_op(ops); vt->next =3D *var_types; + vt->name =3D dwarf_diename(die_mem); *var_types =3D vt; =20 return DIE_FIND_CB_SIBLING; diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index 24446412b869..406a5b1e269b 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h @@ -146,6 +146,7 @@ struct die_var_type { u64 addr; int reg; int offset; + const char *name; }; =20 /* Return type info of a member at offset */ diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index add8601c57fd..c7dfeea1a23c 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -2303,9 +2303,12 @@ static int hist_entry__typeoff_snprintf(struct hist_= entry *he, char *bf, char buf[4096]; =20 buf[0] =3D '\0'; - if (list_empty(&he_type->self.children)) + if (list_empty(&he_type->self.children)) { snprintf(buf, sizeof(buf), "no field"); - else + if (he_type->self.var_name) + strcpy(buf, he_type->self.var_name); + + } else fill_member_name(buf, sizeof(buf), &he_type->self, he->mem_type_off, true); buf[4095] =3D '\0'; --=20 2.43.0