From patchwork Wed Jan 22 06:23:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946889 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C32C91A4F22 for ; Wed, 22 Jan 2025 06:23:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527036; cv=none; b=aCi+P8jjR6N7V+h9NeaA6q9iVuE6IGmBoz7RJRlAzVO9igI00/Rlo4JHi4WResf7CSqQ1JP5Yo3EuiewulZqo8McEQsbGw4Iz9J6oYZ0akRKYc11BYJrrCFAKV+LfAEIqLUT5gzT1i4G1Rb9XfbrKrYidnXseGLgv1M9vQ5ZnPg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527036; c=relaxed/simple; bh=HLjYxhTE0ZJA3vcrfmMm7AEqm0+HanoGfKT1dIg80hQ=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=pmdClUIEj3X1fKuyrEXIIld0+nLRjUrVM/z4MNMemjZYkSMBp8ZtAkgspzHebBy7V3dOC53G+dZvU6hgd3ahn3ZCd9qH/nnhaVosIdvAw2g4uIyuFY3XuMnYcbMzAwdJjua/Q/xdZ9TzsraAxP1rwa5pFIsfkVfjG8jZ8ZoL858= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=THCiXvsO; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="THCiXvsO" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-e572df6db3eso14151954276.3 for ; Tue, 21 Jan 2025 22:23:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527034; x=1738131834; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=WWOFr+hD7k+GjJj0c2HJd4uR6zLfGwFEDOqmlnPBFno=; b=THCiXvsO6VNOFTe2tb9Jbg2o+FFHAwnWXdkEh8LvfKjwd/Tsf73eVWQ+kBLkfI4zAt n89OpXlLMhn+7DPnI0qx1KDGxj7wqRhsCu1qFCvuRNwN4xlqAYWbSuT47O11+tsytcSt Abf2cVov/UQ4vCUNIARTMOEREwfTXd8a0e6PQU+jau6LU/2GysctuOWgylbrmprHzrtx EtB8HFP1w3F98vF2TjEhcXpZn1NodGAU4PBLa1UiNmw9+lBuuPWBcLI83MIFqf64OCRA 0Lw1hQgfCElu8Z2fb5zAfeBGY2QTNKeo70B53Rnqh0kThQ7R+q+eYeRXtsUonqFSD0tx wIxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527034; x=1738131834; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=WWOFr+hD7k+GjJj0c2HJd4uR6zLfGwFEDOqmlnPBFno=; b=kJBsv0VHT63Jr7qpfxkGFoTOJnPTuOu+NT7maiSOQW6+K9BhEt/gkS8HwjOO6yGA9A qZihBlhSFw2rPrvYtIB9XN76LbgYURjiPfqxyIqkKb8mkq7toCYLsi15DZZ/ckEkdQBH ugzOvQ8dRAYA2sH10xxTGePXK9LbwOaMzVYV4ON9OVzhoXs5zYSTF1mltGKEJsZwj/Q5 hAlRXxfdWY9kieCb1wGJARRcH6XFqS+S6X/8JqrUxLW+g3iJyaSdvbkYeVkKBfqVrOzv pyfVrsqVng4jIsLoF49pgb3Ay/ZrqIbSjfNa4GF28y4AwdDRyo+X/jgExqgvXsHjN0ZO 0SNA== X-Forwarded-Encrypted: i=1; AJvYcCUAJHh7KVubNMYsdWAik05+i5zFjxaRgZMZs8tkYUQ+VaLsH5QnyFU0wwO95UUHBb7ALkE=@vger.kernel.org X-Gm-Message-State: AOJu0Yy2opoDfMWQjJb/U6QbrQaKUgwvFBdUuSlP4TlWufKD5aEhQxj9 VPK9QStZxDoaULFFenorx6gAwJ2+2eycE5g6g6TplvpdOhYM/nM98F3PGvK5B5QqIMj12WwUZ+x nLvbrxA== X-Google-Smtp-Source: AGHT+IG+2fKJSD9bXucwytV4V3StKpytOSpv10FBbeatTPAofS0m6i9zzGrQqG9RlCLEOmJ8JZYJVNhsnJ3b X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a25:881:0:b0:e57:fb93:606 with SMTP id 3f1490d57ef6-e57fb9309f5mr14706276.0.1737527033629; Tue, 21 Jan 2025 22:23:53 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:16 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-2-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 01/17] perf build: Remove libtracefs configuration From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org libtracefs isn't used by perf but not having it installed causes build warnings. Given the library isn't used, there is no need for the configuration or warnings so remove. Signed-off-by: Ian Rogers --- tools/perf/Makefile.config | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index a148ca9efca9..cd773fbbc176 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -1174,20 +1174,6 @@ ifneq ($(NO_LIBTRACEEVENT),1) else $(error ERROR: libtraceevent is missing. Please install libtraceevent-dev/libtraceevent-devel and/or set LIBTRACEEVENT_DIR or build with NO_LIBTRACEEVENT=1) endif - - ifeq ($(feature-libtracefs), 1) - CFLAGS += $(shell $(PKG_CONFIG) --cflags libtracefs) - LDFLAGS += $(shell $(PKG_CONFIG) --libs-only-L libtracefs) - EXTLIBS += $(shell $(PKG_CONFIG) --libs-only-l libtracefs) - LIBTRACEFS_VERSION := $(shell $(PKG_CONFIG) --modversion libtracefs).0.0 - LIBTRACEFS_VERSION_1 := $(word 1, $(subst ., ,$(LIBTRACEFS_VERSION))) - LIBTRACEFS_VERSION_2 := $(word 2, $(subst ., ,$(LIBTRACEFS_VERSION))) - LIBTRACEFS_VERSION_3 := $(word 3, $(subst ., ,$(LIBTRACEFS_VERSION))) - LIBTRACEFS_VERSION_CPP := $(shell expr $(LIBTRACEFS_VERSION_1) \* 255 \* 255 + $(LIBTRACEFS_VERSION_2) \* 255 + $(LIBTRACEFS_VERSION_3)) - CFLAGS += -DLIBTRACEFS_VERSION=$(LIBTRACEFS_VERSION_CPP) - else - $(warning libtracefs is missing. Please install libtracefs-dev/libtracefs-devel) - endif endif # Among the variables below, these: From patchwork Wed Jan 22 06:23:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946890 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7320C1B0F33 for ; Wed, 22 Jan 2025 06:24:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527045; cv=none; b=PBXGLegfMh4l8FwJ7Cnz+Q04/ybOvMe94U9XWRO4NkhaMWEMGEtZdnsFZP8cgAfe680h2rtBgquKjVO7tmSrunxhpMbrSZjzeHg1+iMAZPh+SG8C638k488824GmxlPYdGuyarZnAA/KaZTZspMc8rgYRmSrepE0yT8AwnNZOWY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527045; c=relaxed/simple; bh=Qmq55MBFFDlIdUOT+YCdRI2WTxYpsmxURFZ8UOnIG5k=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=TKyUPX+7CUgoQq7JnMzQOat0XDGB6Q3gntjca5TdD9Kt6fgf2NEzUzXAVBNeVblfOF4xyRx1mna63XY37X28QkHwvmqVgQB4UCHamuXATlgs+HWS1qjzfaGtdAskAlyct2gHkhC+1ETyDwUqa38/jbpRZ57qMAZqZSV6Ydz2YnI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=OEcwJO/P; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="OEcwJO/P" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e3a0f608b88so14681857276.0 for ; Tue, 21 Jan 2025 22:24:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527042; x=1738131842; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=kWzjT8BGnYGxE3H8fS5inyNnD+mPb+JDTto8cogfHm8=; b=OEcwJO/PcJ7tCjmdFyihQKTJaN5sxCvk7mIuXM2aKP7ArHVL3TWemg1jcgWQouMca/ JM7ZXjPYR88nyOpGvf99pk4JBPbHtxzmIhMNB66zqBXKlcqx1ecBgJze3UjTPMWfMl7r XaXXnOnsytFzllX6bRFYr4nd3A/H2pqF769GaBqVmsep+H/j+Q0JibbkxKPpRBeYCXCo FBPQS2tI1wxEIQZYOGYCaJTvZvjevQQ4RY21JUL8bijKww3iNvuyUd5saq2ihQoWAS+M u6sgTQynzJMoTbThTtdPzSelYcyY0Qp28QiG86/B0KEzNJ7z6ZpO5Gju/QpxHOhZciVA Inhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527042; x=1738131842; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=kWzjT8BGnYGxE3H8fS5inyNnD+mPb+JDTto8cogfHm8=; b=rADtJL5BuXP70F8cwrOO7NU+NHWhH4nHHLnMuRRgIer1LsdoqDjftjm2ty9pD6zSfA w+XtvM4h6K/++dqRkgzajWqzHS+vFa4wQ6vupHTFTclYtyt4ENu5idcclLPNdzZobwEu /D8WpJEVkno+jXD12TGDIlp7QlNqk1dA9oaiZR3Eig1S/OHzkpyUbywWmzV36ZXOJIVZ nKskO7JZxiw2yMl/Ml2GgxBKh0D11H0HHKmldRtyXqP69f2jEy278DWc+sP9rKjeGPKt yIp6zyepNulmWy0KXPIBkFRB+8vXvnaY0M90YPR7VqnKws9svmvRBJIXe2cG3xVSZe0U 0nTg== X-Forwarded-Encrypted: i=1; AJvYcCV+PnmabzYB1g3rqnZnAi1j4qhOjuiETsYCFG9PJXWtztcFQeYgsf2DIoMjoFTQ5rr4twA=@vger.kernel.org X-Gm-Message-State: AOJu0Yx62ydZXjhVlYu9i8PGE34Z+qix5ZUcX5/kEwpgaEyLm2zl+Brw J3IxvQQulxpY+OHTYU3/ILVezGTXkGJaOQix/AUOAZvP9toY6mIK4pcjdrpbuq+KP6KtGJDXduz WtbLCNA== X-Google-Smtp-Source: AGHT+IEkQrVl+S1ecATwU/x39/z+G48tsIZyI5LDZqnLUZLk9fS8HATbtR2ta/8MhmTWSqrSAgqjrw5VZEOC X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a25:538a:0:b0:e39:91bc:eef5 with SMTP id 3f1490d57ef6-e57b103b91emr42227276.2.1737527042387; Tue, 21 Jan 2025 22:24:02 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:17 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-3-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 02/17] perf map: Constify objdump offset/address conversion APIs From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org Make the map argument const as the conversion act won't modify the map and this allows other callers to use a const struct map. Signed-off-by: Ian Rogers --- tools/perf/util/map.c | 19 +++++++++++++++---- tools/perf/util/map.h | 6 +++--- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index d729438b7d65..a22a423792d7 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -514,6 +514,8 @@ void srccode_state_free(struct srccode_state *state) state->line = 0; } +static const struct kmap *__map__const_kmap(const struct map *map); + /** * map__rip_2objdump - convert symbol start address to objdump address. * @map: memory map @@ -525,9 +527,9 @@ void srccode_state_free(struct srccode_state *state) * * Return: Address suitable for passing to "objdump --start-address=" */ -u64 map__rip_2objdump(struct map *map, u64 rip) +u64 map__rip_2objdump(const struct map *map, u64 rip) { - struct kmap *kmap = __map__kmap(map); + const struct kmap *kmap = __map__const_kmap(map); const struct dso *dso = map__dso(map); /* @@ -570,7 +572,7 @@ u64 map__rip_2objdump(struct map *map, u64 rip) * * Return: Memory address. */ -u64 map__objdump_2mem(struct map *map, u64 ip) +u64 map__objdump_2mem(const struct map *map, u64 ip) { const struct dso *dso = map__dso(map); @@ -587,7 +589,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip) } /* convert objdump address to relative address. (To be removed) */ -u64 map__objdump_2rip(struct map *map, u64 ip) +u64 map__objdump_2rip(const struct map *map, u64 ip) { const struct dso *dso = map__dso(map); @@ -619,6 +621,15 @@ struct kmap *__map__kmap(struct map *map) return (struct kmap *)(&RC_CHK_ACCESS(map)[1]); } +static const struct kmap *__map__const_kmap(const struct map *map) +{ + const struct dso *dso = map__dso(map); + + if (!dso || !dso__kernel(dso)) + return NULL; + return (struct kmap *)(&RC_CHK_ACCESS(map)[1]); +} + struct kmap *map__kmap(struct map *map) { struct kmap *kmap = __map__kmap(map); diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 4262f5a143be..768501eec70e 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h @@ -133,13 +133,13 @@ static inline u64 map__unmap_ip(const struct map *map, u64 ip_or_rip) } /* rip/ip <-> addr suitable for passing to `objdump --start-address=` */ -u64 map__rip_2objdump(struct map *map, u64 rip); +u64 map__rip_2objdump(const struct map *map, u64 rip); /* objdump address -> memory address */ -u64 map__objdump_2mem(struct map *map, u64 ip); +u64 map__objdump_2mem(const struct map *map, u64 ip); /* objdump address -> rip */ -u64 map__objdump_2rip(struct map *map, u64 ip); +u64 map__objdump_2rip(const struct map *map, u64 ip); struct symbol; struct thread; From patchwork Wed Jan 22 06:23:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946891 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 553471922F4 for ; Wed, 22 Jan 2025 06:24:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527055; cv=none; b=fxd5L+1w2fm8j/mdhQVNY/yZ7Uj/xLquj67asr9BmRyf6er3MxCyRqo7uCKsvMWLb0NMcWqri/pkQEX9PpxC7NP8TmPos7uAV0O0LaZMwIwXz0IeTAG4umZc8KCN8T+m26K7M0ClrMqSm8tu7KHwsgELOARIW3K+37uFl2eAy70= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527055; c=relaxed/simple; bh=vFb+HyGIMnTuE4+8yPur8hNT1aQ25ULyLOvz1kWdv/8=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=szocx37KXxuOIfE/RcM/MaOQJ9CXySkrlJIARTRIb8jq2LFR3AHa1O+VMgISq8hzV61tVFq+ch1Wgid+V5miZIytALtYa9SN9MYhXCjxkB14bJuK3GZZO0zjQ/gBIgntZ74YsfumWo8VOLoIWAQoxiycHRDbxzv2D62YnjGNh3k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=2ePCui7c; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="2ePCui7c" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-e5799401f12so13942129276.0 for ; Tue, 21 Jan 2025 22:24:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527052; x=1738131852; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=V/Xkh0A7UQ6xsQQnl38+jJR7kMCb05O19GL71kRj76o=; b=2ePCui7chSNYITPY2OazZTTu8F5iMJgBXOgNvbFDjezI/FGTlmUMtMyMc0ePcy8GY8 xr58O452IdoEXy7dADA2nST8cS/umt0so7+ZeOaX8rwUtcdDtzLLEx7kXuIuZWHJYJNf eqv/R9HU6DVDqxpTArWuRIFvAQUrAy2eK/6RNOalHDGpCcPJNSj1er2wgh9rJ+XEy7+c M7eBPNeEHFFewuSleTfeJCdMvXovYIjyByw0yMA/SCQ5TntLP5lHzU8DmFvT0TQk9Y9p R3yfC+d3tmGGl07AecCKH9iQVDmUqkk7jV3mxE11um4ZT9MJSle9Y+g1YmoZNSCgnoGi Nj0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527052; x=1738131852; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=V/Xkh0A7UQ6xsQQnl38+jJR7kMCb05O19GL71kRj76o=; b=mJa2NG/0jmu1+vIOjY1i+1GHc2HPqzDWqsJtsM9j63zNCNKQQjmxbN6+dCBGUZQYqQ KsnBKwiP3zy8ih4pIP8mND0p6rOCjl0+7WYqWGniiO2p6IJ5T0hgDBtViXqgxafmgqqY 5XliirHzI6J2aWywW7JSjQlDFAyjuVLusnh4PMLNSquRC7m+nH0Lg3fDFE0rfpR4GI8e U1SpFG2IT7NvkOwDJ2P82bFtIo5bxISnWjzMGqAC/o8SoYyTNPsCGG2GYCv9akCJ4NwK jmUJWElCdpzCDMC/fV9AfoePxvdTWbQcwaoXZGxa9qFGoXwPuLUo+HGSOSO82uu0rPeP gLkA== X-Forwarded-Encrypted: i=1; AJvYcCVYKVSGMg6ntO18XGSGs3f1PLSDvcdOLv+FFeh3y4Q5gHzoJv9koijfSXC30JyaCoI56QQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwwkLGEmJD7lvR2QuWjeleYWl/oOgnqcik73jz5n6wpgrCL3x1V 6t7mTne3o8acGIa4apzljKL70ZgfLb6xVzAzoVTU0sScQ2cUPVqkoZyfWs+kS3Et+gS0PhpIVhR vzPoI7A== X-Google-Smtp-Source: AGHT+IEpCMP3xuDb6S3I6xdW9UBjl5UYkf2X5DmguPd3jZmu+4fP/uRDDLWB1ip9iJeqpSaDUpzp2mVE2aKb X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a05:690c:7306:b0:6f0:22ad:43f8 with SMTP id 00721157ae682-6f6eb953485mr540447b3.7.1737527052060; Tue, 21 Jan 2025 22:24:12 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:18 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-4-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 03/17] perf capstone: Move capstone functionality into its own file From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org Capstone disassembly support was split between disasm.c and print_insn.c. Move support out of these files into capstone.[ch] and remove include capstone/capstone.h from those files. As disassembly routines can fail, make failure the only option without HAVE_LIBCAPSTONE_SUPPORT. For simplicity's sake, duplicate the read_symbol utility function. The intent with moving capstone support into a single file is that dynamic support, using dlopen for libcapstone, can be added in later patches. This can potentially always succeed or fail, so relying on ifdefs isn't sufficient. Using dlopen is a useful option to minimize the perf tools dependencies and potentially size. Signed-off-by: Ian Rogers --- tools/perf/builtin-script.c | 2 - tools/perf/util/Build | 1 + tools/perf/util/capstone.c | 536 +++++++++++++++++++++++++++++++++++ tools/perf/util/capstone.h | 24 ++ tools/perf/util/disasm.c | 358 +---------------------- tools/perf/util/print_insn.c | 117 +------- 6 files changed, 569 insertions(+), 469 deletions(-) create mode 100644 tools/perf/util/capstone.c create mode 100644 tools/perf/util/capstone.h diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 33667b534634..f05b2b70d5a7 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1200,7 +1200,6 @@ static int any_dump_insn(struct evsel *evsel __maybe_unused, u8 *inbuf, int inlen, int *lenp, FILE *fp) { -#ifdef HAVE_LIBCAPSTONE_SUPPORT if (PRINT_FIELD(BRSTACKDISASM)) { int printed = fprintf_insn_asm(x->machine, x->thread, x->cpumode, x->is64bit, (uint8_t *)inbuf, inlen, ip, lenp, @@ -1209,7 +1208,6 @@ static int any_dump_insn(struct evsel *evsel __maybe_unused, if (printed > 0) return printed; } -#endif return fprintf(fp, "%s", dump_insn(x, ip, inbuf, inlen, lenp)); } diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 5ec97e8d6b6d..9542decf9625 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -8,6 +8,7 @@ perf-util-y += block-info.o perf-util-y += block-range.o perf-util-y += build-id.o perf-util-y += cacheline.o +perf-util-y += capstone.o perf-util-y += config.o perf-util-y += copyfile.o perf-util-y += ctype.o diff --git a/tools/perf/util/capstone.c b/tools/perf/util/capstone.c new file mode 100644 index 000000000000..c0a6d94ebc18 --- /dev/null +++ b/tools/perf/util/capstone.c @@ -0,0 +1,536 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "capstone.h" +#include "annotate.h" +#include "addr_location.h" +#include "debug.h" +#include "disasm.h" +#include "dso.h" +#include "machine.h" +#include "map.h" +#include "namespaces.h" +#include "print_insn.h" +#include "symbol.h" +#include "thread.h" +#include +#include + +#ifdef HAVE_LIBCAPSTONE_SUPPORT +#include +#endif + +#ifdef HAVE_LIBCAPSTONE_SUPPORT +static int capstone_init(struct machine *machine, csh *cs_handle, bool is64, + bool disassembler_style) +{ + cs_arch arch; + cs_mode mode; + + if (machine__is(machine, "x86_64") && is64) { + arch = CS_ARCH_X86; + mode = CS_MODE_64; + } else if (machine__normalized_is(machine, "x86")) { + arch = CS_ARCH_X86; + mode = CS_MODE_32; + } else if (machine__normalized_is(machine, "arm64")) { + arch = CS_ARCH_ARM64; + mode = CS_MODE_ARM; + } else if (machine__normalized_is(machine, "arm")) { + arch = CS_ARCH_ARM; + mode = CS_MODE_ARM + CS_MODE_V8; + } else if (machine__normalized_is(machine, "s390")) { + arch = CS_ARCH_SYSZ; + mode = CS_MODE_BIG_ENDIAN; + } else { + return -1; + } + + if (cs_open(arch, mode, cs_handle) != CS_ERR_OK) { + pr_warning_once("cs_open failed\n"); + return -1; + } + + if (machine__normalized_is(machine, "x86")) { + /* + * In case of using capstone_init while symbol__disassemble + * setting CS_OPT_SYNTAX_ATT depends if disassembler_style opts + * is set via annotation args + */ + if (disassembler_style) + cs_option(*cs_handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); + /* + * Resolving address operands to symbols is implemented + * on x86 by investigating instruction details. + */ + cs_option(*cs_handle, CS_OPT_DETAIL, CS_OPT_ON); + } + + return 0; +} +#endif + +#ifdef HAVE_LIBCAPSTONE_SUPPORT +static size_t print_insn_x86(struct thread *thread, u8 cpumode, cs_insn *insn, + int print_opts, FILE *fp) +{ + struct addr_location al; + size_t printed = 0; + + if (insn->detail && insn->detail->x86.op_count == 1) { + cs_x86_op *op = &insn->detail->x86.operands[0]; + + addr_location__init(&al); + if (op->type == X86_OP_IMM && + thread__find_symbol(thread, cpumode, op->imm, &al)) { + printed += fprintf(fp, "%s ", insn[0].mnemonic); + printed += symbol__fprintf_symname_offs(al.sym, &al, fp); + if (print_opts & PRINT_INSN_IMM_HEX) + printed += fprintf(fp, " [%#" PRIx64 "]", op->imm); + addr_location__exit(&al); + return printed; + } + addr_location__exit(&al); + } + + printed += fprintf(fp, "%s %s", insn[0].mnemonic, insn[0].op_str); + return printed; +} +#endif + + +ssize_t capstone__fprintf_insn_asm(struct machine *machine __maybe_unused, + struct thread *thread __maybe_unused, + u8 cpumode __maybe_unused, bool is64bit __maybe_unused, + const uint8_t *code __maybe_unused, + size_t code_size __maybe_unused, + uint64_t ip __maybe_unused, int *lenp __maybe_unused, + int print_opts __maybe_unused, FILE *fp __maybe_unused) +{ +#ifdef HAVE_LIBCAPSTONE_SUPPORT + size_t printed; + cs_insn *insn; + csh cs_handle; + size_t count; + int ret; + + /* TODO: Try to initiate capstone only once but need a proper place. */ + ret = capstone_init(machine, &cs_handle, is64bit, true); + if (ret < 0) + return ret; + + count = cs_disasm(cs_handle, code, code_size, ip, 1, &insn); + if (count > 0) { + if (machine__normalized_is(machine, "x86")) + printed = print_insn_x86(thread, cpumode, &insn[0], print_opts, fp); + else + printed = fprintf(fp, "%s %s", insn[0].mnemonic, insn[0].op_str); + if (lenp) + *lenp = insn->size; + cs_free(insn, count); + } else { + printed = -1; + } + + cs_close(&cs_handle); + return printed; +#else + return -1; +#endif +} + +#ifdef HAVE_LIBCAPSTONE_SUPPORT +static int open_capstone_handle(struct annotate_args *args, bool is_64bit, csh *handle) +{ + struct annotation_options *opt = args->options; + cs_mode mode = is_64bit ? CS_MODE_64 : CS_MODE_32; + + /* TODO: support more architectures */ + if (!arch__is(args->arch, "x86")) + return -1; + + if (cs_open(CS_ARCH_X86, mode, handle) != CS_ERR_OK) + return -1; + + if (!opt->disassembler_style || + !strcmp(opt->disassembler_style, "att")) + cs_option(*handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); + + /* + * Resolving address operands to symbols is implemented + * on x86 by investigating instruction details. + */ + cs_option(*handle, CS_OPT_DETAIL, CS_OPT_ON); + + return 0; +} +#endif + +#ifdef HAVE_LIBCAPSTONE_SUPPORT +static void print_capstone_detail(cs_insn *insn, char *buf, size_t len, + struct annotate_args *args, u64 addr) +{ + int i; + struct map *map = args->ms.map; + struct symbol *sym; + + /* TODO: support more architectures */ + if (!arch__is(args->arch, "x86")) + return; + + if (insn->detail == NULL) + return; + + for (i = 0; i < insn->detail->x86.op_count; i++) { + cs_x86_op *op = &insn->detail->x86.operands[i]; + u64 orig_addr; + + if (op->type != X86_OP_MEM) + continue; + + /* only print RIP-based global symbols for now */ + if (op->mem.base != X86_REG_RIP) + continue; + + /* get the target address */ + orig_addr = addr + insn->size + op->mem.disp; + addr = map__objdump_2mem(map, orig_addr); + + if (dso__kernel(map__dso(map))) { + /* + * The kernel maps can be splitted into sections, + * let's find the map first and the search the symbol. + */ + map = maps__find(map__kmaps(map), addr); + if (map == NULL) + continue; + } + + /* convert it to map-relative address for search */ + addr = map__map_ip(map, addr); + + sym = map__find_symbol(map, addr); + if (sym == NULL) + continue; + + if (addr == sym->start) { + scnprintf(buf, len, "\t# %"PRIx64" <%s>", + orig_addr, sym->name); + } else { + scnprintf(buf, len, "\t# %"PRIx64" <%s+%#"PRIx64">", + orig_addr, sym->name, addr - sym->start); + } + break; + } +} +#endif + +#ifdef HAVE_LIBCAPSTONE_SUPPORT +struct find_file_offset_data { + u64 ip; + u64 offset; +}; + +/* This will be called for each PHDR in an ELF binary */ +static int find_file_offset(u64 start, u64 len, u64 pgoff, void *arg) +{ + struct find_file_offset_data *data = arg; + + if (start <= data->ip && data->ip < start + len) { + data->offset = pgoff + data->ip - start; + return 1; + } + return 0; +} +#endif + +#ifdef HAVE_LIBCAPSTONE_SUPPORT +static u8 * +read_symbol(const char *filename, struct map *map, struct symbol *sym, + u64 *len, bool *is_64bit) +{ + struct dso *dso = map__dso(map); + struct nscookie nsc; + u64 start = map__rip_2objdump(map, sym->start); + u64 end = map__rip_2objdump(map, sym->end); + int fd, count; + u8 *buf = NULL; + struct find_file_offset_data data = { + .ip = start, + }; + + *is_64bit = false; + + nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); + fd = open(filename, O_RDONLY); + nsinfo__mountns_exit(&nsc); + if (fd < 0) + return NULL; + + if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, + is_64bit) == 0) + goto err; + + *len = end - start; + buf = malloc(*len); + if (buf == NULL) + goto err; + + count = pread(fd, buf, *len, data.offset); + close(fd); + fd = -1; + + if ((u64)count != *len) + goto err; + + return buf; + +err: + if (fd >= 0) + close(fd); + free(buf); + return NULL; +} +#endif + +int symbol__disassemble_capstone(const char *filename __maybe_unused, + struct symbol *sym __maybe_unused, + struct annotate_args *args __maybe_unused) +{ +#ifdef HAVE_LIBCAPSTONE_SUPPORT + struct annotation *notes = symbol__annotation(sym); + struct map *map = args->ms.map; + u64 start = map__rip_2objdump(map, sym->start); + u64 len; + u64 offset; + int i, count, free_count; + bool is_64bit = false; + bool needs_cs_close = false; + u8 *buf = NULL; + csh handle; + cs_insn *insn = NULL; + char disasm_buf[512]; + struct disasm_line *dl; + + if (args->options->objdump_path) + return -1; + + buf = read_symbol(filename, map, sym, &len, &is_64bit); + if (buf == NULL) + return -1; + + /* add the function address and name */ + scnprintf(disasm_buf, sizeof(disasm_buf), "%#"PRIx64" <%s>:", + start, sym->name); + + args->offset = -1; + args->line = disasm_buf; + args->line_nr = 0; + args->fileloc = NULL; + args->ms.sym = sym; + + dl = disasm_line__new(args); + if (dl == NULL) + goto err; + + annotation_line__add(&dl->al, ¬es->src->source); + + if (open_capstone_handle(args, is_64bit, &handle) < 0) + goto err; + + needs_cs_close = true; + + free_count = count = cs_disasm(handle, buf, len, start, len, &insn); + for (i = 0, offset = 0; i < count; i++) { + int printed; + + printed = scnprintf(disasm_buf, sizeof(disasm_buf), + " %-7s %s", + insn[i].mnemonic, insn[i].op_str); + print_capstone_detail(&insn[i], disasm_buf + printed, + sizeof(disasm_buf) - printed, args, + start + offset); + + args->offset = offset; + args->line = disasm_buf; + + dl = disasm_line__new(args); + if (dl == NULL) + goto err; + + annotation_line__add(&dl->al, ¬es->src->source); + + offset += insn[i].size; + } + + /* It failed in the middle: probably due to unknown instructions */ + if (offset != len) { + struct list_head *list = ¬es->src->source; + + /* Discard all lines and fallback to objdump */ + while (!list_empty(list)) { + dl = list_first_entry(list, struct disasm_line, al.node); + + list_del_init(&dl->al.node); + disasm_line__free(dl); + } + count = -1; + } + +out: + if (needs_cs_close) { + cs_close(&handle); + if (free_count > 0) + cs_free(insn, free_count); + } + free(buf); + return count < 0 ? count : 0; + +err: + if (needs_cs_close) { + struct disasm_line *tmp; + + /* + * It probably failed in the middle of the above loop. + * Release any resources it might add. + */ + list_for_each_entry_safe(dl, tmp, ¬es->src->source, al.node) { + list_del(&dl->al.node); + disasm_line__free(dl); + } + } + count = -1; + goto out; +#else + return -1; +#endif +} + +int symbol__disassemble_capstone_powerpc(const char *filename __maybe_unused, + struct symbol *sym __maybe_unused, + struct annotate_args *args __maybe_unused) +{ +#ifdef HAVE_LIBCAPSTONE_SUPPORT + struct annotation *notes = symbol__annotation(sym); + struct map *map = args->ms.map; + struct dso *dso = map__dso(map); + struct nscookie nsc; + u64 start = map__rip_2objdump(map, sym->start); + u64 end = map__rip_2objdump(map, sym->end); + u64 len = end - start; + u64 offset; + int i, fd, count; + bool is_64bit = false; + bool needs_cs_close = false; + u8 *buf = NULL; + struct find_file_offset_data data = { + .ip = start, + }; + csh handle; + char disasm_buf[512]; + struct disasm_line *dl; + u32 *line; + bool disassembler_style = false; + + if (args->options->objdump_path) + return -1; + + nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); + fd = open(filename, O_RDONLY); + nsinfo__mountns_exit(&nsc); + if (fd < 0) + return -1; + + if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, + &is_64bit) == 0) + goto err; + + if (!args->options->disassembler_style || + !strcmp(args->options->disassembler_style, "att")) + disassembler_style = true; + + if (capstone_init(maps__machine(args->ms.maps), &handle, is_64bit, disassembler_style) < 0) + goto err; + + needs_cs_close = true; + + buf = malloc(len); + if (buf == NULL) + goto err; + + count = pread(fd, buf, len, data.offset); + close(fd); + fd = -1; + + if ((u64)count != len) + goto err; + + line = (u32 *)buf; + + /* add the function address and name */ + scnprintf(disasm_buf, sizeof(disasm_buf), "%#"PRIx64" <%s>:", + start, sym->name); + + args->offset = -1; + args->line = disasm_buf; + args->line_nr = 0; + args->fileloc = NULL; + args->ms.sym = sym; + + dl = disasm_line__new(args); + if (dl == NULL) + goto err; + + annotation_line__add(&dl->al, ¬es->src->source); + + /* + * TODO: enable disassm for powerpc + * count = cs_disasm(handle, buf, len, start, len, &insn); + * + * For now, only binary code is saved in disassembled line + * to be used in "type" and "typeoff" sort keys. Each raw code + * is 32 bit instruction. So use "len/4" to get the number of + * entries. + */ + count = len/4; + + for (i = 0, offset = 0; i < count; i++) { + args->offset = offset; + sprintf(args->line, "%x", line[i]); + + dl = disasm_line__new(args); + if (dl == NULL) + break; + + annotation_line__add(&dl->al, ¬es->src->source); + + offset += 4; + } + + /* It failed in the middle */ + if (offset != len) { + struct list_head *list = ¬es->src->source; + + /* Discard all lines and fallback to objdump */ + while (!list_empty(list)) { + dl = list_first_entry(list, struct disasm_line, al.node); + + list_del_init(&dl->al.node); + disasm_line__free(dl); + } + count = -1; + } + +out: + if (needs_cs_close) + cs_close(&handle); + free(buf); + return count < 0 ? count : 0; + +err: + if (fd >= 0) + close(fd); + count = -1; + goto out; +#else + return -1; +#endif +} diff --git a/tools/perf/util/capstone.h b/tools/perf/util/capstone.h new file mode 100644 index 000000000000..0f030ea034b6 --- /dev/null +++ b/tools/perf/util/capstone.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_CAPSTONE_H +#define __PERF_CAPSTONE_H + +#include +#include +#include +#include +#include + +struct annotate_args; +struct machine; +struct symbol; +struct thread; + +ssize_t capstone__fprintf_insn_asm(struct machine *machine, struct thread *thread, u8 cpumode, + bool is64bit, const uint8_t *code, size_t code_size, + uint64_t ip, int *lenp, int print_opts, FILE *fp); +int symbol__disassemble_capstone(const char *filename, struct symbol *sym, + struct annotate_args *args); +int symbol__disassemble_capstone_powerpc(const char *filename, struct symbol *sym, + struct annotate_args *args); + +#endif /* __PERF_CAPSTONE_H */ diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index b7de4d9fd004..0e5881189ae8 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -14,6 +14,7 @@ #include "annotate.h" #include "annotate-data.h" #include "build-id.h" +#include "capstone.h" #include "debug.h" #include "disasm.h" #include "disasm_bpf.h" @@ -1329,39 +1330,7 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil return 0; } -#ifdef HAVE_LIBCAPSTONE_SUPPORT -#include - -int capstone_init(struct machine *machine, csh *cs_handle, bool is64, bool disassembler_style); - -static int open_capstone_handle(struct annotate_args *args, bool is_64bit, - csh *handle) -{ - struct annotation_options *opt = args->options; - cs_mode mode = is_64bit ? CS_MODE_64 : CS_MODE_32; - - /* TODO: support more architectures */ - if (!arch__is(args->arch, "x86")) - return -1; - - if (cs_open(CS_ARCH_X86, mode, handle) != CS_ERR_OK) - return -1; - - if (!opt->disassembler_style || - !strcmp(opt->disassembler_style, "att")) - cs_option(*handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); - - /* - * Resolving address operands to symbols is implemented - * on x86 by investigating instruction details. - */ - cs_option(*handle, CS_OPT_DETAIL, CS_OPT_ON); - - return 0; -} -#endif - -#if defined(HAVE_LIBCAPSTONE_SUPPORT) || defined(HAVE_LIBLLVM_SUPPORT) +#if defined(HAVE_LIBLLVM_SUPPORT) struct find_file_offset_data { u64 ip; u64 offset; @@ -1427,322 +1396,6 @@ read_symbol(const char *filename, struct map *map, struct symbol *sym, } #endif -#if !defined(HAVE_LIBCAPSTONE_SUPPORT) || !defined(HAVE_LIBLLVM_SUPPORT) -static void symbol__disassembler_missing(const char *disassembler, const char *filename, - struct symbol *sym) -{ - pr_debug("The %s disassembler isn't linked in for %s in %s\n", - disassembler, sym->name, filename); -} -#endif - -#ifdef HAVE_LIBCAPSTONE_SUPPORT -static void print_capstone_detail(cs_insn *insn, char *buf, size_t len, - struct annotate_args *args, u64 addr) -{ - int i; - struct map *map = args->ms.map; - struct symbol *sym; - - /* TODO: support more architectures */ - if (!arch__is(args->arch, "x86")) - return; - - if (insn->detail == NULL) - return; - - for (i = 0; i < insn->detail->x86.op_count; i++) { - cs_x86_op *op = &insn->detail->x86.operands[i]; - u64 orig_addr; - - if (op->type != X86_OP_MEM) - continue; - - /* only print RIP-based global symbols for now */ - if (op->mem.base != X86_REG_RIP) - continue; - - /* get the target address */ - orig_addr = addr + insn->size + op->mem.disp; - addr = map__objdump_2mem(map, orig_addr); - - if (dso__kernel(map__dso(map))) { - /* - * The kernel maps can be splitted into sections, - * let's find the map first and the search the symbol. - */ - map = maps__find(map__kmaps(map), addr); - if (map == NULL) - continue; - } - - /* convert it to map-relative address for search */ - addr = map__map_ip(map, addr); - - sym = map__find_symbol(map, addr); - if (sym == NULL) - continue; - - if (addr == sym->start) { - scnprintf(buf, len, "\t# %"PRIx64" <%s>", - orig_addr, sym->name); - } else { - scnprintf(buf, len, "\t# %"PRIx64" <%s+%#"PRIx64">", - orig_addr, sym->name, addr - sym->start); - } - break; - } -} - -static int symbol__disassemble_capstone_powerpc(char *filename, struct symbol *sym, - struct annotate_args *args) -{ - struct annotation *notes = symbol__annotation(sym); - struct map *map = args->ms.map; - struct dso *dso = map__dso(map); - struct nscookie nsc; - u64 start = map__rip_2objdump(map, sym->start); - u64 end = map__rip_2objdump(map, sym->end); - u64 len = end - start; - u64 offset; - int i, fd, count; - bool is_64bit = false; - bool needs_cs_close = false; - u8 *buf = NULL; - struct find_file_offset_data data = { - .ip = start, - }; - csh handle; - char disasm_buf[512]; - struct disasm_line *dl; - u32 *line; - bool disassembler_style = false; - - if (args->options->objdump_path) - return -1; - - nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); - fd = open(filename, O_RDONLY); - nsinfo__mountns_exit(&nsc); - if (fd < 0) - return -1; - - if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, - &is_64bit) == 0) - goto err; - - if (!args->options->disassembler_style || - !strcmp(args->options->disassembler_style, "att")) - disassembler_style = true; - - if (capstone_init(maps__machine(args->ms.maps), &handle, is_64bit, disassembler_style) < 0) - goto err; - - needs_cs_close = true; - - buf = malloc(len); - if (buf == NULL) - goto err; - - count = pread(fd, buf, len, data.offset); - close(fd); - fd = -1; - - if ((u64)count != len) - goto err; - - line = (u32 *)buf; - - /* add the function address and name */ - scnprintf(disasm_buf, sizeof(disasm_buf), "%#"PRIx64" <%s>:", - start, sym->name); - - args->offset = -1; - args->line = disasm_buf; - args->line_nr = 0; - args->fileloc = NULL; - args->ms.sym = sym; - - dl = disasm_line__new(args); - if (dl == NULL) - goto err; - - annotation_line__add(&dl->al, ¬es->src->source); - - /* - * TODO: enable disassm for powerpc - * count = cs_disasm(handle, buf, len, start, len, &insn); - * - * For now, only binary code is saved in disassembled line - * to be used in "type" and "typeoff" sort keys. Each raw code - * is 32 bit instruction. So use "len/4" to get the number of - * entries. - */ - count = len/4; - - for (i = 0, offset = 0; i < count; i++) { - args->offset = offset; - sprintf(args->line, "%x", line[i]); - - dl = disasm_line__new(args); - if (dl == NULL) - break; - - annotation_line__add(&dl->al, ¬es->src->source); - - offset += 4; - } - - /* It failed in the middle */ - if (offset != len) { - struct list_head *list = ¬es->src->source; - - /* Discard all lines and fallback to objdump */ - while (!list_empty(list)) { - dl = list_first_entry(list, struct disasm_line, al.node); - - list_del_init(&dl->al.node); - disasm_line__free(dl); - } - count = -1; - } - -out: - if (needs_cs_close) - cs_close(&handle); - free(buf); - return count < 0 ? count : 0; - -err: - if (fd >= 0) - close(fd); - count = -1; - goto out; -} - -static int symbol__disassemble_capstone(char *filename, struct symbol *sym, - struct annotate_args *args) -{ - struct annotation *notes = symbol__annotation(sym); - struct map *map = args->ms.map; - u64 start = map__rip_2objdump(map, sym->start); - u64 len; - u64 offset; - int i, count, free_count; - bool is_64bit = false; - bool needs_cs_close = false; - u8 *buf = NULL; - csh handle; - cs_insn *insn = NULL; - char disasm_buf[512]; - struct disasm_line *dl; - - if (args->options->objdump_path) - return -1; - - buf = read_symbol(filename, map, sym, &len, &is_64bit); - if (buf == NULL) - return -1; - - /* add the function address and name */ - scnprintf(disasm_buf, sizeof(disasm_buf), "%#"PRIx64" <%s>:", - start, sym->name); - - args->offset = -1; - args->line = disasm_buf; - args->line_nr = 0; - args->fileloc = NULL; - args->ms.sym = sym; - - dl = disasm_line__new(args); - if (dl == NULL) - goto err; - - annotation_line__add(&dl->al, ¬es->src->source); - - if (open_capstone_handle(args, is_64bit, &handle) < 0) - goto err; - - needs_cs_close = true; - - free_count = count = cs_disasm(handle, buf, len, start, len, &insn); - for (i = 0, offset = 0; i < count; i++) { - int printed; - - printed = scnprintf(disasm_buf, sizeof(disasm_buf), - " %-7s %s", - insn[i].mnemonic, insn[i].op_str); - print_capstone_detail(&insn[i], disasm_buf + printed, - sizeof(disasm_buf) - printed, args, - start + offset); - - args->offset = offset; - args->line = disasm_buf; - - dl = disasm_line__new(args); - if (dl == NULL) - goto err; - - annotation_line__add(&dl->al, ¬es->src->source); - - offset += insn[i].size; - } - - /* It failed in the middle: probably due to unknown instructions */ - if (offset != len) { - struct list_head *list = ¬es->src->source; - - /* Discard all lines and fallback to objdump */ - while (!list_empty(list)) { - dl = list_first_entry(list, struct disasm_line, al.node); - - list_del_init(&dl->al.node); - disasm_line__free(dl); - } - count = -1; - } - -out: - if (needs_cs_close) { - cs_close(&handle); - if (free_count > 0) - cs_free(insn, free_count); - } - free(buf); - return count < 0 ? count : 0; - -err: - if (needs_cs_close) { - struct disasm_line *tmp; - - /* - * It probably failed in the middle of the above loop. - * Release any resources it might add. - */ - list_for_each_entry_safe(dl, tmp, ¬es->src->source, al.node) { - list_del(&dl->al.node); - disasm_line__free(dl); - } - } - count = -1; - goto out; -} -#else // HAVE_LIBCAPSTONE_SUPPORT -static int symbol__disassemble_capstone(char *filename, struct symbol *sym, - struct annotate_args *args __maybe_unused) -{ - symbol__disassembler_missing("capstone", filename, sym); - return -1; -} - -static int symbol__disassemble_capstone_powerpc(char *filename, struct symbol *sym, - struct annotate_args *args __maybe_unused) -{ - symbol__disassembler_missing("capstone powerpc", filename, sym); - return -1; -} -#endif // HAVE_LIBCAPSTONE_SUPPORT - static int symbol__disassemble_raw(char *filename, struct symbol *sym, struct annotate_args *args) { @@ -2010,10 +1663,11 @@ static int symbol__disassemble_llvm(char *filename, struct symbol *sym, return ret; } #else // HAVE_LIBLLVM_SUPPORT -static int symbol__disassemble_llvm(char *filename, struct symbol *sym, +static int symbol__disassemble_llvm(const char *filename, struct symbol *sym, struct annotate_args *args __maybe_unused) { - symbol__disassembler_missing("LLVM", filename, sym); + pr_debug("The LLVM disassembler isn't linked in for %s in %s\n", + sym->name, filename); return -1; } #endif // HAVE_LIBLLVM_SUPPORT @@ -2225,9 +1879,7 @@ static int annotation_options__init_disassemblers(struct annotation_options *opt #ifdef HAVE_LIBLLVM_SUPPORT "llvm," #endif -#ifdef HAVE_LIBCAPSTONE_SUPPORT "capstone," -#endif "objdump"; options->disassemblers_str = strdup(default_disassemblers_str); diff --git a/tools/perf/util/print_insn.c b/tools/perf/util/print_insn.c index a33a7726422d..02e6fbb8ca04 100644 --- a/tools/perf/util/print_insn.c +++ b/tools/perf/util/print_insn.c @@ -7,6 +7,7 @@ #include #include #include +#include "capstone.h" #include "debug.h" #include "sample.h" #include "symbol.h" @@ -29,84 +30,6 @@ size_t sample__fprintf_insn_raw(struct perf_sample *sample, FILE *fp) return printed; } -#ifdef HAVE_LIBCAPSTONE_SUPPORT -#include - -int capstone_init(struct machine *machine, csh *cs_handle, bool is64, bool disassembler_style); - -int capstone_init(struct machine *machine, csh *cs_handle, bool is64, bool disassembler_style) -{ - cs_arch arch; - cs_mode mode; - - if (machine__is(machine, "x86_64") && is64) { - arch = CS_ARCH_X86; - mode = CS_MODE_64; - } else if (machine__normalized_is(machine, "x86")) { - arch = CS_ARCH_X86; - mode = CS_MODE_32; - } else if (machine__normalized_is(machine, "arm64")) { - arch = CS_ARCH_ARM64; - mode = CS_MODE_ARM; - } else if (machine__normalized_is(machine, "arm")) { - arch = CS_ARCH_ARM; - mode = CS_MODE_ARM + CS_MODE_V8; - } else if (machine__normalized_is(machine, "s390")) { - arch = CS_ARCH_SYSZ; - mode = CS_MODE_BIG_ENDIAN; - } else { - return -1; - } - - if (cs_open(arch, mode, cs_handle) != CS_ERR_OK) { - pr_warning_once("cs_open failed\n"); - return -1; - } - - if (machine__normalized_is(machine, "x86")) { - /* - * In case of using capstone_init while symbol__disassemble - * setting CS_OPT_SYNTAX_ATT depends if disassembler_style opts - * is set via annotation args - */ - if (disassembler_style) - cs_option(*cs_handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); - /* - * Resolving address operands to symbols is implemented - * on x86 by investigating instruction details. - */ - cs_option(*cs_handle, CS_OPT_DETAIL, CS_OPT_ON); - } - - return 0; -} - -static size_t print_insn_x86(struct thread *thread, u8 cpumode, cs_insn *insn, - int print_opts, FILE *fp) -{ - struct addr_location al; - size_t printed = 0; - - if (insn->detail && insn->detail->x86.op_count == 1) { - cs_x86_op *op = &insn->detail->x86.operands[0]; - - addr_location__init(&al); - if (op->type == X86_OP_IMM && - thread__find_symbol(thread, cpumode, op->imm, &al)) { - printed += fprintf(fp, "%s ", insn[0].mnemonic); - printed += symbol__fprintf_symname_offs(al.sym, &al, fp); - if (print_opts & PRINT_INSN_IMM_HEX) - printed += fprintf(fp, " [%#" PRIx64 "]", op->imm); - addr_location__exit(&al); - return printed; - } - addr_location__exit(&al); - } - - printed += fprintf(fp, "%s %s", insn[0].mnemonic, insn[0].op_str); - return printed; -} - static bool is64bitip(struct machine *machine, struct addr_location *al) { const struct dso *dso = al->map ? map__dso(al->map) : NULL; @@ -123,32 +46,8 @@ ssize_t fprintf_insn_asm(struct machine *machine, struct thread *thread, u8 cpum bool is64bit, const uint8_t *code, size_t code_size, uint64_t ip, int *lenp, int print_opts, FILE *fp) { - size_t printed; - cs_insn *insn; - csh cs_handle; - size_t count; - int ret; - - /* TODO: Try to initiate capstone only once but need a proper place. */ - ret = capstone_init(machine, &cs_handle, is64bit, true); - if (ret < 0) - return ret; - - count = cs_disasm(cs_handle, code, code_size, ip, 1, &insn); - if (count > 0) { - if (machine__normalized_is(machine, "x86")) - printed = print_insn_x86(thread, cpumode, &insn[0], print_opts, fp); - else - printed = fprintf(fp, "%s %s", insn[0].mnemonic, insn[0].op_str); - if (lenp) - *lenp = insn->size; - cs_free(insn, count); - } else { - printed = -1; - } - - cs_close(&cs_handle); - return printed; + return capstone__fprintf_insn_asm(machine, thread, cpumode, is64bit, code, code_size, + ip, lenp, print_opts, fp); } size_t sample__fprintf_insn_asm(struct perf_sample *sample, struct thread *thread, @@ -166,13 +65,3 @@ size_t sample__fprintf_insn_asm(struct perf_sample *sample, struct thread *threa return printed; } -#else -size_t sample__fprintf_insn_asm(struct perf_sample *sample __maybe_unused, - struct thread *thread __maybe_unused, - struct machine *machine __maybe_unused, - FILE *fp __maybe_unused, - struct addr_location *al __maybe_unused) -{ - return 0; -} -#endif From patchwork Wed Jan 22 06:23:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946892 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 472AA1B85EC for ; Wed, 22 Jan 2025 06:24:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527062; cv=none; b=XqpWld4502UprnN3xSIBn39Phel75O6qCR50NkIsXFuT0PGea3HdmGfnzWjArEWmty+W84+oRWWMYUBx/lzG0vVbAtmfCo+XiwogJOl88TQliy57CAML1fKlJqJNscSMTxHv1BiKhBOE8k0+cNGoKdkND8VOck0w44DT/0JW3lo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527062; c=relaxed/simple; bh=gMiEzYpiD/cjC0pzJfYU33rw5lV4y2RhubD0sQd5ifo=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=YNrXIwTzlmdT14oM2zgdSy27Nc36DWVbbgRFqVyfpa5OwhoXCgYDO3EDYfHIWZR3Cac+r5XWeSrUVb5KgJ2Fh1XPO5JN2+O2cxo3h/OKCDi89aJQchCotMnC0MAF/rBiE93f0lFLVym2dbtVDnBrnpCtMefKW7rIq+mV27AyZvM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=a7BmmM9Z; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="a7BmmM9Z" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e3a0f608b88so14682252276.0 for ; Tue, 21 Jan 2025 22:24:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527059; x=1738131859; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=QkkNQBZWR3jCdxePhOuPJSvZ2usD08fbSiwvUDcxDkI=; b=a7BmmM9Zesm3XjvsUx/miDCc0AbsGgexgWxab6KhLjBCiLWcAac7fQ9Mchgrkl3eUk mptKuzYftV5idHxxZrzoSmcs6jTrQq0iHY+WNzyU4qB0bZyPZs96hpkbiDe7ZNZV12Et yx7eY4uQtP0D0l94fTtAfyXp007qyaua6vrJwGplJN2R2hXHipSDJkwZW62E3279jBc+ KE+qGWHQUI1MO8GwK1M1yCDihW6lQ5cWZBh1ciktYF+FUXffvH2Mxex71KLbKAlTQ736 nMXrzVDnAZLin+GmaXql2v4P/iwsPkSg6I+LeECommQDOm5BobZAEMCLYK5wWyGNF1Ht rNxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527059; x=1738131859; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=QkkNQBZWR3jCdxePhOuPJSvZ2usD08fbSiwvUDcxDkI=; b=BHaND2TC+PcZb6oZiO1k3MpGXhvMIEkqDT0O/Ak+3xbnDnx/7U4TgxjVs7rI8eyIYc omSfxTWzBcSeM0DgsT7lhiizSJuRhVX9GUKnw4hSEe72E8z1JJAWsVSayGQkpZcvdTb2 p+JgiDSQ4sYcWsvOMtG5DRpTCwVAMKX3HyN1tKtakgSgpStcosXU8eM0k2w30sKB6M4O ZSwWuAWklFCnXcXTBG/NWpGiTMXKDrzZCZTxYsDgBtovkzjd6S2Aduk8qIzJKEWmN2OL V1tVgeOA0OgsLWHdVx4JDenkASr8l1x4EIRhcgdwVxwSTNnZnYgMppuKYsZZNr3GbuSK QfJg== X-Forwarded-Encrypted: i=1; AJvYcCWTy+h6l9i4iD95NGti1hIUjUNlU73eEJFwxuBP4elV3a8vrcaJaibwsm2yp/gwnzL+y0w=@vger.kernel.org X-Gm-Message-State: AOJu0YwTqE/xFMXIe2yX4nnqGEsKtbsbCKkhMt3NLnUkO3Jqr8GXI2Sl D2VuSZv4m3iP//Ap9OSkeeM72SIad3VUd/KdGVCQhPhMiYo9Iu4uwjVG73iRqr/Rv/PEnRxjCDp qIbW92A== X-Google-Smtp-Source: AGHT+IENmoAFACJHesP8R5IaLQ3tyMpHIh18PMXcGsSHItR3F0W2UP12KOH1FBgRvpwZ+Zyp8QC4yNN0XK4d X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a81:a907:0:b0:62c:f976:a763 with SMTP id 00721157ae682-6f6eb65eeadmr431027b3.1.1737527059363; Tue, 21 Jan 2025 22:24:19 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:19 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-5-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 04/17] perf llvm: Move llvm functionality into its own file From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org LLVM disassembly support was in disasm.c and addr2line support in srcline.c. Move support out of these files into llvm.[ch] and remove LLVM includes from those files. As disassembl routines can fail, make failure the only option without HAVE_LIBLLVM_SUPPORT. For simplicity's sake, duplicate the read_symbol utility function. The intent with moving LLVM support into a single file is that dynamic support, using dlopen for libllvm, can be added in later patches. This can potentially always succeed or fail, so relying on ifdefs isn't sufficient. Using dlopen is a useful option to minimize the perf tools dependencies and potentially size. Signed-off-by: Ian Rogers --- tools/perf/util/Build | 1 + tools/perf/util/disasm.c | 262 +----------------------------- tools/perf/util/disasm.h | 2 + tools/perf/util/llvm.c | 326 ++++++++++++++++++++++++++++++++++++++ tools/perf/util/llvm.h | 24 +++ tools/perf/util/srcline.c | 65 ++------ tools/perf/util/srcline.h | 6 + 7 files changed, 373 insertions(+), 313 deletions(-) create mode 100644 tools/perf/util/llvm.c create mode 100644 tools/perf/util/llvm.h diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 9542decf9625..6fe0b5882c97 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -26,6 +26,7 @@ perf-util-y += evswitch.o perf-util-y += find_bit.o perf-util-y += get_current_dir_name.o perf-util-y += levenshtein.o +perf-util-y += llvm.o perf-util-y += mmap.o perf-util-y += memswap.o perf-util-y += parse-events.o diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index 0e5881189ae8..a9cc588a3006 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -22,6 +22,7 @@ #include "dwarf-regs.h" #include "env.h" #include "evsel.h" +#include "llvm.h" #include "map.h" #include "maps.h" #include "namespaces.h" @@ -50,7 +51,6 @@ static int call__scnprintf(struct ins *ins, char *bf, size_t size, static void ins__sort(struct arch *arch); static int disasm_line__parse(char *line, const char **namep, char **rawp); static int disasm_line__parse_powerpc(struct disasm_line *dl); -static char *expand_tabs(char *line, char **storage, size_t *storage_len); static __attribute__((constructor)) void symbol__init_regexpr(void) { @@ -1330,72 +1330,6 @@ static int dso__disassemble_filename(struct dso *dso, char *filename, size_t fil return 0; } -#if defined(HAVE_LIBLLVM_SUPPORT) -struct find_file_offset_data { - u64 ip; - u64 offset; -}; - -/* This will be called for each PHDR in an ELF binary */ -static int find_file_offset(u64 start, u64 len, u64 pgoff, void *arg) -{ - struct find_file_offset_data *data = arg; - - if (start <= data->ip && data->ip < start + len) { - data->offset = pgoff + data->ip - start; - return 1; - } - return 0; -} - -static u8 * -read_symbol(const char *filename, struct map *map, struct symbol *sym, - u64 *len, bool *is_64bit) -{ - struct dso *dso = map__dso(map); - struct nscookie nsc; - u64 start = map__rip_2objdump(map, sym->start); - u64 end = map__rip_2objdump(map, sym->end); - int fd, count; - u8 *buf = NULL; - struct find_file_offset_data data = { - .ip = start, - }; - - *is_64bit = false; - - nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); - fd = open(filename, O_RDONLY); - nsinfo__mountns_exit(&nsc); - if (fd < 0) - return NULL; - - if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, - is_64bit) == 0) - goto err; - - *len = end - start; - buf = malloc(*len); - if (buf == NULL) - goto err; - - count = pread(fd, buf, *len, data.offset); - close(fd); - fd = -1; - - if ((u64)count != *len) - goto err; - - return buf; - -err: - if (fd >= 0) - close(fd); - free(buf); - return NULL; -} -#endif - static int symbol__disassemble_raw(char *filename, struct symbol *sym, struct annotate_args *args) { @@ -1482,202 +1416,12 @@ static int symbol__disassemble_raw(char *filename, struct symbol *sym, goto out; } -#ifdef HAVE_LIBLLVM_SUPPORT -#include -#include -#include "util/llvm-c-helpers.h" - -struct symbol_lookup_storage { - u64 branch_addr; - u64 pcrel_load_addr; -}; - -/* - * Whenever LLVM wants to resolve an address into a symbol, it calls this - * callback. We don't ever actually _return_ anything (in particular, because - * it puts quotation marks around what we return), but we use this as a hint - * that there is a branch or PC-relative address in the expression that we - * should add some textual annotation for after the instruction. The caller - * will use this information to add the actual annotation. - */ -static const char * -symbol_lookup_callback(void *disinfo, uint64_t value, - uint64_t *ref_type, - uint64_t address __maybe_unused, - const char **ref __maybe_unused) -{ - struct symbol_lookup_storage *storage = disinfo; - - if (*ref_type == LLVMDisassembler_ReferenceType_In_Branch) - storage->branch_addr = value; - else if (*ref_type == LLVMDisassembler_ReferenceType_In_PCrel_Load) - storage->pcrel_load_addr = value; - *ref_type = LLVMDisassembler_ReferenceType_InOut_None; - return NULL; -} - -static int symbol__disassemble_llvm(char *filename, struct symbol *sym, - struct annotate_args *args) -{ - struct annotation *notes = symbol__annotation(sym); - struct map *map = args->ms.map; - struct dso *dso = map__dso(map); - u64 start = map__rip_2objdump(map, sym->start); - u8 *buf; - u64 len; - u64 pc; - bool is_64bit; - char triplet[64]; - char disasm_buf[2048]; - size_t disasm_len; - struct disasm_line *dl; - LLVMDisasmContextRef disasm = NULL; - struct symbol_lookup_storage storage; - char *line_storage = NULL; - size_t line_storage_len = 0; - int ret = -1; - - if (args->options->objdump_path) - return -1; - - LLVMInitializeAllTargetInfos(); - LLVMInitializeAllTargetMCs(); - LLVMInitializeAllDisassemblers(); - - buf = read_symbol(filename, map, sym, &len, &is_64bit); - if (buf == NULL) - return -1; - - if (arch__is(args->arch, "x86")) { - if (is_64bit) - scnprintf(triplet, sizeof(triplet), "x86_64-pc-linux"); - else - scnprintf(triplet, sizeof(triplet), "i686-pc-linux"); - } else { - scnprintf(triplet, sizeof(triplet), "%s-linux-gnu", - args->arch->name); - } - - disasm = LLVMCreateDisasm(triplet, &storage, 0, NULL, - symbol_lookup_callback); - if (disasm == NULL) - goto err; - - if (args->options->disassembler_style && - !strcmp(args->options->disassembler_style, "intel")) - LLVMSetDisasmOptions(disasm, - LLVMDisassembler_Option_AsmPrinterVariant); - - /* - * This needs to be set after AsmPrinterVariant, due to a bug in LLVM; - * setting AsmPrinterVariant makes a new instruction printer, making it - * forget about the PrintImmHex flag (which is applied before if both - * are given to the same call). - */ - LLVMSetDisasmOptions(disasm, LLVMDisassembler_Option_PrintImmHex); - - /* add the function address and name */ - scnprintf(disasm_buf, sizeof(disasm_buf), "%#"PRIx64" <%s>:", - start, sym->name); - - args->offset = -1; - args->line = disasm_buf; - args->line_nr = 0; - args->fileloc = NULL; - args->ms.sym = sym; - - dl = disasm_line__new(args); - if (dl == NULL) - goto err; - - annotation_line__add(&dl->al, ¬es->src->source); - - pc = start; - for (u64 offset = 0; offset < len; ) { - unsigned int ins_len; - - storage.branch_addr = 0; - storage.pcrel_load_addr = 0; - - ins_len = LLVMDisasmInstruction(disasm, buf + offset, - len - offset, pc, - disasm_buf, sizeof(disasm_buf)); - if (ins_len == 0) - goto err; - disasm_len = strlen(disasm_buf); - - if (storage.branch_addr != 0) { - char *name = llvm_name_for_code(dso, filename, - storage.branch_addr); - if (name != NULL) { - disasm_len += scnprintf(disasm_buf + disasm_len, - sizeof(disasm_buf) - - disasm_len, - " <%s>", name); - free(name); - } - } - if (storage.pcrel_load_addr != 0) { - char *name = llvm_name_for_data(dso, filename, - storage.pcrel_load_addr); - disasm_len += scnprintf(disasm_buf + disasm_len, - sizeof(disasm_buf) - disasm_len, - " # %#"PRIx64, - storage.pcrel_load_addr); - if (name) { - disasm_len += scnprintf(disasm_buf + disasm_len, - sizeof(disasm_buf) - - disasm_len, - " <%s>", name); - free(name); - } - } - - args->offset = offset; - args->line = expand_tabs(disasm_buf, &line_storage, - &line_storage_len); - args->line_nr = 0; - args->fileloc = NULL; - args->ms.sym = sym; - - llvm_addr2line(filename, pc, &args->fileloc, - (unsigned int *)&args->line_nr, false, NULL); - - dl = disasm_line__new(args); - if (dl == NULL) - goto err; - - annotation_line__add(&dl->al, ¬es->src->source); - - free(args->fileloc); - pc += ins_len; - offset += ins_len; - } - - ret = 0; - -err: - LLVMDisasmDispose(disasm); - free(buf); - free(line_storage); - return ret; -} -#else // HAVE_LIBLLVM_SUPPORT -static int symbol__disassemble_llvm(const char *filename, struct symbol *sym, - struct annotate_args *args __maybe_unused) -{ - pr_debug("The LLVM disassembler isn't linked in for %s in %s\n", - sym->name, filename); - return -1; -} -#endif // HAVE_LIBLLVM_SUPPORT - /* * Possibly create a new version of line with tabs expanded. Returns the * existing or new line, storage is updated if a new line is allocated. If * allocation fails then NULL is returned. */ -static char *expand_tabs(char *line, char **storage, size_t *storage_len) +char *expand_tabs(char *line, char **storage, size_t *storage_len) { size_t i, src, dst, len, new_storage_len, num_tabs; char *new_line; @@ -1876,9 +1620,7 @@ static int annotation_options__init_disassemblers(struct annotation_options *opt if (options->disassemblers_str == NULL) { const char *default_disassemblers_str = -#ifdef HAVE_LIBLLVM_SUPPORT "llvm," -#endif "capstone," "objdump"; diff --git a/tools/perf/util/disasm.h b/tools/perf/util/disasm.h index c135db2416b5..2cb4e1a6bd30 100644 --- a/tools/perf/util/disasm.h +++ b/tools/perf/util/disasm.h @@ -128,4 +128,6 @@ int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, int symbol__disassemble(struct symbol *sym, struct annotate_args *args); +char *expand_tabs(char *line, char **storage, size_t *storage_len); + #endif /* __PERF_UTIL_DISASM_H */ diff --git a/tools/perf/util/llvm.c b/tools/perf/util/llvm.c new file mode 100644 index 000000000000..ddc737194692 --- /dev/null +++ b/tools/perf/util/llvm.c @@ -0,0 +1,326 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "llvm.h" +#include "annotate.h" +#include "debug.h" +#include "dso.h" +#include "map.h" +#include "namespaces.h" +#include "srcline.h" +#include "symbol.h" +#include +#include +#include + +#ifdef HAVE_LIBLLVM_SUPPORT +#include "llvm-c-helpers.h" +#include +#include +#endif + +#ifdef HAVE_LIBLLVM_SUPPORT +static void free_llvm_inline_frames(struct llvm_a2l_frame *inline_frames, + int num_frames) +{ + if (inline_frames != NULL) { + for (int i = 0; i < num_frames; ++i) { + zfree(&inline_frames[i].filename); + zfree(&inline_frames[i].funcname); + } + zfree(&inline_frames); + } +} +#endif + +int llvm__addr2line(const char *dso_name __maybe_unused, u64 addr __maybe_unused, + char **file __maybe_unused, unsigned int *line __maybe_unused, + struct dso *dso __maybe_unused, bool unwind_inlines __maybe_unused, + struct inline_node *node __maybe_unused, struct symbol *sym __maybe_unused) +{ +#ifdef HAVE_LIBLLVM_SUPPORT + struct llvm_a2l_frame *inline_frames = NULL; + int num_frames = llvm_addr2line(dso_name, addr, file, line, + node && unwind_inlines, &inline_frames); + + if (num_frames == 0 || !inline_frames) { + /* Error, or we didn't want inlines. */ + return num_frames; + } + + for (int i = 0; i < num_frames; ++i) { + struct symbol *inline_sym = + new_inline_sym(dso, sym, inline_frames[i].funcname); + char *srcline = NULL; + + if (inline_frames[i].filename) { + srcline = + srcline_from_fileline(inline_frames[i].filename, + inline_frames[i].line); + } + if (inline_list__append(inline_sym, srcline, node) != 0) { + free_llvm_inline_frames(inline_frames, num_frames); + return 0; + } + } + free_llvm_inline_frames(inline_frames, num_frames); + + return num_frames; +#else + return -1; +#endif +} + +void dso__free_a2l_llvm(struct dso *dso __maybe_unused) +{ + /* Nothing to free. */ +} + + +#if defined(HAVE_LIBLLVM_SUPPORT) +struct find_file_offset_data { + u64 ip; + u64 offset; +}; + +/* This will be called for each PHDR in an ELF binary */ +static int find_file_offset(u64 start, u64 len, u64 pgoff, void *arg) +{ + struct find_file_offset_data *data = arg; + + if (start <= data->ip && data->ip < start + len) { + data->offset = pgoff + data->ip - start; + return 1; + } + return 0; +} + +static u8 * +read_symbol(const char *filename, struct map *map, struct symbol *sym, + u64 *len, bool *is_64bit) +{ + struct dso *dso = map__dso(map); + struct nscookie nsc; + u64 start = map__rip_2objdump(map, sym->start); + u64 end = map__rip_2objdump(map, sym->end); + int fd, count; + u8 *buf = NULL; + struct find_file_offset_data data = { + .ip = start, + }; + + *is_64bit = false; + + nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); + fd = open(filename, O_RDONLY); + nsinfo__mountns_exit(&nsc); + if (fd < 0) + return NULL; + + if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, + is_64bit) == 0) + goto err; + + *len = end - start; + buf = malloc(*len); + if (buf == NULL) + goto err; + + count = pread(fd, buf, *len, data.offset); + close(fd); + fd = -1; + + if ((u64)count != *len) + goto err; + + return buf; + +err: + if (fd >= 0) + close(fd); + free(buf); + return NULL; +} +#endif + +/* + * Whenever LLVM wants to resolve an address into a symbol, it calls this + * callback. We don't ever actually _return_ anything (in particular, because + * it puts quotation marks around what we return), but we use this as a hint + * that there is a branch or PC-relative address in the expression that we + * should add some textual annotation for after the instruction. The caller + * will use this information to add the actual annotation. + */ +#ifdef HAVE_LIBLLVM_SUPPORT +struct symbol_lookup_storage { + u64 branch_addr; + u64 pcrel_load_addr; +}; + +static const char * +symbol_lookup_callback(void *disinfo, uint64_t value, + uint64_t *ref_type, + uint64_t address __maybe_unused, + const char **ref __maybe_unused) +{ + struct symbol_lookup_storage *storage = disinfo; + + if (*ref_type == LLVMDisassembler_ReferenceType_In_Branch) + storage->branch_addr = value; + else if (*ref_type == LLVMDisassembler_ReferenceType_In_PCrel_Load) + storage->pcrel_load_addr = value; + *ref_type = LLVMDisassembler_ReferenceType_InOut_None; + return NULL; +} +#endif + +int symbol__disassemble_llvm(const char *filename, struct symbol *sym, + struct annotate_args *args __maybe_unused) +{ +#ifdef HAVE_LIBLLVM_SUPPORT + struct annotation *notes = symbol__annotation(sym); + struct map *map = args->ms.map; + struct dso *dso = map__dso(map); + u64 start = map__rip_2objdump(map, sym->start); + u8 *buf; + u64 len; + u64 pc; + bool is_64bit; + char triplet[64]; + char disasm_buf[2048]; + size_t disasm_len; + struct disasm_line *dl; + LLVMDisasmContextRef disasm = NULL; + struct symbol_lookup_storage storage; + char *line_storage = NULL; + size_t line_storage_len = 0; + int ret = -1; + + if (args->options->objdump_path) + return -1; + + LLVMInitializeAllTargetInfos(); + LLVMInitializeAllTargetMCs(); + LLVMInitializeAllDisassemblers(); + + buf = read_symbol(filename, map, sym, &len, &is_64bit); + if (buf == NULL) + return -1; + + if (arch__is(args->arch, "x86")) { + if (is_64bit) + scnprintf(triplet, sizeof(triplet), "x86_64-pc-linux"); + else + scnprintf(triplet, sizeof(triplet), "i686-pc-linux"); + } else { + scnprintf(triplet, sizeof(triplet), "%s-linux-gnu", + args->arch->name); + } + + disasm = LLVMCreateDisasm(triplet, &storage, 0, NULL, + symbol_lookup_callback); + if (disasm == NULL) + goto err; + + if (args->options->disassembler_style && + !strcmp(args->options->disassembler_style, "intel")) + LLVMSetDisasmOptions(disasm, + LLVMDisassembler_Option_AsmPrinterVariant); + + /* + * This needs to be set after AsmPrinterVariant, due to a bug in LLVM; + * setting AsmPrinterVariant makes a new instruction printer, making it + * forget about the PrintImmHex flag (which is applied before if both + * are given to the same call). + */ + LLVMSetDisasmOptions(disasm, LLVMDisassembler_Option_PrintImmHex); + + /* add the function address and name */ + scnprintf(disasm_buf, sizeof(disasm_buf), "%#"PRIx64" <%s>:", + start, sym->name); + + args->offset = -1; + args->line = disasm_buf; + args->line_nr = 0; + args->fileloc = NULL; + args->ms.sym = sym; + + dl = disasm_line__new(args); + if (dl == NULL) + goto err; + + annotation_line__add(&dl->al, ¬es->src->source); + + pc = start; + for (u64 offset = 0; offset < len; ) { + unsigned int ins_len; + + storage.branch_addr = 0; + storage.pcrel_load_addr = 0; + + ins_len = LLVMDisasmInstruction(disasm, buf + offset, + len - offset, pc, + disasm_buf, sizeof(disasm_buf)); + if (ins_len == 0) + goto err; + disasm_len = strlen(disasm_buf); + + if (storage.branch_addr != 0) { + char *name = llvm_name_for_code(dso, filename, + storage.branch_addr); + if (name != NULL) { + disasm_len += scnprintf(disasm_buf + disasm_len, + sizeof(disasm_buf) - + disasm_len, + " <%s>", name); + free(name); + } + } + if (storage.pcrel_load_addr != 0) { + char *name = llvm_name_for_data(dso, filename, + storage.pcrel_load_addr); + disasm_len += scnprintf(disasm_buf + disasm_len, + sizeof(disasm_buf) - disasm_len, + " # %#"PRIx64, + storage.pcrel_load_addr); + if (name) { + disasm_len += scnprintf(disasm_buf + disasm_len, + sizeof(disasm_buf) - + disasm_len, + " <%s>", name); + free(name); + } + } + + args->offset = offset; + args->line = expand_tabs(disasm_buf, &line_storage, + &line_storage_len); + args->line_nr = 0; + args->fileloc = NULL; + args->ms.sym = sym; + + llvm_addr2line(filename, pc, &args->fileloc, + (unsigned int *)&args->line_nr, false, NULL); + + dl = disasm_line__new(args); + if (dl == NULL) + goto err; + + annotation_line__add(&dl->al, ¬es->src->source); + + free(args->fileloc); + pc += ins_len; + offset += ins_len; + } + + ret = 0; + +err: + LLVMDisasmDispose(disasm); + free(buf); + free(line_storage); + return ret; +#else // HAVE_LIBLLVM_SUPPORT + pr_debug("The LLVM disassembler isn't linked in for %s in %s\n", + sym->name, filename); + return -1; +#endif +} diff --git a/tools/perf/util/llvm.h b/tools/perf/util/llvm.h new file mode 100644 index 000000000000..8aa19bb6b068 --- /dev/null +++ b/tools/perf/util/llvm.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_LLVM_H +#define __PERF_LLVM_H + +#include +#include + +struct annotate_args; +struct dso; +struct inline_node; +struct symbol; + +int llvm__addr2line(const char *dso_name, u64 addr, + char **file, unsigned int *line, struct dso *dso, + bool unwind_inlines, struct inline_node *node, + struct symbol *sym); + + +void dso__free_a2l_llvm(struct dso *dso); + +int symbol__disassemble_llvm(const char *filename, struct symbol *sym, + struct annotate_args *args); + +#endif /* __PERF_LLVM_H */ diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index f32d0d4f4bc9..26fd55455efd 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -17,9 +17,7 @@ #include "util/debug.h" #include "util/callchain.h" #include "util/symbol_conf.h" -#ifdef HAVE_LIBLLVM_SUPPORT -#include "util/llvm-c-helpers.h" -#endif +#include "llvm.h" #include "srcline.h" #include "string2.h" #include "symbol.h" @@ -49,8 +47,7 @@ static const char *srcline_dso_name(struct dso *dso) return dso_name; } -static int inline_list__append(struct symbol *symbol, char *srcline, - struct inline_node *node) +int inline_list__append(struct symbol *symbol, char *srcline, struct inline_node *node) { struct inline_list *ilist; @@ -77,7 +74,7 @@ static const char *gnu_basename(const char *path) return base ? base + 1 : path; } -static char *srcline_from_fileline(const char *file, unsigned int line) +char *srcline_from_fileline(const char *file, unsigned int line) { char *srcline; @@ -93,9 +90,9 @@ static char *srcline_from_fileline(const char *file, unsigned int line) return srcline; } -static struct symbol *new_inline_sym(struct dso *dso, - struct symbol *base_sym, - const char *funcname) +struct symbol *new_inline_sym(struct dso *dso, + struct symbol *base_sym, + const char *funcname) { struct symbol *inline_sym; char *demangled = NULL; @@ -135,58 +132,20 @@ static struct symbol *new_inline_sym(struct dso *dso, #define MAX_INLINE_NEST 1024 #ifdef HAVE_LIBLLVM_SUPPORT - -static void free_llvm_inline_frames(struct llvm_a2l_frame *inline_frames, - int num_frames) -{ - if (inline_frames != NULL) { - for (int i = 0; i < num_frames; ++i) { - zfree(&inline_frames[i].filename); - zfree(&inline_frames[i].funcname); - } - zfree(&inline_frames); - } -} +#include "llvm.h" static int addr2line(const char *dso_name, u64 addr, char **file, unsigned int *line, struct dso *dso, - bool unwind_inlines, struct inline_node *node, - struct symbol *sym) + bool unwind_inlines, struct inline_node *node, + struct symbol *sym) { - struct llvm_a2l_frame *inline_frames = NULL; - int num_frames = llvm_addr2line(dso_name, addr, file, line, - node && unwind_inlines, &inline_frames); - - if (num_frames == 0 || !inline_frames) { - /* Error, or we didn't want inlines. */ - return num_frames; - } - - for (int i = 0; i < num_frames; ++i) { - struct symbol *inline_sym = - new_inline_sym(dso, sym, inline_frames[i].funcname); - char *srcline = NULL; - - if (inline_frames[i].filename) { - srcline = - srcline_from_fileline(inline_frames[i].filename, - inline_frames[i].line); - } - if (inline_list__append(inline_sym, srcline, node) != 0) { - free_llvm_inline_frames(inline_frames, num_frames); - return 0; - } - } - free_llvm_inline_frames(inline_frames, num_frames); - - return num_frames; + return llvm__addr2line(dso_name, addr, file, line, dso, unwind_inlines, node, sym); } -void dso__free_a2l(struct dso *dso __maybe_unused) +void dso__free_a2l(struct dso *dso) { - /* Nothing to free. */ + dso__free_a2l_llvm(dso); } - #elif defined(HAVE_LIBBFD_SUPPORT) /* diff --git a/tools/perf/util/srcline.h b/tools/perf/util/srcline.h index 75010d39ea28..80c20169e250 100644 --- a/tools/perf/util/srcline.h +++ b/tools/perf/util/srcline.h @@ -55,4 +55,10 @@ struct inline_node *inlines__tree_find(struct rb_root_cached *tree, u64 addr); /* delete all nodes within the tree of inline_node s */ void inlines__tree_delete(struct rb_root_cached *tree); +int inline_list__append(struct symbol *symbol, char *srcline, struct inline_node *node); +char *srcline_from_fileline(const char *file, unsigned int line); +struct symbol *new_inline_sym(struct dso *dso, + struct symbol *base_sym, + const char *funcname); + #endif /* PERF_SRCLINE_H */ From patchwork Wed Jan 22 06:23:20 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946893 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F9F61B87F1 for ; Wed, 22 Jan 2025 06:24:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527071; cv=none; b=ho1mNpQyTwHGuI0pfVYgngX1uhPv7OAxmkFgbOugsImTADrT4GhNeTmM1J44sISh9vi2+35YCvU5EOtVVhvsnFBfPosfqYnzFBeGzqBNlQT+DLLj/dMpncrDxp9lx0JtS1LDUWPBrBm9Dj1nhxW/o9O30NAmj5JDQayxL1bs/Tg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527071; c=relaxed/simple; bh=ksmTITiwDHRKN7AM1iSFOtcCcIcP7GGHu1o6+CqXZco=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=ifR9UP4ZotKlGH0dLdsSJSYbRM/Q3m2j1KBWTB9EeRJrFXkR7p/MOlkYAE3FsaS5jN/fi1Ni6AdW/Xa46QYjVSYKqwWlXgVcXpPDOVkULotfy+W0zUdf+Af2J6+0j+mK7V0uxPZZw0hC1bP9LMKomRKe9xPrM4EAzp5G5PKahPY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=TyKVpYj7; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="TyKVpYj7" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-e399d4ef55cso16786425276.2 for ; Tue, 21 Jan 2025 22:24:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527068; x=1738131868; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=HtzTzHqLOrR4WcyKkQw1nPTI/K9PhaOnccVbKtmGOUc=; b=TyKVpYj70eRmTUWHD//d+KGPRiHo3IMzlkXgrMfmfr0HxaVQXKhrmOrg75yfZNgttk cAGWGss8N0WA0PhWdmGJTYUb1gvwi4oOZ8kzbfn6QU8BrQ/+DtSe7V6aTfwXEqAo3ZJR MhnOpbUdbuRKWJsKxZJ/5jij8M/AXY2iasXu85UzE1b1VEwde17l6z6ivTWNwD+KASDB G1UAaUfcFdiCjeCyAkxuqIGDTJVw68aQqJyFE6aKQyY30CKfFyj7TpfqWqb2u3eg++15 XDTX/uIBKUKVNgeKoRTVczBsxgt7/bDsiw3o43nc/jxuIEvfC/w2Lfz6H7/v7+CEt2UN /dPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527068; x=1738131868; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=HtzTzHqLOrR4WcyKkQw1nPTI/K9PhaOnccVbKtmGOUc=; b=amgH3Ur3wo7b8aGTGkYIHiohXdptvW0s+ZYmY1SfQ/T3qPgqNJ8O9kimu+ZkOBCJdM pjGPj1tcGWUMPVjYvGjjvHjYL7KV3Hk8R9IqWvo+JCwRSg90cL/xpmvm3tNG0oBlq/7M aQrjAW/0IYWE0VmsGhWpZqkNEfp/jHYZFD7j/0To68D2VWawwpJS99o3jSFjoTVHBK8e 7usXTaDfuddFt+ALlmOmZaWLhyn7+twISPTBOhgq0qGqnqyKmzQizRP3RAKK9zqDQ8xV zioNZQX3HpvzTQMzt25qkDR7+tr2zvkU+yXIGHFqiTG3Vo6XJw93dlZVGUAowHyCLFta kWdQ== X-Forwarded-Encrypted: i=1; AJvYcCWbDsQvH96tvuIwRHm0b/Khc08mjBp76eTTMS87wgFEuKgiCn77lq4Y2U8IACTKnME6SAQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yx0c4h/kNvsM47PrsrDNv4gTyl8ozvxl9O2E/8daT67Xg+UtlAw jYlSRxV54zlCYwtzLip0vnC3t+baEFe1Bzbjj2mq0a4xxlNtPOEe/A+zvkYMl3nR5EaUon3PPBJ mFg1X+w== X-Google-Smtp-Source: AGHT+IF4xW6MszewyE48AJoSmqv42vaUKpGWDsoNDMUd22FuA0iZtmjyorbaunxgqGCpQY+ff4Pe+DYCCOq9 X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a05:690c:6f8c:b0:6ef:4ba2:6bfc with SMTP id 00721157ae682-6f6eb95f9eemr535417b3.5.1737527068640; Tue, 21 Jan 2025 22:24:28 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:20 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-6-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 05/17] perf capstone: Remove open_capstone_handle From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org open_capstone_handle is similar to capstone_init and used only by symbol__disassemble_capstone. symbol__disassemble_capstone_powerpc already uses capstone_init, transition symbol__disassemble_capstone and eliminate open_capstone_handle. Signed-off-by: Ian Rogers --- tools/perf/util/capstone.c | 34 ++++++---------------------------- 1 file changed, 6 insertions(+), 28 deletions(-) diff --git a/tools/perf/util/capstone.c b/tools/perf/util/capstone.c index c0a6d94ebc18..c9845e4d8781 100644 --- a/tools/perf/util/capstone.c +++ b/tools/perf/util/capstone.c @@ -137,33 +137,6 @@ ssize_t capstone__fprintf_insn_asm(struct machine *machine __maybe_unused, #endif } -#ifdef HAVE_LIBCAPSTONE_SUPPORT -static int open_capstone_handle(struct annotate_args *args, bool is_64bit, csh *handle) -{ - struct annotation_options *opt = args->options; - cs_mode mode = is_64bit ? CS_MODE_64 : CS_MODE_32; - - /* TODO: support more architectures */ - if (!arch__is(args->arch, "x86")) - return -1; - - if (cs_open(CS_ARCH_X86, mode, handle) != CS_ERR_OK) - return -1; - - if (!opt->disassembler_style || - !strcmp(opt->disassembler_style, "att")) - cs_option(*handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); - - /* - * Resolving address operands to symbols is implemented - * on x86 by investigating instruction details. - */ - cs_option(*handle, CS_OPT_DETAIL, CS_OPT_ON); - - return 0; -} -#endif - #ifdef HAVE_LIBCAPSTONE_SUPPORT static void print_capstone_detail(cs_insn *insn, char *buf, size_t len, struct annotate_args *args, u64 addr) @@ -309,6 +282,7 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, cs_insn *insn = NULL; char disasm_buf[512]; struct disasm_line *dl; + bool disassembler_style = false; if (args->options->objdump_path) return -1; @@ -333,7 +307,11 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, annotation_line__add(&dl->al, ¬es->src->source); - if (open_capstone_handle(args, is_64bit, &handle) < 0) + if (!args->options->disassembler_style || + !strcmp(args->options->disassembler_style, "att")) + disassembler_style = true; + + if (capstone_init(maps__machine(args->ms.maps), &handle, is_64bit, disassembler_style) < 0) goto err; needs_cs_close = true; From patchwork Wed Jan 22 06:23:21 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946894 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A639C1B424F for ; Wed, 22 Jan 2025 06:24:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527080; cv=none; b=UIAp3BtwU7z8o837DZq9seZvcBZ5U18k/vqf8FC8Bhq8XPpzABjlUK5YXh+wlImoL46oiQZGiR9RKlM/K7/FG4gtDUMGXKnMctr9g90qj8YDeXb+qCTE/ki+eBNBDnRbJCd6teNGTNiguTeBaKIhsKDM+AZkyRcr8C4BC20gNTk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527080; c=relaxed/simple; bh=zkchVUHmiy6FsViQcMXqgJK4h3ZnaivC3KMiQNyelg4=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=o7VUwChl8WasMtUuYdAorP5GG2mz6d0AThsfm3ZnEqkePDSuP9H3HiXRz13NRWU3Bg0yk776zanYMYmYguimIkvpWhdw6wN3vH86WuJGgQub7EcnmrbEOQHKwq+agN9Mjae2xR7pBVi4+cAZ9nxKrigVTvYt3g81gCmQcwh08WI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=DT32ZcWM; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="DT32ZcWM" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-e5799401f12so13942564276.0 for ; Tue, 21 Jan 2025 22:24:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527078; x=1738131878; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=fh49i/U4dxuuGJFb439c1+LAXnNwt18a++KYTwx6RAY=; b=DT32ZcWMgxhC/9ueKZp8elE96HFZ3TJbXzAV1G6y/eCrVtb3YbCj6KjvXJRQ9XzKi8 7tJnN7eWXoSRG8BSUgXrFbrJSd9up3xZGbGraYSQOSxzOJVJjMfuP2ffQVztxgdYurhG Kdj/4uXixhiaUhusY+30QGBOIwNthUciKMTkHg5vMDeKhWv8QxiEiVp0rNqOI/asb7Sl waa6/ApqsEbsbiv3ef+K3NmREX3ZgB/CShDWKhTtSFcR7QjqL6Tw0C7GhWSfiV+xHCpm +CH4m2ZLqLo7JCcVDy4ckDVHF0sQEJHs0DpkjtYkzC3bGIH6rs3aHVyUfebGvan8eW2V yGeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527078; x=1738131878; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fh49i/U4dxuuGJFb439c1+LAXnNwt18a++KYTwx6RAY=; b=Cg0VHK5PR/ojHTCaXS9Uy7AepK6MxnlhvBgVQuMbbqR5l08EiY1I/Mt1izrcfF4QJ5 G3+rO1Hehr6Vr7xtT9JRFVf88hApYQ+oI1aIBU52eP1Po7qJ1bXqZosk9H6u5XU5zUFl gv5QSzF5LO6hTvEXm3ioUY9mB5z2wAQ9dZ7qhXDyMXLhgWJRJn4DzEAsnCKbK67w6EIi wOEaNFA0MwOnRgrgisQxEKo7wl76ZZCl7XUefpislrTZzN0F5YvHEcygsSou7Mza8dmB yWQop2pWRICGRyWXgaRG66sbifzaaqLiKngKm9BwaQ87Wji51cTOrpXOuqj3PdnxYjd9 7lZA== X-Forwarded-Encrypted: i=1; AJvYcCWkg0Osn9pBsLlPC0JDcCzW3X+r/6zCRPmRQZwyOfk9jCUMLs2fo5dAtBs1BQRlGmwukkE=@vger.kernel.org X-Gm-Message-State: AOJu0YysqppL7cYMWGEEsv4iA3B4pE1Z/CAix+Q7xt9MgorHDOyqRZtu 6OJX+206QDXm5O2IFMtaWxGncVt0Fr0sLquXFaT39nQDjKIyLPyMzrpD2qrW/vHPnPqmWkd0chs npsCtqQ== X-Google-Smtp-Source: AGHT+IGBlrKCAF4YXeXIDrMSLK6zjNAH0wIy/uJds3uMRL/gMfUbBtYaIuAcecVR48y7sliHx0Dh7zO+ZTy5 X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a25:acda:0:b0:e57:e61b:8b5d with SMTP id 3f1490d57ef6-e57e61b8ca3mr24401276.5.1737527077833; Tue, 21 Jan 2025 22:24:37 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:21 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-7-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 06/17] perf capstone: Support for dlopen-ing libcapstone.so From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org If perf wasn't built against libcapstone, no HAVE_LIBCAPSTONE_SUPPORT, support dlopen-ing libcapstone.so and then calling the necessary functions by looking them up using dlsym. Reverse engineer the types in the API using pahole, adding only what's used in the perf code or necessary for the sake of struct size and alignment. Signed-off-by: Ian Rogers --- tools/perf/util/capstone.c | 287 ++++++++++++++++++++++++++++++++----- 1 file changed, 248 insertions(+), 39 deletions(-) diff --git a/tools/perf/util/capstone.c b/tools/perf/util/capstone.c index c9845e4d8781..8d65c7a55a8b 100644 --- a/tools/perf/util/capstone.c +++ b/tools/perf/util/capstone.c @@ -11,19 +11,249 @@ #include "print_insn.h" #include "symbol.h" #include "thread.h" +#include #include +#include #include #ifdef HAVE_LIBCAPSTONE_SUPPORT #include +#else +typedef size_t csh; +enum cs_arch { + CS_ARCH_ARM = 0, + CS_ARCH_ARM64 = 1, + CS_ARCH_X86 = 3, + CS_ARCH_SYSZ = 6, +}; +enum cs_mode { + CS_MODE_ARM = 0, + CS_MODE_32 = 1 << 2, + CS_MODE_64 = 1 << 3, + CS_MODE_V8 = 1 << 6, + CS_MODE_BIG_ENDIAN = 1 << 31, +}; +enum cs_opt_type { + CS_OPT_SYNTAX = 1, + CS_OPT_DETAIL = 2, +}; +enum cs_opt_value { + CS_OPT_SYNTAX_ATT = 2, + CS_OPT_ON = 3, +}; +enum cs_err { + CS_ERR_OK = 0, + CS_ERR_HANDLE = 3, +}; +enum x86_op_type { + X86_OP_IMM = 2, + X86_OP_MEM = 3, +}; +enum x86_reg { + X86_REG_RIP = 41, +}; +typedef int32_t x86_avx_bcast; +struct x86_op_mem { + enum x86_reg segment; + enum x86_reg base; + enum x86_reg index; + int scale; + int64_t disp; +}; + +struct cs_x86_op { + enum x86_op_type type; + union { + enum x86_reg reg; + int64_t imm; + struct x86_op_mem mem; + }; + uint8_t size; + uint8_t access; + x86_avx_bcast avx_bcast; + bool avx_zero_opmask; +}; +struct cs_x86_encoding { + uint8_t modrm_offset; + uint8_t disp_offset; + uint8_t disp_size; + uint8_t imm_offset; + uint8_t imm_size; +}; +typedef int32_t x86_xop_cc; +typedef int32_t x86_sse_cc; +typedef int32_t x86_avx_cc; +typedef int32_t x86_avx_rm; +struct cs_x86 { + uint8_t prefix[4]; + uint8_t opcode[4]; + uint8_t rex; + uint8_t addr_size; + uint8_t modrm; + uint8_t sib; + int64_t disp; + enum x86_reg sib_index; + int8_t sib_scale; + enum x86_reg sib_base; + x86_xop_cc xop_cc; + x86_sse_cc sse_cc; + x86_avx_cc avx_cc; + bool avx_sae; + x86_avx_rm avx_rm; + union { + uint64_t eflags; + uint64_t fpu_flags; + }; + uint8_t op_count; + struct cs_x86_op operands[8]; + struct cs_x86_encoding encoding; +}; +struct cs_detail { + uint16_t regs_read[12]; + uint8_t regs_read_count; + uint16_t regs_write[20]; + uint8_t regs_write_count; + uint8_t groups[8]; + uint8_t groups_count; + + union { + struct cs_x86 x86; + }; +}; +struct cs_insn { + unsigned int id; + uint64_t address; + uint16_t size; + uint8_t bytes[16]; + char mnemonic[32]; + char op_str[160]; + struct cs_detail *detail; +}; +#endif + +#ifndef HAVE_LIBCAPSTONE_SUPPORT +static void *perf_cs_dll_handle(void) +{ + static bool dll_handle_init; + static void *dll_handle; + + if (!dll_handle_init) { + dll_handle_init = true; + dll_handle = dlopen("libcapstone.so", RTLD_LAZY); + if (!dll_handle) + pr_debug("dlopen failed for libcapstone.so\n"); + } + return dll_handle; +} +#endif + +static enum cs_err perf_cs_open(enum cs_arch arch, enum cs_mode mode, csh *handle) +{ +#ifdef HAVE_LIBCAPSTONE_SUPPORT + return cs_open(arch, mode, handle); +#else + static bool fn_init; + static enum cs_err (*fn)(enum cs_arch arch, enum cs_mode mode, csh *handle); + + if (!fn_init) { + fn = dlsym(perf_cs_dll_handle(), "cs_open"); + if (!fn) + pr_debug("dlsym failed for cs_open\n"); + fn_init = true; + } + if (!fn) + return CS_ERR_HANDLE; + return fn(arch, mode, handle); +#endif +} + +static enum cs_err perf_cs_option(csh handle, enum cs_opt_type type, size_t value) +{ +#ifdef HAVE_LIBCAPSTONE_SUPPORT + return cs_option(handle, type, value); +#else + static bool fn_init; + static enum cs_err (*fn)(csh handle, enum cs_opt_type type, size_t value); + + if (!fn_init) { + fn = dlsym(perf_cs_dll_handle(), "cs_option"); + if (!fn) + pr_debug("dlsym failed for cs_option\n"); + fn_init = true; + } + if (!fn) + return CS_ERR_HANDLE; + return fn(handle, type, value); +#endif +} + +static size_t perf_cs_disasm(csh handle, const uint8_t *code, size_t code_size, + uint64_t address, size_t count, struct cs_insn **insn) +{ +#ifdef HAVE_LIBCAPSTONE_SUPPORT + return cs_disasm(handle, code, code_size, address, count, insn); +#else + static bool fn_init; + static enum cs_err (*fn)(csh handle, const uint8_t *code, size_t code_size, + uint64_t address, size_t count, struct cs_insn **insn); + + if (!fn_init) { + fn = dlsym(perf_cs_dll_handle(), "cs_disasm"); + if (!fn) + pr_debug("dlsym failed for cs_disasm\n"); + fn_init = true; + } + if (!fn) + return CS_ERR_HANDLE; + return fn(handle, code, code_size, address, count, insn); #endif +} +static void perf_cs_free(struct cs_insn *insn, size_t count) +{ #ifdef HAVE_LIBCAPSTONE_SUPPORT + cs_free(insn, count); +#else + static bool fn_init; + static void (*fn)(struct cs_insn *insn, size_t count); + + if (!fn_init) { + fn = dlsym(perf_cs_dll_handle(), "cs_free"); + if (!fn) + pr_debug("dlsym failed for cs_free\n"); + fn_init = true; + } + if (!fn) + return; + fn(insn, count); +#endif +} + +static enum cs_err perf_cs_close(csh *handle) +{ +#ifdef HAVE_LIBCAPSTONE_SUPPORT + return cs_close(handle); +#else + static bool fn_init; + static enum cs_err (*fn)(csh *handle); + + if (!fn_init) { + fn = dlsym(perf_cs_dll_handle(), "cs_close"); + if (!fn) + pr_debug("dlsym failed for cs_close\n"); + fn_init = true; + } + if (!fn) + return CS_ERR_HANDLE; + return fn(handle); +#endif +} + static int capstone_init(struct machine *machine, csh *cs_handle, bool is64, bool disassembler_style) { - cs_arch arch; - cs_mode mode; + enum cs_arch arch; + enum cs_mode mode; if (machine__is(machine, "x86_64") && is64) { arch = CS_ARCH_X86; @@ -44,7 +274,7 @@ static int capstone_init(struct machine *machine, csh *cs_handle, bool is64, return -1; } - if (cs_open(arch, mode, cs_handle) != CS_ERR_OK) { + if (perf_cs_open(arch, mode, cs_handle) != CS_ERR_OK) { pr_warning_once("cs_open failed\n"); return -1; } @@ -56,27 +286,25 @@ static int capstone_init(struct machine *machine, csh *cs_handle, bool is64, * is set via annotation args */ if (disassembler_style) - cs_option(*cs_handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); + perf_cs_option(*cs_handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); /* * Resolving address operands to symbols is implemented * on x86 by investigating instruction details. */ - cs_option(*cs_handle, CS_OPT_DETAIL, CS_OPT_ON); + perf_cs_option(*cs_handle, CS_OPT_DETAIL, CS_OPT_ON); } return 0; } -#endif -#ifdef HAVE_LIBCAPSTONE_SUPPORT -static size_t print_insn_x86(struct thread *thread, u8 cpumode, cs_insn *insn, +static size_t print_insn_x86(struct thread *thread, u8 cpumode, struct cs_insn *insn, int print_opts, FILE *fp) { struct addr_location al; size_t printed = 0; if (insn->detail && insn->detail->x86.op_count == 1) { - cs_x86_op *op = &insn->detail->x86.operands[0]; + struct cs_x86_op *op = &insn->detail->x86.operands[0]; addr_location__init(&al); if (op->type == X86_OP_IMM && @@ -94,7 +322,6 @@ static size_t print_insn_x86(struct thread *thread, u8 cpumode, cs_insn *insn, printed += fprintf(fp, "%s %s", insn[0].mnemonic, insn[0].op_str); return printed; } -#endif ssize_t capstone__fprintf_insn_asm(struct machine *machine __maybe_unused, @@ -105,9 +332,8 @@ ssize_t capstone__fprintf_insn_asm(struct machine *machine __maybe_unused, uint64_t ip __maybe_unused, int *lenp __maybe_unused, int print_opts __maybe_unused, FILE *fp __maybe_unused) { -#ifdef HAVE_LIBCAPSTONE_SUPPORT size_t printed; - cs_insn *insn; + struct cs_insn *insn; csh cs_handle; size_t count; int ret; @@ -117,7 +343,7 @@ ssize_t capstone__fprintf_insn_asm(struct machine *machine __maybe_unused, if (ret < 0) return ret; - count = cs_disasm(cs_handle, code, code_size, ip, 1, &insn); + count = perf_cs_disasm(cs_handle, code, code_size, ip, 1, &insn); if (count > 0) { if (machine__normalized_is(machine, "x86")) printed = print_insn_x86(thread, cpumode, &insn[0], print_opts, fp); @@ -125,20 +351,16 @@ ssize_t capstone__fprintf_insn_asm(struct machine *machine __maybe_unused, printed = fprintf(fp, "%s %s", insn[0].mnemonic, insn[0].op_str); if (lenp) *lenp = insn->size; - cs_free(insn, count); + perf_cs_free(insn, count); } else { printed = -1; } - cs_close(&cs_handle); + perf_cs_close(&cs_handle); return printed; -#else - return -1; -#endif } -#ifdef HAVE_LIBCAPSTONE_SUPPORT -static void print_capstone_detail(cs_insn *insn, char *buf, size_t len, +static void print_capstone_detail(struct cs_insn *insn, char *buf, size_t len, struct annotate_args *args, u64 addr) { int i; @@ -153,7 +375,7 @@ static void print_capstone_detail(cs_insn *insn, char *buf, size_t len, return; for (i = 0; i < insn->detail->x86.op_count; i++) { - cs_x86_op *op = &insn->detail->x86.operands[i]; + struct cs_x86_op *op = &insn->detail->x86.operands[i]; u64 orig_addr; if (op->type != X86_OP_MEM) @@ -194,9 +416,7 @@ static void print_capstone_detail(cs_insn *insn, char *buf, size_t len, break; } } -#endif -#ifdef HAVE_LIBCAPSTONE_SUPPORT struct find_file_offset_data { u64 ip; u64 offset; @@ -213,9 +433,7 @@ static int find_file_offset(u64 start, u64 len, u64 pgoff, void *arg) } return 0; } -#endif -#ifdef HAVE_LIBCAPSTONE_SUPPORT static u8 * read_symbol(const char *filename, struct map *map, struct symbol *sym, u64 *len, bool *is_64bit) @@ -262,13 +480,11 @@ read_symbol(const char *filename, struct map *map, struct symbol *sym, free(buf); return NULL; } -#endif int symbol__disassemble_capstone(const char *filename __maybe_unused, struct symbol *sym __maybe_unused, struct annotate_args *args __maybe_unused) { -#ifdef HAVE_LIBCAPSTONE_SUPPORT struct annotation *notes = symbol__annotation(sym); struct map *map = args->ms.map; u64 start = map__rip_2objdump(map, sym->start); @@ -279,7 +495,7 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, bool needs_cs_close = false; u8 *buf = NULL; csh handle; - cs_insn *insn = NULL; + struct cs_insn *insn = NULL; char disasm_buf[512]; struct disasm_line *dl; bool disassembler_style = false; @@ -316,7 +532,7 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, needs_cs_close = true; - free_count = count = cs_disasm(handle, buf, len, start, len, &insn); + free_count = count = perf_cs_disasm(handle, buf, len, start, len, &insn); for (i = 0, offset = 0; i < count; i++) { int printed; @@ -355,9 +571,9 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, out: if (needs_cs_close) { - cs_close(&handle); + perf_cs_close(&handle); if (free_count > 0) - cs_free(insn, free_count); + perf_cs_free(insn, free_count); } free(buf); return count < 0 ? count : 0; @@ -377,16 +593,12 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, } count = -1; goto out; -#else - return -1; -#endif } int symbol__disassemble_capstone_powerpc(const char *filename __maybe_unused, struct symbol *sym __maybe_unused, struct annotate_args *args __maybe_unused) { -#ifdef HAVE_LIBCAPSTONE_SUPPORT struct annotation *notes = symbol__annotation(sym); struct map *map = args->ms.map; struct dso *dso = map__dso(map); @@ -499,7 +711,7 @@ int symbol__disassemble_capstone_powerpc(const char *filename __maybe_unused, out: if (needs_cs_close) - cs_close(&handle); + perf_cs_close(&handle); free(buf); return count < 0 ? count : 0; @@ -508,7 +720,4 @@ int symbol__disassemble_capstone_powerpc(const char *filename __maybe_unused, close(fd); count = -1; goto out; -#else - return -1; -#endif } From patchwork Wed Jan 22 06:23:22 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946895 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2ECFD1BD4F1 for ; Wed, 22 Jan 2025 06:24:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527090; cv=none; b=FrKa0Xh51qN8oM1abOYOVzsMjto0by3gvoQMYtmKKW2dBwpLDqOkeaDxYTI2EfA3734zvaDfoT+mHuIcAI7PPlH178sTPHWZSCh+bxyT4oU8RaswL6/JZsj1Rg8P2kbxaDWuoB5i2eF0r7iLpAzBPoF3zhyguMg9nyvoFJ9d2yw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527090; c=relaxed/simple; bh=6Dnx/wnBwDBR9erRaIWVSMvw7if6PKKA/0Y+ez6I5JI=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=tALZ7BNohiJO9xUlZcMG+iDW5YZTAhzG+tVahZs7fYrDqEJgcdcdScBd1OZRFzc/00nDC6SH7Atqd5LmoPK68EvVnIOZGJVJ+eApLur1rzvmsqKqwoq9cB9WtFMryu3V8v68SvVvyfHxRNnUtSjAzYLPRNSkc6I1eiJnsXq6UyA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Lox9nzeU; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Lox9nzeU" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-e578b0d2afdso16992455276.3 for ; Tue, 21 Jan 2025 22:24:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527085; x=1738131885; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=dzLcjr6O61jYzsZav0yweFrp3Yn/RqRQUqm43OH2Kc8=; b=Lox9nzeUFaCfV7uk8hyDv4vvXCu18fZfu8fsuSqSD8Lc8E58KnehLfV8lSckZJop8J zi6Y0P1Z2zIlt44+XYNvShIsL3WSjzYw/tr1BShJjc7cPxEQaw2RCLGbVWlp7zPoHex7 jaMfN7Fg4gFC+82hj0j5SEK2RnXF7reIxhmPRz8LuwMCDuHtA2+YqiK6mOEJxqFTJ7sB gssoAf6DQvpJQ8selSBlx/Ql4qK/Sj1lOi66/u8t4aEYKODYafCMcCw/tP+ekaRX0le5 Md1pt8oWAOYaglIazvolT4XkCzlBo2XGbJU78wtlD4ZGy2wpiEk2lEr06gC5dutj06Pr O0uA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527085; x=1738131885; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=dzLcjr6O61jYzsZav0yweFrp3Yn/RqRQUqm43OH2Kc8=; b=hY5LU99ziZuKN1LALVSw0/mV/okxiPoUfQBwbjrAX1uxT+gPVwy+2kLoMcCXxSG8UZ 7zzeCLJTXCbU5gF3A/2GpIBf4wlVTpiJTZf2m13mfYEGARZ24Np1j/PDDilJvhXEexb8 8BMCbqLiEV8WrCyiLSjqYNQHgFQ7F1Rdd+JCuQgwIDOBnGNkWekSTgcXIvYZ+5uCyCtS rVgRZZmRzc1A18TdIzJdXDF74JtPbRm8fSnLmRkn2kkyXb7u67bWu5vdi+Gf15hG8O/+ v9xT6wzGbYhwGiwsNvLwfvCqyPQLi58l+T22jLnW4yrTtSSFtHi8EsJtxgZktnDW4kA8 IVlQ== X-Forwarded-Encrypted: i=1; AJvYcCWHmH4FhrgeNMgLNlJwVw/eAbRUnaVGbKGfonWYfeYqK0GroQQtMNYEdyMZDmnDi0BCzRg=@vger.kernel.org X-Gm-Message-State: AOJu0YzKG04z+z38d+xTuYDEaxc3GOD3ljsrbnfREABd3vk4hKPgt5cX xtVRqhmWa+qE+QTI44AqtbWb3bx8ShPuDXycJpJYDGJfY6wvwzndJZ9O6yW1z5cT2IXVG1h7yqM pRi8obQ== X-Google-Smtp-Source: AGHT+IG70iVzkJaei+JOv9VI9WG4JUemPvM+BnKbB85PIFrCDBONxI/Gv0xIkOsOSIVIENT3hHxsVR7pvwfu X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a25:aab2:0:b0:e39:8506:c03d with SMTP id 3f1490d57ef6-e57b138d8demr38308276.9.1737527085349; Tue, 21 Jan 2025 22:24:45 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:22 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-8-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 07/17] perf llvm: Support for dlopen-ing libLLVM.so From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org If perf wasn't built against libLLVM, no HAVE_LIBLLVM_SUPPORT, support dlopen-ing libLLVM.so and then calling the necessary functions by looking them up using dlsym. As the C++ code in llvm-c-helpers used for addr2line is problematic to call using dlsym, build that C++ code against libLLVM.so as a separate shared object, and support dynamic loading of it. This build option is enabled with LIBLLVM_DYNAMIC=1 Signed-off-by: Ian Rogers --- tools/perf/Makefile.config | 13 ++ tools/perf/Makefile.perf | 23 ++- tools/perf/tests/make | 2 + tools/perf/util/Build | 2 +- tools/perf/util/llvm-c-helpers.cpp | 113 +++++++++++- tools/perf/util/llvm.c | 271 +++++++++++++++++++++++++---- 6 files changed, 386 insertions(+), 38 deletions(-) diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index cd773fbbc176..5c2814acc5d5 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -963,6 +963,19 @@ ifndef NO_LIBLLVM NO_LIBLLVM := 1 endif endif +ifdef LIBLLVM_DYNAMIC + ifndef NO_LIBLLVM + $(error LIBLLVM_DYNAMIC should be used with NO_LIBLLVM) + endif + $(call feature_check,llvm-perf) + ifneq ($(feature-llvm-perf), 1) + $(warning LIBLLVM_DYNAMIC requires libLLVM.so which wasn't feature detected) + endif + CFLAGS += -DHAVE_LIBLLVM_DYNAMIC + CFLAGS += $(shell $(LLVM_CONFIG) --cflags) + CXXFLAGS += -DHAVE_LIBLLVM_DYNAMIC + CXXFLAGS += $(shell $(LLVM_CONFIG) --cxxflags) +endif ifndef NO_DEMANGLE $(call feature_check,cxa-demangle) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 55d6ce9ea52f..eae77f6af59d 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -456,6 +456,12 @@ ifndef NO_JVMTI PROGRAMS += $(OUTPUT)$(LIBJVMTI) endif +LIBPERF_LLVM = libperf-llvm.so + +ifdef LIBLLVM_DYNAMIC +PROGRAMS += $(OUTPUT)$(LIBPERF_LLVM) +endif + DLFILTERS := dlfilter-test-api-v0.so dlfilter-test-api-v2.so dlfilter-show-cycles.so DLFILTERS := $(patsubst %,$(OUTPUT)dlfilters/%,$(DLFILTERS)) @@ -1019,6 +1025,16 @@ $(LIBSYMBOL)-clean: $(call QUIET_CLEAN, libsymbol) $(Q)$(RM) -r -- $(LIBSYMBOL_OUTPUT) +ifdef LIBLLVM_DYNAMIC +LIBPERF_LLVM_CXXFLAGS := $(call filter-out,-DHAVE_LIBLLVM_DYNAMIC,$(CXXFLAGS)) -DHAVE_LIBLLVM_SUPPORT +LIBPERF_LLVM_LIBS = -L$(shell $(LLVM_CONFIG) --libdir) $(LIBLLVM) -lstdc++ + +$(OUTPUT)$(LIBPERF_LLVM): util/llvm-c-helpers.cpp + $(QUIET_LINK)$(CXX) $(LIBPERF_LLVM_CXXFLAGS) $(LIBPERF_LLVM_LIBS) -shared -o $@ $< + +$(OUTPUT)perf: $(OUTPUT)$(LIBPERF_LLVM) +endif + help: @echo 'Perf make targets:' @echo ' doc - make *all* documentation (see below)' @@ -1120,6 +1136,11 @@ ifndef NO_JVMTI $(call QUIET_INSTALL, $(LIBJVMTI)) \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)'; \ $(INSTALL) $(OUTPUT)$(LIBJVMTI) '$(DESTDIR_SQ)$(libdir_SQ)'; +endif +ifdef LIBLLVM_DYNAMIC + $(call QUIET_INSTALL, $(LIBPERF_LLVM)) \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)'; \ + $(INSTALL) $(OUTPUT)$(LIBPERF_LLVM) '$(DESTDIR_SQ)$(libdir_SQ)'; endif $(call QUIET_INSTALL, libexec) \ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' @@ -1301,7 +1322,7 @@ clean:: $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBSYMBOL)-clean $( -name '\.*.cmd' -delete -o -name '\.*.d' -delete -o -name '*.shellcheck_log' -delete $(Q)$(RM) $(OUTPUT).config-detected $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 \ - perf-read-vdsox32 $(OUTPUT)$(LIBJVMTI).so + perf-read-vdsox32 $(OUTPUT)$(LIBJVMTI) $(OUTPUT)$(LIBPERF_LLVM) $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo \ $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE \ $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \ diff --git a/tools/perf/tests/make b/tools/perf/tests/make index 0ee94caf9ec1..44d76eacce49 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -93,6 +93,7 @@ make_libbpf_dynamic := LIBBPF_DYNAMIC=1 make_no_libbpf_DEBUG := NO_LIBBPF=1 DEBUG=1 make_no_libcrypto := NO_LIBCRYPTO=1 make_no_libllvm := NO_LIBLLVM=1 +make_libllvm_dynamic := NO_LIBLLVM=1 LIBLLVM_DYNAMIC=1 make_with_babeltrace:= LIBBABELTRACE=1 make_with_coresight := CORESIGHT=1 make_no_sdt := NO_SDT=1 @@ -162,6 +163,7 @@ run += make_no_libbpf run += make_no_libbpf_DEBUG run += make_no_libcrypto run += make_no_libllvm +run += make_libllvm_dynamic run += make_no_sdt run += make_no_syscall_tbl run += make_with_babeltrace diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 6fe0b5882c97..eb00c599e179 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -27,6 +27,7 @@ perf-util-y += find_bit.o perf-util-y += get_current_dir_name.o perf-util-y += levenshtein.o perf-util-y += llvm.o +perf-util-y += llvm-c-helpers.o perf-util-y += mmap.o perf-util-y += memswap.o perf-util-y += parse-events.o @@ -239,7 +240,6 @@ perf-util-$(CONFIG_CXX_DEMANGLE) += demangle-cxx.o perf-util-y += demangle-ocaml.o perf-util-y += demangle-java.o perf-util-y += demangle-rust.o -perf-util-$(CONFIG_LIBLLVM) += llvm-c-helpers.o ifdef CONFIG_JITDUMP perf-util-$(CONFIG_LIBELF) += jitdump.o diff --git a/tools/perf/util/llvm-c-helpers.cpp b/tools/perf/util/llvm-c-helpers.cpp index 004081bd12c9..5a6f76e6b705 100644 --- a/tools/perf/util/llvm-c-helpers.cpp +++ b/tools/perf/util/llvm-c-helpers.cpp @@ -5,17 +5,23 @@ * macros (e.g. noinline) that conflict with compiler builtins used * by LLVM. */ +#ifdef HAVE_LIBLLVM_SUPPORT #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" /* Needed for LLVM <= 15 */ #include #include #pragma GCC diagnostic pop +#endif +#if !defined(HAVE_LIBLLVM_SUPPORT) || defined(HAVE_LIBLLVM_DYNAMIC) +#include +#endif #include #include #include #include extern "C" { +#include "debug.h" #include } #include "llvm-c-helpers.h" @@ -23,14 +29,33 @@ extern "C" { extern "C" char *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name); +#ifdef HAVE_LIBLLVM_SUPPORT using namespace llvm; using llvm::symbolize::LLVMSymbolizer; +#endif + +#if !defined(HAVE_LIBLLVM_SUPPORT) && defined(HAVE_LIBLLVM_DYNAMIC) +static void *perf_llvm_c_helpers_dll_handle(void) +{ + static bool dll_handle_init; + static void *dll_handle; + + if (!dll_handle_init) { + dll_handle_init = true; + dll_handle = dlopen("libperf-llvm.so", RTLD_LAZY); + if (!dll_handle) + pr_debug("dlopen failed for libperf-llvm.so\n"); + } + return dll_handle; +} +#endif /* * Allocate a static LLVMSymbolizer, which will live to the end of the program. * Unlike the bfd paths, LLVMSymbolizer has its own cache, so we do not need * to store anything in the dso struct. */ +#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) static LLVMSymbolizer *get_symbolizer() { static LLVMSymbolizer *instance = nullptr; @@ -49,8 +74,10 @@ static LLVMSymbolizer *get_symbolizer() } return instance; } +#endif /* Returns 0 on error, 1 on success. */ +#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) static int extract_file_and_line(const DILineInfo &line_info, char **file, unsigned int *line) { @@ -69,13 +96,15 @@ static int extract_file_and_line(const DILineInfo &line_info, char **file, *line = line_info.Line; return 1; } +#endif extern "C" -int llvm_addr2line(const char *dso_name, u64 addr, - char **file, unsigned int *line, - bool unwind_inlines, - llvm_a2l_frame **inline_frames) +int llvm_addr2line(const char *dso_name __maybe_unused, u64 addr __maybe_unused, + char **file __maybe_unused, unsigned int *line __maybe_unused, + bool unwind_inlines __maybe_unused, + llvm_a2l_frame **inline_frames __maybe_unused) { +#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) LLVMSymbolizer *symbolizer = get_symbolizer(); object::SectionedAddress sectioned_addr = { addr, @@ -135,8 +164,33 @@ int llvm_addr2line(const char *dso_name, u64 addr, return 0; return extract_file_and_line(*res_or_err, file, line); } +#elif defined(HAVE_LIBLLVM_DYNAMIC) + static bool fn_init; + static int (*fn)(const char *dso_name, u64 addr, + char **file, unsigned int *line, + bool unwind_inlines, + llvm_a2l_frame **inline_frames); + + if (!fn_init) { + void * handle = perf_llvm_c_helpers_dll_handle(); + + if (!handle) + return 0; + + fn = reinterpret_cast(dlsym(handle, "llvm_addr2line")); + if (!fn) + pr_debug("dlsym failed for llvm_addr2line\n"); + fn_init = true; + } + if (!fn) + return 0; + return fn(dso_name, addr, file, line, unwind_inlines, inline_frames); +#else + return 0; +#endif } +#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) static char * make_symbol_relative_string(struct dso *dso, const char *sym_name, u64 addr, u64 base_addr) @@ -158,10 +212,13 @@ make_symbol_relative_string(struct dso *dso, const char *sym_name, return strdup(sym_name); } } +#endif extern "C" -char *llvm_name_for_code(struct dso *dso, const char *dso_name, u64 addr) +char *llvm_name_for_code(struct dso *dso __maybe_unused, const char *dso_name __maybe_unused, + u64 addr __maybe_unused) { +#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) LLVMSymbolizer *symbolizer = get_symbolizer(); object::SectionedAddress sectioned_addr = { addr, @@ -175,11 +232,34 @@ char *llvm_name_for_code(struct dso *dso, const char *dso_name, u64 addr) return make_symbol_relative_string( dso, res_or_err->FunctionName.c_str(), addr, res_or_err->StartAddress ? *res_or_err->StartAddress : 0); +#elif defined(HAVE_LIBLLVM_DYNAMIC) + static bool fn_init; + static char *(*fn)(struct dso *dso, const char *dso_name, u64 addr); + + if (!fn_init) { + void * handle = perf_llvm_c_helpers_dll_handle(); + + if (!handle) + return NULL; + + fn = reinterpret_cast(dlsym(handle, "llvm_name_for_code")); + if (!fn) + pr_debug("dlsym failed for llvm_name_for_code\n"); + fn_init = true; + } + if (!fn) + return NULL; + return fn(dso, dso_name, addr); +#else + return 0; +#endif } extern "C" -char *llvm_name_for_data(struct dso *dso, const char *dso_name, u64 addr) +char *llvm_name_for_data(struct dso *dso __maybe_unused, const char *dso_name __maybe_unused, + u64 addr __maybe_unused) { +#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) LLVMSymbolizer *symbolizer = get_symbolizer(); object::SectionedAddress sectioned_addr = { addr, @@ -193,4 +273,25 @@ char *llvm_name_for_data(struct dso *dso, const char *dso_name, u64 addr) return make_symbol_relative_string( dso, res_or_err->Name.c_str(), addr, res_or_err->Start); +#elif defined(HAVE_LIBLLVM_DYNAMIC) + static bool fn_init; + static char *(*fn)(struct dso *dso, const char *dso_name, u64 addr); + + if (!fn_init) { + void * handle = perf_llvm_c_helpers_dll_handle(); + + if (!handle) + return NULL; + + fn = reinterpret_cast(dlsym(handle, "llvm_name_for_data")); + if (!fn) + pr_debug("dlsym failed for llvm_name_for_data\n"); + fn_init = true; + } + if (!fn) + return NULL; + return fn(dso, dso_name, addr); +#else + return 0; +#endif } diff --git a/tools/perf/util/llvm.c b/tools/perf/util/llvm.c index ddc737194692..f6a8943b7c9d 100644 --- a/tools/perf/util/llvm.c +++ b/tools/perf/util/llvm.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "llvm.h" +#include "llvm-c-helpers.h" #include "annotate.h" #include "debug.h" #include "dso.h" @@ -7,17 +8,243 @@ #include "namespaces.h" #include "srcline.h" #include "symbol.h" +#include #include +#include #include #include -#ifdef HAVE_LIBLLVM_SUPPORT -#include "llvm-c-helpers.h" +#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) #include #include +#else +typedef void *LLVMDisasmContextRef; +typedef int (*LLVMOpInfoCallback)(void *dis_info, uint64_t pc, uint64_t offset, + uint64_t op_size, uint64_t inst_size, + int tag_type, void *tag_buf); +typedef const char *(*LLVMSymbolLookupCallback)(void *dis_info, + uint64_t reference_value, + uint64_t *reference_type, + uint64_t reference_pc, + const char **reference_name); +#define LLVMDisassembler_ReferenceType_InOut_None 0 +#define LLVMDisassembler_ReferenceType_In_Branch 1 +#define LLVMDisassembler_ReferenceType_In_PCrel_Load 2 +#define LLVMDisassembler_Option_PrintImmHex 2 +#define LLVMDisassembler_Option_AsmPrinterVariant 4 +const char *llvm_targets[] = { + "AMDGPU", + "ARM", + "AVR", + "BPF", + "Hexagon", + "Lanai", + "LoongArch", + "Mips", + "MSP430", + "NVPTX", + "PowerPC", + "RISCV", + "Sparc", + "SystemZ", + "VE", + "WebAssembly", + "X86", + "XCore", + "M68k", + "Xtensa", +}; +#endif + +#if !defined(HAVE_LIBLLVM_SUPPORT) || defined(HAVE_LIBLLVM_DYNAMIC) +static void *perf_llvm_dll_handle(void) +{ + static bool dll_handle_init; + static void *dll_handle; + + if (!dll_handle_init) { + dll_handle_init = true; + dll_handle = dlopen("libLLVM.so", RTLD_LAZY); + if (!dll_handle) + pr_debug("dlopen failed for libLLVM.so\n"); + } + return dll_handle; +} +#endif + +#if !defined(HAVE_LIBLLVM_SUPPORT) || defined(HAVE_LIBLLVM_DYNAMIC) +static void *perf_llvm_dll_fun(const char *fmt, const char *target) +{ + char buf[128]; + void *fn; + + snprintf(buf, sizeof(buf), fmt, target); + fn = dlsym(perf_llvm_dll_handle(), buf); + if (!fn) + pr_debug("dlsym failed for %s\n", buf); + + return fn; +} +#endif + +static void perf_LLVMInitializeAllTargetInfos(void) +{ +#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) + LLVMInitializeAllTargetInfos(); +#else + /* LLVMInitializeAllTargetInfos is a header file function not available as a symbol. */ + static bool done_init; + + if (done_init) + return; + + for (size_t i = 0; i < ARRAY_SIZE(llvm_targets); i++) { + void (*fn)(void) = perf_llvm_dll_fun("LLVMInitialize%sTargetInfo", + llvm_targets[i]); + + if (!fn) + continue; + fn(); + } + done_init = true; +#endif +} + +static void perf_LLVMInitializeAllTargetMCs(void) +{ +#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) + LLVMInitializeAllTargetMCs(); +#else + /* LLVMInitializeAllTargetMCs is a header file function not available as a symbol. */ + static bool done_init; + + if (done_init) + return; + + for (size_t i = 0; i < ARRAY_SIZE(llvm_targets); i++) { + void (*fn)(void) = perf_llvm_dll_fun("LLVMInitialize%sTargetMC", + llvm_targets[i]); + + if (!fn) + continue; + fn(); + } + done_init = true; +#endif +} + +static void perf_LLVMInitializeAllDisassemblers(void) +{ +#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) + LLVMInitializeAllDisassemblers(); +#else + /* LLVMInitializeAllDisassemblers is a header file function not available as a symbol. */ + static bool done_init; + + if (done_init) + return; + + for (size_t i = 0; i < ARRAY_SIZE(llvm_targets); i++) { + void (*fn)(void) = perf_llvm_dll_fun("LLVMInitialize%sDisassembler", + llvm_targets[i]); + + if (!fn) + continue; + fn(); + } + done_init = true; +#endif +} + +static LLVMDisasmContextRef perf_LLVMCreateDisasm(const char *triple_name, void *dis_info, + int tag_type, LLVMOpInfoCallback get_op_info, + LLVMSymbolLookupCallback symbol_lookup) +{ +#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) + return LLVMCreateDisasm(triple_name, dis_info, tag_type, get_op_info, symbol_lookup); +#else + static bool fn_init; + static LLVMDisasmContextRef (*fn)(const char *triple_name, void *dis_info, + int tag_type, LLVMOpInfoCallback get_op_info, + LLVMSymbolLookupCallback symbol_lookup); + + if (!fn_init) { + fn = dlsym(perf_llvm_dll_handle(), "LLVMCreateDisasm"); + if (!fn) + pr_debug("dlsym failed for LLVMCreateDisasm\n"); + fn_init = true; + } + if (!fn) + return NULL; + return fn(triple_name, dis_info, tag_type, get_op_info, symbol_lookup); +#endif +} + +static int perf_LLVMSetDisasmOptions(LLVMDisasmContextRef context, uint64_t options) +{ +#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) + return LLVMSetDisasmOptions(context, options); +#else + static bool fn_init; + static int (*fn)(LLVMDisasmContextRef context, uint64_t options); + + if (!fn_init) { + fn = dlsym(perf_llvm_dll_handle(), "LLVMSetDisasmOptions"); + if (!fn) + pr_debug("dlsym failed for LLVMSetDisasmOptions\n"); + fn_init = true; + } + if (!fn) + return 0; + return fn(context, options); +#endif +} + +static size_t perf_LLVMDisasmInstruction(LLVMDisasmContextRef context, uint8_t *bytes, + uint64_t bytes_size, uint64_t pc, + char *out_string, size_t out_string_size) +{ +#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) + return LLVMDisasmInstruction(context, bytes, bytes_size, pc, out_string, out_string_size); +#else + static bool fn_init; + static int (*fn)(LLVMDisasmContextRef context, uint8_t *bytes, + uint64_t bytes_size, uint64_t pc, + char *out_string, size_t out_string_size); + + if (!fn_init) { + fn = dlsym(perf_llvm_dll_handle(), "LLVMDisasmInstruction"); + if (!fn) + pr_debug("dlsym failed for LLVMDisasmInstruction\n"); + fn_init = true; + } + if (!fn) + return 0; + return fn(context, bytes, bytes_size, pc, out_string, out_string_size); +#endif +} + +static void perf_LLVMDisasmDispose(LLVMDisasmContextRef context) +{ +#if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) + LLVMDisasmDispose(context); +#else + static bool fn_init; + static int (*fn)(LLVMDisasmContextRef context); + + if (!fn_init) { + fn = dlsym(perf_llvm_dll_handle(), "LLVMDisasmDispose"); + if (!fn) + pr_debug("dlsym failed for LLVMDisasmDispose\n"); + fn_init = true; + } + if (!fn) + return; + fn(context); #endif +} + -#ifdef HAVE_LIBLLVM_SUPPORT static void free_llvm_inline_frames(struct llvm_a2l_frame *inline_frames, int num_frames) { @@ -29,14 +256,12 @@ static void free_llvm_inline_frames(struct llvm_a2l_frame *inline_frames, zfree(&inline_frames); } } -#endif int llvm__addr2line(const char *dso_name __maybe_unused, u64 addr __maybe_unused, char **file __maybe_unused, unsigned int *line __maybe_unused, struct dso *dso __maybe_unused, bool unwind_inlines __maybe_unused, struct inline_node *node __maybe_unused, struct symbol *sym __maybe_unused) { -#ifdef HAVE_LIBLLVM_SUPPORT struct llvm_a2l_frame *inline_frames = NULL; int num_frames = llvm_addr2line(dso_name, addr, file, line, node && unwind_inlines, &inline_frames); @@ -64,9 +289,6 @@ int llvm__addr2line(const char *dso_name __maybe_unused, u64 addr __maybe_unused free_llvm_inline_frames(inline_frames, num_frames); return num_frames; -#else - return -1; -#endif } void dso__free_a2l_llvm(struct dso *dso __maybe_unused) @@ -75,7 +297,6 @@ void dso__free_a2l_llvm(struct dso *dso __maybe_unused) } -#if defined(HAVE_LIBLLVM_SUPPORT) struct find_file_offset_data { u64 ip; u64 offset; @@ -139,7 +360,6 @@ read_symbol(const char *filename, struct map *map, struct symbol *sym, free(buf); return NULL; } -#endif /* * Whenever LLVM wants to resolve an address into a symbol, it calls this @@ -149,7 +369,6 @@ read_symbol(const char *filename, struct map *map, struct symbol *sym, * should add some textual annotation for after the instruction. The caller * will use this information to add the actual annotation. */ -#ifdef HAVE_LIBLLVM_SUPPORT struct symbol_lookup_storage { u64 branch_addr; u64 pcrel_load_addr; @@ -170,12 +389,10 @@ symbol_lookup_callback(void *disinfo, uint64_t value, *ref_type = LLVMDisassembler_ReferenceType_InOut_None; return NULL; } -#endif int symbol__disassemble_llvm(const char *filename, struct symbol *sym, struct annotate_args *args __maybe_unused) { -#ifdef HAVE_LIBLLVM_SUPPORT struct annotation *notes = symbol__annotation(sym); struct map *map = args->ms.map; struct dso *dso = map__dso(map); @@ -197,9 +414,9 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, if (args->options->objdump_path) return -1; - LLVMInitializeAllTargetInfos(); - LLVMInitializeAllTargetMCs(); - LLVMInitializeAllDisassemblers(); + perf_LLVMInitializeAllTargetInfos(); + perf_LLVMInitializeAllTargetMCs(); + perf_LLVMInitializeAllDisassemblers(); buf = read_symbol(filename, map, sym, &len, &is_64bit); if (buf == NULL) @@ -215,15 +432,14 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, args->arch->name); } - disasm = LLVMCreateDisasm(triplet, &storage, 0, NULL, - symbol_lookup_callback); + disasm = perf_LLVMCreateDisasm(triplet, &storage, 0, NULL, + symbol_lookup_callback); if (disasm == NULL) goto err; if (args->options->disassembler_style && !strcmp(args->options->disassembler_style, "intel")) - LLVMSetDisasmOptions(disasm, - LLVMDisassembler_Option_AsmPrinterVariant); + perf_LLVMSetDisasmOptions(disasm, LLVMDisassembler_Option_AsmPrinterVariant); /* * This needs to be set after AsmPrinterVariant, due to a bug in LLVM; @@ -231,7 +447,7 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, * forget about the PrintImmHex flag (which is applied before if both * are given to the same call). */ - LLVMSetDisasmOptions(disasm, LLVMDisassembler_Option_PrintImmHex); + perf_LLVMSetDisasmOptions(disasm, LLVMDisassembler_Option_PrintImmHex); /* add the function address and name */ scnprintf(disasm_buf, sizeof(disasm_buf), "%#"PRIx64" <%s>:", @@ -256,9 +472,9 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, storage.branch_addr = 0; storage.pcrel_load_addr = 0; - ins_len = LLVMDisasmInstruction(disasm, buf + offset, - len - offset, pc, - disasm_buf, sizeof(disasm_buf)); + ins_len = perf_LLVMDisasmInstruction(disasm, buf + offset, + len - offset, pc, + disasm_buf, sizeof(disasm_buf)); if (ins_len == 0) goto err; disasm_len = strlen(disasm_buf); @@ -314,13 +530,8 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, ret = 0; err: - LLVMDisasmDispose(disasm); + perf_LLVMDisasmDispose(disasm); free(buf); free(line_storage); return ret; -#else // HAVE_LIBLLVM_SUPPORT - pr_debug("The LLVM disassembler isn't linked in for %s in %s\n", - sym->name, filename); - return -1; -#endif } From patchwork Wed Jan 22 06:23:23 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946896 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 02DFB1C3BE6 for ; Wed, 22 Jan 2025 06:24:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527096; cv=none; b=NhTiBFuQyuF1OV/w3Ja6s5MEaIRcHkGRLj31Ltpjzd5kBrNT95Y4jt3hyjFZLLHb/DWEviimvz9H30LbeDE46CGPWSurVprPZz9vYbmCLrbGhp5gGPV6k2q2I1ECbC32IROsUgNgc8uP5SVDqjQ9eP3PhmmdCRYTP6MVyaKukXY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527096; c=relaxed/simple; bh=jZ4IkRMbc56FrM1l0SIjkdbfl4Olsr1QAGf6JHIVKBU=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=U3/0zy47YXeEKhRhpl/rz0yMmCnnjzWwL2Ow0mjHvCwyJK9ZnyPIn4eVUU+HHDMP8V9pwnxipwaBw6hKVE4q26WuX0e420RreGUUb/Nvtx9okpGwVFMl9z271eTWvVtH9RP/MjtGAZkOCJxaScR3O9Z3wn0BzennICXK8lzwAW4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=cnPFxEok; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="cnPFxEok" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-e54cb50c3baso1583721276.0 for ; Tue, 21 Jan 2025 22:24:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527094; x=1738131894; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=voJ/Pq/GvJ/AGxjOFOtV9ZWeGm6Z21/zyADHQU1xORI=; b=cnPFxEokuVIaRdJ13k6bGdjalik9aTqYFe25+VOsRS6AMi2q4JvArcVeJAIPTok/ok 3yA7scf9JXWhnscBSg8xsrpuAB2blZrv7yy+jSwfca1pNTdNekm+zen80KOiVQF3pgDa EotPTI5XkppmJ0qtUPjd+ZjuhKauXaaMnPAbHFxzPDTaaJ/XooHsk44vDTapNQy/jM09 D37PYxI+6u12LPt941CvAV92AWl5C/4fGIshSnAMlIqZfFKS8/nFew7rKRC49adowp6W dgCQxLefgf6v0JUhQCpUlGhkKBhtZCuIY77vq7pB2Q7E9mpFIaEK64MBDbKKzmqT16OR qbCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527094; x=1738131894; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=voJ/Pq/GvJ/AGxjOFOtV9ZWeGm6Z21/zyADHQU1xORI=; b=hjz+UZMIltGaV5raRJDrgdrdM/Acjj0n/cDmKq5u4RqbOI4vLWlA5zLNouZcdjSMvn jtm9+xDGzmcIuJNooasV6oe3ymQTDeTpEz5glR9mMO1QQTqCUI9t68T0Smatcg/yoZt2 A7XtwlG/bf0yGdwaIrolpQkgw/9pKZJFocAmnRwZUUyT7Eytsq0oWNz3lsgRzeGtIs7i vFI4LamBIQaFFxGBjNO6lFpE6FYqa0Co86B7/ivhSEJmxQ2mwPHsG7VZalY9SxukHOxh XdH8KgW/A1ORjMQh1M2/d1FuPkqNVfzi2S06KwKLSp6RmGW9rPY62Ku2u6/wqmd8yQGN 58nA== X-Forwarded-Encrypted: i=1; AJvYcCXIQfPpVZo5x35VMaJHQgpwA3WI39EG+kF4tat0/E6YiN2lvSL20PsS4+aEuASc4uLNHW4=@vger.kernel.org X-Gm-Message-State: AOJu0YyNvUQQuZcKBUJqke1zVt9LUtVxs2H0NhuRaN/OyhlDZ8BcXLc/ at0FGlMv6jLQ4b8ERsughPxhIAvOAuo89SxWDRYEBgFqqo8WjCCaO6xrrxeE4vWn3F620hXEppc mnvs+Xg== X-Google-Smtp-Source: AGHT+IGGtA0A2c0NnRtlqmsTYya1bjH/d2LCz7w5U/h3QISaG3Lb0h0KMLBS05lL6WSmZVrAohMkiUR9M9Hj X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a25:ace7:0:b0:e57:965e:37ac with SMTP id 3f1490d57ef6-e57965e39fcmr71558276.0.1737527093964; Tue, 21 Jan 2025 22:24:53 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:23 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-9-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 08/17] perf llvm: Mangle libperf-llvm.so function names From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org For a function like llvm_addr2line having the libperf-llvm.so exported symbol named llvm_addr2line meant that the perf llvm_addr2line could sometimes erroneously be returned. This led to infinite recursion and eventual stack overflow. To avoid this conflict add a new BUILDING_PERF_LLVMSO when libperf-llvm.so is being built and use it to alter the behavior of MANGLE_PERF_LLVM_API, a macro that prefixes the name when libperf-llvm.so is being built. The prefixed named avoids the name collision. Signed-off-by: Ian Rogers --- tools/perf/Makefile.perf | 3 ++- tools/perf/util/llvm-c-helpers.cpp | 29 ++++++++++++++++++----------- tools/perf/util/llvm-c-helpers.h | 24 ++++++++++++++++-------- 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index eae77f6af59d..a2886abd4f02 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -1026,7 +1026,8 @@ $(LIBSYMBOL)-clean: $(Q)$(RM) -r -- $(LIBSYMBOL_OUTPUT) ifdef LIBLLVM_DYNAMIC -LIBPERF_LLVM_CXXFLAGS := $(call filter-out,-DHAVE_LIBLLVM_DYNAMIC,$(CXXFLAGS)) -DHAVE_LIBLLVM_SUPPORT +LIBPERF_LLVM_CXXFLAGS := $(call filter-out,-DHAVE_LIBLLVM_DYNAMIC,$(CXXFLAGS)) +LIBPERF_LLVM_CXXFLAGS += -DHAVE_LIBLLVM_SUPPORT -DBUILDING_PERF_LLVMSO LIBPERF_LLVM_LIBS = -L$(shell $(LLVM_CONFIG) --libdir) $(LIBLLVM) -lstdc++ $(OUTPUT)$(LIBPERF_LLVM): util/llvm-c-helpers.cpp diff --git a/tools/perf/util/llvm-c-helpers.cpp b/tools/perf/util/llvm-c-helpers.cpp index 5a6f76e6b705..8cea380be5c2 100644 --- a/tools/perf/util/llvm-c-helpers.cpp +++ b/tools/perf/util/llvm-c-helpers.cpp @@ -99,10 +99,12 @@ static int extract_file_and_line(const DILineInfo &line_info, char **file, #endif extern "C" -int llvm_addr2line(const char *dso_name __maybe_unused, u64 addr __maybe_unused, - char **file __maybe_unused, unsigned int *line __maybe_unused, - bool unwind_inlines __maybe_unused, - llvm_a2l_frame **inline_frames __maybe_unused) +int MANGLE_PERF_LLVM_API(llvm_addr2line)(const char *dso_name __maybe_unused, + u64 addr __maybe_unused, + char **file __maybe_unused, + unsigned int *line __maybe_unused, + bool unwind_inlines __maybe_unused, + llvm_a2l_frame **inline_frames __maybe_unused) { #if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) LLVMSymbolizer *symbolizer = get_symbolizer(); @@ -177,7 +179,8 @@ int llvm_addr2line(const char *dso_name __maybe_unused, u64 addr __maybe_unused, if (!handle) return 0; - fn = reinterpret_cast(dlsym(handle, "llvm_addr2line")); + fn = reinterpret_cast( + dlsym(handle, MANGLE_PERF_LLVM_API_STR(llvm_addr2line))); if (!fn) pr_debug("dlsym failed for llvm_addr2line\n"); fn_init = true; @@ -215,8 +218,9 @@ make_symbol_relative_string(struct dso *dso, const char *sym_name, #endif extern "C" -char *llvm_name_for_code(struct dso *dso __maybe_unused, const char *dso_name __maybe_unused, - u64 addr __maybe_unused) +char *MANGLE_PERF_LLVM_API(llvm_name_for_code)(struct dso *dso __maybe_unused, + const char *dso_name __maybe_unused, + u64 addr __maybe_unused) { #if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) LLVMSymbolizer *symbolizer = get_symbolizer(); @@ -242,7 +246,8 @@ char *llvm_name_for_code(struct dso *dso __maybe_unused, const char *dso_name __ if (!handle) return NULL; - fn = reinterpret_cast(dlsym(handle, "llvm_name_for_code")); + fn = reinterpret_cast( + dlsym(handle, MANGLE_PERF_LLVM_API_STR(llvm_name_for_code))); if (!fn) pr_debug("dlsym failed for llvm_name_for_code\n"); fn_init = true; @@ -256,8 +261,9 @@ char *llvm_name_for_code(struct dso *dso __maybe_unused, const char *dso_name __ } extern "C" -char *llvm_name_for_data(struct dso *dso __maybe_unused, const char *dso_name __maybe_unused, - u64 addr __maybe_unused) +char *MANGLE_PERF_LLVM_API(llvm_name_for_data)(struct dso *dso __maybe_unused, + const char *dso_name __maybe_unused, + u64 addr __maybe_unused) { #if defined(HAVE_LIBLLVM_SUPPORT) && !defined(HAVE_LIBLLVM_DYNAMIC) LLVMSymbolizer *symbolizer = get_symbolizer(); @@ -283,7 +289,8 @@ char *llvm_name_for_data(struct dso *dso __maybe_unused, const char *dso_name __ if (!handle) return NULL; - fn = reinterpret_cast(dlsym(handle, "llvm_name_for_data")); + fn = reinterpret_cast( + dlsym(handle, MANGLE_PERF_LLVM_API_STR(llvm_name_for_data))); if (!fn) pr_debug("dlsym failed for llvm_name_for_data\n"); fn_init = true; diff --git a/tools/perf/util/llvm-c-helpers.h b/tools/perf/util/llvm-c-helpers.h index d2b99637a28a..cfcfd540cdae 100644 --- a/tools/perf/util/llvm-c-helpers.h +++ b/tools/perf/util/llvm-c-helpers.h @@ -13,6 +13,14 @@ extern "C" { #endif +/* Support name mangling so that libperf_llvm.so's names don't match those in perf. */ +#ifdef BUILDING_PERF_LLVMSO +#define MANGLE_PERF_LLVM_API(x) PERF_LLVM_SO_ ## x +#else +#define MANGLE_PERF_LLVM_API(x) x +#endif +#define MANGLE_PERF_LLVM_API_STR(x) "PERF_LLVM_SO_" #x + struct dso; struct llvm_a2l_frame { @@ -37,12 +45,12 @@ struct llvm_a2l_frame { * a newly allocated array with that length. The caller is then responsible * for freeing both the strings and the array itself. */ -int llvm_addr2line(const char* dso_name, - u64 addr, - char** file, - unsigned int* line, - bool unwind_inlines, - struct llvm_a2l_frame** inline_frames); +int MANGLE_PERF_LLVM_API(llvm_addr2line)(const char *dso_name, + u64 addr, + char **file, + unsigned int *line, + bool unwind_inlines, + struct llvm_a2l_frame **inline_frames); /* * Simple symbolizers for addresses; will convert something like @@ -50,8 +58,8 @@ int llvm_addr2line(const char* dso_name, * * The returned value must be freed by the caller, with free(). */ -char *llvm_name_for_code(struct dso *dso, const char *dso_name, u64 addr); -char *llvm_name_for_data(struct dso *dso, const char *dso_name, u64 addr); +char *MANGLE_PERF_LLVM_API(llvm_name_for_code)(struct dso *dso, const char *dso_name, u64 addr); +char *MANGLE_PERF_LLVM_API(llvm_name_for_data)(struct dso *dso, const char *dso_name, u64 addr); #ifdef __cplusplus } From patchwork Wed Jan 22 06:23:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946897 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 873AE1B85EC for ; Wed, 22 Jan 2025 06:25:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527105; cv=none; b=cMKAM/rtKmZf15f8zv9CnT9KyvPMj42JLkuTf5ItmbjoeJZ2omP3mgrCkAOSaNX47yZxyHXoSWnO4GXSINSHVl/6Az4IfkB4Re/1N0HpnIFC65c985zf2rk3subsAn7Ta7ovpYteZI4HpPKftD6LhZPLQyuR5RiQ+umALlYUeoM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527105; c=relaxed/simple; bh=HyF8MzGPJg1E6Do/DMTf+qbt3SxXfZbYtVitHb/HJLs=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=CGMFd9p/HAoLZJ+wI9TRKav68j04MwTL3AwL6zYJ951RM/vwQrtSoBFEtw4Iw+dFl0RI6T9lbOPfcZM72fbGTauxAR94z3A0rlg4peSMfXTs5mY/POsBagZZuimSjiB4jjYrL7T3KIjKtkYZsdBnhm8DD6d1rYI2re6YhehQ9sU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=BIbZOfM0; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="BIbZOfM0" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-e572f6dee18so17071889276.0 for ; Tue, 21 Jan 2025 22:25:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527103; x=1738131903; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=OgrvkZ657QImwi6lc3WsCCSLkVlVfHzjlVLn1y8own8=; b=BIbZOfM0oZMDcjTw8dHudjz/5IdMC7Adzc9/sPMbzypg962eT86wQLKnvrFkEzzXSW GUKDm7eVSJs2RILH5L2crREwT7U5DBjBygTMH1Tna+3YYR/vqaTc627r4/ldLWmFC2Up pZIUc+MOYrvcinziNMrwgunBbA4fkRvDzVqdQ3tYMo1/6LW0wH/h5MTASePiWtHNyuX5 hNiig0ajiffFW8pKIpkZXdRZPkEvutmbZWOaKVLvwAjrwRndrhIs5VKcn6RyXZZvBEqU PZBkjXt6G2b47Wo91OTAsLvGjd7YhnZcbrqo48YNFHX7cf5L8WkBCi9mxjQ7CplEiwuh xveQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527103; x=1738131903; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=OgrvkZ657QImwi6lc3WsCCSLkVlVfHzjlVLn1y8own8=; b=SvPmiSghYySj1H7sUYiOAmnurNELRp5cryIRn8HV2PzAW8AINm0VgCaHaJsk+ZP8Sr hsdCXlZje8iGOj682ipCFxzd4S+Q+er+mmgYiHOC4G84bQePPZOzxpm7rifc11Guswf8 UQFURRTdiPfDt/yM1QW2IH8AwC8NI5re2NexYjgMopoKWnyT4ffCnpk8Tz9TCDKMn0jQ au1fUTJN4b46ASdU2N5AdCGyyFyPRbwfxUNzAURi/pE92/Rs4f6j76guyFNQ/mXKiius Q9RnXOCvWlxgP8s3y1RzTozlHrqyWh1XO3pVaqtiBpUEAuDnRgCqMu+8gFZ5kFQtTuDM jrAg== X-Forwarded-Encrypted: i=1; AJvYcCXoDDWNoJbsm41EOFoIcRm9Xww8Jvhotrf+TmjQinCv2+EkDoKRv22udi6w+m56S/t4AVw=@vger.kernel.org X-Gm-Message-State: AOJu0Yz5ZUMee8ZzU9bndVatypeqKqfCn1nzewTlKGVQ18m36qY/o16i 4LggJ9ZG+lAblWakiZlyqZ7WsfUTHGEJTbv5iYxRH/CsZMQ37rYFDFU04yoB759AqZzHUFxHH2K fdHuu7g== X-Google-Smtp-Source: AGHT+IFEOrfiAwnNwnDSaAeF9iqef1fiQ/E6IuDI5dItzM8nXl59fKPhAOg42XIax1O7ETkSWKQsfIZHvj1T X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a05:690c:5204:b0:6ef:c86b:af48 with SMTP id 00721157ae682-6f6eb649e8dmr258027b3.2.1737527102737; Tue, 21 Jan 2025 22:25:02 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:24 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-10-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 09/17] perf dso: Move read_symbol from llvm/capstone to dso From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org Move the read_symbol function to dso.h, make the return type const and add a mutable out_buf out parameter. In future changes this will allow a code pointer to be returned without necessary allocating memory. Signed-off-by: Ian Rogers --- tools/perf/util/capstone.c | 64 +++++----------------------- tools/perf/util/dso.c | 67 +++++++++++++++++++++++++++++ tools/perf/util/dso.h | 4 ++ tools/perf/util/llvm.c | 87 +++++++------------------------------- 4 files changed, 97 insertions(+), 125 deletions(-) diff --git a/tools/perf/util/capstone.c b/tools/perf/util/capstone.c index 8d65c7a55a8b..f103988184c8 100644 --- a/tools/perf/util/capstone.c +++ b/tools/perf/util/capstone.c @@ -434,66 +434,23 @@ static int find_file_offset(u64 start, u64 len, u64 pgoff, void *arg) return 0; } -static u8 * -read_symbol(const char *filename, struct map *map, struct symbol *sym, - u64 *len, bool *is_64bit) -{ - struct dso *dso = map__dso(map); - struct nscookie nsc; - u64 start = map__rip_2objdump(map, sym->start); - u64 end = map__rip_2objdump(map, sym->end); - int fd, count; - u8 *buf = NULL; - struct find_file_offset_data data = { - .ip = start, - }; - - *is_64bit = false; - - nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); - fd = open(filename, O_RDONLY); - nsinfo__mountns_exit(&nsc); - if (fd < 0) - return NULL; - - if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, - is_64bit) == 0) - goto err; - - *len = end - start; - buf = malloc(*len); - if (buf == NULL) - goto err; - - count = pread(fd, buf, *len, data.offset); - close(fd); - fd = -1; - - if ((u64)count != *len) - goto err; - - return buf; - -err: - if (fd >= 0) - close(fd); - free(buf); - return NULL; -} - int symbol__disassemble_capstone(const char *filename __maybe_unused, struct symbol *sym __maybe_unused, struct annotate_args *args __maybe_unused) { struct annotation *notes = symbol__annotation(sym); struct map *map = args->ms.map; + struct dso *dso = map__dso(map); u64 start = map__rip_2objdump(map, sym->start); - u64 len; u64 offset; int i, count, free_count; bool is_64bit = false; bool needs_cs_close = false; - u8 *buf = NULL; + /* Malloc-ed buffer containing instructions read from disk. */ + u8 *code_buf = NULL; + /* Pointer to code to be disassembled. */ + const u8 *buf; + u64 buf_len; csh handle; struct cs_insn *insn = NULL; char disasm_buf[512]; @@ -503,7 +460,8 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, if (args->options->objdump_path) return -1; - buf = read_symbol(filename, map, sym, &len, &is_64bit); + buf = dso__read_symbol(dso, filename, map, sym, + &code_buf, &buf_len, &is_64bit); if (buf == NULL) return -1; @@ -532,7 +490,7 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, needs_cs_close = true; - free_count = count = perf_cs_disasm(handle, buf, len, start, len, &insn); + free_count = count = perf_cs_disasm(handle, buf, buf_len, start, buf_len, &insn); for (i = 0, offset = 0; i < count; i++) { int printed; @@ -556,7 +514,7 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, } /* It failed in the middle: probably due to unknown instructions */ - if (offset != len) { + if (offset != buf_len) { struct list_head *list = ¬es->src->source; /* Discard all lines and fallback to objdump */ @@ -575,7 +533,7 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, if (free_count > 0) perf_cs_free(insn, free_count); } - free(buf); + free(code_buf); return count < 0 ? count : 0; err: diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 5c6e85fdae0d..0285904ed26d 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1664,3 +1664,70 @@ bool is_perf_pid_map_name(const char *dso_name) return perf_pid_map_tid(dso_name, &tid); } + +struct find_file_offset_data { + u64 ip; + u64 offset; +}; + +/* This will be called for each PHDR in an ELF binary */ +static int find_file_offset(u64 start, u64 len, u64 pgoff, void *arg) +{ + struct find_file_offset_data *data = arg; + + if (start <= data->ip && data->ip < start + len) { + data->offset = pgoff + data->ip - start; + return 1; + } + return 0; +} + +const u8 *dso__read_symbol(struct dso *dso, const char *symfs_filename, + const struct map *map, const struct symbol *sym, + u8 **out_buf, u64 *out_buf_len, bool *is_64bit) +{ + struct nscookie nsc; + u64 start = map__rip_2objdump(map, sym->start); + u64 end = map__rip_2objdump(map, sym->end); + int fd, count; + u8 *buf = NULL; + size_t len; + struct find_file_offset_data data = { + .ip = start, + }; + + *out_buf = NULL; + *out_buf_len = 0; + *is_64bit = false; + + nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); + fd = open(symfs_filename, O_RDONLY); + nsinfo__mountns_exit(&nsc); + if (fd < 0) + return NULL; + + if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, is_64bit) == 0) + goto err; + + len = end - start; + buf = malloc(len); + if (buf == NULL) + goto err; + + count = pread(fd, buf, len, data.offset); + close(fd); + fd = -1; + + if ((u64)count != len) + goto err; + + *out_buf = buf; + *out_buf_len = len; + return buf; + +err: + if (fd >= 0) + close(fd); + free(buf); + return NULL; +} diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index bb8e8f444054..734e3a3d95f0 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -828,4 +828,8 @@ u64 dso__findnew_global_type(struct dso *dso, u64 addr, u64 offset); bool perf_pid_map_tid(const char *dso_name, int *tid); bool is_perf_pid_map_name(const char *dso_name); +const u8 *dso__read_symbol(struct dso *dso, const char *symfs_filename, + const struct map *map, const struct symbol *sym, + u8 **out_buf, u64 *out_buf_len, bool *is_64bit); + #endif /* __PERF_DSO */ diff --git a/tools/perf/util/llvm.c b/tools/perf/util/llvm.c index f6a8943b7c9d..a0774373f0d6 100644 --- a/tools/perf/util/llvm.c +++ b/tools/perf/util/llvm.c @@ -296,71 +296,6 @@ void dso__free_a2l_llvm(struct dso *dso __maybe_unused) /* Nothing to free. */ } - -struct find_file_offset_data { - u64 ip; - u64 offset; -}; - -/* This will be called for each PHDR in an ELF binary */ -static int find_file_offset(u64 start, u64 len, u64 pgoff, void *arg) -{ - struct find_file_offset_data *data = arg; - - if (start <= data->ip && data->ip < start + len) { - data->offset = pgoff + data->ip - start; - return 1; - } - return 0; -} - -static u8 * -read_symbol(const char *filename, struct map *map, struct symbol *sym, - u64 *len, bool *is_64bit) -{ - struct dso *dso = map__dso(map); - struct nscookie nsc; - u64 start = map__rip_2objdump(map, sym->start); - u64 end = map__rip_2objdump(map, sym->end); - int fd, count; - u8 *buf = NULL; - struct find_file_offset_data data = { - .ip = start, - }; - - *is_64bit = false; - - nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); - fd = open(filename, O_RDONLY); - nsinfo__mountns_exit(&nsc); - if (fd < 0) - return NULL; - - if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, - is_64bit) == 0) - goto err; - - *len = end - start; - buf = malloc(*len); - if (buf == NULL) - goto err; - - count = pread(fd, buf, *len, data.offset); - close(fd); - fd = -1; - - if ((u64)count != *len) - goto err; - - return buf; - -err: - if (fd >= 0) - close(fd); - free(buf); - return NULL; -} - /* * Whenever LLVM wants to resolve an address into a symbol, it calls this * callback. We don't ever actually _return_ anything (in particular, because @@ -397,8 +332,11 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, struct map *map = args->ms.map; struct dso *dso = map__dso(map); u64 start = map__rip_2objdump(map, sym->start); - u8 *buf; - u64 len; + /* Malloc-ed buffer containing instructions read from disk. */ + u8 *code_buf = NULL; + /* Pointer to code to be disassembled. */ + const u8 *buf; + u64 buf_len; u64 pc; bool is_64bit; char triplet[64]; @@ -418,7 +356,8 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, perf_LLVMInitializeAllTargetMCs(); perf_LLVMInitializeAllDisassemblers(); - buf = read_symbol(filename, map, sym, &len, &is_64bit); + buf = dso__read_symbol(dso, filename, map, sym, + &code_buf, &buf_len, &is_64bit); if (buf == NULL) return -1; @@ -466,14 +405,18 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, annotation_line__add(&dl->al, ¬es->src->source); pc = start; - for (u64 offset = 0; offset < len; ) { + for (u64 offset = 0; offset < buf_len; ) { unsigned int ins_len; storage.branch_addr = 0; storage.pcrel_load_addr = 0; - ins_len = perf_LLVMDisasmInstruction(disasm, buf + offset, - len - offset, pc, + /* + * LLVM's API has the code be disassembled as non-const, cast + * here as we may be disassembling from mapped read-only memory. + */ + ins_len = perf_LLVMDisasmInstruction(disasm, (u8 *)(buf + offset), + buf_len - offset, pc, disasm_buf, sizeof(disasm_buf)); if (ins_len == 0) goto err; @@ -531,7 +474,7 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, err: perf_LLVMDisasmDispose(disasm); - free(buf); + free(code_buf); free(line_storage); return ret; } From patchwork Wed Jan 22 06:23:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946898 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 660D31B0F35 for ; Wed, 22 Jan 2025 06:25:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527113; cv=none; b=U8+OYDIsuds3lFluFKSNXadg2RQYd9K4v6WJ1fXWM65iaBDO1/LTv0Om4zE6uUP8jcAOnh9IPHO9KdlVC5JGykYa+MiT7Zm44q/bNONfe5DmyX3XSSch92/isEe23zPQ1PmhG+74BJyBgNgP+6heNMW3ae6rIj6IavhIRhmlTeg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527113; c=relaxed/simple; bh=63nBtpeMpe7xv4aEwrBhb9npTX5s1rkxRdlgAXmvoMc=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=tCKS56CKEZLkRW5i2UFFvtTamaWYtEvD0gY7Y/R3PmI+uSA6dTuxqQC+GtxN93s9wqj835UWk4XVdpRIoXLc0qfuYqZ9FR9mk+WK+vFogauoaiclX5T5vRAY139TlxS35eb6trRQ86WVymyeWOgxI6ubQCjpiNNvXr7UPOsLt84= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=llUaRN7g; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="llUaRN7g" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e579836ee17so12674262276.2 for ; Tue, 21 Jan 2025 22:25:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527110; x=1738131910; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=wLotHYn7qhYJCMkThRcrq9/AzDWfjF/CYgpDO7eIVEI=; b=llUaRN7gBolxFomTia5TxhwOGEKEtBtoIDt5c8ccPPDWHyYb9+lZHyiiEqvzLXlHxy AOPhX1+EgnnIc/vqVCymXRogQ2Y7Ut2wAZKdaxxAJe2CshECvTevjNn5k1It8G9KIugf QKfpKS3G6Uj3vZ0woIAMyFya283lrvwVIYTZ6LnyPVFU+SEDeFNRc0bZZcioGncMdLyp JKLOCEsBW/ReqXITUYcPIOHB/p/OqdmJHlrRuuL8AcPYKsrs4cfqNU/y01T8jfzbJRqc NWV47idbRTLz+F4YmdBkZxwaq4AOwH5wKFl5EmQxyS0f20wxLm+KzuHLn/dJBgjXZcoo Bz6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527110; x=1738131910; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=wLotHYn7qhYJCMkThRcrq9/AzDWfjF/CYgpDO7eIVEI=; b=j0zMSchET/f5vSevKPXj4pdxBN69p6hv1YOViXunOPQ4kDYZZuRnUSEgY6hZ7mxGBh zECXxEZCT9R3CJmRE62LoWGihAy3sJM/GDhkwDloGYVjjHCoN1sb+5YD8srVTD3yWSBS ZnLfICTwW+pQM3ZBcKgJ6HY57CwSDR6GS82xVRSg9OmoCn/W4rmVY5nP0xdfaIsV2b0D FE29jUOgFagw7cg/0HlV2GPmjj76VAiAG/MiZtcTxftNh/OCEAgX6iyM/vLzTp3Sq9ra gYAm8BiP7XvYd61aVq4N5MUHVkMVGKH8t9hnfieCJBq3fcLRhri81oIP5bSy0ufiXvHY y8zg== X-Forwarded-Encrypted: i=1; AJvYcCWWDYvQgZJ4FtQYzF8cvoI1nm78WG02eTsScn2DjCdp6AdZxcZzXIBtGk7KGexuZnyZtLA=@vger.kernel.org X-Gm-Message-State: AOJu0YwuWWb3v3mQC6HWtc8rOqdorADmJxv/sqgERvY6v1QlJ5xjZKST IjZx2i7XmJJtVZ0uIQ4EFf0Xf6pO0gikhytxX7ANge0PMsXg7R9OZI8sA1LPKhbwsOv9+sygJLj 6Stj7Jw== X-Google-Smtp-Source: AGHT+IEqK8ZkONJZBAyEEerDbvvaV8PkDpFyO4x4ko4onzv5SasjqsaaN+Db8+thwFx1lPNpBvA0psxpee3q X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a5b:341:0:b0:e48:9cab:d051 with SMTP id 3f1490d57ef6-e57b13e4fcamr41710276.9.1737527110404; Tue, 21 Jan 2025 22:25:10 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:25 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-11-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 10/17] perf dso: Support BPF programs in dso__read_symbol From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org Set the buffer to the code in the BPF linear info. This enables BPF JIT code disassembly by LLVM and capstone. Move the disassmble_bpf calls to disassemble_objdump so that they are only called after falling back to the objdump option. Signed-off-by: Ian Rogers --- tools/perf/util/disasm.c | 12 +++--- tools/perf/util/dso.c | 85 +++++++++++++++++++++++++--------------- 2 files changed, 60 insertions(+), 37 deletions(-) diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index a9cc588a3006..99b9c21e02b0 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -1500,6 +1500,12 @@ static int symbol__disassemble_objdump(const char *filename, struct symbol *sym, struct child_process objdump_process; int err; + if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) + return symbol__disassemble_bpf(sym, args); + + if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) + return symbol__disassemble_bpf_image(sym, args); + err = asprintf(&command, "%s %s%s --start-address=0x%016" PRIx64 " --stop-address=0x%016" PRIx64 @@ -1681,11 +1687,7 @@ int symbol__disassemble(struct symbol *sym, struct annotate_args *args) pr_debug("annotating [%p] %30s : [%p] %30s\n", dso, dso__long_name(dso), sym, sym->name); - if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) { - return symbol__disassemble_bpf(sym, args); - } else if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) { - return symbol__disassemble_bpf_image(sym, args); - } else if (dso__binary_type(dso) == DSO_BINARY_TYPE__NOT_FOUND) { + if (dso__binary_type(dso) == DSO_BINARY_TYPE__NOT_FOUND) { return SYMBOL_ANNOTATE_ERRNO__COULDNT_DETERMINE_FILE_TYPE; } else if (dso__is_kcore(dso)) { kce.addr = map__rip_2objdump(map, sym->start); diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 0285904ed26d..a90799bed230 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1686,48 +1686,69 @@ const u8 *dso__read_symbol(struct dso *dso, const char *symfs_filename, const struct map *map, const struct symbol *sym, u8 **out_buf, u64 *out_buf_len, bool *is_64bit) { - struct nscookie nsc; u64 start = map__rip_2objdump(map, sym->start); u64 end = map__rip_2objdump(map, sym->end); - int fd, count; - u8 *buf = NULL; - size_t len; - struct find_file_offset_data data = { - .ip = start, - }; + const u8 *buf; + size_t len = end - start; *out_buf = NULL; *out_buf_len = 0; *is_64bit = false; - nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); - fd = open(symfs_filename, O_RDONLY); - nsinfo__mountns_exit(&nsc); - if (fd < 0) + if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) { + pr_debug("No BPF image disassembly support\n"); return NULL; + } else if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) { +#ifdef HAVE_LIBBPF_SUPPORT + struct bpf_prog_info_node *info_node; + struct perf_bpil *info_linear; + + *is_64bit = sizeof(void *) == sizeof(u64); + info_node = perf_env__find_bpf_prog_info(dso__bpf_prog(dso)->env, + dso__bpf_prog(dso)->id); + if (!info_node) { + errno = SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF; + return NULL; + } + info_linear = info_node->info_linear; + buf = (const u8 *)(uintptr_t)(info_linear->info.jited_prog_insns); + assert(len <= info_linear->info.jited_prog_len); +#else + pr_debug("No BPF program disassembly support\n"); + return NULL; +#endif + } else { + struct nscookie nsc; + int fd; + ssize_t count; + struct find_file_offset_data data = { + .ip = start, + }; + u8 *code_buf = NULL; - if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, is_64bit) == 0) - goto err; - - len = end - start; - buf = malloc(len); - if (buf == NULL) - goto err; - - count = pread(fd, buf, len, data.offset); - close(fd); - fd = -1; - - if ((u64)count != len) - goto err; + nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); + fd = open(symfs_filename, O_RDONLY); + nsinfo__mountns_exit(&nsc); + if (fd < 0) + return NULL; - *out_buf = buf; + if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, is_64bit) == 0) { + close(fd); + return NULL; + } + buf = code_buf = malloc(len); + if (buf == NULL) { + close(fd); + return NULL; + } + count = pread(fd, code_buf, len, data.offset); + close(fd); + if ((u64)count != len) { + free(code_buf); + return NULL; + } + *out_buf = code_buf; + } *out_buf_len = len; return buf; - -err: - if (fd >= 0) - close(fd); - free(buf); - return NULL; } From patchwork Wed Jan 22 06:23:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946899 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2AB141C5D51 for ; Wed, 22 Jan 2025 06:25:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527120; cv=none; b=uWqtRWO2Gidd/Eg0HvGC+E/xE0CYWljizdvv2uUXFBXOkvvQ20mDLU7IWSBXEk0pNUfWLLcCV7TrvN3LtngUJ0GkBvye3gsgA6gIJoY8MOL583Qu49rCeO05tYNb/gw01EBzK/zlO3EEihXbCE0RGUkw32hydRqxUuyiH64D4dM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527120; c=relaxed/simple; bh=fslZfMEltprSZcTKlHEcI81MzAYEcQiKGjjQrOFeeQs=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=VKY/V++0WNLl9R04ugFQTI/aC9/u1u7/r2aEA1iiSotBhBjb/Qd7Wxc+uIIOw3kLAZC9c3+iFarwHhSQNbj1C/f3Jctq0DQxZdJ8rxccUaGwMHyd47k7DrCHA/vXNFjZTF1cEuDFXKGzO6tVAFolk0IJH8Jn4DU8QSnztl5NeLE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=4ijyAVgO; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="4ijyAVgO" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-e3fea893dc5so1439181276.1 for ; Tue, 21 Jan 2025 22:25:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527118; x=1738131918; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=ifAh4z9tkFouiScWwWQSL99thftn0z74dbeCX/fEfD8=; b=4ijyAVgOgmNWOI0u5LeNsDEhFDkMNtAzjr00Xc5nYgmBo/id2uy5pVM31oDTG03O6U 0HYTfJVlIp21M4qY1Ala6X44oORXfL8r/uMFgFxHSJU7mPsQKONeTQ3jjQaJnlEVAkM6 siWiBBpHmRaML1O5tvxbkEfUce+IDia6LtoZNEy90a1ekylk96CleKRzn9MRakvpu81y bhkTJKjuEfF56lGjesvnnrNw4L8GG+g4LCc1p4k6u7tPtPuIMwW66r29xQWQRshHw5Gu v21TcHET73uPCNvT7nvNuyEeVqQh5TqlgefHNSplceN9q7OWimVhq1LVsfbjMT/8GMw2 Ekwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527118; x=1738131918; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ifAh4z9tkFouiScWwWQSL99thftn0z74dbeCX/fEfD8=; b=IYadK9Dk3UHqfnW7syUY0ZaT3w34Ok90d7PD5LgtKPsj8MydJCxGdGJw00TpgSgoTw /1ldyJIqC4OkqKxkaO5BfneehW+PLOoiCVXCcBixHyM6UF9nX8vPrTlITii8MfgnWA8l 9JtXodW3GjZgZXF5veIf/SXCp11UYJhatzJ/9C2QIDRLJZbvHttOne2TNfeeqRsVS9lO YiwlH1L5bpUDvSIR5K1oJAVnMhq5y1t8KEXAtW9S/um0IIYv4CyHPAeyxQq2Nye2mZ3d jFbM+fpigaIw1GSUzJXmFWIy5S/U4YaoV30QeOO85oD6ekLbiV1+ZYyalEAVngrDsYLY 8efw== X-Forwarded-Encrypted: i=1; AJvYcCX3No5UY8wbO8S/9Z/wtixbDvA4Vh4pqYoW8NWEmO8H+dHMTREaYQ508yjO4J7BO42P9UE=@vger.kernel.org X-Gm-Message-State: AOJu0Yw9EdQ+iSVca1Hplle88Pdjs41Utl5Pxh2hRpR1StwovDXNDm7W cfOYP6NAhcFtoPaPTbU+G9NeI6YL9zFXk283KZfRYW1HGo7Fj3nVj0v/8cv26zOpzC+Uk1BEFHr ld6OAEQ== X-Google-Smtp-Source: AGHT+IHYRcdPxQUE7RFn1o5mEQhJrq8PAszt9Jv65BlBcEciA0rf2Yi2TG/Nx4Vi1nxNKr4a7TSmsVRBAdUi X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a05:690c:d0b:b0:6ee:a2b0:a803 with SMTP id 00721157ae682-6f6c98438a8mr1261387b3.1.1737527118189; Tue, 21 Jan 2025 22:25:18 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:26 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-12-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 11/17] perf llvm: Disassemble cleanup From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org Move the 3 LLVM initialization routines to be called in a single init_llvm function that has its own bool to avoid repeated initialization. Reduce the scope of triplet and avoid copying strings for x86. Signed-off-by: Ian Rogers --- tools/perf/util/llvm.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/tools/perf/util/llvm.c b/tools/perf/util/llvm.c index a0774373f0d6..a28f130c8951 100644 --- a/tools/perf/util/llvm.c +++ b/tools/perf/util/llvm.c @@ -244,6 +244,17 @@ static void perf_LLVMDisasmDispose(LLVMDisasmContextRef context) #endif } +static void init_llvm(void) +{ + static bool init; + + if (!init) { + perf_LLVMInitializeAllTargetInfos(); + perf_LLVMInitializeAllTargetMCs(); + perf_LLVMInitializeAllDisassemblers(); + init = true; + } +} static void free_llvm_inline_frames(struct llvm_a2l_frame *inline_frames, int num_frames) @@ -339,7 +350,6 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, u64 buf_len; u64 pc; bool is_64bit; - char triplet[64]; char disasm_buf[2048]; size_t disasm_len; struct disasm_line *dl; @@ -352,27 +362,25 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, if (args->options->objdump_path) return -1; - perf_LLVMInitializeAllTargetInfos(); - perf_LLVMInitializeAllTargetMCs(); - perf_LLVMInitializeAllDisassemblers(); - buf = dso__read_symbol(dso, filename, map, sym, &code_buf, &buf_len, &is_64bit); if (buf == NULL) return -1; + init_llvm(); if (arch__is(args->arch, "x86")) { - if (is_64bit) - scnprintf(triplet, sizeof(triplet), "x86_64-pc-linux"); - else - scnprintf(triplet, sizeof(triplet), "i686-pc-linux"); + const char *triplet = is_64bit ? "x86_64-pc-linux" : "i686-pc-linux"; + + disasm = perf_LLVMCreateDisasm(triplet, &storage, /*tag_type=*/0, + /*get_op_info=*/NULL, symbol_lookup_callback); } else { + char triplet[64]; + scnprintf(triplet, sizeof(triplet), "%s-linux-gnu", args->arch->name); + disasm = perf_LLVMCreateDisasm(triplet, &storage, /*tag_type=*/0, + /*get_op_info=*/NULL, symbol_lookup_callback); } - - disasm = perf_LLVMCreateDisasm(triplet, &storage, 0, NULL, - symbol_lookup_callback); if (disasm == NULL) goto err; From patchwork Wed Jan 22 06:23:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946900 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A6C791BBBD0 for ; Wed, 22 Jan 2025 06:25:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527130; cv=none; b=jbztvYW03nM9vSbz/uFfKoUg9b5b3rgjS5erwjSTrf+B0EJiYNCnUF9t1fBQZnYwDXeY2Og24ZBk/Dyn+/iilGLlbjCZVK5X4NoY1PlD3W9isyjMftqRRyypSggzye8jZ0qGy9QK6vAidUNKMcyYtF+XV0IM0IUQ5LUv3202E7w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527130; c=relaxed/simple; bh=Lzob+NuJy06upC4gEoA3ss329xpU9HN0aFks4gS31oA=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=nsa0ej8MmBhFkgkHD0oUDSy0ErwL+o/WJ2OawVDnb2mrIvivuifuP1/IhQ58hlVWcO+GZTO8p91zaRAzyyaasZ2fY+ME0gUimniCOT0Io4DFaZj2e/KxbO7TxPqp81UV0WKdjQytrgSmCyPiNFciEqMSXNBf2St7cSH5OghMrjU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=ANiKYH4z; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ANiKYH4z" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e3a1bc0c875so14135569276.2 for ; Tue, 21 Jan 2025 22:25:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527128; x=1738131928; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=/etQtMYVd4NbKTRYWQL1OC8HOEVmkVBi2gOIQvu8y4k=; b=ANiKYH4ztvhhrEYCm6bUvWLFDnu25QEwpZjA1wJhoeHTw7GNA6kpy4S1P+WXT2dCBh ENtefrel0vuqlbk+uquRzDWuqnn00JIiaAE2LZNTPPW/0O8zRCLUh6O9mcGg0t/jXNx8 eTyuSQcSMXfqpIOwk9KI9VO1LtQRiZvBaW1iemEX3PtyWWl1BuxbEcMZ/+gpmPwUQTUG BEP3TbvnFoT+0W8TmOvOh2UVpRjyzu5o4jQ3jKo1r8GxA75xBx47Fs4+0ohfCvB/8WvT SphYD4L3196ffGlTtZ6R/kXPpKPWdcLpTM+xR0VITgQ8ez2nUAdH9+FbKPbnMUmo9+5J ExTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527128; x=1738131928; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=/etQtMYVd4NbKTRYWQL1OC8HOEVmkVBi2gOIQvu8y4k=; b=FHSWmxtgjOIE+Oy+x18tRhkjBzl0ecy1r+9Fg29PSqjk96H8QPk4TUnaF4xSE3HLVw F9ndEhfdMuJw42+t4ztXeqDzeZlqJHz0fun/6zTR6mOjJlFm+ZDTaJmVcrAaMKtnA5Zr 6q9ayP7lj4PRS1b4KmF6CxOmU3qSPCOXMCXitvRmpb0pzP73IbPq4WKSPOE8ZW2f3jyL gzb9RRBqtAXHgVKady/Myy36olBsRCKJJaix3Xq/mL+jEwW2ljK/liu/2SSo6ICAy4Au 6IA7kTOSgGiyGeGAvdyjE3tW6JA2CU8k6G9he0cSnoyVWLtXdGXXk3Hj7CioM/WrSZAN w+Kw== X-Forwarded-Encrypted: i=1; AJvYcCWUKtqjMkWBnW131ha2S9/tV48Sq2r3cozDI12YtQ/S/rH+7ewsqjrH5AUeu4DTmaKde3Q=@vger.kernel.org X-Gm-Message-State: AOJu0Yw2os8ZDgU8Sfec4wJV7yIoEiF1ilv91IUiXSS0wePTb3eHdwzo 1BnUQk+WaIhQp8/skY5AHO7AYm57mkArp8HTuA0sI/1rfwHFVZ5vGr1SobN64N4dVLJpt640JE4 dR5LQzA== X-Google-Smtp-Source: AGHT+IH6D33Da/yJv7XvymX6q4uMCft9Y3ZBUbwM3+o4/Q+cURxwz6r2bb7aP9Xyo1liFmfBDPf1zpaiIvA1 X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a25:33c4:0:b0:e58:228:d611 with SMTP id 3f1490d57ef6-e580228d824mr11847276.8.1737527127476; Tue, 21 Jan 2025 22:25:27 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:27 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-13-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 12/17] perf dso: Clean up read_symbol error handling From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org Ensure errno is set and return to caller for error handling. Unusually for perf the value isn't negated as expected by symbol__strerror_disassemble. Signed-off-by: Ian Rogers --- tools/perf/util/capstone.c | 3 ++- tools/perf/util/dso.c | 14 ++++++++++++-- tools/perf/util/llvm.c | 3 ++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/capstone.c b/tools/perf/util/capstone.c index f103988184c8..032548828925 100644 --- a/tools/perf/util/capstone.c +++ b/tools/perf/util/capstone.c @@ -12,6 +12,7 @@ #include "symbol.h" #include "thread.h" #include +#include #include #include #include @@ -463,7 +464,7 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, buf = dso__read_symbol(dso, filename, map, sym, &code_buf, &buf_len, &is_64bit); if (buf == NULL) - return -1; + return errno; /* add the function address and name */ scnprintf(disasm_buf, sizeof(disasm_buf), "%#"PRIx64" <%s>:", diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index a90799bed230..247e59605f26 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -1697,6 +1697,7 @@ const u8 *dso__read_symbol(struct dso *dso, const char *symfs_filename, if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) { pr_debug("No BPF image disassembly support\n"); + errno = EOPNOTSUPP; return NULL; } else if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) { #ifdef HAVE_LIBBPF_SUPPORT @@ -1715,6 +1716,7 @@ const u8 *dso__read_symbol(struct dso *dso, const char *symfs_filename, assert(len <= info_linear->info.jited_prog_len); #else pr_debug("No BPF program disassembly support\n"); + errno = EOPNOTSUPP; return NULL; #endif } else { @@ -1725,26 +1727,34 @@ const u8 *dso__read_symbol(struct dso *dso, const char *symfs_filename, .ip = start, }; u8 *code_buf = NULL; + int saved_errno; nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); fd = open(symfs_filename, O_RDONLY); + saved_errno = errno; nsinfo__mountns_exit(&nsc); - if (fd < 0) + if (fd < 0) { + errno = saved_errno; return NULL; + } - if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, is_64bit) == 0) { + if (file__read_maps(fd, /*exe=*/true, find_file_offset, &data, is_64bit) <= 0) { close(fd); + errno = ENOENT; return NULL; } buf = code_buf = malloc(len); if (buf == NULL) { close(fd); + errno = ENOMEM; return NULL; } count = pread(fd, code_buf, len, data.offset); + saved_errno = errno; close(fd); if ((u64)count != len) { free(code_buf); + errno = saved_errno; return NULL; } *out_buf = code_buf; diff --git a/tools/perf/util/llvm.c b/tools/perf/util/llvm.c index a28f130c8951..1607364ee736 100644 --- a/tools/perf/util/llvm.c +++ b/tools/perf/util/llvm.c @@ -9,6 +9,7 @@ #include "srcline.h" #include "symbol.h" #include +#include #include #include #include @@ -365,7 +366,7 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, buf = dso__read_symbol(dso, filename, map, sym, &code_buf, &buf_len, &is_64bit); if (buf == NULL) - return -1; + return errno; init_llvm(); if (arch__is(args->arch, "x86")) { From patchwork Wed Jan 22 06:23:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946901 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B7D261B6CE0 for ; Wed, 22 Jan 2025 06:25:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527141; cv=none; b=GdvO9aSmXpq8LxZHJATCwC3WPlhP/P/U65Hfy9YA9xcEj7A8WA318FeCi5Af1OG+KvvrcT41zn6w9QahFanPviqta+6ByZKKRuNRbdvjm+D4SN7VU4qr86jHj6S20kegQmBSIkdQQ8BbhgIKGIVva9/tlQ3Hz2NPb1l3fyl1o1A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527141; c=relaxed/simple; bh=f6o1LS1X+qjlha6mpPMevGe1pIgCCqYagikh9Eepk1M=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=kRF5PvHoTXtJptefr2fuyACIyOQREEm9+VQYM59axB2Kp5ZIKyw2GuDPdFxVNY5fU/QoBNMixTY8cclq/jEU9aBkVVZh1T35hq1FzZtVOI6oNZXIrQHVTkUyZIFLlVpLLY5HIXF0DA0IMBf2mvb7IYXYzjKJftJZjsSfTzsV9x4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=0147NysC; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="0147NysC" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-e3a109984a5so14096698276.3 for ; Tue, 21 Jan 2025 22:25:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527137; x=1738131937; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=JrQIP45xTxAkLJpborhugYXvzh4pwkFBxhO2wlxPBok=; b=0147NysCLMS2AfkBtzqgBpK9g4Um+0FGh3IOvfTgqzX6cTejw91MueJ0pBuv6HRCMF M8c9gLbIjFE5di2jqZBhC2rrxulJPRtY8ZQM4KC2WI2b6/yehq0Sv5GjksQlq3OFSNmM KBSe7C9jngb8+LmmKcu65GSHfF76WzBB1CZEQf61ZF5fB6DZpXUAL6MWN01Cb3lY062c 8LwrMtEK7DPjwaoTkaCOX53EH0N1WpUyZEXJeZezAsscMwBGcrkn52XPRNQ91knwvkWG iAkcn+090tqHoLG6F5Hfz/8s5pcrKBBIImYJHod16kjbJcqFbyvtFJIQu0dMRxs7RPQ3 lpXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527137; x=1738131937; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=JrQIP45xTxAkLJpborhugYXvzh4pwkFBxhO2wlxPBok=; b=qkPaXLeQqp+NF9DGg30O/fPU59v7D1kY0/9Il6igv+GyVKnoyYhXNJ0YbZVTEjg1Uq pB++PSs6ek5ZybOVcFFwAL+YeC4oQV3R8rZn7m5irYw7RfZFSyjKCOVfXz1otsXd22oD XUuSNpa9kpUCM+SipN1HOPyi6Ayuk20MCtbK6e4BYBe1n3W+mGU0J1YZduPzx4vaY0wr ZqIzRkulZRMtZ8GJJ+f/shkyvBarys3Tra8vRh5PM7rmA20icVjfFZy6yDfiWQnhpl+h 06nVs9USZPks+CDQtfSGKsdCWNqCx9yHD1RhJjV7ClGXLDP3ZXkOX61w8Am9d8itdDAW oMZQ== X-Forwarded-Encrypted: i=1; AJvYcCUMVktQOxwHwRf55mXQ+nDwtIzOvyhVqY7vZcxNzqQo9p/tAgLRCdzTUnErLJDaJi8rRF8=@vger.kernel.org X-Gm-Message-State: AOJu0Ywyl0emI5WuIUGv6MoICoV8GSfwo7msAC4I6TQpzdvrxoIo7m1A uuoUxO/Ux7BsAhba7ug6IpJc6usBU0UvDyIFM0F4RNLc9jH/dl7IovdW0Hjcg/MWbtVaGgNiQ/O r3D7v4Q== X-Google-Smtp-Source: AGHT+IHE6fD0j2MA++/EebCAhD+dsb1NpI24+5HSBEEzmwNyg6Q+YoIf2VrkJevOwadnBxYFR1qi73JU4kYP X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a25:acda:0:b0:e57:e61b:8b5d with SMTP id 3f1490d57ef6-e57e61b8ca3mr24407276.5.1737527136936; Tue, 21 Jan 2025 22:25:36 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:28 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-14-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 13/17] perf build: Remove libbfd support From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org libbfd is license incompatible with perf and building requires the BUILD_NONDISTRO=1 build flag. Remove the code to simplify the code base. Signed-off-by: Ian Rogers --- tools/perf/Documentation/perf-check.txt | 1 - tools/perf/Makefile.config | 38 +--- tools/perf/builtin-check.c | 1 - tools/perf/tests/Build | 1 - tools/perf/tests/builtin-test.c | 1 - tools/perf/tests/pe-file-parsing.c | 101 ---------- tools/perf/tests/tests.h | 1 - tools/perf/util/demangle-cxx.cpp | 13 +- tools/perf/util/disasm_bpf.c | 166 ---------------- tools/perf/util/srcline.c | 243 +----------------------- tools/perf/util/symbol-elf.c | 86 +-------- tools/perf/util/symbol.c | 135 ------------- tools/perf/util/symbol.h | 4 - 13 files changed, 7 insertions(+), 784 deletions(-) delete mode 100644 tools/perf/tests/pe-file-parsing.c diff --git a/tools/perf/Documentation/perf-check.txt b/tools/perf/Documentation/perf-check.txt index a764a4629220..f6ec81ad87b2 100644 --- a/tools/perf/Documentation/perf-check.txt +++ b/tools/perf/Documentation/perf-check.txt @@ -51,7 +51,6 @@ feature:: dwarf_getlocations / HAVE_LIBDW_SUPPORT dwarf-unwind / HAVE_DWARF_UNWIND_SUPPORT auxtrace / HAVE_AUXTRACE_SUPPORT - libbfd / HAVE_LIBBFD_SUPPORT libcapstone / HAVE_LIBCAPSTONE_SUPPORT libcrypto / HAVE_LIBCRYPTO_SUPPORT libdw-dwarf-unwind / HAVE_LIBDW_SUPPORT diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 5c2814acc5d5..900be0349de9 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -911,42 +911,6 @@ ifneq ($(NO_JEVENTS),1) endif endif -ifdef BUILD_NONDISTRO - ifeq ($(feature-libbfd), 1) - EXTLIBS += -lbfd -lopcodes - else - # we are on a system that requires -liberty and (maybe) -lz - # to link against -lbfd; test each case individually here - - # call all detections now so we get correct - # status in VF output - $(call feature_check,libbfd-liberty) - $(call feature_check,libbfd-liberty-z) - - ifeq ($(feature-libbfd-liberty), 1) - EXTLIBS += -lbfd -lopcodes -liberty - FEATURE_CHECK_LDFLAGS-disassembler-four-args += -liberty -ldl - FEATURE_CHECK_LDFLAGS-disassembler-init-styled += -liberty -ldl - else - ifeq ($(feature-libbfd-liberty-z), 1) - EXTLIBS += -lbfd -lopcodes -liberty -lz - FEATURE_CHECK_LDFLAGS-disassembler-four-args += -liberty -lz -ldl - FEATURE_CHECK_LDFLAGS-disassembler-init-styled += -liberty -lz -ldl - endif - endif - $(call feature_check,disassembler-four-args) - $(call feature_check,disassembler-init-styled) - endif - - CFLAGS += -DHAVE_LIBBFD_SUPPORT - CXXFLAGS += -DHAVE_LIBBFD_SUPPORT - ifeq ($(feature-libbfd-buildid), 1) - CFLAGS += -DHAVE_LIBBFD_BUILDID_SUPPORT - else - $(warning Old version of libbfd/binutils things like PE executable profiling will not be available) - endif -endif - ifndef NO_LIBLLVM $(call feature_check,llvm-perf) ifeq ($(feature-llvm-perf), 1) @@ -1334,6 +1298,6 @@ endif # re-generate FEATURE-DUMP as we may have called feature_check, found out # extra libraries to add to LDFLAGS of some other test and then redo those -# tests, see the block about libbfd, disassembler-four-args, for instance. +# tests, see the block about disassembler-four-args, for instance. $(shell rm -f $(FEATURE_DUMP_FILENAME)) $(foreach feat,$(FEATURE_TESTS),$(shell echo "$(call feature_assign,$(feat))" >> $(FEATURE_DUMP_FILENAME))) diff --git a/tools/perf/builtin-check.c b/tools/perf/builtin-check.c index 61a11a9b4e75..046956ebf816 100644 --- a/tools/perf/builtin-check.c +++ b/tools/perf/builtin-check.c @@ -31,7 +31,6 @@ struct feature_status supported_features[] = { FEATURE_STATUS("dwarf_getlocations", HAVE_LIBDW_SUPPORT), FEATURE_STATUS("dwarf-unwind", HAVE_DWARF_UNWIND_SUPPORT), FEATURE_STATUS("auxtrace", HAVE_AUXTRACE_SUPPORT), - FEATURE_STATUS("libbfd", HAVE_LIBBFD_SUPPORT), FEATURE_STATUS("libcapstone", HAVE_LIBCAPSTONE_SUPPORT), FEATURE_STATUS("libcrypto", HAVE_LIBCRYPTO_SUPPORT), FEATURE_STATUS("libdw-dwarf-unwind", HAVE_LIBDW_SUPPORT), diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 4bf8d3f5eae7..165ba84dc93f 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -58,7 +58,6 @@ perf-test-y += demangle-java-test.o perf-test-y += demangle-ocaml-test.o perf-test-y += pfm.o perf-test-y += parse-metric.o -perf-test-y += pe-file-parsing.o perf-test-y += expand-cgroup.o perf-test-y += perf-time-to-tsc.o perf-test-y += dlfilter-test.o diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 14d30a5053be..e77bf446e821 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -127,7 +127,6 @@ static struct test_suite *generic_tests[] = { &suite__demangle_java, &suite__demangle_ocaml, &suite__parse_metric, - &suite__pe_file_parsing, &suite__expand_cgroup_events, &suite__perf_time_to_tsc, &suite__dlfilter, diff --git a/tools/perf/tests/pe-file-parsing.c b/tools/perf/tests/pe-file-parsing.c deleted file mode 100644 index fff58b220c07..000000000000 --- a/tools/perf/tests/pe-file-parsing.c +++ /dev/null @@ -1,101 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "debug.h" -#include "util/build-id.h" -#include "util/symbol.h" -#include "util/dso.h" - -#include "tests.h" - -#ifdef HAVE_LIBBFD_SUPPORT - -static int run_dir(const char *d) -{ - char filename[PATH_MAX]; - char debugfile[PATH_MAX]; - struct build_id bid; - char debuglink[PATH_MAX]; - char expect_build_id[] = { - 0x5a, 0x0f, 0xd8, 0x82, 0xb5, 0x30, 0x84, 0x22, - 0x4b, 0xa4, 0x7b, 0x62, 0x4c, 0x55, 0xa4, 0x69, - }; - char expect_debuglink[PATH_MAX] = "pe-file.exe.debug"; - struct dso *dso; - struct symbol *sym; - int ret; - size_t idx; - - scnprintf(filename, PATH_MAX, "%s/pe-file.exe", d); - ret = filename__read_build_id(filename, &bid); - TEST_ASSERT_VAL("Failed to read build_id", - ret == sizeof(expect_build_id)); - TEST_ASSERT_VAL("Wrong build_id", !memcmp(bid.data, expect_build_id, - sizeof(expect_build_id))); - - ret = filename__read_debuglink(filename, debuglink, PATH_MAX); - TEST_ASSERT_VAL("Failed to read debuglink", ret == 0); - TEST_ASSERT_VAL("Wrong debuglink", - !strcmp(debuglink, expect_debuglink)); - - scnprintf(debugfile, PATH_MAX, "%s/%s", d, debuglink); - ret = filename__read_build_id(debugfile, &bid); - TEST_ASSERT_VAL("Failed to read debug file build_id", - ret == sizeof(expect_build_id)); - TEST_ASSERT_VAL("Wrong build_id", !memcmp(bid.data, expect_build_id, - sizeof(expect_build_id))); - - dso = dso__new(filename); - TEST_ASSERT_VAL("Failed to get dso", dso); - - ret = dso__load_bfd_symbols(dso, debugfile); - TEST_ASSERT_VAL("Failed to load symbols", ret == 0); - - dso__sort_by_name(dso); - sym = dso__find_symbol_by_name(dso, "main", &idx); - TEST_ASSERT_VAL("Failed to find main", sym); - dso__delete(dso); - - return TEST_OK; -} - -static int test__pe_file_parsing(struct test_suite *test __maybe_unused, - int subtest __maybe_unused) -{ - struct stat st; - char path_dir[PATH_MAX]; - - /* First try development tree tests. */ - if (!lstat("./tests", &st)) - return run_dir("./tests"); - - /* Then installed path. */ - snprintf(path_dir, PATH_MAX, "%s/tests", get_argv_exec_path()); - - if (!lstat(path_dir, &st)) - return run_dir(path_dir); - - return TEST_SKIP; -} - -#else - -static int test__pe_file_parsing(struct test_suite *test __maybe_unused, - int subtest __maybe_unused) -{ - return TEST_SKIP; -} - -#endif - -DEFINE_SUITE("PE file support", pe_file_parsing); diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 8aea344536b8..751c8489059a 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -159,7 +159,6 @@ DECLARE_SUITE(demangle_java); DECLARE_SUITE(demangle_ocaml); DECLARE_SUITE(pfm); DECLARE_SUITE(parse_metric); -DECLARE_SUITE(pe_file_parsing); DECLARE_SUITE(expand_cgroup_events); DECLARE_SUITE(perf_time_to_tsc); DECLARE_SUITE(dlfilter); diff --git a/tools/perf/util/demangle-cxx.cpp b/tools/perf/util/demangle-cxx.cpp index 85b706641837..bd657eb37efc 100644 --- a/tools/perf/util/demangle-cxx.cpp +++ b/tools/perf/util/demangle-cxx.cpp @@ -4,16 +4,11 @@ #include #include -#ifdef HAVE_LIBBFD_SUPPORT -#define PACKAGE 'perf' -#include -#endif - #ifdef HAVE_CXA_DEMANGLE_SUPPORT #include #endif -#if defined(HAVE_LIBBFD_SUPPORT) || defined(HAVE_CPLUS_DEMANGLE_SUPPORT) +#if defined(HAVE_CPLUS_DEMANGLE_SUPPORT) #ifndef DMGL_PARAMS #define DMGL_PARAMS (1 << 0) /* Include function args */ #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ @@ -29,11 +24,7 @@ extern "C" char *cxx_demangle_sym(const char *str, bool params __maybe_unused, bool modifiers __maybe_unused) { -#ifdef HAVE_LIBBFD_SUPPORT - int flags = (params ? DMGL_PARAMS : 0) | (modifiers ? DMGL_ANSI : 0); - - return bfd_demangle(NULL, str, flags); -#elif defined(HAVE_CPLUS_DEMANGLE_SUPPORT) +#if defined(HAVE_CPLUS_DEMANGLE_SUPPORT) int flags = (params ? DMGL_PARAMS : 0) | (modifiers ? DMGL_ANSI : 0); return cplus_demangle(str, flags); diff --git a/tools/perf/util/disasm_bpf.c b/tools/perf/util/disasm_bpf.c index 1fee71c79b62..a891a0b909a7 100644 --- a/tools/perf/util/disasm_bpf.c +++ b/tools/perf/util/disasm_bpf.c @@ -6,176 +6,10 @@ #include #include -#if defined(HAVE_LIBBFD_SUPPORT) && defined(HAVE_LIBBPF_SUPPORT) -#define PACKAGE "perf" -#include -#include -#include -#include -#include -#include -#include -#include - -#include "util/bpf-event.h" -#include "util/bpf-utils.h" -#include "util/debug.h" -#include "util/dso.h" -#include "util/map.h" -#include "util/env.h" -#include "util/util.h" - -int symbol__disassemble_bpf(struct symbol *sym, struct annotate_args *args) -{ - struct annotation *notes = symbol__annotation(sym); - struct bpf_prog_linfo *prog_linfo = NULL; - struct bpf_prog_info_node *info_node; - int len = sym->end - sym->start; - disassembler_ftype disassemble; - struct map *map = args->ms.map; - struct perf_bpil *info_linear; - struct disassemble_info info; - struct dso *dso = map__dso(map); - int pc = 0, count, sub_id; - struct btf *btf = NULL; - char tpath[PATH_MAX]; - size_t buf_size; - int nr_skip = 0; - char *buf; - bfd *bfdf; - int ret; - FILE *s; - - if (dso__binary_type(dso) != DSO_BINARY_TYPE__BPF_PROG_INFO) - return SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE; - - pr_debug("%s: handling sym %s addr %" PRIx64 " len %" PRIx64 "\n", __func__, - sym->name, sym->start, sym->end - sym->start); - - memset(tpath, 0, sizeof(tpath)); - perf_exe(tpath, sizeof(tpath)); - - bfdf = bfd_openr(tpath, NULL); - if (bfdf == NULL) - abort(); - - if (!bfd_check_format(bfdf, bfd_object)) - abort(); - - s = open_memstream(&buf, &buf_size); - if (!s) { - ret = errno; - goto out; - } - init_disassemble_info_compat(&info, s, - (fprintf_ftype) fprintf, - fprintf_styled); - info.arch = bfd_get_arch(bfdf); - info.mach = bfd_get_mach(bfdf); - - info_node = perf_env__find_bpf_prog_info(dso__bpf_prog(dso)->env, - dso__bpf_prog(dso)->id); - if (!info_node) { - ret = SYMBOL_ANNOTATE_ERRNO__BPF_MISSING_BTF; - goto out; - } - info_linear = info_node->info_linear; - sub_id = dso__bpf_prog(dso)->sub_id; - - info.buffer = (void *)(uintptr_t)(info_linear->info.jited_prog_insns); - info.buffer_length = info_linear->info.jited_prog_len; - - if (info_linear->info.nr_line_info) - prog_linfo = bpf_prog_linfo__new(&info_linear->info); - - if (info_linear->info.btf_id) { - struct btf_node *node; - - node = perf_env__find_btf(dso__bpf_prog(dso)->env, - info_linear->info.btf_id); - if (node) - btf = btf__new((__u8 *)(node->data), - node->data_size); - } - - disassemble_init_for_target(&info); - -#ifdef DISASM_FOUR_ARGS_SIGNATURE - disassemble = disassembler(info.arch, - bfd_big_endian(bfdf), - info.mach, - bfdf); -#else - disassemble = disassembler(bfdf); -#endif - if (disassemble == NULL) - abort(); - - fflush(s); - do { - const struct bpf_line_info *linfo = NULL; - struct disasm_line *dl; - size_t prev_buf_size; - const char *srcline; - u64 addr; - - addr = pc + ((u64 *)(uintptr_t)(info_linear->info.jited_ksyms))[sub_id]; - count = disassemble(pc, &info); - - if (prog_linfo) - linfo = bpf_prog_linfo__lfind_addr_func(prog_linfo, - addr, sub_id, - nr_skip); - - if (linfo && btf) { - srcline = btf__name_by_offset(btf, linfo->line_off); - nr_skip++; - } else - srcline = NULL; - - fprintf(s, "\n"); - prev_buf_size = buf_size; - fflush(s); - - if (!annotate_opts.hide_src_code && srcline) { - args->offset = -1; - args->line = strdup(srcline); - args->line_nr = 0; - args->fileloc = NULL; - args->ms.sym = sym; - dl = disasm_line__new(args); - if (dl) { - annotation_line__add(&dl->al, - ¬es->src->source); - } - } - - args->offset = pc; - args->line = buf + prev_buf_size; - args->line_nr = 0; - args->fileloc = NULL; - args->ms.sym = sym; - dl = disasm_line__new(args); - if (dl) - annotation_line__add(&dl->al, ¬es->src->source); - - pc += count; - } while (count > 0 && pc < len); - - ret = 0; -out: - free(prog_linfo); - btf__free(btf); - fclose(s); - bfd_close(bfdf); - return ret; -} -#else // defined(HAVE_LIBBFD_SUPPORT) && defined(HAVE_LIBBPF_SUPPORT) int symbol__disassemble_bpf(struct symbol *sym __maybe_unused, struct annotate_args *args __maybe_unused) { return SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF; } -#endif // defined(HAVE_LIBBFD_SUPPORT) && defined(HAVE_LIBBPF_SUPPORT) int symbol__disassemble_bpf_image(struct symbol *sym, struct annotate_args *args) { diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index 26fd55455efd..797e78826508 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -146,247 +146,8 @@ void dso__free_a2l(struct dso *dso) { dso__free_a2l_llvm(dso); } -#elif defined(HAVE_LIBBFD_SUPPORT) -/* - * Implement addr2line using libbfd. - */ -#define PACKAGE "perf" -#include - -struct a2l_data { - const char *input; - u64 addr; - - bool found; - const char *filename; - const char *funcname; - unsigned line; - - bfd *abfd; - asymbol **syms; -}; - -static int bfd_error(const char *string) -{ - const char *errmsg; - - errmsg = bfd_errmsg(bfd_get_error()); - fflush(stdout); - - if (string) - pr_debug("%s: %s\n", string, errmsg); - else - pr_debug("%s\n", errmsg); - - return -1; -} - -static int slurp_symtab(bfd *abfd, struct a2l_data *a2l) -{ - long storage; - long symcount; - asymbol **syms; - bfd_boolean dynamic = FALSE; - - if ((bfd_get_file_flags(abfd) & HAS_SYMS) == 0) - return bfd_error(bfd_get_filename(abfd)); - - storage = bfd_get_symtab_upper_bound(abfd); - if (storage == 0L) { - storage = bfd_get_dynamic_symtab_upper_bound(abfd); - dynamic = TRUE; - } - if (storage < 0L) - return bfd_error(bfd_get_filename(abfd)); - - syms = malloc(storage); - if (dynamic) - symcount = bfd_canonicalize_dynamic_symtab(abfd, syms); - else - symcount = bfd_canonicalize_symtab(abfd, syms); - - if (symcount < 0) { - free(syms); - return bfd_error(bfd_get_filename(abfd)); - } - - a2l->syms = syms; - return 0; -} - -static void find_address_in_section(bfd *abfd, asection *section, void *data) -{ - bfd_vma pc, vma; - bfd_size_type size; - struct a2l_data *a2l = data; - flagword flags; - - if (a2l->found) - return; - -#ifdef bfd_get_section_flags - flags = bfd_get_section_flags(abfd, section); -#else - flags = bfd_section_flags(section); -#endif - if ((flags & SEC_ALLOC) == 0) - return; - - pc = a2l->addr; -#ifdef bfd_get_section_vma - vma = bfd_get_section_vma(abfd, section); -#else - vma = bfd_section_vma(section); -#endif -#ifdef bfd_get_section_size - size = bfd_get_section_size(section); -#else - size = bfd_section_size(section); -#endif - - if (pc < vma || pc >= vma + size) - return; - - a2l->found = bfd_find_nearest_line(abfd, section, a2l->syms, pc - vma, - &a2l->filename, &a2l->funcname, - &a2l->line); - - if (a2l->filename && !strlen(a2l->filename)) - a2l->filename = NULL; -} - -static struct a2l_data *addr2line_init(const char *path) -{ - bfd *abfd; - struct a2l_data *a2l = NULL; - - abfd = bfd_openr(path, NULL); - if (abfd == NULL) - return NULL; - - if (!bfd_check_format(abfd, bfd_object)) - goto out; - - a2l = zalloc(sizeof(*a2l)); - if (a2l == NULL) - goto out; - - a2l->abfd = abfd; - a2l->input = strdup(path); - if (a2l->input == NULL) - goto out; - - if (slurp_symtab(abfd, a2l)) - goto out; - - return a2l; - -out: - if (a2l) { - zfree((char **)&a2l->input); - free(a2l); - } - bfd_close(abfd); - return NULL; -} - -static void addr2line_cleanup(struct a2l_data *a2l) -{ - if (a2l->abfd) - bfd_close(a2l->abfd); - zfree((char **)&a2l->input); - zfree(&a2l->syms); - free(a2l); -} - -static int inline_list__append_dso_a2l(struct dso *dso, - struct inline_node *node, - struct symbol *sym) -{ - struct a2l_data *a2l = dso__a2l(dso); - struct symbol *inline_sym = new_inline_sym(dso, sym, a2l->funcname); - char *srcline = NULL; - - if (a2l->filename) - srcline = srcline_from_fileline(a2l->filename, a2l->line); - - return inline_list__append(inline_sym, srcline, node); -} - -static int addr2line(const char *dso_name, u64 addr, - char **file, unsigned int *line, struct dso *dso, - bool unwind_inlines, struct inline_node *node, - struct symbol *sym) -{ - int ret = 0; - struct a2l_data *a2l = dso__a2l(dso); - - if (!a2l) { - a2l = addr2line_init(dso_name); - dso__set_a2l(dso, a2l); - } - - if (a2l == NULL) { - if (!symbol_conf.disable_add2line_warn) - pr_warning("addr2line_init failed for %s\n", dso_name); - return 0; - } - - a2l->addr = addr; - a2l->found = false; - - bfd_map_over_sections(a2l->abfd, find_address_in_section, a2l); - - if (!a2l->found) - return 0; - - if (unwind_inlines) { - int cnt = 0; - - if (node && inline_list__append_dso_a2l(dso, node, sym)) - return 0; - - while (bfd_find_inliner_info(a2l->abfd, &a2l->filename, - &a2l->funcname, &a2l->line) && - cnt++ < MAX_INLINE_NEST) { - - if (a2l->filename && !strlen(a2l->filename)) - a2l->filename = NULL; - - if (node != NULL) { - if (inline_list__append_dso_a2l(dso, node, sym)) - return 0; - // found at least one inline frame - ret = 1; - } - } - } - - if (file) { - *file = a2l->filename ? strdup(a2l->filename) : NULL; - ret = *file ? 1 : 0; - } - - if (line) - *line = a2l->line; - - return ret; -} - -void dso__free_a2l(struct dso *dso) -{ - struct a2l_data *a2l = dso__a2l(dso); - - if (!a2l) - return; - - addr2line_cleanup(a2l); - - dso__set_a2l(dso, NULL); -} - -#else /* HAVE_LIBBFD_SUPPORT */ +#else /* HAVE_LIBLLVM_SUPPORT */ static int filename_split(char *filename, unsigned int *line_nr) { @@ -805,7 +566,7 @@ void dso__free_a2l(struct dso *dso) dso__set_a2l(dso, NULL); } -#endif /* HAVE_LIBBFD_SUPPORT */ +#endif /* HAVE_LIBLLVM_SUPPORT */ static struct inline_node *addr2inlines(const char *dso_name, u64 addr, struct dso *dso, struct symbol *sym) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 66fd1249660a..8140f60af1e5 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -27,12 +27,7 @@ #include #include -#ifdef HAVE_LIBBFD_SUPPORT -#define PACKAGE 'perf' -#include -#endif - -#if defined(HAVE_LIBBFD_SUPPORT) || defined(HAVE_CPLUS_DEMANGLE_SUPPORT) +#if defined(HAVE_CPLUS_DEMANGLE_SUPPORT) #ifndef DMGL_PARAMS #define DMGL_PARAMS (1 << 0) /* Include function args */ #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ @@ -291,11 +286,7 @@ static bool want_demangle(bool is_kernel_sym) char *cxx_demangle_sym(const char *str __maybe_unused, bool params __maybe_unused, bool modifiers __maybe_unused) { -#ifdef HAVE_LIBBFD_SUPPORT - int flags = (params ? DMGL_PARAMS : 0) | (modifiers ? DMGL_ANSI : 0); - - return bfd_demangle(NULL, str, flags); -#elif defined(HAVE_CPLUS_DEMANGLE_SUPPORT) +#if defined(HAVE_CPLUS_DEMANGLE_SUPPORT) int flags = (params ? DMGL_PARAMS : 0) | (modifiers ? DMGL_ANSI : 0); return cplus_demangle(str, flags); @@ -935,37 +926,6 @@ static int elf_read_build_id(Elf *elf, void *bf, size_t size) return err; } -#ifdef HAVE_LIBBFD_BUILDID_SUPPORT - -static int read_build_id(const char *filename, struct build_id *bid) -{ - size_t size = sizeof(bid->data); - int err = -1; - bfd *abfd; - - abfd = bfd_openr(filename, NULL); - if (!abfd) - return -1; - - if (!bfd_check_format(abfd, bfd_object)) { - pr_debug2("%s: cannot read %s bfd file.\n", __func__, filename); - goto out_close; - } - - if (!abfd->build_id || abfd->build_id->size > size) - goto out_close; - - memcpy(bid->data, abfd->build_id->data, abfd->build_id->size); - memset(bid->data + abfd->build_id->size, 0, size - abfd->build_id->size); - err = bid->size = abfd->build_id->size; - -out_close: - bfd_close(abfd); - return err; -} - -#else // HAVE_LIBBFD_BUILDID_SUPPORT - static int read_build_id(const char *filename, struct build_id *bid) { size_t size = sizeof(bid->data); @@ -996,8 +956,6 @@ static int read_build_id(const char *filename, struct build_id *bid) return err; } -#endif // HAVE_LIBBFD_BUILDID_SUPPORT - int filename__read_build_id(const char *filename, struct build_id *bid) { struct kmod_path m = { .name = NULL, }; @@ -1081,44 +1039,6 @@ int sysfs__read_build_id(const char *filename, struct build_id *bid) return err; } -#ifdef HAVE_LIBBFD_SUPPORT - -int filename__read_debuglink(const char *filename, char *debuglink, - size_t size) -{ - int err = -1; - asection *section; - bfd *abfd; - - abfd = bfd_openr(filename, NULL); - if (!abfd) - return -1; - - if (!bfd_check_format(abfd, bfd_object)) { - pr_debug2("%s: cannot read %s bfd file.\n", __func__, filename); - goto out_close; - } - - section = bfd_get_section_by_name(abfd, ".gnu_debuglink"); - if (!section) - goto out_close; - - if (section->size > size) - goto out_close; - - if (!bfd_get_section_contents(abfd, section, debuglink, 0, - section->size)) - goto out_close; - - err = 0; - -out_close: - bfd_close(abfd); - return err; -} - -#else - int filename__read_debuglink(const char *filename, char *debuglink, size_t size) { @@ -1171,8 +1091,6 @@ int filename__read_debuglink(const char *filename, char *debuglink, return err; } -#endif - static int dso__swap_init(struct dso *dso, unsigned char eidata) { static unsigned int const endian = 1; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 49b08adc6ee3..7c24e88f444f 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1573,137 +1573,6 @@ static int dso__load_perf_map(const char *map_path, struct dso *dso) return -1; } -#ifdef HAVE_LIBBFD_SUPPORT -#define PACKAGE 'perf' -#include - -static int bfd_symbols__cmpvalue(const void *a, const void *b) -{ - const asymbol *as = *(const asymbol **)a, *bs = *(const asymbol **)b; - - if (bfd_asymbol_value(as) != bfd_asymbol_value(bs)) - return bfd_asymbol_value(as) - bfd_asymbol_value(bs); - - return bfd_asymbol_name(as)[0] - bfd_asymbol_name(bs)[0]; -} - -static int bfd2elf_binding(asymbol *symbol) -{ - if (symbol->flags & BSF_WEAK) - return STB_WEAK; - if (symbol->flags & BSF_GLOBAL) - return STB_GLOBAL; - if (symbol->flags & BSF_LOCAL) - return STB_LOCAL; - return -1; -} - -int dso__load_bfd_symbols(struct dso *dso, const char *debugfile) -{ - int err = -1; - long symbols_size, symbols_count, i; - asection *section; - asymbol **symbols, *sym; - struct symbol *symbol; - bfd *abfd; - u64 start, len; - - abfd = bfd_openr(debugfile, NULL); - if (!abfd) - return -1; - - if (!bfd_check_format(abfd, bfd_object)) { - pr_debug2("%s: cannot read %s bfd file.\n", __func__, - dso__long_name(dso)); - goto out_close; - } - - if (bfd_get_flavour(abfd) == bfd_target_elf_flavour) - goto out_close; - - symbols_size = bfd_get_symtab_upper_bound(abfd); - if (symbols_size == 0) { - bfd_close(abfd); - return 0; - } - - if (symbols_size < 0) - goto out_close; - - symbols = malloc(symbols_size); - if (!symbols) - goto out_close; - - symbols_count = bfd_canonicalize_symtab(abfd, symbols); - if (symbols_count < 0) - goto out_free; - - section = bfd_get_section_by_name(abfd, ".text"); - if (section) { - for (i = 0; i < symbols_count; ++i) { - if (!strcmp(bfd_asymbol_name(symbols[i]), "__ImageBase") || - !strcmp(bfd_asymbol_name(symbols[i]), "__image_base__")) - break; - } - if (i < symbols_count) { - /* PE symbols can only have 4 bytes, so use .text high bits */ - u64 text_offset = (section->vma - (u32)section->vma) - + (u32)bfd_asymbol_value(symbols[i]); - dso__set_text_offset(dso, text_offset); - dso__set_text_end(dso, (section->vma - text_offset) + section->size); - } else { - dso__set_text_offset(dso, section->vma - section->filepos); - dso__set_text_end(dso, section->filepos + section->size); - } - } - - qsort(symbols, symbols_count, sizeof(asymbol *), bfd_symbols__cmpvalue); - -#ifdef bfd_get_section -#define bfd_asymbol_section bfd_get_section -#endif - for (i = 0; i < symbols_count; ++i) { - sym = symbols[i]; - section = bfd_asymbol_section(sym); - if (bfd2elf_binding(sym) < 0) - continue; - - while (i + 1 < symbols_count && - bfd_asymbol_section(symbols[i + 1]) == section && - bfd2elf_binding(symbols[i + 1]) < 0) - i++; - - if (i + 1 < symbols_count && - bfd_asymbol_section(symbols[i + 1]) == section) - len = symbols[i + 1]->value - sym->value; - else - len = section->size - sym->value; - - start = bfd_asymbol_value(sym) - dso__text_offset(dso); - symbol = symbol__new(start, len, bfd2elf_binding(sym), STT_FUNC, - bfd_asymbol_name(sym)); - if (!symbol) - goto out_free; - - symbols__insert(dso__symbols(dso), symbol); - } -#ifdef bfd_get_section -#undef bfd_asymbol_section -#endif - - symbols__fixup_end(dso__symbols(dso), false); - symbols__fixup_duplicate(dso__symbols(dso)); - dso__set_adjust_symbols(dso, true); - - err = 0; -out_free: - free(symbols); -out_close: - bfd_close(abfd); - return err; -} -#endif - static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod, enum dso_binary_type type) { @@ -1905,10 +1774,6 @@ int dso__load(struct dso *dso, struct map *map) } } -#ifdef HAVE_LIBBFD_SUPPORT - if (is_reg) - bfdrc = dso__load_bfd_symbols(dso, name); -#endif if (is_reg && bfdrc < 0) sirc = symsrc__init(ss, dso, name, symtab_type); diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 3fb5d146d9b1..508fd559a8a1 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -174,10 +174,6 @@ int symbol__config_symfs(const struct option *opt __maybe_unused, struct symsrc; -#ifdef HAVE_LIBBFD_SUPPORT -int dso__load_bfd_symbols(struct dso *dso, const char *debugfile); -#endif - int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss, struct symsrc *runtime_ss, int kmodule); int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss); From patchwork Wed Jan 22 06:23:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946902 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 29AD71C5F1A for ; Wed, 22 Jan 2025 06:25:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527147; cv=none; b=Fy1wyBl24c9KXCBWHYHgKTC/Y61cPWkVcpXYWAawWt5g7gkz5ySxbL1FzrekaUl42F86FUDb5YzjghDi4So+pXWwFdH2MAjkZbR6lEX1MxvAjv7zLp5CgT4g1MgiAHGwczKDs2vGUQENq4uEXbb2LNfnp9/9Yc3FnBbHHR/1Z+Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527147; c=relaxed/simple; bh=8YdK72iZdR17owyBQbQB5b4SQ6Ubblw50VG+kDokyoA=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=elH11thov5azH3KeR/GLbO8mXNm0gfPC5FAc60yy7eiXD8W0UySJP9dpN+wECcnCZCqi2og5vFGCmjFCKTy9cs54hkRKyTQnE4YhQ5vYpLfuk4VyatuYVhnD7DCiPTONRoIAeoA3LVEgubAmSZATNMnsAXlJmRHWRjAa1ldGrD0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=werHbYdS; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="werHbYdS" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-e39993d8594so16203426276.3 for ; Tue, 21 Jan 2025 22:25:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527144; x=1738131944; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=ifrzx08xgFVVOvnuD1mbePIHPYzVbA5mBaTsSvEVMM8=; b=werHbYdSXVOXsor5ScmwWjCIKaKexRTdbCU2/5P0gwefctanX8ZYKQOfibNL3eSRxh oAoP/JG26pKWuCXNlZ1ItLDYgXcwNnM78bOSnPMoC2bvevJAVE9Zq2zDqkPGaj6XqTSQ Rw2WrQde+uf/SrhvwiMR45TDyPyi211Mya8NeSw01eYLe8dWVroTtJoLT93uQrHb8wry UqrRuHgG76X2R4iW740tXvRvR1K9rLguI/Do7eBHsxb7jIjqw2hbibkC3uxB50+orVsc U+t+HnQrcyoqpn9cZdDiQncBNDJbSSlXbAsbA9XAOQN4WaPTL6jS2rBv35Iz3f+Ep7BU u/3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527144; x=1738131944; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ifrzx08xgFVVOvnuD1mbePIHPYzVbA5mBaTsSvEVMM8=; b=RgXYwpeJRWkJzXhegDrGhVlAsh74hN1HjgfXb/NpXx+iWXIAkjo2GnzcNDapAS19M8 Y+g20c1PbcIxMoQ8rFiMpsgWJl5cWG0iR8w/6IDBuuP/jiR73vO9x/hbPO+pbAANEcMr E+xfE30eNW0mBor/QdLNL/hJ5g9nz2olQn4JIVJBrzBEIHWgme8enlp7VDvHZWfpWcju dGzWS+InnRBMLCnZZuIlzEprH95Sg82aI8kXCnVtZxmtJVTqToGZcmYJ/OYdyEw4B9nr j2Tx+8iDhGKZrDU0SHjwkfa1st7q+ml8xjfdGUP/9i1pxRY7HXUo1Sv8XLMCBfuFeY5P UObw== X-Forwarded-Encrypted: i=1; AJvYcCXPIx9wRejkhJDfzAozdyn2Yt1wLY7ueMv26p17gLiB2vIYBN/+HK0gxBIQVDNOAePBJ9g=@vger.kernel.org X-Gm-Message-State: AOJu0Yz6Jzp+2StMXhr+hrhBfivnfCCzNzORz8HGs8fnIn/n4yZGbFaB M4zmdvQroTgReUr9Sv8iarbjMHamVdyuK8/+QucsJcIMaZA7h8LRoneH4XZgRmzkJvxUY7OoVUn 07vRtCg== X-Google-Smtp-Source: AGHT+IEUzUAkofeuVvAtDYMZZaTprBavOTBiC/v5bGjwuLSAhbX6+dOAwBIHHcktV1WdUK0vxmNle87xnyEI X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a81:a907:0:b0:62c:f976:a763 with SMTP id 00721157ae682-6f6eb65eeadmr431097b3.1.1737527144144; Tue, 21 Jan 2025 22:25:44 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:29 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-15-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 14/17] perf build: Remove libiberty support From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org libiberty is license incompatible with perf and building requires the BUILD_NONDISTRO=1 build flag. libiberty is used for HAVE_CPLUS_DEMANGLE_SUPPORT. Remove the code to simplify the code base as it can't be distributed. Remove the BUILD_NONDISTRO build flag and test as they no longer enable/disable support. Signed-off-by: Ian Rogers --- tools/perf/Makefile.config | 12 ------------ tools/perf/Makefile.perf | 11 ++++------- tools/perf/tests/make | 2 -- tools/perf/util/demangle-cxx.cpp | 13 +------------ tools/perf/util/symbol-elf.c | 13 ------------- 5 files changed, 5 insertions(+), 46 deletions(-) diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 900be0349de9..513dd5cab605 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -949,18 +949,6 @@ ifndef NO_DEMANGLE CXXFLAGS += -DHAVE_CXA_DEMANGLE_SUPPORT $(call detected,CONFIG_CXX_DEMANGLE) endif - ifdef BUILD_NONDISTRO - ifeq ($(filter -liberty,$(EXTLIBS)),) - $(call feature_check,cplus-demangle) - ifeq ($(feature-cplus-demangle), 1) - EXTLIBS += -liberty - endif - endif - ifneq ($(filter -liberty,$(EXTLIBS)),) - CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT - CXXFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT - endif - endif endif ifndef NO_LZMA diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index a2886abd4f02..398c30b6bdce 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -123,9 +123,6 @@ include ../scripts/utilities.mak # # Set BUILD_BPF_SKEL to 0 to override BUILD_BPF_SKEL and not build BPF skeletons # -# Define BUILD_NONDISTRO to enable building an linking against libbfd and -# libiberty distribution license incompatible libraries. -# # Define EXTRA_TESTS to enable building extra tests useful mainly to perf # developers, such as: # x86 instruction decoder - new instructions test @@ -329,10 +326,10 @@ LIBSYMBOL_DIR = $(srctree)/tools/lib/symbol/ LIBPERF_DIR = $(srctree)/tools/lib/perf/ DOC_DIR = $(srctree)/tools/perf/Documentation/ -# Set FEATURE_TESTS to 'all' so all possible feature checkers are executed. -# Without this setting the output feature dump file misses some features, for -# example, liberty. Select all checkers so we won't get an incomplete feature -# dump file. +# Set FEATURE_TESTS to 'all' so all possible feature checkers are +# executed. Without this setting the output feature dump file misses +# some features. Select all checkers so we won't get an incomplete +# feature dump file. ifeq ($(config),1) ifdef MAKECMDGOALS ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump) diff --git a/tools/perf/tests/make b/tools/perf/tests/make index 44d76eacce49..4a1ed20bff7e 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -68,7 +68,6 @@ python_perf_so := $(shell $(MAKE) python_perf_target|grep "Target is:"|awk '{pri make_clean_all := clean all make_python_perf_so := $(python_perf_so) make_debug := DEBUG=1 -make_nondistro := BUILD_NONDISTRO=1 make_extra_tests := EXTRA_TESTS=1 make_jevents_all := JEVENTS_ARCH=all make_no_bpf_skel := BUILD_BPF_SKEL=0 @@ -139,7 +138,6 @@ MAKE_F := $(MAKE) -f $(MK) endif run += make_python_perf_so run += make_debug -run += make_nondistro run += make_extra_tests run += make_jevents_all run += make_no_bpf_skel diff --git a/tools/perf/util/demangle-cxx.cpp b/tools/perf/util/demangle-cxx.cpp index bd657eb37efc..36801ea327a6 100644 --- a/tools/perf/util/demangle-cxx.cpp +++ b/tools/perf/util/demangle-cxx.cpp @@ -8,13 +8,6 @@ #include #endif -#if defined(HAVE_CPLUS_DEMANGLE_SUPPORT) -#ifndef DMGL_PARAMS -#define DMGL_PARAMS (1 << 0) /* Include function args */ -#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ -#endif -#endif - /* * Demangle C++ function signature * @@ -24,11 +17,7 @@ extern "C" char *cxx_demangle_sym(const char *str, bool params __maybe_unused, bool modifiers __maybe_unused) { -#if defined(HAVE_CPLUS_DEMANGLE_SUPPORT) - int flags = (params ? DMGL_PARAMS : 0) | (modifiers ? DMGL_ANSI : 0); - - return cplus_demangle(str, flags); -#elif defined(HAVE_CXA_DEMANGLE_SUPPORT) +#if defined(HAVE_CXA_DEMANGLE_SUPPORT) char *output; int status; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 8140f60af1e5..121db55b9709 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -27,13 +27,6 @@ #include #include -#if defined(HAVE_CPLUS_DEMANGLE_SUPPORT) -#ifndef DMGL_PARAMS -#define DMGL_PARAMS (1 << 0) /* Include function args */ -#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ -#endif -#endif - #ifndef EM_AARCH64 #define EM_AARCH64 183 /* ARM 64 bit */ #endif @@ -286,13 +279,7 @@ static bool want_demangle(bool is_kernel_sym) char *cxx_demangle_sym(const char *str __maybe_unused, bool params __maybe_unused, bool modifiers __maybe_unused) { -#if defined(HAVE_CPLUS_DEMANGLE_SUPPORT) - int flags = (params ? DMGL_PARAMS : 0) | (modifiers ? DMGL_ANSI : 0); - - return cplus_demangle(str, flags); -#else return NULL; -#endif } #endif /* !HAVE_CXA_DEMANGLE_SUPPORT */ From patchwork Wed Jan 22 06:23:30 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946903 Received: from mail-yb1-f201.google.com (mail-yb1-f201.google.com [209.85.219.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2AD0A1BD4F1 for ; Wed, 22 Jan 2025 06:25:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527155; cv=none; b=ZSM+jADhNtMzqGBjEGo8YEiYNta4eEjvUYjExR5wAqFmnnyzowOibrr2SJYIo3JhdGBZ6nlVR1FbZpBKfdGyfaCK8BVvIrSmO4WVhZvSF/C1y5mMIuRCnUrGfG2bj7WNzZGn2gk6WZfdLXasv6mEwmk2lGY8+wGqBtP1V420Re4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527155; c=relaxed/simple; bh=YkWOp6sBnU9ELov42ERsPm7Vngu6X+NP4toNn4LW5Oc=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=Qj1doTh7MPhaQ1Tgh9NEjQPlqGdh+c/9UKZfmvu9rHDdhd6HPoGTzZBQrInfIe4Lfx6v7oXA2COb0irzASAOjhpkdxD0tfoP/GWSLRvlee51J+62aIKyDe+0UbIo7Odrbe8Vf5j0FS1QrtxeSocAZIXESK5P7dhWxkI9TPi+/4s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=AyUb5EqX; arc=none smtp.client-ip=209.85.219.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="AyUb5EqX" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-e39fd56398cso15278225276.1 for ; Tue, 21 Jan 2025 22:25:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527153; x=1738131953; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=M9hPyZ1Eqh7FkhnlmqyYPUb6W8XykQq6Ozx0wTDbMtQ=; b=AyUb5EqXwM+HhTGIaPtl/e5ly715nkUGyRXd9pppHJAMVbeKJIDzLphhXccre/gT45 mhLbEkkiQEVrW0Mp7F7g/wSsHFn0FZYcb32g4bqxSwyJG0vaOMPLC2tlmtZhxQdyIG6a s3E3wCIcD1/QxKkAEPW8uLQ7evlJMj5GKkg/cG9srdSdgNO4+SZkea5qFg1ZmojRlxR8 7Gja07D3t/WbPNM94nL6LUr7tTYjGLbexHb0Pkr067GdXXu0aGimWn0jBsny1F0qjENa lqJBkHGB0FFIB2sqgExZPH7FitiqJe1jjs8VQSvQtD5RABZO8ZCGwQT9ycwNUfDckXBU RQLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527153; x=1738131953; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=M9hPyZ1Eqh7FkhnlmqyYPUb6W8XykQq6Ozx0wTDbMtQ=; b=TNgVl9jNpffv88mzXrGok4PgaHltFgdyESeVQ3Xw8U/9t+g/R2hVTj/YnYXCq+4Qyc RecWwUGaJ0NmVmk5KHde/6X1ErqM3qtNCnA0iRipPWgpUA1D0f4LSLEp5p5z0VXISN1d c2bG8yNEtwFzf/Jy5JcTL2qe3ot+f9OWJWsQ7U0KYF2LgDZm1vANLr5JAGhzRzvNcG+O x5fdk7HByWYnzdRgfD+IBC/XNtsykqvSH++cSlsGY5oLUUnKp/gopcbD7InaIbHxZdwE En4eg+UJNobnCdvFhTX3oEJ8B9BYMafqkOPveYlljOaGHirzXftTr9E8t23xLfQCoI1B PsAg== X-Forwarded-Encrypted: i=1; AJvYcCX77GnZGVir0M6JBlMRx/dbNuqIS1Kd8uRWSq+O3hRFpKmzEOlySy+wqKnvZ9YYMDPqNRw=@vger.kernel.org X-Gm-Message-State: AOJu0Yz9oAPyxBARYbzNjNjRCWzITd/pCzF+tQCNh8RIZuWcnJ4V9qZj nzt9nPGRfzwJTNPEzoTC7uv0iL+TOku6XQSYEo3AOlJIVNPNvfjriZDZFh0YzBwl4AloU3xikBg xKVsdmQ== X-Google-Smtp-Source: AGHT+IENajIP32nGxFM0VFkKXqErBuQpYWc46Ni8szy3vhHn4bDuMStRS5BfINva+xTIFK/Nmc3Oq8aYUx+T X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a81:c807:0:b0:6f2:8819:2318 with SMTP id 00721157ae682-6f6eb93c63emr362427b3.5.1737527153324; Tue, 21 Jan 2025 22:25:53 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:30 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-16-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 15/17] perf build: Remove unused defines From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org DISASM_FOUR_ARGS_SIGNATURE and DISASM_INIT_STYLED were used with libbfd support. Remove now that libbfd support is removed. Signed-off-by: Ian Rogers --- tools/perf/Makefile.config | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 513dd5cab605..ba60a5b47be7 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -320,9 +320,6 @@ FEATURE_CHECK_LDFLAGS-libpython := $(PYTHON_EMBED_LDOPTS) FEATURE_CHECK_LDFLAGS-libaio = -lrt -FEATURE_CHECK_LDFLAGS-disassembler-four-args = -lbfd -lopcodes -ldl -FEATURE_CHECK_LDFLAGS-disassembler-init-styled = -lbfd -lopcodes -ldl - CORE_CFLAGS += -fno-omit-frame-pointer CORE_CFLAGS += -Wall CORE_CFLAGS += -Wextra @@ -349,7 +346,7 @@ endif ifeq ($(FEATURES_DUMP),) # We will display at the end of this Makefile.config, using $(call feature_display_entries) -# As we may retry some feature detection here, see the disassembler-four-args case, for instance +# As we may retry some feature detection here. FEATURE_DISPLAY_DEFERRED := 1 include $(srctree)/tools/build/Makefile.feature else @@ -1001,14 +998,6 @@ ifdef HAVE_KVM_STAT_SUPPORT CFLAGS += -DHAVE_KVM_STAT_SUPPORT endif -ifeq ($(feature-disassembler-four-args), 1) - CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE -endif - -ifeq ($(feature-disassembler-init-styled), 1) - CFLAGS += -DDISASM_INIT_STYLED -endif - ifeq (${IS_64_BIT}, 1) ifndef NO_PERF_READ_VDSO32 $(call feature_check,compile-32) @@ -1286,6 +1275,6 @@ endif # re-generate FEATURE-DUMP as we may have called feature_check, found out # extra libraries to add to LDFLAGS of some other test and then redo those -# tests, see the block about disassembler-four-args, for instance. +# tests. $(shell rm -f $(FEATURE_DUMP_FILENAME)) $(foreach feat,$(FEATURE_TESTS),$(shell echo "$(call feature_assign,$(feat))" >> $(FEATURE_DUMP_FILENAME))) From patchwork Wed Jan 22 06:23:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946904 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BFB861BC9FB for ; Wed, 22 Jan 2025 06:26:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527163; cv=none; b=JNncvvpYgf3/EYI8/ksaIkiWyhprmVLX9f3/NZd58pSrVcpKxGXYPcwIJDZHFDJjVfsrP4YYAreXlJ7likZ/gQ28wLKs+32iJkHqEIeiP0/kgdxZ/vI3YaR6pQ/C8cp92D8PTiLbnHkV3Nv4/cIWn4MM80VquOuIi4d+UDZcss8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527163; c=relaxed/simple; bh=4eVzUx7LyXLmyBqZ04/qHfp1ubXNS/OOuZG0/Fwht+I=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=gas2DLZ5m7LAYd4R3sY4xSwUudys6obFK7bMcHxnDdltJub6lpJLeHiZFiFJkCDEn1JkGrzjkgr9zDmW7psIZYkLINQG3HqDZgRRv40OYVUjxL7k6oq5nNh5VFA4RKA0zo6IA/njznRpEKDzcpVZfYERFzLnp76MgOw95syR/fA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=uLMNP+2w; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="uLMNP+2w" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e572cd106f7so16880770276.3 for ; Tue, 21 Jan 2025 22:26:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527161; x=1738131961; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=IKqawTnGAxAu0q/wc+BOpGtG2cpu0MmUyGjHNjJM5iE=; b=uLMNP+2wku+g8XHgq1a0QMm+DqUIPcXmglqPs9ADRx5Z7XsMkmeTpEaiMNLigiHPuc pQU85jRbMBR8VdNUkYhTvErGNQM/IveVkNZY0b92gn9pxSrGSFgBfSbLcidPbLgLGY2k pUp3DTqfc1ebfo/5X+lkvpVxqn5dD0or2DG4sWCYcFA+m737XyZ3KvDvqOxeIcAc1xRN WSiH7VbibKrYxKfR9p7vm0KNkRGP0NKcNbpHhfL4xQ4l/Q2qp/2Ik7cTpSUIWaIo91u6 jo8zG96/5a7jY3WuWkfUUEIr79n4B5rQ7X3MobGKbDgbLJVVI2g06PDF09+5k0vjOLbk NFaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527161; x=1738131961; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=IKqawTnGAxAu0q/wc+BOpGtG2cpu0MmUyGjHNjJM5iE=; b=Ou5WFRLKAFUl+5tYJeI0Zyejwebn7iJhyp+XksTyjxkCIz2tXtmyAvRWtZcPfFMF1Z c+awjDVPCPT93HLtFVHsE0vqY9FpLwIkyVZuQNQK2JP9NbPLcB7fKACeDIj5H0v7FHda z7Jiky1UDgpa3A27veKeaavA92TJddvASpN8N8TvsoGmvCbvmNc4UCqGS7WcVjYMQEZV WCvFVtyLstkImOoHipyvPTrYEcfPGY0nEZQhSdZhoOpKgSxGapZkXIeBOt4+wh1XwF8d /6hV59h/bYhO4Y3B/RRqn2xvzvyFu6NcQ0qpYrfdNdpdq6m2pKEtiw4XvXi8PrbPMiVp xD7w== X-Forwarded-Encrypted: i=1; AJvYcCXOj53kzyeAD5iHFSks4e6MjgiOzgm4vOlh5HKiPvef4jJyvZq1snQfjAYrEtJTSEHX7ow=@vger.kernel.org X-Gm-Message-State: AOJu0YzLMGlRYF/ab8DAU3AeXEO0ZIZN6+zmrry9XPGcKSxkPzLDwPC3 Aj5KbsrYma3a78HnicYOqWZqmvGA57zYMcYoIsPlpV1tleuzQGeNlpD5yNBD9LI9pdtAirBN9oj XkOjw3g== X-Google-Smtp-Source: AGHT+IEIfcJLtTBEZluRA1nwsuELe3zQ6ijw/DfjYoqYE5QW7fzSo8dNRVRcgtzpL8L2iIcD9YGQFvcEtgOh X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a25:c181:0:b0:e57:3e87:8c1b with SMTP id 3f1490d57ef6-e57b1337eacmr35774276.6.1737527160752; Tue, 21 Jan 2025 22:26:00 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:31 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-17-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 16/17] perf disasm: Remove disasm_bpf From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org BPF disassembly was handled in here by libbfd. The LLVM and capstone disassemblers now support BPF JIT disassembly. As libbfd support was removed the functions here no longer did anything remove them and associated error values. Signed-off-by: Ian Rogers --- tools/perf/util/Build | 1 - tools/perf/util/annotate.h | 1 - tools/perf/util/disasm.c | 12 +++--------- tools/perf/util/disasm_bpf.c | 29 ----------------------------- tools/perf/util/disasm_bpf.h | 12 ------------ 5 files changed, 3 insertions(+), 52 deletions(-) delete mode 100644 tools/perf/util/disasm_bpf.c delete mode 100644 tools/perf/util/disasm_bpf.h diff --git a/tools/perf/util/Build b/tools/perf/util/Build index eb00c599e179..4b757d157f13 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -14,7 +14,6 @@ perf-util-y += copyfile.o perf-util-y += ctype.o perf-util-y += db-export.o perf-util-y += disasm.o -perf-util-y += disasm_bpf.o perf-util-y += env.o perf-util-y += event.o perf-util-y += evlist.o diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index 0ba5846dad4d..e704a9c913f7 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -438,7 +438,6 @@ enum symbol_disassemble_errno { __SYMBOL_ANNOTATE_ERRNO__START = -10000, SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX = __SYMBOL_ANNOTATE_ERRNO__START, - SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF, SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING, SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP, SYMBOL_ANNOTATE_ERRNO__BPF_INVALID_FILE, diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index 99b9c21e02b0..ebd86691acf8 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -17,7 +17,6 @@ #include "capstone.h" #include "debug.h" #include "disasm.h" -#include "disasm_bpf.h" #include "dso.h" #include "dwarf-regs.h" #include "env.h" @@ -1230,9 +1229,6 @@ int symbol__strerror_disassemble(struct map_symbol *ms, int errnum, char *buf, s " --vmlinux vmlinux\n", build_id_msg ?: ""); } break; - case SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF: - scnprintf(buf, buflen, "Please link with binutils's libopcode to enable BPF annotation"); - break; case SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP: scnprintf(buf, buflen, "Problems with arch specific instruction name regular expressions."); break; @@ -1500,11 +1496,9 @@ static int symbol__disassemble_objdump(const char *filename, struct symbol *sym, struct child_process objdump_process; int err; - if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO) - return symbol__disassemble_bpf(sym, args); - - if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) - return symbol__disassemble_bpf_image(sym, args); + if (dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_PROG_INFO || + dso__binary_type(dso) == DSO_BINARY_TYPE__BPF_IMAGE) + return -1; err = asprintf(&command, "%s %s%s --start-address=0x%016" PRIx64 diff --git a/tools/perf/util/disasm_bpf.c b/tools/perf/util/disasm_bpf.c deleted file mode 100644 index a891a0b909a7..000000000000 --- a/tools/perf/util/disasm_bpf.c +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include "util/annotate.h" -#include "util/disasm_bpf.h" -#include "util/symbol.h" -#include -#include - -int symbol__disassemble_bpf(struct symbol *sym __maybe_unused, struct annotate_args *args __maybe_unused) -{ - return SYMBOL_ANNOTATE_ERRNO__NO_LIBOPCODES_FOR_BPF; -} - -int symbol__disassemble_bpf_image(struct symbol *sym, struct annotate_args *args) -{ - struct annotation *notes = symbol__annotation(sym); - struct disasm_line *dl; - - args->offset = -1; - args->line = strdup("to be implemented"); - args->line_nr = 0; - args->fileloc = NULL; - dl = disasm_line__new(args); - if (dl) - annotation_line__add(&dl->al, ¬es->src->source); - - zfree(&args->line); - return 0; -} diff --git a/tools/perf/util/disasm_bpf.h b/tools/perf/util/disasm_bpf.h deleted file mode 100644 index 2ecb19545388..000000000000 --- a/tools/perf/util/disasm_bpf.h +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#ifndef __PERF_DISASM_BPF_H -#define __PERF_DISASM_BPF_H - -struct symbol; -struct annotate_args; - -int symbol__disassemble_bpf(struct symbol *sym, struct annotate_args *args); -int symbol__disassemble_bpf_image(struct symbol *sym, struct annotate_args *args); - -#endif /* __PERF_DISASM_BPF_H */ From patchwork Wed Jan 22 06:23:32 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 13946905 Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 436D11B4F3E for ; Wed, 22 Jan 2025 06:26:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.219.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527171; cv=none; b=lUswtMJIaYpySLeFxQ+pwdRrEKuyPpk/+YUsEunlNAx3IG5JVOzpmad4fMAHctnlpTve7KWbLErCoQjKsfMri5Fe8NEAbU1KoiviLViJkAiaiNut7M271WbJhr2g+g/hyq7OI0SqoGbUYWFo15hanYCMMr+3JEVr7ELzDOIXgbs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737527171; c=relaxed/simple; bh=BfQOAR1G+at7pRYGYXzHQjPEnrcQ33cHSvtWSYC7XKw=; h=Date:In-Reply-To:Message-Id:Mime-Version:References:Subject:From: To:Content-Type; b=JGvCcguSzaWaWEH5Qpy9rGyJ5EvBV3e1f8iwGPHQmfiHF3Nz3we0H+shHZg35yKFfv35zhb4jExaQLmm26laSNWGSmkpYJs1ZxnkE/r+yCYp8o3U/bfIor6SpG92OghzY42MRIoMt29EQJpo5iKjTDLQckKfobJ7Ucg1N/nycCw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=EO4DABGB; arc=none smtp.client-ip=209.85.219.202 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="EO4DABGB" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e54d9b54500so16407504276.3 for ; Tue, 21 Jan 2025 22:26:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1737527169; x=1738131969; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=jgqdWXIgH31oO69HT02RtwzG7MxuXhHOOr55YpEQGAs=; b=EO4DABGB9M5LH0lBfxs+nYZ3Iz/nFBetOUEARsxxJEg0B5zbSzZFbJtoAlFcpiBhYq oYFGSwmYzsTv6D8qdQMVbyNC9DxM2RczL3JHXtwKOWP7cKZCdF1JkQOHNRpV126iKsoJ t5bTwlCVRZBd8wS6k5YJyjOB8qXRxI19JMH6MSYJKLBl6ZVEN8VRb2FRCYR95ih6F3A8 s/FUteA9lJvOxpY9sd1HSFfVOam4PMTNiIm88FHrtvrClCKj3ITkY9JjKe1D+ydTV+5v aoxGxWH1/2l+0WxiAsM8iwWm3EmnnAInrLuOxH8UqixMeHMkwwC6z9EHeOdb3mwbvEo4 BwFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737527169; x=1738131969; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=jgqdWXIgH31oO69HT02RtwzG7MxuXhHOOr55YpEQGAs=; b=TKtqNELTEdHPkp0G5lxEnhr0wiX1BNV2R8OpDd1up5t6MMeym1oJnvqnUw6ms+Vtd+ pNJ3GtaKdMhhvZ1nFFeIyJrvWvMCfwc0mn7g+gLpqf7l0rzW8NolMaqtyI7nr7GfC4nA V8gVEpU8tAD9W0LOlQLAIDglaMqmgViXa63cO7p4r0B0s9YlsI+KSt2QpMrWdM2XlPyd 1oWBerMrIL5Qff+QRjsQKb39f2TbAkan/si+HapXRLxg6hpSePck1cAXfp3Ng5PEOUkV ZtwwDLy3WH1HzQcx54XrsiTnhGZ0VVZCSYdDN0YStvtw2o22A6wTAnb4vHF579c8DOFd u4VQ== X-Forwarded-Encrypted: i=1; AJvYcCX+K8txerWmHyim2bm8rH+gIey6L+Jf1ISq7N8rG83gTNZ7IHyDs8F+Co7z2XMl/SvB91E=@vger.kernel.org X-Gm-Message-State: AOJu0Yxd93up7CYQLRSNBvY1Kd7YVvvoftX1wqxJOyR796SNMDJn297X 8TR1pJKwW/1GCU/jzKn5YzE7TFDKPEma7mOzc7vvugtzgM7Fj0Ug9qPuPgJxgWdfkMv8XM0BhBd 3BT1Hfg== X-Google-Smtp-Source: AGHT+IF6rwzVNy8tbQ12mHzbRHmKpJHEzsK35EPLx3KJfYalflkJcjMfzIoyWZyP5IcEbo2YvBdof+rOLPE0 X-Received: from irogers.svl.corp.google.com ([2620:15c:2c5:11:807b:be79:d5c3:ee5c]) (user=irogers job=sendgmr) by 2002:a05:690c:3005:b0:6e9:f188:8638 with SMTP id 00721157ae682-6f6eb9475efmr341777b3.7.1737527169492; Tue, 21 Jan 2025 22:26:09 -0800 (PST) Date: Tue, 21 Jan 2025 22:23:32 -0800 In-Reply-To: <20250122062332.577009-1-irogers@google.com> Message-Id: <20250122062332.577009-18-irogers@google.com> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250122062332.577009-1-irogers@google.com> X-Mailer: git-send-email 2.48.0.rc2.279.g1de40edade-goog Subject: [PATCH v2 17/17] perf disasm: Make ins__scnprintf and ins__is_nop static From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Mark Rutland , Alexander Shishkin , Jiri Olsa , Ian Rogers , Adrian Hunter , Kan Liang , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Aditya Gupta , "Steinar H. Gunderson" , Charlie Jenkins , Changbin Du , "Masami Hiramatsu (Google)" , James Clark , Kajol Jain , Athira Rajeev , Li Huafei , Dmitry Vyukov , Andi Kleen , Chaitanya S Prakash , linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org, llvm@lists.linux.dev, Song Liu , bpf@vger.kernel.org Reduce the scope of ins__scnprintf and ins__is_nop that aren't used outside of disasm.c. Signed-off-by: Ian Rogers --- tools/perf/util/disasm.c | 6 +++--- tools/perf/util/disasm.h | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index ebd86691acf8..b2dfd40588ef 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -246,8 +246,8 @@ static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->raw); } -int ins__scnprintf(struct ins *ins, char *bf, size_t size, - struct ins_operands *ops, int max_ins_name) +static int ins__scnprintf(struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name) { if (ins->ops->scnprintf) return ins->ops->scnprintf(ins, bf, size, ops, max_ins_name); @@ -824,7 +824,7 @@ static struct ins_ops ret_ops = { .scnprintf = ins__raw_scnprintf, }; -bool ins__is_nop(const struct ins *ins) +static bool ins__is_nop(const struct ins *ins) { return ins->ops == &nop_ops; } diff --git a/tools/perf/util/disasm.h b/tools/perf/util/disasm.h index 2cb4e1a6bd30..09c86f540f7f 100644 --- a/tools/perf/util/disasm.h +++ b/tools/perf/util/disasm.h @@ -110,13 +110,10 @@ struct arch *arch__find(const char *name); bool arch__is(struct arch *arch, const char *name); struct ins_ops *ins__find(struct arch *arch, const char *name, struct disasm_line *dl); -int ins__scnprintf(struct ins *ins, char *bf, size_t size, - struct ins_operands *ops, int max_ins_name); bool ins__is_call(const struct ins *ins); bool ins__is_jump(const struct ins *ins); bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2); -bool ins__is_nop(const struct ins *ins); bool ins__is_ret(const struct ins *ins); bool ins__is_lock(const struct ins *ins);