From patchwork Mon Jun 17 17:58:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701131 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.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 2F47F1922DC for ; Mon, 17 Jun 2024 17:58:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647109; cv=none; b=pXylvAYACB25kSPFFuLdZhjYEWBXngeVmjAJ6azrdYW8em8AZ0iFXlgBZrqbl9mklEo0+4AKSq4w/4KD3M5IPoCEFs+mj2Nw7HJRCN1uZADAqv+5gZj573ZGs3ETUPiPmd0aYcUk8WexUNHvqQ7ztWhFbF6XOc0Bjs4mahCT0H4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647109; c=relaxed/simple; bh=Xs4KwoxMlQJYeEXm0rnpnTVWjgFyQKLzxA4GR17idpU=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=JJWNv0VkMUqD0tBgWHy01SH7AyAVjl8aWm4uK9F7Ztnkz4gGOyvZ758WYN0t6jZfUE8rKwBf+YWc4HFyqw5bkJSXo/aF3viasRQEwqty+FMnYCG2hNsw92FOve/xeeL31UV5VpS6wXeCcJ5sKMqBGAAuzLL1zoluL8tvrDj64BY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=pL+/eo/q; arc=none smtp.client-ip=209.85.214.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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="pL+/eo/q" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-1f87cb270e5so25821485ad.1 for ; Mon, 17 Jun 2024 10:58:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647107; x=1719251907; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=DUXYcBMIdUd+zaarsTS02Ok3bfGsgWGWrIF0wd751zk=; b=pL+/eo/q9WpkR/igK7yNuzL7KuAMqcL7l8PkUAuOPFWBORerAWmYC3qf84RFdsL+FK 49YKRMU92tPmi6D/bQKNeJV1hEhC2flF9AMcq7shuhfVd7WvSzzd3V4skfFVm128fe+t eyBcfcpAPSnjHM+Xqvdzj5C8BcIcCFuintprD2sqgNztfW80zExMobOPC3PMnudnayjp TCfaHomCwbVQvLBC80qE8q0BtliM8zqrLO8kBVl+COir+AEj8tN9gXM8Y104pbg9trr3 TjIy2SxrkLiWui3wvYGvcA8thKEyWVHqeS8rlEtCZdIH0YUSu0Nxx8m5eSfjybLKyTHA 0R5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647107; x=1719251907; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=DUXYcBMIdUd+zaarsTS02Ok3bfGsgWGWrIF0wd751zk=; b=ouRiWXIUhhWf6udfKOgOxrmzGHp4aQUK6jx4yrBCibpbRTlAACMqwZA11mDzx8JuHe enaOmnAmbwQRu0GJ4Y2YVg2kxiJndEO30OcMgvh7+1oD6nQCShz74qOb1oJVj9kFcrmf D/CATsFOuLtPrlQ79y5JQAr0hH3YrdHDoxpGUiyHb3lMLZ4xkuaDQCw6TqFrFT14SwYH csMo1gUNX0J9CtUGI5SowLAM9V/obh5aFvHKFb5luohkFVhdxVPUo9YaO/iHSwxSEzNv i2tHdKkFZIZcn89br+mFVx1h0/xuWOWtz1Ots5ZehzdpPRtpDbyhil7k+WA03YhzCVq9 2mEA== X-Forwarded-Encrypted: i=1; AJvYcCW3+bW+nmrxsm68qzlRcnAx3nehxDVjn9EjNjf+8klct5B6EHxOSO9FMuLc9n/Ljns4PT2LyvKmtKJrweV2YxiZqhDDckkk3T24G9PFIA== X-Gm-Message-State: AOJu0YzL3ZgJ4qGeOkIq+TDdpEiFFmkiiBeZs+AVhNHhANNbaNjkfRdt qXlBAHElLlP28TiEhx13LjAEQiOb/mDjIRorVF50eIwLsFnwPn+TLRhS6pOx3l6Yfp5PhDA1rvQ jqmq+w2viMrINkMM5MFhWy4nYfQ== X-Google-Smtp-Source: AGHT+IEA4cUUoJ3DpsCthdA+8I05uaHgHeN12zjF5sW6zMmJNlL+nFOI3fB/nnhyRIrUpruWLkHexG2JjXFqODJSEZg= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a17:903:1246:b0:1f4:8a2a:6394 with SMTP id d9443c01a7336-1f8627f336dmr9242265ad.8.1718647107293; Mon, 17 Jun 2024 10:58:27 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:20 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=13011; i=samitolvanen@google.com; h=from:subject; bh=Xs4KwoxMlQJYeEXm0rnpnTVWjgFyQKLzxA4GR17idpU=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk6od45vEuvdcIBwLiaolMBNrH8eaDDzYUua Gj3bki6kGyJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5OgAKCRBMtfaEi7xW 7q+/C/496QTbzCXL4tbdWN/11WLksSPbgTRoQFGVVj/ECkfhHQ8ojff7vlo8n0YGMzqKO2+tO0b kUQ2cAxy0xHGPtvXHo13CaMmIMbvgDcyDLLOtJc2FZ7HPlrgj5bNZ1D1udNTgEDv+AzB5dwIuJK +0ubgSZ8G/WDXDgFxJknTGTaoZgG0TJsLsgrY+TVuuRhVdK+etmCJ3V2hEiMTqd2PaSwt2g39lD QkcXZJ40xVgyZlIK5CAbMexlxbfmTnKzHl48dnYQQcS04TVGMaUSgax5cBgxsCu0uX2GVYy6g/x cmMxqCCG/WmdR9Qht2qLdp4k38iVOm1G1lbFq1jxYbSMASNawDmYAxvkFDvgyCxJ0r//NILJTMU RUYmuobzLnRjTxzwUY8mvjPAZ09piSoX/tqkrv6PDaPIC4mzuRysTdGXyMl+CdbUy5UmaLnR+ya ECxJpTk51Jx+9Ksgu88jIjI2lfc1wHw/ured/dV5YkFFALlQ4ei1d4o49roZFXsQ45p4M= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-18-samitolvanen@google.com> Subject: [PATCH 01/15] tools: Add gendwarfksyms From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Add a basic DWARF parser, which uses libdw to traverse the debugging information in an object file and looks for functions and variables. In follow-up patches, this will be expanded to produce symbol versions for CONFIG_MODVERSIONS from DWARF. This tool is needed mainly for Rust kernel module compatibility. Signed-off-by: Sami Tolvanen --- tools/Makefile | 11 +-- tools/gendwarfksyms/Build | 2 + tools/gendwarfksyms/Makefile | 49 +++++++++++ tools/gendwarfksyms/gendwarfksyms.c | 128 ++++++++++++++++++++++++++++ tools/gendwarfksyms/gendwarfksyms.h | 71 +++++++++++++++ tools/gendwarfksyms/types.c | 87 +++++++++++++++++++ 6 files changed, 343 insertions(+), 5 deletions(-) create mode 100644 tools/gendwarfksyms/Build create mode 100644 tools/gendwarfksyms/Makefile create mode 100644 tools/gendwarfksyms/gendwarfksyms.c create mode 100644 tools/gendwarfksyms/gendwarfksyms.h create mode 100644 tools/gendwarfksyms/types.c diff --git a/tools/Makefile b/tools/Makefile index 276f5d0d53a4..60806ff753b7 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -17,6 +17,7 @@ help: @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' @echo ' firmware - Firmware tools' @echo ' freefall - laptop accelerometer program for disk protection' + @echo ' gendwarfksyms - generates symbol versions from DWARF' @echo ' gpio - GPIO tools' @echo ' hv - tools used when in Hyper-V clients' @echo ' iio - IIO tools' @@ -68,7 +69,7 @@ acpi: FORCE cpupower: FORCE $(call descend,power/$@) -counter firewire hv guest bootconfig spi usb virtio mm bpf iio gpio objtool leds wmi pci firmware debugging tracing: FORCE +counter firewire hv guest bootconfig spi usb virtio mm bpf iio gendwarfksyms gpio objtool leds wmi pci firmware debugging tracing: FORCE $(call descend,$@) bpf/%: FORCE @@ -154,8 +155,8 @@ freefall_install: kvm_stat_install: $(call descend,kvm/$(@:_install=),install) -install: acpi_install counter_install cpupower_install gpio_install \ - hv_install firewire_install iio_install \ +install: acpi_install counter_install cpupower_install gendwarfksyms_install \ + gpio_install hv_install firewire_install iio_install \ perf_install selftests_install turbostat_install usb_install \ virtio_install mm_install bpf_install x86_energy_perf_policy_install \ tmon_install freefall_install objtool_install kvm_stat_install \ @@ -168,7 +169,7 @@ acpi_clean: cpupower_clean: $(call descend,power/cpupower,clean) -counter_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean mm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean tracing_clean: +counter_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean mm_clean wmi_clean bpf_clean iio_clean gendwarfksyms_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean tracing_clean: $(call descend,$(@:_clean=),clean) libapi_clean: @@ -211,7 +212,7 @@ build_clean: clean: acpi_clean counter_clean cpupower_clean hv_clean firewire_clean \ perf_clean selftests_clean turbostat_clean bootconfig_clean spi_clean usb_clean virtio_clean \ mm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \ - freefall_clean build_clean libbpf_clean libsubcmd_clean \ + freefall_clean build_clean libbpf_clean libsubcmd_clean gendwarfksyms_clean \ gpio_clean objtool_clean leds_clean wmi_clean pci_clean firmware_clean debugging_clean \ intel-speed-select_clean tracing_clean thermal_clean thermometer_clean thermal-engine_clean diff --git a/tools/gendwarfksyms/Build b/tools/gendwarfksyms/Build new file mode 100644 index 000000000000..805591b6df80 --- /dev/null +++ b/tools/gendwarfksyms/Build @@ -0,0 +1,2 @@ +gendwarfksyms-y += gendwarfksyms.o +gendwarfksyms-y += types.o diff --git a/tools/gendwarfksyms/Makefile b/tools/gendwarfksyms/Makefile new file mode 100644 index 000000000000..1138ebd8bd0f --- /dev/null +++ b/tools/gendwarfksyms/Makefile @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: GPL-2.0 +include ../scripts/Makefile.include +include ../scripts/Makefile.arch + +ifeq ($(srctree),) +srctree := $(patsubst %/,%,$(dir $(CURDIR))) +srctree := $(patsubst %/,%,$(dir $(srctree))) +endif + +GENDWARFKSYMS := $(OUTPUT)gendwarfksyms +GENDWARFKSYMS_IN := $(GENDWARFKSYMS)-in.o + +LIBDW_FLAGS := $(shell $(HOSTPKG_CONFIG) libdw --cflags 2>/dev/null) +LIBDW_LIBS := $(shell $(HOSTPKG_CONFIG) libdw --libs 2>/dev/null || echo -ldw -lelf) + +all: $(GENDWARFKSYMS) + +INCLUDES := -I$(srctree)/tools/include + +WARNINGS := -Wall -Wno-unused-value +GENDWARFKSYMS_CFLAGS := -Werror $(WARNINGS) $(KBUILD_HOSTCFLAGS) -g $(INCLUDES) $(LIBDW_FLAGS) +GENDWARFKSYMS_LDFLAGS := $(LIBDW_LIBS) $(KBUILD_HOSTLDFLAGS) + +# Always want host compilation. +HOST_OVERRIDES := CC="$(HOSTCC)" LD="$(HOSTLD)" AR="$(HOSTAR)" + +ifeq ($(V),1) + Q = +else + Q = @ +endif + +export srctree OUTPUT +include $(srctree)/tools/build/Makefile.include + +$(GENDWARFKSYMS_IN): FORCE + $(Q)$(MAKE) $(build)=gendwarfksyms $(HOST_OVERRIDES) CFLAGS="$(GENDWARFKSYMS_CFLAGS)" \ + LDFLAGS="$(GENDWARFKSYMS_LDFLAGS)" + + +$(GENDWARFKSYMS): $(GENDWARFKSYMS_IN) + $(QUIET_LINK)$(HOSTCC) $(GENDWARFKSYMS_IN) $(GENDWARFKSYMS_LDFLAGS) -o $@ + +clean: + $(call QUIET_CLEAN, gendwarfksyms) $(RM) $(GENDWARFKSYMS) + +FORCE: + +.PHONY: clean FORCE diff --git a/tools/gendwarfksyms/gendwarfksyms.c b/tools/gendwarfksyms/gendwarfksyms.c new file mode 100644 index 000000000000..4a2dea307849 --- /dev/null +++ b/tools/gendwarfksyms/gendwarfksyms.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2024 Google LLC + */ + +#include +#include +#include +#include +#include "gendwarfksyms.h" + +/* + * Options + */ + +/* Print type descriptions and debugging output to stderr */ +bool debug; + +static const struct { + const char *arg; + bool *flag; +} options[] = { + { "--debug", &debug }, +}; + +static int usage(void) +{ + error("usage: gendwarfksyms [options] elf-object-file < symbol-list"); + return -1; +} + +static int parse_options(int argc, const char **argv, const char **filename) +{ + *filename = NULL; + + for (int i = 1; i < argc; i++) { + bool found = false; + + for (int j = 0; j < ARRAY_SIZE(options); j++) { + if (!strcmp(argv[i], options[j].arg)) { + *options[j].flag = true; + found = true; + break; + } + } + + if (!found) { + if (!*filename) + *filename = argv[i]; + else + return -1; + } + } + + return *filename ? 0 : -1; +} + +static int process_modules(Dwfl_Module *mod, void **userdata, const char *name, + Dwarf_Addr base, void *arg) +{ + Dwarf_Addr dwbias; + Dwarf_Die cudie; + Dwarf_CU *cu = NULL; + Dwarf *dbg; + int res; + + debug("%s", name); + dbg = dwfl_module_getdwarf(mod, &dwbias); + + do { + res = dwarf_get_units(dbg, cu, &cu, NULL, NULL, &cudie, NULL); + if (res < 0) { + error("dwarf_get_units failed: no debugging information?"); + return -1; + } else if (res == 1) { + return DWARF_CB_OK; /* No more units */ + } + + check(process_module(mod, dbg, &cudie)); + } while (cu); + + return DWARF_CB_OK; +} + +static const Dwfl_Callbacks callbacks = { + .section_address = dwfl_offline_section_address, + .find_debuginfo = dwfl_standard_find_debuginfo, +}; + +int main(int argc, const char **argv) +{ + const char *filename = NULL; + Dwfl *dwfl; + int fd; + + if (parse_options(argc, argv, &filename) < 0) + return usage(); + + fd = open(filename, O_RDONLY); + if (fd == -1) { + error("open failed for '%s': %s", filename, strerror(errno)); + return -1; + } + + dwfl = dwfl_begin(&callbacks); + if (!dwfl) { + error("dwfl_begin failed for '%s': %s", filename, + dwarf_errmsg(-1)); + return -1; + } + + if (!dwfl_report_offline(dwfl, filename, filename, fd)) { + error("dwfl_report_offline failed for '%s': %s", filename, + dwarf_errmsg(-1)); + return -1; + } + + dwfl_report_end(dwfl, NULL, NULL); + + if (dwfl_getmodules(dwfl, &process_modules, NULL, 0)) { + error("dwfl_getmodules failed for '%s'", filename); + return -1; + } + + dwfl_end(dwfl); + + return 0; +} diff --git a/tools/gendwarfksyms/gendwarfksyms.h b/tools/gendwarfksyms/gendwarfksyms.h new file mode 100644 index 000000000000..44e94f1d9671 --- /dev/null +++ b/tools/gendwarfksyms/gendwarfksyms.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2024 Google LLC + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef __GENDWARFKSYMS_H +#define __GENDWARFKSYMS_H + +/* + * Options -- in gendwarfksyms.c + */ +extern bool debug; + +/* + * Output helpers + */ +#define __PREFIX "gendwarfksyms: " +#define __println(prefix, format, ...) \ + fprintf(stderr, prefix __PREFIX "%s: " format "\n", __func__, \ + ##__VA_ARGS__) + +#define debug(format, ...) \ + do { \ + if (debug) \ + __println("", format, ##__VA_ARGS__); \ + } while (0) + +#define warn(format, ...) __println("warning: ", format, ##__VA_ARGS__) +#define error(format, ...) __println("error: ", format, ##__VA_ARGS__) + +/* + * Error handling helpers + */ +#define check(expr) \ + ({ \ + int __res = expr; \ + if (__res < 0) { \ + error("`%s` failed: %d", #expr, __res); \ + return __res; \ + } \ + __res; \ + }) + +/* + * types.c + */ + +struct state { + Dwfl_Module *mod; + Dwarf *dbg; +}; + +typedef int (*die_callback_t)(struct state *state, Dwarf_Die *die); +typedef bool (*die_match_callback_t)(Dwarf_Die *die); +extern bool match_all(Dwarf_Die *die); + +extern int process_die_container(struct state *state, Dwarf_Die *die, + die_callback_t func, + die_match_callback_t match); + +extern int process_module(Dwfl_Module *mod, Dwarf *dbg, Dwarf_Die *cudie); + +#endif /* __GENDWARFKSYMS_H */ diff --git a/tools/gendwarfksyms/types.c b/tools/gendwarfksyms/types.c new file mode 100644 index 000000000000..2a8e45ae911c --- /dev/null +++ b/tools/gendwarfksyms/types.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2024 Google LLC + */ + +#include "gendwarfksyms.h" + +/* + * Type string processing + */ +static int process(struct state *state, const char *s) +{ + s = s ?: ""; + + if (debug) + fputs(s, stderr); + + return 0; +} + +bool match_all(Dwarf_Die *die) +{ + return true; +} + +int process_die_container(struct state *state, Dwarf_Die *die, + die_callback_t func, die_match_callback_t match) +{ + Dwarf_Die current; + int res; + + res = check(dwarf_child(die, ¤t)); + while (!res) { + if (match(¤t)) + check(func(state, ¤t)); + res = check(dwarf_siblingof(¤t, ¤t)); + } + + return 0; +} + +/* + * Symbol processing + */ +static int process_subprogram(struct state *state, Dwarf_Die *die) +{ + return check(process(state, "subprogram;\n")); +} + +static int process_variable(struct state *state, Dwarf_Die *die) +{ + return check(process(state, "variable;\n")); +} + +static int process_exported_symbols(struct state *state, Dwarf_Die *die) +{ + int tag = dwarf_tag(die); + + switch (tag) { + /* Possible containers of exported symbols */ + case DW_TAG_namespace: + case DW_TAG_class_type: + case DW_TAG_structure_type: + return check(process_die_container( + state, die, process_exported_symbols, match_all)); + + /* Possible exported symbols */ + case DW_TAG_subprogram: + case DW_TAG_variable: + if (tag == DW_TAG_subprogram) + check(process_subprogram(state, die)); + else + check(process_variable(state, die)); + + return 0; + default: + return 0; + } +} + +int process_module(Dwfl_Module *mod, Dwarf *dbg, Dwarf_Die *cudie) +{ + struct state state = { .mod = mod, .dbg = dbg }; + + return check(process_die_container( + &state, cudie, process_exported_symbols, match_all)); +} From patchwork Mon Jun 17 17:58:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701132 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.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 16DB0194A7A for ; Mon, 17 Jun 2024 17:58:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647111; cv=none; b=CqmhyMxsH2QamGwaAKYxYCeEkVSuLMK9KukG1UauhaxS7D0/utuYzsYSUz3KeSQwfqRoVaXro9PQsTE6hmAYakQMGnscaJqgMWgQkcu2luwI+0lGnRSDOWuGJxAhQ2/ktFrPW6HhVC+GEHgdIDlRsJiHQaEOMCuxwxCuT4tmnE8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647111; c=relaxed/simple; bh=xEYsXEZcuwwhUBMDlUBf1X1yPVPLH2iuty1W6//7LKE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=VKNR+Jn+EjHSp/qY5HeKDG90pqnpt+0svAoHGJ0JJmX2TGJP5YmwPYCL+N1708ie4yLWW3kSi36d4Qu0ii9nNigI/xSpsNz1atAz8imDPplzkBPXN4cKYIgUPkJeihISI+hLt9XtKsuytHGbdPorXZlTG70SD2H0i2Ykngel4KQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=YsK0k5r9; arc=none smtp.client-ip=209.85.214.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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="YsK0k5r9" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-1f844f8a565so49098235ad.0 for ; Mon, 17 Jun 2024 10:58:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647109; x=1719251909; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=X3E8V7gmLyohlBlm4SnFOe783c56Xkz1mRG3vn3a+Cc=; b=YsK0k5r9C8Q57thtCDVipAKCZbXoOQDonsoFbHteE8LIK4lSMjpHQDertfZFR+cgoY Fm+jwHlC8tqZ8S49bXRGHuYP75sHRJ8+6hSPTh4req5aGp/AzAjmbAU79lw5pEDpsctk YXURUc8rRQA4w+LOpQqN7aRaPxO32BK+4XTTPoDawoSwlQt33cZq79lBB50OyfRdatiR gdn4mtvQblBaKI5wV1nFbxa9WvkMQmk0U4oMd6NO3FhCvLbXTG7Ac8RNzSjRcC/6BCRV /V6NutKjzpUofZ/Awm7bsi7IjLtOrDHgI7qvb0frN7HdvRAzhUKLCAW7vKflpJxdiWQK pCfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647109; x=1719251909; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=X3E8V7gmLyohlBlm4SnFOe783c56Xkz1mRG3vn3a+Cc=; b=JAFGktlMgkTDQRpTYvB6+8h+6FHXpH6fje+JGDS02u5uCIq6ZhqdErd0c6hg3xQFnl lVasS3AU9vqgY9dlvo/jTOq1VE3OG99PUfz1AjcO3wZ3AnGjGZXTt71Bsc9S9Ag8WYtk PfO8eMVJfQ6trc+b7Xns5gy7P7MdT4UXiQf/HQB5cdIvzVrUXprl4KddIlEqvnwjBK7d AyIJRpevxM/5x/2P5wjE2OUbKLLNv5bPbHK2XiEd6oSTmLw1V5/9tJ4WwxT997zqV7Cn zbtn2HympUoonbID/yukpmT/kczmFfAfySMLoZ2QgUtXDgmZljpRLZIUbSlVMun9SDLR GsDA== X-Forwarded-Encrypted: i=1; AJvYcCUpRb2+mZ1UbdLxLoBsnEqPmcuJM8p3+qN+7RNOMiJBOR8u4UhMB8YrZH+aOMqmoml48HTO1w41CVdf7+LsXBwban8svQU1mWJNmlyOpg== X-Gm-Message-State: AOJu0Yx0rLZZVOHH8div4ZxUt3Ueo/0uupocGEQGeScZWaGX3qZ5QLQs 6otRS8RGcxSgtlKUTQEI8fe1j1vLtbU/cDzT+ARLiOfezKeOu0w5f6g+4FEMZs+yg/x7sz31q59 IYc3pTNupz2ssOF+AQOkdL5aesw== X-Google-Smtp-Source: AGHT+IHsjSrwOS0Wj6w6liPWf1kv/uqSpoF2WSPbUclGM+sXDYGYNn9as+p2jf2d8vSq09tsOBsmTenxf4MfLYAt/8U= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a17:902:f601:b0:1f7:3e75:20cf with SMTP id d9443c01a7336-1f8627f9149mr763355ad.8.1718647109252; Mon, 17 Jun 2024 10:58:29 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:21 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=8432; i=samitolvanen@google.com; h=from:subject; bh=xEYsXEZcuwwhUBMDlUBf1X1yPVPLH2iuty1W6//7LKE=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk6sng5HUOoC/7PBTpSTIHLFp+zaKAkdN/PD 3Pay0BzSciJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5OgAKCRBMtfaEi7xW 7koJDACqAdbqz0N0fPaklN5axIJo9/W9Atwvp0ZtvnO5B+8ZSkl8hLF9tJF8YaTMbGIPAIgULmX tXuCuZhhOFCsrwYfYWyNzpV0RZtSqSckWGdcfLG/4+Q0rJMsoWiyorxsh8X54Ehb7ZFqDHT7o1G CV6edtc+Rei2jiOR5ABAcdA7yHSl+folJT//qII8uXNRbiJHhOcf7a0is7s/xm9lHmpwvyFTVlI KF7FJHEEDEG/YI8ahPtKcio1JOkDCT+ND0/9dJC63lqVS+tfIbXYnojkFXheNpIQrbWEs+2O94Z rntIqvvWvAL72TXg/Ql6xxP7MCzhBK9F5Z7SrnO+Udd1gWnlf0EEoSLlpSg+E30RZfZFA5Rhvqa KvzYrtFSDuHSa3RtyyoHxyiM0lvLH3Al8UfmyEi16bs/ZYzXLXJEFhuKmlGLn2iLYHDXwBO0vEY NjpQWUn8TPfGSaB+VuU/0jJ5acQASB7dzw692q9U+bcth9TAnJNazvVU5+QQOWcZPJK2k= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-19-samitolvanen@google.com> Subject: [PATCH 02/15] gendwarfksyms: Add symbol list input handling From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Support passing a list of exported symbols to gendwarfksyms via stdin and filter non-exported symbols from the output. The symbol list input has the format 'symbol-address symbol-name' to allow the parser to discover exported symbols also by address. This is necessary for aliased symbols, where only one name appears in the debugging information. Signed-off-by: Sami Tolvanen --- tools/gendwarfksyms/Build | 1 + tools/gendwarfksyms/gendwarfksyms.c | 2 + tools/gendwarfksyms/gendwarfksyms.h | 17 ++++ tools/gendwarfksyms/symbols.c | 130 ++++++++++++++++++++++++++++ tools/gendwarfksyms/types.c | 70 ++++++++++++++- 5 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 tools/gendwarfksyms/symbols.c diff --git a/tools/gendwarfksyms/Build b/tools/gendwarfksyms/Build index 805591b6df80..a83c59bfef8b 100644 --- a/tools/gendwarfksyms/Build +++ b/tools/gendwarfksyms/Build @@ -1,2 +1,3 @@ gendwarfksyms-y += gendwarfksyms.o +gendwarfksyms-y += symbols.o gendwarfksyms-y += types.o diff --git a/tools/gendwarfksyms/gendwarfksyms.c b/tools/gendwarfksyms/gendwarfksyms.c index 4a2dea307849..4a1bd9239182 100644 --- a/tools/gendwarfksyms/gendwarfksyms.c +++ b/tools/gendwarfksyms/gendwarfksyms.c @@ -96,6 +96,8 @@ int main(int argc, const char **argv) if (parse_options(argc, argv, &filename) < 0) return usage(); + check(symbol_read_list(stdin)); + fd = open(filename, O_RDONLY); if (fd == -1) { error("open failed for '%s': %s", filename, strerror(errno)); diff --git a/tools/gendwarfksyms/gendwarfksyms.h b/tools/gendwarfksyms/gendwarfksyms.h index 44e94f1d9671..b77855cc94a7 100644 --- a/tools/gendwarfksyms/gendwarfksyms.h +++ b/tools/gendwarfksyms/gendwarfksyms.h @@ -49,6 +49,21 @@ extern bool debug; __res; \ }) +/* + * symbols.c + */ + +/* Exported symbol -- matching either the name or the address */ +struct symbol { + const char *name; + uintptr_t addr; + struct hlist_node addr_hash; + struct hlist_node name_hash; +}; + +extern int symbol_read_list(FILE *file); +extern struct symbol *symbol_get(uintptr_t addr, const char *name); + /* * types.c */ @@ -56,6 +71,8 @@ extern bool debug; struct state { Dwfl_Module *mod; Dwarf *dbg; + struct symbol *sym; + Dwarf_Die origin; }; typedef int (*die_callback_t)(struct state *state, Dwarf_Die *die); diff --git a/tools/gendwarfksyms/symbols.c b/tools/gendwarfksyms/symbols.c new file mode 100644 index 000000000000..2cae61bcede7 --- /dev/null +++ b/tools/gendwarfksyms/symbols.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2024 Google LLC + */ + +#include +#include +#include "gendwarfksyms.h" + +/* Hash tables for looking up requested symbols by address and name */ +#define SYMBOL_HASH_BITS 7 +DEFINE_HASHTABLE(symbol_addrs, SYMBOL_HASH_BITS); +DEFINE_HASHTABLE(symbol_names, SYMBOL_HASH_BITS); + +static u32 name_hash(const char *name) +{ + return jhash(name, strlen(name), 0); +} + +/* symbol_for_each callback -- return true to stop, false to continue */ +typedef bool (*symbol_callback_t)(struct symbol *, void *arg); + +static bool for_each_addr(uintptr_t addr, symbol_callback_t func, void *data) +{ + struct symbol *sym; + bool found = false; + + if (addr == UINTPTR_MAX) + return false; + + hash_for_each_possible(symbol_addrs, sym, addr_hash, addr) { + if (sym->addr == addr) { + if (func(sym, data)) + return true; + found = true; + } + } + + return found; +} + +static bool for_each_name(const char *name, symbol_callback_t func, void *data) +{ + struct symbol *sym; + bool found = false; + + if (!name) + return false; + + hash_for_each_possible(symbol_names, sym, name_hash, name_hash(name)) { + if (!strcmp(sym->name, name)) { + if (func(sym, data)) + return true; + found = true; + } + } + + return found; +} + +static bool for_each(uintptr_t addr, const char *name, symbol_callback_t func, + void *data) +{ + bool found = false; + + if (for_each_addr(addr, func, data)) + found = true; + if (for_each_name(name, func, data)) + found = true; + + return found; +} + +int symbol_read_list(FILE *file) +{ + struct symbol *sym; + char *line = NULL; + char *name = NULL; + uint64_t addr; + size_t size = 0; + + while (getline(&line, &size, file) > 0) { + if (sscanf(line, "%" PRIx64 " %ms\n", &addr, &name) != 2) { + error("malformed input line (expected 'address symbol-name'): %s", + line); + return -1; + } + + free(line); + line = NULL; + + sym = malloc(sizeof(struct symbol)); + if (!sym) { + error("malloc failed"); + return -1; + } + + debug("adding { %lx, \"%s\" }", addr, name); + + sym->addr = (uintptr_t)addr; + sym->name = name; + name = NULL; + + hash_add(symbol_addrs, &sym->addr_hash, sym->addr); + hash_add(symbol_names, &sym->name_hash, name_hash(sym->name)); + } + + if (line) + free(line); + + return 0; +} + +static bool return_symbol(struct symbol *sym, void *arg) +{ + struct symbol **res = (struct symbol **)arg; + + *res = sym; + return true; /* Stop -- return the first match */ +} + +struct symbol *symbol_get(uintptr_t addr, const char *name) +{ + struct symbol *sym; + + if (for_each(addr, name, return_symbol, &sym)) + return sym; + + return NULL; +} diff --git a/tools/gendwarfksyms/types.c b/tools/gendwarfksyms/types.c index 2a8e45ae911c..f1ce7bfcf510 100644 --- a/tools/gendwarfksyms/types.c +++ b/tools/gendwarfksyms/types.c @@ -5,6 +5,68 @@ #include "gendwarfksyms.h" +#define DEFINE_GET_ATTR(attr, type) \ + static bool get_##attr##_attr(Dwarf_Die *die, unsigned int id, \ + type *value) \ + { \ + Dwarf_Attribute da; \ + return dwarf_attr(die, id, &da) && \ + !dwarf_form##attr(&da, value); \ + } + +DEFINE_GET_ATTR(addr, Dwarf_Addr) + +static bool get_ref_die_attr(Dwarf_Die *die, unsigned int id, Dwarf_Die *value) +{ + Dwarf_Attribute da; + + /* dwarf_formref_die returns a pointer instead of an error value. */ + return dwarf_attr(die, id, &da) && dwarf_formref_die(&da, value); +} + +static const char *get_name(Dwarf_Die *die) +{ + Dwarf_Attribute attr; + + /* rustc uses DW_AT_linkage_name for exported symbols */ + if (dwarf_attr(die, DW_AT_linkage_name, &attr) || + dwarf_attr(die, DW_AT_name, &attr)) { + return dwarf_formstring(&attr); + } + + return NULL; +} + +static Dwarf_Die *get_exported(struct state *state, Dwarf_Die *die) +{ + Dwarf_Die *origin = NULL; + Dwarf_Word addr = UINTPTR_MAX; + + state->sym = NULL; + + /* If the DIE has an abstract origin, use it for type expansion. */ + if (get_ref_die_attr(die, DW_AT_abstract_origin, &state->origin)) + origin = &state->origin; + + /* + * Only one name is emitted for aliased functions, so we must match + * the address too, if available. + */ + if (get_addr_attr(die, DW_AT_low_pc, &addr) && + dwfl_module_relocate_address(state->mod, &addr) < 0) { + error("dwfl_module_relocate_address failed"); + return NULL; + } + + state->sym = symbol_get(addr, get_name(die)); + + /* Look up using the origin name if there are no matches. */ + if (!state->sym && origin) + state->sym = symbol_get(addr, get_name(origin)); + + return origin ? origin : die; +} + /* * Type string processing */ @@ -40,7 +102,7 @@ int process_die_container(struct state *state, Dwarf_Die *die, } /* - * Symbol processing + * Exported symbol processing */ static int process_subprogram(struct state *state, Dwarf_Die *die) { @@ -67,6 +129,12 @@ static int process_exported_symbols(struct state *state, Dwarf_Die *die) /* Possible exported symbols */ case DW_TAG_subprogram: case DW_TAG_variable: + die = get_exported(state, die); + if (!die || !state->sym) + return 0; + + debug("%s (@ %lx)", state->sym->name, state->sym->addr); + if (tag == DW_TAG_subprogram) check(process_subprogram(state, die)); else From patchwork Mon Jun 17 17:58:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701133 Received: from mail-pl1-f201.google.com (mail-pl1-f201.google.com [209.85.214.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 001E6196D9E for ; Mon, 17 Jun 2024 17:58:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647113; cv=none; b=XYqy+5DBXbw5ZMq2KUKyJXciVRPhKnhQ84nQExZINIVnVC8BIXJX1RL6d8M2pr5VYTSe0YD+jXRMU0scHZTLnHK5c/fkdKQ0yYTOMgbWzeA+FFG3FynEuXAfRGv4v7LPg5pBu4zIAkqp3yXMHG+hnD9EyekqruWGJc/p2A3w1YA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647113; c=relaxed/simple; bh=fbwuwqk6CBs6GxSLKW1YVstmYpQxC2PKUQTmM9ZWc3Y=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=PCn2DPxSoXaic7B8kIm3UJjW0pXRgRtRJLjmzf8HG1cNJDLkA1e16DzAkUiHzDo0YSGZ1R7QIsI8ksc+ArCg5TZkve3pU6JY3VlO08itKKC/NxLKq5K6Cv6qtZifmxmJSZxfP+LHujWLzxxnSgdX7PTp+oHkTLZFX76oVWWJZBo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=eitwI3sh; arc=none smtp.client-ip=209.85.214.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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="eitwI3sh" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-1f72c0c4529so40386455ad.3 for ; Mon, 17 Jun 2024 10:58:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647111; x=1719251911; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=3yQQ8muIrU64lKPhl98I11AYavN8wWVSXjeR/8aXPik=; b=eitwI3shRewtdSV6/OF5GwOcnTvODTfhuF+nekKiz05AEq02eCLZsFsxcZa6Y2rNO5 gcQL7EvbvcGssNj74GADc1ZiVs2/jrOEveU8Ymcqv0/a0Ld/P6Dei2QkrXcLqNfgbq7F bJdjILsBGVdLjzbiYgNPyrAF/4GYE7MBmv10OF2/kkvaxczp4/BcHsPjtJrl/gL/ez4z HfSqvprY6qw9rpGZYdatZ1sGagPBsWemO4ThuGcc7vgwEESzDmcuS4KerXcztAqgtyW6 EXpBX1tWfA1MQdmuk0X6Qgi3M0hOziSyzXM8fT4Ic1+Z743BuGT9d0DbaJ+vqhoWWXB4 GCXA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647111; x=1719251911; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=3yQQ8muIrU64lKPhl98I11AYavN8wWVSXjeR/8aXPik=; b=EcDz+D65VChYtFOwjUGUmP4drV96bGRlHbUDra3Y27P2cgafl4f074SJmyMKCH76cS 6j5j2QiHNmthZzWK+Ew5atX0yVyRB6Lsf+V6avP2O2MGc0ZVfUFrwywofjR76ygEzDSy v/lOipX5Tcv5swca7MF7hszW4CGoRD9JBB/+ntvmhMbtg4yAaMvVIuPUNBXoPtM+Plvw KGBuQ4X3DW5OWOEGonZ3UVewg5BzBgmyMFjTwermv/q1WGMHY5SYfixrYVSj95bm7Qpt 7EvaPmERmEi0reLImpEoI9AIP4JQlrdVqTjkc4pp9Q+kaMlF1+xWN/MKW9l1yG7LwXCr 87zA== X-Forwarded-Encrypted: i=1; AJvYcCVM+z5Oc0Nl9J7F4XqFQhQFPwQPcYlE8YW5fPT4IlLXAf/czEEGA8K4lfJGEpQDRjYeJjo+Sr2dVf51tk6Zk9+Qo42OPAJUxXmLSiT8mg== X-Gm-Message-State: AOJu0YxPsp4GnzoaWomv0CoPyJnYcbfzB9APOL2hmTrk/HeSFERY9uG9 XT0mi0jsDYmx0o6OQR+wbldxu0Lu4/zEnT3olTqE6QCMEZrS8CMj36LqtrXl6MXPRhvSx/QCDgz mXYdCQ8rzfkRPteGIplH99fHDWw== X-Google-Smtp-Source: AGHT+IFK8KoS179LjP4Kh2WPYtoL4z47JnrJOp2742SzH3XkeLnWMFebk1mDJfKA5lS/HKcLScCvGfD9qICWKoeLaJY= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a17:903:187:b0:1f6:5631:4eb4 with SMTP id d9443c01a7336-1f862806058mr4168515ad.10.1718647111118; Mon, 17 Jun 2024 10:58:31 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:22 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=13960; i=samitolvanen@google.com; h=from:subject; bh=fbwuwqk6CBs6GxSLKW1YVstmYpQxC2PKUQTmM9ZWc3Y=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk6W7swSMlMXEfHHZ4lDet9yNrknEg65M0/F kJ95lvbatGJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5OgAKCRBMtfaEi7xW 7o2RDACryqWKB0s4mkpnv7sidxnwYF/2IZ7pM9CR+UnhHvbTmVWJWEz/vxUw7ewA/CVqHM7yEfH 0xju2BYdvgQyJCw7Z+QbKtQXw6wfzJZVmjZQfDR2g19sv4OAxVjB8uY6QiC6veeyHbA9zeELh/n SNLvcrgEjjkEjGuyFETAomolBAGnPfbm8wBsApAPs5qUiYBslRZ6+AVeNlxqD2tetw88zxn0KGC H1ihgqDx452proTcjdmQZ6YRIfOan6lpNx4sQ2o1hnaYkDNVe2Yw2YFeJJFqSml3zfC1CK5elma RZaZ45QdCNFGuYJfmuolIhZiY1OH5Ur+oP7yF13xWAIphvOYSBAfwtuvu4RdN+iI8qK/FVzxkOn QCA9xh29HUjiH+Ef2DncDSwbeB47+W9PLR3Aw9EwVRkMvZirfYig7pVP6yZcpC4JqvAlSiOPdgD 1GMr38SUX0Nsn3ojyyAsUWkrgzcbp1pgsvsbzHZbdYTJRcEzQE4rrLVV3CR6tiESWI2co= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-20-samitolvanen@google.com> Subject: [PATCH 03/15] gendwarfksyms: Add CRC calculation From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Add a basic CRC32 implementation adapted from genksyms, and produce matching output from type strings. Example usage: $ nm -p --defined-only rust/alloc.o | \ awk '/ (T|R|D) / {printf "%s %s\n",$1, $3}' | \ tools/gendwarfksyms/gendwarfksyms rust/alloc.o Output: #SYMVER _RNvNvMs_NtCscg2doA4GLaz_5alloc3vecINtB6_3VecppE11swap_remove13assert_failed 0x985f94dd #SYMVER _RNvXs1_NtCscg2doA4GLaz_5alloc11collectionsNtB5_15TryReserveErrorNtNtCs5QSdWC790r4_4core3fmt7Display3fmt 0x985f94dd #SYMVER _RNvNvMs_NtCscg2doA4GLaz_5alloc3vecINtB6_3VecppE6remove13assert_failed 0x985f94dd ... Note that type strings are not yet expanded, so the CRCs can only distinguish between functions and variables for now. Signed-off-by: Sami Tolvanen --- tools/gendwarfksyms/Build | 1 + tools/gendwarfksyms/crc32.c | 69 ++++++++++++++++++++++++++++ tools/gendwarfksyms/crc32.h | 34 ++++++++++++++ tools/gendwarfksyms/gendwarfksyms.c | 1 + tools/gendwarfksyms/gendwarfksyms.h | 6 +++ tools/gendwarfksyms/symbols.c | 71 +++++++++++++++++++++++++++-- tools/gendwarfksyms/types.c | 19 ++++++-- 7 files changed, 194 insertions(+), 7 deletions(-) create mode 100644 tools/gendwarfksyms/crc32.c create mode 100644 tools/gendwarfksyms/crc32.h diff --git a/tools/gendwarfksyms/Build b/tools/gendwarfksyms/Build index a83c59bfef8b..518642c9b9de 100644 --- a/tools/gendwarfksyms/Build +++ b/tools/gendwarfksyms/Build @@ -1,3 +1,4 @@ gendwarfksyms-y += gendwarfksyms.o +gendwarfksyms-y += crc32.o gendwarfksyms-y += symbols.o gendwarfksyms-y += types.o diff --git a/tools/gendwarfksyms/crc32.c b/tools/gendwarfksyms/crc32.c new file mode 100644 index 000000000000..23b328cd74f2 --- /dev/null +++ b/tools/gendwarfksyms/crc32.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Based on scripts/genksyms/genksyms.c, which has the following + * notice: + * + * Generate kernel symbol version hashes. + * Copyright 1996, 1997 Linux International. + * + * New implementation contributed by Richard Henderson + * Based on original work by Bjorn Ekwall + * + * This file was part of the Linux modutils 2.4.22: moved back into the + * kernel sources by Rusty Russell/Kai Germaschewski. + */ + +const unsigned int crctab32[] = { + 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U, + 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U, + 0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, + 0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, + 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U, + 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U, + 0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, + 0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, + 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U, + 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU, + 0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, + 0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, + 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U, + 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU, + 0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, + 0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, + 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU, + 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U, + 0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, + 0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, + 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU, + 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U, + 0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U, + 0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, + 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U, + 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U, + 0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U, + 0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, + 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U, + 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU, + 0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, + 0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, + 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U, + 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU, + 0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, + 0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, + 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU, + 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U, + 0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, + 0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, + 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU, + 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U, + 0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, + 0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, + 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U, + 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U, + 0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, + 0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, + 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U, + 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U, + 0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, + 0x2d02ef8dU +}; diff --git a/tools/gendwarfksyms/crc32.h b/tools/gendwarfksyms/crc32.h new file mode 100644 index 000000000000..89e4454b2a70 --- /dev/null +++ b/tools/gendwarfksyms/crc32.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Based on scripts/genksyms/genksyms.c, which has the following + * notice: + * + * Generate kernel symbol version hashes. + * Copyright 1996, 1997 Linux International. + * + * New implementation contributed by Richard Henderson + * Based on original work by Bjorn Ekwall + * + * This file was part of the Linux modutils 2.4.22: moved back into the + * kernel sources by Rusty Russell/Kai Germaschewski. + */ + +#ifndef __CRC32_H +#define __CRC32_H + +extern const unsigned int crctab32[]; + +static inline unsigned long partial_crc32_one(unsigned char c, + unsigned long crc) +{ + return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8); +} + +static inline unsigned long partial_crc32(const char *s, unsigned long crc) +{ + while (*s) + crc = partial_crc32_one(*s++, crc); + return crc; +} + +#endif /* __CRC32_H */ diff --git a/tools/gendwarfksyms/gendwarfksyms.c b/tools/gendwarfksyms/gendwarfksyms.c index 4a1bd9239182..7938b7440674 100644 --- a/tools/gendwarfksyms/gendwarfksyms.c +++ b/tools/gendwarfksyms/gendwarfksyms.c @@ -125,6 +125,7 @@ int main(int argc, const char **argv) } dwfl_end(dwfl); + symbol_print_versions(); return 0; } diff --git a/tools/gendwarfksyms/gendwarfksyms.h b/tools/gendwarfksyms/gendwarfksyms.h index b77855cc94a7..7440f1c73500 100644 --- a/tools/gendwarfksyms/gendwarfksyms.h +++ b/tools/gendwarfksyms/gendwarfksyms.h @@ -52,17 +52,22 @@ extern bool debug; /* * symbols.c */ +enum symbol_state { UNPROCESSED, PROCESSED_ADDR, PROCESSED_NAME }; /* Exported symbol -- matching either the name or the address */ struct symbol { const char *name; uintptr_t addr; + enum symbol_state state; + unsigned long crc; struct hlist_node addr_hash; struct hlist_node name_hash; }; +extern int symbol_set_crc(struct symbol *sym, unsigned long crc); extern int symbol_read_list(FILE *file); extern struct symbol *symbol_get(uintptr_t addr, const char *name); +extern void symbol_print_versions(void); /* * types.c @@ -73,6 +78,7 @@ struct state { Dwarf *dbg; struct symbol *sym; Dwarf_Die origin; + unsigned long crc; }; typedef int (*die_callback_t)(struct state *state, Dwarf_Die *die); diff --git a/tools/gendwarfksyms/symbols.c b/tools/gendwarfksyms/symbols.c index 2cae61bcede7..71029635fc83 100644 --- a/tools/gendwarfksyms/symbols.c +++ b/tools/gendwarfksyms/symbols.c @@ -18,7 +18,8 @@ static u32 name_hash(const char *name) } /* symbol_for_each callback -- return true to stop, false to continue */ -typedef bool (*symbol_callback_t)(struct symbol *, void *arg); +typedef bool (*symbol_callback_t)(struct symbol *, enum symbol_state type, + void *arg); static bool for_each_addr(uintptr_t addr, symbol_callback_t func, void *data) { @@ -30,7 +31,7 @@ static bool for_each_addr(uintptr_t addr, symbol_callback_t func, void *data) hash_for_each_possible(symbol_addrs, sym, addr_hash, addr) { if (sym->addr == addr) { - if (func(sym, data)) + if (func(sym, PROCESSED_ADDR, data)) return true; found = true; } @@ -49,7 +50,7 @@ static bool for_each_name(const char *name, symbol_callback_t func, void *data) hash_for_each_possible(symbol_names, sym, name_hash, name_hash(name)) { if (!strcmp(sym->name, name)) { - if (func(sym, data)) + if (func(sym, PROCESSED_NAME, data)) return true; found = true; } @@ -71,6 +72,45 @@ static bool for_each(uintptr_t addr, const char *name, symbol_callback_t func, return found; } +static bool set_crc(struct symbol *sym, enum symbol_state type, void *data) +{ + unsigned long *crc = data; + + /* Prefer an address match if found, otherwise match by name. */ + if (type == PROCESSED_ADDR) { + if (sym->state == PROCESSED_ADDR) { + warn("symbol %s (@ %lx) already matched by address (crc %lx vs. %lx)", + sym->name, sym->addr, sym->crc, *crc); + return false; + } + if (sym->state == PROCESSED_NAME && sym->crc != *crc) + debug("symbol %s (@ %lx) overriding name match (crc %lx vs. %lx)", + sym->name, sym->addr, sym->crc, *crc); + } else if (type == PROCESSED_NAME) { + if (sym->state == PROCESSED_ADDR) { + if (sym->crc != *crc) + debug("symbol %s (@ %lx) ignoring name match (crc %lx vs. %lx)", + sym->name, sym->addr, sym->crc, *crc); + return false; + } + if (sym->state == PROCESSED_NAME) { + warn("symbol %s (@ %lx) already matched by name (crc %lx vs. %lx)", + sym->name, sym->addr, sym->crc, *crc); + return false; + } + } + + sym->state = type; + sym->crc = *crc; + + return false; /* Continue */ +} + +int symbol_set_crc(struct symbol *sym, unsigned long crc) +{ + return for_each(sym->addr, sym->name, set_crc, &crc) ? 0 : -1; +} + int symbol_read_list(FILE *file) { struct symbol *sym; @@ -99,6 +139,8 @@ int symbol_read_list(FILE *file) sym->addr = (uintptr_t)addr; sym->name = name; + sym->state = UNPROCESSED; + sym->crc = 0; name = NULL; hash_add(symbol_addrs, &sym->addr_hash, sym->addr); @@ -111,7 +153,7 @@ int symbol_read_list(FILE *file) return 0; } -static bool return_symbol(struct symbol *sym, void *arg) +static bool return_symbol(struct symbol *sym, enum symbol_state type, void *arg) { struct symbol **res = (struct symbol **)arg; @@ -128,3 +170,24 @@ struct symbol *symbol_get(uintptr_t addr, const char *name) return NULL; } + +void symbol_print_versions(void) +{ + struct hlist_node *tmp; + struct symbol *sym; + int i; + + hash_for_each_safe(symbol_addrs, i, tmp, sym, addr_hash) { + if (sym->state == UNPROCESSED) + warn("no information for symbol %s (@ %lx)", sym->name, + sym->addr); + + printf("#SYMVER %s 0x%08lx\n", sym->name, sym->crc); + + free((void *)sym->name); + free(sym); + } + + hash_init(symbol_addrs); + hash_init(symbol_names); +} diff --git a/tools/gendwarfksyms/types.c b/tools/gendwarfksyms/types.c index f1ce7bfcf510..47ae967d42ee 100644 --- a/tools/gendwarfksyms/types.c +++ b/tools/gendwarfksyms/types.c @@ -4,6 +4,7 @@ */ #include "gendwarfksyms.h" +#include "crc32.h" #define DEFINE_GET_ATTR(attr, type) \ static bool get_##attr##_attr(Dwarf_Die *die, unsigned int id, \ @@ -68,7 +69,7 @@ static Dwarf_Die *get_exported(struct state *state, Dwarf_Die *die) } /* - * Type string processing + * Type string and CRC processing */ static int process(struct state *state, const char *s) { @@ -77,6 +78,7 @@ static int process(struct state *state, const char *s) if (debug) fputs(s, stderr); + state->crc = partial_crc32(s, state->crc); return 0; } @@ -101,6 +103,11 @@ int process_die_container(struct state *state, Dwarf_Die *die, return 0; } +static void state_init(struct state *state) +{ + state->crc = 0xffffffff; +} + /* * Exported symbol processing */ @@ -130,17 +137,23 @@ static int process_exported_symbols(struct state *state, Dwarf_Die *die) case DW_TAG_subprogram: case DW_TAG_variable: die = get_exported(state, die); - if (!die || !state->sym) + if (!die || !state->sym || state->sym->state != UNPROCESSED) return 0; + /* + * For each exported symbol, compute a CRC of the expanded type + * description. + */ debug("%s (@ %lx)", state->sym->name, state->sym->addr); + state_init(state); if (tag == DW_TAG_subprogram) check(process_subprogram(state, die)); else check(process_variable(state, die)); - return 0; + return check( + symbol_set_crc(state->sym, state->crc ^ 0xffffffff)); default: return 0; } From patchwork Mon Jun 17 17:58:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701134 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 C0708197A95 for ; Mon, 17 Jun 2024 17:58:33 +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=1718647115; cv=none; b=dd4khXZUhmvI9d6J5siqNgf27LKWDD8cxd0z7LbVMWI279caUFd+oTW4c2/y287qpxkqm8D13ai+ycXD04AzfBjGfCtxVoQXsGxFNAEEuQYmXit+yWYcYlMRZPur/9TNqDzO/IM1K33icUyxzxEeaGWnX75ONGAivBA4RkbkxlA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647115; c=relaxed/simple; bh=n0WO328t/R/22oR4dAFfOzsZotv9Vy1BGsad/Gul6sE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=T62TWhCsyJhaLhJE87eBTWPFDRMN2pFHfo/XFLxN3xOKMfn7sJcsTtOxyflheUhoU0qi2arIdjDUO6qxV5AqTYoPNqO2GtSY+tXTBD3gh+LUa3Wzeyjs0OK8vC1xaZ1CfXMSg2upcuMilxJ9Uh6+M0fTWOx9e8mgTOGsKYUISZE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=0dB5/dc7; 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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="0dB5/dc7" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dfdfe3d9fc8so9507832276.3 for ; Mon, 17 Jun 2024 10:58:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647113; x=1719251913; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=76YAbYQsN4iBlLO/AdhdCy35iLXKLbSen1j9CZMms3w=; b=0dB5/dc7o7DUJLLo+CLU3qpr9i8DmqWFxFlI5ebrPhKx/m2yQ8Fq1stTxykAID4Bt8 oz2qhuP7HbrVD5GNhdj7XELiSakDyTqdi008sDaPkUFmCWYosHPj9WvDov0ZMJT67/hN Zz5piK3RoVIJJPMRfQmB/ZDXeRfmi1yOUfSalXN2DLzSRggyKR2t483fCMYGd3ObRF1j MPbXpw4iEnYqDTzfyvURH6F9U3tEy3IzEyAIJaCoQ9nXI+0Y8SJPH1g/lWbYi+JsO9PU fi5+hVTpqHmh6lr8JNwYlelaNOz+gGUA3KuB0Dso/oM7pWTvWQxLIuhbd3PeaIJQDUux AGZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647113; x=1719251913; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=76YAbYQsN4iBlLO/AdhdCy35iLXKLbSen1j9CZMms3w=; b=E+T/V1LZtMA0b9VHmUyAERYef4gbcxB8mbckODKQde6+Zfc0+pd05i1ebAANjINfIR orl6o0TyMEEIY5Jma4oQwY9MNug0xSeEmOOEqCPENwwlz/70zLCb7IbOk81GTgNw4RZ3 HDFxs47rEaPQcDA6muLsmKx4tcz2+vNuSS3rnx6vTVnb1aNnfJYTWoVoDT00dtcfX0eR hs7U4pQVPoLX3HLzvEqB+VR4QnGQ3exW0cjN9J2Y8QJ7NfzzgQdIel+uP8rd6q5Q8l6+ jzJo3i8qWPjtXPXTv9B8UoAGuk5MBdh4gSAwe9simi+4Z72/TikdLf6jHwtAsGqG5BG6 K/uA== X-Forwarded-Encrypted: i=1; AJvYcCWdqvKfLqzcM0uN753+EV82GqNMUlRRuxkFa6V7wKPIeT8FRmorMLuP1v+jRLv52WdhUjzy2OKbyS9gURTmx9vKOo6402+xsEco9esspg== X-Gm-Message-State: AOJu0YxHSiaz0u6jnihQ+2+uKvc0PWips+1JXq0GJiTH0ZaeQNrZuizg CvLhALg8m/AdKMy1mvp81CpemOWq+/8huSXUZGhHuBYXln6INybweAks9507NGZKIgGsPBzkXiS XW8VG4cTpqGDehTRgUwsdf7dLcw== X-Google-Smtp-Source: AGHT+IEFlFDxRrubSZKRKq19ggp4bGgoj3XoC6AvOCv9XxrI5awLRpUMpL3IaZAxaZPpwk4phGXhW1ExNLzu5coj+zU= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a05:6902:2984:b0:dfb:fb2:ebe with SMTP id 3f1490d57ef6-dff15480784mr1072302276.13.1718647112827; Mon, 17 Jun 2024 10:58:32 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:23 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=4723; i=samitolvanen@google.com; h=from:subject; bh=n0WO328t/R/22oR4dAFfOzsZotv9Vy1BGsad/Gul6sE=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk7VghQRt6tJGo+Lh47/+dL7GF5TrJggVB/Z YqQXn8U8gKJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5OwAKCRBMtfaEi7xW 7hifC/0SP1IKS7zZIqmmeCgMSQNkuUFdCo1FdX/QfJw4dcz1EktOSWQ87V9jK4Z7eVazfE0Bcvk 2GIYZlmIJjtM/xn/dZfozLVtys9cuUc8GHBd+DJooXharA1ZHjTiuuvzDz+rKCM8nTZfcSAZgKX 6uoXbqjJ5zsaC+O+uKvWLN3mxxL95amU9m/f4w8PZlyuLVjnGlNYse/oMdMvcvmke5ECMiqnKnz Lvb2dslKCjnk3EDIfPMQkZ8JUJiGhw9JebdVbViOQaKdQIhfh93Yl7H+glQHGocNJlpcgTKaFj7 OdUDNqe/ZWSIY6WTUM0qQRb7gn6yJem92yyYyRo4FcT67l75b87WWcslEEihf8BDKvUfhMZdcko uq2WFTu8rnd2Pgr4k0goi7QLCfiURuYmCjBAf6ByvrlxG3r0sRURFcnsV+hL/eoTObhFxvpkqwS /qGAgUM2pso52796WF2ZgB/+Cl42HAU7Zd6OoLdhboYfUGRS3yS/BasH4cZo4Dr9C8S5U= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-21-samitolvanen@google.com> Subject: [PATCH 04/15] gendwarfksyms: Expand base_type From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Add support for expanding basic DWARF attributes and DW_TAG_base_type types. Example usage: $ nm -p --defined-only vmlinux.o | \ awk '/ (T|R|D) / {printf "%s %s\n",$1, $3}' | \ grep loops_per_jiffy | \ ./tools/gendwarfksyms/gendwarfksyms --debug vmlinux.o Output: gendwarfksyms: symbol_read_list: adding { 4b0, "loops_per_jiffy" } gendwarfksyms: process_modules: vmlinux.o gendwarfksyms: process_exported_symbols: loops_per_jiffy (@ 4b0) variable base_type unsigned long byte_size(8); #SYMVER loops_per_jiffy 0xc694aefc Signed-off-by: Sami Tolvanen --- tools/gendwarfksyms/types.c | 109 +++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) diff --git a/tools/gendwarfksyms/types.c b/tools/gendwarfksyms/types.c index 47ae967d42ee..7508d0fb8b80 100644 --- a/tools/gendwarfksyms/types.c +++ b/tools/gendwarfksyms/types.c @@ -16,6 +16,7 @@ } DEFINE_GET_ATTR(addr, Dwarf_Addr) +DEFINE_GET_ATTR(udata, Dwarf_Word) static bool get_ref_die_attr(Dwarf_Die *die, unsigned int id, Dwarf_Die *value) { @@ -82,6 +83,73 @@ static int process(struct state *state, const char *s) return 0; } +#define MAX_FMT_BUFFER_SIZE 128 + +static int process_fmt(struct state *state, const char *fmt, ...) +{ + char buf[MAX_FMT_BUFFER_SIZE]; + va_list args; + int res; + + va_start(args, fmt); + + res = check(vsnprintf(buf, sizeof(buf), fmt, args)); + if (res >= MAX_FMT_BUFFER_SIZE - 1) { + error("vsnprintf overflow: increase MAX_FMT_BUFFER_SIZE"); + res = -1; + } else { + check(process(state, buf)); + } + + va_end(args); + return res; +} + +/* Process a fully qualified name from DWARF scopes */ +static int process_fqn(struct state *state, Dwarf_Die *die) +{ + Dwarf_Die *scopes = NULL; + const char *name; + int res; + int i; + + res = check(dwarf_getscopes_die(die, &scopes)); + if (!res) { + name = get_name(die); + name = name ?: ""; + return check(process(state, name)); + } + + for (i = res - 1; i >= 0; i--) { + if (dwarf_tag(&scopes[i]) == DW_TAG_compile_unit) + continue; + + name = get_name(&scopes[i]); + name = name ?: ""; + check(process(state, name)); + if (i > 0) + check(process(state, "::")); + } + + free(scopes); + return 0; +} + +#define DEFINE_PROCESS_UDATA_ATTRIBUTE(attribute) \ + static int process_##attribute##_attr(struct state *state, \ + Dwarf_Die *die) \ + { \ + Dwarf_Word value; \ + if (get_udata_attr(die, DW_AT_##attribute, &value)) \ + check(process_fmt(state, \ + " " #attribute "(%" PRIu64 ")", \ + value)); \ + return 0; \ + } + +DEFINE_PROCESS_UDATA_ATTRIBUTE(alignment) +DEFINE_PROCESS_UDATA_ATTRIBUTE(byte_size) + bool match_all(Dwarf_Die *die) { return true; @@ -103,11 +171,48 @@ int process_die_container(struct state *state, Dwarf_Die *die, return 0; } +static int process_type(struct state *state, Dwarf_Die *die); + +static int process_type_attr(struct state *state, Dwarf_Die *die) +{ + Dwarf_Die type; + + if (get_ref_die_attr(die, DW_AT_type, &type)) + return check(process_type(state, &type)); + + /* Compilers can omit DW_AT_type -- print out 'void' to clarify */ + return check(process(state, "base_type void")); +} + +static int process_base_type(struct state *state, Dwarf_Die *die) +{ + check(process(state, "base_type ")); + check(process_fqn(state, die)); + check(process_byte_size_attr(state, die)); + return check(process_alignment_attr(state, die)); +} + static void state_init(struct state *state) { state->crc = 0xffffffff; } +static int process_type(struct state *state, Dwarf_Die *die) +{ + int tag = dwarf_tag(die); + + switch (tag) { + case DW_TAG_base_type: + check(process_base_type(state, die)); + break; + default: + debug("unimplemented type: %x", tag); + break; + } + + return 0; +} + /* * Exported symbol processing */ @@ -118,7 +223,9 @@ static int process_subprogram(struct state *state, Dwarf_Die *die) static int process_variable(struct state *state, Dwarf_Die *die) { - return check(process(state, "variable;\n")); + check(process(state, "variable ")); + check(process_type_attr(state, die)); + return check(process(state, ";\n")); } static int process_exported_symbols(struct state *state, Dwarf_Die *die) From patchwork Mon Jun 17 17:58:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701135 Received: from mail-pg1-f202.google.com (mail-pg1-f202.google.com [209.85.215.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 8131F198A02 for ; Mon, 17 Jun 2024 17:58:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647117; cv=none; b=nKMU2BQprPzmJNf53/SRwhQIuab3E9+RVJFzi1biPea2pF9gpxD+TzCWWf3eRW7Ed9W4MGLh1GxWSea7m8UfTl1uoYtSWDvHpbJZaWZREyIXe3NGqeKn+t8+mzdm76bYHnYH0dfc8GZ3hh8c7B1ujH+48aWAujkcNWnclqeRESw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647117; c=relaxed/simple; bh=lgkFlLCBv/2kjHShQr9qX9TjxJu4hDPDlpEc+ceu+EI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=tiZYe4Vi72OSJ2S4QhZZ89rg58FEq0/7kC1JujUR+O6wKm5FsrcNIoUiIyBGxX64gb0bhURSbYHVuFaoPf/6XHkyz8AoI43IxG96P5rFeu5ZU0cudEODuySOIlPQGmXxa5j3+46+z5g2LpDb3uYJWEdrtcAQ/BS1KyDyYA20Jus= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=X1wbD0t2; arc=none smtp.client-ip=209.85.215.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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="X1wbD0t2" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-6f18f1ec8d8so4111380a12.3 for ; Mon, 17 Jun 2024 10:58:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647115; x=1719251915; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=nlJGUQdZTqvKu/ZrihS+0fg1MxLVhWfwa5Lrufl7K5s=; b=X1wbD0t25P3U4fhntGksHvDMR065Ob46rh2UUwaqemQY3lddQUUnC1G6/R+VT2JoRs 5FDRDo6j9WABsieknb5uN1bBE28+wWyYSwzSYXWbDUFY/sz1W7vrNf8+Y3RyBp3VpnB7 VnmOR/9ADM9/nD2Q/AMz1Ba2P/rKIBuDdE1Q+CovaW3VDlMQwgiguUEFBqzaSVruthQn O6jyEjlzYWWu3Bewan5siXmmHYzyZdwVETU1cHHv4JhF0RytBR1e6U01PBJGoEqJxRHh WosjSNDFwKCgaFhB/HFXO3HuMyrRmmZgUR+HsswKuHBOUmDqrw1Cpr78CMRloM+TLtvW QC2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647115; x=1719251915; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=nlJGUQdZTqvKu/ZrihS+0fg1MxLVhWfwa5Lrufl7K5s=; b=jKJR+JS6VvMdP59BUDkgOuarFfAYb5gK8mFXyMzNhG5tAVNCAE6dnKpF5Nf31D5RId 3tYXmANOIpDCS7D0z2OjnMZoszlJxUIyy7KmmTa0E38Fli8lPgzmwpGU+GgPScEyEorp VundctlJITq8UwHTIhzZW0bUJ0jyPMcfymNYUuwEtp+Xmbkk+KIzY+kDQZb8SqRSLDRm +slWohaB7AjcQI7U0LNloBcHhIJMK+K9ZwIMHWBnodvNNaciA3uaEjtt5rmyC8Zy8v1J GYQqTXoTyW2FSthrnHiEtgm1kZDoWE7Pr+PdmoEBV+Ofkq3y+6Cna7ioGmtoQ63+VD4E AZSA== X-Forwarded-Encrypted: i=1; AJvYcCXa4hHwnUm9yvNbJBsbL3r27s9iziE0/+q7iW8rQBw00fTIXprhTQCJ0lpiTdFFzRJFNeOJ04VyM7MyIj2yVbqKvdKAGFhHhJrxucdxTQ== X-Gm-Message-State: AOJu0YwbjqkR7szZ27pxx/FdONMB8yuXcP7peUZeam7hC5iKxB14bJvB 9hstDOX6uogfPy3Z+HjePhUUUw/NYM8Rhonbh8W7l8G0X0t6scHTazaxMS38mTcSSYxJaQgsisJ bpdpBxwQ62n3ezzII8FK0W25TCA== X-Google-Smtp-Source: AGHT+IGZXIIl85hA263p5dvacYnsGHeuOOVXY79NbHJ/LEYBDyj4hhPBhCMZql7Bh18Iv9manizNAAKAMTGp4BOGF4U= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a63:6542:0:b0:6e8:7078:afa9 with SMTP id 41be03b00d2f7-70199a2a798mr28218a12.7.1718647114516; Mon, 17 Jun 2024 10:58:34 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:24 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=15488; i=samitolvanen@google.com; h=from:subject; bh=lgkFlLCBv/2kjHShQr9qX9TjxJu4hDPDlpEc+ceu+EI=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk73d3Nc1tvR72KyrmVeSruYnNm0r/XQGyQZ PQlRI0tWraJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5OwAKCRBMtfaEi7xW 7oZxC/9+kC89o9QxfqfhY9IP9ao1TrlWdtYUOBdAPZveGBnFQsmgXT7/OU7wWGi1fj1rEIh8j4o MMIsZSOT/9pTvQeyq+vnBTnW06fvBaRvVEphTiv5emwTbJAer8p4VU3JhETcznEcwl1LZ9XYhsb DSD9Iym/XgEt0ubDSLx5+avfYixUkYR6KwYlVsOgxWLeuggkl+fLYTJC3mxdbBboLX3rpIaKuU/ WJjWWAnPjynDBFMHS6ONqpjxdm7g83Egpe1ry89zA93DqCmuH08invTACKiQPBMwfo35YTa5qcB GvxSN4NHNUJsT30oSLj+8zEKRK6S5fmjZF5E6A9NcStwgzI2hdo1xGVjQzo2cggXtWqoFV3+nob u5kkXgkQOnRYI0JWxyi2d8T/+3FK5IWqvXDSXMGZEBGH+UOzz2W9YRIk1B/xv96ZGdl+/EYyhet xEogreVjueWQdX0+3tZXR+jJgPzHj9vC9NJBtDjV+he72BPORtXDhnfU5xuD7Z4PPEOuM= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-22-samitolvanen@google.com> Subject: [PATCH 05/15] gendwarfksyms: Add a cache From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Basic types in DWARF repeat frequently and traversing the DIEs using libdw is relatively slow. Add a simple hashtable based cache for the processed DIEs. Signed-off-by: Sami Tolvanen --- tools/gendwarfksyms/Build | 1 + tools/gendwarfksyms/cache.c | 147 ++++++++++++++++++++++++++++ tools/gendwarfksyms/gendwarfksyms.c | 4 + tools/gendwarfksyms/gendwarfksyms.h | 37 ++++++- tools/gendwarfksyms/types.c | 140 ++++++++++++++++++-------- 5 files changed, 286 insertions(+), 43 deletions(-) create mode 100644 tools/gendwarfksyms/cache.c diff --git a/tools/gendwarfksyms/Build b/tools/gendwarfksyms/Build index 518642c9b9de..220a4aa9b380 100644 --- a/tools/gendwarfksyms/Build +++ b/tools/gendwarfksyms/Build @@ -1,4 +1,5 @@ gendwarfksyms-y += gendwarfksyms.o +gendwarfksyms-y += cache.o gendwarfksyms-y += crc32.o gendwarfksyms-y += symbols.o gendwarfksyms-y += types.o diff --git a/tools/gendwarfksyms/cache.c b/tools/gendwarfksyms/cache.c new file mode 100644 index 000000000000..9adda113e0b6 --- /dev/null +++ b/tools/gendwarfksyms/cache.c @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2024 Google LLC + */ + +#include +#include "gendwarfksyms.h" + +#define DIE_HASH_BITS 10 + +/* die->addr -> struct cached_die */ +DEFINE_HASHTABLE(die_cache, DIE_HASH_BITS); + +static unsigned int cache_hits; +static unsigned int cache_misses; + +static int create_die(Dwarf_Die *die, struct cached_die **res) +{ + struct cached_die *cd; + + cd = malloc(sizeof(struct cached_die)); + if (!cd) { + error("malloc failed"); + return -1; + } + + cd->state = INCOMPLETE; + cd->addr = (uintptr_t)die->addr; + cd->list = NULL; + + hash_add(die_cache, &cd->hash, cd->addr); + *res = cd; + return 0; +} + +int cache_get(Dwarf_Die *die, enum cached_die_state state, + struct cached_die **res) +{ + struct cached_die *cd; + uintptr_t addr = (uintptr_t)die->addr; + + hash_for_each_possible(die_cache, cd, hash, addr) { + if (cd->addr == addr && cd->state == state) { + *res = cd; + cache_hits++; + return 0; + } + } + + cache_misses++; + return check(create_die(die, res)); +} + +static void reset_die(struct cached_die *cd) +{ + struct cached_item *tmp; + struct cached_item *ci = cd->list; + + while (ci) { + if (ci->type == STRING) + free(ci->data.str); + + tmp = ci->next; + free(ci); + ci = tmp; + } + + cd->state = INCOMPLETE; + cd->list = NULL; +} + +void cache_free(void) +{ + struct cached_die *cd; + struct hlist_node *tmp; + int i; + + hash_for_each_safe(die_cache, i, tmp, cd, hash) { + reset_die(cd); + free(cd); + } + hash_init(die_cache); + + if ((cache_hits + cache_misses > 0)) + debug("cache: hits %u, misses %u (hit rate %.02f%%)", + cache_hits, cache_misses, + (100.0f * cache_hits) / (cache_hits + cache_misses)); +} + +static int append_item(struct cached_die *cd, struct cached_item **res) +{ + struct cached_item *prev; + struct cached_item *ci; + + ci = malloc(sizeof(struct cached_item)); + if (!ci) { + error("malloc failed"); + return -1; + } + + ci->type = EMPTY; + ci->next = NULL; + + prev = cd->list; + while (prev && prev->next) + prev = prev->next; + + if (prev) + prev->next = ci; + else + cd->list = ci; + + *res = ci; + return 0; +} + +int cache_add_string(struct cached_die *cd, const char *str) +{ + struct cached_item *ci; + + if (!cd) + return 0; + + check(append_item(cd, &ci)); + + ci->data.str = strdup(str); + if (!ci->data.str) { + error("strdup failed"); + return -1; + } + + ci->type = STRING; + return 0; +} + +int cache_add_die(struct cached_die *cd, Dwarf_Die *die) +{ + struct cached_item *ci; + + if (!cd) + return 0; + + check(append_item(cd, &ci)); + ci->data.addr = (uintptr_t)die->addr; + ci->type = DIE; + return 0; +} diff --git a/tools/gendwarfksyms/gendwarfksyms.c b/tools/gendwarfksyms/gendwarfksyms.c index 7938b7440674..38ccaeb72426 100644 --- a/tools/gendwarfksyms/gendwarfksyms.c +++ b/tools/gendwarfksyms/gendwarfksyms.c @@ -15,12 +15,15 @@ /* Print type descriptions and debugging output to stderr */ bool debug; +/* Don't use caching */ +bool no_cache; static const struct { const char *arg; bool *flag; } options[] = { { "--debug", &debug }, + { "--no-cache", &no_cache }, }; static int usage(void) @@ -126,6 +129,7 @@ int main(int argc, const char **argv) dwfl_end(dwfl); symbol_print_versions(); + cache_free(); return 0; } diff --git a/tools/gendwarfksyms/gendwarfksyms.h b/tools/gendwarfksyms/gendwarfksyms.h index 7440f1c73500..ea5a9fbda66f 100644 --- a/tools/gendwarfksyms/gendwarfksyms.h +++ b/tools/gendwarfksyms/gendwarfksyms.h @@ -18,6 +18,7 @@ * Options -- in gendwarfksyms.c */ extern bool debug; +extern bool no_cache; /* * Output helpers @@ -69,6 +70,35 @@ extern int symbol_read_list(FILE *file); extern struct symbol *symbol_get(uintptr_t addr, const char *name); extern void symbol_print_versions(void); +/* + * cache.c + */ +enum cached_item_type { EMPTY, STRING, DIE }; + +struct cached_item { + enum cached_item_type type; + union { + char *str; + uintptr_t addr; + } data; + struct cached_item *next; +}; + +enum cached_die_state { INCOMPLETE, COMPLETE }; + +struct cached_die { + enum cached_die_state state; + uintptr_t addr; + struct cached_item *list; + struct hlist_node hash; +}; + +extern int cache_get(Dwarf_Die *die, enum cached_die_state state, + struct cached_die **res); +extern int cache_add_string(struct cached_die *pd, const char *str); +extern int cache_add_die(struct cached_die *pd, Dwarf_Die *die); +extern void cache_free(void); + /* * types.c */ @@ -81,12 +111,13 @@ struct state { unsigned long crc; }; -typedef int (*die_callback_t)(struct state *state, Dwarf_Die *die); +typedef int (*die_callback_t)(struct state *state, struct cached_die *cache, + Dwarf_Die *die); typedef bool (*die_match_callback_t)(Dwarf_Die *die); extern bool match_all(Dwarf_Die *die); -extern int process_die_container(struct state *state, Dwarf_Die *die, - die_callback_t func, +extern int process_die_container(struct state *state, struct cached_die *cache, + Dwarf_Die *die, die_callback_t func, die_match_callback_t match); extern int process_module(Dwfl_Module *mod, Dwarf *dbg, Dwarf_Die *cudie); diff --git a/tools/gendwarfksyms/types.c b/tools/gendwarfksyms/types.c index 7508d0fb8b80..78046c08be23 100644 --- a/tools/gendwarfksyms/types.c +++ b/tools/gendwarfksyms/types.c @@ -72,7 +72,7 @@ static Dwarf_Die *get_exported(struct state *state, Dwarf_Die *die) /* * Type string and CRC processing */ -static int process(struct state *state, const char *s) +static int process(struct state *state, struct cached_die *cache, const char *s) { s = s ?: ""; @@ -80,12 +80,13 @@ static int process(struct state *state, const char *s) fputs(s, stderr); state->crc = partial_crc32(s, state->crc); - return 0; + return cache_add_string(cache, s); } #define MAX_FMT_BUFFER_SIZE 128 -static int process_fmt(struct state *state, const char *fmt, ...) +static int process_fmt(struct state *state, struct cached_die *cache, + const char *fmt, ...) { char buf[MAX_FMT_BUFFER_SIZE]; va_list args; @@ -98,7 +99,7 @@ static int process_fmt(struct state *state, const char *fmt, ...) error("vsnprintf overflow: increase MAX_FMT_BUFFER_SIZE"); res = -1; } else { - check(process(state, buf)); + check(process(state, cache, buf)); } va_end(args); @@ -106,7 +107,8 @@ static int process_fmt(struct state *state, const char *fmt, ...) } /* Process a fully qualified name from DWARF scopes */ -static int process_fqn(struct state *state, Dwarf_Die *die) +static int process_fqn(struct state *state, struct cached_die *cache, + Dwarf_Die *die) { Dwarf_Die *scopes = NULL; const char *name; @@ -117,7 +119,7 @@ static int process_fqn(struct state *state, Dwarf_Die *die) if (!res) { name = get_name(die); name = name ?: ""; - return check(process(state, name)); + return check(process(state, cache, name)); } for (i = res - 1; i >= 0; i--) { @@ -126,25 +128,25 @@ static int process_fqn(struct state *state, Dwarf_Die *die) name = get_name(&scopes[i]); name = name ?: ""; - check(process(state, name)); + check(process(state, cache, name)); if (i > 0) - check(process(state, "::")); + check(process(state, cache, "::")); } free(scopes); return 0; } -#define DEFINE_PROCESS_UDATA_ATTRIBUTE(attribute) \ - static int process_##attribute##_attr(struct state *state, \ - Dwarf_Die *die) \ - { \ - Dwarf_Word value; \ - if (get_udata_attr(die, DW_AT_##attribute, &value)) \ - check(process_fmt(state, \ - " " #attribute "(%" PRIu64 ")", \ - value)); \ - return 0; \ +#define DEFINE_PROCESS_UDATA_ATTRIBUTE(attribute) \ + static int process_##attribute##_attr( \ + struct state *state, struct cached_die *cache, Dwarf_Die *die) \ + { \ + Dwarf_Word value; \ + if (get_udata_attr(die, DW_AT_##attribute, &value)) \ + check(process_fmt(state, cache, \ + " " #attribute "(%" PRIu64 ")", \ + value)); \ + return 0; \ } DEFINE_PROCESS_UDATA_ATTRIBUTE(alignment) @@ -155,8 +157,9 @@ bool match_all(Dwarf_Die *die) return true; } -int process_die_container(struct state *state, Dwarf_Die *die, - die_callback_t func, die_match_callback_t match) +int process_die_container(struct state *state, struct cached_die *cache, + Dwarf_Die *die, die_callback_t func, + die_match_callback_t match) { Dwarf_Die current; int res; @@ -164,32 +167,65 @@ int process_die_container(struct state *state, Dwarf_Die *die, res = check(dwarf_child(die, ¤t)); while (!res) { if (match(¤t)) - check(func(state, ¤t)); + check(func(state, cache, ¤t)); res = check(dwarf_siblingof(¤t, ¤t)); } return 0; } -static int process_type(struct state *state, Dwarf_Die *die); +static int process_type(struct state *state, struct cached_die *parent, + Dwarf_Die *die); -static int process_type_attr(struct state *state, Dwarf_Die *die) +static int process_type_attr(struct state *state, struct cached_die *cache, + Dwarf_Die *die) { Dwarf_Die type; if (get_ref_die_attr(die, DW_AT_type, &type)) - return check(process_type(state, &type)); + return check(process_type(state, cache, &type)); /* Compilers can omit DW_AT_type -- print out 'void' to clarify */ - return check(process(state, "base_type void")); + return check(process(state, cache, "base_type void")); +} + +static int process_base_type(struct state *state, struct cached_die *cache, + Dwarf_Die *die) +{ + check(process(state, cache, "base_type ")); + check(process_fqn(state, cache, die)); + check(process_byte_size_attr(state, cache, die)); + return check(process_alignment_attr(state, cache, die)); } -static int process_base_type(struct state *state, Dwarf_Die *die) +static int process_cached(struct state *state, struct cached_die *cache, + Dwarf_Die *die) { - check(process(state, "base_type ")); - check(process_fqn(state, die)); - check(process_byte_size_attr(state, die)); - return check(process_alignment_attr(state, die)); + struct cached_item *ci = cache->list; + Dwarf_Die child; + + while (ci) { + switch (ci->type) { + case STRING: + check(process(state, NULL, ci->data.str)); + break; + case DIE: + if (!dwarf_die_addr_die(state->dbg, + (void *)ci->data.addr, + &child)) { + error("dwarf_die_addr_die failed"); + return -1; + } + check(process_type(state, NULL, &child)); + break; + default: + error("empty cached_item"); + return -1; + } + ci = ci->next; + } + + return 0; } static void state_init(struct state *state) @@ -197,19 +233,41 @@ static void state_init(struct state *state) state->crc = 0xffffffff; } -static int process_type(struct state *state, Dwarf_Die *die) +static int process_type(struct state *state, struct cached_die *parent, + Dwarf_Die *die) { + struct cached_die *cache = NULL; int tag = dwarf_tag(die); + /* + * If we have the DIE already cached, use it instead of walking + * through DWARF. + */ + if (!no_cache) { + check(cache_get(die, COMPLETE, &cache)); + + if (cache->state == COMPLETE) { + check(process_cached(state, cache, die)); + check(cache_add_die(parent, die)); + return 0; + } + } + switch (tag) { case DW_TAG_base_type: - check(process_base_type(state, die)); + check(process_base_type(state, cache, die)); break; default: debug("unimplemented type: %x", tag); break; } + if (!no_cache) { + /* Update cache state and append to the parent (if any) */ + cache->state = COMPLETE; + check(cache_add_die(parent, die)); + } + return 0; } @@ -218,17 +276,18 @@ static int process_type(struct state *state, Dwarf_Die *die) */ static int process_subprogram(struct state *state, Dwarf_Die *die) { - return check(process(state, "subprogram;\n")); + return check(process(state, NULL, "subprogram;\n")); } static int process_variable(struct state *state, Dwarf_Die *die) { - check(process(state, "variable ")); - check(process_type_attr(state, die)); - return check(process(state, ";\n")); + check(process(state, NULL, "variable ")); + check(process_type_attr(state, NULL, die)); + return check(process(state, NULL, ";\n")); } -static int process_exported_symbols(struct state *state, Dwarf_Die *die) +static int process_exported_symbols(struct state *state, + struct cached_die *cache, Dwarf_Die *die) { int tag = dwarf_tag(die); @@ -237,8 +296,9 @@ static int process_exported_symbols(struct state *state, Dwarf_Die *die) case DW_TAG_namespace: case DW_TAG_class_type: case DW_TAG_structure_type: - return check(process_die_container( - state, die, process_exported_symbols, match_all)); + return check(process_die_container(state, cache, die, + process_exported_symbols, + match_all)); /* Possible exported symbols */ case DW_TAG_subprogram: @@ -271,5 +331,5 @@ int process_module(Dwfl_Module *mod, Dwarf *dbg, Dwarf_Die *cudie) struct state state = { .mod = mod, .dbg = dbg }; return check(process_die_container( - &state, cudie, process_exported_symbols, match_all)); + &state, NULL, cudie, process_exported_symbols, match_all)); } From patchwork Mon Jun 17 17:58:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701136 Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.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 84E36198E7A for ; Mon, 17 Jun 2024 17:58:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647119; cv=none; b=DMi5qLnyKsH1sWhCyD24otkbaFiXdnVDC+Dkq3UzVvDEYoqL5CwjaSHJHgAniIZOZasSo0WiQU4c3+0V04t+5aUqT7pVuGTmuYTPqJ33cTh5GqwkaYrFLKN25VwWHUwItyY1utWhJ/KRzFNmVd/RRMKu8Qg/koZLtY0N37vgzz8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647119; c=relaxed/simple; bh=H5KOAGVfXZJmk+NFA/+tTZJYgSeCRqBkuPOyQyavQG4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=qfBW94dvHPfjt4OmcXhEbwgQSXYMc5AQP/fXiKd3KStUmzMepgfzsaIueiWhoBYzgL6eQx0cL/TuFm1p3AJpqobs2UERHxBDdMXWxfNtrjnOqNqLQusWPP1E/cOhGennAkXZ4IOrqt0QN+TAD5G8PKjKRXRntklqM6XP5PUOKbU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=AvO3rxY5; arc=none smtp.client-ip=209.85.128.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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="AvO3rxY5" Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-62fb36d7f5fso93250717b3.1 for ; Mon, 17 Jun 2024 10:58:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647116; x=1719251916; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=T+S9saSNPIU2DvcxL2+Yd4Qfr8i4F6S0XsoNHIuu5T8=; b=AvO3rxY5Rqoo/3Loe7xBdFJkw1ArGorxUiNemlXstklNlSWR3hcDEsxEl2BOLJLNCj xMcv5ZsSl6ZmL3tW97My7zcMjTX+wfZWhJyX71WvvCvCzP+WWed/xKNQyMQlO7rH4H1G fZ6Or8kaM6BR6GSHqWA703wNHg6Nxl+iIwAEG3fNHa/ROiKijEDUgt1AThhcY2TLedux tBO41Un9nfjV9UxlBb6eU84v5FeBvzWueud9yX1pvO3p0K7p3UoAB2wI8JzxpKD6JP3m 1eOHKLawLl4uxld6X/43/EDxCRGj5mTq4q5KwZ2V/wX/3won/9j04Ap20GcavI58dCO6 yMYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647116; x=1719251916; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=T+S9saSNPIU2DvcxL2+Yd4Qfr8i4F6S0XsoNHIuu5T8=; b=JAkkEMUVwQz3Js91ap8a50lG9z3jMpg3EcdrKFBTjzWL06cTM/nG6JR2tsysulUjjL nQwid+p+JYtKZJmZyWcyVP5ofAbVSUiJSxDqryBVuwTKjuZh/Xg2Gshy9wxIbZkhrJ4V E0lYDnmB0yoX27/K6KYEUeMLW/QqJZ2CKOIU35/3XW6aPXzUPmKLZN1ABRqXnvly5oZc u0t85gJ2Ss9Sho2GPkTCOX+89oesZZUG8UNwhDUe2RMXp1/SIxFi6BHE12gtpkKu0UeR VPI+Tgi7TDHAT9laiT7jwazggqg8XJQeoTi42mR+mW0o7cFu7JrIunIaLXBYGf6qrhDS XNAw== X-Forwarded-Encrypted: i=1; AJvYcCV0GbziNbO2CLmp5I9qhTlXyiGmvFKxERxe0Rb9YgKteKfflKWPJuhbHUDS/O5+pLRjc8I5k/clT41Ah/n4GVJPlHUjxN1+QyfHwPVwEA== X-Gm-Message-State: AOJu0YwjXBX0BEpqmp2tRfSWpGDBthCFBMYgPup+K1rHv4ZCx0/CPzvo Pu8kxxwxhJiL0LC/ff+FCwTIPxjDSWadu0zv++rZ9Hq/mcx6P0M+9WbQobgDTwJaX2cxggpgNHA KkIFhq7JWAqF7NNPRzg7TLdIn5g== X-Google-Smtp-Source: AGHT+IFjn+P7dntCkJGcXDizaFOTyUC5TJtnxV3JuDKw8gokiADeudVJlIIDrCQw9XX+W0DpQxsG2TQfoKQpJcPc50A= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a05:690c:4805:b0:61b:e8a2:6f4a with SMTP id 00721157ae682-6321f394015mr24272597b3.0.1718647116640; Mon, 17 Jun 2024 10:58:36 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:25 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=3632; i=samitolvanen@google.com; h=from:subject; bh=H5KOAGVfXZJmk+NFA/+tTZJYgSeCRqBkuPOyQyavQG4=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk7XOzd3feUM+aCz1uQk58MOC7SFsXRgcHVJ 2Cr3YT25d6JAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5OwAKCRBMtfaEi7xW 7i7sC/9IKFDIzWVj80laMn3YewIUn9B0VnVGxVyfYcDHFQBNvs8TwXJp1/r7rwaf4jCShPXU/fo VvEjLjpFPq7PcGpp6Ms+UbfYLbjSWuWqk9M/nG4styfZY47IL8nKll3iYCYWbjF634wrvtxmK/e zkRnjlNKVJjoo3JNsNVbOwyzDYqxjpNzpj6Snx2zqWF1U1XJUGGSx9SHMnPr+ribEOTmQg8iLwM fw6jrr/SKxQ74+mguDDA2vKa5bNIFyG0k7LNa2x7dusc/InRuJg0FM1EDOpb1YPhZUTn6juIxvh lkRMZ6KeNDnQ55vwScYhMyURHfLMnO7Yb8Ob+hVz0EQpAtDQHV2qkUUVYwaDqWArOYtMWizh2HO co7oRCSLSpMI0/5M9qyhR9cCzHFHeZRMT+SibSvpki7tB66F8g2Wz9/QcMQa7/cB1yeetc6cuhj oeHQIkrcSRnmuTClrAAJu+MKgs8Ybaa8Ud9TXo4kXqj4qZSm6EN85YTqiroM6oj8OFh04= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-23-samitolvanen@google.com> Subject: [PATCH 06/15] gendwarfksyms: Expand type modifiers and typedefs From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Add support for expanding DWARF type modifiers, such as pointers, const values etc., and typedefs. These types all have DW_AT_type attribute pointing the underlying type, and thus produce similar output. Signed-off-by: Sami Tolvanen --- tools/gendwarfksyms/gendwarfksyms.h | 3 ++ tools/gendwarfksyms/types.c | 54 +++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/tools/gendwarfksyms/gendwarfksyms.h b/tools/gendwarfksyms/gendwarfksyms.h index ea5a9fbda66f..d5ebfe405445 100644 --- a/tools/gendwarfksyms/gendwarfksyms.h +++ b/tools/gendwarfksyms/gendwarfksyms.h @@ -50,6 +50,9 @@ extern bool no_cache; __res; \ }) +/* Consistent aliases (DW_TAG__type) for DWARF tags */ +#define DW_TAG_typedef_type DW_TAG_typedef + /* * symbols.c */ diff --git a/tools/gendwarfksyms/types.c b/tools/gendwarfksyms/types.c index 78046c08be23..27169c77937f 100644 --- a/tools/gendwarfksyms/types.c +++ b/tools/gendwarfksyms/types.c @@ -189,6 +189,38 @@ static int process_type_attr(struct state *state, struct cached_die *cache, return check(process(state, cache, "base_type void")); } +/* Container types with DW_AT_type */ +static int __process_type(struct state *state, struct cached_die *cache, + Dwarf_Die *die, const char *type) +{ + check(process(state, cache, type)); + check(process_fqn(state, cache, die)); + check(process(state, cache, " {")); + check(process_type_attr(state, cache, die)); + check(process(state, cache, "}")); + check(process_byte_size_attr(state, cache, die)); + return check(process_alignment_attr(state, cache, die)); +} + +#define DEFINE_PROCESS_TYPE(type) \ + static int process_##type##_type( \ + struct state *state, struct cached_die *cache, Dwarf_Die *die) \ + { \ + return __process_type(state, cache, die, #type "_type "); \ + } + +DEFINE_PROCESS_TYPE(atomic) +DEFINE_PROCESS_TYPE(const) +DEFINE_PROCESS_TYPE(immutable) +DEFINE_PROCESS_TYPE(packed) +DEFINE_PROCESS_TYPE(pointer) +DEFINE_PROCESS_TYPE(reference) +DEFINE_PROCESS_TYPE(restrict) +DEFINE_PROCESS_TYPE(rvalue_reference) +DEFINE_PROCESS_TYPE(shared) +DEFINE_PROCESS_TYPE(volatile) +DEFINE_PROCESS_TYPE(typedef) + static int process_base_type(struct state *state, struct cached_die *cache, Dwarf_Die *die) { @@ -233,6 +265,11 @@ static void state_init(struct state *state) state->crc = 0xffffffff; } +#define PROCESS_TYPE(type) \ + case DW_TAG_##type##_type: \ + check(process_##type##_type(state, cache, die)); \ + break; + static int process_type(struct state *state, struct cached_die *parent, Dwarf_Die *die) { @@ -254,9 +291,20 @@ static int process_type(struct state *state, struct cached_die *parent, } switch (tag) { - case DW_TAG_base_type: - check(process_base_type(state, cache, die)); - break; + /* Type modifiers */ + PROCESS_TYPE(atomic) + PROCESS_TYPE(const) + PROCESS_TYPE(immutable) + PROCESS_TYPE(packed) + PROCESS_TYPE(pointer) + PROCESS_TYPE(reference) + PROCESS_TYPE(restrict) + PROCESS_TYPE(rvalue_reference) + PROCESS_TYPE(shared) + PROCESS_TYPE(volatile) + /* Other types */ + PROCESS_TYPE(base) + PROCESS_TYPE(typedef) default: debug("unimplemented type: %x", tag); break; From patchwork Mon Jun 17 17:58:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701137 Received: from mail-pg1-f201.google.com (mail-pg1-f201.google.com [209.85.215.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 BF8BF198E90 for ; Mon, 17 Jun 2024 17:58:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647120; cv=none; b=bC7JpfPSBgeeNkIl5AoG79bBglqt37g0IeJAx6xnVowroISBEw9bdWWfRTOT2G6N7DRQaiMVP3+GOFlFVSocQ3XjFMHrSPTB+ITSZj0/VNSyqA8fhFFhCtZScgBpsJRRYQMy6NCuswkGoW2/2cwjfqGIxdDH0Z1fDHkIleqppXc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647120; c=relaxed/simple; bh=kOMHom4gVs6RWKcDfBpdNRS2iu22iu6ooQQly4TUfUg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=rK4515sscapiZc1rNMv2SC9ecG8Xy5GJaprn/ZsZIDo4FCNWC1YGSwzFnAgQXJDT4CyU3iMCHJ/oRS3fyyIqXp7ZBf9pqGJDeKBrtubxRswUqRPpao8Q3zA8I4pb6td8JomJPNjaDsra0iyqwtokmPVBQEj82SiWnqSBporDyXs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=xspmofmy; arc=none smtp.client-ip=209.85.215.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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="xspmofmy" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-704d99cb97aso2299775a12.0 for ; Mon, 17 Jun 2024 10:58:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647118; x=1719251918; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Ixi9Tabuy3CnXqRjT8zQOnb7QNjznqM/C/Fa/bP10ZY=; b=xspmofmyeDGriIAwGWcwVkqw6RgdBV/qF5v7/ZtkdtI4fE1x0LBchGLfRVFWdY79Ad wuHog5giJVrYIeAua/bMxckf5wTPh4X+iTMhPn+mz8tz/Hgmb82kfJ7JP2M4cDPJS/+O S52BbZrIIa7m2R2UdqxomhjH8UOTvhwEwU7fUzgrmrhJgKzJyvueqJ4Nn53gRtr0CsiF 3p06fOkUFLN21a1wCB2VI44++RLOgek26jIm4/zOUEtQH8mcrDFMjGJaitO/k+9NLLBr 7DzTsasqyrNnY5/9J+wN+nV+C/aoOLWEwEi6vrE0j6KzeBH1i96raq+dWCfXL+BgWUTr uymg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647118; x=1719251918; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Ixi9Tabuy3CnXqRjT8zQOnb7QNjznqM/C/Fa/bP10ZY=; b=LNcuiXzbHVgsEEowfW2n1bppxyWqEGu8DWsyN2mJmmtrRQiCsV5i9b4HDh6zCcN81j IEiTxRAskImMSOMNwlxDxa8hPfGMQiOjnuQVhFgo1ygxt9xMW/b9PPz7hflzNm4Wdc+u C62UQOUKdvZ+yuL4e4nPTa94L1utqpep9X1x6kQIqajUCxr3UabRypFr/huKTVtEEiQk jDAu/gMJAt4PwkgmYj/t3Q7Ju/J+uB1YdzLYSyryUYoZh2+n3kwMw3YX85BQbxUH3WsN 5Rzeod1hT79ALAdviprSu0VUPdN4blHIcfIeFpNSDxuU9f7o3y8w67pnFoLBbjTJLGKi RWPw== X-Forwarded-Encrypted: i=1; AJvYcCULl3AZNob/n8J0RiMpFwKsmsKX6JhvI5X5rXMtm8DHVE6gYmnldil0vbg2TXymbRrYFXNQ03FUnBCP2rd0goxkogo1mohUuF3+UcKxJA== X-Gm-Message-State: AOJu0YxGv230S6ewxLVXvCNgX58FNOBvt5M5aSXyUsifpJ5oR/WxV4db BeTgN31TqWV80mAxBIJiiegK0TMf9ju6boLXcHppU0JzC2tnKjRzP3EXZ1aB/2pK6uD+SsRZ1JS coKIiKpZM8A+1hwcWzUBekqYx5A== X-Google-Smtp-Source: AGHT+IHCicmwZJWS4aDIb3BbC3DAPBGOj6Uu7pMNETbNCKIL0/2phEEyDM9aUx9nahpwEuqkTnqYVTgXJDHFS5dGtRE= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a17:90b:3805:b0:2c2:e31f:4993 with SMTP id 98e67ed59e1d1-2c4db1290e1mr93429a91.1.1718647118108; Mon, 17 Jun 2024 10:58:38 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:26 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=4937; i=samitolvanen@google.com; h=from:subject; bh=kOMHom4gVs6RWKcDfBpdNRS2iu22iu6ooQQly4TUfUg=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk7Ef8A7+1CNTp+xTArVDN7sEYreWBUSNkp9 TVNkF3AYoCJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5OwAKCRBMtfaEi7xW 7tNsC/98cAuLslmd+4Vd5IBw4994Ko9bAeysBor5ueyKAcXwQpGYIqjZj0NvnZLLCZg/oL3Xosc uoUipBkaRPOKghNoyqI7XdVu6APJ67S31vUAwF4hZcRgokl0OL/yJKGUPwR7h53D8W95x5mI/Vf m69dnikfR+AtcGLWxc3KhwXDyGMdVNljI8wyBN1gVqNjv8kzbfchz6hN3FpMcRMaj7765Em0YDS JUSrEtfHjbl7H/5Y+hA6X4zq+vp1E3eMbmoFsVHWOwh4VciTS0/pr2mYff1clG+BkKDnnANvONd xIej9xyI/krErEkjZ0eLzdPQGl57LOfArJAEvq2Zq1C3NZYOKPc19Vd6RfGcQJ18Nv61MmyM3ap 3HA0Lbi0VxYosETLOKMlLe/tmfaHrPOYgGglhWHH1Pc+IEaF3PHk7nWZMyVEJBc1BTe5kJmAXA/ 4DftpiisZcdK5MX40dWQDJvyfSjze/FkW3F27y0MpgDzmn6jsJg2MJtBOpGENqZIhu2CI= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-24-samitolvanen@google.com> Subject: [PATCH 07/15] gendwarfksyms: Add pretty-printing From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Add linebreaks and indentation to --debug output. This will be particularly useful for more complex structures. Example output with --debug: variable pointer_type { base_type char byte_size(1) }; And the same with --debug --no-pretty-print: variable pointer_type {base_type char byte_size(1)}; Signed-off-by: Sami Tolvanen --- tools/gendwarfksyms/cache.c | 13 +++++++++++++ tools/gendwarfksyms/gendwarfksyms.c | 3 +++ tools/gendwarfksyms/gendwarfksyms.h | 5 ++++- tools/gendwarfksyms/types.c | 22 ++++++++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/tools/gendwarfksyms/cache.c b/tools/gendwarfksyms/cache.c index 9adda113e0b6..85a2adeb649d 100644 --- a/tools/gendwarfksyms/cache.c +++ b/tools/gendwarfksyms/cache.c @@ -133,6 +133,19 @@ int cache_add_string(struct cached_die *cd, const char *str) return 0; } +int cache_add_linebreak(struct cached_die *cd, int linebreak) +{ + struct cached_item *ci; + + if (!cd) + return 0; + + check(append_item(cd, &ci)); + ci->data.linebreak = linebreak; + ci->type = LINEBREAK; + return 0; +} + int cache_add_die(struct cached_die *cd, Dwarf_Die *die) { struct cached_item *ci; diff --git a/tools/gendwarfksyms/gendwarfksyms.c b/tools/gendwarfksyms/gendwarfksyms.c index 38ccaeb72426..7095f0ecccab 100644 --- a/tools/gendwarfksyms/gendwarfksyms.c +++ b/tools/gendwarfksyms/gendwarfksyms.c @@ -17,6 +17,8 @@ bool debug; /* Don't use caching */ bool no_cache; +/* Don't pretty-print (with --debug) */ +bool no_pretty_print; static const struct { const char *arg; @@ -24,6 +26,7 @@ static const struct { } options[] = { { "--debug", &debug }, { "--no-cache", &no_cache }, + { "--no-pretty-print", &no_pretty_print }, }; static int usage(void) diff --git a/tools/gendwarfksyms/gendwarfksyms.h b/tools/gendwarfksyms/gendwarfksyms.h index d5ebfe405445..43eff91e2f2f 100644 --- a/tools/gendwarfksyms/gendwarfksyms.h +++ b/tools/gendwarfksyms/gendwarfksyms.h @@ -19,6 +19,7 @@ */ extern bool debug; extern bool no_cache; +extern bool no_pretty_print; /* * Output helpers @@ -76,12 +77,13 @@ extern void symbol_print_versions(void); /* * cache.c */ -enum cached_item_type { EMPTY, STRING, DIE }; +enum cached_item_type { EMPTY, STRING, LINEBREAK, DIE }; struct cached_item { enum cached_item_type type; union { char *str; + int linebreak; uintptr_t addr; } data; struct cached_item *next; @@ -99,6 +101,7 @@ struct cached_die { extern int cache_get(Dwarf_Die *die, enum cached_die_state state, struct cached_die **res); extern int cache_add_string(struct cached_die *pd, const char *str); +extern int cache_add_linebreak(struct cached_die *pd, int linebreak); extern int cache_add_die(struct cached_die *pd, Dwarf_Die *die); extern void cache_free(void); diff --git a/tools/gendwarfksyms/types.c b/tools/gendwarfksyms/types.c index 27169c77937f..74b3755c3e16 100644 --- a/tools/gendwarfksyms/types.c +++ b/tools/gendwarfksyms/types.c @@ -6,6 +6,17 @@ #include "gendwarfksyms.h" #include "crc32.h" +static bool do_linebreak; +static int indentation_level; + +/* Line breaks and indentation for pretty-printing */ +static int process_linebreak(struct cached_die *cache, int n) +{ + indentation_level += n; + do_linebreak = true; + return check(cache_add_linebreak(cache, n)); +} + #define DEFINE_GET_ATTR(attr, type) \ static bool get_##attr##_attr(Dwarf_Die *die, unsigned int id, \ type *value) \ @@ -76,6 +87,12 @@ static int process(struct state *state, struct cached_die *cache, const char *s) { s = s ?: ""; + if (debug && !no_pretty_print && do_linebreak) { + fputs("\n", stderr); + for (int i = 0; i < indentation_level; i++) + fputs(" ", stderr); + do_linebreak = false; + } if (debug) fputs(s, stderr); @@ -196,7 +213,9 @@ static int __process_type(struct state *state, struct cached_die *cache, check(process(state, cache, type)); check(process_fqn(state, cache, die)); check(process(state, cache, " {")); + check(process_linebreak(cache, 1)); check(process_type_attr(state, cache, die)); + check(process_linebreak(cache, -1)); check(process(state, cache, "}")); check(process_byte_size_attr(state, cache, die)); return check(process_alignment_attr(state, cache, die)); @@ -241,6 +260,9 @@ static int process_cached(struct state *state, struct cached_die *cache, case STRING: check(process(state, NULL, ci->data.str)); break; + case LINEBREAK: + check(process_linebreak(NULL, ci->data.linebreak)); + break; case DIE: if (!dwarf_die_addr_die(state->dbg, (void *)ci->data.addr, From patchwork Mon Jun 17 17:58:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701138 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 039E91990DC for ; Mon, 17 Jun 2024 17:58:40 +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=1718647122; cv=none; b=WfbwQxpOzQOCYxWjcuBjwvJdwNU7el74HlGjdoR66EtU0RhvhPPNcKIqQjPuGJ/ahrPxuItWw4QaknIZdo8hxnmIganKb2otMcEjoXIwUc9JUZ3rQQK3CrintoBIlT1H2IyuAd1diW/b6v8kFOXHrSA423wn0QrFbet+AGi2G1A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647122; c=relaxed/simple; bh=sgkmHHFnIgB0fgQ5FEpkS1fH49CWjOzk+cSBmlZvE+g=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=YhC+zb9dxQbVm+E3HdWLAPfcTAcBT0cN+toryRN/hROGTDUleKhBTLQNcXh1uQlBuYTYEYJ3T56ASOsKpHQHaAWy1dDboy5+CWBwV5Db8LnjiEkOwPpwdSNaa2sQ5g9v4yUD1VdXIn78dNGv7FvtwtRA7epF0BzJSQ9qp+Uq/Tk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=aSSIq/Vg; 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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="aSSIq/Vg" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-df773f9471fso8459044276.3 for ; Mon, 17 Jun 2024 10:58:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647120; x=1719251920; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=qMAR1cIo1JflM9ePFvjznKTtOdomJ8KqqAZoYV6fqok=; b=aSSIq/Vg0mEUxZbfyuoJDSjPXY5kdFgnqOK0BxqpVe6hLG7xUpmerxv7f/HWqUSU4E +ut4Cx7ryL8R7NqNdXQBBhnjcdJDE8wTGPKhsjv+VFykeMoOEFSXh1pv5vzSYxIgBf+3 B/BVj0jRzvUj/2SN8a2eQ7hbNvdzUQWXT2dv86A9ZIv8NNvKWKvbrw9qncHzN8UHZamV LDTCE/nMsznV9CTkwBsEea+Al5SGZfC9qTeXf5XcFi62oZTw9p4YnzhmbF2HVYAEU/Ce +/94/6V+NaSo1r7JVFcleDGCpZvUDTrluosC1TYsQY7PMk8t/2Ml3j1oiCSDdOrmBJWc l43Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647120; x=1719251920; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=qMAR1cIo1JflM9ePFvjznKTtOdomJ8KqqAZoYV6fqok=; b=BXQZDrOJPsur7cNmQF34hn+SrxdUn5foMneka+mSeoR73AZ0VqHNAhB6q40DF7VVed yIbg1sqZQShXktVArfN+iv5NvRA4WD2OUGR7ZrPAf82g4w5JJdJhKIjP3pS60I42SE60 ORckERRoD/uZzTPh7/5YwkKClllTf4Iw2TyXSWRfc0Qw3MAXflv9jX3qK/u67d0ozxB5 4k+mBG2k+zRm4dD5luSrtguFXFDjRcXzcEwCL2DyEpQMGkGOUshzfX9jCjPZFqpKFFJZ d6G6GpeIkcy7nRUzuJBxVebTYqt2HCrxyDyiBYb0r5pN6lNsvrXDxlY389Xm4cgUhtAX mcFA== X-Forwarded-Encrypted: i=1; AJvYcCW9xP7iD1qXWONDBx/EL3E/VyRuZ8xwHsvownB6OgksZ33OS4EvwtPGwUlvv9TMHjTkbAZpooQbaO8mZIKwQGrYhkJIOP82NawJpmsghg== X-Gm-Message-State: AOJu0Yy6M+oRyKwApARYtoC9cu8qq3Z0yTvB7NNy+CWQDAuJcCUDtlsB WItnDzUvPk2mQqfsUr64IMZblHYKA46J04Tas1ts17Abfe2QnyDtH5/DPCuU+NMfP+uaazTvSU/ ylMvx5nogE2+4slM1m2zG60+HVg== X-Google-Smtp-Source: AGHT+IFdexRvcSmQr5+Zf9A7PFK5DHMt79Lyecr2ImLo5Up/lK98Mnn5Aubagnf5Di1TNyTy2AK06begshnaJ81l7cw= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a05:6902:1208:b0:dff:36b3:5c27 with SMTP id 3f1490d57ef6-dff36b35ee5mr1965483276.3.1718647119989; Mon, 17 Jun 2024 10:58:39 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:27 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=4730; i=samitolvanen@google.com; h=from:subject; bh=sgkmHHFnIgB0fgQ5FEpkS1fH49CWjOzk+cSBmlZvE+g=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk7mdNJ1Hcm9wwik+5zWJw3o6X1Gdefgl2+Q 212qRIsZb2JAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5OwAKCRBMtfaEi7xW 7u1+C/448XY4cuyoh1o5pdIihgCKSCltPVNd1wZ0KxjivdxeLSElMgUYpOOKSWRqveG6eWW6YWL moinHkzp12eaFM7TMYWlrc6MuwUnPTXr/a92JXCZGjdoBDNvCFL4zlFZwIo4QDkx52YgoB9IBjH ne0fHUFVbO2/fWoXh8yM6/fxCu8Nr0NG5Qka5f/j7OwtSCzEcUmA2QOItuijUVbbx9xW2znfEt4 zkFmJKpj4Nf5u6/cvKWiUjOHUHZacSjC/V8+R3zitfULsqcEA5pxY/KI4P1FuR88QrbFrnl0KSH FwrC+UU6CAhl+JoO/k3tvRda9irsOkzJWemxL85Skxu9HwhWeh1oN0yNY4WtgiRixmxzrxXRZ6/ /lF3ARzZiC8YyVmJRMaj+qB496LY2oM4HHV1z4ZR9cnwFUYF2mWBTCw0nGHHZ84zNmrW270qb+H D8AnS29U4Osgb5RKQHt3idrpyGaJ2bSAne288Wet5YeVgXh1yE1s8OgJ9J05En5KT77iE= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-25-samitolvanen@google.com> Subject: [PATCH 08/15] gendwarfksyms: Expand subroutine_type From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Add support for expanding DW_TAG_subroutine_type and the parameters in DW_TAG_formal_parameter. Use also to expand subprograms. Example output with --debug: subprogram( formal_parameter base_type usize byte_size(8), formal_parameter base_type usize byte_size(8), ) -> base_type void; Signed-off-by: Sami Tolvanen --- tools/gendwarfksyms/gendwarfksyms.h | 1 + tools/gendwarfksyms/types.c | 58 ++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/tools/gendwarfksyms/gendwarfksyms.h b/tools/gendwarfksyms/gendwarfksyms.h index 43eff91e2f2f..03d8a4a039c3 100644 --- a/tools/gendwarfksyms/gendwarfksyms.h +++ b/tools/gendwarfksyms/gendwarfksyms.h @@ -52,6 +52,7 @@ extern bool no_pretty_print; }) /* Consistent aliases (DW_TAG__type) for DWARF tags */ +#define DW_TAG_formal_parameter_type DW_TAG_formal_parameter #define DW_TAG_typedef_type DW_TAG_typedef /* diff --git a/tools/gendwarfksyms/types.c b/tools/gendwarfksyms/types.c index 74b3755c3e16..a56aeaa4f3a1 100644 --- a/tools/gendwarfksyms/types.c +++ b/tools/gendwarfksyms/types.c @@ -169,6 +169,15 @@ static int process_fqn(struct state *state, struct cached_die *cache, DEFINE_PROCESS_UDATA_ATTRIBUTE(alignment) DEFINE_PROCESS_UDATA_ATTRIBUTE(byte_size) +/* Match functions -- die_match_callback_t */ +#define DEFINE_MATCH(type) \ + static bool match_##type##_type(Dwarf_Die *die) \ + { \ + return dwarf_tag(die) == DW_TAG_##type##_type; \ + } + +DEFINE_MATCH(formal_parameter) + bool match_all(Dwarf_Die *die) { return true; @@ -206,6 +215,25 @@ static int process_type_attr(struct state *state, struct cached_die *cache, return check(process(state, cache, "base_type void")); } +/* Comma-separated with DW_AT_type */ +static int __process_list_type(struct state *state, struct cached_die *cache, + Dwarf_Die *die, const char *type) +{ + check(process(state, cache, type)); + check(process_type_attr(state, cache, die)); + check(process(state, cache, ",")); + return check(process_linebreak(cache, 0)); +} + +#define DEFINE_PROCESS_LIST_TYPE(type) \ + static int process_##type##_type( \ + struct state *state, struct cached_die *cache, Dwarf_Die *die) \ + { \ + return __process_list_type(state, cache, die, #type " "); \ + } + +DEFINE_PROCESS_LIST_TYPE(formal_parameter) + /* Container types with DW_AT_type */ static int __process_type(struct state *state, struct cached_die *cache, Dwarf_Die *die, const char *type) @@ -240,6 +268,30 @@ DEFINE_PROCESS_TYPE(shared) DEFINE_PROCESS_TYPE(volatile) DEFINE_PROCESS_TYPE(typedef) +static int __process_subroutine_type(struct state *state, + struct cached_die *cache, Dwarf_Die *die, + const char *type) +{ + check(process(state, cache, type)); + check(process(state, cache, "(")); + check(process_linebreak(cache, 1)); + /* Parameters */ + check(process_die_container(state, cache, die, process_type, + match_formal_parameter_type)); + check(process_linebreak(cache, -1)); + check(process(state, cache, ")")); + process_linebreak(cache, 0); + /* Return type */ + check(process(state, cache, "-> ")); + return check(process_type_attr(state, cache, die)); +} + +static int process_subroutine_type(struct state *state, + struct cached_die *cache, Dwarf_Die *die) +{ + return check(__process_subroutine_type(state, cache, die, + "subroutine_type")); +} static int process_base_type(struct state *state, struct cached_die *cache, Dwarf_Die *die) { @@ -324,8 +376,11 @@ static int process_type(struct state *state, struct cached_die *parent, PROCESS_TYPE(rvalue_reference) PROCESS_TYPE(shared) PROCESS_TYPE(volatile) + /* Subtypes */ + PROCESS_TYPE(formal_parameter) /* Other types */ PROCESS_TYPE(base) + PROCESS_TYPE(subroutine) PROCESS_TYPE(typedef) default: debug("unimplemented type: %x", tag); @@ -346,7 +401,8 @@ static int process_type(struct state *state, struct cached_die *parent, */ static int process_subprogram(struct state *state, Dwarf_Die *die) { - return check(process(state, NULL, "subprogram;\n")); + check(__process_subroutine_type(state, NULL, die, "subprogram")); + return check(process(state, NULL, ";\n")); } static int process_variable(struct state *state, Dwarf_Die *die) From patchwork Mon Jun 17 17:58:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701139 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 B86AD1991CD for ; Mon, 17 Jun 2024 17:58:42 +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=1718647124; cv=none; b=cY2pMfKKSllI+9P1tu/eC9H6Ba+t6s7tgVV2G3QERm9g4POTVyT3u9Rrnd3HuFqhJLVnPsPHkG5WkBnmoJBMo4ZYrTKrN5vsYtEYYYVTr4/O8qBQciS4/ckEUMRBrllon/3dbbI9xfZTcpfLnB1EvQ1KkNa+rFD5/SCFNUU83/I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647124; c=relaxed/simple; bh=rJM9lNpfTY2lBoAmMOvcqcpNNy6swQ5ugktfxvNPVeE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=cVBv+E/Bpsf+vy9H+5/7juUSX0L9NJZIJyG7+Jw7APYlu5wCS2H0WMCRaPbaWV1NOZ1FPVExM8PYJEvQIhalJfaWzpWiWtM1pT6ENItoLvPks8za5cCGEn5gc1arZEJktW4VM5+SJ1LVnQr2hD8KXo+IcMFqHd2bBfcLiNie0ps= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=wnSWJJpH; 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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="wnSWJJpH" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dfb0e59ac7cso9231884276.0 for ; Mon, 17 Jun 2024 10:58:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647122; x=1719251922; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Al6oYvjeu808n2Qb7f95tGIv0BU5o2UXOdmPU+OQTkI=; b=wnSWJJpHMlDE2N8jK695FyeYxArBhyVJY71ZGU3vrw6N/bWGXrmTyHwo0wiB8kcplR 7jykoAeRYLsmt4IrpfPHfaCA5lTdzfHll5OVEcqWTGOI3i2Ws5wK7bDjyAaS2/y7ietj E0cCEjRaXbjpTfoymeNKu1mkUR8rJhszfcjDe8RIReyHShqWn+uVwUv5Vzb4CplwQgVt Ww7iJ5JXTo6+qa/3u2e+mfR2I+rrdCX5hknIbMWWwlfQxK35r0EzRcWtCG/7zfdFGhXP /JoOc0nzYibK99adlF8A6BWDG6OY8jVl2cEIGk/M4BFibIhIHrEf57noy/k2/AxSsE2i K4kw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647122; x=1719251922; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Al6oYvjeu808n2Qb7f95tGIv0BU5o2UXOdmPU+OQTkI=; b=BbeCGlH3Vp8tSvtfIO31d5rY+ApaDXhJd5hwDFvMKwDRQNjfE1/N7+0ZScioXclyX5 iAkQZHF10n3Rw16wEFHP35Z9KFdyU5GjIa05HBO+N2wut1bNAgf0tj0t6z3tJo0lgtmz 5slJnxmk6VuARKhHjwYeApB9R+RRzdwLcuKo2TpXOu0XTENXVqOZgypozoYVoI8AAdNG I8iiaFo5TA4o4PaHSegZlrsxL6OGM/jSxjyTUCRhdRuWaIr4OuHDBrnh7Tu2RX+i60Th PsSh1GfH4HzIT1U+t9f2hDPAIVXqsxCrLbrZsca/3dXjJy18hkbGD4GthDE7YiYBFjRz C8eQ== X-Forwarded-Encrypted: i=1; AJvYcCVfHnUxkEOE3tV2UxfnXMlu9mrV2juX5xkpjGC+0G7VWHA9R1kwMCTobYRkkpSDsCCbO8pZ/xx5EXuf0oEi8qNuQ1Y+yMjpfQa2ef5AXw== X-Gm-Message-State: AOJu0YyHFf+qOfqT0XCt0QHjf0VlBFks+Ao5JEDrExrNlemGuPkrzHkx fEAHUBgLD89A06J7afYPNT55plNArtKxRnP384JbiVZqu8s37lzPshc/XgSSFwHbXjOTQ+G4f8O Eg1LFe+EKdcO11uOJDG/vdsgJVQ== X-Google-Smtp-Source: AGHT+IGLprv7GhBP6neE3HiuXn2ed+MEUclZy5dU5KGTDqzgVm1AGourYHGVIQ+Ek143H5gX2bqohmq85Q7pvEp2Vbw= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a05:6902:18d4:b0:dff:3a41:3670 with SMTP id 3f1490d57ef6-dff3a4142bdmr2026210276.10.1718647121802; Mon, 17 Jun 2024 10:58:41 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:28 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=2203; i=samitolvanen@google.com; h=from:subject; bh=rJM9lNpfTY2lBoAmMOvcqcpNNy6swQ5ugktfxvNPVeE=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk7A54POYQP2SP+j8e2QM627dstf2daWWvdD RRz32R5XK2JAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5OwAKCRBMtfaEi7xW 7lX6C/9WLHYYGkgA9zTOWpSQYm35c0WbQxcNuSPcsWbNoQtwL814zB9FAEdhTnukWGgPCm6IskJ Se3ziWceeRMGeNGK7EGPhv3sLKZlwJ2/22ydxO+HGcgGTaWY7vqQWRYQSPE790hm71Abu0ncCFP owLv44ow5xhj1G5a6OWMHG+CElCCptz9zEVZJ+onSaO6VUM4UzSUgY8KxnFWXLifWmut/9b6FYB G+Yq64pQM8eI5hfvDztBhKlbY2JWSCL+05/LKfckaQEEMvY9sInhZJpa8c+MEQ36AZTV9Ju7tZZ Kzx5VY8NBFORTz5FaMXWEq1/X00G7gGNS7e5zMIop/cDbCN2P/8RlEV6PENYw5donWYsujdGJ6z 8QQRJuA/Qc3h2rRVzz41sXx35BEGuw0Y5vvHIxMzHMv2SW5O6EtAk/3u8qftF4xtoIK/8Ll2T0s e3hQ9ePdCwjFvR3yxc33wCaDde5ynfAEJJT5bSQlm1clkaxv0ZLMwVbEn9xBTo9MsaWtY= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-26-samitolvanen@google.com> Subject: [PATCH 09/15] gendwarfksyms: Expand array_type From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Add support for expanding DW_TAG_array_type, and the subrange type indicating array size. Example output with --debug: variable array_type [34] { pointer_type { const_type { base_type char byte_size(1) } } }; Signed-off-by: Sami Tolvanen --- tools/gendwarfksyms/types.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tools/gendwarfksyms/types.c b/tools/gendwarfksyms/types.c index a56aeaa4f3a1..b1b82d166eb8 100644 --- a/tools/gendwarfksyms/types.c +++ b/tools/gendwarfksyms/types.c @@ -177,6 +177,7 @@ DEFINE_PROCESS_UDATA_ATTRIBUTE(byte_size) } DEFINE_MATCH(formal_parameter) +DEFINE_MATCH(subrange) bool match_all(Dwarf_Die *die) { @@ -268,6 +269,31 @@ DEFINE_PROCESS_TYPE(shared) DEFINE_PROCESS_TYPE(volatile) DEFINE_PROCESS_TYPE(typedef) +static int process_subrange_type(struct state *state, struct cached_die *cache, + Dwarf_Die *die) +{ + Dwarf_Word count = 0; + + if (get_udata_attr(die, DW_AT_count, &count)) + return check(process_fmt(state, cache, "[%" PRIu64 "]", count)); + + return check(process(state, cache, "[]")); +} + +static int process_array_type(struct state *state, struct cached_die *cache, + Dwarf_Die *die) +{ + check(process(state, cache, "array_type ")); + /* Array size */ + check(process_die_container(state, cache, die, process_type, + match_subrange_type)); + check(process(state, cache, " {")); + check(process_linebreak(cache, 1)); + check(process_type_attr(state, cache, die)); + check(process_linebreak(cache, -1)); + return check(process(state, cache, "}")); +} + static int __process_subroutine_type(struct state *state, struct cached_die *cache, Dwarf_Die *die, const char *type) @@ -378,7 +404,9 @@ static int process_type(struct state *state, struct cached_die *parent, PROCESS_TYPE(volatile) /* Subtypes */ PROCESS_TYPE(formal_parameter) + PROCESS_TYPE(subrange) /* Other types */ + PROCESS_TYPE(array) PROCESS_TYPE(base) PROCESS_TYPE(subroutine) PROCESS_TYPE(typedef) From patchwork Mon Jun 17 17:58:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701140 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 98030199240 for ; Mon, 17 Jun 2024 17:58: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=1718647126; cv=none; b=XJITofCQ65SR2m+QHoFMsebX5+/edoWbhHmKEQZNNgk5Gt94vrZTd9kmp42K5XUvQ40A8XPy/4jIXks7Bz7pjUysPCeDbNL9ziCOtVyu9UCb+PsR2c3mksYIpKFVbVQsIPVcB+ObbdAKmFQ/CqWBl1v+KKFVDhcHdmWENM5y2Ew= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647126; c=relaxed/simple; bh=XIDm/IOcnmSGRDZykPA9liAdqCFSsAd2g1mmllF3ZO0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=kgUXVuC9r8rPUZflvVNNGIaM33UTqa6CSmYWr7OhOoy3baB++0qVE0xtkX6gN7xsWjIFwbmAIOuXLLCRkYs5Q1xg4enintlaIWBdV8tX62OFZ18+cUpgFEXkIhScTmkFmRqJMx6IfnFqzFIKaXSUmPi3b1ieBZoXJRclIUPZzGM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=NLN0bOPB; 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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="NLN0bOPB" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dfb2fc8ca5dso8171656276.1 for ; Mon, 17 Jun 2024 10:58:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647123; x=1719251923; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=nN9pDjuFWWDWuPZRfZeW6v4V3iAJfj5C43zqnVRqXos=; b=NLN0bOPBeo6G5KJa8PwuJ1FOr9ZLKMsBX3nyIVPNzDaD1D4o0l36UAKloQUTw+5Z/U tWWB2qaNp7jzXQm05UHkkRnV1kIaIVi9znylAcnOTWh72zQil+Lv1wLUKqUZBX8AqZ6u 0Y8RTvsDb4rSzV2ieD15abKYe1dRfLdfIlazN+hRZZGhobUiMGsscArhWXRDVl8soAJs sH7lqMepSY/DOye527dfvSZitVzS8XHp2K/DH59gCZEfAvtdVTl5qtkkElgzHI9ijsMw 2BTuuV8Mt4ZT48npbldl8dxmIuj1xzbnSXesweFqhKdpr7Jk2PMF8QUd/NXC6P3Tt+v4 1brA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647123; x=1719251923; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=nN9pDjuFWWDWuPZRfZeW6v4V3iAJfj5C43zqnVRqXos=; b=eKqwFUOE8otnyz4czjFS1qwXsygD7OA9qd9xIuJ4hj2HCPJkA5taEuTLeRIPsGFpWf 8gvw8qkhUeEBbnCmEdVmBKi+vkt1B4br6lguNxO92xcFu+EdxvQQP1C1GiDvpQvzoUSu IMJ2mWS28I6Hp66qpsagaJXWlxHLGZKZYZgSuPZJKvh4kW7IcVfr/dVyIOk2LDBj0MaN 0mO9sLxoxdInGbdxQEtRUdr/4fCiy4o/lCeIaOqQmFSBcaFuoAdg9kYP0xuEiLi3RXJi l2YRQB0FcZMFHgxO5UUVVAppCXw33MTHUTg4s/dKn5KrZGtZp3jBHv6W3F12AFltLFHe ESMA== X-Forwarded-Encrypted: i=1; AJvYcCWTQ1KOOCg7bqsCcI1Kyw38vyf9/21T6qi2JdP0SCRDx5okErwGdjzZ0yE8lnlGthAQxuL0dAIKghTbejlBPhOJqVVXikrIZ4v/UWIfng== X-Gm-Message-State: AOJu0YzWxiCHyC8zAXGgdQdTU9M+3bBuryBfiwgf/9SBXj+U4uxBgaRi +bqOx5HTbwgdiszJv/TskfeAoiWADcdf1yl5Mmv9VitcmdPiedVK4LZjtQImraYttOA728qpfX5 RRh3OvNLK4M/2rP13JjYupeMxLg== X-Google-Smtp-Source: AGHT+IEWDv3pOYrvwbQFA5o/sBoe7ILYQ2yVz2C/LfsP6Bia4brXc9ssd1tO4cjztWz1j+qnoWZQNdQ26oJrCU6dyp8= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a05:6902:e89:b0:dff:9dc:7e41 with SMTP id 3f1490d57ef6-dff154ac5fcmr600120276.11.1718647123620; Mon, 17 Jun 2024 10:58:43 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:29 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=8085; i=samitolvanen@google.com; h=from:subject; bh=XIDm/IOcnmSGRDZykPA9liAdqCFSsAd2g1mmllF3ZO0=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk7VJhBxdyaGyeP6CZ35BcX4LCuWEkv2ceAu 8w6TTBno9SJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5OwAKCRBMtfaEi7xW 7kV5C/9/t2WEwxaXp5A7X/Jzwwu4eUlRlOgiGERWkwIO8MrLCCDZVVuQSj5AgtNeQfcYAFid6Fx IQg4gJHfWPrd2nVn9zu615wnWkIkLFZGxvZySBRpdkKkxSXxTDC7y2C7WWCVCb+aSIOcWpOBeWQ xJ0LXft6UQ1fogWs/K3cMV5A6xQI3sOP7fdXgGDeKpx5Ckll6DZUzILUfurEU2SB6etbr89QXxI N4RSfm77evwX+3g2Bv2yAxoDLd3dbi0COgeGRm8Pg6OCyZ2Eadz4mLNSG5/cAlmNsge0t0+voRu M6khFzFyXj9mro68k5AhZftRwEvUnze5TjUtqtrZJ2ZIATcv0tgPxOlcPXzzTmvSpX0Aoa5FeIL LoPBuL2+BKVLWrt+ij1Bvh8tiZdwB9A71gT7JQ99oGzJEDZ2jVIvfvncC1ru31d/m3NmghKZCJv DWIFMzuIOAHIt0BUGrKfAn6VLtlirM7GOJ7Qvj765vF4JSZdGmIZ+spdu3x3JWmbn+JX4= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-27-samitolvanen@google.com> Subject: [PATCH 10/15] gendwarfksyms: Expand structure types From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Recursively expand DWARF structure types, e.g. structs, unions, and enums. Type strings also encode structure member layout, which allows us to determine ABI breakages if the compiler decides to reorder members or otherwise change the layout. Example output with --debug: subprogram( formal_parameter pointer_type *mut &str { structure_type &str { member pointer_type { base_type u8 byte_size(1) } data_member_location(0), member base_type usize byte_size(8) data_member_location(8), } byte_size(16) alignment(8) }, ) -> base_type void; Signed-off-by: Sami Tolvanen --- tools/gendwarfksyms/gendwarfksyms.h | 5 ++ tools/gendwarfksyms/types.c | 127 +++++++++++++++++++++++++++- 2 files changed, 130 insertions(+), 2 deletions(-) diff --git a/tools/gendwarfksyms/gendwarfksyms.h b/tools/gendwarfksyms/gendwarfksyms.h index 03d8a4a039c3..4646eaf5c85e 100644 --- a/tools/gendwarfksyms/gendwarfksyms.h +++ b/tools/gendwarfksyms/gendwarfksyms.h @@ -52,8 +52,13 @@ extern bool no_pretty_print; }) /* Consistent aliases (DW_TAG__type) for DWARF tags */ +#define DW_TAG_enumerator_type DW_TAG_enumerator #define DW_TAG_formal_parameter_type DW_TAG_formal_parameter +#define DW_TAG_member_type DW_TAG_member +#define DW_TAG_template_type_parameter_type DW_TAG_template_type_parameter #define DW_TAG_typedef_type DW_TAG_typedef +#define DW_TAG_variant_part_type DW_TAG_variant_part +#define DW_TAG_variant_type DW_TAG_variant /* * symbols.c diff --git a/tools/gendwarfksyms/types.c b/tools/gendwarfksyms/types.c index b1b82d166eb8..fa74e6fc26e3 100644 --- a/tools/gendwarfksyms/types.c +++ b/tools/gendwarfksyms/types.c @@ -166,8 +166,10 @@ static int process_fqn(struct state *state, struct cached_die *cache, return 0; \ } +DEFINE_PROCESS_UDATA_ATTRIBUTE(accessibility) DEFINE_PROCESS_UDATA_ATTRIBUTE(alignment) DEFINE_PROCESS_UDATA_ATTRIBUTE(byte_size) +DEFINE_PROCESS_UDATA_ATTRIBUTE(data_member_location) /* Match functions -- die_match_callback_t */ #define DEFINE_MATCH(type) \ @@ -176,8 +178,11 @@ DEFINE_PROCESS_UDATA_ATTRIBUTE(byte_size) return dwarf_tag(die) == DW_TAG_##type##_type; \ } +DEFINE_MATCH(enumerator) DEFINE_MATCH(formal_parameter) +DEFINE_MATCH(member) DEFINE_MATCH(subrange) +DEFINE_MATCH(variant) bool match_all(Dwarf_Die *die) { @@ -222,6 +227,8 @@ static int __process_list_type(struct state *state, struct cached_die *cache, { check(process(state, cache, type)); check(process_type_attr(state, cache, die)); + check(process_accessibility_attr(state, cache, die)); + check(process_data_member_location_attr(state, cache, die)); check(process(state, cache, ",")); return check(process_linebreak(cache, 0)); } @@ -234,6 +241,7 @@ static int __process_list_type(struct state *state, struct cached_die *cache, } DEFINE_PROCESS_LIST_TYPE(formal_parameter) +DEFINE_PROCESS_LIST_TYPE(member) /* Container types with DW_AT_type */ static int __process_type(struct state *state, struct cached_die *cache, @@ -266,6 +274,7 @@ DEFINE_PROCESS_TYPE(reference) DEFINE_PROCESS_TYPE(restrict) DEFINE_PROCESS_TYPE(rvalue_reference) DEFINE_PROCESS_TYPE(shared) +DEFINE_PROCESS_TYPE(template_type_parameter) DEFINE_PROCESS_TYPE(volatile) DEFINE_PROCESS_TYPE(typedef) @@ -318,6 +327,110 @@ static int process_subroutine_type(struct state *state, return check(__process_subroutine_type(state, cache, die, "subroutine_type")); } + +static int process_variant_type(struct state *state, struct cached_die *cache, + Dwarf_Die *die) +{ + return check(process_die_container(state, cache, die, process_type, + match_member_type)); +} + +static int process_variant_part_type(struct state *state, + struct cached_die *cache, Dwarf_Die *die) +{ + check(process(state, cache, "variant_part {")); + check(process_linebreak(cache, 1)); + check(process_die_container(state, cache, die, process_type, + match_variant_type)); + check(process_linebreak(cache, -1)); + check(process(state, cache, "},")); + return check(process_linebreak(cache, 0)); +} + +static int ___process_structure_type(struct state *state, + struct cached_die *cache, Dwarf_Die *die) +{ + switch (dwarf_tag(die)) { + case DW_TAG_member: + case DW_TAG_variant_part: + return check(process_type(state, cache, die)); + case DW_TAG_class_type: + case DW_TAG_enumeration_type: + case DW_TAG_structure_type: + case DW_TAG_template_type_parameter: + case DW_TAG_union_type: + check(process_type(state, cache, die)); + check(process(state, cache, ",")); + return check(process_linebreak(cache, 0)); + case DW_TAG_subprogram: + return 0; /* Skip member functions */ + default: + error("unexpected structure_type child: %x", dwarf_tag(die)); + return -1; + } +} + +static int __process_structure_type(struct state *state, + struct cached_die *cache, Dwarf_Die *die, + const char *type, + die_callback_t process_func, + die_match_callback_t match_func) +{ + check(process(state, cache, type)); + check(process_fqn(state, cache, die)); + check(process(state, cache, " {")); + check(process_linebreak(cache, 1)); + + check(process_die_container(state, cache, die, process_func, + match_func)); + + check(process_linebreak(cache, -1)); + check(process(state, cache, "}")); + + check(process_byte_size_attr(state, cache, die)); + check(process_alignment_attr(state, cache, die)); + + return 0; +} + +#define DEFINE_PROCESS_STRUCTURE_TYPE(structure) \ + static int process_##structure##_type( \ + struct state *state, struct cached_die *cache, Dwarf_Die *die) \ + { \ + return check(__process_structure_type( \ + state, cache, die, #structure "_type ", \ + ___process_structure_type, match_all)); \ + } + +DEFINE_PROCESS_STRUCTURE_TYPE(class) +DEFINE_PROCESS_STRUCTURE_TYPE(structure) +DEFINE_PROCESS_STRUCTURE_TYPE(union) + +static int process_enumerator_type(struct state *state, + struct cached_die *cache, Dwarf_Die *die) +{ + Dwarf_Word value; + + check(process(state, cache, "enumerator ")); + check(process_fqn(state, cache, die)); + + if (get_udata_attr(die, DW_AT_const_value, &value)) { + check(process(state, cache, " = ")); + check(process_fmt(state, cache, "%" PRIu64, value)); + } + + check(process(state, cache, ",")); + return check(process_linebreak(cache, 0)); +} + +static int process_enumeration_type(struct state *state, + struct cached_die *cache, Dwarf_Die *die) +{ + return check(__process_structure_type(state, cache, die, + "enumeration_type ", process_type, + match_enumerator_type)); +} + static int process_base_type(struct state *state, struct cached_die *cache, Dwarf_Die *die) { @@ -402,17 +515,27 @@ static int process_type(struct state *state, struct cached_die *parent, PROCESS_TYPE(rvalue_reference) PROCESS_TYPE(shared) PROCESS_TYPE(volatile) + /* Container types */ + PROCESS_TYPE(class) + PROCESS_TYPE(structure) + PROCESS_TYPE(union) + PROCESS_TYPE(enumeration) /* Subtypes */ + PROCESS_TYPE(enumerator) PROCESS_TYPE(formal_parameter) + PROCESS_TYPE(member) PROCESS_TYPE(subrange) + PROCESS_TYPE(template_type_parameter) + PROCESS_TYPE(variant) + PROCESS_TYPE(variant_part) /* Other types */ PROCESS_TYPE(array) PROCESS_TYPE(base) PROCESS_TYPE(subroutine) PROCESS_TYPE(typedef) default: - debug("unimplemented type: %x", tag); - break; + error("unexpected type: %x", tag); + return -1; } if (!no_cache) { From patchwork Mon Jun 17 17:58:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701141 Received: from mail-pl1-f202.google.com (mail-pl1-f202.google.com [209.85.214.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 1919519925C for ; Mon, 17 Jun 2024 17:58:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647127; cv=none; b=eS5lWc97fiXVc6xXGijf+HRijO97Evivo2EnI5Q4Q+qPqTfRS2frUZwIOWiTSlp298nqS8TC2PqsGfuh7mr2UmWO7sMUSHZFoVW0+LsV2jH5xC/ENo5bAXfFhoN+Vvk8Lik084gbxVPB4IxD8eLfh57uKolQmFHBkUAqygp5kW8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647127; c=relaxed/simple; bh=5QGYkwk/E4Q6+rrK8r8Qc7nJUUivw+COjNp3jkT0e4c=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=roHdR2xu0W6qAFya0skwibJ31kU2+fdmS4xN4JXseQA6Qq4VEGnydSd/NkS/gmxIn46WiBHyJ/xxqxPaTkTQQwY3ZFqqCSDjPmOX/G3evZQ+bQYGIoN6Z0G33H3g+tcDGRqe53tw8TXDaie2HyKZqakA2pd+e6pCKh7VGb7OmnI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=iXz3uAKZ; arc=none smtp.client-ip=209.85.214.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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="iXz3uAKZ" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-1f717559ed9so46009115ad.1 for ; Mon, 17 Jun 2024 10:58:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647125; x=1719251925; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=HJS2qGel4yduzddYByEwVYwl3lRWbRkhbTBiPKp6MJw=; b=iXz3uAKZCrCWghYIvjohFkJ6vRF9lz1mbVCpSKEB/Tkp+JB9LPaZYzcMsL7mKGAYRl WvxeMng4y/EdAHiAjPYJj46V6IjNlpzhZeINF+LNYCDmCKZJRJeUYF4edSQzXaH4yfDe srvIKKq3QTxL6CE38KCpIjzQJoV9kpiNXb/mM20ncgDmg53MlWZ/11UIITMtSLMHYYaI w0JglBiHwF+1Nc2kB8/rQMt55UD7zpCs9G6HY19fT9vwHGw7DJvH8tDwxQmXvbSsHo9n ft4guXJuG9ZaXzgOv3/6HpOPQDC+ZWaXt+EG/WjKlKfqciI9wiXAws3TegOge6bbLLt/ Y70g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647125; x=1719251925; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=HJS2qGel4yduzddYByEwVYwl3lRWbRkhbTBiPKp6MJw=; b=B8jVGlcMntMpYP1/jc5aqMA/smYHaQ786BWoGeI4z4d448MwP4IDZfSFh8QgfvXKBK 6xAyD91/XYro/6hbyTtz1lH+IAvZ/4lWFoQtRb/hUsWSPq7xr9NhXc68vBLBAdhES77D ZF6BRGYzZIj1IgHgUBGntIFeLA1z25RjKQMGZewbxOfyy1LpjCZoyMFIHeuVTH2Q0yPJ w9qb0FQOD7jiaeVxqVlexIWszKdjcb1zpa0Ycd5pd/zQxT+bwBeksUrrZMfkptvX8DO6 sT+Vzz+C0a26fF+/n0f/wus8j3wTpUnsGmftsuQP8/4hQOr/naz7u5L027diuf2/krvn YB5g== X-Forwarded-Encrypted: i=1; AJvYcCVTAX4N/u0ZRhcvaWaeejPg0dUXbzb2jVvM/izrx2MBSXMMJxmPJTvYaFHM67K6dk2LlAQRptKg5/Yr0Bxw1yPsEnVPvrsE/FH11ToC4w== X-Gm-Message-State: AOJu0YwHjBz+9v2Fio8UZaD5onNpNLRvC+OKpQ8sC1+v4GoNdhJVDxfh DSpA+NV5zshTxQDGseC7aN+6uq3ZiOhPPcUcZx4eB+n7S5a7qo5kjYQB09rzPGJHzBdimb3JdgA 4FlR81hUMZa8p/9jgsMzXD5tATA== X-Google-Smtp-Source: AGHT+IHKjC0CX34pVUQa0Y9ornsY1/i5bBR74aqDPFW/EAbpIF5+uvTPtCpotMJonL0QUGth2SATiIUukrIzaTeaK4E= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a17:902:e844:b0:1f7:1046:d68e with SMTP id d9443c01a7336-1f98b2219aamr78555ad.2.1718647125429; Mon, 17 Jun 2024 10:58:45 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:30 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=7777; i=samitolvanen@google.com; h=from:subject; bh=5QGYkwk/E4Q6+rrK8r8Qc7nJUUivw+COjNp3jkT0e4c=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk74/KgDUBKZV1popDzLuA1ek3BXMxcD3VZW UgpxTvuAOaJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5OwAKCRBMtfaEi7xW 7lHEDACSFEate7TcAPTNQ4VH8+1rvGKNRy8wDm6Wogha8iHjE2xIT43/mQo3hROAVqmGPCSkE32 hkohns20j3NH5LfafCAGjKGhxZsbj45Kdn7AFuTSnkGtl4ECfEJey22w+/nuN3REdRqgxfmMkHI NlPZ5EjzUbkbYis2utWtxpYVZqbp5nJE84yxMyRcAZ4soi5urhHbrfrxkf+NE+c8HoXYktaPLev sEJaOA0fhjb4SPvjB/ka5gKBzKfXWhtd/+lOnlH1PSh6cjOSISo/iOFrILp2qDT+xtd39yc5JVI WXNeKbYAfsXjEYmgoQ12w9P2p+2o4gWQFk//vt6oHF0+l7cqKt+qZsUxSWqwhgedNuqak6mVZ+N +feeicpA/NEz1AYhDPAsC2ntCbFFkZkE7USv6x6bsQc4juevI35vYQkzYS4NWHyc114AxKA81pL 3i/wGpEEuPNREU6RybCZiSy0wP5sDp335z1IXSkf2s03lrV2NzbhcWlcqZVpQRbaXbv4U= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-28-samitolvanen@google.com> Subject: [PATCH 11/15] gendwarfksyms: Limit structure expansion From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Expand each structure type only once per exported symbol. This is necessary to support self-referential structures, which would otherwise result in infinite recursion. Expanding each structure type just once is enough to catch ABI changes. For pointers to structure types, limit expansion to three levels inside the pointer. This should be plenty for catching ABI differences and stops us from pulling in half the kernel for structs that contain pointers to large structs like task_struct. Signed-off-by: Sami Tolvanen --- tools/gendwarfksyms/cache.c | 49 ++++++++++++++++ tools/gendwarfksyms/gendwarfksyms.h | 9 ++- tools/gendwarfksyms/types.c | 87 ++++++++++++++++++++++++++--- 3 files changed, 136 insertions(+), 9 deletions(-) diff --git a/tools/gendwarfksyms/cache.c b/tools/gendwarfksyms/cache.c index 85a2adeb649d..1d6eb27d799d 100644 --- a/tools/gendwarfksyms/cache.c +++ b/tools/gendwarfksyms/cache.c @@ -158,3 +158,52 @@ int cache_add_die(struct cached_die *cd, Dwarf_Die *die) ci->type = DIE; return 0; } + +/* A list of structure types that were already expanded for the current symbol */ +struct expanded { + uintptr_t addr; + struct hlist_node hash; +}; + +/* die->addr -> struct expanded */ +DEFINE_HASHTABLE(expansion_cache, DIE_HASH_BITS); + +int cache_mark_expanded(Dwarf_Die *die) +{ + struct expanded *es; + + es = malloc(sizeof(struct expanded)); + if (!es) { + error("malloc failed"); + return -1; + } + + es->addr = (uintptr_t)die->addr; + hash_add(expansion_cache, &es->hash, es->addr); + return 0; +} + +bool cache_was_expanded(Dwarf_Die *die) +{ + struct expanded *es; + uintptr_t addr = (uintptr_t)die->addr; + + hash_for_each_possible(expansion_cache, es, hash, addr) { + if (es->addr == addr) + return true; + } + + return false; +} + +void cache_clear_expanded(void) +{ + struct hlist_node *tmp; + struct expanded *es; + int i; + + hash_for_each_safe(expansion_cache, i, tmp, es, hash) { + free(es); + } + hash_init(expansion_cache); +} diff --git a/tools/gendwarfksyms/gendwarfksyms.h b/tools/gendwarfksyms/gendwarfksyms.h index 4646eaf5c85e..568f3727017e 100644 --- a/tools/gendwarfksyms/gendwarfksyms.h +++ b/tools/gendwarfksyms/gendwarfksyms.h @@ -95,7 +95,7 @@ struct cached_item { struct cached_item *next; }; -enum cached_die_state { INCOMPLETE, COMPLETE }; +enum cached_die_state { INCOMPLETE, UNEXPANDED, COMPLETE }; struct cached_die { enum cached_die_state state; @@ -111,6 +111,10 @@ extern int cache_add_linebreak(struct cached_die *pd, int linebreak); extern int cache_add_die(struct cached_die *pd, Dwarf_Die *die); extern void cache_free(void); +extern int cache_mark_expanded(Dwarf_Die *die); +extern bool cache_was_expanded(Dwarf_Die *die); +extern void cache_clear_expanded(void); + /* * types.c */ @@ -120,6 +124,9 @@ struct state { Dwarf *dbg; struct symbol *sym; Dwarf_Die origin; + unsigned int ptr_expansion_depth; + bool in_pointer_type; + bool expand; unsigned long crc; }; diff --git a/tools/gendwarfksyms/types.c b/tools/gendwarfksyms/types.c index fa74e6fc26e3..da3aa2ad9f57 100644 --- a/tools/gendwarfksyms/types.c +++ b/tools/gendwarfksyms/types.c @@ -381,14 +381,21 @@ static int __process_structure_type(struct state *state, check(process(state, cache, " {")); check(process_linebreak(cache, 1)); - check(process_die_container(state, cache, die, process_func, - match_func)); + if (state->expand) { + check(cache_mark_expanded(die)); + check(process_die_container(state, cache, die, process_func, + match_func)); + } else { + check(process(state, cache, "")); + } check(process_linebreak(cache, -1)); check(process(state, cache, "}")); - check(process_byte_size_attr(state, cache, die)); - check(process_alignment_attr(state, cache, die)); + if (state->expand) { + check(process_byte_size_attr(state, cache, die)); + check(process_alignment_attr(state, cache, die)); + } return 0; } @@ -475,9 +482,38 @@ static int process_cached(struct state *state, struct cached_die *cache, static void state_init(struct state *state) { + state->ptr_expansion_depth = 0; + state->in_pointer_type = false; + state->expand = true; state->crc = 0xffffffff; } +static void state_restore(struct state *state, struct state *saved) +{ + state->ptr_expansion_depth = saved->ptr_expansion_depth; + state->in_pointer_type = saved->in_pointer_type; + state->expand = saved->expand; +} + +static void state_save(struct state *state, struct state *saved) +{ + state_restore(saved, state); +} + +static bool is_pointer_type(int tag) +{ + return tag == DW_TAG_pointer_type || tag == DW_TAG_reference_type; +} + +static bool is_expanded_type(int tag) +{ + return tag == DW_TAG_class_type || tag == DW_TAG_structure_type || + tag == DW_TAG_union_type || tag == DW_TAG_enumeration_type; +} + +/* The maximum depth for expanding structures in pointers */ +#define MAX_POINTER_EXPANSION_DEPTH 3 + #define PROCESS_TYPE(type) \ case DW_TAG_##type##_type: \ check(process_##type##_type(state, cache, die)); \ @@ -486,19 +522,52 @@ static void state_init(struct state *state) static int process_type(struct state *state, struct cached_die *parent, Dwarf_Die *die) { + enum cached_die_state want_state = COMPLETE; struct cached_die *cache = NULL; + struct state saved; int tag = dwarf_tag(die); + state_save(state, &saved); + /* - * If we have the DIE already cached, use it instead of walking + * Structures and enumeration types are expanded only once per + * exported symbol. This is sufficient for detecting ABI changes + * within the structure. + * + * If the exported symbol contains a pointer to a structure, + * at most MAX_POINTER_EXPANSION_DEPTH levels are expanded into + * the referenced structure. + */ + state->in_pointer_type = saved.in_pointer_type || is_pointer_type(tag); + + if (state->in_pointer_type && + state->ptr_expansion_depth >= MAX_POINTER_EXPANSION_DEPTH) + state->expand = false; + else + state->expand = saved.expand && !cache_was_expanded(die); + + /* Keep track of pointer expansion depth */ + if (state->expand && state->in_pointer_type && is_expanded_type(tag)) + state->ptr_expansion_depth++; + + /* + * If we have want_state already cached, use it instead of walking * through DWARF. */ if (!no_cache) { - check(cache_get(die, COMPLETE, &cache)); + if (!state->expand && is_expanded_type(tag)) + want_state = UNEXPANDED; + + check(cache_get(die, want_state, &cache)); + + if (cache->state == want_state) { + if (want_state == COMPLETE && is_expanded_type(tag)) + check(cache_mark_expanded(die)); - if (cache->state == COMPLETE) { check(process_cached(state, cache, die)); check(cache_add_die(parent, die)); + + state_restore(state, &saved); return 0; } } @@ -540,10 +609,11 @@ static int process_type(struct state *state, struct cached_die *parent, if (!no_cache) { /* Update cache state and append to the parent (if any) */ - cache->state = COMPLETE; + cache->state = want_state; check(cache_add_die(parent, die)); } + state_restore(state, &saved); return 0; } @@ -596,6 +666,7 @@ static int process_exported_symbols(struct state *state, else check(process_variable(state, die)); + cache_clear_expanded(); return check( symbol_set_crc(state->sym, state->crc ^ 0xffffffff)); default: From patchwork Mon Jun 17 17:58:31 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701142 Received: from mail-pf1-f201.google.com (mail-pf1-f201.google.com [209.85.210.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 AEDEF1993AE for ; Mon, 17 Jun 2024 17:58:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647130; cv=none; b=rjfYMGsb8eqzapHd5NNEr47f+eYulxnICpr7TNfF8QN6Q2KY1FD80r5ZPCj2ELQp1qva5X/7NKwdaoqzQPoscPrqZRON8k0FjhNKmCVUjxet2oGy8p3E37OyyWD1bOdxascb/a6pg2H9MgICeihMZrW/w7nv7x+U4k5PxZtaUME= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647130; c=relaxed/simple; bh=E8SnT3PVNgwvs9gIA8r8UmB9RILzIMEk5mxRikJC8gY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=P74R/Sk8M8hqyeDo1hsLaBcn6Xe319jcVYBvvxWkwVyyQZs294f/PHuO9BI5AaOyWSKzoBSdRz/HNa/H/tW8Sq4sUT1K9CTXtz9g0bo7utc+xkc2M7Qzfoekt1jHdaQ3VHHvhOxMpTNgEFtCWBSZ7V2sOnMfVCISsiGQivCqWf4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=fX/hZuTq; arc=none smtp.client-ip=209.85.210.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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="fX/hZuTq" Received: by mail-pf1-f201.google.com with SMTP id d2e1a72fcca58-70419ef7f48so4339060b3a.1 for ; Mon, 17 Jun 2024 10:58:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647127; x=1719251927; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=Q78REyi52sqkWL03kuxiNz+yyQ9ejPgzHXaQsMRmJ8I=; b=fX/hZuTqdTeAAo+DEk3WrIyHJWpdonvIf+ID2BSTh4xCRom+PH6qNyDxtwDFBoZXRU oZNqogRuNmblU8ioPf6xerIHKwgHPk1rYGhHa9XahbpsEa3VY21rq92JU2Uap16YzUUo 3cycS/qKR7M+UjPoEYsBiMjb2/2tgzVRejR0quU9dgh4Ym+HjdpfOiZHAQq+CFrfWEC2 ff+IUyw2R7nRYPms+RcdX0ommm17Q8U357Vv4ihI7y0V7kSUNINkmg7iwgeVw0h4YAgU gaP9T7jU1B0Lh5FJHiUhWJtQpH66u8fsBRNsBMjR3FCqljOPZftdmKV9QGMJpOQVvW9U LbfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647127; x=1719251927; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Q78REyi52sqkWL03kuxiNz+yyQ9ejPgzHXaQsMRmJ8I=; b=YvhUD2CUpU4+o4EDQQ01ctjTYVBfbnH06U55CSp9pKI6K4OJgosR2zcAUS94r5q9YY 6NgQ8I8vIM3XyI9EI2p2UzgpOmXXIPx9gOYKeZIeHKpJoTPW5P7UmcW95J7t+tbi0lO7 qKH3HdLdhc8OpDSsnoXorVtGo/AFWPqB920ypc0zHMUe7q7cLO6Pgrjf6tNJiaQsMKGI /Mm7mVuO4VDUuTQ9C+zblyLpWvZt/yz9LBbly38kCA1hLV+EitEI5DgyuLPIrF9sIrly 21lMv8UXS6fsFHSxmAEob4fXDwVYl1ExpO4TSFreq0yut/N+uA+O+ggzzORHxg2rEWkD IvXQ== X-Forwarded-Encrypted: i=1; AJvYcCXneBlEyrS2vtX5bqauz/zviCJdGOoavtAJsU+XK7Np0PfGwWZmUYIylsjx59qqWf7Ek5vRoLJNsK2gJpmiDvqmg9SbhDQDhefkW/RrLw== X-Gm-Message-State: AOJu0YznV+NNWhEyetUT9xZWc0xMZqaD1hyrQsYHznEnCatFy/Sg5Y6K 5Dm1rkDqEqbSLfBJ+w27KcTI8KOgto3z5d5ma4LzPkRBCKZy1PRMrqcfzxBsjBG/8Ql08ZvSBC1 qkDm8PHTprDVHWZo4sFJhGWcWHw== X-Google-Smtp-Source: AGHT+IG7Ue5DJDS1N7DP4tCk4vCEgaA5IoS5ykSNmz1WLMo+HqkFJZ34S73K58/Xvvf2E+rzd0MQkiPOgpUx01THRW4= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a05:6a00:1d9a:b0:705:d750:83dd with SMTP id d2e1a72fcca58-7061a9cd714mr1634b3a.0.1718647126976; Mon, 17 Jun 2024 10:58:46 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:31 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=5421; i=samitolvanen@google.com; h=from:subject; bh=E8SnT3PVNgwvs9gIA8r8UmB9RILzIMEk5mxRikJC8gY=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk8Bb1DCi99v6wb89Vda/7vwSnIbRDTw0ABB IYi86zqYneJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5PAAKCRBMtfaEi7xW 7nsZC/0fY4b4nIhSqSmetH7M+TuHCSDRTPXYnz6APqYIR82AgLo3SR3Ca+zpPFziHT1Rvik7uWJ zbbTbE32fF7R6lopcUh6k6qh+cctPuAvDyN8CkOqnb/8lMAbFPb0xZNnZmHyEjgeccTLmusU9yX VqNaEs5SIhiDoST8A4iAJMwnAOzKKXMm7X4nfZ7cL+RsMBIGAf4C0WnoszRDD6GbfLh1gMumKVa KQ0XD7c9cne4LvKv8m8s/9Hp0SJnsVYdXWB86YueROeGhYVSflI5wsXS5UvNa3XoZO9JFhXUJTS 8YlBnQpE/+EWz8rZXdKYdz3Q4SIk9ZiRVwpqA8Cj1uZm2toAw2ht99lvfXleE4nwg3xo3QWft/R J5ca6acXIjNTxb2jWVqlWkNSbF+OZZ58Q55ETL83qi2OALARh0OSMBx0XhNS6zAd/gwFgyR2TZK mD/JQPyoZ0uxXu2y905BawVVBWgkgJ5zuEvfYGUg9b7LdKl6n7oFmM+LHBAOeTGft9HD8= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-29-samitolvanen@google.com> Subject: [PATCH 12/15] gendwarfksyms: Add inline debugging From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Understanding the operation and caching of the tool can be somewhat challenging without a debugger. Add inline debugging information with the --inline-debug command, which adds highlighted tags to the --debug output with information about cache states etc. Signed-off-by: Sami Tolvanen --- tools/gendwarfksyms/gendwarfksyms.c | 3 +++ tools/gendwarfksyms/gendwarfksyms.h | 29 +++++++++++++++++++++++++++++ tools/gendwarfksyms/types.c | 14 ++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/tools/gendwarfksyms/gendwarfksyms.c b/tools/gendwarfksyms/gendwarfksyms.c index 7095f0ecccab..acf4b44238e2 100644 --- a/tools/gendwarfksyms/gendwarfksyms.c +++ b/tools/gendwarfksyms/gendwarfksyms.c @@ -15,6 +15,8 @@ /* Print type descriptions and debugging output to stderr */ bool debug; +/* Print inline debugging information to stderr (with --debug) */ +bool inline_debug; /* Don't use caching */ bool no_cache; /* Don't pretty-print (with --debug) */ @@ -25,6 +27,7 @@ static const struct { bool *flag; } options[] = { { "--debug", &debug }, + { "--inline-debug", &inline_debug }, { "--no-cache", &no_cache }, { "--no-pretty-print", &no_pretty_print }, }; diff --git a/tools/gendwarfksyms/gendwarfksyms.h b/tools/gendwarfksyms/gendwarfksyms.h index 568f3727017e..34d1be3cfb7f 100644 --- a/tools/gendwarfksyms/gendwarfksyms.h +++ b/tools/gendwarfksyms/gendwarfksyms.h @@ -18,6 +18,7 @@ * Options -- in gendwarfksyms.c */ extern bool debug; +extern bool inline_debug; extern bool no_cache; extern bool no_pretty_print; @@ -38,6 +39,18 @@ extern bool no_pretty_print; #define warn(format, ...) __println("warning: ", format, ##__VA_ARGS__) #define error(format, ...) __println("error: ", format, ##__VA_ARGS__) +#define __inline_debug(color, format, ...) \ + do { \ + if (debug && inline_debug) \ + fprintf(stderr, \ + "\033[" #color "m<" format ">\033[39m", \ + __VA_ARGS__); \ + } while (0) + +#define inline_debug_r(format, ...) __inline_debug(91, format, __VA_ARGS__) +#define inline_debug_g(format, ...) __inline_debug(92, format, __VA_ARGS__) +#define inline_debug_b(format, ...) __inline_debug(94, format, __VA_ARGS__) + /* * Error handling helpers */ @@ -51,6 +64,9 @@ extern bool no_pretty_print; __res; \ }) +/* + * DWARF helpers + */ /* Consistent aliases (DW_TAG__type) for DWARF tags */ #define DW_TAG_enumerator_type DW_TAG_enumerator #define DW_TAG_formal_parameter_type DW_TAG_formal_parameter @@ -97,6 +113,19 @@ struct cached_item { enum cached_die_state { INCOMPLETE, UNEXPANDED, COMPLETE }; +static inline const char *cache_state_name(enum cached_die_state state) +{ + switch (state) { + default: + case INCOMPLETE: + return "INCOMPLETE"; + case UNEXPANDED: + return "UNEXPANDED"; + case COMPLETE: + return "COMPLETE"; + } +} + struct cached_die { enum cached_die_state state; uintptr_t addr; diff --git a/tools/gendwarfksyms/types.c b/tools/gendwarfksyms/types.c index da3aa2ad9f57..694b33cdd606 100644 --- a/tools/gendwarfksyms/types.c +++ b/tools/gendwarfksyms/types.c @@ -97,6 +97,7 @@ static int process(struct state *state, struct cached_die *cache, const char *s) fputs(s, stderr); state->crc = partial_crc32(s, state->crc); + inline_debug_r("cache %p string '%s'", cache, s); return cache_add_string(cache, s); } @@ -456,6 +457,8 @@ static int process_cached(struct state *state, struct cached_die *cache, while (ci) { switch (ci->type) { case STRING: + inline_debug_b("cache %p STRING '%s'", cache, + ci->data.str); check(process(state, NULL, ci->data.str)); break; case LINEBREAK: @@ -468,6 +471,8 @@ static int process_cached(struct state *state, struct cached_die *cache, error("dwarf_die_addr_die failed"); return -1; } + inline_debug_b("cache %p DIE addr %lx tag %d", cache, + ci->data.addr, dwarf_tag(&child)); check(process_type(state, NULL, &child)); break; default: @@ -561,6 +566,9 @@ static int process_type(struct state *state, struct cached_die *parent, check(cache_get(die, want_state, &cache)); if (cache->state == want_state) { + inline_debug_g("cached addr %p tag %d -- %s", die->addr, + tag, cache_state_name(cache->state)); + if (want_state == COMPLETE && is_expanded_type(tag)) check(cache_mark_expanded(die)); @@ -572,6 +580,9 @@ static int process_type(struct state *state, struct cached_die *parent, } } + inline_debug_g("addr %p tag %d -- INCOMPLETE -> %s", die->addr, tag, + cache_state_name(want_state)); + switch (tag) { /* Type modifiers */ PROCESS_TYPE(atomic) @@ -608,6 +619,9 @@ static int process_type(struct state *state, struct cached_die *parent, } if (!no_cache) { + inline_debug_r("parent %p cache %p die addr %p tag %d", parent, + cache, die->addr, tag); + /* Update cache state and append to the parent (if any) */ cache->state = want_state; check(cache_add_die(parent, die)); From patchwork Mon Jun 17 17:58:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701143 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 CE1B7199E9D for ; Mon, 17 Jun 2024 17:58:49 +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=1718647131; cv=none; b=rJ9PAvZGyvciSkFXkZzCV9gsN3k3hT0DIGEwJLOOyTUVZ+sc6XJqwAVP0XRFhXyywKO+9e91O6dwoxlEjKVXVdLU71r4x1KgyV6sVVykugdYYLi66/jsWkoumvoSqxmom/7A3HTO0aVMPWIpZ/ehuhu60BzvJp3FDasEFkhoakk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647131; c=relaxed/simple; bh=XeWLpjfbip2cG1reCp5fuwFDg0zCF0I9155zvse/ZJc=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=LugDzyPUEiJ0whxHN9HK4ZDWRQIyBXiGhB3BOWntUM86AN4m8inz0vb3hw4B7tIBtXi7UKSHjmCdwafONej+UFP75O6SWR/DT/lm3uyiAqlMD+sEPASF/iR5IAq3560dJcxDbo3JF3aVU3loSkZvaOpvn9PZJsYeAzV/ySmpPLw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=3uizPohl; 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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="3uizPohl" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-dff189c7e65so6230254276.1 for ; Mon, 17 Jun 2024 10:58:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647129; x=1719251929; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=aDtl7Q8+dGnVJgz6nefcFJrXDgszLOVdSnX1Gj5oN2E=; b=3uizPohlTjkm97ZKCTgoicwbxM9i1iCPVr6bvS97D6Ht17k5/qElTf+8k37moWd3OE nPxD/sTOpm4IZuJFN+MeQ4TTaZj7U51jg4lpn2Pjr9DjiAZHo+vXAuyvfdJgEhwQMCq1 K+WmRjqcPfBGHQjnAJ6gP/DED4GalvLYQXjfT1eQwhFPGQXW/8RuPq5/xoRDislZ7hvG 52epP5bJ+iSBHPUxXIZKPRMUFZqAApFd1vjfdUyRaiAg63uXjJAQpANyzVqXMZKVfLl9 EWoGCRKJuynNWPtmS6KPzdAmodUlfjK3q0kA5COCUAbFHnunz4gtLwEf5zaH73wY0IQm AtVQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647129; x=1719251929; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=aDtl7Q8+dGnVJgz6nefcFJrXDgszLOVdSnX1Gj5oN2E=; b=LL50pdO45twi5XOCDmoGTEAr8lWgpCSYPeCBDfKlBL+3OaM66YI7HILQpxJS15jGxT kZ1ziAwBhjH20FfHOe2PsfplXGj7xEvDZ1H6HBB3oNhDxl92a7eXTIeyLlIusJ3Y/sMp W66gd1ecm/v94jWrbJvfZ2p+2FY615ztH4lZiboxVzm+pfGx1JrRn3RosI2dM8Cr3Y/f S1aKNMY0EkEIIA3/5cBxYLpIHxSfCNf4ZmD99ba+ilS/cZzTi2Dec0pYxS4GQC6KjIDq CQTUriGq9UKn6R9758XdcGCeWdZByovUYsxAw8pbM/13LAoC7dPErIjO5+R6zXilnhPz xCPQ== X-Forwarded-Encrypted: i=1; AJvYcCU+79dqIUmpekdV24Qb4p4ZSz1MO9v95/VgWe6Ps+kpPaPjheleMFxsdMGIvS742hGTw0KeBNm9l/v0YasxrDSvrKaPawvyOirw3qu5ZA== X-Gm-Message-State: AOJu0YyG6D4R1+l73RBpjJ7gfUkFvn/5ekhAdElBUyz6Q7hN8opdC/G1 yrD6VPra7Awbm5gHvc1cqWWIvYYJaoZGSrvgT0xWlaR4JYmRlR9ZxRXf4qT98H5Shv4M+iNlA4T nf7eccMQ6CoB+u5LyFjqxFyfU8A== X-Google-Smtp-Source: AGHT+IEPsCaMFfOkZ8T4Tiv95vdcZi2tL3ndrzRupJFWeE1D/DO1qf/1J5PcAqULyuJkAvIHq9t4JZEnvngWo+4TUXg= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a05:6902:100f:b0:dfd:d6ec:4e3b with SMTP id 3f1490d57ef6-dff15399367mr3619876276.7.1718647128807; Mon, 17 Jun 2024 10:58:48 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:32 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=14655; i=samitolvanen@google.com; h=from:subject; bh=XeWLpjfbip2cG1reCp5fuwFDg0zCF0I9155zvse/ZJc=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk8BR59D/orRkAZgweMqljSH/+OkombAD0jp 16TM3Cl+yaJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5PAAKCRBMtfaEi7xW 7jtDC/9KMOiJdtqQmd5yxeu9lQtRLDPRU8fXZcwwe+m9L7fQNt9m4tEmVkD3cHo/0qJynlRygzR FGxxenl3OadcMMwHEvQAwL7+xbzS1xmPGA8q3/GH++yL86nlY+UiqEgaoCJ1Zt16Una6K5aixt/ Szt3xHwLJXzIGX5LXdZp1WpLCmjMqYaPcLyj0+RFSr35a/aaSNVLkrYe0CNuhXGWsEEnXJz+Z8H hQTPFOU4r/TgqI616+OjNX7HCZYDzVLTsciRVWN0BPq1ybvfdNgzs2t6j8fvbDqIeNmDu2f/Hct +FUEKr8RNFf4y38ml9Z/uCE8/EsW6ZDBJoaGrF+cdKvoJi+weBxDr55cvCTpXDzn1A2ry5sv6MP +KA22t/oizWEYDimLLtTU3Bb63Kxh8GcUzfDlhEi3XtEpeVXVTLo8lay3cKTqwGGucIlunlNaNc dS9rxJGLfpk0e9RqjLHahC4/ao+yAQXfT4D0YhK6iPicI/Bq1MnYK4l/Uoo/SPN8ogtTs= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-30-samitolvanen@google.com> Subject: [PATCH 13/15] modpost: Add support for hashing long symbol names From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Rust frequently has symbol names longer than MODULE_NAME_LEN, because the full namespace path is encoded into the mangled name. Instead of modpost failing when running into a long name with CONFIG_MODVERSIONS, store a hash of the name in struct modversion_info. To avoid breaking userspace tools that parse the __versions array, include a null-terminated hash function name at the beginning of the name string, followed by a binary hash. In order to keep .mod.c files more human-readable, add a comment with the full symbol name before the array entry. Example output in rust_minimal.mod.c: static const struct modversion_info ____versions[] __used __section("__versions") = { /* _RNvNtNtCs1cdwasc6FUb_6kernel5print14format_strings4INFO */ { 0x9ec5442f, "sha256\x00\x56\x96\xf4\x27\xdb\x4a\xbf[...]" }, { 0x1d6595b1, "_RNvNtCs1cdwasc6FUb_6kernel5print11call_printk" }, { 0x3c642974, "__rust_dealloc" }, ... }; modprobe output for the resulting module: $ modprobe --dump-modversions rust_minimal.ko 0x9ec5442f sha256 0x1d6595b1 _RNvNtCs1cdwasc6FUb_6kernel5print11call_printk 0x3c642974 __rust_dealloc ... While the output is less useful, the tool continues to work and can be later updated to produce more helpful output for hashed symbols. Note that this patch adds a generic SHA-256 implementation to modpost adapted from the Crypto API, but other hash functions may be used in future if needed. Suggested-by: Matthew Maurer Signed-off-by: Sami Tolvanen --- scripts/mod/Makefile | 4 +- scripts/mod/modpost.c | 20 ++- scripts/mod/modpost.h | 20 +++ scripts/mod/symhash.c | 327 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 364 insertions(+), 7 deletions(-) create mode 100644 scripts/mod/symhash.c diff --git a/scripts/mod/Makefile b/scripts/mod/Makefile index c729bc936bae..ddd59ea9027e 100644 --- a/scripts/mod/Makefile +++ b/scripts/mod/Makefile @@ -4,7 +4,7 @@ CFLAGS_REMOVE_empty.o += $(CC_FLAGS_LTO) hostprogs-always-y += modpost mk_elfconfig always-y += empty.o -modpost-objs := modpost.o file2alias.o sumversion.o symsearch.o +modpost-objs := modpost.o file2alias.o symhash.o sumversion.o symsearch.o devicetable-offsets-file := devicetable-offsets.h @@ -15,7 +15,7 @@ targets += $(devicetable-offsets-file) devicetable-offsets.s # dependencies on generated files need to be listed explicitly -$(obj)/modpost.o $(obj)/file2alias.o $(obj)/sumversion.o $(obj)/symsearch.o: $(obj)/elfconfig.h +$(obj)/modpost.o $(obj)/file2alias.o $(obj)/symhash.o $(obj)/sumversion.o $(obj)/symsearch.o: $(obj)/elfconfig.h $(obj)/file2alias.o: $(obj)/$(devicetable-offsets-file) quiet_cmd_elfconfig = MKELF $@ diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index f48d72d22dc2..2631e3e75a5c 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1900,7 +1900,10 @@ static void add_exported_symbols(struct buffer *buf, struct module *mod) **/ static void add_versions(struct buffer *b, struct module *mod) { + char hash[SYMHASH_STR_LEN]; struct symbol *s; + const char *name; + size_t len; if (!modversions) return; @@ -1917,13 +1920,20 @@ static void add_versions(struct buffer *b, struct module *mod) s->name, mod->name); continue; } - if (strlen(s->name) >= MODULE_NAME_LEN) { - error("too long symbol \"%s\" [%s.ko]\n", - s->name, mod->name); - break; + len = strlen(s->name); + /* + * For symbols with a long name, use the hash format, but include + * the full symbol name as a comment to keep the generated files + * human-readable. + */ + if (len >= MODULE_NAME_LEN) { + buf_printf(b, "\t/* %s */\n", s->name); + name = symhash_str(s->name, len, hash); + } else { + name = s->name; } buf_printf(b, "\t{ %#8x, \"%s\" },\n", - s->crc, s->name); + s->crc, name); } buf_printf(b, "};\n"); diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index ee43c7950636..cd2eb718936b 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -183,6 +183,26 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, Elf_Sym *sym, const char *symname); void add_moddevtable(struct buffer *buf, struct module *mod); +/* symhash.c */ +/* + * For symbol names longer than MODULE_NAME_LEN, encode a hash of the + * symbol name in version information as follows: + * + * \0 + * + * e.g. as a string in .mod.c files: + * "sha256\x00\xNN{32}" + * + * The string is null terminated after the hash name to avoid breaking + * userspace tools that parse the __versions table and don't understand + * the format. + */ +#define SYMHASH_STR_PREFIX "sha256\\x00" +#define SYMHASH_STR_PREFIX_LEN (sizeof(SYMHASH_STR_PREFIX) - 1) +#define SYMHASH_STR_LEN (SYMHASH_STR_PREFIX_LEN + 4*32 + 1) + +char *symhash_str(const char *name, size_t len, char hash_str[SYMHASH_STR_LEN]); + /* sumversion.c */ void get_src_version(const char *modname, char sum[], unsigned sumlen); diff --git a/scripts/mod/symhash.c b/scripts/mod/symhash.c new file mode 100644 index 000000000000..d0c9cf5f1f6c --- /dev/null +++ b/scripts/mod/symhash.c @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * symhash.c + * + * Symbol name hashing using a SHA-256 implementation adapted from the + * Cryptographic API. + */ +#include +#include "modpost.h" + +#if HOST_ELFDATA == ELFDATA2MSB +/* Big endian */ +#define be32_to_cpu(val) (val) +#define cpu_to_be32(val) (val) +#define cpu_to_be64(val) (val) +#else +/* Little endian */ +#define be32_to_cpu(val) bswap_32(val) +#define cpu_to_be32(val) bswap_32(val) +#define cpu_to_be64(val) bswap_64(val) +#endif + +#define barrier_data(ptr) __asm__ __volatile__("": :"r"(ptr) :"memory") + +static inline void memzero_explicit(void *s, size_t count) +{ + memset(s, 0, count); + barrier_data(s); +} + +static inline uint32_t ror32(uint32_t word, unsigned int shift) +{ + return (word >> (shift & 31)) | (word << ((-shift) & 31)); +} + +/* + * include/crypto/sha2.h - Common values for SHA-2 algorithms + */ +#define SHA256_DIGEST_SIZE 32 +#define SHA256_BLOCK_SIZE 64 + +#define SHA256_H0 0x6a09e667UL +#define SHA256_H1 0xbb67ae85UL +#define SHA256_H2 0x3c6ef372UL +#define SHA256_H3 0xa54ff53aUL +#define SHA256_H4 0x510e527fUL +#define SHA256_H5 0x9b05688cUL +#define SHA256_H6 0x1f83d9abUL +#define SHA256_H7 0x5be0cd19UL + +struct sha256_state { + uint32_t state[SHA256_DIGEST_SIZE / 4]; + uint64_t count; + uint8_t buf[SHA256_BLOCK_SIZE]; +}; + +static inline void sha256_init(struct sha256_state *sctx) +{ + sctx->state[0] = SHA256_H0; + sctx->state[1] = SHA256_H1; + sctx->state[2] = SHA256_H2; + sctx->state[3] = SHA256_H3; + sctx->state[4] = SHA256_H4; + sctx->state[5] = SHA256_H5; + sctx->state[6] = SHA256_H6; + sctx->state[7] = SHA256_H7; + sctx->count = 0; +} + +/* + * include/crypto/sha256_base.h - core logic for SHA-256 implementations + * + * Copyright (C) 2015 Linaro Ltd + */ +typedef void (sha256_block_fn)(struct sha256_state *sst, uint8_t const *src, + int blocks); + +static inline int lib_sha256_base_do_update(struct sha256_state *sctx, + const uint8_t *data, + unsigned int len, + sha256_block_fn *block_fn) +{ + unsigned int partial = sctx->count % SHA256_BLOCK_SIZE; + + sctx->count += len; + + if ((partial + len) >= SHA256_BLOCK_SIZE) { + int blocks; + + if (partial) { + int p = SHA256_BLOCK_SIZE - partial; + + memcpy(sctx->buf + partial, data, p); + data += p; + len -= p; + + block_fn(sctx, sctx->buf, 1); + } + + blocks = len / SHA256_BLOCK_SIZE; + len %= SHA256_BLOCK_SIZE; + + if (blocks) { + block_fn(sctx, data, blocks); + data += blocks * SHA256_BLOCK_SIZE; + } + partial = 0; + } + if (len) + memcpy(sctx->buf + partial, data, len); + + return 0; +} + +static inline int lib_sha256_base_do_finalize(struct sha256_state *sctx, + sha256_block_fn *block_fn) +{ + const int bit_offset = SHA256_BLOCK_SIZE - sizeof(uint64_t); + uint64_t *bits = (uint64_t *)(sctx->buf + bit_offset); + unsigned int partial = sctx->count % SHA256_BLOCK_SIZE; + + sctx->buf[partial++] = 0x80; + if (partial > bit_offset) { + memset(sctx->buf + partial, 0x0, SHA256_BLOCK_SIZE - partial); + partial = 0; + + block_fn(sctx, sctx->buf, 1); + } + + memset(sctx->buf + partial, 0x0, bit_offset - partial); + *bits = cpu_to_be64(sctx->count << 3); + block_fn(sctx, sctx->buf, 1); + + return 0; +} + +static inline int lib_sha256_base_finish(struct sha256_state *sctx, uint8_t *out, + unsigned int digest_size) +{ + uint32_t *digest = (uint32_t *)out; + int i; + + for (i = 0; digest_size > 0; i++, digest_size -= sizeof(uint32_t)) + *digest++ = cpu_to_be32(sctx->state[i]); + + memzero_explicit(sctx, sizeof(*sctx)); + return 0; +} + +/* + * lib/crypto/sha256.c + * + * SHA-256, as specified in + * http://csrc.nist.gov/groups/STM/cavp/documents/shs/sha256-384-512.pdf + * + * SHA-256 code by Jean-Luc Cooke . + * + * Copyright (c) Jean-Luc Cooke + * Copyright (c) Andrew McDonald + * Copyright (c) 2002 James Morris + * Copyright (c) 2014 Red Hat Inc. + */ +static const uint32_t SHA256_K[] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, +}; + +static inline uint32_t Ch(uint32_t x, uint32_t y, uint32_t z) +{ + return z ^ (x & (y ^ z)); +} + +static inline uint32_t Maj(uint32_t x, uint32_t y, uint32_t z) +{ + return (x & y) | (z & (x | y)); +} + +#define e0(x) (ror32(x, 2) ^ ror32(x, 13) ^ ror32(x, 22)) +#define e1(x) (ror32(x, 6) ^ ror32(x, 11) ^ ror32(x, 25)) +#define s0(x) (ror32(x, 7) ^ ror32(x, 18) ^ (x >> 3)) +#define s1(x) (ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10)) + +static inline void LOAD_OP(int I, uint32_t *W, const uint8_t *input) +{ + W[I] = be32_to_cpu(*((__uint32_t *)input + I)); +} + +static inline void BLEND_OP(int I, uint32_t *W) +{ + W[I] = s1(W[I-2]) + W[I-7] + s0(W[I-15]) + W[I-16]; +} + +#define SHA256_ROUND(i, a, b, c, d, e, f, g, h) do { \ + uint32_t t1, t2; \ + t1 = h + e1(e) + Ch(e, f, g) + SHA256_K[i] + W[i]; \ + t2 = e0(a) + Maj(a, b, c); \ + d += t1; \ + h = t1 + t2; \ +} while (0) + +static void sha256_transform(uint32_t *state, const uint8_t *input, uint32_t *W) +{ + uint32_t a, b, c, d, e, f, g, h; + int i; + + /* load the input */ + for (i = 0; i < 16; i += 8) { + LOAD_OP(i + 0, W, input); + LOAD_OP(i + 1, W, input); + LOAD_OP(i + 2, W, input); + LOAD_OP(i + 3, W, input); + LOAD_OP(i + 4, W, input); + LOAD_OP(i + 5, W, input); + LOAD_OP(i + 6, W, input); + LOAD_OP(i + 7, W, input); + } + + /* now blend */ + for (i = 16; i < 64; i += 8) { + BLEND_OP(i + 0, W); + BLEND_OP(i + 1, W); + BLEND_OP(i + 2, W); + BLEND_OP(i + 3, W); + BLEND_OP(i + 4, W); + BLEND_OP(i + 5, W); + BLEND_OP(i + 6, W); + BLEND_OP(i + 7, W); + } + + /* load the state into our registers */ + a = state[0]; b = state[1]; c = state[2]; d = state[3]; + e = state[4]; f = state[5]; g = state[6]; h = state[7]; + + /* now iterate */ + for (i = 0; i < 64; i += 8) { + SHA256_ROUND(i + 0, a, b, c, d, e, f, g, h); + SHA256_ROUND(i + 1, h, a, b, c, d, e, f, g); + SHA256_ROUND(i + 2, g, h, a, b, c, d, e, f); + SHA256_ROUND(i + 3, f, g, h, a, b, c, d, e); + SHA256_ROUND(i + 4, e, f, g, h, a, b, c, d); + SHA256_ROUND(i + 5, d, e, f, g, h, a, b, c); + SHA256_ROUND(i + 6, c, d, e, f, g, h, a, b); + SHA256_ROUND(i + 7, b, c, d, e, f, g, h, a); + } + + state[0] += a; state[1] += b; state[2] += c; state[3] += d; + state[4] += e; state[5] += f; state[6] += g; state[7] += h; +} + +static void sha256_transform_blocks(struct sha256_state *sctx, + const uint8_t *input, int blocks) +{ + uint32_t W[64]; + + do { + sha256_transform(sctx->state, input, W); + input += SHA256_BLOCK_SIZE; + } while (--blocks); + + memzero_explicit(W, sizeof(W)); +} + +static void sha256_update(struct sha256_state *sctx, const uint8_t *data, unsigned int len) +{ + lib_sha256_base_do_update(sctx, data, len, sha256_transform_blocks); +} + +static void __sha256_final(struct sha256_state *sctx, uint8_t *out, int digest_size) +{ + lib_sha256_base_do_finalize(sctx, sha256_transform_blocks); + lib_sha256_base_finish(sctx, out, digest_size); +} + +static void sha256_final(struct sha256_state *sctx, uint8_t *out) +{ + __sha256_final(sctx, out, 32); +} + +char *symhash_str(const char *name, size_t len, char hash_str[SYMHASH_STR_LEN]) +{ + static const char hex[] = "0123456789abcdef"; + uint8_t hash[SHA256_DIGEST_SIZE]; + struct sha256_state sctx; + char *p = hash_str; + + /* + * If the symbol name has an initial dot, dedotify it before hashing to match + * PPC64 behavior in arch/powerpc/kernel/module_64.c. + */ + if (name[0] == '.') { + name++; + len--; + } + + sha256_init(&sctx); + sha256_update(&sctx, (const uint8_t *)name, len); + sha256_final(&sctx, hash); + + /* Null-terminated prefix */ + memcpy(p, SYMHASH_STR_PREFIX, SYMHASH_STR_PREFIX_LEN); + p += SYMHASH_STR_PREFIX_LEN; + + /* Binary hash */ + for (int i = 0; i < SHA256_DIGEST_SIZE; i++) { + *p++ = '\\'; + *p++ = 'x'; + *p++ = hex[(hash[i] & 0xf0) >> 4]; + *p++ = hex[hash[i] & 0x0f]; + } + + hash_str[SYMHASH_STR_LEN - 1] = '\0'; + return hash_str; +} From patchwork Mon Jun 17 17:58:33 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701144 Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.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 62B8A19A286 for ; Mon, 17 Jun 2024 17:58:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647133; cv=none; b=pnSQ6S2v5JsqBDhYozQVzvM95VELjPRPiAhBsvG8qwX6qFvJDdNDQ+b2kj93TCHMuV987FccmBqxdhp9wpeDFQ9BY/XyMNZ1ZTE5CEStEXog4GIyFpMVvac3wPOq0dCXxjroAwfhjnkak+RQ0ovBtR7xe8cWdq7jzleul76tDes= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647133; c=relaxed/simple; bh=qxjnDPhbkT2bqk3JUgXG+OMT2L0q9TuqyeH9xgQXlZY=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=fuSDumGWKOcMD9GkoRFX15fIgQNqeF8ZSV5UHPzVG6wcj+eukr/EWtN9GEyrdzWZQIWUfKEH0+PlPcLcStrtam8syRwm6ZSWhWd7tNnt725PeQ3XrISpdVNvqjzx5j1mtmqLi99vfgK4V1RIOTkYiITNhX12s03W/oSAWd4VIfE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Ntve6mM6; arc=none smtp.client-ip=209.85.128.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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Ntve6mM6" Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-631b498f981so66798037b3.0 for ; Mon, 17 Jun 2024 10:58:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647130; x=1719251930; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=FepdhZeTk2P/UGpz1yHjDkWXnUR5Ic7EpV5t8vA3VJ8=; b=Ntve6mM6DKbaoATCL/7rMMqKbS9RdvB9UiL/y3A3x3g0guz27tUYPP8v5pFjwjQ0Le X2SfN8OMi80AMvct+25h3aXEXiNgkl49ZzSBD5zMWU5tef8xdOxr7E82rWpOTGj90of+ uSD6IaLzoa9In3pCqBjrYBPldTfG3+FEHgArJ8dk3NzpRtQZGnqHl0CyVvNXDzoi93tL zXerhRSEUfiaO2aEtmsntV7ZEXdUiQ77hTjOvKvYFBH1VW0vzMHnV5444J3A928kzmmU p7qltGWrgmjeR77D4Yc/MqPP3CGGM9WOHZgB4uu8SiR78Xl11lHDTaWCql62P91C8Kbn fKSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647130; x=1719251930; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=FepdhZeTk2P/UGpz1yHjDkWXnUR5Ic7EpV5t8vA3VJ8=; b=R/L/e64DS0y0DTqhIQgB1q5oz3mSDA5Mip8cGWGmYjLkh1mrDBr/2TtK03U4UAOdle qfIzC/yi1eg0xLLojzbuT3bUDJeevkwnW4s7EVi2j/ukGL0NEGdrCs+bi46lqv0oLRVs WrR8zthpsRvcPObQcIi3amMdrfpi1yjf5HeqEOW9UuWxJHK/AqErNOVUzrzw9H0XZks9 MjbaDaZT2QDwOtXtoIGMxBVoZ2o4UR1Izz9FySPiPkZ23o2nwa1DkSrXVycvG1ArwMHe EPq3Yo2WZ0veeV8TYjQ7ruoqcyUa4eAUzuujUpfT6+I+FW6IvlOFmsa/c2pZ+NL+SnZy fnSw== X-Forwarded-Encrypted: i=1; AJvYcCXtL1VJSWphO5WME6Q+/89hhFoYmFfraSJ2tlS6PTW6fg3ZB1/2VC5xahJeWcGfykQ8Lzrc7pfW+4kyH1oe3u2NK1+JGnBxZ850bZClZQ== X-Gm-Message-State: AOJu0Yy+w6yir8UVpKiS+RW3VHQCCpKzpS4ekwu3PXIBNxTFPz0ZgtiS l1TsoqEfL1rQUGo0BWwW8y9RuyNtLIIA7CpJeC7GIQ6h07/par7KmX2fVNsqVfk3Zwos1xGVszz VmT7x2ZjgHDUTHqeWmk44dqUzLg== X-Google-Smtp-Source: AGHT+IEKWMn41cQguv0qNaedPOXvzvvCPGUBW2Ai4IEXCZr+AQfjcwobN3pE2EUdIwaI2VHKh5POsClBLW5Uwl1z0o0= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a05:690c:4a0f:b0:62c:de05:5a78 with SMTP id 00721157ae682-6322402cc6cmr27980207b3.6.1718647130513; Mon, 17 Jun 2024 10:58:50 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:33 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=2620; i=samitolvanen@google.com; h=from:subject; bh=qxjnDPhbkT2bqk3JUgXG+OMT2L0q9TuqyeH9xgQXlZY=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk8BkgxPBOcTFd109aXG7GZv2GPe3nQuIQTV +Ps+2NQwXmJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5PAAKCRBMtfaEi7xW 7jz9C/4irEUBFYs+I2aOmFliiJGDZqYDERdlWQJY/S2Kbp2uY4rgt0ooq54+mWm/RT29dZRw1qu wzZiFq3yJ5kfWTI7Em5p8rOwLLsAlr8cATc+M//wemnhZOM4pYjVxleLdFdht0Smp1bVohtkM2Y 6x+zf+KwjcDE2nYxWr8hqpjFF6idGlQnuBq47MhzEJaSmyy1WJjtqddvn3gxNCaBcwcBv4Vnp4Q fyDZHNKoqZGdfiwqWKvgOynjGMAotjb3BvoI9d9AkP/qR3F1pN7IFWM6xgqCDeGCaDl9Eu68/rQ kbPtux6ew2Ox0cVDiVjQOLDnxLOHyDgFsK2a9JCSJaJzMxyugaZIRPpv7fyLYrsK/hCI/y0q+GM uKT5ReLVoA31RS7SnoKjUGgYi0DOUw+OIuPcX5qP11TCp4+Y8hrnzAXxNy6zByYL3wJujL5fTCV 7m+q7O8nwVMrXXoKTpARpZ4LqG+8Ui3OUm+s92JY1f3ZicqYMkl4sJUtTMrAc9Q799oLY= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-31-samitolvanen@google.com> Subject: [PATCH 14/15] module: Support hashed symbol names when checking modversions From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen When checking modversions for symbol names longer than MODULE_NAME_LEN, look for the hashed symbol name instead. This is needed for Rust modules, which frequently use symbol names longer than the maximum length supported by struct modversion_info. Suggested-by: Matthew Maurer Signed-off-by: Sami Tolvanen --- kernel/module/version.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/kernel/module/version.c b/kernel/module/version.c index 53f43ac5a73e..0b33ca085138 100644 --- a/kernel/module/version.c +++ b/kernel/module/version.c @@ -8,8 +8,36 @@ #include #include #include +#include #include "internal.h" +/* + * For symbol names longer than MODULE_NAME_LEN, the version table includes + * a hash of the symbol name in the following format: + * + * \0 + */ +#define SYMHASH_PREFIX "sha256" +#define SYMHASH_PREFIX_LEN sizeof(SYMHASH_PREFIX) /* includes \0 */ +#define SYMHASH_LEN (SYMHASH_PREFIX_LEN + SHA256_DIGEST_SIZE) + +static void symhash(const char *name, size_t len, u8 hash[SYMHASH_LEN]) +{ + memcpy(hash, SYMHASH_PREFIX, SYMHASH_PREFIX_LEN); + sha256(name, len, &hash[SYMHASH_PREFIX_LEN]); +} + +static int symcmp(const char *version_name, const char *name, size_t len, + const u8 *hash) +{ + BUILD_BUG_ON(SYMHASH_LEN > MODULE_NAME_LEN); + + if (len >= MODULE_NAME_LEN) + return memcmp(version_name, hash, SYMHASH_LEN); + + return strcmp(version_name, name); +} + int check_version(const struct load_info *info, const char *symname, struct module *mod, @@ -19,6 +47,8 @@ int check_version(const struct load_info *info, unsigned int versindex = info->index.vers; unsigned int i, num_versions; struct modversion_info *versions; + u8 hash[SYMHASH_LEN]; + size_t len; /* Exporting module didn't supply crcs? OK, we're already tainted. */ if (!crc) @@ -32,10 +62,16 @@ int check_version(const struct load_info *info, num_versions = sechdrs[versindex].sh_size / sizeof(struct modversion_info); + len = strlen(symname); + + /* For symbols with a long name, use the hash format. */ + if (len >= MODULE_NAME_LEN) + symhash(symname, len, hash); + for (i = 0; i < num_versions; i++) { u32 crcval; - if (strcmp(versions[i].name, symname) != 0) + if (symcmp(versions[i].name, symname, len, hash) != 0) continue; crcval = *crc; From patchwork Mon Jun 17 17:58:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13701145 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 0AC06192B88 for ; Mon, 17 Jun 2024 17:58:53 +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=1718647134; cv=none; b=HsKVNMmE0Uo58CuRrWBzjUAX1KzXL75F7WbN6No0UQTYmwAVDop6SvdlsZ5mKO6ksf5NMcUpc9MDVZRWS/YBSckmHZtdVWnGziyvRFfwsfTbrkCZvIzFNE9m/l1wzmIKXPT9uAuUloKydkEmUq8cIRg8dazZnJ63Z07z3Zsp6ZU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718647134; c=relaxed/simple; bh=fgkHPoIfKV45x9z/FkKUVFWMMp1fQbapxOYrE3e+eC0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=RkypiJk8IE1CDGwW/AFvhulNV8sqWz5E8HKpbYFmPLcXDeE8rPDdZXAdtAKQLZT/2smVKIxqtFEXQ1GVcp6H+tQVODNvrAyBvMsswTMT3pjwILj5H9rzsUbKuT45kteKqDi4o/g4EmbhbOCANFQWCPFOgKJ8wpOmtq20kk/23Mw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--samitolvanen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=dX/YX/jm; 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--samitolvanen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dX/YX/jm" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-dc691f1f83aso2010199276.1 for ; Mon, 17 Jun 2024 10:58:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1718647132; x=1719251932; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=bLYk6wjWkl3juH0J6ovTQNRSOAciGZLb1YErRTCUnNY=; b=dX/YX/jmYd3sn8Pm4eMUMr9zmf5njHWQXEJKDY14VnL8yfKXGT03KATgH/1uhZ0z4j ekgFoIej7jr6trCy75t5T9iUqTQH+88MkT3Z9hkc+6L+OG+6mbEanFp44pNd2cNqHMWZ dSSW4YBua3kFRd4DUT6oYPFNaBVdHeyCOJaplPtzr32obEebpkAxkQ3kcjZ60OlCWCYS KQ8u3JUDLiYD0pHx065dUx/5L+6DFdprv3xefHXLt7vKaK45zBMWm2DjU7VrVhvQbwUl IFBLg82Gq/uvunSht0hos4EszJSNnbOOB5t/g14tUSBMQCRlNGDv8jpkvgYmkBFCuE8J 8qRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1718647132; x=1719251932; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=bLYk6wjWkl3juH0J6ovTQNRSOAciGZLb1YErRTCUnNY=; b=X0Que+Wu/Mx3pOWzs9hJv3cGouK6sdZoWJpmEuRwPAAIltr1Z8/TrDYtaz7cVt/5jx DAkcctBVDT33gxne65QII9G+61h4kDD2HCbdC3YMV1qUaWrTXDaHJ0SyaPi0JKJQYoBB Rc28a6GRf2qR+eCCyT45/3AL3a/u5+o9rvIawwXLZxsCIX++vbZRfeId0o4rZ50YhWdq NdelPecWaGXK6JiF7v6P2ghuJT6tny8zi0mtGrLYEF2T6T3dwgnHBzn+eEgfV7XMoLMj IEfkMR1jznLEqMjkO6S7b1FKp+089gEbz7i/wcX1P9GNhNe2TYCT9ZThTdp3QiMDonsL GIEQ== X-Forwarded-Encrypted: i=1; AJvYcCWD+EUEdBwShnhrMXxLSarBDhmTN0PGby0RKs2ZEtGIrzZid8Vt1dJMJCivvKmpQNomtJbWXiXwOFohq6+PWSWyodHYSmacUnZVGBK+mg== X-Gm-Message-State: AOJu0YzAjysQ0jC+Ds9JcQpOwxYzhw8XO06vYcoRwTjIP20WhGYS54L6 LeBazTBurYnPpw3gbe4xJYZaFCzKDhxoIRrd3TEVsu8Gu+QPja9IBANBaNciI66iAXc5FIw/Io4 /3LAZTWPkaSk28ZNBC34o7kS/pw== X-Google-Smtp-Source: AGHT+IGQ0kaxipcpN+AMKyQsL99MKALkBH0wZMe834vcYOvJGUzDPB28UULwwd+JdyoFZzcBb+pYU7AhTng+2Qb9itM= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a25:ab0d:0:b0:dff:1d27:4b80 with SMTP id 3f1490d57ef6-e022392641amr44457276.4.1718647132243; Mon, 17 Jun 2024 10:58:52 -0700 (PDT) Date: Mon, 17 Jun 2024 17:58:34 +0000 In-Reply-To: <20240617175818.58219-17-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240617175818.58219-17-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=4578; i=samitolvanen@google.com; h=from:subject; bh=fgkHPoIfKV45x9z/FkKUVFWMMp1fQbapxOYrE3e+eC0=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmcHk8LDHvXIagYgFxknPxDdn8T7FgRTBtTGHds CYsT4RaZamJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZnB5PAAKCRBMtfaEi7xW 7pyDC/wIk2JiSe2ugPHTOqu/njY6MVYno9CbIgmrLTZ0ZnVep6zki2FMFDLiAE29rs9ul7uERoe 61Q5nEgznEwOdDHFzHScSXRFFoIbNTAZJ8Too04vEMhHatyd3+r0J2sUPSbk5objzs2RBjWXVOJ +HJWS9xd2kwA1WEvGODVBo6k9WX26WKsxUR6ug0YZ4DCsBRj8/JdygTUEhnZm3zDlIsh3CChA1Q OP24DTzd0veW8UhuU6HasbiKGeld/Zpc++SJ+9CxSycH6XJxzvNyf/t4xVP8K4iBAk3fNxhWNVZ dEpMWHA9qOyST2nWwEzUDxDuX6Ops1r74rScwidUizuA1wKxCJKhysN+R87QRIyjdeQ4Wd76LR5 cC7hwZKIR9/KlC6lKe/HylfxgeRl39fveo5Lf820BN2nuDjjapNM8sf049Fdl+IRJKiEn3zGPgq 1GceOJLEwD2pwfTdrYjejSqR7O7OwIFPUK0Uz8eJtceNHcXGCizMdAadlBQdgE8z/kaXc= X-Mailer: git-send-email 2.45.2.627.g7a2c4fd464-goog Message-ID: <20240617175818.58219-32-samitolvanen@google.com> Subject: [PATCH 15/15] kbuild: Use gendwarfksyms to generate Rust symbol versions From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Use gendwarfksyms to generate symbol versions for exported Rust symbols, and allow CONFIG_MODVERSIONS to be enabled with CONFIG_RUST, assuming the debugging information needed by gendwarfksyms is also available. Signed-off-by: Sami Tolvanen --- Makefile | 6 ++++++ init/Kconfig | 2 +- rust/Makefile | 30 ++++++++++++++++++++++++------ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 14427547dc1e..0701917c5172 100644 --- a/Makefile +++ b/Makefile @@ -1344,6 +1344,12 @@ prepare: tools/bpf/resolve_btfids endif endif +ifdef CONFIG_MODVERSIONS +ifdef CONFIG_RUST +prepare: tools/gendwarfksyms +endif +endif + PHONY += resolve_btfids_clean resolve_btfids_O = $(abspath $(objtree))/tools/bpf/resolve_btfids diff --git a/init/Kconfig b/init/Kconfig index 72404c1f2157..ef29f002e932 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1903,7 +1903,7 @@ config RUST depends on HAVE_RUST depends on RUST_IS_AVAILABLE depends on !CFI_CLANG - depends on !MODVERSIONS + depends on !MODVERSIONS || (DEBUG_INFO && !DEBUG_INFO_REDUCED && !DEBUG_INFO_SPLIT) depends on !GCC_PLUGINS depends on !RANDSTRUCT depends on !DEBUG_INFO_BTF || PAHOLE_HAS_LANG_EXCLUDE diff --git a/rust/Makefile b/rust/Makefile index f70d5e244fee..385cdf5dc320 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -356,10 +356,11 @@ $(obj)/bindings/bindings_helpers_generated.rs: private bindgen_target_extra = ; $(obj)/bindings/bindings_helpers_generated.rs: $(src)/helpers.c FORCE $(call if_changed_dep,bindgen) +rust_exports = $(NM) -p --defined-only $(1) | awk '/ (T|R|D) / { printf $(2),$(3) }' + quiet_cmd_exports = EXPORTS $@ cmd_exports = \ - $(NM) -p --defined-only $< \ - | awk '/ (T|R|D) / {printf "EXPORT_SYMBOL_RUST_GPL(%s);\n",$$3}' > $@ + $(call rust_exports,$<,"EXPORT_SYMBOL_RUST_GPL(%s);\n",$$3) > $@ $(obj)/exports_core_generated.h: $(obj)/core.o FORCE $(call if_changed,exports) @@ -420,12 +421,29 @@ ifneq ($(or $(CONFIG_ARM64),$(and $(CONFIG_RISCV),$(CONFIG_64BIT))),) __ashlti3 __lshrti3 endif +ifdef CONFIG_MODVERSIONS +# When module versioning is enabled, calculate symbol versions from the DWARF +# debugging information. We can't use a source code parser like genksyms, +# because the source files don't have information about the final structure +# layout and emitted symbols. +gendwarfksyms := $(objtree)/tools/gendwarfksyms/gendwarfksyms + +cmd_gendwarfksyms = \ + $(call rust_exports,$@,"%s %s\n",$$1$(comma)$$3) \ + | $(gendwarfksyms) $@ >> $(dot-target).cmd +endif + +define rule_rustc_library_with_exports + $(call cmd_and_fixdep,rustc_library) + $(call cmd,gendwarfksyms) +endef + $(obj)/core.o: private skip_clippy = 1 $(obj)/core.o: private skip_flags = -Dunreachable_pub $(obj)/core.o: private rustc_objcopy = $(foreach sym,$(redirect-intrinsics),--redefine-sym $(sym)=__rust$(sym)) $(obj)/core.o: private rustc_target_flags = $(core-cfgs) $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs FORCE - +$(call if_changed_dep,rustc_library) + +$(call if_changed_rule,rustc_library_with_exports) ifdef CONFIG_X86_64 $(obj)/core.o: scripts/target.json endif @@ -438,7 +456,7 @@ $(obj)/alloc.o: private skip_clippy = 1 $(obj)/alloc.o: private skip_flags = -Dunreachable_pub $(obj)/alloc.o: private rustc_target_flags = $(alloc-cfgs) $(obj)/alloc.o: $(RUST_LIB_SRC)/alloc/src/lib.rs $(obj)/compiler_builtins.o FORCE - +$(call if_changed_dep,rustc_library) + +$(call if_changed_rule,rustc_library_with_exports) $(obj)/build_error.o: $(src)/build_error.rs $(obj)/compiler_builtins.o FORCE +$(call if_changed_dep,rustc_library) @@ -447,7 +465,7 @@ $(obj)/bindings.o: $(src)/bindings/lib.rs \ $(obj)/compiler_builtins.o \ $(obj)/bindings/bindings_generated.rs \ $(obj)/bindings/bindings_helpers_generated.rs FORCE - +$(call if_changed_dep,rustc_library) + +$(call if_changed_rule,rustc_library_with_exports) $(obj)/uapi.o: $(src)/uapi/lib.rs \ $(obj)/compiler_builtins.o \ @@ -458,6 +476,6 @@ $(obj)/kernel.o: private rustc_target_flags = --extern alloc \ --extern build_error --extern macros --extern bindings --extern uapi $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/alloc.o $(obj)/build_error.o \ $(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE - +$(call if_changed_dep,rustc_library) + +$(call if_changed_rule,rustc_library_with_exports) endif # CONFIG_RUST