From patchwork Fri Feb 16 23:54:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 202434 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp59499dyc; Fri, 16 Feb 2024 15:55:46 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVPrDtVmqn7kQNbX2u6kzXSGNoQeU/gtdMaYds7xdF7uOIpXAnN0KHfrbAM3ZOWElYOh8n/cx4hdZspTs8b7lAmqLL5+w== X-Google-Smtp-Source: AGHT+IEBq9DyGLG09bFsDxxlJvEGYd2Hb9WOpMMG9MhdE+5L+vLbFTnDta2OInNf55unduEZIZXf X-Received: by 2002:a05:620a:cc8:b0:787:1fb5:7dd5 with SMTP id b8-20020a05620a0cc800b007871fb57dd5mr6673846qkj.46.1708127745974; Fri, 16 Feb 2024 15:55:45 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708127745; cv=pass; d=google.com; s=arc-20160816; b=BpQSj0rt2ZrE1cn3Eny4jSRdHmZOhZTJ+/XKxprIb0WDRJFu88bFzxV/dV5dwo/Gd9 H2Y4fP++FqqNwgp59mtOkkDjgI/kdaaDtqdQZw5nYBzFzzboYqBbBoKhgdaTktnNBBaH 86TVSX5IThBnSMcCiLNYAkhe5LZODtw0H13ROAplMgCiZLquTN/j65+RSN4qtlun5h+J D95PlVRA/k4DZHSs8AGjn6zsidmatTPsD0in7f1rfuC9mW/pip9BF7N5iT7XMZFIO5GV pqyRaZVMeUP++iQn9CU4jO3eFMcyjFEVNgsmHVbAJy73Of5Oi7ltIcM7J9zS1ngYBkd+ Lxmg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=V7hI5mT5byuSHq/TKtacJ485IEoNjDZjP6xcdoi6N38=; fh=44lErbL5kvNUjSV6UDWgBEjJyOJpjjMpxi6K+HFi+Bc=; b=icHlEHwwG2p1BvKvyKkEJTHdJRBcxjnQtYYM5Cw0ASdB0UCk6Anl6BczNyE3EBtmOo bbyBsvXJSfmLQQoR12WmTUHL7VqoDCGEqt4GY9B/eySlt0COWZnVkwGKY3OHC1p+TB2y T0jc3JgiIFVw6hlYUMO2SPJsn3P8GCJzibRs4zNiUMjKqO5nBHvC/Rtxfy0uI2soaviu KXcjghfMUpaQVXcR+zGKvIVCq8pdgdi5QH6aZLNPFEuwwjDODpkF8kU9m8bpSwDiYP/f 87Z7W3SWZN2u/DFypnoTUev0t77KEJcF5zRY1cYuxMIxSDrjDBIPRwdyZqkTsRxX7pJ2 gZ+g==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=lrFcSa2m; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69494-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69494-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id c8-20020a05620a164800b00786117e1cffsi1092703qko.7.2024.02.16.15.55.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Feb 2024 15:55:45 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-69494-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=lrFcSa2m; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69494-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69494-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 5CE9D1C22EE5 for ; Fri, 16 Feb 2024 23:55:31 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5FF5814C585; Fri, 16 Feb 2024 23:54:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lrFcSa2m" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 0F5D2148FFF; Fri, 16 Feb 2024 23:54:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127666; cv=none; b=sSfOLrH/Q3vWR6FE3Ej63oSZ2Pnpkhgv9iU7ZOXQcgr4K9RL17gzTTE4vo1hb5BpdlPahCdu/nKdHskEU51fcEoNvlo5oyuVMAVv1isEp3ZVKxU3a6rP1l3c5hAWchoxs058/uWrOMw1SDTORS6bo6UXQ5+jJ3TnscpSleJ4yl4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127666; c=relaxed/simple; bh=Qw5in8yXru6XDR/MkCtSi5udF5OsSGUvfaaiz1BQ/Vc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CpsXbPZG4elA9E0BSn+0Iaxmh+S3FO6MLvIJQkn9q1fivkFGqQ6rOoMk3NkSPAZrZOSjBizdNhxL4264pHcPNERtzA5oWifWxfNIVsItgc5bHvbbdO+JDd5QfH7X+RohpmA+zVKC7L27e8CMPMnJ1wcWkfX1/QcyzXDCLhk3H14= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lrFcSa2m; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2151BC433C7; Fri, 16 Feb 2024 23:54:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708127665; bh=Qw5in8yXru6XDR/MkCtSi5udF5OsSGUvfaaiz1BQ/Vc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lrFcSa2mRpoWSX/v9+yZiSyZX8U54mmS1u1B7ANszJyVkrCyL0oxTOXL0Vu94WFqT QYm4QgDfKMlQ3UPjrHvUCtRN2dmb8tQgha8RkZ/8PXUnMm6113IP7ZRtg+1ewWqDY/ Nb0OsPevP437xNFMXGlOQ5CV6ksbYFw80KPnOzNL+RpnxmlVhnsQvRHs0BS+qLy14v jFXjLF+R1omwAtzj+MHh1nV5lEdncpiJP8ZepuNhipnnvi37Al2HElIP9YalSxDdjb 6B4cqH5ung2S5x5pdMf2G8eFi5NRF4dw+g7o0af8+EeIm8vDImvAGQ7SLWGE/Jf5ve 7jOnr+a7lTTaA== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 01/14] perf dwarf-aux: Add die_collect_vars() Date: Fri, 16 Feb 2024 15:54:10 -0800 Message-ID: <20240216235423.2343167-2-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org> References: <20240216235423.2343167-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791101759124824958 X-GMAIL-MSGID: 1791101759124824958 The die_collect_vars() is to find all variable information in the scope including function parameters. The struct die_var_type is to save the type of the variable with the location (reg and offset) as well as where it's defined in the code (addr). Acked-by: Masami Hiramatsu (Google) Signed-off-by: Namhyung Kim --- tools/perf/util/dwarf-aux.c | 118 +++++++++++++++++++++++++++--------- tools/perf/util/dwarf-aux.h | 17 ++++++ 2 files changed, 107 insertions(+), 28 deletions(-) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 2791126069b4..f878014c9e27 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -1136,6 +1136,40 @@ int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf) return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die)); } +#if defined(HAVE_DWARF_GETLOCATIONS_SUPPORT) || defined(HAVE_DWARF_CFI_SUPPORT) +static int reg_from_dwarf_op(Dwarf_Op *op) +{ + switch (op->atom) { + case DW_OP_reg0 ... DW_OP_reg31: + return op->atom - DW_OP_reg0; + case DW_OP_breg0 ... DW_OP_breg31: + return op->atom - DW_OP_breg0; + case DW_OP_regx: + case DW_OP_bregx: + return op->number; + default: + break; + } + return -1; +} + +static int offset_from_dwarf_op(Dwarf_Op *op) +{ + switch (op->atom) { + case DW_OP_reg0 ... DW_OP_reg31: + case DW_OP_regx: + return 0; + case DW_OP_breg0 ... DW_OP_breg31: + return op->number; + case DW_OP_bregx: + return op->number2; + default: + break; + } + return -1; +} +#endif /* HAVE_DWARF_GETLOCATIONS_SUPPORT || HAVE_DWARF_CFI_SUPPORT */ + #ifdef HAVE_DWARF_GETLOCATIONS_SUPPORT /** * die_get_var_innermost_scope - Get innermost scope range of given variable DIE @@ -1479,41 +1513,69 @@ Dwarf_Die *die_find_variable_by_addr(Dwarf_Die *sc_die, Dwarf_Addr pc, *offset = data.offset; return result; } -#endif /* HAVE_DWARF_GETLOCATIONS_SUPPORT */ -#ifdef HAVE_DWARF_CFI_SUPPORT -static int reg_from_dwarf_op(Dwarf_Op *op) +static int __die_collect_vars_cb(Dwarf_Die *die_mem, void *arg) { - switch (op->atom) { - case DW_OP_reg0 ... DW_OP_reg31: - return op->atom - DW_OP_reg0; - case DW_OP_breg0 ... DW_OP_breg31: - return op->atom - DW_OP_breg0; - case DW_OP_regx: - case DW_OP_bregx: - return op->number; - default: - break; - } - return -1; + struct die_var_type **var_types = arg; + Dwarf_Die type_die; + int tag = dwarf_tag(die_mem); + Dwarf_Attribute attr; + Dwarf_Addr base, start, end; + Dwarf_Op *ops; + size_t nops; + struct die_var_type *vt; + + if (tag != DW_TAG_variable && tag != DW_TAG_formal_parameter) + return DIE_FIND_CB_SIBLING; + + if (dwarf_attr(die_mem, DW_AT_location, &attr) == NULL) + return DIE_FIND_CB_SIBLING; + + /* + * Only collect the first location as it can reconstruct the + * remaining state by following the instructions. + * start = 0 means it covers the whole range. + */ + if (dwarf_getlocations(&attr, 0, &base, &start, &end, &ops, &nops) <= 0) + return DIE_FIND_CB_SIBLING; + + if (die_get_real_type(die_mem, &type_die) == NULL) + return DIE_FIND_CB_SIBLING; + + vt = malloc(sizeof(*vt)); + if (vt == NULL) + return DIE_FIND_CB_END; + + vt->die_off = dwarf_dieoffset(&type_die); + vt->addr = start; + vt->reg = reg_from_dwarf_op(ops); + vt->offset = offset_from_dwarf_op(ops); + vt->next = *var_types; + *var_types = vt; + + return DIE_FIND_CB_SIBLING; } -static int offset_from_dwarf_op(Dwarf_Op *op) +/** + * die_collect_vars - Save all variables and parameters + * @sc_die: a scope DIE + * @var_types: a pointer to save the resulting list + * + * Save all variables and parameters in the @sc_die and save them to @var_types. + * The @var_types is a singly-linked list containing type and location info. + * Actual type can be retrieved using dwarf_offdie() with 'die_off' later. + * + * Callers should free @var_types. + */ +void die_collect_vars(Dwarf_Die *sc_die, struct die_var_type **var_types) { - switch (op->atom) { - case DW_OP_reg0 ... DW_OP_reg31: - case DW_OP_regx: - return 0; - case DW_OP_breg0 ... DW_OP_breg31: - return op->number; - case DW_OP_bregx: - return op->number2; - default: - break; - } - return -1; + Dwarf_Die die_mem; + + die_find_child(sc_die, __die_collect_vars_cb, (void *)var_types, &die_mem); } +#endif /* HAVE_DWARF_GETLOCATIONS_SUPPORT */ +#ifdef HAVE_DWARF_CFI_SUPPORT /** * die_get_cfa - Get frame base information * @dwarf: a Dwarf info diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index 85dd527ae1f7..efafd3a1f5b6 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h @@ -135,6 +135,15 @@ void die_skip_prologue(Dwarf_Die *sp_die, Dwarf_Die *cu_die, /* Get the list of including scopes */ int die_get_scopes(Dwarf_Die *cu_die, Dwarf_Addr pc, Dwarf_Die **scopes); +/* Variable type information */ +struct die_var_type { + struct die_var_type *next; + u64 die_off; + u64 addr; + int reg; + int offset; +}; + #ifdef HAVE_DWARF_GETLOCATIONS_SUPPORT /* Get byte offset range of given variable DIE */ @@ -150,6 +159,9 @@ Dwarf_Die *die_find_variable_by_addr(Dwarf_Die *sc_die, Dwarf_Addr pc, Dwarf_Addr addr, Dwarf_Die *die_mem, int *offset); +/* Save all variables and parameters in this scope */ +void die_collect_vars(Dwarf_Die *sc_die, struct die_var_type **var_types); + #else /* HAVE_DWARF_GETLOCATIONS_SUPPORT */ static inline int die_get_var_range(Dwarf_Die *sp_die __maybe_unused, @@ -178,6 +190,11 @@ static inline Dwarf_Die *die_find_variable_by_addr(Dwarf_Die *sc_die __maybe_unu return NULL; } +static inline void die_collect_vars(Dwarf_Die *sc_die __maybe_unused, + struct die_var_type **var_types __maybe_unused) +{ +} + #endif /* HAVE_DWARF_GETLOCATIONS_SUPPORT */ #ifdef HAVE_DWARF_CFI_SUPPORT From patchwork Fri Feb 16 23:54:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 202435 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp59517dyc; Fri, 16 Feb 2024 15:55:50 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXw3mjcTa/5rSJLlI10l48oQ0HO9+qiHAzw9oqXXizrSOxGDWTKwi6w+A0hrBlVcw1Dl6ZnlqhuD99iV+nQtEvlcrYLSw== X-Google-Smtp-Source: AGHT+IHf8pMQxoQqE085gldY8zWpii09UVTZ27O4JmQzvK4NcizowInTzjtvBm5yiZRGvpBxUF6N X-Received: by 2002:a05:620a:179f:b0:787:3fb9:462e with SMTP id ay31-20020a05620a179f00b007873fb9462emr5175258qkb.0.1708127750005; Fri, 16 Feb 2024 15:55:50 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708127749; cv=pass; d=google.com; s=arc-20160816; b=x0XInezczo/PpN5sMFZOwTbYYf268xdq3d00DwobtL2a36pTKNWJSYs+/gUN9oE/k+ +hpVV0PLoAKgM5vTIMkwGc+PbF8GuREbJgbsXylczIyTmqknT0RUQnnSF5JLpwqJGpRY 80gFqS0kahqr22tj2htZPmTYOFrBNVNQx6JiGUY8GSEN4MBxlLs5yvMeuiXJXoNQxq6m 0w+EYSi5UlSdHkW5yC4oIwx6fnGsqFuPD/dCZhGjSED84IsvOUDGGf1Wi54SLkr+aHHB ClMPuUiK5OOajvQDgALY3uKfXjksNUYxCRpEUntHXVtY3AE7EUNn7IaGsVl1EgDP6xcL I/tQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=AMjn1MOHxQ47BFFvvgVpz+CYXZhZH/7Kzah8Z8XWlVI=; fh=44lErbL5kvNUjSV6UDWgBEjJyOJpjjMpxi6K+HFi+Bc=; b=kF4OcE1/ZuBGI/SkB/P2psUbeBpeIIfxEQXFA8Ey+b6JFsvSIJACf4gykuLelh7x92 GIZ4B2PYSQZ5TuYGLLzO2wNY+Rh75A8/kt4dzZY7NjRIHu0x/Ha4duCoOxR8OxrLIEuu x9OSUK4qtY6r5SKRmGhFxh6FBn9xB+wXafzwe3NCa6/+/ZExjX/SJNY/WEcD2+cu6Via dj8u9IlP24QtEA3LKAETisjsKKx87pWKWi/zzUY4l4mkOpodnI7SxYrjvtiUSaGSoK5i PCCuDbli+z7EdHG4OA/KSMM05HIQgUYvlZj7eQQZVs4aeATkYD6y9SMovNKIeksb4mFt NByA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=dj2OBKlc; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69495-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69495-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id oq18-20020a05620a611200b00787167c97cfsi1022992qkn.324.2024.02.16.15.55.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Feb 2024 15:55:49 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-69495-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=dj2OBKlc; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69495-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69495-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 3EC851C22267 for ; Fri, 16 Feb 2024 23:55:39 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id BC02E14C5A6; Fri, 16 Feb 2024 23:54:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dj2OBKlc" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 9D33514A087; Fri, 16 Feb 2024 23:54:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127666; cv=none; b=SlMN+7P0tQSoyssMlmYxOqnILdmZuSWBQhMr2SArT2ktWbI0bg3nrGOQYjoT4lpawg3DoQkhRtIa2xkwNGfu1gRl/8mLtq2fUP8+9LzaKJz5tn8fr4BqdYjlOeGL+37LrN8WN+XIVmz8ETEGa36K9FYv1IOV4XqQsyfj+sbNrSE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127666; c=relaxed/simple; bh=yYo85dqmUvjj/MYrq9h8iGZJuhDhkkgQ/jmNNXT6JHI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QLLYHfcGHi/7+GJ+ktNHyGybeqRXUlelqH+MFBFYvwRyaC2rW1s9I767dsEoSPnYW2nb/up/PIzXfpNiK7Fpmz5ziR18q2jwR+P/dRn0PK+X85WVLObs6+J1f4puYrIw73dsJtv4g+jDZquR+vQWxfhchrryFKdEmhJUQiHKAIo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dj2OBKlc; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id B49C7C43394; Fri, 16 Feb 2024 23:54:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708127666; bh=yYo85dqmUvjj/MYrq9h8iGZJuhDhkkgQ/jmNNXT6JHI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dj2OBKlcSEHwerRQs2FFVXSo6SZ6FtK8rSto1WrOtbZ+DRGo7gvzjEgf50D/MllDs 5no8ezrgD4kYDpItCLEUmRWCuup70QLmll33UzE5yvC88O2T3HJ5Qr0ltfjKqgx7IY Eloy+ilGt8jAkBiPaH1fj9biz6DrrdVD6LkRFKJjgCz0BWrBGeri51KAbkml/MH/xk IoXRitUwiy4h5ex4OWRSle21pi0eqxjhhJbfexoCQAKOaGE2UIJZOgymU7R0IVZui2 TmIokKkbNus2S1f3r/lF8bs1lXwGv2YNHg/y3KXJX5oS+5J9HXzoTR9zuIUHSCdpFi wZpVpp2LwYxRw== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 02/14] perf dwarf-aux: Handle type transfer for memory access Date: Fri, 16 Feb 2024 15:54:11 -0800 Message-ID: <20240216235423.2343167-3-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org> References: <20240216235423.2343167-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791101763486537557 X-GMAIL-MSGID: 1791101763486537557 We want to track type states as instructions are executed. Each instruction can access compound types like struct or union and load/ store its members to a different location. The die_deref_ptr_type() is to find a type of memory access with a pointer variable. If it points to a compound type like struct, the target memory is a member in the struct. The access will happen with an offset indicating which member it refers. Let's follow the DWARF info to figure out the type of the pointer target. For example, say we have the following code. struct foo { int a; int b; }; struct foo *p = malloc(sizeof(*p)); p->b = 0; The last pointer access should produce x86 asm like below: mov 0x0, 4(%rbx) And we know %rbx register has a pointer to struct foo. Then offset 4 should return the debug info of member 'b'. Also variables of compound types can be accessed directly without a pointer. The die_get_member_type() is to handle a such case. Acked-by: Masami Hiramatsu (Google) Signed-off-by: Namhyung Kim --- tools/perf/util/dwarf-aux.c | 110 ++++++++++++++++++++++++++++++++++++ tools/perf/util/dwarf-aux.h | 6 ++ 2 files changed, 116 insertions(+) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index f878014c9e27..39851ff1d5c4 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -1841,3 +1841,113 @@ int die_get_scopes(Dwarf_Die *cu_die, Dwarf_Addr pc, Dwarf_Die **scopes) *scopes = data.scopes; return data.nr; } + +static int __die_find_member_offset_cb(Dwarf_Die *die_mem, void *arg) +{ + Dwarf_Die type_die; + Dwarf_Word size, loc; + Dwarf_Word offset = (long)arg; + int tag = dwarf_tag(die_mem); + + if (tag != DW_TAG_member) + return DIE_FIND_CB_SIBLING; + + /* Unions might not have location */ + if (die_get_data_member_location(die_mem, &loc) < 0) + loc = 0; + + if (offset == loc) + return DIE_FIND_CB_END; + + die_get_real_type(die_mem, &type_die); + + if (dwarf_aggregate_size(&type_die, &size) < 0) + size = 0; + + if (loc < offset && offset < (loc + size)) + return DIE_FIND_CB_END; + + return DIE_FIND_CB_SIBLING; +} + +/** + * die_get_member_type - Return type info of struct member + * @type_die: a type DIE + * @offset: offset in the type + * @die_mem: a buffer to save the resulting DIE + * + * This function returns a type of a member in @type_die where it's located at + * @offset if it's a struct. For now, it just returns the first matching + * member in a union. For other types, it'd return the given type directly + * if it's within the size of the type or NULL otherwise. + */ +Dwarf_Die *die_get_member_type(Dwarf_Die *type_die, int offset, + Dwarf_Die *die_mem) +{ + Dwarf_Die *member; + Dwarf_Die mb_type; + int tag; + + tag = dwarf_tag(type_die); + /* If it's not a compound type, return the type directly */ + if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) { + Dwarf_Word size; + + if (dwarf_aggregate_size(type_die, &size) < 0) + size = 0; + + if ((unsigned)offset >= size) + return NULL; + + *die_mem = *type_die; + return die_mem; + } + + mb_type = *type_die; + /* TODO: Handle union types better? */ + while (tag == DW_TAG_structure_type || tag == DW_TAG_union_type) { + member = die_find_child(&mb_type, __die_find_member_offset_cb, + (void *)(long)offset, die_mem); + if (member == NULL) + return NULL; + + if (die_get_real_type(member, &mb_type) == NULL) + return NULL; + + tag = dwarf_tag(&mb_type); + + if (tag == DW_TAG_structure_type || tag == DW_TAG_union_type) { + Dwarf_Word loc; + + /* Update offset for the start of the member struct */ + if (die_get_data_member_location(member, &loc) == 0) + offset -= loc; + } + } + *die_mem = mb_type; + return die_mem; +} + +/** + * die_deref_ptr_type - Return type info for pointer access + * @ptr_die: a pointer type DIE + * @offset: access offset for the pointer + * @die_mem: a buffer to save the resulting DIE + * + * This function follows the pointer in @ptr_die with given @offset + * and saves the resulting type in @die_mem. If the pointer points + * a struct type, actual member at the offset would be returned. + */ +Dwarf_Die *die_deref_ptr_type(Dwarf_Die *ptr_die, int offset, + Dwarf_Die *die_mem) +{ + Dwarf_Die type_die; + + if (dwarf_tag(ptr_die) != DW_TAG_pointer_type) + return NULL; + + if (die_get_real_type(ptr_die, &type_die) == NULL) + return NULL; + + return die_get_member_type(&type_die, offset, die_mem); +} diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index efafd3a1f5b6..ad4d7322fcbf 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h @@ -144,6 +144,12 @@ struct die_var_type { int offset; }; +/* Return type info of a member at offset */ +Dwarf_Die *die_get_member_type(Dwarf_Die *type_die, int offset, Dwarf_Die *die_mem); + +/* Return type info where the pointer and offset point to */ +Dwarf_Die *die_deref_ptr_type(Dwarf_Die *ptr_die, int offset, Dwarf_Die *die_mem); + #ifdef HAVE_DWARF_GETLOCATIONS_SUPPORT /* Get byte offset range of given variable DIE */ From patchwork Fri Feb 16 23:54:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 202437 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp59682dyc; Fri, 16 Feb 2024 15:56:25 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXEqXVbpq4okgOfYrYynTlar7Bx61ScM4PBp9EBj+8VmUZpdjA5TesUKT0rA05/nGVubRZlkJSY95hEfTLI1mHfshs2Mw== X-Google-Smtp-Source: AGHT+IFtj/W2+tGYvncFqjN2RQjSdMGhzNqhtpMa2iw8CpwSWkphT29MQCGEl5+cfILhYoMa8BHB X-Received: by 2002:a0c:e2d2:0:b0:68c:c948:219b with SMTP id t18-20020a0ce2d2000000b0068cc948219bmr6409613qvl.20.1708127785640; Fri, 16 Feb 2024 15:56:25 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708127785; cv=pass; d=google.com; s=arc-20160816; b=uJ5QWPKq5BHin357pHIVTOAHpYO7R1sxONuuL6b1irSsT/0Kj8q6yP0NHeMU5ovu6L WQjBYoJBJqvSTJbBFrBqxsxk04MAvTJsS220zh/yltFlfBNJkm/HYAYIkmQNFEReiNQ8 lzJowiWftzZRZp5yseiny/zF/QOkY90k2WVRPKMiefGv5m3P2AY1wcEXp6cxwA3NUNQy gtbNwDU8VFSdlNEWnANG2Zr6QSQLfTXDBbj8aoI0y5Vj0m1JQF6V23YOq70gnECigLnI n1ZTF8Foj5W8BGQv4Jt6EFXgJUMRWDPF55Vy0+slAQk98SgkqHomuIdckSruW9Vth8xF Z9jQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=p53MXwINotOJMBFnfI25DU/Wc/5y744yp7PIu8NnIoU=; fh=44lErbL5kvNUjSV6UDWgBEjJyOJpjjMpxi6K+HFi+Bc=; b=X2ROHCoIwHcohI56fo5R+AqXbd3yQ9Pff6R6h+1H6OnrDo8/Gd2F6iByI0ntdcMrph 6PAALX11SSZmLIFjNm2BXvWZJeuWadiZiiJ6fr4ewTAZoeaWXi9B//ggshumBw2i/QlF iPnN+tg2wtkTlsKMQWD+oEWT0tEspOJAg3dZLw3Ou+/WnEmFvTZ9RQK3XzI5sk8Ilm1v 1XTJjXzug+Q5tjUMtatTwSyxPKSCardU6TM7bjPv+Ux/1Dnl/usZ3WjFMEgWC1fX+WI6 mwHG4M4v9muMZnz5YXskCv8O6xPyphplZ7AKXe7aV6b2UDlQJjRgiq6N2hGrvt/P/Tst x/tA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=AlTzbRBJ; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69496-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69496-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [147.75.199.223]) by mx.google.com with ESMTPS id iw3-20020a0562140f2300b0068f34850e6dsi860173qvb.596.2024.02.16.15.56.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Feb 2024 15:56:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-69496-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) client-ip=147.75.199.223; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=AlTzbRBJ; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69496-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.199.223 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69496-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 5F26B1C2157F for ; Fri, 16 Feb 2024 23:56:25 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 0AE8514E2EE; Fri, 16 Feb 2024 23:54:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="AlTzbRBJ" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 5483A14A0A4; Fri, 16 Feb 2024 23:54:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127667; cv=none; b=AzgSA6yA7gpHlg2x78KlHEMaikMCwuu4gJRu3A929UvBN39aus1QoMIkKUNIbjcCJWI7dWbWtGsbZCv0pent4aRBrxGoK6gnBOHYSwt80GUlCFLJAh3GnwChqOGIfduHwC6WoiCLyM5H6lXlm5ooy76Zc4F9EdE7Dx+KQqy3ugE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127667; c=relaxed/simple; bh=Uq6bNXvr4kGp89Uou2qipGFct50QoLkSBu5YLU+6QS8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KpBVrbhT4Z9cu2VRXQWNnE7iIebiZOP4yhwqLgPMu9iQnwuaGrrAU7Ky+Ecoe+tq7WxKPqEvGyRHe7fUCwG/+ELcUE2pM1AuejJKFwVZIozqMB1jTr8h8N0QfokdFAbzTCgZE6P+WZcbTjosYJmNR6AqR3fS23ZUjNAv1JHRITg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AlTzbRBJ; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 58E70C43609; Fri, 16 Feb 2024 23:54:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708127666; bh=Uq6bNXvr4kGp89Uou2qipGFct50QoLkSBu5YLU+6QS8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AlTzbRBJJKMD0yLEatSxoL9A/tszYeSYQG2kFNopP+lFyccWMaZHIKljKTUsRf4kn mFwIopH49aexvgyevJGeugdwz6+SwqxhxSCnSQXA/4AYR7ZnYVbbspM3pU0tExBOlI 214XGwiQHI2ShbW3vu+jtOJOjvy4CyQqbgecGn51JVK6Fs8o/IqDN8vKTtbt/uummH 3A1NgCwIl4s8yBzQUf4eSEsKsWblQmA7U7kK2O21cYy7uYHt6SxnQbDftRcT7tjaw0 /rijHWznuRd+t46QJ3zCdMeIM5h5SrUM3D2CR5G0iWLUfkS/dZ+Tx6hh55wy/eBpyd DVv1zR2hPjnbg== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 03/14] perf annotate-data: Introduce struct data_loc_info Date: Fri, 16 Feb 2024 15:54:12 -0800 Message-ID: <20240216235423.2343167-4-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org> References: <20240216235423.2343167-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791101801133943149 X-GMAIL-MSGID: 1791101801133943149 The find_data_type() needs many information to describe the location of the data. Add the new struct data_loc_info to pass those information at once. No functional changes intended. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 83 +++++++++++++++++---------------- tools/perf/util/annotate-data.h | 38 ++++++++++++--- tools/perf/util/annotate.c | 30 ++++++------ 3 files changed, 91 insertions(+), 60 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index 30c4d19fcf11..b8e60c42af8c 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -239,21 +239,28 @@ static int check_variable(Dwarf_Die *var_die, Dwarf_Die *type_die, int offset, } /* The result will be saved in @type_die */ -static int find_data_type_die(struct debuginfo *di, u64 pc, u64 addr, - const char *var_name, struct annotated_op_loc *loc, - Dwarf_Die *type_die) +static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die) { + struct annotated_op_loc *loc = dloc->op; Dwarf_Die cu_die, var_die; Dwarf_Die *scopes = NULL; int reg, offset; int ret = -1; int i, nr_scopes; int fbreg = -1; - bool is_fbreg = false; int fb_offset = 0; + bool is_fbreg = false; + u64 pc; + + /* + * IP is a relative instruction address from the start of the map, as + * it can be randomized/relocated, it needs to translate to PC which is + * a file address for DWARF processing. + */ + pc = map__rip_2objdump(dloc->ms->map, dloc->ip); /* Get a compile_unit for this address */ - if (!find_cu_die(di, pc, &cu_die)) { + if (!find_cu_die(dloc->di, pc, &cu_die)) { pr_debug("cannot find CU for address %" PRIx64 "\n", pc); ann_data_stat.no_cuinfo++; return -1; @@ -263,18 +270,19 @@ static int find_data_type_die(struct debuginfo *di, u64 pc, u64 addr, offset = loc->offset; if (reg == DWARF_REG_PC) { - if (die_find_variable_by_addr(&cu_die, pc, addr, &var_die, &offset)) { + if (die_find_variable_by_addr(&cu_die, pc, dloc->var_addr, + &var_die, &offset)) { ret = check_variable(&var_die, type_die, offset, /*is_pointer=*/false); - loc->offset = offset; + dloc->type_offset = offset; goto out; } - if (var_name && die_find_variable_at(&cu_die, var_name, pc, - &var_die)) { - ret = check_variable(&var_die, type_die, 0, + if (dloc->var_name && + die_find_variable_at(&cu_die, dloc->var_name, pc, &var_die)) { + ret = check_variable(&var_die, type_die, dloc->type_offset, /*is_pointer=*/false); - /* loc->offset will be updated by the caller */ + /* dloc->type_offset was updated by the caller */ goto out; } } @@ -291,10 +299,11 @@ static int find_data_type_die(struct debuginfo *di, u64 pc, u64 addr, dwarf_formblock(&attr, &block) == 0 && block.length == 1) { switch (*block.data) { case DW_OP_reg0 ... DW_OP_reg31: - fbreg = *block.data - DW_OP_reg0; + fbreg = dloc->fbreg = *block.data - DW_OP_reg0; break; case DW_OP_call_frame_cfa: - if (die_get_cfa(di->dbg, pc, &fbreg, + dloc->fb_cfa = true; + if (die_get_cfa(dloc->di->dbg, pc, &fbreg, &fb_offset) < 0) fbreg = -1; break; @@ -312,7 +321,7 @@ static int find_data_type_die(struct debuginfo *di, u64 pc, u64 addr, /* Search from the inner-most scope to the outer */ for (i = nr_scopes - 1; i >= 0; i--) { if (reg == DWARF_REG_PC) { - if (!die_find_variable_by_addr(&scopes[i], pc, addr, + if (!die_find_variable_by_addr(&scopes[i], pc, dloc->var_addr, &var_die, &offset)) continue; } else { @@ -325,7 +334,7 @@ static int find_data_type_die(struct debuginfo *di, u64 pc, u64 addr, /* Found a variable, see if it's correct */ ret = check_variable(&var_die, type_die, offset, reg != DWARF_REG_PC && !is_fbreg); - loc->offset = offset; + dloc->type_offset = offset; goto out; } @@ -344,50 +353,46 @@ static int find_data_type_die(struct debuginfo *di, u64 pc, u64 addr, /** * find_data_type - Return a data type at the location - * @ms: map and symbol at the location - * @ip: instruction address of the memory access - * @loc: instruction operand location - * @addr: data address of the memory access - * @var_name: global variable name + * @dloc: data location * * This functions searches the debug information of the binary to get the data - * type it accesses. The exact location is expressed by (@ip, reg, offset) - * for pointer variables or (@ip, @addr) for global variables. Note that global - * variables might update the @loc->offset after finding the start of the variable. - * If it cannot find a global variable by address, it tried to fine a declaration - * of the variable using @var_name. In that case, @loc->offset won't be updated. + * type it accesses. The exact location is expressed by (ip, reg, offset) + * for pointer variables or (ip, addr) for global variables. Note that global + * variables might update the @dloc->type_offset after finding the start of the + * variable. If it cannot find a global variable by address, it tried to find + * a declaration of the variable using var_name. In that case, @dloc->offset + * won't be updated. * * It return %NULL if not found. */ -struct annotated_data_type *find_data_type(struct map_symbol *ms, u64 ip, - struct annotated_op_loc *loc, u64 addr, - const char *var_name) +struct annotated_data_type *find_data_type(struct data_loc_info *dloc) { struct annotated_data_type *result = NULL; - struct dso *dso = map__dso(ms->map); - struct debuginfo *di; + struct dso *dso = map__dso(dloc->ms->map); Dwarf_Die type_die; - u64 pc; - di = debuginfo__new(dso->long_name); - if (di == NULL) { + dloc->di = debuginfo__new(dso->long_name); + if (dloc->di == NULL) { pr_debug("cannot get the debug info\n"); return NULL; } /* - * IP is a relative instruction address from the start of the map, as - * it can be randomized/relocated, it needs to translate to PC which is - * a file address for DWARF processing. + * The type offset is the same as instruction offset by default. + * But when finding a global variable, the offset won't be valid. */ - pc = map__rip_2objdump(ms->map, ip); - if (find_data_type_die(di, pc, addr, var_name, loc, &type_die) < 0) + if (dloc->var_name == NULL) + dloc->type_offset = dloc->op->offset; + + dloc->fbreg = -1; + + if (find_data_type_die(dloc, &type_die) < 0) goto out; result = dso__findnew_data_type(dso, &type_die); out: - debuginfo__delete(di); + debuginfo__delete(dloc->di); return result; } diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h index 1b0db8e8c40e..ad6493ea2c8e 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -8,6 +8,7 @@ #include struct annotated_op_loc; +struct debuginfo; struct evsel; struct map_symbol; @@ -72,6 +73,35 @@ struct annotated_data_type { extern struct annotated_data_type unknown_type; extern struct annotated_data_type stackop_type; +/** + * struct data_loc_info - Data location information + * @ms: Map and Symbol info + * @ip: Instruction address + * @var_addr: Data address (for global variables) + * @var_name: Variable name (for global variables) + * @op: Instruction operand location (regs and offset) + * @di: Debug info + * @fbreg: Frame base register + * @fb_cfa: Whether the frame needs to check CFA + * @type_offset: Final offset in the type + */ +struct data_loc_info { + /* These are input field, should be filled by caller */ + struct map_symbol *ms; + u64 ip; + u64 var_addr; + const char *var_name; + struct annotated_op_loc *op; + + /* These are used internally */ + struct debuginfo *di; + int fbreg; + bool fb_cfa; + + /* This is for the result */ + int type_offset; +}; + /** * struct annotated_data_stat - Debug statistics * @total: Total number of entry @@ -106,9 +136,7 @@ extern struct annotated_data_stat ann_data_stat; #ifdef HAVE_DWARF_SUPPORT /* Returns data type at the location (ip, reg, offset) */ -struct annotated_data_type *find_data_type(struct map_symbol *ms, u64 ip, - struct annotated_op_loc *loc, u64 addr, - const char *var_name); +struct annotated_data_type *find_data_type(struct data_loc_info *dloc); /* Update type access histogram at the given offset */ int annotated_data_type__update_samples(struct annotated_data_type *adt, @@ -121,9 +149,7 @@ void annotated_data_type__tree_delete(struct rb_root *root); #else /* HAVE_DWARF_SUPPORT */ static inline struct annotated_data_type * -find_data_type(struct map_symbol *ms __maybe_unused, u64 ip __maybe_unused, - struct annotated_op_loc *loc __maybe_unused, - u64 addr __maybe_unused, const char *var_name __maybe_unused) +find_data_type(struct data_loc_info *dloc __maybe_unused) { return NULL; } diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 107b264fa41e..cb5d4c517a4d 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -3788,9 +3788,7 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) struct annotated_op_loc *op_loc; struct annotated_data_type *mem_type; struct annotated_item_stat *istat; - u64 ip = he->ip, addr = 0; - const char *var_name = NULL; - int var_offset; + u64 ip = he->ip; int i; ann_data_stat.total++; @@ -3843,51 +3841,53 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) } for_each_insn_op_loc(&loc, i, op_loc) { + struct data_loc_info dloc = { + .ms = ms, + /* Recalculate IP for LOCK prefix or insn fusion */ + .ip = ms->sym->start + dl->al.offset, + .op = op_loc, + }; + if (!op_loc->mem_ref) continue; /* Recalculate IP because of LOCK prefix or insn fusion */ ip = ms->sym->start + dl->al.offset; - var_offset = op_loc->offset; - /* PC-relative addressing */ if (op_loc->reg1 == DWARF_REG_PC) { struct addr_location al; struct symbol *var; u64 map_addr; - addr = annotate_calc_pcrel(ms, ip, op_loc->offset, dl); + dloc.var_addr = annotate_calc_pcrel(ms, ip, op_loc->offset, dl); /* Kernel symbols might be relocated */ - map_addr = addr + map__reloc(ms->map); + map_addr = dloc.var_addr + map__reloc(ms->map); addr_location__init(&al); var = thread__find_symbol_fb(he->thread, he->cpumode, map_addr, &al); if (var) { - var_name = var->name; + dloc.var_name = var->name; /* Calculate type offset from the start of variable */ - var_offset = map_addr - map__unmap_ip(al.map, var->start); + dloc.type_offset = map_addr - map__unmap_ip(al.map, var->start); } addr_location__exit(&al); } - mem_type = find_data_type(ms, ip, op_loc, addr, var_name); + mem_type = find_data_type(&dloc); if (mem_type) istat->good++; else istat->bad++; - if (mem_type && var_name) - op_loc->offset = var_offset; - if (symbol_conf.annotate_data_sample) { annotated_data_type__update_samples(mem_type, evsel, - op_loc->offset, + dloc.type_offset, he->stat.nr_events, he->stat.period); } - he->mem_type_off = op_loc->offset; + he->mem_type_off = dloc.type_offset; return mem_type; } From patchwork Fri Feb 16 23:54:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 202436 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp59521dyc; Fri, 16 Feb 2024 15:55:51 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCU7Cd3UUZEx0UchSb+Die+TDgjVyt3KZIBM/MjtWnKt+RVgQEd2VIujNkJ3J5Wp4PtqkqPjuz1e+36JtLa371hhnBFZZQ== X-Google-Smtp-Source: AGHT+IFh96KW/HMci9ht6XOrYXMoifMnRKwcRlbLZTTXYm2amJBFY61RDLZ2z/Jv3x1O5rdRsOps X-Received: by 2002:a17:903:32c7:b0:1db:8c27:c24d with SMTP id i7-20020a17090332c700b001db8c27c24dmr7199191plr.50.1708127751426; Fri, 16 Feb 2024 15:55:51 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708127751; cv=pass; d=google.com; s=arc-20160816; b=lfgNBlXYVvgKZ+1tdveVaJ1+HLSxczs1p7wMVRLCD5rs1VqMS3qTN0NttFWRt0/y5B anFDf2vBPcVboOvU3CHC/HXlrpbAShC8wcenjwtW5k87mWfcbH8E4WIKzhk/cyoIeDt+ eCvvQoBzbCpKqhBbO3nm0WCLK5vfF9Ffs2JU8L0lA79TkBeZyyuVJSCrtih0lAqNAcYh 5nGIqCqZ/PHC15i6/aDrGCLk++OMH1EOlNWGouvygktfHQ20iLdzL3uDB3vpjoXMKNg2 nIbDC5Prj2fIDb+MOMZsN4pXfRFjhvdXLnG6ZvANPisEVv6SwxDXKvUn4FKnjmwV2bRk g8RA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=rbAYfhyZgqMeWRdRJHPU4rQHj2hEJ4EDQLoCK64Uk7E=; fh=44lErbL5kvNUjSV6UDWgBEjJyOJpjjMpxi6K+HFi+Bc=; b=caKr0LaG1MpCkIsOzUMIQQ8kw6dStkd/97uhoHsKWvLEWj2tuFP+im8FGLLksu/7Ve rJ0nNemfG5Nhx0f3CX9z0GTAtJkFVf1Gp6emas65oHa918pbEqrFjKf5C0iPXJ5VPoBt MFnZx9l+Qy8X2AXGFi4oYZ6syCexUJM0aNK5Bk1kOVzGwe3pMXWLdvO+ncmUeKa6X1jH EYzqSJFSDgo54zk9dKV3Eipv1o4K/pqCMl8CG7bZ8PKAEXSYDx02Iwvu8aF5tu8piZR0 mddutwbvwmdzQBe8a6+T6KNp1H8/3edjKwa6p0k7iPy6SJ+JZMju6En0tHk/lz0209NC VfiA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Av659Inu; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69497-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69497-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id kd6-20020a17090313c600b001da1d3d7971si590251plb.447.2024.02.16.15.55.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Feb 2024 15:55:51 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-69497-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=Av659Inu; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69497-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69497-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 41BE4289981 for ; Fri, 16 Feb 2024 23:55:51 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5508814D42D; Fri, 16 Feb 2024 23:54:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Av659Inu" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 A295014A0B9; Fri, 16 Feb 2024 23:54:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127667; cv=none; b=hzUFPtSK3Bn6Ityx+tunkT8JtlP2jsoDvslFmxJTXcBQfekCiWQhb22mcWtkolJWVjiOaskpNF0pZ87GTo3kHcIqfIQ63HEH8XkgUqH++RF3gT7UpWHT7lrlU32+BU0Y1bMwMVLZYhtFIHcE9p4SdYEkvkPgMbC3TVH/sw4ETUA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127667; c=relaxed/simple; bh=guWfSQhoX6jlJEUVpGGsH55EWxqQ6WRn1lYxZhtk0g8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=k73XK9EYw1hXDnbYYKaACthaV50Zdx2n8ZIZoSQE50KHi9NFXdRokJJr6fMsyHzxPpU7EX3WeJmk2fgG1DN7POF4dEUgbS3R/6y/2QccmKXLI+kX/byLKkPeZdW8YgMRCtOItK74Raq5zkAo7Vd9f/ZYjZQPml5pLKdncXbTdGQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Av659Inu; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 02993C433F1; Fri, 16 Feb 2024 23:54:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708127667; bh=guWfSQhoX6jlJEUVpGGsH55EWxqQ6WRn1lYxZhtk0g8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Av659InuKBIH1peQ3YSR4o7AnooIKjsn5U5brRDHW2BxnmzLmyEYHRjWN/G/R0gqH 4z5eRT5M6R7PRIpVHrUPsdL3S/CBBec1qaDdpWVfFSkLghSe4AVPFhxPwzvAufO9Yk niXrX9ColBgpzW4dR0Y3J7g3OWJaQkMddGl3b2UBfkAMzmVOwxrKGGujeRvtoEXqUS QlbT4dkBiQTMVvkjhShC4wTvMKDiYb+2byX4uyusPIvrxYd+DfzVd1TEDGWRRb3SI5 RB9mD6BzGIZApNhG/7MmMoNikvMPbCq422jevP+EpoCZtsqSxUZqeyMYrUvgTTdeUE DH6+I4D32Rg4Q== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 04/14] perf map: Add map__objdump_2rip() Date: Fri, 16 Feb 2024 15:54:13 -0800 Message-ID: <20240216235423.2343167-5-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org> References: <20240216235423.2343167-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791101765180262608 X-GMAIL-MSGID: 1791101765180262608 Sometimes we want to convert an address in objdump output to map-relative address to match with a sample data. Let's add map__objdump_2rip() for that. Cc: Adrian Hunter Signed-off-by: Namhyung Kim --- tools/perf/util/map.c | 17 +++++++++++++++++ tools/perf/util/map.h | 3 +++ 2 files changed, 20 insertions(+) diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 14a5ea70d81e..a5d57c201a30 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -587,6 +587,23 @@ u64 map__objdump_2mem(struct map *map, u64 ip) return ip + map__reloc(map); } +/* convert objdump address to relative address. (To be removed) */ +u64 map__objdump_2rip(struct map *map, u64 ip) +{ + const struct dso *dso = map__dso(map); + + if (!dso->adjust_symbols) + return ip; + + if (dso->rel) + return ip + map__pgoff(map); + + if (dso->kernel == DSO_SPACE__USER) + return ip - dso->text_offset; + + return map__map_ip(map, ip + map__reloc(map)); +} + bool map__contains_symbol(const struct map *map, const struct symbol *sym) { u64 ip = map__unmap_ip(map, sym->start); diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 49756716cb13..65e2609fa1b1 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -132,6 +132,9 @@ u64 map__rip_2objdump(struct map *map, u64 rip); /* objdump address -> memory address */ u64 map__objdump_2mem(struct map *map, u64 ip); +/* objdump address -> rip */ +u64 map__objdump_2rip(struct map *map, u64 ip); + struct symbol; struct thread; From patchwork Fri Feb 16 23:54:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 202439 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp59843dyc; Fri, 16 Feb 2024 15:56:59 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXyDcxaYjA4aQLx4zvxw0PK5wquFx8ms7rBzcczh0HFcWYEMZSL2Vog1NS82itM9zSKk/wrrmlZAj7r/PxPkmqu1mmgqw== X-Google-Smtp-Source: AGHT+IErzKzV3oJ7Cx5q77LpolhUFxoB0v4zhqFi2wumAsynzNhFvWAfvOh3eyvCk6NOzwP3zJcj X-Received: by 2002:a0c:cc06:0:b0:68c:e481:c099 with SMTP id r6-20020a0ccc06000000b0068ce481c099mr5869116qvk.58.1708127818915; Fri, 16 Feb 2024 15:56:58 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708127818; cv=pass; d=google.com; s=arc-20160816; b=qqR6G8QPiRHDF+xc6d389PXHlKnCpV8u7cPa894Q5kYMpO7C0fVy0W6tXbSzfFW/MU 8wxbiWEkYL3g/27ez2plA+Xqnt9BBYX9+pkKIXY5cxWwdPI+dn/EOScsgo9FnX85f3gw sVA54Q8z1Izn8/UG7W8ls9eJAQbDXnBKKtMnTRXM/jeMIfol4xGWGEKwiAXqGDh07Q15 KhvZAaWZE7i6m3qI/ScBasc02xak47+r35rg1D6+IUO04aw7jKbIn/6cVdZzdV34RT+t 4vqd/T/vzSyYI4xdIvtVaRnhDCuBEpz+Ees8QnodzAbC4UcqrIyIWx4vdpahasEftzEl C0rA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=EqgbTZPDUAREFz/NDWoHzzXNcA8fMAr4DqV7cIxMBfk=; fh=44lErbL5kvNUjSV6UDWgBEjJyOJpjjMpxi6K+HFi+Bc=; b=cezoHp9tVagJ/0e6ImYD3E9DDRoZaysUOyi7cwNf5UL9MQR05o+cTgPPDhj5kUp0iK Yc9hu4ob6gRRJ0jsi5wAK284R+7IMJsyeiv7EVFe5HTTyK/U96gfjzCMUDaL2BgvwhcL 0du8hY7nDQbQC/9btbx+dKYuAj/yz1MPQzyq1ZNiRXMd4WnrxKcro68KH+nCN9+PlD2X PkqAB7tfMXspDVOMMnfLkhLPIxTp/Eu7CNzk7EkDLnmp1xyJ75o4Pz6wOb7z36qGKg99 f+4Miub/L5gDtXP0416OGOG/YPHnxkvLq4Acp1VFxx6yXRndPl0f+W8j0yyF1O2gAETr TYsw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=ZeLCMDV7; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69498-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69498-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id iy11-20020a0562140f6b00b0068f33422207si1045429qvb.110.2024.02.16.15.56.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Feb 2024 15:56:58 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-69498-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=ZeLCMDV7; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69498-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69498-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 9F45F1C20AF2 for ; Fri, 16 Feb 2024 23:56:58 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6C2F015098C; Fri, 16 Feb 2024 23:54:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ZeLCMDV7" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 9793514A4F3; Fri, 16 Feb 2024 23:54:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127668; cv=none; b=frS1Xanpp6sFM++bMnVjWW2jdBA7B6fnjAPxuDOxKINPaKwenUKgU0tIYCSJnoQRHNd6ILHMUrW+w/qF7fI1xHTUzGjxNzX6DLQcMVGPINqf70fMF9vyYIRfTAgm+SkaXmmsXCYArwhK4BxceJKKVqu0HTBoGv+uRL2BuO0HF5M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127668; c=relaxed/simple; bh=7EAn2Z7hh95QVpxT5LLVg3XrS1iSEiXohUgQ6njH8Hg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uJDdRo58u9MrQN2TEuECg/UKcq92Z17wCavTT/xBjy5lZMB24NXtHRoJ/Oh1gDgikMMaXsyYBXofRUAODvIYuxSYN8OZfC018B7x7tHh7QinzuU7H95ZoFcHyCwho4s1hxE529R7Q9U0cne8v9yOSUYAsgl8e/A2BhplWuTfwwA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZeLCMDV7; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9DC2AC433B1; Fri, 16 Feb 2024 23:54:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708127668; bh=7EAn2Z7hh95QVpxT5LLVg3XrS1iSEiXohUgQ6njH8Hg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZeLCMDV7bHtdsFi8sCylsREmrW9tSE3m0vzGLdXQI0OC1VxfLN81/lMqFjVzT2DpS mQqvRLFyDJut08I1lYqvTfBqf2EyCzVPeC3B63aMK2CtBSILhAz/CwXEObNRhXAP6S Y6Pc3SqQOoLYjNx2VQzj0jV9euTr3TUgLqhWFCXpbxNZTlC48BBiN7IDqfPz9HHhWQ WMUSTki/oEvwNq3LcenYTN6m6tBCxXy8nv605+fn44WeeypIakSbvNzkTatIPh4toT HFN/Y76xhbe1W4AbXKR3eX2uPtVkAOGP+uZhxKiA1PD6UVw9EUx8CoCriP/JPFyG2x ej3V0tPVkmGIA== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 05/14] perf annotate: Add annotate_get_basic_blocks() Date: Fri, 16 Feb 2024 15:54:14 -0800 Message-ID: <20240216235423.2343167-6-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org> References: <20240216235423.2343167-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791101835860436781 X-GMAIL-MSGID: 1791101835860436781 The annotate_get_basic_blocks() is to find a list of basic blocks from the source instruction to the destination instruction in a function. It'll be used to find variables in a scope. Use BFS (Breadth First Search) to find a shortest path to carry the variable/register state minimally. Also change find_disasm_line() to be used in annotate_get_basic_blocks() and add 'allow_update' argument to control if it can update the IP. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate.c | 222 ++++++++++++++++++++++++++++++++++++- tools/perf/util/annotate.h | 16 +++ 2 files changed, 235 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index cb5d4c517a4d..4ef14b3f49e4 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -3686,7 +3686,8 @@ static void symbol__ensure_annotate(struct map_symbol *ms, struct evsel *evsel) } } -static struct disasm_line *find_disasm_line(struct symbol *sym, u64 ip) +static struct disasm_line *find_disasm_line(struct symbol *sym, u64 ip, + bool allow_update) { struct disasm_line *dl; struct annotation *notes; @@ -3699,7 +3700,8 @@ static struct disasm_line *find_disasm_line(struct symbol *sym, u64 ip) * llvm-objdump places "lock" in a separate line and * in that case, we want to get the next line. */ - if (!strcmp(dl->ins.name, "lock") && *dl->ops.raw == '\0') { + if (!strcmp(dl->ins.name, "lock") && + *dl->ops.raw == '\0' && allow_update) { ip++; continue; } @@ -3815,7 +3817,7 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) * Get a disasm to extract the location from the insn. * This is too slow... */ - dl = find_disasm_line(ms->sym, ip); + dl = find_disasm_line(ms->sym, ip, /*allow_update=*/true); if (dl == NULL) { ann_data_stat.no_insn++; return NULL; @@ -3909,3 +3911,217 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) istat->bad++; return NULL; } + +/* Basic block traversal (BFS) data structure */ +struct basic_block_data { + struct list_head queue; + struct list_head visited; +}; + +/* + * During the traversal, it needs to know the parent block where the current + * block block started from. Note that single basic block can be parent of + * two child basic blocks (in case of condition jump). + */ +struct basic_block_link { + struct list_head node; + struct basic_block_link *parent; + struct annotated_basic_block *bb; +}; + +/* Check any of basic block in the list already has the offset */ +static bool basic_block_has_offset(struct list_head *head, s64 offset) +{ + struct basic_block_link *link; + + list_for_each_entry(link, head, node) { + s64 begin_offset = link->bb->begin->al.offset; + s64 end_offset = link->bb->end->al.offset; + + if (begin_offset <= offset && offset <= end_offset) + return true; + } + return false; +} + +static bool is_new_basic_block(struct basic_block_data *bb_data, + struct disasm_line *dl) +{ + s64 offset = dl->al.offset; + + if (basic_block_has_offset(&bb_data->visited, offset)) + return false; + if (basic_block_has_offset(&bb_data->queue, offset)) + return false; + return true; +} + +/* Add a basic block starting from dl and link it to the parent */ +static int add_basic_block(struct basic_block_data *bb_data, + struct basic_block_link *parent, + struct disasm_line *dl) +{ + struct annotated_basic_block *bb; + struct basic_block_link *link; + + if (dl == NULL) + return -1; + + if (!is_new_basic_block(bb_data, dl)) + return 0; + + bb = zalloc(sizeof(*bb)); + if (bb == NULL) + return -1; + + bb->begin = dl; + bb->end = dl; + INIT_LIST_HEAD(&bb->list); + + link = malloc(sizeof(*link)); + if (link == NULL) { + free(bb); + return -1; + } + + link->bb = bb; + link->parent = parent; + list_add_tail(&link->node, &bb_data->queue); + return 0; +} + +/* Returns true when it finds the target in the current basic block */ +static bool process_basic_block(struct basic_block_data *bb_data, + struct basic_block_link *link, + struct symbol *sym, u64 target) +{ + struct disasm_line *dl, *next_dl, *last_dl; + struct annotation *notes = symbol__annotation(sym); + bool found = false; + + dl = link->bb->begin; + /* Check if it's already visited */ + if (basic_block_has_offset(&bb_data->visited, dl->al.offset)) + return false; + + last_dl = list_last_entry(¬es->src->source, + struct disasm_line, al.node); + + list_for_each_entry_from(dl, ¬es->src->source, al.node) { + /* Found the target instruction */ + if (sym->start + dl->al.offset == target) { + found = true; + break; + } + /* End of the function, finish the block */ + if (dl == last_dl) + break; + /* 'return' instruction finishes the block */ + if (dl->ins.ops == &ret_ops) + break; + /* normal instructions are part of the basic block */ + if (dl->ins.ops != &jump_ops) + continue; + /* jump to a different function, tail call or return */ + if (dl->ops.target.outside) + break; + /* jump instruction creates new basic block(s) */ + next_dl = find_disasm_line(sym, sym->start + dl->ops.target.offset, + /*allow_update=*/false); + add_basic_block(bb_data, link, next_dl); + + /* + * FIXME: determine conditional jumps properly. + * Conditional jumps create another basic block with the + * next disasm line. + */ + if (!strstr(dl->ins.name, "jmp")) { + next_dl = list_next_entry(dl, al.node); + add_basic_block(bb_data, link, next_dl); + } + break; + + } + link->bb->end = dl; + return found; +} + +/* + * It founds a target basic block, build a proper linked list of basic blocks + * by following the link recursively. + */ +static void link_found_basic_blocks(struct basic_block_link *link, + struct list_head *head) +{ + while (link) { + struct basic_block_link *parent = link->parent; + + list_move(&link->bb->list, head); + list_del(&link->node); + free(link); + + link = parent; + } +} + +static void delete_basic_blocks(struct basic_block_data *bb_data) +{ + struct basic_block_link *link, *tmp; + + list_for_each_entry_safe(link, tmp, &bb_data->queue, node) { + list_del(&link->node); + free(link->bb); + free(link); + } + + list_for_each_entry_safe(link, tmp, &bb_data->visited, node) { + list_del(&link->node); + free(link->bb); + free(link); + } +} + +/** + * annotate_get_basic_blocks - Get basic blocks for given address range + * @sym: symbol to annotate + * @src: source address + * @dst: destination address + * @head: list head to save basic blocks + * + * This function traverses disasm_lines from @src to @dst and save them in a + * list of annotated_basic_block to @head. It uses BFS to find the shortest + * path between two. The basic_block_link is to maintain parent links so + * that it can build a list of blocks from the start. + */ +int annotate_get_basic_blocks(struct symbol *sym, s64 src, s64 dst, + struct list_head *head) +{ + struct basic_block_data bb_data = { + .queue = LIST_HEAD_INIT(bb_data.queue), + .visited = LIST_HEAD_INIT(bb_data.visited), + }; + struct basic_block_link *link; + struct disasm_line *dl; + int ret = -1; + + dl = find_disasm_line(sym, src, /*allow_update=*/false); + if (dl == NULL) + return -1; + + if (add_basic_block(&bb_data, /*parent=*/NULL, dl) < 0) + return -1; + + /* Find shortest path from src to dst using BFS */ + while (!list_empty(&bb_data.queue)) { + link = list_first_entry(&bb_data.queue, struct basic_block_link, node); + + if (process_basic_block(&bb_data, link, sym, dst)) { + link_found_basic_blocks(link, head); + ret = 0; + break; + } + list_move(&link->node, &bb_data.visited); + } + delete_basic_blocks(&bb_data); + return ret; +} diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 94435607c958..83afbe294ab7 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -495,4 +495,20 @@ extern struct list_head ann_insn_stat; u64 annotate_calc_pcrel(struct map_symbol *ms, u64 ip, int offset, struct disasm_line *dl); +/** + * struct annotated_basic_block - Basic block of instructions + * @list: List node + * @begin: start instruction in the block + * @end: end instruction in the block + */ +struct annotated_basic_block { + struct list_head list; + struct disasm_line *begin; + struct disasm_line *end; +}; + +/* Get a list of basic blocks from src to dst addresses */ +int annotate_get_basic_blocks(struct symbol *sym, s64 src, s64 dst, + struct list_head *head); + #endif /* __PERF_ANNOTATE_H */ From patchwork Fri Feb 16 23:54:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 202438 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp59825dyc; Fri, 16 Feb 2024 15:56:54 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXEuxVnXfibjJZhQS5n/v8pvps1AEcsd4RBVtITETVTFKixTg8SLn9Iv33xsVfKMbqgZ9BjwaiNF5uenspKutkOwRWOUw== X-Google-Smtp-Source: AGHT+IFk+Epq5tL7dLA5vhETJnSIMQHoO2ZrbED4Lt8qLPMu0y6J1QxobUZoWNXvMq6IemX5kjAY X-Received: by 2002:a50:ec85:0:b0:564:121e:5c0 with SMTP id e5-20020a50ec85000000b00564121e05c0mr800698edr.27.1708127814035; Fri, 16 Feb 2024 15:56:54 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708127814; cv=pass; d=google.com; s=arc-20160816; b=FhHgr34VblfPYKQWj/WyWxcKgntSQvadQowcE2X2uscqfsZbv2K1cvQPBcWFUqqNJs I6QhmvPLvrtA6xIPWyZKwUWfyI1mSXvylz6jeGG7cWPvR4/WpL4c46l+QQq7uuKDCOkA vVEFioIVtnVF1720sBqks0cvVmPYxgawIBEpPwUfGwU9pNGuwn0Ps1RzHimhriWIDELK HKCMWlqxn0JMPx+FyXEuY0KSra3dBR8qYS5iSFHanmVM5rATT4eDwhklKlSVc09Vcwwt qPihCrJU2bPQO84BRDpITCO8pnho3eejhfSRiktc7POepp0K/h+yl7paelvA1T9wtb5z kKGQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=2AljVG6KKhqCc5EoWiOBlVVI8InCCq523Ju+6LANSno=; fh=44lErbL5kvNUjSV6UDWgBEjJyOJpjjMpxi6K+HFi+Bc=; b=qXWNEAK2KwpuzPw7JercExM2ndWsKqeTvp/ckZ/J4C66ux3GwDGPj+Fm5zcWYxpxQL R96+2OODk8ywiMR7vMKRYJT2bUwNJwJTTfeVEYDA2yXqekm+cwRTAZ7KbQvzwEkNWaIu kQVfp9VW8zoh4cvG3Mn3XRRmcNG5ycT6APDIFQZ7DsmAdXTi8wRWSsdWltHk2HMIXz7K 5tyMsUwYCPHFdHLZj+Yz/3yvVIwjl8W11j7nWkNvNezoOyruTEEZs9jn+mieah5sBMnp cTejj9RLlDjuJ64CwpimuM34tvljgB4t8AENZrTr/Lcr3mBn8goZQSxc7Kjb0WeJjr4C EfXw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=SZtMVSoT; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69499-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69499-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id co28-20020a0564020c1c00b0056409ad3958si390574edb.277.2024.02.16.15.56.53 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Feb 2024 15:56:54 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-69499-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=SZtMVSoT; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69499-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69499-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 36B0E1F2184F for ; Fri, 16 Feb 2024 23:56:53 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3E52614F9FE; Fri, 16 Feb 2024 23:54:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="SZtMVSoT" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 DB52B14AD12; Fri, 16 Feb 2024 23:54:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127669; cv=none; b=Ty1NDCaiK/y1UYbNrqzGE++F9y6l6Paix/P1MPEQG4OeJLMTKcCPCb/yfbEYMgUxe1GV7CACH87+licoM76alKEKYpFUArjS2yNq5hgnO8UdBLkNdSUzWk5rfQLkkC5gMQvT6gofuEG1XcviacPmE8+Wj1yNmr8LeubkfQ5WDVY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127669; c=relaxed/simple; bh=eSM/+Sxgv8mx5E2cIdXWdLARV/iN60h+68eiZpB+exQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NE+zryffkGHqm7RcjxVVcnxqx0nrCrMFWA3XZysWwUqKxyEmGS4i7KSfzoczN5n1GkXdMZ+nWaNeENAdWZd3DgTe5dFAS5lfOw9NA4OpV/tDHJp3Q1SOQUk8HJ0CKfw7oNYF4cQyFDhTLQiPFeqvAuq2lHUt/8DwNVgBjUFpOLE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SZtMVSoT; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 414A3C43399; Fri, 16 Feb 2024 23:54:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708127668; bh=eSM/+Sxgv8mx5E2cIdXWdLARV/iN60h+68eiZpB+exQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SZtMVSoT06QzBYligpAPGL6iZHXBO/ugGVASvjx5gb+i4i6s226UQu1/jJ9Q4MU4Z c67rEzQGPBbAvdvQoY9snrYXWTL/Hwt1jkgR2DnxvJY9jPAxVm2s2hSRgPQOl5sCim CciVu7/w49SU0wFrZBZT+AnL/OvpTHqiUdqnzfVrK8JknzVSsckzqvTsVsmdSxYWgC 5exoQu2H4Iw/sjoq7Cn1ks7k7wQ0SvIOrESF2KPATJJOOhvuu9vMSq7b0cK6khAnQX cl8LbC7IN9RO4MXaoQ5F4lTv5L5ClE0bVP7grRBN9agjd3lzkN94av0ED4HFKV/Co0 /v1jiQZJPi/+A== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 06/14] perf annotate-data: Maintain variable type info Date: Fri, 16 Feb 2024 15:54:15 -0800 Message-ID: <20240216235423.2343167-7-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org> References: <20240216235423.2343167-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791101830308704859 X-GMAIL-MSGID: 1791101830308704859 As it collected basic block and variable information in each scope, it now can build a state table to find matching variable at the location. The struct type_state is to keep the type info saved in each register and stack slot. The update_var_state() updates the table when it finds variables in the current address. It expects die_collect_vars() filled a list of variables with type info and starting address. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 155 ++++++++++++++++++++++++++++++++ tools/perf/util/annotate-data.h | 29 ++++++ tools/perf/util/dwarf-aux.c | 4 + 3 files changed, 188 insertions(+) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index b8e60c42af8c..f8768c224bcc 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -23,6 +23,57 @@ #include "symbol.h" #include "symbol_conf.h" +/* Type information in a register, valid when ok is true */ +struct type_state_reg { + Dwarf_Die type; + bool ok; + bool scratch; +}; + +/* 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; +}; + +/* 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 { + struct type_state_reg regs[TYPE_STATE_MAX_REGS]; + struct list_head stack_vars; +}; + +static bool has_reg_type(struct type_state *state, int reg) +{ + return (unsigned)reg < ARRAY_SIZE(state->regs); +} + +void init_type_state(struct type_state *state, struct arch *arch __maybe_unused) +{ + memset(state, 0, sizeof(*state)); + INIT_LIST_HEAD(&state->stack_vars); +} + +void exit_type_state(struct type_state *state) +{ + struct type_state_stack *stack, *tmp; + + list_for_each_entry_safe(stack, tmp, &state->stack_vars, list) { + list_del(&stack->list); + free(stack); + } +} + /* * Compare type name and size to maintain them in a tree. * I'm not sure if DWARF would have information of a single type in many @@ -238,6 +289,110 @@ static int check_variable(Dwarf_Die *var_die, Dwarf_Die *type_die, int offset, return 0; } +static struct type_state_stack *find_stack_state(struct type_state *state, + int offset) +{ + struct type_state_stack *stack; + + list_for_each_entry(stack, &state->stack_vars, list) { + if (offset == stack->offset) + return stack; + + if (stack->compound && stack->offset < offset && + offset < stack->offset + stack->size) + return stack; + } + return NULL; +} + +static void set_stack_state(struct type_state_stack *stack, int offset, + Dwarf_Die *type_die) +{ + int tag; + Dwarf_Word size; + + if (dwarf_aggregate_size(type_die, &size) < 0) + size = 0; + + tag = dwarf_tag(type_die); + + stack->type = *type_die; + stack->size = size; + stack->offset = offset; + + switch (tag) { + case DW_TAG_structure_type: + case DW_TAG_union_type: + stack->compound = true; + break; + default: + stack->compound = false; + break; + } +} + +static struct type_state_stack *findnew_stack_state(struct type_state *state, + int offset, Dwarf_Die *type_die) +{ + struct type_state_stack *stack = find_stack_state(state, offset); + + if (stack) { + set_stack_state(stack, offset, type_die); + return stack; + } + + stack = malloc(sizeof(*stack)); + if (stack) { + set_stack_state(stack, offset, type_die); + list_add(&stack->list, &state->stack_vars); + } + return stack; +} + +/** + * update_var_state - Update type state using given variables + * @state: type state table + * @dloc: data location info + * @addr: instruction address to update + * @var_types: list of variables with type info + * + * This function fills the @state table using @var_types info. Each variable + * is used only at the given location and updates an entry in the table. + */ +void update_var_state(struct type_state *state, struct data_loc_info *dloc, + u64 addr, struct die_var_type *var_types) +{ + Dwarf_Die mem_die; + struct die_var_type *var; + int fbreg = dloc->fbreg; + int fb_offset = 0; + + if (dloc->fb_cfa) { + if (die_get_cfa(dloc->di->dbg, addr, &fbreg, &fb_offset) < 0) + fbreg = -1; + } + + for (var = var_types; var != NULL; var = var->next) { + if (var->addr != addr) + continue; + /* Get the type DIE using the offset */ + if (!dwarf_offdie(dloc->di->dbg, var->die_off, &mem_die)) + continue; + + if (var->reg == DWARF_REG_FB) { + findnew_stack_state(state, var->offset, &mem_die); + } else if (var->reg == fbreg) { + findnew_stack_state(state, var->offset - fb_offset, &mem_die); + } else if (has_reg_type(state, var->reg)) { + struct type_state_reg *reg; + + reg = &state->regs[var->reg]; + reg->type = mem_die; + reg->ok = true; + } + } +} + /* The result will be saved in @type_die */ static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die) { diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h index ad6493ea2c8e..7fbb9eb2e96f 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -8,9 +8,12 @@ #include struct annotated_op_loc; +struct arch; struct debuginfo; +struct die_var_type; struct evsel; struct map_symbol; +struct type_state; /** * struct annotated_member - Type of member field @@ -146,6 +149,16 @@ int annotated_data_type__update_samples(struct annotated_data_type *adt, /* Release all data type information in the tree */ void annotated_data_type__tree_delete(struct rb_root *root); +/* Initialize type state table */ +void init_type_state(struct type_state *state, struct arch *arch); + +/* Destroy type state table */ +void exit_type_state(struct type_state *state); + +/* Update type state table using variables */ +void update_var_state(struct type_state *state, struct data_loc_info *dloc, + u64 addr, struct die_var_type *var_types); + #else /* HAVE_DWARF_SUPPORT */ static inline struct annotated_data_type * @@ -168,6 +181,22 @@ static inline void annotated_data_type__tree_delete(struct rb_root *root __maybe { } +static inline void init_type_state(struct type_state *state __maybe_unused, + struct arch *arch __maybe_unused) +{ +} + +static inline void exit_type_state(struct type_state *state __maybe_unused) +{ +} + +static inline void update_var_state(struct type_state *state __maybe_unused, + struct data_loc_info *dloc __maybe_unused, + u64 addr __maybe_unused, + struct die_var_type *var_types __maybe_unused) +{ +} + #endif /* HAVE_DWARF_SUPPORT */ #endif /* _PERF_ANNOTATE_DATA_H */ diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 39851ff1d5c4..f88a8fb4a350 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -9,6 +9,7 @@ #include #include "debug.h" #include "dwarf-aux.h" +#include "dwarf-regs.h" #include "strbuf.h" #include "string2.h" @@ -1147,6 +1148,8 @@ static int reg_from_dwarf_op(Dwarf_Op *op) case DW_OP_regx: case DW_OP_bregx: return op->number; + case DW_OP_fbreg: + return DWARF_REG_FB; default: break; } @@ -1160,6 +1163,7 @@ static int offset_from_dwarf_op(Dwarf_Op *op) case DW_OP_regx: return 0; case DW_OP_breg0 ... DW_OP_breg31: + case DW_OP_fbreg: return op->number; case DW_OP_bregx: return op->number2; From patchwork Fri Feb 16 23:54:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 202440 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp59973dyc; Fri, 16 Feb 2024 15:57:23 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCX+V2FmtO71LlsXlQ3YcXDwQzN/fsUnDsUk/szP/Xu2iRG46Ah9CvnK71cj79KlvmBGkMBM8P7xIvCxn7/2xQo7wlM9xw== X-Google-Smtp-Source: AGHT+IEOvv1+tvKDv6Jin1YA5FSrNBtu8sfzkf+QqbvB0yGaYaFUIez7zRjgOvvrADPSgwLVoYqD X-Received: by 2002:a17:906:68ca:b0:a3d:b822:1287 with SMTP id y10-20020a17090668ca00b00a3db8221287mr2776452ejr.67.1708127843401; Fri, 16 Feb 2024 15:57:23 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708127843; cv=pass; d=google.com; s=arc-20160816; b=tIknujZvMbWwCzwusFfBPmWo6Q1G2Z178RqcejxUyPtvH9IrwBhJCRo55YKCinL1xF Ii9uQfUBh/Oxo0sDcTnh/5CsRY7EwNJI6Tb4gbIw2UE8Nka1Dh/zXQbbhB3/vGu+2njd b8+nQ1wJSfPJxsTra8YrvEFZdRAami/CpsdiKyTOsIR+0xMluEEnNF9IBG+ciUhEv207 WXYTzbO85qEf30glGAGtDMdMUnsn0O57rnpAIZbNpFQ6n1mY4zujgSdaiBkCWZwvCwzj wzCln+H9NXsJVG56Wc5IlYwKUkR9mmbohJN+WDKoCqpbhdsEQMB6clszOOc2MjZvr8Qs +RfQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=aVQAmi2sSTt4Yumd4m8L37d19h/9ZtgotG9/V4lF1xE=; fh=44lErbL5kvNUjSV6UDWgBEjJyOJpjjMpxi6K+HFi+Bc=; b=h3tiCrsIzra4acUkqk5FzqdiShOeztVGikTU5jHSHG2/oFhzkfqDm9DOugyVmYfhUA YJBft/lVqE5HD2lCMSWAgbLb4xW7JkniAW/6JwmrkvQ/2JyH6Rpc9D8NWlDSlm8bGp0f jdxdES2PWKZEoKwFp+OboNegTajbnPWgvN+rSl4717OuVD/Ak/gdZp7J9ZxzArbETOdd 9rY0qAMbq5Hb8vUPGGsk05p/iDfQBM1bIXUVMsaxnpwgBHApTNUXYlv+WURak86O3gSC FENKLSji0ldVIJRamZPhoP/sIKMKUChk4xpggh7fFkVGgO6ARC4hFLN5gxt5iFFczoKZ 6gzg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="VmV/yUso"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69500-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69500-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id ay4-20020a170906d28400b00a3d41bd0afasi345212ejb.907.2024.02.16.15.57.23 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Feb 2024 15:57:23 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-69500-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="VmV/yUso"; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69500-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69500-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id D43DD1F216EF for ; Fri, 16 Feb 2024 23:57:22 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 40B6D151CC2; Fri, 16 Feb 2024 23:54:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="VmV/yUso" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 8341714C589; Fri, 16 Feb 2024 23:54:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127669; cv=none; b=RHkmJm6S2TY2v1iBpy/BFx/Uz2v+vVfH+YiyBc9ZKe4KaBJXXFFLtG7xVqmI8luheFsUwx1gmvURsjEqSvVjVbEOD62UxtcDsynzeKkrOHKCZJlsArTsxSyllhQ2rXu3vCOnN6yEdlABTJzKBanw9KP7wPvB11NeeNezHW/qyfM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127669; c=relaxed/simple; bh=LZgtF1cN7v1cB/kC9ZwKwA1r5hlpoAXLKbeHZPP2G0U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UJC0cpvEympnYR9A18alNglD4SRPF9xRE01XRxUi0l7A8GvYTiWKQVsvof5s/eXvxvAX0dvUAsP29dh7Vm0QOP2PJPVMRCoEB1TayTArL5lP1iDq1HrbftESOrHptcDzEJRVbxO15mQn1BJ0FINXjq+Vmeokb9V2TcLkYqhoYC0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VmV/yUso; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id D9398C43601; Fri, 16 Feb 2024 23:54:28 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708127669; bh=LZgtF1cN7v1cB/kC9ZwKwA1r5hlpoAXLKbeHZPP2G0U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VmV/yUso96Fj3kVWMUAkerJtrZCGtaIcBw7PSCkIUOhF2zT46L1UnMFLl3gip/EPW wCh50zPJQN+0iqIPQ6cmxNCpBFenXGH5RdySTht69jo9nCXk7QSABgUrOiD0fCwOMC /bJuPvFb3QRLRoBsaP1vpeBhBd99BEbGbKV7eMZYNNfqeuVJgxDor3F9pdD0U5bRZo gTiY2IHIiCfiPcC1RZMgXUhHiOZ9DU0pq3pGaWyL8gQrRmRKN7EkmQdVaOpAC+ZgPV y+/I3P3DVR3ggOo6Mh0a/w6YFAZyhN6vnYcA3DctnyO+rlSC8RDrNKc+hIFPXzuY8N NtVb7IZsn8GOg== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 07/14] perf annotate-data: Add update_insn_state() Date: Fri, 16 Feb 2024 15:54:16 -0800 Message-ID: <20240216235423.2343167-8-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org> References: <20240216235423.2343167-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791101861598127231 X-GMAIL-MSGID: 1791101861598127231 The update_insn_state() function is to update the type state table after processing each instruction. For now, it handles MOV (on x86) insn to transfer type info from the source location to the target. The location can be a register or a stack slot. Check carefully when memory reference happens and fetch the type correctly. It basically ignores write to a memory since it doesn't change the type info. One exception is writes to (new) stack slots for register spilling. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 128 +++++++++++++++++++++++++++++++- tools/perf/util/annotate-data.h | 13 ++++ tools/perf/util/annotate.c | 1 + 3 files changed, 140 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index f8768c224bcc..b1e921663452 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -27,7 +27,6 @@ struct type_state_reg { Dwarf_Die type; bool ok; - bool scratch; }; /* Type information in a stack location, dynamically allocated */ @@ -383,7 +382,7 @@ void update_var_state(struct type_state *state, struct data_loc_info *dloc, findnew_stack_state(state, var->offset, &mem_die); } else if (var->reg == fbreg) { findnew_stack_state(state, var->offset - fb_offset, &mem_die); - } else if (has_reg_type(state, var->reg)) { + } else if (has_reg_type(state, var->reg) && var->offset == 0) { struct type_state_reg *reg; reg = &state->regs[var->reg]; @@ -393,6 +392,131 @@ void update_var_state(struct type_state *state, struct data_loc_info *dloc, } } +/** + * update_insn_state - Update type state for an instruction + * @state: type state table + * @dloc: data location info + * @dl: disasm line for the instruction + * + * This function updates the @state table for the target operand of the + * instruction at @dl if it transfers the type like MOV on x86. Since it + * tracks the type, it won't care about the values like in arithmetic + * instructions like ADD/SUB/MUL/DIV and INC/DEC. + * + * Note that ops->reg2 is only available when both mem_ref and multi_regs + * are true. + */ +void update_insn_state(struct type_state *state, struct data_loc_info *dloc, + struct disasm_line *dl) +{ + struct annotated_insn_loc loc; + struct annotated_op_loc *src = &loc.ops[INSN_OP_SOURCE]; + struct annotated_op_loc *dst = &loc.ops[INSN_OP_TARGET]; + Dwarf_Die type_die; + int fbreg = dloc->fbreg; + int fboff = 0; + + /* FIXME: remove x86 specific code and handle more instructions like LEA */ + if (!strstr(dl->ins.name, "mov")) + return; + + if (annotate_get_insn_location(dloc->arch, dl, &loc) < 0) + return; + + if (dloc->fb_cfa) { + u64 ip = dloc->ms->sym->start + dl->al.offset; + u64 pc = map__rip_2objdump(dloc->ms->map, ip); + + if (die_get_cfa(dloc->di->dbg, pc, &fbreg, &fboff) < 0) + fbreg = -1; + } + + /* Case 1. register to register transfers */ + if (!src->mem_ref && !dst->mem_ref) { + if (!has_reg_type(state, dst->reg1)) + return; + + if (has_reg_type(state, src->reg1)) + state->regs[dst->reg1] = state->regs[src->reg1]; + else + state->regs[dst->reg1].ok = false; + } + /* Case 2. memory to register transers */ + if (src->mem_ref && !dst->mem_ref) { + int sreg = src->reg1; + + if (!has_reg_type(state, dst->reg1)) + return; + +retry: + /* Check stack variables with offset */ + if (sreg == fbreg) { + struct type_state_stack *stack; + int offset = src->offset - fboff; + + stack = find_stack_state(state, offset); + if (stack && die_get_member_type(&stack->type, + offset - stack->offset, + &type_die)) { + state->regs[dst->reg1].type = type_die; + state->regs[dst->reg1].ok = true; + } else + state->regs[dst->reg1].ok = false; + } + /* And then dereference the pointer if it has one */ + else if (has_reg_type(state, sreg) && state->regs[sreg].ok && + die_deref_ptr_type(&state->regs[sreg].type, + src->offset, &type_die)) { + state->regs[dst->reg1].type = type_die; + state->regs[dst->reg1].ok = true; + } + /* Or try another register if any */ + else if (src->multi_regs && sreg == src->reg1 && + src->reg1 != src->reg2) { + sreg = src->reg2; + goto retry; + } + /* It failed to get a type info, mark it as invalid */ + else { + state->regs[dst->reg1].ok = 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 == fbreg) { + struct type_state_stack *stack; + int offset = dst->offset - fboff; + + stack = 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, + &state->regs[src->reg1].type); + } else { + findnew_stack_state(state, offset, + &state->regs[src->reg1].type); + } + } + /* + * 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) */ +} + /* The result will be saved in @type_die */ static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die) { diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h index 7fbb9eb2e96f..ff9acf6ea808 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -11,6 +11,7 @@ struct annotated_op_loc; struct arch; struct debuginfo; struct die_var_type; +struct disasm_line; struct evsel; struct map_symbol; struct type_state; @@ -78,6 +79,7 @@ extern struct annotated_data_type stackop_type; /** * struct data_loc_info - Data location information + * @arch: architecture info * @ms: Map and Symbol info * @ip: Instruction address * @var_addr: Data address (for global variables) @@ -90,6 +92,7 @@ extern struct annotated_data_type stackop_type; */ struct data_loc_info { /* These are input field, should be filled by caller */ + struct arch *arch; struct map_symbol *ms; u64 ip; u64 var_addr; @@ -159,6 +162,10 @@ void exit_type_state(struct type_state *state); void update_var_state(struct type_state *state, struct data_loc_info *dloc, u64 addr, struct die_var_type *var_types); +/* Update type state table for an instruction */ +void update_insn_state(struct type_state *state, struct data_loc_info *dloc, + struct disasm_line *dl); + #else /* HAVE_DWARF_SUPPORT */ static inline struct annotated_data_type * @@ -197,6 +204,12 @@ static inline void update_var_state(struct type_state *state __maybe_unused, { } +static inline void update_insn_state(struct type_state *state __maybe_unused, + struct data_loc_info *dloc __maybe_unused, + struct disasm_line *dl __maybe_unused) +{ +} + #endif /* HAVE_DWARF_SUPPORT */ #endif /* _PERF_ANNOTATE_DATA_H */ diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 4ef14b3f49e4..44574056d4bd 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -3844,6 +3844,7 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) for_each_insn_op_loc(&loc, i, op_loc) { struct data_loc_info dloc = { + .arch = arch, .ms = ms, /* Recalculate IP for LOCK prefix or insn fusion */ .ip = ms->sym->start + dl->al.offset, From patchwork Fri Feb 16 23:54:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 202458 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp69230dyc; Fri, 16 Feb 2024 16:18:53 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVFanGUKk4o91Z+1nvv5Xp6Nrm7Cb+qjYLV77LREb5hHE++ch12i3GqDrags8+ozisgA5hyG7AS8uOLcBQeiHIAwWDOeg== X-Google-Smtp-Source: AGHT+IGSSmdk9uKFlv/K4nyeMg7+Y6z+F2BV9V8L22rjDqm0ki+18ZnrwY8kml8BrDNZbaBgvs53 X-Received: by 2002:a05:6358:2627:b0:179:20bb:d0b6 with SMTP id l39-20020a056358262700b0017920bbd0b6mr7374047rwc.6.1708129132810; Fri, 16 Feb 2024 16:18:52 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708129132; cv=pass; d=google.com; s=arc-20160816; b=mhhBbEbIQ9IpqMBZjIdP8UwzxcKI5RfY026u0+9BsY72UIhxwEshGw7lGCXOtedEl6 N/uTw9139RgA6mG+lxYTB3jKqguhEbi3VOlj/n3oQxIiJPvwv1A1C1RxdNpDcp7aNJsn smqUeGZYypDqPFZ6Hfl4/6Yos1Duqa1fHIduI5jC0Yiv13XSBjJ4jMX+llByBpaY6fGw CMTOivfzxD9vjXCmnGXF7IyuC7uBUkvbOyuRZmXHyTsWb925dfIZBp/r2ke3BMEMf5Cy sQLQ/kPlNcMIIi0cjGhT7Lrh4Bl83bk8K5Ox6GkqmvBCVf4spy22bv5epyQd4Vrmolvm avJQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=/Ayd1PcygyYKv/ZlqfFNyq404V9tIao1xZ8G4tIRr7U=; fh=44lErbL5kvNUjSV6UDWgBEjJyOJpjjMpxi6K+HFi+Bc=; b=ld3Jh+AgjiJ8Kfebq3fU20FTtu+rCi8lymn7Zcz+04oW+cASB4UtdYUINyEx1UOHEL t7I8q/svR5O2y+bcekXSetuy3h14FaSfQLUdbBmAh3gC70OW+Zx3gS+gaEv1eFCUx4ud mK9OK6n+S0SB4QmNWJR1FJD8BF/G2JuyXe7eiXI/Q0uVv4JMmqMV3tug/RJPjpu1DVpR av/kJhTYwGhMXdloJNZmIEckOu5tnNPDldsPKmZAllOKHMQJs6XPKoOnwXb+v8GLjFp2 C/S22+3V1Ok5t6G681l8C0BbYqDwUREFbBYuzq8s6rxHJrtzGZd+xIC8l2xSQbjSm2+n 6tYA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=hO2TBk0Q; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69501-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69501-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id s193-20020a6377ca000000b005d8e320fea9si627213pgc.112.2024.02.16.16.18.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Feb 2024 16:18:52 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-69501-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=hO2TBk0Q; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69501-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69501-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 9894AB26C04 for ; Fri, 16 Feb 2024 23:57:23 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 446A3151CC3; Fri, 16 Feb 2024 23:54:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hO2TBk0Q" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 2407F14C5B7; Fri, 16 Feb 2024 23:54:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127670; cv=none; b=csPh6MuXYkq6PGoasZc3KLHM8X9onvtuyrAiHIIDh4QCfsuC0J/FWevepGjGaMidE50AwUhEXzs0155+01nE5kbarmIpnRjOW+XE/Y7YvKacu7SMYNtdN31c/oPFLhOIr9XoMiRLlFkt8ZLeqISv7V1hWXy4O5/pJ6KqewavZwI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127670; c=relaxed/simple; bh=PrQxE5dvr8+mJjo6e46jyPhkqtx2vS84G0Ikoy+xe+0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hXpXa6eqRZqu7OfMsoBywoadCQGDDsezHwBzARn2ZxGrlfHss/Guhd74gaKVWSMmCCCjYBDE5MPAqxYhFHSYiTyj1ba+C5dIoertN0o3txkVvyswx0zalOTVJ+YU6pM6Jk/xwIqSwGGWradu4QNeHQGCGx6jnVQaAcKwTBAmGyY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hO2TBk0Q; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E0CBC433C7; Fri, 16 Feb 2024 23:54:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708127670; bh=PrQxE5dvr8+mJjo6e46jyPhkqtx2vS84G0Ikoy+xe+0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hO2TBk0QA5Dkf4pTpyVPmUBRWot7k4ysGW1sHeSHa+2FMWZmHYcnNto2YdQ0MQZIl Z8IRUUNKeToP91HGcxZA44Y4eK3WC/uBKOy/UPfK34getv3G2TPhfsNZf1+U6VzHXY eSEx3ybnkL3aJ2fQNe0xREFItYRb2Fp7kNmuxcNlDfLtMoyGZWY7MWkBm6URRHec7r SbSraPy+w0kCV2SC5WBKyI6Z3hjp0/NHE8qWoV+7CeE7ZqPSzhxB//dg4yvDGIeE2R ZwfDwqjQgZ7pSCBne63+D9DbSg06iQmpU3vXJLHgmRBghHkrnS0CBaolauHX5zBR8X fffLsvMvMqUNQ== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 08/14] perf annotate-data: Handle global variable access Date: Fri, 16 Feb 2024 15:54:17 -0800 Message-ID: <20240216235423.2343167-9-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org> References: <20240216235423.2343167-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791103213298000982 X-GMAIL-MSGID: 1791103213298000982 When updating the instruction states, it also needs to handle global variable accesses. Same as it does for PC-relative addressing, it can look up the type by address (if it's defined in the same file), or by name after finding the symbol by address (for declarations). Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 45 ++++++++++++++++++++++++++++++--- tools/perf/util/annotate-data.h | 10 ++++++-- tools/perf/util/annotate.c | 45 ++++++++++++++++++++------------- tools/perf/util/annotate.h | 5 ++++ 4 files changed, 83 insertions(+), 22 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index b1e921663452..e46e162c783f 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -396,6 +396,7 @@ void update_var_state(struct type_state *state, struct data_loc_info *dloc, * update_insn_state - Update type state for an instruction * @state: type state table * @dloc: data location info + * @cu_die: compile unit debug entry * @dl: disasm line for the instruction * * This function updates the @state table for the target operand of the @@ -407,7 +408,7 @@ void update_var_state(struct type_state *state, struct data_loc_info *dloc, * are true. */ void update_insn_state(struct type_state *state, struct data_loc_info *dloc, - struct disasm_line *dl) + void *cu_die, struct disasm_line *dl) { struct annotated_insn_loc loc; struct annotated_op_loc *src = &loc.ops[INSN_OP_SOURCE]; @@ -449,8 +450,46 @@ void update_insn_state(struct type_state *state, struct data_loc_info *dloc, return; retry: - /* Check stack variables with offset */ - if (sreg == fbreg) { + /* Check if it's a global variable */ + if (sreg == DWARF_REG_PC) { + Dwarf_Die var_die; + struct map_symbol *ms = dloc->ms; + int offset = src->offset; + u64 ip = ms->sym->start + dl->al.offset; + u64 pc, addr; + const char *var_name = NULL; + + addr = annotate_calc_pcrel(ms, ip, offset, dl); + pc = map__rip_2objdump(ms->map, ip); + + if (die_find_variable_by_addr(cu_die, pc, addr, + &var_die, &offset) && + check_variable(&var_die, &type_die, offset, + /*is_pointer=*/false) == 0 && + die_get_member_type(&type_die, offset, &type_die)) { + state->regs[dst->reg1].type = type_die; + state->regs[dst->reg1].ok = true; + return; + } + + /* Try to get the name of global variable */ + offset = src->offset; + get_global_var_info(dloc->thread, ms, ip, dl, + dloc->cpumode, &addr, + &var_name, &offset); + + if (var_name && die_find_variable_at(cu_die, var_name, + pc, &var_die) && + check_variable(&var_die, &type_die, offset, + /*is_pointer=*/false) == 0 && + die_get_member_type(&type_die, offset, &type_die)) { + state->regs[dst->reg1].type = type_die; + state->regs[dst->reg1].ok = true; + } else + state->regs[dst->reg1].ok = false; + } + /* And check stack variables with offset */ + else if (sreg == fbreg) { struct type_state_stack *stack; int offset = src->offset - fboff; diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h index ff9acf6ea808..0bfef29fa52c 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -14,6 +14,7 @@ struct die_var_type; struct disasm_line; struct evsel; struct map_symbol; +struct thread; struct type_state; /** @@ -79,11 +80,13 @@ extern struct annotated_data_type stackop_type; /** * struct data_loc_info - Data location information - * @arch: architecture info + * @arch: CPU architecture info + * @thread: Thread info * @ms: Map and Symbol info * @ip: Instruction address * @var_addr: Data address (for global variables) * @var_name: Variable name (for global variables) + * @cpumode: CPU execution mode * @op: Instruction operand location (regs and offset) * @di: Debug info * @fbreg: Frame base register @@ -94,8 +97,10 @@ struct data_loc_info { /* These are input field, should be filled by caller */ struct arch *arch; struct map_symbol *ms; + struct thread *thread; u64 ip; u64 var_addr; + u8 cpumode; const char *var_name; struct annotated_op_loc *op; @@ -164,7 +169,7 @@ void update_var_state(struct type_state *state, struct data_loc_info *dloc, /* Update type state table for an instruction */ void update_insn_state(struct type_state *state, struct data_loc_info *dloc, - struct disasm_line *dl); + void *cu_die, struct disasm_line *dl); #else /* HAVE_DWARF_SUPPORT */ @@ -206,6 +211,7 @@ static inline void update_var_state(struct type_state *state __maybe_unused, static inline void update_insn_state(struct type_state *state __maybe_unused, struct data_loc_info *dloc __maybe_unused, + void *cu_die __maybe_unused, struct disasm_line *dl __maybe_unused) { } diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 44574056d4bd..89a8d57b1bf7 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -3771,6 +3771,28 @@ u64 annotate_calc_pcrel(struct map_symbol *ms, u64 ip, int offset, return map__rip_2objdump(ms->map, addr); } +void get_global_var_info(struct thread *thread, struct map_symbol *ms, u64 ip, + struct disasm_line *dl, u8 cpumode, u64 *var_addr, + const char **var_name, int *poffset) +{ + struct addr_location al; + struct symbol *var; + u64 map_addr; + + *var_addr = annotate_calc_pcrel(ms, ip, *poffset, dl); + /* Kernel symbols might be relocated */ + map_addr = *var_addr + map__reloc(ms->map); + + addr_location__init(&al); + var = thread__find_symbol_fb(thread, cpumode, map_addr, &al); + if (var) { + *var_name = var->name; + /* Calculate type offset from the start of variable */ + *poffset = map_addr - map__unmap_ip(al.map, var->start); + } + addr_location__exit(&al); +} + /** * hist_entry__get_data_type - find data type for given hist entry * @he: hist entry @@ -3845,6 +3867,8 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) for_each_insn_op_loc(&loc, i, op_loc) { struct data_loc_info dloc = { .arch = arch, + .thread = he->thread, + .cpumode = he->cpumode, .ms = ms, /* Recalculate IP for LOCK prefix or insn fusion */ .ip = ms->sym->start + dl->al.offset, @@ -3859,23 +3883,10 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) /* PC-relative addressing */ if (op_loc->reg1 == DWARF_REG_PC) { - struct addr_location al; - struct symbol *var; - u64 map_addr; - - dloc.var_addr = annotate_calc_pcrel(ms, ip, op_loc->offset, dl); - /* Kernel symbols might be relocated */ - map_addr = dloc.var_addr + map__reloc(ms->map); - - addr_location__init(&al); - var = thread__find_symbol_fb(he->thread, he->cpumode, - map_addr, &al); - if (var) { - dloc.var_name = var->name; - /* Calculate type offset from the start of variable */ - dloc.type_offset = map_addr - map__unmap_ip(al.map, var->start); - } - addr_location__exit(&al); + dloc.type_offset = op_loc->offset; + get_global_var_info(he->thread, ms, ip, dl, he->cpumode, + &dloc.var_addr, &dloc.var_name, + &dloc.type_offset); } mem_type = find_data_type(&dloc); diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 83afbe294ab7..b460785111a1 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -23,6 +23,7 @@ struct option; struct perf_sample; struct evsel; struct symbol; +struct thread; struct annotated_data_type; struct ins { @@ -495,6 +496,10 @@ extern struct list_head ann_insn_stat; u64 annotate_calc_pcrel(struct map_symbol *ms, u64 ip, int offset, struct disasm_line *dl); +void get_global_var_info(struct thread *thread, struct map_symbol *ms, u64 ip, + struct disasm_line *dl, u8 cpumode, u64 *var_addr, + const char **var_name, int *poffset); + /** * struct annotated_basic_block - Basic block of instructions * @list: List node From patchwork Fri Feb 16 23:54:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 202441 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp60004dyc; Fri, 16 Feb 2024 15:57:28 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCXAS14blHhJxpyC+Yd3rSPSvaVlXr7z7L0JKQSCyA2pebTj2VtQ71HwnkPspqRxYquxEjFEpYv3FeuEfk0nSvbP/abDow== X-Google-Smtp-Source: AGHT+IFaWbvjuVUl4P00xbEaufzBbEh4io5e7kpnOwz1rY2WwFju+l575gQ9DR1IsZmiD35tq0j8 X-Received: by 2002:a0c:e389:0:b0:68c:9d36:db88 with SMTP id a9-20020a0ce389000000b0068c9d36db88mr5530780qvl.6.1708127848286; Fri, 16 Feb 2024 15:57:28 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708127848; cv=pass; d=google.com; s=arc-20160816; b=FeA5KPucvidfMQxp/pAThxLvAusygriit/BbIe1nwoT2pENEhUSF+D27Ot4EVypDw9 C+wFKOj9dgTkP+neXrWr7lGfsq4wPscBZ5fO/2WV8plOI+n51as88MMYVuUkG6KScuth xz9kaGHEgFPTrsMrxjQVyRmRoyq0/6yRYIDg7iHAENk4zXvVK4ZsTfcQygqD6ucikz+A tbjRZhy5b8ka2aIgHF+gRFZFtMaFR7Z7fDVwtqIbC8ygkYOS8rlQair6saI69wgm15ap amW5//S0C4Tt7VC/ZBg9AFkYvuNpxoW3x96cLH5CLmowa8MES0DZoyRqvsQQjSMaHpSu jitA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=LKjJc/di3rsXXDt/3Tw8I4jt2NSg7jeQAXy8AdYRrZM=; fh=44lErbL5kvNUjSV6UDWgBEjJyOJpjjMpxi6K+HFi+Bc=; b=pYYG9jy1Gl3KQQTdYaEvjcuCOQRTkxtQ/7cHTa70Zos6sv5yZh4S362/yuR7l3suGe 5okeucA9WdO754NWlFEB3qZcCJEGvh8HrXR+bzp95IOVkfDH4zJay8p9Kx35ZClNXA4r jPcbBhRU1hg7N9UUhg+Sfl0Sh/ybX3oBTMkxOvtFLtAUBzqTkW2HfSjU4RO43s4BFIdk fxhoQ8BZurIkn09REaFwOnl/8TucPHpoubwUS9dumTu6J70MmfL0oj/6oD4Any2lQ0n7 iOY/MSAVgPiZSjw3FWgpOg1KxEqssFrW59AMe2+JF+7qUFMutRxwNx8jQraAOzb75sZw 4tYA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=tZVxGjD9; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69503-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69503-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id fo5-20020ad45f05000000b0068cfb592036si942460qvb.449.2024.02.16.15.57.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Feb 2024 15:57:28 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-69503-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=tZVxGjD9; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69503-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69503-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 0C8161C21F65 for ; Fri, 16 Feb 2024 23:57:28 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8CA89151CD2; Fri, 16 Feb 2024 23:54:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="tZVxGjD9" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 902ED14E2C4; Fri, 16 Feb 2024 23:54:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127671; cv=none; b=SwvFCNsX1TjIIR/gAJYIhd50mvtT+YbPwSIk9dKWMYtdPfSXq+9TaxZauzV6tPbKXvEGZcYWgkTOY5GZgZddZfw+P1WwhG/FyhUquBRF7emJyrGnEiUURRd7Fg9jmeLZBU6u1+cZCgxTO1Mxs3aLfixUz3gDayhtZ7xYZegKdPE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127671; c=relaxed/simple; bh=zZHOIpCOQRvZUMTIDQX7NJi7rHNLMrUEbf5ATQRYfWI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JAxZDGh9xLbIVk7RbY55S+6brTpgQtaPFD7RwaKF6KXj3mbqYVdWEI2Eej2xU+zNc/nVihQrlyVLDhccdLkstwI4aYAGSqXlQOw+LNhAYJPWgUM1dVz18wRdn1Zh+21RkZeJlmO7vknLzwRhvVr1aaUhu20O3mQ4a4y5NjN6cEg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tZVxGjD9; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 215B6C433B1; Fri, 16 Feb 2024 23:54:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708127670; bh=zZHOIpCOQRvZUMTIDQX7NJi7rHNLMrUEbf5ATQRYfWI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tZVxGjD9fx55g/829dqU23cR9Np786MufZf4Yc5V7mqADC3/a+IuTCz2gRxEWzfhO M9QSXZnPQKiyslE/mGzNLg/0UoyBZsox0KCkEQnV54tIKBjukFdb29EnXfXahcqaSN kCzb5KBTY+SuyYADZPxf2V2oOiCtEEVithd3oP25ZfewJYx6UdtdpRrLiEr2kqayIa WqGWQ3+gca7KSH9b2bspj15L9eSz0/0sb686xOPqciCrlTbYUGEh3B7EW8MpFPMsDw An6T8jbnrK+LWBfKAwN32K6wccKsYCsA1WKgPPlxZCqmNXhin/HShdaG2Eyy+ZItYE mz7FSZcKt6MsA== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 09/14] perf annotate-data: Handle call instructions Date: Fri, 16 Feb 2024 15:54:18 -0800 Message-ID: <20240216235423.2343167-10-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org> References: <20240216235423.2343167-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791101866801410002 X-GMAIL-MSGID: 1791101866801410002 When updating instruction states, the call instruction should play a role since it changes the register states. For simplicity, mark some registers as caller-saved registers (should be arch-dependent), and invalidate them all after a function call. If the function returns something, the designated register (ret_reg) will have the type info. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 45 +++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index e46e162c783f..e8e363fed8c2 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -23,10 +23,14 @@ #include "symbol.h" #include "symbol_conf.h" -/* Type information in a register, valid when ok is true */ +/* + * 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; bool ok; + bool caller_saved; }; /* Type information in a stack location, dynamically allocated */ @@ -50,6 +54,7 @@ struct type_state_stack { struct type_state { struct type_state_reg regs[TYPE_STATE_MAX_REGS]; struct list_head stack_vars; + int ret_reg; }; static bool has_reg_type(struct type_state *state, int reg) @@ -57,10 +62,23 @@ static bool has_reg_type(struct type_state *state, int reg) return (unsigned)reg < ARRAY_SIZE(state->regs); } -void init_type_state(struct type_state *state, struct arch *arch __maybe_unused) +void init_type_state(struct type_state *state, struct arch *arch) { memset(state, 0, sizeof(*state)); INIT_LIST_HEAD(&state->stack_vars); + + if (arch__is(arch, "x86")) { + state->regs[0].caller_saved = true; + state->regs[1].caller_saved = true; + state->regs[2].caller_saved = true; + state->regs[4].caller_saved = true; + state->regs[5].caller_saved = true; + state->regs[8].caller_saved = true; + state->regs[9].caller_saved = true; + state->regs[10].caller_saved = true; + state->regs[11].caller_saved = true; + state->ret_reg = 0; + } } void exit_type_state(struct type_state *state) @@ -417,6 +435,29 @@ void update_insn_state(struct type_state *state, struct data_loc_info *dloc, int fbreg = dloc->fbreg; int fboff = 0; + if (ins__is_call(&dl->ins)) { + Dwarf_Die func_die; + + /* __fentry__ will preserve all registers */ + if (dl->ops.target.sym && + !strcmp(dl->ops.target.sym->name, "__fentry__")) + return; + + /* Otherwise invalidate caller-saved registers after call */ + for (unsigned i = 0; i < ARRAY_SIZE(state->regs); i++) { + if (state->regs[i].caller_saved) + state->regs[i].ok = false; + } + + /* Update register with the return type (if any) */ + if (die_find_realfunc(cu_die, dl->ops.target.addr, &func_die) && + die_get_real_type(&func_die, &type_die)) { + state->regs[state->ret_reg].type = type_die; + state->regs[state->ret_reg].ok = true; + } + return; + } + /* FIXME: remove x86 specific code and handle more instructions like LEA */ if (!strstr(dl->ins.name, "mov")) return; From patchwork Fri Feb 16 23:54:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 202461 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp69467dyc; Fri, 16 Feb 2024 16:19:33 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCU6NhNZenp/rx4G+K64M5V781t/M9Kojplk6HW4y9p/FiAUPok/xABYzGDrkvpLAHAD8tHwNlA93tm/5kom+h7jqP16pQ== X-Google-Smtp-Source: AGHT+IGzFjdrJ2X0358eg30fD8uq/NuhDnO+wgdk4eEQitMQcqhmJtMeRS3qo9LYhhM5uRs5URhJ X-Received: by 2002:a92:dd05:0:b0:364:f536:b89e with SMTP id n5-20020a92dd05000000b00364f536b89emr5907393ilm.5.1708129173277; Fri, 16 Feb 2024 16:19:33 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708129173; cv=pass; d=google.com; s=arc-20160816; b=KWvsQWOTHPw5iZNXCfDKMe9OL37K2kjmuoRNREQX3RvykYqByZaWu/fruIEyherJIG /JYUgej80tq8J/w31EPdgr/J8blRuz6w6rw8tCYVpf+xrGHt/E1IOos1CpU5h/1Wd9DA mFHgW2y7dHk1TXODwFApDIKtpYzCGwzKn/NmeNTE8m8i6oKreK9ddpnlr/rv8M6xbTCM +7cgfr0l5gZ0T5ZxZfhv865BDBmO9YgCjpQgXsaqDKzTG5p+ju7Mwsz3tbObuqXUC9GD pvWSmGWzqQmdUw2IeVp6h5gMJz1uMNlYBogaBjNInBdZuYLsxuJY89bBI4+EJQGGBQme Ukbg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=er8y/TVFWzkgzp7A3MRcVGky5625Aiif3zcDK4jErGU=; fh=44lErbL5kvNUjSV6UDWgBEjJyOJpjjMpxi6K+HFi+Bc=; b=oQw7aUf0jNcv4d2E5hbvN64HkA03w8eL/R7YR2gA+w0+WWJgP+ohjxV1PuwMoNs1K0 B+ddM/nZQUj6BDR8TzDVFMDpsUOTyGucY+ucXQHZcZM8N/Hiv/IPKvqnwHQkuxn4XC7d qRJIPU90wjUgzzBz6FHyyXyMC0bQP6r+oZG+aVp5adjevrWCqFuT4BzE/R9XMquLSpHe jRMZx5/0fkj+944crTf/+8+RGKoGEdrWiUw8U7mW5Adsa+qUCR7dHt+/cBGi1TTGS9i+ fYnsCMSqoskmrqUQlCMdpBWq4iQUtYMuAi7YdoH+uGeTCJmTZ0vwTW/aQqzyMi3lhftv KlKw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=svlHEZrA; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69502-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69502-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id by26-20020a056a02059a00b005dc8961f39dsi670242pgb.69.2024.02.16.16.19.32 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Feb 2024 16:19:33 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-69502-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=svlHEZrA; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69502-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69502-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 29144B275C6 for ; Fri, 16 Feb 2024 23:58:00 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DA28F152DF5; Fri, 16 Feb 2024 23:54:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="svlHEZrA" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 8D04E14E2C3; Fri, 16 Feb 2024 23:54:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127671; cv=none; b=lidHjEeH7QUvUrHailowGQFobxkcIkFphuo6qUiDkmcfhL3XORiinKiS2w9+zNC77FrQSqzkLzIFZ3M3HZcoUz0EOPclteNUwIGoSDiMQ4NyFmnr4JeFfsbnD9giGo21323ZIq7m2GKCd+9eAtOlXGmzL2mVP0eMYn9wwVWHJUw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127671; c=relaxed/simple; bh=mxQgos6l91axIiDZvKbOHQz0qaSv4aKPPA72xFNlJzY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mZrEVG+BNVBEFqLDrQ0Sa3xaBDn85jQxzA471EYalHZf4HzaZRfNH+ZBs225qgDW2XwVIOjqLSwN5GwWvyxx4vJQJqyDb2e2Fki8wgbLTMQ6u4ae8mfBXLduM8fCVn2V9TrVGqWCW+Pfs69jRo9HuqW9jZYa6epHq0XE1jhQ9+I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=svlHEZrA; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id DAE6CC43390; Fri, 16 Feb 2024 23:54:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708127671; bh=mxQgos6l91axIiDZvKbOHQz0qaSv4aKPPA72xFNlJzY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=svlHEZrAjad61GT4SGkJYPeohlJ4BH2qhvWmrxvxGrgSPgmm9VdPFU5c/003bc+Lj eMhbhdKn4D4Y26VTgamKR4HW3SC3Rc8rd0Wf4dDb8dJYMYwcDvctHtzVcbufYGNYrF Tomua08pSdvQxPRrm11AIxUZX4m8iB+8Ul9X+YZm1UAcLFT5Vk7LM/0iJeQSyeZ4Ej lVp9DhbMqZRnAoKF74yn7afwi9C6F2lJ4pVmg2g/XBZAmTJBLeGggBEEWEFDhphXkL ctbiVIxgfqYXE6XLZFE55rvrg+5O3QmHvhM/ey9+ZreCk8HVXH2L8eExGBss0utcrD QRMfg3imvQrXg== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 10/14] perf annotate-data: Implement instruction tracking Date: Fri, 16 Feb 2024 15:54:19 -0800 Message-ID: <20240216235423.2343167-11-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org> References: <20240216235423.2343167-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791103256107293300 X-GMAIL-MSGID: 1791103256107293300 If it failed to find a variable for the location directly, it might be due to a missing variable in the source code. For example, accessing pointer variables in a chain can result in the case like below: struct foo *foo = ...; int i = foo->bar->baz; The DWARF debug information is created for each variable so it'd have one for 'foo'. But there's no variable for 'foo->bar' and then it cannot know the type of 'bar' and 'baz'. The above source code can be compiled to the follow x86 instructions: mov 0x8(%rax), %rcx mov 0x4(%rcx), %rdx <=== PMU sample mov %rdx, -4(%rbp) Let's say 'foo' is located in the %rax and it has a pointer to struct foo. But perf sample is captured in the second instruction and there is no variable or type info for the %rcx. It'd be great if compiler could generate debug info for %rcx, but we should handle it on our side. So this patch implements the logic to iterate instructions and update the type table for each location. As it already collected a list of scopes including the target instruction, we can use it to construct the type table smartly. +---------------- scope[0] subprogram | | +-------------- scope[1] lexical_block | | | | +------------ scope[2] inlined_subroutine | | | | | | +---------- scope[3] inlined_subroutine | | | | | | | | +-------- scope[4] lexical_block | | | | | | | | | | *** target instruction ... Image the target instruction has 5 scopes, each scope will have its own variables and parameters. Then it can start with the innermost scope (4). So it'd search the shortest path from the start of scope[4] to the target address and build a list of basic blocks. Then it iterates the basic blocks with the variables in the scope and update the table. If it finds a type at the target instruction, then returns it. Otherwise, it moves to the upper scope[3]. Now it'd search the shortest path from the start of scope[3] to the start of scope[4]. Then connect it to the existing basic block list. Then it'd iterate the blocks with variables for both scopes. It can repeat this until it finds a type at the target instruction or reaches to the top scope[0]. As the basic blocks contain the shortest path, it won't worry about branches and can update the table simply. With this change, the stat now looks like below: Annotate data type stats: total 294, ok 185 (62.9%), bad 109 (37.1%) ----------------------------------------------------------- 30 : no_sym 32 : no_mem_ops 27 : no_var 13 : no_typeinfo 7 : bad_offset Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 232 ++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index e8e363fed8c2..9dab5cc5c842 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -597,6 +597,231 @@ void update_insn_state(struct type_state *state, struct data_loc_info *dloc, /* Case 4. memory to memory transfers (not handled for now) */ } +/* Prepend this_list to full_list, removing duplicate disasm line */ +static void prepend_basic_blocks(struct list_head *this_blocks, + struct list_head *full_blocks) +{ + struct annotated_basic_block *first_bb, *last_bb; + + last_bb = list_last_entry(this_blocks, typeof(*last_bb), list); + first_bb = list_first_entry(full_blocks, typeof(*first_bb), list); + + if (list_empty(full_blocks)) + goto out; + + if (last_bb->end != first_bb->begin) { + pr_debug("prepend basic blocks: mismatched disasm line %lx -> %lx\n", + last_bb->end->al.offset, first_bb->begin->al.offset); + goto out; + } + + /* Is the basic block have only one disasm_line? */ + if (last_bb->begin == last_bb->end) { + list_del(&last_bb->list); + free(last_bb); + goto out; + } + + last_bb->end = list_prev_entry(last_bb->end, al.node); + +out: + list_splice(this_blocks, full_blocks); +} + +static void delete_basic_blocks(struct list_head *basic_blocks) +{ + struct annotated_basic_block *bb, *tmp; + + list_for_each_entry_safe(bb, tmp, basic_blocks, list) { + list_del(&bb->list); + free(bb); + } +} + +/* Make sure all variables have a valid start address */ +static void fixup_var_address(struct die_var_type *var_types, u64 addr) +{ + while (var_types) { + /* + * Some variables have no address range meaning it's always + * available in the whole scope. Let's adjust the start + * address to the start of the scope. + */ + if (var_types->addr == 0) + var_types->addr = addr; + + var_types = var_types->next; + } +} + +static void delete_var_types(struct die_var_type *var_types) +{ + while (var_types) { + struct die_var_type *next = var_types->next; + + free(var_types); + var_types = next; + } +} + +/* It's at the target address, check if it has a matching type */ +static bool find_matching_type(struct type_state *state, + struct data_loc_info *dloc, int reg, + Dwarf_Die *type_die) +{ + Dwarf_Word size; + + if (state->regs[reg].ok) { + int tag = dwarf_tag(&state->regs[reg].type); + + /* + * Normal registers should hold a pointer (or array) to + * dereference a memory location. + */ + if (tag != DW_TAG_pointer_type && tag != DW_TAG_array_type) + return false; + + if (die_get_real_type(&state->regs[reg].type, type_die) == NULL) + return false; + + dloc->type_offset = dloc->op->offset; + + /* Get the size of the actual type */ + if (dwarf_aggregate_size(type_die, &size) < 0 || + (unsigned)dloc->type_offset >= size) + return false; + + return true; + } + + if (reg == dloc->fbreg) { + struct type_state_stack *stack; + + stack = find_stack_state(state, dloc->type_offset); + if (stack == NULL) + return false; + + *type_die = stack->type; + /* Update the type offset from the start of slot */ + dloc->type_offset -= stack->offset; + return true; + } + + if (dloc->fb_cfa) { + struct type_state_stack *stack; + u64 pc = map__rip_2objdump(dloc->ms->map, dloc->ip); + int fbreg, fboff; + + if (die_get_cfa(dloc->di->dbg, pc, &fbreg, &fboff) < 0) + fbreg = -1; + + if (reg != fbreg) + return false; + + stack = find_stack_state(state, dloc->type_offset - fboff); + if (stack == NULL) + return false; + + *type_die = stack->type; + /* Update the type offset from the start of slot */ + dloc->type_offset -= fboff + stack->offset; + return true; + } + + return false; +} + +/* Iterate instructions in basic blocks and update type table */ +static bool find_data_type_insn(struct data_loc_info *dloc, int reg, + struct list_head *basic_blocks, + struct die_var_type *var_types, + Dwarf_Die *cu_die, Dwarf_Die *type_die) +{ + struct type_state state; + struct symbol *sym = dloc->ms->sym; + struct annotation *notes = symbol__annotation(sym); + struct annotated_basic_block *bb; + bool found = false; + + init_type_state(&state, dloc->arch); + + list_for_each_entry(bb, basic_blocks, list) { + struct disasm_line *dl = bb->begin; + + list_for_each_entry_from(dl, ¬es->src->source, al.node) { + u64 this_ip = sym->start + dl->al.offset; + u64 addr = map__rip_2objdump(dloc->ms->map, this_ip); + + /* Update variable type at this address */ + update_var_state(&state, dloc, addr, var_types); + + if (this_ip == dloc->ip) { + found = find_matching_type(&state, dloc, reg, + type_die); + goto out; + } + + /* Update type table after processing the instruction */ + update_insn_state(&state, dloc, cu_die, dl); + if (dl == bb->end) + break; + } + } + +out: + exit_type_state(&state); + return found; +} + +/* + * 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. + */ +static int find_data_type_block(struct data_loc_info *dloc, int reg, + Dwarf_Die *cu_die, Dwarf_Die *scopes, + int nr_scopes, Dwarf_Die *type_die) +{ + LIST_HEAD(basic_blocks); + struct die_var_type *var_types = NULL; + u64 src_ip, dst_ip; + int ret = -1; + + dst_ip = dloc->ip; + for (int i = nr_scopes - 1; i >= 0; i--) { + Dwarf_Addr base, start, end; + LIST_HEAD(this_blocks); + + if (dwarf_ranges(&scopes[i], 0, &base, &start, &end) < 0) + break; + + src_ip = map__objdump_2rip(dloc->ms->map, start); + + /* Get basic blocks for this scope */ + if (annotate_get_basic_blocks(dloc->ms->sym, src_ip, dst_ip, + &this_blocks) < 0) + continue; + prepend_basic_blocks(&this_blocks, &basic_blocks); + + /* Get variable info for this scope and add to var_types list */ + die_collect_vars(&scopes[i], &var_types); + fixup_var_address(var_types, start); + + /* Find from start of this scope to the target instruction */ + if (find_data_type_insn(dloc, reg, &basic_blocks, var_types, + cu_die, type_die)) { + ret = 0; + break; + } + + /* Go up to the next scope and find blocks to the start */ + dst_ip = src_ip; + } + + delete_basic_blocks(&basic_blocks); + delete_var_types(var_types); + 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) { @@ -697,6 +922,13 @@ static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die) goto out; } + if (reg != DWARF_REG_PC) { + ret = find_data_type_block(dloc, reg, &cu_die, scopes, + nr_scopes, type_die); + if (ret == 0) + goto out; + } + if (loc->multi_regs && reg == loc->reg1 && loc->reg1 != loc->reg2) { reg = loc->reg2; goto retry; From patchwork Fri Feb 16 23:54:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 202442 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp60092dyc; Fri, 16 Feb 2024 15:57:45 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWIh+0+NMHbQXr7z331nqIEDG/ApRjiIQItBy+CL2dykxOm7RFsjf7ULeRZ/S2cuN3LYamcLvGMqRDsUkPJKdhR2Mp81Q== X-Google-Smtp-Source: AGHT+IHyk86OZYngEDEG3pZyMmg3LYMkLQY0UtVF8Kh2gmQBO5ia1n3jGSdF0OM6e3yOiZhvPdiF X-Received: by 2002:a05:6512:b82:b0:511:a477:64aa with SMTP id b2-20020a0565120b8200b00511a47764aamr5014410lfv.51.1708127865423; Fri, 16 Feb 2024 15:57:45 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708127865; cv=pass; d=google.com; s=arc-20160816; b=zY0cmx8EGcK6gvhodl1KRLsP5koaQD9SVfwXAioXFb1FWZuyT69Hr/Et6yLFmUlfn+ 7EYimeM3rLIKeHpyOeeYMiuR7XaPMmA8Rnljh/7guJqyh0nFIRabmCzYqHVUSGNXgcim 9a0UTbVMzOLS4hs0D3Nd1sT0V/4ErzygKfkvE7V434lnNFSWX89+Ypn3AdOH4tpxJgKp L0Za32lXgbEDJsaqZVlu2FYm7iRbv5vVUVpCvtjwXi6vlH3i8ZaK5EIbXC5Knwhj6a9g hcLFgV3rFpqo04rMPSWz/CS0sRL3OYckWD3DOOZP3l8m5bZMoOP2kZsaoEefWNYVNBbX Uhxg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=Zp+dOLmxvWyhM0zQ5M/VC4yYqHFwzPr8XkB4otprQ1U=; fh=44lErbL5kvNUjSV6UDWgBEjJyOJpjjMpxi6K+HFi+Bc=; b=EvEKIbhwU/UOpaxBAobN6RtviNTkUZVyHd2bRuWaDwxqyuj9uV+LyhbJYbstmJW9wa SlmD2IRLkUelGJD6VfV5n1VnPnmUlMU4h+EuEXXMXas+dt2d1y4GgdY3d+Ibq/E7N4Mf jjAFg1gTL12DDxI2GxPQz4J+ojSVAqBRmblzLiTFnIM3jqZYmCUNnYi1tu+IAui9+a04 zc4Cpio13mxJ0X4FtoKiGL6Sh+rcJPdirNTwz136zr88hcA2M830Ndo7Cy43lgpdv2xo TTBv5LeDmnQq5CeSPneLTEsUqCZaeKku4pyknjTGU5qhc6iEszdBjIU4wqVjsA4sN3mh LWvw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=sFFfU0DK; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69504-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69504-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id da23-20020a056402177700b00563d2360c90si384221edb.385.2024.02.16.15.57.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Feb 2024 15:57:45 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-69504-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=sFFfU0DK; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69504-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69504-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id ED94F1F21D1D for ; Fri, 16 Feb 2024 23:57:44 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 27C25151CF6; Fri, 16 Feb 2024 23:54:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="sFFfU0DK" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 3A7B714E2FA; Fri, 16 Feb 2024 23:54:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127672; cv=none; b=lBehcsa7lNPc885g44idCkkUDCyT/CMToNMKqEQNhGXKNIzF1Ndi06xc9U7Ht3KW94nBxC3stP/0fF5j5ZZL+vXiOqgwhynT62QMtF8XGx5UYdgmg4fjnP6VN/tcac+c9fSOFB44A72S2hJ02t45BLYwYavAffiJg34zAJT2L/s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127672; c=relaxed/simple; bh=hE1QOsjMoRBTV7VH3Rsm9gTxYJbWkglfagXVRxF52QA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=P6zUSR5G6xwuizTs36WrsJtSez6anWSpxk+VxpTQ1wAsvAVTLftOIomYW7H4rLBLUsqa5rUuqyca61DyI1FUvpILIt+9rXqsSU5HXuKChurSgWmViy8VjE/jnl34+YfHWfnBDj2EmPabapEx1Xi9UOnG4piP8j/tL6Nfo1nFKow= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=sFFfU0DK; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8E1C5C43601; Fri, 16 Feb 2024 23:54:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708127672; bh=hE1QOsjMoRBTV7VH3Rsm9gTxYJbWkglfagXVRxF52QA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sFFfU0DKnsw016crE+V8gx1s8ss9Ik6x5huShitQFcFQ1lI1h/HQMAZ49c7zUA88d o5swo8klCxEgrQOJoTjsuATrV2FYcdHcXjvphKvGdCV0RHPLe8Xo2zngwVDGie5xdv Ek40jcGK4OZYgWZSrmHqCxotFM5i6caEFgQNxOAJwWTo6qkLpoAMrh40DOCBwywMaB UupHxBD3hSChVlL29j7XXDJmJMMd0o4lj7U1RKpIkmXoMzjdBzUNIJgRqVQasAH56h Vgas1hK5ue+aiInad8iHXyvS+Y/O8PncOsf9MyHT4nquTNrP9AkA+h1j09y9DK/L/c q75LuSv/HRdnA== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 11/14] perf annotate: Parse x86 segment register location Date: Fri, 16 Feb 2024 15:54:20 -0800 Message-ID: <20240216235423.2343167-12-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org> References: <20240216235423.2343167-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791101884974602682 X-GMAIL-MSGID: 1791101884974602682 Add a segment field in the struct annotated_insn_loc and save it for the segment based addressing like %gs:0x28. For simplicity it now handles %gs register only. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate.c | 21 +++++++++++++++++++-- tools/perf/util/annotate.h | 13 +++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 89a8d57b1bf7..86ac44c476bf 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -3557,6 +3557,12 @@ static int extract_reg_offset(struct arch *arch, const char *str, * %gs:0x18(%rbx). In that case it should skip the part. */ if (*str == arch->objdump.register_char) { + if (arch__is(arch, "x86")) { + /* FIXME: Handle other segment registers */ + if (!strncmp(str, "%gs:", 4)) + op_loc->segment = INSN_SEG_X86_GS; + } + while (*str && !isdigit(*str) && *str != arch->objdump.memory_ref_char) str++; @@ -3653,8 +3659,19 @@ int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl, op_loc->multi_regs = multi_regs; extract_reg_offset(arch, insn_str, op_loc); } else { - char *s = strdup(insn_str); + char *s; + + if (arch__is(arch, "x86")) { + /* FIXME: Handle other segment registers */ + if (!strncmp(insn_str, "%gs:", 4)) { + op_loc->segment = INSN_SEG_X86_GS; + op_loc->offset = strtol(insn_str + 4, + NULL, 0); + continue; + } + } + s = strdup(insn_str); if (s) { op_loc->reg1 = get_dwarf_regnum(s, 0); free(s); @@ -3875,7 +3892,7 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) .op = op_loc, }; - if (!op_loc->mem_ref) + if (!op_loc->mem_ref && op_loc->segment == INSN_SEG_NONE) continue; /* Recalculate IP because of LOCK prefix or insn fusion */ diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index b460785111a1..2bd654620de3 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -446,6 +446,7 @@ int annotate_check_args(void); * @reg1: First register in the operand * @reg2: Second register in the operand * @offset: Memory access offset in the operand + * @segment: Segment selector register * @mem_ref: Whether the operand accesses memory * @multi_regs: Whether the second register is used */ @@ -453,6 +454,7 @@ struct annotated_op_loc { int reg1; int reg2; int offset; + u8 segment; bool mem_ref; bool multi_regs; }; @@ -464,6 +466,17 @@ enum annotated_insn_ops { INSN_OP_MAX, }; +enum annotated_x86_segment { + INSN_SEG_NONE = 0, + + INSN_SEG_X86_CS, + INSN_SEG_X86_DS, + INSN_SEG_X86_ES, + INSN_SEG_X86_FS, + INSN_SEG_X86_GS, + INSN_SEG_X86_SS, +}; + /** * struct annotated_insn_loc - Location info of instruction * @ops: Array of location info for source and target operands From patchwork Fri Feb 16 23:54:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 202443 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp60178dyc; Fri, 16 Feb 2024 15:58:00 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCV/Ljb5o0SmVRYnvpTtKEwHhtch41h1szpdt269qWX/tbgPwZKGSJ2LTyceGAJECftrHD3yS8mne8mxaEaKT2W0IR8RQg== X-Google-Smtp-Source: AGHT+IELG9u7cdoq9tYy91JTlLsPGUSz4qjN65+YeV/fSKsnta/3saksiuKIyVPgicrSJ+vpW0NC X-Received: by 2002:a17:90a:e54c:b0:299:4649:13cb with SMTP id ei12-20020a17090ae54c00b00299464913cbmr2599129pjb.9.1708127880413; Fri, 16 Feb 2024 15:58:00 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708127880; cv=pass; d=google.com; s=arc-20160816; b=nD4+UXAVAAUIrDPKbRPJEnZ0wZCvylDNGAyuhFVhizS8lARM4+DJDOEbC7sh/Wfics P+9vF8w6qJsprdGCKTyiii0kxDN3a5Dy1JQtFlb76HiMLIagmBUyXvo5bU8yc9T7oGTY 5t0lRPKAuHYNYVRXgDZM4EgjI/0e32v1UOPBBJBUk3eLmLkYiPq3WTA2ppFSIp4NMDB6 0U12KtEwB/r0WOVmJ0sbmvsVStJpzDNtcV4zPWNIcxh6/6H0dopjqIVKAS4lbYdpBfRr pOCY6guAVn/G9p9KH18hq+ltMSnY3HR+xkd0VgoEUfdUgnu+Ls83lpgGcychZa/Rxnfa l7XQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=cDcNzjYsN2LCrj6kS/WmF+366XULiA4YZZaJkxq7ZDQ=; fh=44lErbL5kvNUjSV6UDWgBEjJyOJpjjMpxi6K+HFi+Bc=; b=IM1brk2bS1QDzwQl8cxStqXGNOkJu+j2O+mo85q9THuv+k3cTMtwXf5I7cAqcO4M4f jEyY6X3Z4aD8oyUHFxyCbSasy2Ex/uOG0uPBFRb0ZiJ75kCzsmjPxga5XsH51PXZczzn 7V5E/O61uGviCESttq0+0GmhSMjHxzwvwS90Akjq24TxFi5siA1ipbibsaWeMjMNdzJX M1jZTEvNBFsFplx77Bca9JIufX+w2Jn2ibjF0MOeLsNDuzVcip/oCWyqyXY6q3aI3u8N thhUAVJMqHXlF0F8QR0P7ftx7hW5NMCJcQ6Nc9C1Y4EzKMC/ksVgWuwijmXCsMNoonSq eg/A==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=FbGdxWtq; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69505-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69505-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id gp5-20020a17090adf0500b002991ce07fa8si670035pjb.111.2024.02.16.15.58.00 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Feb 2024 15:58:00 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-69505-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=FbGdxWtq; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69505-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69505-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 3CF242899D3 for ; Fri, 16 Feb 2024 23:58:00 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 18558152DFB; Fri, 16 Feb 2024 23:54:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FbGdxWtq" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 25CB614F9EF; Fri, 16 Feb 2024 23:54:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127673; cv=none; b=kCcGgs1eJK1z6au9yGHgAAqzSHUfgNbEQRK1dyFaxUh8mJhOdzdTjsbcasPoTChQjQffc9g9TeVaCPzbmqd1BdmJ01Zv5jNhuM1L5g2CjEaZiPfYeeuG0QIGupj/W0J6Li1vWCnTcQ461q28+URFBBV5Z3/OZ728Swtyrhbd6p4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127673; c=relaxed/simple; bh=7H93tb4nFoxmqjMsy4F0W3n1gdRCYZwiYhvSl0/wg+o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nZDjHrPunQSeG9q/3C8CYiX/HJFLAfra1zikmkaQ+8RdTJjxgGd9KrkP9qe/mW7c+uuP1GHhLlnHLLsMm/cUYabyEnKM6kEbsKg/WaLe3ZvUfGHo+mhJqolZtiR1vkoJ/CcNtJp6ZIxFtLvXqBjge17y8k7MyDUXa6joDtV9FrM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FbGdxWtq; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 36FBDC43330; Fri, 16 Feb 2024 23:54:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708127672; bh=7H93tb4nFoxmqjMsy4F0W3n1gdRCYZwiYhvSl0/wg+o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FbGdxWtqka1vUepXIIOKJpZUUEQF1Uh+iaY3+hlzETqCcmxP6BGbwHCIshcPyZFUb xzSTOuJXQrYO7/Ztk+Da3UTt6C93Fe037aE5lryspZh+R6L52VE9jFUhsY/ON83lEQ err2HfGWkSzBYH9wLfxswwyz3rnPiBCOIEhbglSUEh6attWX9Kedvxkj2NrApcUpam Xuaek3p7EIKCg274zuh2LVV26UIGvwtYJolXU1NdZmkJDK+LpSNyE6nSk/b5tFAIka vHdfZNKGzqvR0x/S219pvSC80+1GVprPlDpadUpEqGA4fqz3o22DpIMvpchONw+Yio 8qebJZoODgE4w== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 12/14] perf annotate-data: Handle this-cpu variables in kernel Date: Fri, 16 Feb 2024 15:54:21 -0800 Message-ID: <20240216235423.2343167-13-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org> References: <20240216235423.2343167-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791101900346935201 X-GMAIL-MSGID: 1791101900346935201 On x86, the kernel gets the current task using the current macro like below: #define current get_current() static __always_inline struct task_struct *get_current(void) { return this_cpu_read_stable(pcpu_hot.current_task); } So it returns the current_task field of struct pcpu_hot which is the first member. On my build, it's located at 0x32940. $ nm vmlinux | grep pcpu_hot 0000000000032940 D pcpu_hot And the current macro generates the instructions like below: mov %gs:0x32940, %rcx So the %gs segment register points to the beginning of the per-cpu region of this cpu and it points the variable with a constant. Let's update the instruction location info to have a segment register and handle %gs in kernel to look up a global variable. The new get_percpu_var_info() helper is to get information about the variable. Pretend it as a global variable by changing the register number to DWARF_REG_PC. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate.c | 31 +++++++++++++++++++++++++++++++ tools/perf/util/annotate.h | 4 ++++ 2 files changed, 35 insertions(+) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 86ac44c476bf..5f3136f57c62 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -3810,6 +3810,27 @@ void get_global_var_info(struct thread *thread, struct map_symbol *ms, u64 ip, addr_location__exit(&al); } +void get_percpu_var_info(struct thread *thread, struct map_symbol *ms, + u8 cpumode, u64 var_addr, const char **var_name, + int *poffset) +{ + struct addr_location al; + struct symbol *var; + u64 map_addr; + + /* Kernel symbols might be relocated */ + map_addr = var_addr + map__reloc(ms->map); + + addr_location__init(&al); + var = thread__find_symbol_fb(thread, cpumode, map_addr, &al); + if (var) { + *var_name = var->name; + /* Calculate type offset from the start of variable */ + *poffset = map_addr - map__unmap_ip(al.map, var->start); + } + addr_location__exit(&al); +} + /** * hist_entry__get_data_type - find data type for given hist entry * @he: hist entry @@ -3906,6 +3927,16 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) &dloc.type_offset); } + /* This CPU access in kernel - pretend PC-relative addressing */ + if (op_loc->reg1 < 0 && map__dso(ms->map)->kernel && + arch__is(arch, "x86") && op_loc->segment == INSN_SEG_X86_GS) { + dloc.var_addr = op_loc->offset; + get_percpu_var_info(he->thread, ms, he->cpumode, + dloc.var_addr, &dloc.var_name, + &dloc.type_offset); + op_loc->reg1 = DWARF_REG_PC; + } + mem_type = find_data_type(&dloc); if (mem_type) istat->good++; diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 2bd654620de3..490134d19c9d 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -513,6 +513,10 @@ void get_global_var_info(struct thread *thread, struct map_symbol *ms, u64 ip, struct disasm_line *dl, u8 cpumode, u64 *var_addr, const char **var_name, int *poffset); +void get_percpu_var_info(struct thread *thread, struct map_symbol *ms, + u8 cpumode, u64 var_addr, const char **var_name, + int *poffset); + /** * struct annotated_basic_block - Basic block of instructions * @list: List node From patchwork Fri Feb 16 23:54:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 202463 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp69560dyc; Fri, 16 Feb 2024 16:19:48 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVor7aNLv1vOy6H+qhksLC36eN2wGS+2Xj+0+fchX0HvMt8NleGJxY/nLB3iSAgLBUyE/fgtcf/v6qZN+aIBd9Uqcb6Zw== X-Google-Smtp-Source: AGHT+IHe8LXTq2sC7S7oDE1ngfn6u/1BX71fTusPLVcAare5YD6ns7VgsYEZL4kJmfNPrqqWxy76 X-Received: by 2002:a17:90a:f0cc:b0:296:7480:7650 with SMTP id fa12-20020a17090af0cc00b0029674807650mr6484021pjb.26.1708129188798; Fri, 16 Feb 2024 16:19:48 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708129188; cv=pass; d=google.com; s=arc-20160816; b=L55i04jsHa1iRYKzYq/mBYgIHwuAqelyPV7jEqENDv7e6trqXshMgn1aTehuIa072N xCuy6Qa9dJNHM2a/FvlrMt18oN9gMSL/leCMxG+nfs/PMfLnODmZk7ZcUf54d6z+oQ5k /qgdN1Jw3EfcOtdjP9NznJZQatvcyMyZ0Rz6XGsCYnvREYr2nCYmcXossc0NVRwlKrIM b776ft7uMUxIk81cYHvqIxXojDN0Abl0dy3hBMzcBq1T6Vy7g/oWXcYShhiVntTKm7IN g6iESKNokV/riBkc9mbL/fQBrUY58XkUIw7DA4XQIC0lX8gXfAfeUV9yJsBkFJUSR2RY kDng== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=jmG6CXDkx0EZCfb5Hq/rJ+Zzk0fLM2xwmsvGT9m/wbc=; fh=44lErbL5kvNUjSV6UDWgBEjJyOJpjjMpxi6K+HFi+Bc=; b=eq8AOCtNtXpy0HxXBdpIX7yxLRWqjG4Zh9XjpXVmqalRGBv9PhLl8HlXSlHenZJME3 p4vJ4sFOdlTTK8Pn52W3XtcXULSMDRB8o+8cvPl0mE5nM+tEvrtK8yLoBU71LkCtXIuf FCYHpFvR7Shj7091B9bB9qN+he8SmmOSWUemCH6xI1dN8iE0IelfR3K3TxojeWmoxa0l gHItW0y6QY/0OzX0hTKXueAcKXnHy2Wg85oZ3ooXeWdaCJB1HPJ7VGumvScmHlLL/w5e qInZc8uCbJdkn5EZmZuCFE5MDPv9nV/9ZbojSkzO3nYB5CNpoyeYiRErp/sNc4MLg86u KjSQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=DYxYN2nd; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69506-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69506-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id qc18-20020a17090b289200b0029703861513si715500pjb.122.2024.02.16.16.19.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Feb 2024 16:19:48 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-69506-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=DYxYN2nd; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69506-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69506-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id CF6C2B27700 for ; Fri, 16 Feb 2024 23:58:13 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id F14FF152E16; Fri, 16 Feb 2024 23:54:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="DYxYN2nd" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 C57D21509A2; Fri, 16 Feb 2024 23:54:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127673; cv=none; b=aj1Jcmz3MgkWr8VwGCSqsCsUG/4nv/t6q+b2qDRPjnzShnZx5EQmtGHfjferQBwT9mkIUK6atsStYhBfVL03b3btv2gXz3VJ/Ns1DP1yV/Q+cQv8AomU5pxYOkJW6ea+iplLQ+ReJB2XxVAry3NMjIVm9UjO43cWqS/bdDU/xOs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127673; c=relaxed/simple; bh=xWpjopYeC2vvlPkH8zqbdsgUF2q6BBssG2vgYw4CIrc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cnXWbBHYxqL9Mw/a4TyQxGVG9GIi2blHdw/FlJfk9PWBcDAyQ+rFkYyLKHfdRBD8n+SH25voSh5N1TFTa36EtVbZ2imsd9cbm6oj/DSTOY9/e61mU8XwZSOmyGT0Lb/ltSKVjEw+GRPWC38TEEd+XKkb0t/y1P219Juy6WV25Sw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DYxYN2nd; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id CE042C433F1; Fri, 16 Feb 2024 23:54:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708127673; bh=xWpjopYeC2vvlPkH8zqbdsgUF2q6BBssG2vgYw4CIrc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DYxYN2ndPd2e6Gf1f7hgGodnEOJPQFWR3RVRDfVyd8e89z5sOJEneek0lPeXTu8Yh 01K/5QxquTIrSBLjV/Mxkw7qCzkg+IN+/hFU+mL3BT1rjOo+qUvoYUPE/bbE7Z5HIy 7cEaDoPc4hIGOB2UI3lRzUYKaNrBY5SYx56eVr3Utw269fb52ezqIF0AVbV+NrfApI 0zzorB1Z5HzUmtZf6XuHJ79ciyI4N/o2Qh7i7OC/dLvH2hJBXwpkEuXnL3svlHmDDU TPZgz8OYFDH1Qp2LsnlFsTrz/YppShL1kqoPgNz3+YasKcUyg+v9lez01zNwXxjosd 0wOZwYPYZ6zeQ== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 13/14] perf annotate-data: Track instructions with a this-cpu variable Date: Fri, 16 Feb 2024 15:54:22 -0800 Message-ID: <20240216235423.2343167-14-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org> References: <20240216235423.2343167-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791103272085963889 X-GMAIL-MSGID: 1791103272085963889 Like global variables, this per-cpu variables should be tracked correctly. Factor our get_global_var_type() to handle both global and per-cpu (for this cpu) variables in the same manner. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.c | 84 +++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 24 deletions(-) diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index 9dab5cc5c842..e3af5aec937a 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -410,6 +410,37 @@ void update_var_state(struct type_state *state, struct data_loc_info *dloc, } } +static bool get_global_var_type(Dwarf_Die *cu_die, struct map_symbol *ms, u64 ip, + u64 var_addr, const char *var_name, int var_offset, + Dwarf_Die *type_die) +{ + u64 pc; + int offset = var_offset; + bool is_pointer = false; + Dwarf_Die var_die; + + pc = map__rip_2objdump(ms->map, ip); + + /* Try to get the variable by address first */ + if (die_find_variable_by_addr(cu_die, pc, var_addr, &var_die, &offset) && + check_variable(&var_die, type_die, offset, is_pointer) == 0 && + die_get_member_type(type_die, offset, type_die)) + return true; + + if (var_name == NULL) + return false; + + offset = var_offset; + + /* Try to get the name of global variable */ + if (die_find_variable_at(cu_die, var_name, pc, &var_die) && + check_variable(&var_die, type_die, offset, is_pointer) == 0 && + die_get_member_type(type_die, offset, type_die)) + return true; + + return false; +} + /** * update_insn_state - Update type state for an instruction * @state: type state table @@ -473,14 +504,36 @@ void update_insn_state(struct type_state *state, struct data_loc_info *dloc, fbreg = -1; } - /* Case 1. register to register transfers */ + /* 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; if (has_reg_type(state, src->reg1)) state->regs[dst->reg1] = state->regs[src->reg1]; - else + else if (map__dso(dloc->ms->map)->kernel && + src->segment == INSN_SEG_X86_GS) { + struct map_symbol *ms = dloc->ms; + int offset = src->offset; + u64 ip = ms->sym->start + dl->al.offset; + const char *var_name = NULL; + u64 var_addr; + + /* + * 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 = src->offset; + get_percpu_var_info(dloc->thread, ms, dloc->cpumode, + var_addr, &var_name, &offset); + + if (get_global_var_type(cu_die, ms, ip, var_addr, + var_name, offset, &type_die)) { + state->regs[dst->reg1].type = type_die; + state->regs[dst->reg1].ok = true; + } + } else state->regs[dst->reg1].ok = false; } /* Case 2. memory to register transers */ @@ -493,37 +546,20 @@ void update_insn_state(struct type_state *state, struct data_loc_info *dloc, retry: /* Check if it's a global variable */ if (sreg == DWARF_REG_PC) { - Dwarf_Die var_die; struct map_symbol *ms = dloc->ms; int offset = src->offset; u64 ip = ms->sym->start + dl->al.offset; - u64 pc, addr; const char *var_name = NULL; + u64 var_addr; - addr = annotate_calc_pcrel(ms, ip, offset, dl); - pc = map__rip_2objdump(ms->map, ip); - - if (die_find_variable_by_addr(cu_die, pc, addr, - &var_die, &offset) && - check_variable(&var_die, &type_die, offset, - /*is_pointer=*/false) == 0 && - die_get_member_type(&type_die, offset, &type_die)) { - state->regs[dst->reg1].type = type_die; - state->regs[dst->reg1].ok = true; - return; - } + var_addr = annotate_calc_pcrel(ms, ip, offset, dl); - /* Try to get the name of global variable */ - offset = src->offset; get_global_var_info(dloc->thread, ms, ip, dl, - dloc->cpumode, &addr, + dloc->cpumode, &var_addr, &var_name, &offset); - if (var_name && die_find_variable_at(cu_die, var_name, - pc, &var_die) && - check_variable(&var_die, &type_die, offset, - /*is_pointer=*/false) == 0 && - die_get_member_type(&type_die, offset, &type_die)) { + if (get_global_var_type(cu_die, ms, ip, var_addr, + var_name, offset, &type_die)) { state->regs[dst->reg1].type = type_die; state->regs[dst->reg1].ok = true; } else From patchwork Fri Feb 16 23:54:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 202444 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:108:e6aa:91d0 with SMTP id mn5csp60239dyc; Fri, 16 Feb 2024 15:58:14 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUJ7sSBOMT3RT/qQaxenJazGaeBvaNdQBhH3JLtTMMEoRFzVL0U1R/EXl+C2Jl9zOAvppp342EhMT/EExeGKxk9b1mVFg== X-Google-Smtp-Source: AGHT+IGpVv1EpMGmnxDDzf7GTR8aVn/ePCeXupQ1S+sPnUxflEDGoluoszw00L7stAHTctpWWXS2 X-Received: by 2002:a25:b286:0:b0:dcc:6757:1720 with SMTP id k6-20020a25b286000000b00dcc67571720mr6638453ybj.32.1708127894406; Fri, 16 Feb 2024 15:58:14 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708127894; cv=pass; d=google.com; s=arc-20160816; b=1Ingjl6fcvCneS/qTuGZ7ggAbx3/N2Uw+wxkTAgQsTpMuDOkObvDzbXnwmtruLflwA QmzrXI/KXJ6X+zfRoQ/a0z7ASubOyG5fxu4Ls85/QPkjCQm2kqIJbOzMnkS+eshYjFwJ 8OBWtcUTSqyl4zeu3Z+qV7QCUMFXK7w3/juO+Y2TxJIam72ftNV7u/9mr4dMQe5M0vYY lsuw8dhOKdVu942XzWqPZlEwieIog7hgQ6o2CPW3jFt6XkGlghy5mojpcDFPXfOFJFvN tuDr190SM6AGrgqlATcNJvDlRmg7FwDckdaOm085No0LButQqmR4mmbLnSljq3yRicT4 AjlA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=X7eiQEjQZ8+r3IpJmlwVdHL2qoOT43TqB7HOLA7IOVk=; fh=44lErbL5kvNUjSV6UDWgBEjJyOJpjjMpxi6K+HFi+Bc=; b=KXA6JImL2yMp5zwhOkjfRDhdDcNAt7e3i8R+xRSW/4BOrsGSBxvgjzMCEBuWF/wsmc W3XN3mSgSC8A2vBqSBUSLZf9rSRWBpVNrHQWt/M7IiKY2KKvvi66El/aNAfSxQnzayU/ e/Wq4kZBbathEiJao19Xfm1mlXDKVyKifPBKbh8E9GMTGNDHA5eZaPW0f2DkjBEYWZgP Ite4aO5gOZ+EUET/koVLA9etvFp8rNNX9MY5Q3pYTTvoQF1yZ9/V8/6+A7YeRM78TYts Xr9NZ6h4iYI2QEcgf/r2SL5IUbxDz6vK4XjEpo220qjWXGMr4TtLo3FTD1ZWTYTo2B4i yUXg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=MTAWCSTF; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69507-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69507-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id f17-20020a05620a20d100b00783f2040be5si1058807qka.535.2024.02.16.15.58.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 16 Feb 2024 15:58:14 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-69507-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=MTAWCSTF; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-69507-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-69507-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id 3403D1C21DBA for ; Fri, 16 Feb 2024 23:58:14 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 28AED152E1B; Fri, 16 Feb 2024 23:54:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MTAWCSTF" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 728E3151CD1; Fri, 16 Feb 2024 23:54:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127674; cv=none; b=S6sTxaWOvAsMZpd9DPADPCt27OfcJeiC8yDMci9A90RsjUc/b9xYFrO1wLu2tAHIUtTv47kI4Zyh3s5I7gbwMx3qmRUyo/muy4VMyc+C5A7LAFiLWorCCfEvenOc7hmWPLygCOdLaCBFcKZopqaNWhMs0IT3sG7zAQseBbO44KU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708127674; c=relaxed/simple; bh=JSCVTE9XqiSDlA8ej8yd/v+YYkjMI/c+XOMMHYmpMcI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=N9xMtNa89UjGVftyZh1Pvf2NxyrpZyXmVJDNgODptdDZYiuvI+C0eAtVdHVT/q0Tv33/1zhHvVBSKUCj9UZlm0xAcx7UNKj6yBDJTD2NNOAdnVfEhVY/dHgR2lsjP2Q5x5gXcI0IeGzrQLQ7IMdPIfdfw0A8SMcP3mH6f2ZCWd4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MTAWCSTF; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6FEFFC43390; Fri, 16 Feb 2024 23:54:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708127673; bh=JSCVTE9XqiSDlA8ej8yd/v+YYkjMI/c+XOMMHYmpMcI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MTAWCSTFqFpQXQG/f3joQWMIncRQ5STu7HgSAMGWoppmG7mNaW/7UP7WCaKPO80OP PDAUkm64BEI/oIPTYpSJoVGDwyyqbp3bL/5ImyYfyvOQor5HIqw+JHIjQttryesqM7 ZCnP31OeXbmcxL+hONZqbJ3VcHpNuQM8IBo0Ye/ZqY1tmOis6sJI+sxmlejm0Vfaim RzTuboxDG4k5ez7x38ETDoi/qM4dEjEOi4qu1vcJiS9DVdJQwK45+7pI0XhLYVOpUJ bNzYMjCQCG63xb4Ys6nUYvKaFb6lEbZ2vkdUBmZvGm2xRVW1XRD8tC5Rlq/Wqc7UtW jKFVz3evaBKRA== From: Namhyung Kim To: Arnaldo Carvalho de Melo , Ian Rogers Cc: Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 14/14] perf annotate-data: Add stack canary type Date: Fri, 16 Feb 2024 15:54:23 -0800 Message-ID: <20240216235423.2343167-15-namhyung@kernel.org> X-Mailer: git-send-email 2.44.0.rc0.258.g7320e95886-goog In-Reply-To: <20240216235423.2343167-1-namhyung@kernel.org> References: <20240216235423.2343167-1-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791101914954174088 X-GMAIL-MSGID: 1791101914954174088 When the stack protector is enabled, compiler would generate code to check stack overflow with a special value called 'stack carary' at runtime. On x86_64, GCC hard-codes the stack canary as %gs:40. While there's a definition of fixed_percpu_data in asm/processor.h, it seems that the header is not included everywhere and many places it cannot find the type info. As it's in the well-known location (at %gs:40), let's add a pseudo stack canary type to handle it specially. Signed-off-by: Namhyung Kim --- tools/perf/util/annotate-data.h | 1 + tools/perf/util/annotate.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h index 0bfef29fa52c..e293980eb11b 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -77,6 +77,7 @@ struct annotated_data_type { extern struct annotated_data_type unknown_type; extern struct annotated_data_type stackop_type; +extern struct annotated_data_type canary_type; /** * struct data_loc_info - Data location information diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 5f3136f57c62..f2683dadf3cf 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -116,6 +116,13 @@ struct annotated_data_type stackop_type = { }, }; +struct annotated_data_type canary_type = { + .self = { + .type_name = (char *)"(stack canary)", + .children = LIST_HEAD_INIT(canary_type.self.children), + }, +}; + static int arch__grow_instructions(struct arch *arch) { struct ins *new_instructions; @@ -3764,6 +3771,17 @@ static bool is_stack_operation(struct arch *arch, struct disasm_line *dl) return false; } +static bool is_stack_canary(struct arch *arch, struct annotated_op_loc *loc) +{ + /* On x86_64, %gs:40 is used for stack canary */ + if (arch__is(arch, "x86")) { + if (loc->segment == INSN_SEG_X86_GS && loc->offset == 40) + return true; + } + + return false; +} + u64 annotate_calc_pcrel(struct map_symbol *ms, u64 ip, int offset, struct disasm_line *dl) { @@ -3938,6 +3956,12 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) } mem_type = find_data_type(&dloc); + + if (mem_type == NULL && is_stack_canary(arch, op_loc)) { + mem_type = &canary_type; + dloc.type_offset = 0; + } + if (mem_type) istat->good++; else