From patchwork Thu Oct 12 03:50:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Namhyung Kim X-Patchwork-Id: 151722 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2908:b0:403:3b70:6f57 with SMTP id ib8csp965830vqb; Wed, 11 Oct 2023 20:56:47 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFR0aleL4eNO8miniEeyCf+tOmD4EUaPsn18b6d2+/LhLP7EdqEjtSb4epehxbIlwbbZqDb X-Received: by 2002:a05:6a20:429f:b0:15c:b7ba:e9ba with SMTP id o31-20020a056a20429f00b0015cb7bae9bamr27129292pzj.0.1697083007039; Wed, 11 Oct 2023 20:56:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1697083007; cv=none; d=google.com; s=arc-20160816; b=o915UkVbud7iLqOoJ3SlJvxRWPyp+nrtbmwU4aNb9kWAW7Fu2CGMvOwSH827dwe00j giBNsL4SBELiSwhK0kPKtsQvuZvxf8F2SN+LNBsdueWfTvQM5h5uxt0U7/RfqEhMvx2z 78RBweIA0MWa/GBfArP6/NKC8WMw6hTsTwT3HFHca8RA6NACwsuz4ExcylmQa37r7+o6 5GbzbP33Chv2IxTUcs7I8wbJfIJLnOw8/CWDRTzEbBAUKEWQzALU1p6RLjJgGkqIXml9 GEXdJIvCeNRGqc45Wr7XKhY1xzXst3T7ycDgaLPCSeesIu2BdqUuqmwIblg+hPd1T2vs /uyw== 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=fScxRg9rCJRGXzRKFXZYIJ1+B/7O2DI4+C7sBTfd7FY=; fh=7Id7wL2M+oCJXD4imOzx4OKioxBXSOZqypDprm7aO4E=; b=u/DXmjuGdxGPpzZ+a9NdOWDdj1fXsAZBmGno1SoLWdfx7n/0ESqgAJIXL4YrL0BQQt CUKVSa66pljpksr81E8RZ+W9ohjqkpp4vtF2IYjaqVKu2Jz+2MzPF3+tgaFWV8cUh+60 JTtWvyvunWDQP52Rp7SRTtDInfqf5z82r3j0eC4SFy3rRsVirI4Ano8zQqO9eH8LT3Zo 1+j2Fztst7FppIhrrjl4TE8yC6pmgMFvUfxqN4FWzcY7NhWuCk3drVl6Yx7yYg0uw861 Z7VD2cuxbsJayyCTZIyXq98EDCKrqYYidKl+xYhUXi9I+roExn96RkU+vNCV8R5TFksb Y+kg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=lJiWKU8A; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 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 lipwig.vger.email (lipwig.vger.email. [2620:137:e000::3:3]) by mx.google.com with ESMTPS id i68-20020a639d47000000b0057d7cff25c7si1341186pgd.417.2023.10.11.20.56.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Oct 2023 20:56:47 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 as permitted sender) client-ip=2620:137:e000::3:3; Authentication-Results: mx.google.com; dkim=pass header.i=@gmail.com header.s=20230601 header.b=lJiWKU8A; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:3 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 lipwig.vger.email (Postfix) with ESMTP id 6696180ABB3C; Wed, 11 Oct 2023 20:55:42 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1376954AbjJLDza (ORCPT + 18 others); Wed, 11 Oct 2023 23:55:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58582 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1376855AbjJLDx5 (ORCPT ); Wed, 11 Oct 2023 23:53:57 -0400 Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC69B1701; Wed, 11 Oct 2023 20:52:02 -0700 (PDT) Received: by mail-pg1-x535.google.com with SMTP id 41be03b00d2f7-577fff1cae6so371555a12.1; Wed, 11 Oct 2023 20:52:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1697082721; x=1697687521; 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=fScxRg9rCJRGXzRKFXZYIJ1+B/7O2DI4+C7sBTfd7FY=; b=lJiWKU8AtS4NCexm+dP94oZiBZ/Q4xH5lY3ICVkrpqZ+JXlq4RLbbkuqAo8u7OipsI hwY4j48BIH/NxjWLnizb8KPPQSp7pCXJK5u7v9L6o07spCCy3OHUX2EHpGOEc0snl91G l2WL3LYhsZIGQ4mb7rX7f4fxYqTlAagRtnwjIwpvsB2XVyU3FJbNfbiAB1QOcIl0wBaw ZeUXTlNow7LSxHhhUM0XgAQX26B1Y8/5fDrlhqawLqiWhWT4CtMP2PJXQSgYeQAeuyHO AMmGh4kV7lWZoC/z24z5wJ9k4+gKGD6Kky8VCgoHvYDFwVPvNNiFTh1/xk+iFcRLLPlT em6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697082721; x=1697687521; 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=fScxRg9rCJRGXzRKFXZYIJ1+B/7O2DI4+C7sBTfd7FY=; b=Iosg88YQSs5GB5bJ+j7P/vVY44ajLhlPVuc2CFr4sKeI9iRlQ5YdFgNsiNQzbQkUUn eVZOnxFvUQSWBmyjnyXw2lqm7MCcoboD/nSUoWOJS+QWOqtgzAFDSZax3BKQc4MKqPB+ TnANHai0A9axMmbf8enwPUqL8r+kYt8nVtkoWP+Lqnkl+Hm9EVyEi4i/r2HPU8Aq06ql 2G+ryIV+HlrnFegXTSQjCg18UnVjoUtmnHFBuLnbDAliHT0aLgJfZDazgSCGOmMUQGn9 VWxVSNRkxFSVU2kM57OT7Dg9EwevCLAIakkDTfXGvzP7Dp00UVu173WPDSpEX0ztFKbH QgSQ== X-Gm-Message-State: AOJu0Yxs/HeMcAqEkqAeqwPaVH9YEfl9Dns/OfcFwx6e3Uf7OmM7wXdz Aoc6AY2BRGEBsV9JQRVQ4Eo= X-Received: by 2002:a17:903:2352:b0:1b8:8682:62fb with SMTP id c18-20020a170903235200b001b8868262fbmr30826465plh.4.1697082720631; Wed, 11 Oct 2023 20:52:00 -0700 (PDT) Received: from bangji.hsd1.ca.comcast.net ([2601:647:6780:42e0:b1b9:d490:2f5e:be06]) by smtp.gmail.com with ESMTPSA id w8-20020a170902d70800b001bc18e579aesm711374ply.101.2023.10.11.20.51.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Oct 2023 20:52:00 -0700 (PDT) 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 , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: [PATCH 35/48] perf dwarf-aux: Handle type transfer for memory access Date: Wed, 11 Oct 2023 20:50:58 -0700 Message-ID: <20231012035111.676789-36-namhyung@kernel.org> X-Mailer: git-send-email 2.42.0.655.g421f12c284-goog In-Reply-To: <20231012035111.676789-1-namhyung@kernel.org> References: <20231012035111.676789-1-namhyung@kernel.org> MIME-Version: 1.0 X-Spam-Status: No, score=-1.0 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lipwig.vger.email 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 (lipwig.vger.email [0.0.0.0]); Wed, 11 Oct 2023 20:55:42 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1779520511460752591 X-GMAIL-MSGID: 1779520511460752591 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. Signed-off-by: Namhyung Kim Acked-by: Masami Hiramatsu (Google) --- 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 16e63d8caf83..5ec895e0a069 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -1838,3 +1838,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 d0ef41738abd..df846bd30134 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 */