From patchwork Thu Nov 9 23:59:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 163662 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b129:0:b0:403:3b70:6f57 with SMTP id q9csp787103vqs; Thu, 9 Nov 2023 16:03:50 -0800 (PST) X-Google-Smtp-Source: AGHT+IGuiNxyAHBEFuP5bz/T+ssr1QOE2R10iaj9/DkhEfP6UItG9SM6ll2kI6JtLaaOu7HkZ778 X-Received: by 2002:a17:903:18f:b0:1cc:fc8:5be1 with SMTP id z15-20020a170903018f00b001cc0fc85be1mr8602495plg.1.1699574630647; Thu, 09 Nov 2023 16:03:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1699574630; cv=none; d=google.com; s=arc-20160816; b=qfUT72FxhUL6JXnbkQ0mHrR9J7MdfGAnvDfaKgQuseltwqaebuzDvPRTsx6K77HDN4 AYHYCTQItW7ibt9AYGI9/NGq3B6scL2E+zcqTu8BQ5LcYHJ7qLuE6PHlyY9Sy1vL9MrL dYo+8c2zuHqQasnOgdSF8wrpItNmDwNbZ3RSdEYUEuXlSREKtMyYhwgJBpJHe6fBcsLx cyaZn0tLDKfOMkdrQTLdukXwYPBgU7Y8/GrJyGM+0HGO59J16C5cjAq7oF0+OUJQIqEw bZUbxPKmUxb6qC8C6yWT4/qxSZBzLlXOXHOUAINZNkmjLZB6deAnahpYeSSBCNl3qMqe 4aYw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from:sender :dkim-signature; bh=uT1nC/9fwVyUyj/Fu7de7zQ927+akdOp694fgBwHADA=; fh=K//si1Hi/RYC7s39rVvmvh0YbZGmBrdWWHQg3cPF7Xc=; b=sSdlQN5dbWiGWxw49GmHIfEwQwjbpU7IJKgimG4+tyBho6WNL56tPWw9WVmlSKn0al Hs8nErs+5XbTqfvKXIfL70cD6wAjgmMowhGiYwIDM6ozIuUplbafuGHjfzW2SHIXHeBI FKkHbVznj8Nr+nmEKGaxX1ExWfbT5VNdhWZPZHo0yLNy2NKVFEeazWzyC2x4uegFGWZ7 Bnp+218ktJQGBIg/xkm2UiN0lJH88Blv2ZFC0EODvGJYKhgu1rWlIANj/Lwq6f9Iw2Or pHxaJ9aTOqmZc4Go+rpsp9q+DNxbJBtnUmNFkB962GyyNLiIMNBoGq7U07yNN7qi3QAR 32aQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=eQSfHD6q; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from snail.vger.email (snail.vger.email. [2620:137:e000::3:7]) by mx.google.com with ESMTPS id ld7-20020a170902fac700b001cc50c56980si5402289plb.411.2023.11.09.16.03.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Nov 2023 16:03:50 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) client-ip=2620:137:e000::3:7; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=eQSfHD6q; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:7 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by snail.vger.email (Postfix) with ESMTP id 809CC83AAE58; Thu, 9 Nov 2023 16:03:49 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at snail.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345600AbjKJADj (ORCPT + 30 others); Thu, 9 Nov 2023 19:03:39 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46586 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345640AbjKJAC6 (ORCPT ); Thu, 9 Nov 2023 19:02:58 -0500 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B4EFC44BD; Thu, 9 Nov 2023 16:01:14 -0800 (PST) Received: by mail-pj1-x102b.google.com with SMTP id 98e67ed59e1d1-28019b66ad5so1294056a91.3; Thu, 09 Nov 2023 16:01:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1699574474; x=1700179274; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=uT1nC/9fwVyUyj/Fu7de7zQ927+akdOp694fgBwHADA=; b=eQSfHD6qRSxxcCJ4zVBQiHAVW0LYKgFgXjSzEZ8SNsi0xsq8hMByVP00UMwVdYUdO+ TPvk0oiBybTql7XrmO+p8oljr/zD7pD+93m9NsDkBsrkjVtaPgcQUNRIpsUs0qCEj+EZ XCAUrtqiSlX19j6CaFYEhUEaZCNOPjGmybm9CcOWQ/ocnRdJpZ14qowUqEMIQX7JHkGp d/lfRx+BRROYjE8Go2S8NPlkOfdjj32R0+goFYOJ4oxYuULgWCkyemzrsi4MFkeshEPE nxdZBHChrBJqpJNuFbHdghQ1/utoUHDNzNfoWkBha4vosMwPQTOFdJ/zVtEd4zrfC/HI nvCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699574474; x=1700179274; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=uT1nC/9fwVyUyj/Fu7de7zQ927+akdOp694fgBwHADA=; b=VZpKlAPYJGdevsXByj4RBjP7TnSQ0Ec9vAtsGyVpNCPFDFknYJEgUR6egPzGcV+YaO iPKYuTZI4Vk9ljT6QIlWw3X+qStrtLBgSdbTDnCkdMEZAs0B3jIhMsPO0ulp1Cu6yPhe lD1+1xfsAErXliq8ciWw46OK9x/DXRC+mA1xK0r1V667tzMci2rrb1ZlyssUM+mZvKF8 8aWlZXtF4jOnrnNVj9StR51Yt4kvDxuPyRGHZpWD6pQFydyQZMafNQ/6Px+Z8/vRZtby Rj/raLI89dHp02w+ImiN3VdhnFd4M+aNwYbM4GQyeCNUZOjMeTUAMSqb9m6LjbZDrYr1 ggoA== X-Gm-Message-State: AOJu0YwT69TBSD/ZdBPhV2DUUWy0GJg88igh8jjcd2XG+J7SWXXGjg6F eZzuZx1pUjcdJZ1va5oVXAg= X-Received: by 2002:a17:90b:1b45:b0:27d:9f6:47a3 with SMTP id nv5-20020a17090b1b4500b0027d09f647a3mr3498693pjb.31.1699574474120; Thu, 09 Nov 2023 16:01:14 -0800 (PST) Received: from bangji.corp.google.com ([2620:15c:2c0:5:d45c:ae16:d959:a5f1]) by smtp.gmail.com with ESMTPSA id k32-20020a17090a4ca300b002635db431a0sm371312pjh.45.2023.11.09.16.01.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Nov 2023 16:01:13 -0800 (PST) Sender: Namhyung Kim From: Namhyung Kim To: Arnaldo Carvalho de Melo , Jiri Olsa , Peter Zijlstra Cc: Ian Rogers , Adrian Hunter , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , Andi Kleen , linux-trace-devel@vger.kernel.org, linux-toolchains@vger.kernel.org Subject: [PATCH 38/52] perf dwarf-aux: Add die_collect_vars() Date: Thu, 9 Nov 2023 15:59:57 -0800 Message-ID: <20231110000012.3538610-39-namhyung@kernel.org> X-Mailer: git-send-email 2.42.0.869.gea05f2083d-goog In-Reply-To: <20231110000012.3538610-1-namhyung@kernel.org> References: <20231110000012.3538610-1-namhyung@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (snail.vger.email [0.0.0.0]); Thu, 09 Nov 2023 16:03:49 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1782133168042648084 X-GMAIL-MSGID: 1782133168042648084 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