From patchwork Thu Aug 15 17:39:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765016 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 EA1644AEE9 for ; Thu, 15 Aug 2024 17:39:15 +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=1723743557; cv=none; b=g9RHex9FSHxrqA/t/LQCkz7D+wmE6AwlMzMJ451CXesCuvuCfNDWTcYJJtNJD8fDQYq1DuPgYq3TZP0JI6gW4dkn/tgbyUgm6vPuuLPT/fSwPb7e56ZALrPLefz9AW3plocStqSie+935JUy81ZtBNcE9bABjKgaT1Qxqk0HTjo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743557; c=relaxed/simple; bh=bxNi2EoDMx8FMXT38cuDVktpfAT2lY3rDO58JAquwyI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Dy2BOTnYk0fwt3y0D8aaYFxTw2WCVikLslvSAAoPh//B4m4BvQl3XNndA/LB9p0LBJPh5XMN4JeeMdQhwaQ2nn/no3UclcxsXBy2LpUhx2qKdQM5f4gIScJAzEqLv+PvdOwLp0IrsxEbLJKBQ237yIZAj5rIjfRQldStHGyvONA= 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=lRmZryVA; 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="lRmZryVA" Received: by mail-yb1-f201.google.com with SMTP id 3f1490d57ef6-e116b9b670eso1941916276.3 for ; Thu, 15 Aug 2024 10:39:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743555; x=1724348355; 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=qNdMzoDNg3SBOXN5kIH+J4L0OFXsoxTK6BvqXkHiFPI=; b=lRmZryVAuljBTeCQQ5Pg/29DbAh358SPMGDjmQoQYPniBMCNl06C/2+RO9c7NRzVcI ImzSKMs3ewupqw99eDAgTA3que5TnTssxim6Nw/NWNOV21Y1vgFFQ+uwVy8Gkd8f6Ccm DXzrqBPH+IiyBoPWWNWqKpj/wNWBFPSwheWR0KMzKYv4lyrIU8WXRsND/qwtLMFWfefQ wwCTQvvbyOkoE2vjCx5tP92AV9N8iRUHmSlJ12ExW9VJfx9MrwJVuOXRvfhX9+o2uuuG 6INwTVz89Ts1bYJOnRLq5C6h+epS21UTSJmtdNcRJo9SmP7TE0KDgGMVkXaVTxz18wnb mhnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743555; x=1724348355; 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=qNdMzoDNg3SBOXN5kIH+J4L0OFXsoxTK6BvqXkHiFPI=; b=NE3EIfiPsRtJbwC6M7N/4qCMSocxSmWeGibeawE3QPRXweSU/R4idUVAEPHgEGfnvi o3RKn9/xvibHrm8Z6bjUt8TNJwKWrUboHIIzN+bxIveAtwWAxj8vBLEs8m7p5V0Ur5Ta IVKHIkpL4IAyVUdWXv4Q+BqvKTnc5ukUBJiNR01F3CuZtcOU1yUYFXz8rQQcSX92pK/N QJ+5DtVwCQfAM2KxR+Mm1acahF6SRngllgbjea6ZWv6DbBFM0XX6Z3zeM/XGvK48wjxT M0tJtSLQjsBggfRmuGPXfZtbtPFqNTccKqYJC8l35IvJPQefCJ+AHF3lV3aD4TePSyv/ sg3Q== X-Forwarded-Encrypted: i=1; AJvYcCVxsr8asN/rZ8TxIRXylUoSLaB87FletVB/h9r1dDrF+pxbYaj7FnDQPyZ5P5sy5lsGk27l4zmX4aGSFeJpMYAdAZX23/Sr4d+kYkqMlA== X-Gm-Message-State: AOJu0Yxt4gwmV8OwGeY6cuAC/HfEOeXchyAgfRS215YNXwyiH68HbfwP PJnIQvQsgburcNmBTQ31JM5eNLrLdvtG9O5vSIQF0e8+SJziAYFpRQq4nNpmIJSL9j5EZUI7cWy M4GdIBD3RHYVwuBEVw3OBl8MfAQ== X-Google-Smtp-Source: AGHT+IHPxCk3ILqts0dwN0ruCt7oiCn01RaYOO920w1P76dXAowMtUZ+z4/p1v1TXr/x0jIKsh3oPHsRIw4e5lInAac= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a25:8741:0:b0:e11:69f2:e39 with SMTP id 3f1490d57ef6-e1180f6c6e6mr24578276.9.1723743554965; Thu, 15 Aug 2024 10:39:14 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:05 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=10595; i=samitolvanen@google.com; h=from:subject; bh=bxNi2EoDMx8FMXT38cuDVktpfAT2lY3rDO58JAquwyI=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj03rj9tt5wrj9Oop0GTFoXQSq5wmqtqxKtMp Yzs8ToZK7mJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49NwAKCRBMtfaEi7xW 7mv2C/9J/fisIDuw3uC7zNCeENccXXNMNEhImxup017WiI9C1raumF4b/TiPX5pmVOdkHrJdeX4 6oogEA4PsDGD+qbP8sy4vD5fYnCEuna2ddzJdaWVJ6HuVQJltUoGfWVvPXXTUszFTmudEPJl0rk /Zmz0qeSwOHm6bffSaADMYck0ZHk4hs3UOQcgnDI1bB0kz7PuAZl3QQver9NXKuDznRVDZ7sTUJ mD/vGvuaijFMWy3aq7xpYknhl2lewDMrxeD6mvxcI62tubo/paaXe1ETXxflVEBPEAzj2JEXJ1I olO/JpOgWoNF4WXHHopciA6KbQSoRwjTDNcpvExHA4Fw05buwgqQlw4gN3NGok0IuGlzmDbDzQ6 bdZ4QkOWLpmjJfSG65LHtUmaQWUzo6jX90b4X2fdrk4Q6EIjuUd/lOj12i1uLldHrIn0I6mp1x0 Cmmjs/xYFQCoQX5Q9jq0JguOpEwQ8OF+5ZnfXYRAhKhZmxlLyEp/wfDTAm1QvuuEseQBo= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-22-samitolvanen@google.com> Subject: [PATCH v2 01/19] 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 , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , 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. Signed-off-by: Sami Tolvanen --- kernel/module/Kconfig | 8 ++ scripts/Makefile | 1 + scripts/gendwarfksyms/.gitignore | 2 + scripts/gendwarfksyms/Makefile | 7 ++ scripts/gendwarfksyms/dwarf.c | 87 +++++++++++++++ scripts/gendwarfksyms/gendwarfksyms.c | 146 ++++++++++++++++++++++++++ scripts/gendwarfksyms/gendwarfksyms.h | 78 ++++++++++++++ 7 files changed, 329 insertions(+) create mode 100644 scripts/gendwarfksyms/.gitignore create mode 100644 scripts/gendwarfksyms/Makefile create mode 100644 scripts/gendwarfksyms/dwarf.c create mode 100644 scripts/gendwarfksyms/gendwarfksyms.c create mode 100644 scripts/gendwarfksyms/gendwarfksyms.h diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig index 4047b6d48255..a506d4ac660f 100644 --- a/kernel/module/Kconfig +++ b/kernel/module/Kconfig @@ -168,6 +168,14 @@ config MODVERSIONS make them incompatible with the kernel you are running. If unsure, say N. +config GENDWARFKSYMS + bool + depends on DEBUG_INFO + # Requires full debugging information, split DWARF not supported. + depends on !DEBUG_INFO_REDUCED && !DEBUG_INFO_SPLIT + # Requires ELF object files. + depends on !LTO + config ASM_MODVERSIONS bool default HAVE_ASM_MODVERSIONS && MODVERSIONS diff --git a/scripts/Makefile b/scripts/Makefile index dccef663ca82..2fd0199662e9 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -54,6 +54,7 @@ targets += module.lds subdir-$(CONFIG_GCC_PLUGINS) += gcc-plugins subdir-$(CONFIG_MODVERSIONS) += genksyms +subdir-$(CONFIG_GENDWARFKSYMS) += gendwarfksyms subdir-$(CONFIG_SECURITY_SELINUX) += selinux # Let clean descend into subdirs diff --git a/scripts/gendwarfksyms/.gitignore b/scripts/gendwarfksyms/.gitignore new file mode 100644 index 000000000000..ab8c763b3afe --- /dev/null +++ b/scripts/gendwarfksyms/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +/gendwarfksyms diff --git a/scripts/gendwarfksyms/Makefile b/scripts/gendwarfksyms/Makefile new file mode 100644 index 000000000000..c1389c161f9c --- /dev/null +++ b/scripts/gendwarfksyms/Makefile @@ -0,0 +1,7 @@ +hostprogs-always-y += gendwarfksyms + +gendwarfksyms-objs += gendwarfksyms.o +gendwarfksyms-objs += dwarf.o + +HOST_EXTRACFLAGS := -I $(srctree)/tools/include +HOSTLDLIBS_gendwarfksyms := -ldw -lelf diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c new file mode 100644 index 000000000000..65a29d0bd8f4 --- /dev/null +++ b/scripts/gendwarfksyms/dwarf.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 = checkp(dwarf_child(die, ¤t)); + while (!res) { + if (match(¤t)) + check(func(state, ¤t)); + res = checkp(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)); +} diff --git a/scripts/gendwarfksyms/gendwarfksyms.c b/scripts/gendwarfksyms/gendwarfksyms.c new file mode 100644 index 000000000000..27f2d6423c45 --- /dev/null +++ b/scripts/gendwarfksyms/gendwarfksyms.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2024 Google LLC + */ + +#include +#include +#include +#include +#include +#include "gendwarfksyms.h" + +/* + * Options + */ + +/* Print out debugging information to stderr */ +bool debug; + +static const struct { + const char *arg; + bool *flag; + const char **param; +} options[] = { + { "--debug", &debug, NULL }, +}; + +static int usage(void) +{ + error("usage: gendwarfksyms [options] elf-object-file ..."); + return -1; +} + +static const char *object_files[MAX_INPUT_FILES]; +static unsigned int object_count; + +static int parse_options(int argc, const char **argv) +{ + for (int i = 1; i < argc; i++) { + bool flag = false; + + for (int j = 0; j < ARRAY_SIZE(options); j++) { + if (strcmp(argv[i], options[j].arg)) + continue; + + *options[j].flag = true; + + if (options[j].param) { + if (++i >= argc) { + error("%s needs an argument", + options[j].arg); + return -1; + } + + *options[j].param = argv[i]; + } + + flag = true; + break; + } + + if (!flag) + object_files[object_count++] = argv[i]; + } + + return object_count ? 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) { + break; /* 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) +{ + unsigned int n; + + if (parse_options(argc, argv) < 0) + return usage(); + + for (n = 0; n < object_count; n++) { + Dwfl *dwfl; + int fd; + + fd = open(object_files[n], O_RDONLY); + if (fd == -1) { + error("open failed for '%s': %s", object_files[n], + strerror(errno)); + return -1; + } + + dwfl = dwfl_begin(&callbacks); + if (!dwfl) { + error("dwfl_begin failed for '%s': %s", object_files[n], + dwarf_errmsg(-1)); + return -1; + } + + if (!dwfl_report_offline(dwfl, object_files[n], object_files[n], + fd)) { + error("dwfl_report_offline failed for '%s': %s", + object_files[n], 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'", + object_files[n]); + return -1; + } + + dwfl_end(dwfl); + close(fd); + } + + return 0; +} diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h new file mode 100644 index 000000000000..5ab7ce7d4efb --- /dev/null +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -0,0 +1,78 @@ +/* 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; + +#define MAX_INPUT_FILES 128 + +/* + * 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, test, rv) \ + ({ \ + int __res = expr; \ + if (test) { \ + error("`%s` failed: %d", #expr, __res); \ + return rv; \ + } \ + __res; \ + }) + +/* Error == non-zero values */ +#define check(expr) __check(expr, __res, -1) +/* Error == negative values */ +#define checkp(expr) __check(expr, __res < 0, __res) + +/* + * dwarf.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 */ From patchwork Thu Aug 15 17:39:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765017 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 8415A51C4A for ; Thu, 15 Aug 2024 17:39:17 +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=1723743560; cv=none; b=qmNG5cs62trzuia9IYMgI9970x1BE2KInPf+i2xoZnVBCO+KJDlT0jYeu+id2/5Lb7F8A707SdscReCTa3rUJBferBqLnrJ95GQ5LFB7ZL4EUWYkrZiZfz8ZJMJ0siN4BGqrphXoTx4ixfTred6CxbWA4cs7Y6iTuT7zXzB2jTk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743560; c=relaxed/simple; bh=crG2z1QAVdcb8L1xI/ei1FGYqMQPcrm7Rlub8Vb9HSE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=M6pDH86LgYEAuCLausEQxstKVI4msvMnN9XHn7fRAJsCy/JfUfmmJhDe0bCVL0Ucc+kB+LRRnsqmeOsnXgKMXM+XPr7TunNRb0sZdKM7PVe7JSkF2InmMtNfivLxL4CKVD+W4inO51YqsDvQjtLiGGA0bL/fd6TRFEf3c8HhH/E= 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=Rm0zeOK6; 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="Rm0zeOK6" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-7a2787eb33dso965329a12.1 for ; Thu, 15 Aug 2024 10:39:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743557; x=1724348357; 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=Uov0CRlxy4YygtcVstLoe0vAl7pu4tWa+P/EEpIdGls=; b=Rm0zeOK6+sBDP5UqQNzCWa8QyjYf5pTR5Amg4ZM7utjm8by5hJPtFOMAGgtVc6vyl8 0Oe8VUwD2e4DUwu0SmQ0PBBjv5reU0ytaE5y4ZmHeEpo0SUG/kyDkOPqNwD920G1c3M8 +QRmWyQJM1cMAJ5ZCv6fDffMS2rQRHhd/F5e/KcBfAnsYiSdVmrynsM/5bzVkXKSpYUF 6qNWjYcLToR5QbsGsZyAqbIOE32BaEnfxfnyHob88Tn3IS0pM7jm/7S5JXwLbbg1u0K+ Naq+cEftef3I1g5OevGcRMtJgd0DsObzYOpHaono+QK1CzrHwarT1C3c3N30GfpVBGAJ HXwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743557; x=1724348357; 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=Uov0CRlxy4YygtcVstLoe0vAl7pu4tWa+P/EEpIdGls=; b=YbNp2kkfA5XDNlycphzjg1yb7IvWNj+/U9qfknYjotV3gH/qDfqSCc1xHjLUoSDnGG iuNCDkC+pXsn20stqcYYfDrxiXuTLrUMnaMJ3bkujMy5NVENRv4WStsWsmNDSWieqygr PlutpJbwDZ/m6AgXLUK0VVJ0Uw1T037Sc3XPPvaMvW6D65sYcPnzVuHe2L6w5bnfWGdE xV/p60VjBxwjUC2eyjv1FHimlrxGfYG4ZJG1PglRlUO5VIr3j5KciTzvCKrjs+Odnl6D OrZmiEGvPfTG+yTTKLRp5k6kKXrGq3r4T5RA3K+1LzLjHL1fuOH+hP5BqPnT4zjvrysO dkdQ== X-Forwarded-Encrypted: i=1; AJvYcCV4SP5JoCqoC4epvZ94I0+0XK1Gi7G0AFclSQwof/61wEjW0ARZTPbTMtH27UI1BSAGK5x/EUdCjiCdB3xJ5/ZJp7UblAiZv44DXEiTgg== X-Gm-Message-State: AOJu0Yw5Maq6idVM+/kcG57AnBbXgb23F4SyLTkV2YVtcNfvhIAouMZ/ L1omT3rLxkAyg2S/oBGXSH7wv1WhfHjsljBWTJ3g9MJYI/d+epBG8prAzTOKjFCUrk/hUFON7T+ aCrgoIJlQ2RBxCaTq1WnGjyA8yw== X-Google-Smtp-Source: AGHT+IEwcQof9vpv5owFCL5xlAGrgWbmahy7qEGDiupJWRGzXkesK5qX16rh6dI20h9d+J+ztNbd8gVLvvi1kFjdtlI= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a17:903:247:b0:1fb:b3f:b9bf with SMTP id d9443c01a7336-20203b1111bmr437945ad.0.1723743556647; Thu, 15 Aug 2024 10:39:16 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:06 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=7173; i=samitolvanen@google.com; h=from:subject; bh=crG2z1QAVdcb8L1xI/ei1FGYqMQPcrm7Rlub8Vb9HSE=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj03h2SYn2IwipBF/1mhMjbft2puh5x1VQQtr hR01w5wx0KJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49NwAKCRBMtfaEi7xW 7pkjDACi1TmSidtdqQ3U+ev+m7j+aMyKSXe/Gpe/+wqmXzcKHpCrZV34O2WWIa2Bc5hGXypNm5V eHNXgPkLe+AXEwwgUwoaNU6rKfBCZAjmXHdVbOCdBphz+xu28FY0HSJFKjnoLw/xtSVaAbbLCAh I1yCgQBj4gqzMfYqha8ctveVZlw5W7dtQXhaTgUj+rGYPR2qgIEXDPW7eWVw7HfekSyLrVYWwBz L4Bfw+K81fUy1g/72UJla2QO91v4M3ifIHNPljAAHPYCqtMyJ5T6vuF0t15ZXozltgqNputiGft wzaMoje6OXefn1A5egVjauNrv2nlkM2kyYjVjUbUlOl3oxJ8dPad2cgyOloqrGjprhXXACyIoq3 JwfZG9i21qdpGPHhuYOoA4V/hYTf5MYMciXTqktnc+zxNv7HmjeVp7JIVRCO8z6iWwvfPmPTYuP SB4eGS+06dcO2UxmaFoWsIn1Zfgn4z1wulHhu0jABiCD7+q8lRLkSqsejCA2m1Dv41neQ= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-23-samitolvanen@google.com> Subject: [PATCH v2 02/19] gendwarfksyms: Add symbol list handling From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , 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 passing a list of exported symbols to gendwarfksyms via stdin and filter out non-exported symbols from the output. Signed-off-by: Sami Tolvanen --- scripts/gendwarfksyms/Makefile | 1 + scripts/gendwarfksyms/dwarf.c | 53 ++++++++++++++- scripts/gendwarfksyms/gendwarfksyms.c | 4 +- scripts/gendwarfksyms/gendwarfksyms.h | 21 ++++++ scripts/gendwarfksyms/symbols.c | 96 +++++++++++++++++++++++++++ 5 files changed, 171 insertions(+), 4 deletions(-) create mode 100644 scripts/gendwarfksyms/symbols.c diff --git a/scripts/gendwarfksyms/Makefile b/scripts/gendwarfksyms/Makefile index c1389c161f9c..623f8fc975ea 100644 --- a/scripts/gendwarfksyms/Makefile +++ b/scripts/gendwarfksyms/Makefile @@ -2,6 +2,7 @@ hostprogs-always-y += gendwarfksyms gendwarfksyms-objs += gendwarfksyms.o gendwarfksyms-objs += dwarf.o +gendwarfksyms-objs += symbols.o HOST_EXTRACFLAGS := -I $(srctree)/tools/include HOSTLDLIBS_gendwarfksyms := -ldw -lelf diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index 65a29d0bd8f4..71cfab0553da 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -5,6 +5,48 @@ #include "gendwarfksyms.h" +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 bool is_export_symbol(struct state *state, Dwarf_Die *die) +{ + Dwarf_Die *source = die; + Dwarf_Die origin; + + state->sym = NULL; + + /* If the DIE has an abstract origin, use it for type information. */ + if (get_ref_die_attr(die, DW_AT_abstract_origin, &origin)) + source = &origin; + + state->sym = symbol_get(get_name(die)); + + /* Look up using the origin name if there are no matches. */ + if (!state->sym && source != die) + state->sym = symbol_get(get_name(source)); + + state->die = *source; + return !!state->sym; +} + /* * Type string processing */ @@ -40,7 +82,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,10 +109,15 @@ static int process_exported_symbols(struct state *state, Dwarf_Die *die) /* Possible exported symbols */ case DW_TAG_subprogram: case DW_TAG_variable: + if (!is_export_symbol(state, die)) + return 0; + + debug("%s", state->sym->name); + if (tag == DW_TAG_subprogram) - check(process_subprogram(state, die)); + check(process_subprogram(state, &state->die)); else - check(process_variable(state, die)); + check(process_variable(state, &state->die)); return 0; default: diff --git a/scripts/gendwarfksyms/gendwarfksyms.c b/scripts/gendwarfksyms/gendwarfksyms.c index 27f2d6423c45..d209b237766b 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.c +++ b/scripts/gendwarfksyms/gendwarfksyms.c @@ -27,7 +27,7 @@ static const struct { static int usage(void) { - error("usage: gendwarfksyms [options] elf-object-file ..."); + error("usage: gendwarfksyms [options] elf-object-file ... < symbol-list"); return -1; } @@ -105,6 +105,8 @@ int main(int argc, const char **argv) if (parse_options(argc, argv) < 0) return usage(); + check(symbol_read_exports(stdin)); + for (n = 0; n < object_count; n++) { Dwfl *dwfl; int fd; diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index 5ab7ce7d4efb..03f3e408a839 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -7,9 +7,11 @@ #include #include #include +#include #include #include #include +#include #ifndef __GENDWARFKSYMS_H #define __GENDWARFKSYMS_H @@ -56,6 +58,23 @@ extern bool debug; /* Error == negative values */ #define checkp(expr) __check(expr, __res < 0, __res) +/* + * symbols.c + */ + +static inline u32 name_hash(const char *name) +{ + return jhash(name, strlen(name), 0); +} + +struct symbol { + const char *name; + struct hlist_node name_hash; +}; + +extern int symbol_read_exports(FILE *file); +extern struct symbol *symbol_get(const char *name); + /* * dwarf.c */ @@ -63,6 +82,8 @@ extern bool debug; struct state { Dwfl_Module *mod; Dwarf *dbg; + struct symbol *sym; + Dwarf_Die die; }; typedef int (*die_callback_t)(struct state *state, Dwarf_Die *die); diff --git a/scripts/gendwarfksyms/symbols.c b/scripts/gendwarfksyms/symbols.c new file mode 100644 index 000000000000..673ad9cf9e77 --- /dev/null +++ b/scripts/gendwarfksyms/symbols.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2024 Google LLC + */ + +#include "gendwarfksyms.h" + +#define SYMBOL_HASH_BITS 15 +static DEFINE_HASHTABLE(symbol_names, SYMBOL_HASH_BITS); + +typedef int (*symbol_callback_t)(struct symbol *, void *arg); + +static int for_each(const char *name, symbol_callback_t func, void *data) +{ + struct hlist_node *tmp; + struct symbol *match; + + if (!name || !*name) + return 0; + + hash_for_each_possible_safe(symbol_names, match, tmp, name_hash, + name_hash(name)) { + if (strcmp(match->name, name)) + continue; + + if (func) + check(func(match, data)); + + return 1; + } + + return 0; +} + +static bool is_exported(const char *name) +{ + return checkp(for_each(name, NULL, NULL)) > 0; +} + +int symbol_read_exports(FILE *file) +{ + struct symbol *sym; + char *line = NULL; + char *name = NULL; + size_t size = 0; + int nsym = 0; + + while (getline(&line, &size, file) > 0) { + if (sscanf(line, "%ms\n", &name) != 1) { + error("malformed input line: %s", line); + return -1; + } + + free(line); + line = NULL; + + if (is_exported(name)) + continue; /* Ignore duplicates */ + + sym = malloc(sizeof(struct symbol)); + if (!sym) { + error("malloc failed"); + return -1; + } + + sym->name = name; + name = NULL; + + hash_add(symbol_names, &sym->name_hash, name_hash(sym->name)); + ++nsym; + + debug("%s", sym->name); + } + + if (line) + free(line); + + debug("%d exported symbols", nsym); + return 0; +} + +static int get_symbol(struct symbol *sym, void *arg) +{ + struct symbol **res = arg; + + *res = sym; + return 0; +} + +struct symbol *symbol_get(const char *name) +{ + struct symbol *sym = NULL; + + for_each(name, get_symbol, &sym); + return sym; +} From patchwork Thu Aug 15 17:39:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765018 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 4420157CAC for ; Thu, 15 Aug 2024 17:39:19 +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=1723743561; cv=none; b=DcwS6sZgwxUXt2lk26sK6wpyIG5eep0hF9fqlAKfblkN2MHo1unWWf7MAOyndvZiFnpGpeYhZlxrTxoY7eJtAcU++/SeHEMftaa0g8GfA+XKxy02OtCQU36oT8yRdvQ7PSfkmvNLPgT9kYslLQtg15/6bTZ++8B5PBj3vbB/MrQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743561; c=relaxed/simple; bh=hYmG5yt01O2vbqwBp7PP3hIYMSvbeyeHaHO3a1wFkH4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=jSb52/PeJeDbgKD6GNDnEDLXjKT0kMzDtQyM7U+2dr728NsLHYKP3vYwbM2MFL+hakQiBuvIMm/HlJU5qyqZa81y8WB4uPGyLZz9KkB9frq6jxvJlV/V3j0GU1NZeQXUuOBa8jvyz4ldYGs+WB3WoInczEbup8iUw5cmNElYuyk= 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=eGKc6Vog; 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="eGKc6Vog" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-1fc6db23c74so11072495ad.0 for ; Thu, 15 Aug 2024 10:39:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743559; x=1724348359; 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=UpexM9fykb8F2roek5WqlkwH0rKydnPc1uN1TQABN3Y=; b=eGKc6Vog3OywseZSr1HEFNxiFjUrLp3c4pbrYRipDPGFLP99uAibv8pusDk+HRK5Kk VvnwrAeLYzi3o6fZABwZkMsLNg2B+rTqV3CnM3/jeMgr33laDv/FVefWEFJ+5E0FF8D2 VKOEYnrWjPQvOj16DLynyrhNsjKqIYyNinBHVFpIVwZ43GjzKFES+XW0Q9x2pvUIvoVZ qAbbqMMeKQFx7iwd2utWiab4m/VTC3XGvJeIldWIZIRgpQcKQRghWrFDDb3rzz7W0gMW yK5kYpL86n/T+mlZlIutEZmmZ8OXvG1EW+t73UKGf8QOx+r9y/73CNC3wmE7krlh36S+ i/WA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743559; x=1724348359; 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=UpexM9fykb8F2roek5WqlkwH0rKydnPc1uN1TQABN3Y=; b=JxoSP6KA+cFihtvuTKoUUP6A1KSXq4BrRyQa2EJZykNCRIPViLHnTQUwIq3NaZzyR5 Iv95FDXJkWaMLLxnCvcna2tut+2n03DMVSHNRdvfD0Sf+UWBqgcctgzdLvf3pzn7IHCM EnRpWToKHRc50DFE1QvWCkIbYNm38Od5+OYWxedpkJXrr9RP0vQKYBIoav8esIU3pIPy Vd/jXaXQNqJ6MUi0RNYqYJkmSwpk8YpqUMbfPGDJuXvMFYPAsql/Dr9pqkH/8IJ7dZWO mwYa+M93ZZUbC4ujIFWNZaavnjFTKmD/0NLg3zPW94QPpJBCvy0pRJvOB/BSDZ1pvs2Z U0/w== X-Forwarded-Encrypted: i=1; AJvYcCUsMEm6gEpj8KUmnccUeyglRJeCc89qCbvhsjlwQIVRqRdt043xaGjLoXa6ANMZh3YDxIWFuJmHWyxm9cQ51rZMN3m7JVeHyMU2HzCTKw== X-Gm-Message-State: AOJu0YyBe/WNgauqmYPyZKJHc7ZEuisz/gi7dBLF5z9UwOhBbYaqlk4q MZJ1ALSK88qxM0xM0ZBofnhwdIBMTwDEvld2qbROT2vlxhLtnGH3DWBy/4mLG1K2p+CUmH+Iz1D bLrerdUxj8VT+2xTit/Am2Tmb9g== X-Google-Smtp-Source: AGHT+IH8/3eOMWCOeClNJqRJ6nF99J4r8CyoyyKEWH8ahJS3xT9dj2SLUFFnGqAYYgcxxGF2/tmYaOSqjFRejEAGQiU= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a17:902:f684:b0:1fb:56c8:f273 with SMTP id d9443c01a7336-20203e4798fmr440195ad.1.1723743558559; Thu, 15 Aug 2024 10:39:18 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:07 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=7437; i=samitolvanen@google.com; h=from:subject; bh=hYmG5yt01O2vbqwBp7PP3hIYMSvbeyeHaHO3a1wFkH4=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj04hD1u8vcutuUsraMRLPBZY8D62QWQnLdTw Jmu88k1VrCJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OAAKCRBMtfaEi7xW 7vnwC/0RM0rg3Pr6UU/JjzL9sven5E/iF8J23JuqnOnrRU6yIssP2YfjaFvY4Z5EpUrgu+Zob9l u4Yh5xNbzYC1za3vo82V7VrxdIaqxvyTRCO28WPx7kdxN3xB3TB7n9VYX7d9IVQSUkbWA9sQwAL /icm/sXgV+lgdaje+mEKeguw8SK2fDl7OVoFQTWJZpC3fT62nqXGJDpgzOn4Gp865rhE2LDESS6 oJsM0/4qwF0OPMt2ELjCeHyVurVJKEHb1n/y783to+tBmM0C9CD7DcsJcAVZMbBnyRWPl3QwXyd lRrEgXfY9+Pr6TBaQJ9kebo61jHAXN71vlI9QPP2A3hHWOx4CDJ4a7kz27ni1htLW+YFr3BSsSe xI4Ta/8cUU1HPbjRLRTxV91taWgOx99uRp8+/6x1QgB6tBqZ2yU/M24ZLdZKkoDzN8OJpZu3Dk9 DdzXP8jwRSdrICESpYLvbVgjdtBDemlJ3R+xQJQ4JX59ljF1EUd5g4s2WWYZ+mivYw5T0= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-24-samitolvanen@google.com> Subject: [PATCH v2 03/19] gendwarfksyms: Add address matching From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen The compiler may choose not to emit type information in DWARF for all aliases, but it's possible for each alias to be exported separately. To ensure we find type information for the aliases as well, read {section, address} tuples from the symbol table and match symbols also by address. Signed-off-by: Sami Tolvanen --- scripts/gendwarfksyms/gendwarfksyms.c | 2 + scripts/gendwarfksyms/gendwarfksyms.h | 7 ++ scripts/gendwarfksyms/symbols.c | 161 +++++++++++++++++++++++++- 3 files changed, 165 insertions(+), 5 deletions(-) diff --git a/scripts/gendwarfksyms/gendwarfksyms.c b/scripts/gendwarfksyms/gendwarfksyms.c index d209b237766b..e2f8ee5a4bf3 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.c +++ b/scripts/gendwarfksyms/gendwarfksyms.c @@ -118,6 +118,8 @@ int main(int argc, const char **argv) return -1; } + check(symbol_read_symtab(fd)); + dwfl = dwfl_begin(&callbacks); if (!dwfl) { error("dwfl_begin failed for '%s': %s", object_files[n], diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index 03f3e408a839..cb9106dfddb9 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -61,6 +61,10 @@ extern bool debug; /* * symbols.c */ +struct symbol_addr { + uint32_t section; + Elf64_Addr address; +}; static inline u32 name_hash(const char *name) { @@ -69,10 +73,13 @@ static inline u32 name_hash(const char *name) struct symbol { const char *name; + struct symbol_addr addr; + struct hlist_node addr_hash; struct hlist_node name_hash; }; extern int symbol_read_exports(FILE *file); +extern int symbol_read_symtab(int fd); extern struct symbol *symbol_get(const char *name); /* diff --git a/scripts/gendwarfksyms/symbols.c b/scripts/gendwarfksyms/symbols.c index 673ad9cf9e77..f96acb941196 100644 --- a/scripts/gendwarfksyms/symbols.c +++ b/scripts/gendwarfksyms/symbols.c @@ -6,11 +6,43 @@ #include "gendwarfksyms.h" #define SYMBOL_HASH_BITS 15 + +/* struct symbol_addr -> struct symbol */ +static DEFINE_HASHTABLE(symbol_addrs, SYMBOL_HASH_BITS); +/* name -> struct symbol */ static DEFINE_HASHTABLE(symbol_names, SYMBOL_HASH_BITS); +static inline u32 symbol_addr_hash(const struct symbol_addr *addr) +{ + return jhash(addr, sizeof(struct symbol_addr), 0); +} + typedef int (*symbol_callback_t)(struct symbol *, void *arg); -static int for_each(const char *name, symbol_callback_t func, void *data) +static int __for_each_addr(struct symbol *sym, symbol_callback_t func, + void *data) +{ + struct hlist_node *tmp; + struct symbol *match = NULL; + int processed = 0; + + hash_for_each_possible_safe(symbol_addrs, match, tmp, addr_hash, + symbol_addr_hash(&sym->addr)) { + if (match == sym) + continue; /* Already processed */ + + if (match->addr.section == sym->addr.section && + match->addr.address == sym->addr.address) { + check(func(match, data)); + ++processed; + } + } + + return processed; +} + +static int for_each(const char *name, bool name_only, symbol_callback_t func, + void *data) { struct hlist_node *tmp; struct symbol *match; @@ -23,9 +55,13 @@ static int for_each(const char *name, symbol_callback_t func, void *data) if (strcmp(match->name, name)) continue; + /* Call func for the match, and all address matches */ if (func) check(func(match, data)); + if (!name_only && match->addr.section != SHN_UNDEF) + return checkp(__for_each_addr(match, func, data)) + 1; + return 1; } @@ -34,7 +70,7 @@ static int for_each(const char *name, symbol_callback_t func, void *data) static bool is_exported(const char *name) { - return checkp(for_each(name, NULL, NULL)) > 0; + return checkp(for_each(name, true, NULL, NULL)) > 0; } int symbol_read_exports(FILE *file) @@ -57,13 +93,14 @@ int symbol_read_exports(FILE *file) if (is_exported(name)) continue; /* Ignore duplicates */ - sym = malloc(sizeof(struct symbol)); + sym = calloc(1, sizeof(struct symbol)); if (!sym) { - error("malloc failed"); + error("calloc failed"); return -1; } sym->name = name; + sym->addr.section = SHN_UNDEF; name = NULL; hash_add(symbol_names, &sym->name_hash, name_hash(sym->name)); @@ -91,6 +128,120 @@ struct symbol *symbol_get(const char *name) { struct symbol *sym = NULL; - for_each(name, get_symbol, &sym); + for_each(name, false, get_symbol, &sym); return sym; } + +typedef int (*elf_symbol_callback_t)(const char *name, GElf_Sym *sym, + Elf32_Word xndx, void *arg); + +static int elf_for_each_symbol(int fd, elf_symbol_callback_t func, void *arg) +{ + size_t sym_size; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr; + Elf_Data *xndx_data = NULL; + Elf_Scn *scn; + Elf *elf; + + if (elf_version(EV_CURRENT) != EV_CURRENT) { + error("elf_version failed: %s", elf_errmsg(-1)); + return -1; + } + + elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); + if (!elf) { + error("elf_begin failed: %s", elf_errmsg(-1)); + return -1; + } + + sym_size = gelf_getclass(elf) == ELFCLASS32 ? sizeof(Elf32_Sym) : + sizeof(Elf64_Sym); + + scn = elf_nextscn(elf, NULL); + + while (scn) { + shdr = gelf_getshdr(scn, &shdr_mem); + + if (shdr && shdr->sh_type == SHT_SYMTAB_SHNDX) { + xndx_data = elf_getdata(scn, NULL); + break; + } + + scn = elf_nextscn(elf, scn); + } + + scn = elf_nextscn(elf, NULL); + + while (scn) { + shdr = gelf_getshdr(scn, &shdr_mem); + + if (shdr && shdr->sh_type == SHT_SYMTAB) { + Elf_Data *data = elf_getdata(scn, NULL); + unsigned int nsyms = data->d_size / sym_size; + unsigned int n; + + for (n = 0; n < nsyms; ++n) { + const char *name = NULL; + Elf32_Word xndx = 0; + GElf_Sym sym_mem; + GElf_Sym *sym; + + sym = gelf_getsymshndx(data, xndx_data, n, + &sym_mem, &xndx); + + if (sym->st_shndx != SHN_XINDEX) + xndx = sym->st_shndx; + + name = elf_strptr(elf, shdr->sh_link, + sym->st_name); + + /* Skip empty symbol names */ + if (name && *name && + checkp(func(name, sym, xndx, arg)) > 0) + break; + } + } + + scn = elf_nextscn(elf, scn); + } + + return check(elf_end(elf)); +} + +static int set_symbol_addr(struct symbol *sym, void *arg) +{ + struct symbol_addr *addr = arg; + + if (sym->addr.section == SHN_UNDEF) { + sym->addr.section = addr->section; + sym->addr.address = addr->address; + hash_add(symbol_addrs, &sym->addr_hash, + symbol_addr_hash(&sym->addr)); + + debug("%s -> { %u, %lx }", sym->name, sym->addr.section, + sym->addr.address); + } else { + warn("multiple addresses for symbol %s?", sym->name); + } + + return 0; +} + +static int process_symbol(const char *name, GElf_Sym *sym, Elf32_Word xndx, + void *arg) +{ + struct symbol_addr addr = { .section = xndx, .address = sym->st_value }; + + /* Set addresses for exported symbols */ + if (GELF_ST_BIND(sym->st_info) != STB_LOCAL && + addr.section != SHN_UNDEF) + checkp(for_each(name, true, set_symbol_addr, &addr)); + + return 0; +} + +int symbol_read_symtab(int fd) +{ + return elf_for_each_symbol(fd, process_symbol, NULL); +} From patchwork Thu Aug 15 17:39:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765019 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 2B8F37580A for ; Thu, 15 Aug 2024 17:39:20 +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=1723743563; cv=none; b=UEBfDO7gbYmIfIwbwaoiFXAhrZdbpwP1KsKtNxbk9xvfIRfhDhJ3esNsUqkP8AEm0Ew8SbGgbpfLGeaUJf4VmF5O6OjnZkN831i/AZGV40hC0ATWhZBhuNNbrwuc2oqks2r1S7h1tD2e6RQUHkOUw5ty//tq+yUC1qaAmtjxMqE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743563; c=relaxed/simple; bh=Ahmj2O3IR+LSl3BiA52xKx3B/l6T0r/Fo4+Nt8cR26I=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=sOwoMxOSuwP4tidI06d1RCDyBpeFfbC6aBnhxmESwUASpe5RoPKD8UOgDSCHb2kGm8Z7ybbU8RauOfk2mPsA2suQQrvlgP10f6Mx6+A6ULApDQ2i0lmV0dNKjG9t2eJPn9SHX0bbHL1fYP1iqrN+uuEQ7tcSFq6RvBRI1X+5VhA= 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=mYqj+2oP; 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="mYqj+2oP" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-721d20a0807so1081401a12.1 for ; Thu, 15 Aug 2024 10:39:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743560; x=1724348360; 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=mLQlJKBqT4/VzYmf9VfZ8u93RL60RGH7yZrLYBcRMXE=; b=mYqj+2oPpG6Dfn0tdKv50rvipmR1lNvUZEW/bFDN2nRGxkano25ikQ98iSZhDpZQE7 9c1Swuj+Py6hGLL5HvLEZ0ZyXnUWuKEfkQx7/sSedxaJ5touR5pf1ljRLh043hHtFemj juOM/4gOJmXb+02yEPRbA4+A/4LgevSjeAR2wQf4dRVQkyv6f2jVWb70l4qW2gM0wwvY fKm+iKNNHMsA8H5L/vPvp7j+TtZ4dLQ/T1but4MWqCFrfPogy5yX/XcDfazMBfLtloTg HjtiE8UtqaYOnGKk9gAv60kQVQZdNjxXDzmMiwW7RDMs8Q8/pmmw+QJFWjg+G/0GgqXx GjKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743560; x=1724348360; 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=mLQlJKBqT4/VzYmf9VfZ8u93RL60RGH7yZrLYBcRMXE=; b=DPt+fW3qQUTjIYRtLRpGFhTZuPnJFNKVpzeja8tPMBP5kePL+//zbUAiD5X6StTW1P B1ahDOxZ9UqBPGjpOSEAAVYeUdWjadkGC/CAil/Pas8qH9G2s0iTY33NI4JQ+dwd+HpT irXkbh5TkGqB/jIBYFRl1m6h/wlz1uLhPjPYULTrGFL+1Dk5SYy9Sz3Ekyzz+YWAhigg e48SINeIPrwzhWxNpBzPnMpKZ43pyfH4phwLvpHb2z+Lng83uXvq1qF8/4cBLe0JyrDU 00chELOtZmnPsfSCv0G2u247EpYYuziaoU1o+0HqoM/xaaD6Z6LGDl2BHpYgBbT4zr9B WMBQ== X-Forwarded-Encrypted: i=1; AJvYcCWt8eR6NDtl5wf0osQCj0/1dvgpHZCKzdxIy6Q+YAy2H7ycwmE7v70pO5NyO+abxTu8XLwYqfFLGxXIcghQfotpi86qjGgNHbPFn5imng== X-Gm-Message-State: AOJu0Yz6qkUqjZlezHcfNqS7YyqrsNvBh8YeaCF2D3TtXPvgzPixxmeg vdEJHbbf2t57B47av4dU1l//trrnEQ0IWDzlQ7E3LaUiNJpNHs1ubCCSLvIwFW0TYhx4l3KWw/K phn0L6xoQA2hgbIMNh+fGDZ+tLQ== X-Google-Smtp-Source: AGHT+IE1twvMiJGv9A9PF3ykXAMYl/52O8nOi2sdu4GF15yrKLi7qKJGQ8IRVIMXcNpJkBrcc/J9f+3K3535R6ZKioE= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a63:5ec5:0:b0:760:76b9:ade9 with SMTP id 41be03b00d2f7-7c9791e4e77mr64a12.1.1723743560144; Thu, 15 Aug 2024 10:39:20 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:08 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=4474; i=samitolvanen@google.com; h=from:subject; bh=Ahmj2O3IR+LSl3BiA52xKx3B/l6T0r/Fo4+Nt8cR26I=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj04aOj8csDviqueJ1eEjKR7eZPwgInAwuFoD 5HAQqspMuCJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OAAKCRBMtfaEi7xW 7lcUC/9O1P8fFLBUCeOT4Cxm+rBpUW5+73RlFMMG8H+bGc4TSk35d91Su3NehrxYKKU/pT/PVPk DjVOLzLc8vrfvwl1Nt2wQ3EvSJwZZ2eqYER+zrUZkPmdpOjiOYowuBi+VOGnihjQZx8uQsuLUt7 zhIE6Y174Min92jA8j8LDjo3zgA5McorGyWANE2Ma2NOssLU4RB3vC9Cv2K0cJXR5QuckfadlW/ H8vQ6BvRvS05m2JGRSjmSdBZFGPGjJQ6ED/BTajeja7EOvAH4yaTiejmibxBkkf24sQYGkJtIFd 9JRGxIuuBDftKiPVQh0Oy5oK7Bp85TJ10jeczHneuITdV9P5glF6Y93MaLFT/zfIHRIna8eMMht pCs8UVnoc1wLnWExqcs3Q+pdqBXsMgfk0hGBoCKsZS1ot/5/0WRepl1NmMVX+hWHaY52dKgGU/K pA+68yDFF6TmIwfEZNO90AOtKj3WGCZWGirLJ7+tlFKpTSC07C7XYKELv14DkFgF8HGFQ= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-25-samitolvanen@google.com> Subject: [PATCH v2 04/19] gendwarfksyms: Add support for type pointers From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen The compiler may choose not to emit type information in DWARF for external symbols. Clang, for example, does this for symbols not defined in the current TU. To provide a way to work around this issue, add support for __gendwarfksyms_ptr_ pointers that force the compiler to emit the necessary type information in DWARF also for the missing symbols. Example usage: #define GENDWARFKSYMS_PTR(sym) \ static typeof(sym) *__gendwarfksyms_ptr_##sym __used \ __section(".discard.gendwarfksyms") = &sym; extern int external_symbol(void); GENDWARFKSYMS_PTR(external_symbol); Signed-off-by: Sami Tolvanen --- scripts/gendwarfksyms/dwarf.c | 26 +++++++++++++++++++++++++- scripts/gendwarfksyms/gendwarfksyms.h | 6 ++++++ scripts/gendwarfksyms/symbols.c | 16 ++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index 71cfab0553da..956b30224316 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -94,6 +94,28 @@ static int process_variable(struct state *state, Dwarf_Die *die) return check(process(state, "variable;\n")); } +static int process_symbol_ptr(struct state *state, Dwarf_Die *die) +{ + Dwarf_Die ptr_type; + Dwarf_Die type; + + if (!get_ref_die_attr(die, DW_AT_type, &ptr_type) || + dwarf_tag(&ptr_type) != DW_TAG_pointer_type) { + error("%s must be a pointer type!", get_name(die)); + return -1; + } + + if (!get_ref_die_attr(&ptr_type, DW_AT_type, &type)) { + error("%s pointer missing a type attribute?", get_name(die)); + return -1; + } + + if (dwarf_tag(&type) == DW_TAG_subroutine_type) + return check(process_subprogram(state, &type)); + else + return check(process_variable(state, &ptr_type)); +} + static int process_exported_symbols(struct state *state, Dwarf_Die *die) { int tag = dwarf_tag(die); @@ -114,7 +136,9 @@ static int process_exported_symbols(struct state *state, Dwarf_Die *die) debug("%s", state->sym->name); - if (tag == DW_TAG_subprogram) + if (is_symbol_ptr(get_name(&state->die))) + check(process_symbol_ptr(state, &state->die)); + else if (tag == DW_TAG_subprogram) check(process_subprogram(state, &state->die)); else check(process_variable(state, &state->die)); diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index cb9106dfddb9..8f6acd1b8f8f 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -61,6 +61,11 @@ extern bool debug; /* * symbols.c */ + +/* See symbols.c:is_symbol_ptr */ +#define SYMBOL_PTR_PREFIX "__gendwarfksyms_ptr_" +#define SYMBOL_PTR_PREFIX_LEN (sizeof(SYMBOL_PTR_PREFIX) - 1) + struct symbol_addr { uint32_t section; Elf64_Addr address; @@ -78,6 +83,7 @@ struct symbol { struct hlist_node name_hash; }; +extern bool is_symbol_ptr(const char *name); extern int symbol_read_exports(FILE *file); extern int symbol_read_symtab(int fd); extern struct symbol *symbol_get(const char *name); diff --git a/scripts/gendwarfksyms/symbols.c b/scripts/gendwarfksyms/symbols.c index f96acb941196..d6d016458ae1 100644 --- a/scripts/gendwarfksyms/symbols.c +++ b/scripts/gendwarfksyms/symbols.c @@ -41,6 +41,20 @@ static int __for_each_addr(struct symbol *sym, symbol_callback_t func, return processed; } +/* + * For symbols without debugging information (e.g. symbols defined in other + * TUs), we also match __gendwarfksyms_ptr_ symbols, which the + * kernel uses to ensure type information is present in the TU that exports + * the symbol. A __gendwarfksyms_ptr pointer must have the same type as the + * exported symbol, e.g.: + * + * typeof(symname) *__gendwarf_ptr_symname = &symname; + */ +bool is_symbol_ptr(const char *name) +{ + return name && !strncmp(name, SYMBOL_PTR_PREFIX, SYMBOL_PTR_PREFIX_LEN); +} + static int for_each(const char *name, bool name_only, symbol_callback_t func, void *data) { @@ -49,6 +63,8 @@ static int for_each(const char *name, bool name_only, symbol_callback_t func, if (!name || !*name) return 0; + if (is_symbol_ptr(name)) + name += SYMBOL_PTR_PREFIX_LEN; hash_for_each_possible_safe(symbol_names, match, tmp, name_hash, name_hash(name)) { From patchwork Thu Aug 15 17:39:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765020 Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.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 E6F8C7F490 for ; Thu, 15 Aug 2024 17:39:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743565; cv=none; b=ACIge5QXdNsXjl4HfWaaANwDjjbaFDjVmJGRrBpVRWd6is0uV4h5A0Fm3dXwb5bO95F2BOrB59/ml/qAbrbqm5jM5JCbx8NlLxcqOpxtcFQIWxbgpwy6NYm51TnzZNDBTux+zbU83F0RrRe2UFk2enZB0b3U6JOBOBp8vg+wBz0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743565; c=relaxed/simple; bh=wAhZomTPmGa8ryvnda7uC8r92v4iCWnU4YEmuivMqjE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Nhv0lHJs1rifHg/limoPx7H6nW9EHmJjjr8Ux4bSSoedPkOWe7cxBUjK3uK80ta5VjvWUV/KpcdNKC+q4yhondYZk5hRMY9RJDmbJLvM8mSvT2sy/Lji0zFsaMTz+R84I0i6IMCUtumwM7Ep2Jl4gAQUFTuxqMfoRr4GksmAvYs= 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=ixZkCAkd; arc=none smtp.client-ip=209.85.128.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="ixZkCAkd" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-650fccfd1dfso19698837b3.0 for ; Thu, 15 Aug 2024 10:39:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743562; x=1724348362; 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=zxg9NiKzqD/TwsM/Agf4zY5teCnPcigN7w5EkB7vCvE=; b=ixZkCAkdyJ4ZF6Ij6tAB5MLlutGqZgqAW39/NJ8zXj88XLzZLC47nKFLnCjOhmoUT9 /OWcmtzRmyO5Tqlc0M0+cko6A8inJqT3GKdQTXkv2LAgVtC35RRexnKpueeGOPFuNF36 Zq0B1J41Ho0y9M59t3HpsjEmw2kguoEliOrej6XlTFmmttb9yasRYy+FkHzyty8tiJ9B fwjBx8XDrf5wbl0SP3h3HRRNgqtpmSEOeHkAWViRrYDNiL7rlT74ZwmefGMf6avc8aDi kWZ8fm1x2RDZc2wZlGVWdJxpykgS9St6zlZLGQOD1qV1UaKpTvJ96RkJVyZNJf9LbFMX xDdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743562; x=1724348362; 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=zxg9NiKzqD/TwsM/Agf4zY5teCnPcigN7w5EkB7vCvE=; b=ZE6LSXrsfmyJGZTUD+fh1oYyUM/0q5h6mVwxIo6Z0K5HTeyKzTU2KEBIo5GQmcmG2o 9eok7Ujr4BhOa4U3dnALvbdzm6VhfuBF+kDM/QPb0JXpNYHV7lx2IHG6aKMmzgMvdPX2 jS13mjThc5xjkuR3AroL0KkOQ/7YgltPX9uBDOQ+wR6EkpPop3r4M/4s6PB/Ecd7fpEF a6uW2OVaUm1gBq/CfMYGAdJPiIzVu8+yuhW7LUBPI6CpQciBzBaJW8FZlIEz33kbDi2O HPaxigfLm7x0+1j3n37wwdHTMY3ezGvYAIqoGV8W37yV3252JXRaAM8HiLkMjLXjb+kW gAKg== X-Forwarded-Encrypted: i=1; AJvYcCVXHfqW0ytZh1vjqhxBdqisRyEzcUEn5YaL/vYJ50ePyoOWX7zS7vh0YywMfW/q6dRUFWP9QBLvR1/+xtbXvqHeTrYWCi2sjPG+dVUCRg== X-Gm-Message-State: AOJu0Yzj261dXEMedc1JmASCa+TXUlc/pmcWELgYFBC7Ylgsr9GgD7xq 0mpqtmhOoOqdixefmsQfKuubcKRTIJQ5Od9ayB6lQXlDRs+8BBo235pkpu1/BcYSnQKYltnn5Jc 4JgsfmlkdW6DZiSotS+DBMI2ZwA== X-Google-Smtp-Source: AGHT+IEm2CkybTf4Spyo/MEFaqpksIWJ+D50fZxqYSU9rkny7yJCVb9f0Vx4fBHM5Be0k5Bc4nMPKMdD8tOzCxicIIM= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a81:b049:0:b0:62c:67f4:4f5 with SMTP id 00721157ae682-6b1bc3f9536mr38907b3.9.1723743562048; Thu, 15 Aug 2024 10:39:22 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:09 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=4989; i=samitolvanen@google.com; h=from:subject; bh=wAhZomTPmGa8ryvnda7uC8r92v4iCWnU4YEmuivMqjE=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj04SCNuEsbV9MTLnBds7D9v786rWkJb6EcPG a6z0E0GsvqJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OAAKCRBMtfaEi7xW 7k5PC/98UAwkvYp0/qJJ5oId54CkqC3M3LFfbK9ZnGTiOW1giKs5ZBZG0ZqV74WC4cHKA8Z1I+4 PT71JPV4gtivRDmpW6IZwt9J0KNGDn2GIoHBer5yePFvSbqXBDls34A8d0OnDCKPnoIy4Kg5ISo cmRogwN7ABCvaQKO0Vw+IJxL0Yyq8wXjTI0ZoTeHkXPv3fHVxvnexvaKnkQ7rMNSLFp0Sb9SdXT 65ZFtkL61/K0DozliiRgTuNz2RNgwtyqs6gCbdn4J/1QNE7qgNLIvz4fevZi8j5A0pc9AbROhGs k91aBFnd5/bU5GslTX8XgofY4mqvCKSbOIqoTvr8CZL598auKvH7idFIOcfvoFcRVQanLkH0sgB sPeRaTfUF9bQjG2h/uoBn+YiKCDlXMCoy80iteYmyviXwD3ccyuVfdfockJ2P22uZgDEPQWeQw2 HwgHgltUS6CuI19QCKn0nCi3RrJO00a9HpskHvWnghNEtnWvbEuzoHHCTvI9JPJEMPjVI= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-26-samitolvanen@google.com> Subject: [PATCH v2 05/19] 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 , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Start making gendwarfksyms more useful by adding support for expanding DW_TAG_base_type types and basic DWARF attributes. Example: $ echo loops_per_jiffy | \ scripts/gendwarfksyms/gendwarfksyms --debug vmlinux.o ... gendwarfksyms: process_exported_symbols: loops_per_jiffy variable base_type unsigned long byte_size(8) encoding(7); ... Signed-off-by: Sami Tolvanen --- scripts/gendwarfksyms/dwarf.c | 121 +++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index 956b30224316..a37c9049d18e 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -5,6 +5,17 @@ #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(udata, Dwarf_Word) + static bool get_ref_die_attr(Dwarf_Die *die, unsigned int id, Dwarf_Die *value) { Dwarf_Attribute da; @@ -60,6 +71,74 @@ 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 = checkp(vsnprintf(buf, sizeof(buf), fmt, args)); + if (res >= MAX_FMT_BUFFER_SIZE - 1) { + error("vsnprintf overflow: increase MAX_FMT_BUFFER_SIZE"); + res = -1; + } else { + res = 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 = checkp(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) +DEFINE_PROCESS_UDATA_ATTRIBUTE(encoding) + bool match_all(Dwarf_Die *die) { return true; @@ -81,6 +160,44 @@ 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)); + check(process_encoding_attr(state, die)); + return check(process_alignment_attr(state, die)); +} + +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 */ @@ -91,7 +208,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_symbol_ptr(struct state *state, Dwarf_Die *die) From patchwork Thu Aug 15 17:39:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765021 Received: from mail-pf1-f202.google.com (mail-pf1-f202.google.com [209.85.210.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 A867E13C677 for ; Thu, 15 Aug 2024 17:39:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743567; cv=none; b=WHzbuFEKf+KHdUBeo+AAcyyTFjRG+7no+u8/N0pSQdlUfPyz5iwqwo+AxPsvSHHPKqWuA5NvDHtson14r+sBRqbXCxurmKsFpiYkJaiZbHWGkKJCLR3RG0UlZlk0gVbATCYgIrpqeOQ3gt3b0oE3KPMydDxENGnCJsiNqSS6y2w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743567; c=relaxed/simple; bh=WcDCaJXjW0f2JTquZj6OPQ/VcqwyCDdlHz/KUsXci2w=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=XuivHzV34gtBpFNZ4f+IVS8O96IxdFRMdusMBhz1J4y3I+Nmj5NzOmsv1fpOGH3VYZgy/HUGmU9EWz39bcAE4sEQFfeegxkpPfuOHiqupVilB9lYzniU6KVGV4r8Ho9+v7e8PQEcto3yGBGhMVx01MYJ+RLlHaocnVHGWxt/jzA= 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=LAahV7jA; arc=none smtp.client-ip=209.85.210.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="LAahV7jA" Received: by mail-pf1-f202.google.com with SMTP id d2e1a72fcca58-71271a3f15cso927070b3a.3 for ; Thu, 15 Aug 2024 10:39:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743564; x=1724348364; 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=wSWLELxvFuyu6zxWt/XqlJxl649JinucJ0xWmbt0ecA=; b=LAahV7jA0+uz+vzP1+XcH6o8pzMs9c3pvY9D3SZbpGR2fZj95lk9n11a/5iREbJwmA xnh0OqutyHoAXZbRShp7VS783QpTS/T+WF4LE/pIM9xwhuYvvo7R5LZ6xl0ASNHww/wr LWJWJAJUASI2r3iOGTC2V3INNsSZ+UKrJ59/NOZZ0c2ih/7lTPhK+ilfNWWc2jntTNu3 vv2tPS1hBHBYett82DZ7Os5YVhP5K+S9PNWlKGtBxJIplGo+La17Wl6GkDvBVX+JHHNd T2uifsG43LM2KZDBufWwmOnaeF91sMvjg9Fmx2JQHvt2K/mv2jNsfnzmhJ4fLJYAdGqh k6hg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743564; x=1724348364; 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=wSWLELxvFuyu6zxWt/XqlJxl649JinucJ0xWmbt0ecA=; b=qpz6tsIN5gLrbTe/gc9Rfh2+i5bhiz827JPb+K8Yino9LSrpGsTKKkDIWTel5hGxGq 8PwHlw0s4Oc+JZUYY4XAKISKfPS1rVrrb8NBbFLNFhHngI4bpRDDDkUZDXlFvQ+xQK7O tF6q3K67S9IZrSJrxRgFIg27Wji0tbbNStv2rBDqOyxcj+KLZHsmANSYbqPpen8rmcLO 90JN8KxWb3I0cDu03a0hSRGfhbIZv1u/S66nHblZ4cJQkHfHQ6zpYzmXBXsACCODLlQ6 60PFOXxbeaiekO2GNjXdZWhPA3dXJZNlp/bJ1KS62J6KQO3joYcd7gvAboS/h1eyrNSI yxig== X-Forwarded-Encrypted: i=1; AJvYcCX2b0+JHEZ0OnX37uXCcwyice595V67tIyPXkFsW8RQSvhFjrj3SXD4EDPA/qVePXxi9yZczfPnG8MiFc00B9/CTmOQBpsdGR4/QRaqwg== X-Gm-Message-State: AOJu0YzUzFYlueVqgQxgPx7qP43kx/8Z9psHxyMcDEYbMHccTQd4Ra4M cGY/40QjZP8JLLEwRITuXcum4R1leoGYt2PFakhIGSdFcluwD82Va7dM4oYJE3fNVbrf7/pTPZt IJF/lO0755dqV51JfYLtH8htipA== X-Google-Smtp-Source: AGHT+IHR6SAt2JifNMS5dTXYZGoY8TilzPCnRBOfdyHIVDp2HaKQ+8Ln/k+YWaDzQ008IaORCtagkkX5o2KpaUIG5WQ= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a05:6a00:66d0:b0:710:5836:1a24 with SMTP id d2e1a72fcca58-713c534fffbmr936b3a.6.1723743563850; Thu, 15 Aug 2024 10:39:23 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:10 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=17055; i=samitolvanen@google.com; h=from:subject; bh=WcDCaJXjW0f2JTquZj6OPQ/VcqwyCDdlHz/KUsXci2w=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj04qdDtzVZLUBt/GmJyPrnJD8K2Ja+yO/fMy /bXS7xsnZuJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OAAKCRBMtfaEi7xW 7pHhC/9FA6n54b79gRbgatKd3AW9gR5zZ8WIzyDerNT7r275dzEfQNMrcU7cZOtJNIXv4K2tAgC p8IC9m2EitARAwPAymS+fGJwjj9T6k1mfFiGhCkYWbi5kxOO+lYw4pEOFLKbVZmbWJUPwEEtnkR VvWJBmzgL8Edbc7kqCLMEM5SOcxRIVjhEXrnQ5hHdxYpxtn7WYtj1ygo8kzFnstqgUeEYF/duZj GpaPiYVD+AFNb4xWa/sv+r5ddkQZgUTDCiZP9HT594bEzlLvq5rwGLo+g5WAN9AJiVM1VNXrw9c zaxGfZoi5Nx3cQBmzLmaP3+/vNW/ol6m3pUNFQ27RtY13ONWWHr0rQ9wX16urPzCEYd7ZTUO9bT BCssKCWQHdqrrLIGhiV+A5k7+CuGdLrYKHxe2rCmzskHZtoiEyeEmxbduFT9vnilFT+TDrQ78dY 6jsUzCnXOojqkafkNPn1pqLjU5a/ax/GoD+MsrSiWhaLDX0SN/6LWvxTv90vGWPO0r66M= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-27-samitolvanen@google.com> Subject: [PATCH v2 06/19] gendwarfksyms: Add a cache for processed DIEs From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , 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 --- scripts/gendwarfksyms/Makefile | 1 + scripts/gendwarfksyms/die.c | 170 +++++++++++++++++++++++ scripts/gendwarfksyms/dwarf.c | 192 ++++++++++++++++++++------ scripts/gendwarfksyms/gendwarfksyms.c | 6 + scripts/gendwarfksyms/gendwarfksyms.h | 58 +++++++- 5 files changed, 382 insertions(+), 45 deletions(-) create mode 100644 scripts/gendwarfksyms/die.c diff --git a/scripts/gendwarfksyms/Makefile b/scripts/gendwarfksyms/Makefile index 623f8fc975ea..fcbac52ca00a 100644 --- a/scripts/gendwarfksyms/Makefile +++ b/scripts/gendwarfksyms/Makefile @@ -1,6 +1,7 @@ hostprogs-always-y += gendwarfksyms gendwarfksyms-objs += gendwarfksyms.o +gendwarfksyms-objs += die.o gendwarfksyms-objs += dwarf.o gendwarfksyms-objs += symbols.o diff --git a/scripts/gendwarfksyms/die.c b/scripts/gendwarfksyms/die.c new file mode 100644 index 000000000000..ad6ba435d9dd --- /dev/null +++ b/scripts/gendwarfksyms/die.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2024 Google LLC + */ + +#include +#include "gendwarfksyms.h" + +#define DIE_HASH_BITS 20 + +/* uintptr_t die->addr -> struct die * */ +static DEFINE_HASHTABLE(die_map, DIE_HASH_BITS); + +static unsigned int map_hits; +static unsigned int map_misses; + +static int create_die(Dwarf_Die *die, struct die **res) +{ + struct die *cd; + + cd = malloc(sizeof(struct die)); + if (!cd) { + error("malloc failed"); + return -1; + } + + cd->state = INCOMPLETE; + cd->mapped = false; + cd->fqn = NULL; + cd->tag = -1; + cd->addr = (uintptr_t)die->addr; + cd->list = NULL; + + hash_add(die_map, &cd->hash, addr_hash(cd->addr)); + *res = cd; + return 0; +} + +int __die_map_get(uintptr_t addr, enum die_state state, struct die **res) +{ + struct die *cd; + + hash_for_each_possible(die_map, cd, hash, addr_hash(addr)) { + if (cd->addr == addr && cd->state == state) { + *res = cd; + return 0; + } + } + + return -1; +} + +int die_map_get(Dwarf_Die *die, enum die_state state, struct die **res) +{ + if (__die_map_get((uintptr_t)die->addr, state, res) == 0) { + map_hits++; + return 0; + } + + map_misses++; + return check(create_die(die, res)); +} + +static void reset_die(struct die *cd) +{ + struct die_fragment *tmp; + struct die_fragment *df = cd->list; + + while (df) { + if (df->type == STRING) + free(df->data.str); + + tmp = df->next; + free(df); + df = tmp; + } + + cd->state = INCOMPLETE; + cd->mapped = false; + if (cd->fqn) + free(cd->fqn); + cd->fqn = NULL; + cd->tag = -1; + cd->addr = 0; + cd->list = NULL; +} + +void die_map_free(void) +{ + struct hlist_node *tmp; + unsigned int stats[LAST + 1]; + struct die *cd; + int i; + + memset(stats, 0, sizeof(stats)); + + hash_for_each_safe(die_map, i, tmp, cd, hash) { + stats[cd->state]++; + reset_die(cd); + free(cd); + } + hash_init(die_map); + + if ((map_hits + map_misses > 0)) + debug("hits %u, misses %u (hit rate %.02f%%)", map_hits, + map_misses, + (100.0f * map_hits) / (map_hits + map_misses)); + + for (i = 0; i <= LAST; i++) + debug("%s: %u entries", die_state_name(i), stats[i]); +} + +static int append_item(struct die *cd, struct die_fragment **res) +{ + struct die_fragment *prev; + struct die_fragment *df; + + df = malloc(sizeof(struct die_fragment)); + if (!df) { + error("malloc failed"); + return -1; + } + + df->type = EMPTY; + df->next = NULL; + + prev = cd->list; + while (prev && prev->next) + prev = prev->next; + + if (prev) + prev->next = df; + else + cd->list = df; + + *res = df; + return 0; +} + +int die_map_add_string(struct die *cd, const char *str) +{ + struct die_fragment *df; + + if (!cd) + return 0; + + check(append_item(cd, &df)); + + df->data.str = strdup(str); + if (!df->data.str) { + error("strdup failed"); + return -1; + } + + df->type = STRING; + return 0; +} + +int die_map_add_die(struct die *cd, struct die *child) +{ + struct die_fragment *df; + + if (!cd) + return 0; + + check(append_item(cd, &df)); + df->data.addr = child->addr; + df->type = DIE; + return 0; +} diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index a37c9049d18e..82b966269acd 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -61,19 +61,20 @@ static bool is_export_symbol(struct state *state, Dwarf_Die *die) /* * Type string processing */ -static int process(struct state *state, const char *s) +static int process(struct state *state, struct die *cache, const char *s) { s = s ?: ""; if (debug) fputs(s, stderr); - return 0; + return check(die_map_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 die *cache, const char *fmt, + ...) { char buf[MAX_FMT_BUFFER_SIZE]; va_list args; @@ -86,50 +87,103 @@ static int process_fmt(struct state *state, const char *fmt, ...) error("vsnprintf overflow: increase MAX_FMT_BUFFER_SIZE"); res = -1; } else { - res = check(process(state, buf)); + res = check(process(state, cache, buf)); } va_end(args); return res; } -/* Process a fully qualified name from DWARF scopes */ -static int process_fqn(struct state *state, Dwarf_Die *die) +#define MAX_FQN_SIZE 64 + +/* Get a fully qualified name from DWARF scopes */ +static int get_fqn(struct state *state, Dwarf_Die *die, char **fqn) { + const char *list[MAX_FQN_SIZE]; Dwarf_Die *scopes = NULL; - const char *name; + int count = 0; + int len = 0; int res; int i; + *fqn = NULL; + res = checkp(dwarf_getscopes_die(die, &scopes)); if (!res) { - name = get_name(die); - name = name ?: ""; - return check(process(state, name)); + list[count] = get_name(die); + + if (!list[count]) + return 0; + + len += strlen(list[count]); + count++; + + goto done; } - for (i = res - 1; i >= 0; i--) { + for (i = res - 1; i >= 0 && count < MAX_FQN_SIZE; 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, "::")); + /* + * If any of the DIEs in the scope is missing a name, consider + * the DIE to be unnamed. + */ + list[count] = get_name(&scopes[i]); + + if (!list[count]) { + free(scopes); + return 0; + } + + len += strlen(list[count]); + count++; + + if (i > 0) { + list[count++] = "::"; + len += 2; + } } + if (count == MAX_FQN_SIZE) + warn("increase MAX_FQN_SIZE: reached the maximum"); + free(scopes); + +done: + *fqn = malloc(len + 1); + if (!*fqn) { + error("malloc failed"); + return -1; + } + + **fqn = '\0'; + + for (i = 0; i < count; i++) + strcat(*fqn, list[i]); + return 0; } +static int process_fqn(struct state *state, struct die *cache, Dwarf_Die *die) +{ + const char *fqn; + + if (!cache->fqn) + check(get_fqn(state, die, &cache->fqn)); + + fqn = cache->fqn; + fqn = fqn ?: ""; + return check(process(state, cache, fqn)); +} + #define DEFINE_PROCESS_UDATA_ATTRIBUTE(attribute) \ - static int process_##attribute##_attr(struct state *state, \ - Dwarf_Die *die) \ + static int process_##attribute##_attr( \ + struct state *state, struct die *cache, Dwarf_Die *die) \ { \ Dwarf_Word value; \ if (get_udata_attr(die, DW_AT_##attribute, &value)) \ - check(process_fmt(state, \ + check(process_fmt(state, cache, \ " " #attribute "(%" PRIu64 ")", \ value)); \ return 0; \ @@ -144,8 +198,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 die *cache, + Dwarf_Die *die, die_callback_t func, + die_match_callback_t match) { Dwarf_Die current; int res; @@ -153,48 +208,99 @@ int process_die_container(struct state *state, Dwarf_Die *die, res = checkp(dwarf_child(die, ¤t)); while (!res) { if (match(¤t)) - check(func(state, ¤t)); + check(func(state, cache, ¤t)); res = checkp(dwarf_siblingof(¤t, ¤t)); } return 0; } -static int process_type(struct state *state, Dwarf_Die *die); +static int process_type(struct state *state, struct 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 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, Dwarf_Die *die) +static int process_base_type(struct state *state, struct die *cache, + Dwarf_Die *die) { - check(process(state, "base_type ")); - check(process_fqn(state, die)); - check(process_byte_size_attr(state, die)); - check(process_encoding_attr(state, die)); - return check(process_alignment_attr(state, die)); + check(process(state, cache, "base_type ")); + check(process_fqn(state, cache, die)); + check(process_byte_size_attr(state, cache, die)); + check(process_encoding_attr(state, cache, die)); + return check(process_alignment_attr(state, cache, die)); } -static int process_type(struct state *state, Dwarf_Die *die) +static int process_cached(struct state *state, struct die *cache, + Dwarf_Die *die) { + struct die_fragment *df = cache->list; + Dwarf_Die child; + + while (df) { + switch (df->type) { + case STRING: + check(process(state, NULL, df->data.str)); + break; + case DIE: + if (!dwarf_die_addr_die(state->dbg, + (void *)df->data.addr, + &child)) { + error("dwarf_die_addr_die failed"); + return -1; + } + check(process_type(state, NULL, &child)); + break; + default: + error("empty die_fragment"); + return -1; + } + df = df->next; + } + + return 0; +} + +static int process_type(struct state *state, struct die *parent, Dwarf_Die *die) +{ + struct die *cache = NULL; int tag = dwarf_tag(die); + /* + * If we have the DIE already cached, use it instead of walking + * through DWARF. + */ + check(die_map_get(die, COMPLETE, &cache)); + + if (cache->state == COMPLETE) { + check(process_cached(state, cache, die)); + check(die_map_add_die(parent, cache)); + 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; } + /* Update cache state and append to the parent (if any) */ + cache->tag = tag; + cache->state = COMPLETE; + check(die_map_add_die(parent, cache)); + return 0; } @@ -203,14 +309,14 @@ 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_symbol_ptr(struct state *state, Dwarf_Die *die) @@ -235,7 +341,8 @@ static int process_symbol_ptr(struct state *state, Dwarf_Die *die) return check(process_variable(state, &ptr_type)); } -static int process_exported_symbols(struct state *state, Dwarf_Die *die) +static int process_exported_symbols(struct state *state, struct die *cache, + Dwarf_Die *die) { int tag = dwarf_tag(die); @@ -244,8 +351,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: @@ -273,5 +381,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)); } diff --git a/scripts/gendwarfksyms/gendwarfksyms.c b/scripts/gendwarfksyms/gendwarfksyms.c index e2f8ee5a4bf3..55a7fc902bf4 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.c +++ b/scripts/gendwarfksyms/gendwarfksyms.c @@ -78,6 +78,10 @@ static int process_modules(Dwfl_Module *mod, void **userdata, const char *name, debug("%s", name); dbg = dwfl_module_getdwarf(mod, &dwbias); + /* + * Look for exported symbols in each CU, follow the DIE tree, and add + * the entries to die_map. + */ do { res = dwarf_get_units(dbg, cu, &cu, NULL, NULL, &cudie, NULL); if (res < 0) { @@ -90,6 +94,8 @@ static int process_modules(Dwfl_Module *mod, void **userdata, const char *name, check(process_module(mod, dbg, &cudie)); } while (cu); + die_map_free(); + return DWARF_CB_OK; } diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index 8f6acd1b8f8f..b280acceb114 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -76,6 +76,11 @@ static inline u32 name_hash(const char *name) return jhash(name, strlen(name), 0); } +static inline u32 addr_hash(uintptr_t addr) +{ + return jhash(&addr, sizeof(addr), 0); +} + struct symbol { const char *name; struct symbol_addr addr; @@ -88,6 +93,52 @@ extern int symbol_read_exports(FILE *file); extern int symbol_read_symtab(int fd); extern struct symbol *symbol_get(const char *name); +/* + * die.c + */ + +enum die_state { INCOMPLETE, COMPLETE, LAST = COMPLETE }; +enum die_fragment_type { EMPTY, STRING, DIE }; + +struct die_fragment { + enum die_fragment_type type; + union { + char *str; + uintptr_t addr; + } data; + struct die_fragment *next; +}; + +#define CASE_CONST_TO_STR(name) \ + case name: \ + return #name; + +static inline const char *die_state_name(enum die_state state) +{ + switch (state) { + default: + CASE_CONST_TO_STR(INCOMPLETE) + CASE_CONST_TO_STR(COMPLETE) + } +} + +struct die { + enum die_state state; + bool mapped; + char *fqn; + int tag; + uintptr_t addr; + struct die_fragment *list; + struct hlist_node hash; +}; + +extern int __die_map_get(uintptr_t addr, enum die_state state, + struct die **res); +extern int die_map_get(Dwarf_Die *die, enum die_state state, struct die **res); +extern int die_map_add_string(struct die *pd, const char *str); +extern int die_map_add_die(struct die *pd, struct die *child); +extern void die_map_free(void); + /* * dwarf.c */ @@ -99,12 +150,13 @@ struct state { Dwarf_Die die; }; -typedef int (*die_callback_t)(struct state *state, Dwarf_Die *die); +typedef int (*die_callback_t)(struct state *state, struct 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 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); From patchwork Thu Aug 15 17:39:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765022 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 737BA1B1417 for ; Thu, 15 Aug 2024 17:39:26 +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=1723743568; cv=none; b=fd5n42E/q513GLxRMggdwGaD9slryaVcA6otAZRH2DrlSdznR3ZuW/VrUCJQLkzLQkr7nHGKB1ShNQNbEENUroRMYmqiEVaoKzloKQCHW1tnxZTBGNbmctsy9ilRkMbOXF60KvPrJ0IHHMc3g+/EPfDj4H5B+PVAfBFP2vvv1uU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743568; c=relaxed/simple; bh=pw/HqpAceG9KZJncGvbm0Tc+Y0NR2BksFQva9OpCIyo=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=HhWm+T/bBB4vJGRXAmKwR9UNXo5vEh+0dRraRSNEBXDWfLaREQbKKjDZubAfbAwy+z3jJBEtEip7eT92lhZ/nKKEAEhtGVv3L8l05CG8j0mcwbMiT5pNZH9/DegRcjP0kKj0P8r/vSltso7yyLnuaeXmfexkUkQSiAHPHO1ZYaw= 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=uLcAAeNm; 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="uLcAAeNm" Received: by mail-pg1-f201.google.com with SMTP id 41be03b00d2f7-7a134fd9261so1020391a12.3 for ; Thu, 15 Aug 2024 10:39:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743566; x=1724348366; 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=sqbrGwhfvS/o9WkR63NSSG+3ggv2pfYWpb4R8IiMfJY=; b=uLcAAeNmDnXP+Avd+Ze7cEyt12ynuITxuwM0FXswoVP5uwzuTrwGtHoY2Z84Sz76ZS dr4hVLP02+6Onz5jGJ/afGHxJ5Cnw0cab6ZHrf6BIMuwBnRqILhHS6wX0KwMF97aKG3p szstwiAcd8XRgD4IwjtV+Y8Q263RBXus17myvpzSm12n5bX5YqdAFRkXlaSjJ1+tdtAY XWmZs6TH/jJ115095/CzQuFWm60ORY12h2o82sJWChJlpCPCC52sKWE6XqCspOoWLl3T amGXgNx7GOARUrW/6CKl48yHla0iNGPxUI1Gg/l4dPQP2RESmcJSILN9MK/N3awshMwH gbIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743566; x=1724348366; 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=sqbrGwhfvS/o9WkR63NSSG+3ggv2pfYWpb4R8IiMfJY=; b=qnrQ00wjscVzpkTVNKH23NttUwFclV63zHeOfLnwjyWNvotIp4wYM9rh6eSoZQoQOZ JMq1noyYXO+KIMNJ+QqhJu3j7omgLN2rpawHqKhllQlNOe4n5OrKItvhC1mLSJs2psKV /J8apruWA1DZk2oBCj0EAlmMLMWETiJjGoRqdWUj2yWbswj9ifPFjnswIWkYmfGvqjF3 g5E8B2tB2zkD2ggvVVLG5alMtaaF/BrkaNd1kmtdIcooCqPAU55hngMv4Vdr8Ta/tYrD 7AIS8l7q9hZMo6kjwJg4JQIQHpWzSYShj32O8+aQ5uCv8chhTmuCeR72b2z/+X0ZvhiJ LkMw== X-Forwarded-Encrypted: i=1; AJvYcCWzWmln/GBsB2GJDZ7jY8WagFZPldHOAiVlnT/HB+8h3iXaF9z8jm4Um0f7rsRuu/Q2d7lKUrh+0CMsrty4zbdC+zcTkgsNwyTa8ajNTg== X-Gm-Message-State: AOJu0YxBPaZim9noKgvzdJrCk8kTJAaFhFqLD3u+7IZ45g7rAnFRv2H3 1/a/8+ehE/z0Wfs5r7V/nv1BN7kgMMLVJ7hBN/mYq1vItfejSPzBlBpxvZ+P0CtcGYgitQFqbW0 a6r+YyYR768uCw3/qaglUsL8R2A== X-Google-Smtp-Source: AGHT+IEikh37+tKCQQfnwWQEfyYceqW0cvrSUqkS+CWOQoJktHenIYVMdrw9MA5y4VPH80UGrDlrydgt0ZOnnyEEye4= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a65:6712:0:b0:6ea:d240:23b0 with SMTP id 41be03b00d2f7-7c9796d9119mr52a12.4.1723743565745; Thu, 15 Aug 2024 10:39:25 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:11 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=6513; i=samitolvanen@google.com; h=from:subject; bh=pw/HqpAceG9KZJncGvbm0Tc+Y0NR2BksFQva9OpCIyo=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj04y5MroNixYi6Q4mKYktiBZJ/foUVldN1bP rlslcstbPCJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OAAKCRBMtfaEi7xW 7twtC/9nSIzTqkeqA1dIqXL/6ZYfzQuM/gdLn/xttXn3ForrLsYhstOkf7ftk40qu3YyKnd54MH 9/xa4HXN7B3VDiKzg6G/SbamfK1l0vFPVOvb7iSaayKYd/bP2ox0uZlRdehPiMHxdJ1Ui0VgztQ 9+pAcpM6eUTRLkLtUf1UfJ6sHk975nEE4LH4+g1hDuQnegOvEUyYSW/JxuulltZWBsU3k2cmSOa GBh/DY4vlIRAhQHOK9w/HiunYEyxCgEFQWk0D2JIzQCoh5nY+jSotlHu3MUF5VJ41erIx3C3vtu xIfAAKUEKuF6Oxe/P9DZVP7Gskdh2r+1opz0YUk/Uv94uV3PPgwm2YH5BRf2EG8F3OqG8nKUkrg sY9G4A9XMnPZ71P8o5cJ+ilJOd6QcN4/GSI2X9CZBVDLqVC0n2QtD6yrOMPqFYmhCs3YuJuuDTc YRMGE4mR7Ceo4L+6BILOU74Db8LpWR2EcRaFGNUCy6YD4n7Rte4bWXGs8RBQ9IBD4nsQw= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-28-samitolvanen@google.com> Subject: [PATCH v2 07/19] 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 , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , 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 to the underlying type, and thus produce similar output. Also add linebreaks and indentation to debugging output to make it more readable. Signed-off-by: Sami Tolvanen --- scripts/gendwarfksyms/die.c | 13 +++++ scripts/gendwarfksyms/dwarf.c | 76 +++++++++++++++++++++++++-- scripts/gendwarfksyms/gendwarfksyms.h | 7 ++- 3 files changed, 92 insertions(+), 4 deletions(-) diff --git a/scripts/gendwarfksyms/die.c b/scripts/gendwarfksyms/die.c index ad6ba435d9dd..fdd52df88fdd 100644 --- a/scripts/gendwarfksyms/die.c +++ b/scripts/gendwarfksyms/die.c @@ -156,6 +156,19 @@ int die_map_add_string(struct die *cd, const char *str) return 0; } +int die_map_add_linebreak(struct die *cd, int linebreak) +{ + struct die_fragment *df; + + if (!cd) + return 0; + + check(append_item(cd, &df)); + df->data.linebreak = linebreak; + df->type = LINEBREAK; + return 0; +} + int die_map_add_die(struct die *cd, struct die *child) { struct die_fragment *df; diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index 82b966269acd..82185737fa2a 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -5,6 +5,17 @@ #include "gendwarfksyms.h" +static bool do_linebreak; +static int indentation_level; + +/* Line breaks and indentation for pretty-printing */ +static int process_linebreak(struct die *cache, int n) +{ + indentation_level += n; + do_linebreak = true; + return check(die_map_add_linebreak(cache, n)); +} + #define DEFINE_GET_ATTR(attr, type) \ static bool get_##attr##_attr(Dwarf_Die *die, unsigned int id, \ type *value) \ @@ -65,6 +76,12 @@ static int process(struct state *state, struct die *cache, const char *s) { s = s ?: ""; + if (debug && do_linebreak) { + fputs("\n", stderr); + for (int i = 0; i < indentation_level; i++) + fputs(" ", stderr); + do_linebreak = false; + } if (debug) fputs(s, stderr); @@ -230,6 +247,40 @@ static int process_type_attr(struct state *state, struct die *cache, return check(process(state, cache, "base_type void")); } +/* Container types with DW_AT_type */ +static int __process_type(struct state *state, struct 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_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)); +} + +#define DEFINE_PROCESS_TYPE(type) \ + static int process_##type##_type(struct state *state, \ + struct 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 die *cache, Dwarf_Die *die) { @@ -251,6 +302,9 @@ static int process_cached(struct state *state, struct die *cache, case STRING: check(process(state, NULL, df->data.str)); break; + case LINEBREAK: + check(process_linebreak(NULL, df->data.linebreak)); + break; case DIE: if (!dwarf_die_addr_die(state->dbg, (void *)df->data.addr, @@ -270,6 +324,11 @@ static int process_cached(struct state *state, struct die *cache, return 0; } +#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 die *parent, Dwarf_Die *die) { struct die *cache = NULL; @@ -288,9 +347,20 @@ static int process_type(struct state *state, struct die *parent, Dwarf_Die *die) } 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; diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index b280acceb114..e8b4da0fc9a8 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -58,6 +58,9 @@ extern bool debug; /* Error == negative values */ #define checkp(expr) __check(expr, __res < 0, __res) +/* Consistent aliases (DW_TAG__type) for DWARF tags */ +#define DW_TAG_typedef_type DW_TAG_typedef + /* * symbols.c */ @@ -98,12 +101,13 @@ extern struct symbol *symbol_get(const char *name); */ enum die_state { INCOMPLETE, COMPLETE, LAST = COMPLETE }; -enum die_fragment_type { EMPTY, STRING, DIE }; +enum die_fragment_type { EMPTY, STRING, LINEBREAK, DIE }; struct die_fragment { enum die_fragment_type type; union { char *str; + int linebreak; uintptr_t addr; } data; struct die_fragment *next; @@ -136,6 +140,7 @@ extern int __die_map_get(uintptr_t addr, enum die_state state, struct die **res); extern int die_map_get(Dwarf_Die *die, enum die_state state, struct die **res); extern int die_map_add_string(struct die *pd, const char *str); +extern int die_map_add_linebreak(struct die *pd, int linebreak); extern int die_map_add_die(struct die *pd, struct die *child); extern void die_map_free(void); From patchwork Thu Aug 15 17:39:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765023 Received: from mail-pj1-f73.google.com (mail-pj1-f73.google.com [209.85.216.73]) (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 B8FB054656 for ; Thu, 15 Aug 2024 17:39:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743570; cv=none; b=eI/h94PFLBH8QI57ocWQ9zhDet+Gf0uQcXOhd9H54zG//QASoydAcu8qNyOqCWJ6xSoABtrwB22hgIWJZOdeNU94xf29iFfqrfrQyqULVfJH3SCV3pDB23l5AHYVV+y+buTSNQzstUo9L/hwDcnkUlEEQ5Z0DPmu5dR0B0K6EGc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743570; c=relaxed/simple; bh=IxWZKsLfDtf9kxevQsdRvL9iAtwcYd0l83K436mpqAw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=W76eJCqBxTTCF2eVTiLSrI6/GetOMSlqf8VfbeOs2ukljqWKbLNbYBNW5VhB+zXAhXtxgv3iLxZarzcdhE6K+10PvKCLrSUVMNrYFMGkvemEkBM5ok+iRnQW3+euWMK1yDzhh5Iznk07ohs/4+OFQJlsSpRrnY0dzSk5/WDI+WE= 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=3GmBb4rc; arc=none smtp.client-ip=209.85.216.73 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="3GmBb4rc" Received: by mail-pj1-f73.google.com with SMTP id 98e67ed59e1d1-2d3baf38457so1313287a91.0 for ; Thu, 15 Aug 2024 10:39:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743568; x=1724348368; 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=zfuqlaZpivgP61E8IUfDVjWbxuMIer3qaRAVkhI1EpI=; b=3GmBb4rc++vRWW/4KqKV9KTJWL3x6VLo/tP3ZfHIyt3SjWJy4o9mlP9T/odMErYMTC rLq7/uF4I1ziCckGX3kBjiQbgLfAfBYp4WSyqfppCdNKR//2lksivPJ1v0fJXXhREvWd npDqDCsiC6WMwXBWcmq0gjjWo+NXNFRnbyEM4jzg9eUV74FoZUfA8u4hw0zd/B48WtDC OmduN6GjtbJYmV79SIwJUtnKvnnsLytzkZgjkHQyPHiQPQfSu77a5wCctlAp/TVyo+jJ 97NJ2bupphxEHtLdVz4dfYSO7r0w2RHJ7Nttq7j7ucgCe3ecb2D0Xrzbr2bSgmgn6gNx RSWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743568; x=1724348368; 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=zfuqlaZpivgP61E8IUfDVjWbxuMIer3qaRAVkhI1EpI=; b=Ah4gq/ZC3jq063r0SXg1iQOg7R08vRFZx5QrNU8R7nSLZruvvHsS+3tkiL4TW3JLtX M92wHEZBSAAPw02GOapUZlPvk+w774z9LOLl1eItmBiYvLKoFhgOggG0S2jNCGoCO+XC z8VVW6tbgIg9nEXVFH7F8o8GCVUTHvfUUNocggKeB6fkmtvXlSPukJeLC2QTGQ+JGiZk 11ENu3vA1nBYliSXL8rQt3OVQQUk+Dhyx66xmlLT5KMWUWY37zSYXF6S4oO19FSHKdTN ebc7DXOFoNYWKNDcanbzAsx67LQ9pPksN09CedzqyvDGyTc8ri+D0p5S2xSlUerfe6SW IU5A== X-Forwarded-Encrypted: i=1; AJvYcCWbaga7IkNT2ihQKkLj2qZmacQhYB5IUnIrP2vub2eL5S9ZZfvIeuAvjbfoOKB+qSdmuBl4uOT1PyMyJyckPOvDSZzTBViXn7Tyz3ylqg== X-Gm-Message-State: AOJu0YxOroT1W6nx194Nbjoc9QjOGPmnl3BQXhoUqXAc3l59rFSC+BIw qyhVqCN4mvRuA/Y2CuybPte/PJZnyNlZ4ZPMpVPHfClj4j13lVYoKuFzN0GL5tQBAS+Jh+435VN WYD1zNhe2Dyn+JSZAZOXxD0qsbQ== X-Google-Smtp-Source: AGHT+IFQfH4kooGic/QhjPlGgJQHvcaXF8cjadEJBNf7+K5TmqkgZbkyFvn+Yr2S6dOfoFZYy38IjvlUZRUzMCgrMbo= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a17:90a:d78e:b0:2d3:96b5:4940 with SMTP id 98e67ed59e1d1-2d3e20b22a9mr743a91.0.1723743567718; Thu, 15 Aug 2024 10:39:27 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:12 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=4692; i=samitolvanen@google.com; h=from:subject; bh=IxWZKsLfDtf9kxevQsdRvL9iAtwcYd0l83K436mpqAw=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj04GkWhb24TKJqKw4JVSD8OHepYkerwtLdQx qaACpYCrKWJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OAAKCRBMtfaEi7xW 7sWTDACcHTL9GfULRb2s9iLakapapeokqgn87VvgRoaESLeX4qLc/RanJQknVLtcLG6YhJp8RYv qRY2Rko4zoQCzFOWW8UPaaT4qc+mgEicvOfhMlLL8Rnw9kzYr5FSGz1n1Z8ALY0EsEOx3wtW/1k zuEpLF63tTCSLwE7scyHu2pF5B6aAhXbt427egI0quLd1Svj8a1D0fYSZKkb1F76YHEbiMGwyan JoIluQ0Fn9iFOzcXfVeGQWMlTF55oEKVU0lPOrtgtEdwL8o4aLUqI+UF9abnadVnptTuxVJ8WV9 4u6bmfWXL6SXXQwMSDkHaE712B0M7EXa23aBV3cLpglNfnQXKvv7U3MgyjoYRDnbAHo40UMWKiR UMTWMR+DcoOXWQ14S0LaPEr+tsiuwpJCzBLwcUcmMkhrR0KPZI9l5OFCrMHaabH+r0+8NaARQpd dzycoPwoG+9DjaCujbi6uQFh4iPqACsslbf0N/X03KJOJcuZWkndB3IjqDwtl88LliXeg= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-29-samitolvanen@google.com> Subject: [PATCH v2 08/19] 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 , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , 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 this to also 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 --- scripts/gendwarfksyms/dwarf.c | 57 ++++++++++++++++++++++++++- scripts/gendwarfksyms/gendwarfksyms.h | 1 + 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index 82185737fa2a..c81652426be8 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -210,6 +210,15 @@ DEFINE_PROCESS_UDATA_ATTRIBUTE(alignment) DEFINE_PROCESS_UDATA_ATTRIBUTE(byte_size) DEFINE_PROCESS_UDATA_ATTRIBUTE(encoding) +/* 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; @@ -247,6 +256,25 @@ static int process_type_attr(struct state *state, struct 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 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 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 die *cache, Dwarf_Die *die, const char *type) @@ -281,6 +309,29 @@ DEFINE_PROCESS_TYPE(shared) DEFINE_PROCESS_TYPE(volatile) DEFINE_PROCESS_TYPE(typedef) +static int __process_subroutine_type(struct state *state, struct 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 die *cache, + Dwarf_Die *die) +{ + return check(__process_subroutine_type(state, cache, die, + "subroutine_type")); +} static int process_base_type(struct state *state, struct die *cache, Dwarf_Die *die) { @@ -358,8 +409,11 @@ static int process_type(struct state *state, struct die *parent, Dwarf_Die *die) 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); @@ -379,7 +433,8 @@ static int process_type(struct state *state, struct die *parent, Dwarf_Die *die) */ 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) diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index e8b4da0fc9a8..25f87485eb69 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -59,6 +59,7 @@ extern bool debug; #define checkp(expr) __check(expr, __res < 0, __res) /* 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 /* From patchwork Thu Aug 15 17:39:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765024 Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.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 622AE1BC06D for ; Thu, 15 Aug 2024 17:39:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743572; cv=none; b=Rv+7eQGCAexdojOTpuAYRmE1ORR/cwKRQFPEdanap1F+2Kb4a+hDmuFj/7BojCVzlw9WydWp2tdrPUytQxd6tjOT6HrXbaejWFcv+inOLNTlZOubX+c9O0UitUNfwYusCMu5yjpMUsyq5XYmUgGG70PR5y1TjwYRslhCuCf9kQQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743572; c=relaxed/simple; bh=nTcTMkHUN/UCMnmRiFJQDXB1TxZAvoJP5PqJx/o9EQA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Qi8HJtPkbGe9eHU9lEI+k6cYhMUY1JEkJ9ZJW4dAxtWSv+1eLeEz54Ov7glXnO6Ujni8YS8gsMaJA24eRzvTCF1xVfTRCdmmTq2IEPu/JPHNizC2iCpv43KRRYNAWHaVu9EjfBnVV7GQKVkl9gr3KHU3agJBOizLlaK/dv8CEoE= 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=YVEqopoJ; arc=none smtp.client-ip=209.85.128.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="YVEqopoJ" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-6506bfeaf64so17924737b3.1 for ; Thu, 15 Aug 2024 10:39:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743569; x=1724348369; 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=oQTVjPACp33eNMD9tpytKg6MWS9lRG5M8diY/YwwjwU=; b=YVEqopoJuKNqM9+3+scgzHZxH4H0bXe7DRFOrqMJy8CmMuUzHwuc9DKbX+XuaCSJo6 DJaTHjRh5AuNVmGiu7iATig2CVUhP5yNYv5QPiiRyBrOXIwZosI8MveqmLR0fz/FhBK6 oV0wETohq49mPv+trOtiuTQlWehCgSpb4SjudOom+DwGDP7ftsbUEfxYkeD79dfUoHJH 58L3DT28eWgAl02EsYCLrGV1Uj4ejYD1IurF8p97NbiPFXe+e4qstB/AbMbqiMOY+HuB BevFJNn7lGKKRf3441YiQJ2li+MKzneTXxyyGSAjF9fIQgCjh0w/1Mb1v6UYQfm21dc7 G3GQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743569; x=1724348369; 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=oQTVjPACp33eNMD9tpytKg6MWS9lRG5M8diY/YwwjwU=; b=N7B/Zd8JkJfT9Yp0Gr29S7Ipn7ZBZa5DTwI9N4Ao2VUS3hsHYf5BciG10+ORX4/EsC Easc4ODPYlhHN3LxV9fsZMK9qyFHU6W/fjSEJXi81KfLq96iUg8rpWRhrAFOtOUPBfq4 SLtV/w4mbg7pYFdIQ+7jYk3lncYXUjGiEOLlKDVBCvuxZp6aev9SK+o9HzK3su4aF85T quFvAq70CmJ70sgP3txrCeHaauL1b4mQbzEi2B7C7qtwuDV+8adWgOfHKehgeGkbCOwd KchA2RPQrhIHIreq98uP8bjN5LJquZp++XuEer8zIREK6VOJLpdUjq3RWtMFxKcc/7aI HHrA== X-Forwarded-Encrypted: i=1; AJvYcCU2oYb6D5PDZ55IfAwbmHKroiJY+Y/tq6wq78CCmZnZpvaj0OkxUBoLsfoa8rEUgDYvZBQKM35k6Y67ThRhu5lvGfGmAheA+ZYs1jfFNg== X-Gm-Message-State: AOJu0YxBSrTCBp8GqYfoD1aOS3Co68COIbL6fAoTaY82YJIL46ZHj9re PJSRCLxh3RyHZzTNEcqINlwrDlA4XTsXS6m57aroJbMpVUzOIaW2at71CufOqwEMVjMg3krqMnz xJZ31IoBnjOCsZjMTPioMccoTxA== X-Google-Smtp-Source: AGHT+IF5CO+eSdgk4A1o3bwcX4SrUit3pZq5QnY92bhAjwQwlxVmeRJpF4eb4vxYwPpGR9RAkAYB0eRSdszPeH2WSe4= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a05:690c:4084:b0:667:8a45:d0f9 with SMTP id 00721157ae682-6b1b1e5d0dcmr159547b3.0.1723743569512; Thu, 15 Aug 2024 10:39:29 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:13 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=2395; i=samitolvanen@google.com; h=from:subject; bh=nTcTMkHUN/UCMnmRiFJQDXB1TxZAvoJP5PqJx/o9EQA=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj04gVH5i1wio3ZaU6SzQ4CTy530kpMAP58VQ UhjMnOXvnaJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OAAKCRBMtfaEi7xW 7v2aC/9n9aNbg61o1QfjFxg33M09DzU+aiKnoMY1BZQpsmArZ07gstbc5sJ4RGtOy+Aee7yr2WN jqsWFwV3sUG9t3i6SGUMaGVu2mxTapdoeWboqRb3doOR6k5+DfqUPzJ0i8HgVXZXUUu6OXRO0Ec QpDy4+/THzSyrmvDOv9/Z2XcU6dEUoxCVtlkluQNKLuTO32SS52vpmchi+nHsM6ZDm2gcEhLy38 IIF4iyRWYNh3HDacVGmENL0cW5A52SYlkjTT7w6t4gIQ/WRfZqKIbXi5C11t66jrieHzzTShCFj 4mo68AFpqeOhauFRqus/fNT5aSkxtpXlFRCw6pXI1CKq9YGxSnBcOJHW0KtXbjMBJnIr2mJcuxU iLH5DMEuVxf97wyRRgszQDbNpY/MLLZdQjsm+vGSymrh9bGrbaMTXOr7xYTr8H6s90/es9bbjHx 4/9EH6V8K+B7SZ+VqSbXe5msNpzTwsBAFZjrp66RMnldstPBfaMJyyg3GG+LgndBNoYgw= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-30-samitolvanen@google.com> Subject: [PATCH v2 09/19] 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 , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , 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 source code: const char *s[34]; Output with --debug: variable array_type [34] { pointer_type { const_type { base_type char byte_size(1) encoding(6) } } byte_size(8) }; Signed-off-by: Sami Tolvanen --- scripts/gendwarfksyms/dwarf.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index c81652426be8..4ec69fce95f3 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -218,6 +218,7 @@ DEFINE_PROCESS_UDATA_ATTRIBUTE(encoding) } DEFINE_MATCH(formal_parameter) +DEFINE_MATCH(subrange) bool match_all(Dwarf_Die *die) { @@ -309,6 +310,34 @@ DEFINE_PROCESS_TYPE(shared) DEFINE_PROCESS_TYPE(volatile) DEFINE_PROCESS_TYPE(typedef) +static int process_subrange_type(struct state *state, struct 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)); + if (get_udata_attr(die, DW_AT_upper_bound, &count)) + return check( + process_fmt(state, cache, "[%" PRIu64 "]", count + 1)); + + return check(process(state, cache, "[]")); +} + +static int process_array_type(struct state *state, struct 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 die *cache, Dwarf_Die *die, const char *type) { @@ -411,7 +440,9 @@ static int process_type(struct state *state, struct die *parent, Dwarf_Die *die) 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 Thu Aug 15 17:39:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765025 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 4EB911BC9F5 for ; Thu, 15 Aug 2024 17:39:32 +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=1723743574; cv=none; b=rfKfAyJCKdEvLuK/DRI7eshqEaIBG46kG/DatoL3d1fqCQ0y+F7uaXucR7wEkg2GDSdlupM1VQ9Kf3rgD4mtVavCf6i2ZdKAKRQZivS/hkJfo6SUHX6J2XOJbZCzw7yszM1a0Bv0ISHLCTjSTxuu4zih6NUDs5xdfrgnZxy1E5c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743574; c=relaxed/simple; bh=seTjzndQnpborzCoviHr6CbsMyWBJvxYdHHqERTVcCw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=LeOxJZqHhOFTNB9VnrbAESQYrOazTTBfbCRfwIgx/QmtfSfrq+qKzDA7bP6B/SccXx6PyriUgmeepdYHz4fECzlLSnKYHbKbAdT4pRDNpN0X2eXIBP0exUlr/xGRZGhAru7tIwwK1wQ3pE6THA4sYcuAhr83ePVxuNeZ7jeOhhk= 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=bqHfhE/9; 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="bqHfhE/9" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e116c697904so2126890276.1 for ; Thu, 15 Aug 2024 10:39:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743571; x=1724348371; 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=VFwCK9X2QLe1/DNg8JobTxi3rYfg72O97+Gvq68riBQ=; b=bqHfhE/9QRsI5hQDqp3tdVS970gAut+katuwK1SDW6rEWaItmZg7uUmdLkMyusOImo qVFlJaDp2Ms2tRaa7yO6W4/sJosYHkXq4WHUkN9o0J2A9bX8H5aLximciX7G3WI5teRA /EqbkGN6D79qC1KxVP3AZRQQND0y3KeIg8mUDxykfFOA52Ewl2vdXBcsaSlb7v0jxsoO 0tkxZWGQ/C5jotXXQgvIR2DGtaOXBAKubdqGfi/1esACUSbZxyQcc7LIAs54gD88/Dum O4YOqtGNThBcDQN18pnl69ZQcF4oHtsslzeRlEs9KE/O8BFPmOxoDVPLno1PsLHnj3Za N/Sg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743571; x=1724348371; 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=VFwCK9X2QLe1/DNg8JobTxi3rYfg72O97+Gvq68riBQ=; b=oIL2CnLAPzqynyobVfM7KjUH6sddcdmaWOQH9DImSrY/VWDfMpLJ/vMcNj9hSTTgh7 3mob5VyTeS7/qdJMns05KC+RFfo32BThiV/gzYZmcpOC4TBW+76Ngf+rITggMhNHP810 Bz+7S1Ad6t794GyPgaOPIok2ZJziy8MUfCrOGOIdwX2aNcB5IQdM6WNfRSyn/goC7Er+ 18RbIyidAUEf+zPWPUVhQKRFUjMhPUcIuJF48ayvhEDCC57HTTL8mG9FEwI5P2BgUr+t uzZjS5KCZpad68GGvf/XqNyujKAQnFdejfeEKvNpDA00PaltHAOtiRZ57N/PlUkw9Zjp tmxw== X-Forwarded-Encrypted: i=1; AJvYcCXUDY/FY9i9cwtGNuq0NllmwVWNd1pDWByEf1hoVJ6I5Cs/c5pKbWSjCfKPoue+DlIMatvqeFXw/YjOH4d+ZhLjpGBX2ypj2Nyg7FJPCw== X-Gm-Message-State: AOJu0Yz+zHbpiGlPzZGD5w2r4r6pglH70syKe7KmKbZV16uggyRPKqsI bH34Az8QRWbmlgDxsuA8DcRD0ohwub+mofsWgtG46Sy+SS/GhB/jZdrcvTlTeBa6CkRJV0k+TxV mRt17jLSldVIGFpzItOqmzDgrEg== X-Google-Smtp-Source: AGHT+IFpDiu75N2mANtuo7v4YJMU2ippJB5ROuq6c/iYPG7F5aVX3ZilvaGAZuCVdos8P47ImkL+SqtNGTBwKkGZyaM= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a25:83d0:0:b0:e11:584f:c2ca with SMTP id 3f1490d57ef6-e1180e8eb8emr17972276.6.1723743571365; Thu, 15 Aug 2024 10:39:31 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:14 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=8281; i=samitolvanen@google.com; h=from:subject; bh=seTjzndQnpborzCoviHr6CbsMyWBJvxYdHHqERTVcCw=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj0538CHXm4iu8vyUzVodDzA+TFKe40vk7Xbk VkSEjAFJLWJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OQAKCRBMtfaEi7xW 7pEVC/9i6tqmTNz0zbieOL75N1vV2Nnd1mHzQqaT48B8+NCvNgaDNkPuFp8Z8wAHc5M5uyCEDTC GojTEMtseuO7exYf2efh5bAUu4D+M490awuJX8ORnX6D8iFr1EUiBC70La83m4CzZuC5isF7h02 fWE6iNLUDDBcNBRu8v+ACj9pFOoC3T6LhvpC1Tq1L2W9+2x5xZkk1GAfv72p2q8ytGVKe7ybVQE w2fZTAMaa7neJpMi4441GzoWvCx9FImmOhkQOlepo8mh+ApdvUD34tswj0gVt+ltl4Xe23bMVYM loz8EY37GPSjntf9a5MVcYMBKB81CJ01EKQswuecTckA3bTd6aAgfFJmK8FMscwcC/lFEp4K62/ KsX0ZOZQrl0+Lrqpx8FGvACY5v0dIeNtv97pJkApX6vBcSSceAU6/CCSjOOmXTG2tRH1TNAe9+E BOm/zHZ05DkegFlucoBm+FTm7udVomn7th9ksLWe66z29iEzPQ89BC4R1QZ/X91nqV/k0= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-31-samitolvanen@google.com> Subject: [PATCH v2 10/19] 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 , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , 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, i.e. structs, unions, and enums. Also include relevant DWARF attributes in type strings to encode structure layout, for example. Example output with --debug: subprogram( formal_parameter pointer_type *mut &str { structure_type &str { member pointer_type { base_type u8 byte_size(1) encoding(7) } data_member_location(0), member base_type usize byte_size(8) encoding(7) data_member_location(8), } byte_size(16) alignment(8) }, ) -> base_type void; Signed-off-by: Sami Tolvanen --- scripts/gendwarfksyms/dwarf.c | 129 +++++++++++++++++++++++++- scripts/gendwarfksyms/gendwarfksyms.h | 5 + 2 files changed, 132 insertions(+), 2 deletions(-) diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index 4ec69fce95f3..92b6ca4c5c91 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -206,9 +206,13 @@ static int process_fqn(struct state *state, struct die *cache, Dwarf_Die *die) return 0; \ } +DEFINE_PROCESS_UDATA_ATTRIBUTE(accessibility) DEFINE_PROCESS_UDATA_ATTRIBUTE(alignment) +DEFINE_PROCESS_UDATA_ATTRIBUTE(bit_size) DEFINE_PROCESS_UDATA_ATTRIBUTE(byte_size) DEFINE_PROCESS_UDATA_ATTRIBUTE(encoding) +DEFINE_PROCESS_UDATA_ATTRIBUTE(data_bit_offset) +DEFINE_PROCESS_UDATA_ATTRIBUTE(data_member_location) /* Match functions -- die_match_callback_t */ #define DEFINE_MATCH(type) \ @@ -217,8 +221,11 @@ DEFINE_PROCESS_UDATA_ATTRIBUTE(encoding) 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) { @@ -263,6 +270,10 @@ static int __process_list_type(struct state *state, struct die *cache, { check(process(state, cache, type)); check(process_type_attr(state, cache, die)); + check(process_accessibility_attr(state, cache, die)); + check(process_bit_size_attr(state, cache, die)); + check(process_data_bit_offset_attr(state, cache, die)); + check(process_data_member_location_attr(state, cache, die)); check(process(state, cache, ",")); return check(process_linebreak(cache, 0)); } @@ -275,6 +286,7 @@ static int __process_list_type(struct state *state, struct 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 die *cache, @@ -307,6 +319,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) @@ -361,6 +374,108 @@ static int process_subroutine_type(struct state *state, struct die *cache, return check(__process_subroutine_type(state, cache, die, "subroutine_type")); } +static int process_variant_type(struct state *state, struct 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 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 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 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 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 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 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 die *cache, Dwarf_Die *die) { @@ -438,17 +553,27 @@ static int process_type(struct state *state, struct die *parent, Dwarf_Die *die) 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; } /* Update cache state and append to the parent (if any) */ diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index 25f87485eb69..7d32ccd590f8 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -59,8 +59,13 @@ extern bool debug; #define checkp(expr) __check(expr, __res < 0, __res) /* 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 From patchwork Thu Aug 15 17:39:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765026 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 02CAD1BD016 for ; Thu, 15 Aug 2024 17:39:33 +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=1723743576; cv=none; b=YXIdMLhWSTrrRQPVMrKCGH2VL00DOviQdOKP6IEumZp4csJYwdNg6CotXmpG1rVkAWwv2JAogx/HB5X2+++N/9lj1OGHnn29pC9PF4bxer3jI/BR7jAHlhDeKjKLIUCLVlb3WArf8ZFH0EEzEdyp3NH0m9OFBXbSEjFpuxeazDw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743576; c=relaxed/simple; bh=IoI4F3wObxGX4LgHQUFQQdoaz1TRyk0IHL+WJGOTKzw=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=RHYggb2dDoE/It2aszRjI+QkbmUHbbcNWgKVyoY4ak09HVXzKhGFTgWq8JMuVHSlNPmVfF8etoyHuGFsJzCpB2i/nzq449mv8v+V/y8gnllxOpcLkhcWliMzncM/U1zrcR6l7P2ckLy14xZPZ93CgvuH3/CYqJ6ODSBVwVc1AN4= 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=NJ/Q/NG2; 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="NJ/Q/NG2" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-1fd8a1a75e7so11184415ad.3 for ; Thu, 15 Aug 2024 10:39:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743573; x=1724348373; 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=T2I7FT7XC1CLS96AVMtQrrnQsP2LCK4IFkNimJHZT1k=; b=NJ/Q/NG23shoJgIH4MFnTUtlo/Wzb8dxs3MJxGTTwa4M3vs4LwXRvmXjsQtOdybzzN lrktVN3e+wrqXOxihQApH12PH2WUNHeAD3cN6uSjQ7B0BG9ipl5xfO43vYlxfFbQgaNf irmfXXH40uXFEviIq3hbzz96RDaEDdZwa2G69ELQkmQcaAzbsbeJCL6dAN80UTFDVtyD yTjX/fphPJaAWH1gTXj6aoqsJSv3z3YEGqpXSmbMOUQKkAVRsE7yvgVBGMw8wbS8uMCX JUJZCSK0iEJmHo08lSGiM+xdV4AE8xt/kpC0bWnPmYrIP4hfj+MzEXrcQ81r5pB4AAXb oHVg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743573; x=1724348373; 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=T2I7FT7XC1CLS96AVMtQrrnQsP2LCK4IFkNimJHZT1k=; b=Dsag7HxVKSoStbtKqczSTY3OWbQ88dGqXKyGPXdHeuApdpUWVLKDfJvGyx9z9t6+yV Q4vUoMWrtSIF0Jeox/Wu+wSb77KWZKkgY9XEQOqa+ezN5r/Fr0OicbkcC7uzuOBzCa0l 6h1cJTtdcQ9OMMcdDI96P0ZzN5I42MDT029066s1qKV4uiyijOQn9sT5lHYJJyWPz0oB q3RskmwxUdhiFWwT8YZnq59rDuox8gDbq1YRhN+Y2r9I7KV7wJKJNY09vmHQXIrly0eY 7Da8BWrQQNZxTytTAbWlhG2zGiAV4aW3hEmboNeG2do8/Zo6/365o0ACHabqklUmCUrN cE9Q== X-Forwarded-Encrypted: i=1; AJvYcCWIb5PKQXnRZajbkVfMTT3BKpkXrtpGbiBOtwNnr4P/gru2rXTw/HkXfZerJyN3bTNkp+bgTHvJf+V0YXqA7jYnkhJcXWKIXj4vIqGDYg== X-Gm-Message-State: AOJu0YxkvcC3aGzRaFFo2zKWy/dCm+8RzJCdwdgOAfsf6dnj8ZYsIvZs FYiDpn0JGc4JtNapeDyGlcVp/5496DR63No4wWF6gPlEAa7x2rT2lwtNlfG4TEALNR3rzNTokSO 32axXK9TtlCV/QkFNiaowL4M75Q== X-Google-Smtp-Source: AGHT+IGe9pliul9/TcQbfTFZYC3NvVraMnHCkZgqO0axZCCnb7OvgeE4/zJ34X3uG8qzfevmce3mUDn4mCzjbOC5sZU= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a17:903:110e:b0:1ff:4618:36b8 with SMTP id d9443c01a7336-20203f54191mr314165ad.11.1723743573052; Thu, 15 Aug 2024 10:39:33 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:15 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=10707; i=samitolvanen@google.com; h=from:subject; bh=IoI4F3wObxGX4LgHQUFQQdoaz1TRyk0IHL+WJGOTKzw=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj05p/xVSrDsTqSQ6aJyo7Ou8bMUUGlmuI7/2 cxH2uubobaJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OQAKCRBMtfaEi7xW 7tdFDACpBQFkUOEnk3TqYP/yswobNakprEz/Ru4ffXB9Dk7Jgct6Y9xTZt7Qj6esbqqaFSSo2XA p7+/ODjP/CSOZA8YwFF4tupQRUZLOYkbHPJrRrYSEQxGSnUyNZqF+a9mWMprBrnKCuznwjF2bDG 8ejYX6mI99w0jD9wLF1jZCQGxyjWNs8fGLAOIoxvfgoF9cQtu4e76BA0mjc5M9KLT1jfTYtZ8Kb aimIyp+qwqNC9jz3uDLLntL4AOOerU49E7n1sfiwTzH0w8y+L+284Vdj8vkq03ax2VNKR4hnJlb g/a8dA5k+nKO+YFxaFIHPsm3DCmLXBeHJQ8nLpL+GwGJAfLDQnzJ5EzpgWyM0nuxQYWjy/LE2/C jjpXdaN0Sfzq9fVCGQfeiabKZG4yN2zL2LaLUGxSxtxavDLMoY2+8BiOk1zUUoA8PSdiKLzZMEZ Ssjzmf0xqIEwquRLsZhtz3/JFCmHkdAMlcv6lcj7rOG+PdOGvdAmkcff4Y6Ggu4EXHclM= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-32-samitolvanen@google.com> Subject: [PATCH v2 11/19] 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 , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , 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, but is still sufficient for catching ABI changes. For pointers to structure types, limit type expansion inside the pointer to two levels. This should be plenty for detecting ABI differences, but it stops us from pulling in half the kernel for types that contain pointers to large kernel data structures, like task_struct, for example. Signed-off-by: Sami Tolvanen --- scripts/gendwarfksyms/Makefile | 1 + scripts/gendwarfksyms/cache.c | 51 ++++++++++++ scripts/gendwarfksyms/dwarf.c | 108 ++++++++++++++++++++++++-- scripts/gendwarfksyms/gendwarfksyms.h | 38 ++++++++- 4 files changed, 189 insertions(+), 9 deletions(-) create mode 100644 scripts/gendwarfksyms/cache.c diff --git a/scripts/gendwarfksyms/Makefile b/scripts/gendwarfksyms/Makefile index fcbac52ca00a..681b42441840 100644 --- a/scripts/gendwarfksyms/Makefile +++ b/scripts/gendwarfksyms/Makefile @@ -1,6 +1,7 @@ hostprogs-always-y += gendwarfksyms gendwarfksyms-objs += gendwarfksyms.o +gendwarfksyms-objs += cache.o gendwarfksyms-objs += die.o gendwarfksyms-objs += dwarf.o gendwarfksyms-objs += symbols.o diff --git a/scripts/gendwarfksyms/cache.c b/scripts/gendwarfksyms/cache.c new file mode 100644 index 000000000000..0a4efdcb8cda --- /dev/null +++ b/scripts/gendwarfksyms/cache.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2024 Google LLC + */ + +#include "gendwarfksyms.h" + +struct expanded { + uintptr_t addr; + struct hlist_node hash; +}; + +int __cache_mark_expanded(struct expansion_cache *ec, uintptr_t addr) +{ + struct expanded *es; + + es = malloc(sizeof(struct expanded)); + if (!es) { + error("malloc failed"); + return -1; + } + + es->addr = addr; + hash_add(ec->cache, &es->hash, addr_hash(addr)); + return 0; +} + +bool __cache_was_expanded(struct expansion_cache *ec, uintptr_t addr) +{ + struct expanded *es; + + hash_for_each_possible(ec->cache, es, hash, addr_hash(addr)) { + if (es->addr == addr) + return true; + } + + return false; +} + +void cache_clear_expanded(struct expansion_cache *ec) +{ + struct hlist_node *tmp; + struct expanded *es; + int i; + + hash_for_each_safe(ec->cache, i, tmp, es, hash) { + free(es); + } + + hash_init(ec->cache); +} diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index 92b6ca4c5c91..2f1601015c4e 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -25,6 +25,7 @@ static int process_linebreak(struct die *cache, int n) !dwarf_form##attr(&da, value); \ } +DEFINE_GET_ATTR(flag, bool) DEFINE_GET_ATTR(udata, Dwarf_Word) static bool get_ref_die_attr(Dwarf_Die *die, unsigned int id, Dwarf_Die *value) @@ -69,6 +70,13 @@ static bool is_export_symbol(struct state *state, Dwarf_Die *die) return !!state->sym; } +static bool is_declaration(Dwarf_Die *die) +{ + bool value; + + return get_flag_attr(die, DW_AT_declaration, &value) && value; +} + /* * Type string processing */ @@ -421,19 +429,26 @@ static int __process_structure_type(struct state *state, struct die *cache, die_callback_t process_func, die_match_callback_t match_func) { + bool is_decl = is_declaration(die); + 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)); + if (!is_decl && state->expand.expand) { + check(cache_mark_expanded(&state->expansion_cache, die->addr)); + 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)); + if (!is_decl && state->expand.expand) { + check(process_byte_size_attr(state, cache, die)); + check(process_alignment_attr(state, cache, die)); + } return 0; } @@ -519,6 +534,42 @@ static int process_cached(struct state *state, struct die *cache, return 0; } +static void state_init(struct state *state) +{ + state->expand.expand = true; + state->expand.in_pointer_type = false; + state->expand.ptr_expansion_depth = 0; + hash_init(state->expansion_cache.cache); +} + +static void expansion_state_restore(struct expansion_state *state, + struct expansion_state *saved) +{ + state->ptr_expansion_depth = saved->ptr_expansion_depth; + state->in_pointer_type = saved->in_pointer_type; + state->expand = saved->expand; +} + +static void expansion_state_save(struct expansion_state *state, + struct expansion_state *saved) +{ + expansion_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 2 + #define PROCESS_TYPE(type) \ case DW_TAG_##type##_type: \ check(process_##type##_type(state, cache, die)); \ @@ -526,18 +577,56 @@ static int process_cached(struct state *state, struct die *cache, static int process_type(struct state *state, struct die *parent, Dwarf_Die *die) { + enum die_state want_state = COMPLETE; struct die *cache = NULL; + struct expansion_state saved; int tag = dwarf_tag(die); + expansion_state_save(&state->expand, &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->expand.in_pointer_type = saved.in_pointer_type || + is_pointer_type(tag); + + if (state->expand.in_pointer_type && + state->expand.ptr_expansion_depth >= MAX_POINTER_EXPANSION_DEPTH) + state->expand.expand = false; + else + state->expand.expand = + saved.expand && + !cache_was_expanded(&state->expansion_cache, die->addr); + + /* Keep track of pointer expansion depth */ + if (state->expand.expand && state->expand.in_pointer_type && + is_expanded_type(tag)) + state->expand.ptr_expansion_depth++; + + /* + * If we have want_state already cached, use it instead of walking * through DWARF. */ - check(die_map_get(die, COMPLETE, &cache)); + if (!state->expand.expand && is_expanded_type(tag)) + want_state = UNEXPANDED; + + check(die_map_get(die, want_state, &cache)); + + if (cache->state == want_state) { + if (want_state == COMPLETE && is_expanded_type(tag)) + check(cache_mark_expanded(&state->expansion_cache, + die->addr)); - if (cache->state == COMPLETE) { check(process_cached(state, cache, die)); check(die_map_add_die(parent, cache)); + + expansion_state_restore(&state->expand, &saved); return 0; } @@ -578,9 +667,10 @@ static int process_type(struct state *state, struct die *parent, Dwarf_Die *die) /* Update cache state and append to the parent (if any) */ cache->tag = tag; - cache->state = COMPLETE; + cache->state = want_state; check(die_map_add_die(parent, cache)); + expansion_state_restore(&state->expand, &saved); return 0; } @@ -643,6 +733,7 @@ static int process_exported_symbols(struct state *state, struct die *cache, return 0; debug("%s", state->sym->name); + state_init(state); if (is_symbol_ptr(get_name(&state->die))) check(process_symbol_ptr(state, &state->die)); @@ -651,6 +742,7 @@ static int process_exported_symbols(struct state *state, struct die *cache, else check(process_variable(state, &state->die)); + cache_clear_expanded(&state->expansion_cache); return 0; default: return 0; diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index 7d32ccd590f8..6482503e7d6e 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -106,7 +106,7 @@ extern struct symbol *symbol_get(const char *name); * die.c */ -enum die_state { INCOMPLETE, COMPLETE, LAST = COMPLETE }; +enum die_state { INCOMPLETE, UNEXPANDED, COMPLETE, LAST = COMPLETE }; enum die_fragment_type { EMPTY, STRING, LINEBREAK, DIE }; struct die_fragment { @@ -128,6 +128,7 @@ static inline const char *die_state_name(enum die_state state) switch (state) { default: CASE_CONST_TO_STR(INCOMPLETE) + CASE_CONST_TO_STR(UNEXPANDED) CASE_CONST_TO_STR(COMPLETE) } } @@ -150,15 +151,50 @@ extern int die_map_add_linebreak(struct die *pd, int linebreak); extern int die_map_add_die(struct die *pd, struct die *child); extern void die_map_free(void); +/* + * cache.c + */ + +#define EXPANSION_CACHE_HASH_BITS 11 + +/* A cache for addresses we've already seen. */ +struct expansion_cache { + DECLARE_HASHTABLE(cache, EXPANSION_CACHE_HASH_BITS); +}; + +extern int __cache_mark_expanded(struct expansion_cache *ec, uintptr_t addr); +extern bool __cache_was_expanded(struct expansion_cache *ec, uintptr_t addr); + +static inline int cache_mark_expanded(struct expansion_cache *ec, void *addr) +{ + return __cache_mark_expanded(ec, (uintptr_t)addr); +} + +static inline bool cache_was_expanded(struct expansion_cache *ec, void *addr) +{ + return __cache_was_expanded(ec, (uintptr_t)addr); +} + +extern void cache_clear_expanded(struct expansion_cache *ec); + /* * dwarf.c */ +struct expansion_state { + bool expand; + bool in_pointer_type; + unsigned int ptr_expansion_depth; +}; struct state { Dwfl_Module *mod; Dwarf *dbg; struct symbol *sym; Dwarf_Die die; + + /* Structure expansion */ + struct expansion_state expand; + struct expansion_cache expansion_cache; }; typedef int (*die_callback_t)(struct state *state, struct die *cache, From patchwork Thu Aug 15 17:39:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765027 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 C87571BD51F for ; Thu, 15 Aug 2024 17:39:35 +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=1723743577; cv=none; b=rKq3r5Sud5racsrqY5pgN7bIv+gFnlJRx9ZUCwJ2cKrrPfHGUFBilkEKUb70TmNlWy0ChNNqQicAmJ8b5ySRl2WHkMfxFh6KZapngSn6FU4b1wyrlfUHlolC5OuvTyQQd2c4N+Sf0lCGZpIkA+rfKlPSdwgoPlCSDHsfmUc39Vo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743577; c=relaxed/simple; bh=1jJqo9o9aQH+E0GjG/ROahqjvj9Bo5ZqYdph8BSQRt0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=hw9j2os+t/yjs3TB9i/c4m3zKQxS7vlitro8Bz0+iJfQsOAESWiS7F7bimj1q4nlFakfkmG9H8kwOaNCRwTnKP9sqxMujgmldu2S07T9FNpw5tE7WX0zlCdVrLaakKnGU/c1RDVU7y/wuXfLEaxb5vquoqrQxloBhpxbUS0lRA4= 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=JZaHQqBH; 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="JZaHQqBH" Received: by mail-pl1-f201.google.com with SMTP id d9443c01a7336-1fd9a0efe4eso10132255ad.0 for ; Thu, 15 Aug 2024 10:39:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743575; x=1724348375; 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=qtbsIaIfhBiE1DbP5u+JRQZBtsqBwwZART8vtMh98sw=; b=JZaHQqBHQ8g6oatqcBrmCMmZdtVOOa78cVVRTvXj52y+P42i/0rKH+On7UefoKYCh3 AsTI/Av+lWN5icxUuFk392Ph+QbaasPydbuVRIL4SqklPXummpWmYdgvW89/l5QAE41M 8um2uFJJD8EDdg5A945eiktS5+EkUSHDzAv6H1iXGNpnTcGH9+6s0jn7x/UHGdo3MizN 3f+9ZwhwaqkqVGVs/dnj4U7XfBfyy5/lW/lTO5sEVraGmMkNfJN6k+T/V752xAgM5b+G Cz+s4CyIl2bAPBE73nZYl68U8aUWAj/NLemoD9cSEcG4HotoOBjDmsCfPIRLtSNSE/Uq tC/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743575; x=1724348375; 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=qtbsIaIfhBiE1DbP5u+JRQZBtsqBwwZART8vtMh98sw=; b=hls2oSQTqjy30g7P0XqpuA0nFvChL1f+e903pLvXqoHU2CrwqMJsbAxVNuLVlO0dyu 4pbq+geGy9ANFo4Nmx+UIcxQahiKS6fTeyc0OvGYcvtLiKzpUjBxZZfqdJc+tapzHU/F 1T8vbhoP2FhGFoJzZ9LbvAISsmjsgZEQepqJNRYZgLlGrbWbjLVJGfFm5Fq1K7SARa0k V1xjF75HoZ//qYgJeyHsXZhOUW8y5M/cfI2GjTdBIh+U4R/9Ej61SwPtKMHfjHh0ISca Zm7Zv8Vno5Qpi0mlBCbMwSILKhWqTbWiy9pyC7XpNqOLHAH/kplzteT+MsMqu0yIQr2j 02iQ== X-Forwarded-Encrypted: i=1; AJvYcCVHWQ8QN7ao4Fn9OPxr33vBce9ZYVQYVe+EGZswGyTUfyVS5j/2ORycE1rIvZDy5X0ZnSofpndhz96FqlnXLE2Ih04X9MaqvwxUCVwgAg== X-Gm-Message-State: AOJu0Yw4IW11hF1oHbehnNzSWa5YHG7ulDYm6hdim6KpjBc9xeNBZrKM EFTdu9r62PURaAjo04yS7I78vI2wLQDXQUeov/ugBdwTGqfrScltXX1RJpHgTXAVXkPqiItLvgF gTlm+8OQ4aA9c+0F6aKSyf77aPw== X-Google-Smtp-Source: AGHT+IF2vutxQWYsriPKvF7iI6jHIZpZUjx/Iv3JjPdtDdO8O3OmwJ4gQIgzjZnRFjJRknlMxQakessYN+u5iq/0Q34= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a17:902:da8a:b0:1fb:8c26:4b17 with SMTP id d9443c01a7336-20203f31506mr8565ad.9.1723743574840; Thu, 15 Aug 2024 10:39:34 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:16 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=5220; i=samitolvanen@google.com; h=from:subject; bh=1jJqo9o9aQH+E0GjG/ROahqjvj9Bo5ZqYdph8BSQRt0=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj05p4mX3gDUPwZMYwEx1Enne0Ag7prR0Wlf9 GzJChEBdZ6JAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OQAKCRBMtfaEi7xW 7s/sC/9MpvmBZcBA9Rv5mHdI+WO1ut2X7/+YdUhXZtWBz5unbj8Q0jRG1WT0/AAKbXHhGFhIEMC X48h5BwZq8SlLLyqhRsZjVyp1HsmW2h+tl+Q4fUPl1fF5p+jdUakcqxl6m3nZF4lsL+9NWu5JyZ s+ui6D+VRcrnaanyw68hKvjPehdgh16dBL4JBaEkHwFZcb6kUfewAwnLS73rV/+mpMEtt/eppVg tcYwIelS5xQcn7l/B47w0V3vpKEmoubCXJePF1QGoDIsei9LcUbRJdMpJhMXJ8Cl2FmxhVMXbrX dfWpegajVmmUL3KBFjw6ew3AbdEJ7YR/K7ZGcEgik61UJ4FATwBDbBpxNmn3WOVQfo+6u4iEgwc 9sfUaIROxzykz0kzS8LTmURr4Rlboz2p+03LGzJRfTTfJC5Tfuxx/NXCRoO//+HDGfTJyhzUtM9 pIwZNM8rkonwJS7VzTs8pRDeL9rC5MF5DV664B/DXAxhOoyHXXefgyDXA8e87h3bmm6Hk= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-33-samitolvanen@google.com> Subject: [PATCH v2 12/19] gendwarfksyms: Add die_map debugging From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Debugging the DWARF processing can be somewhat challenging, so add more detailed debugging output for die_map operations. Move parsed die_map output behind --dump-dies to clean up the --debug output, and add a --dump-die-map flag, which adds highlighted tags to the output about die_map operations. Signed-off-by: Sami Tolvanen --- scripts/gendwarfksyms/dwarf.c | 19 +++++++++++++++++-- scripts/gendwarfksyms/gendwarfksyms.c | 9 +++++++++ scripts/gendwarfksyms/gendwarfksyms.h | 14 ++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index 2f1601015c4e..9bca21a71639 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -84,15 +84,17 @@ static int process(struct state *state, struct die *cache, const char *s) { s = s ?: ""; - if (debug && do_linebreak) { + if (dump_dies && do_linebreak) { fputs("\n", stderr); for (int i = 0; i < indentation_level; i++) fputs(" ", stderr); do_linebreak = false; } - if (debug) + if (dump_dies) fputs(s, stderr); + if (cache) + die_debug_r("cache %p string '%s'", cache, s); return check(die_map_add_string(cache, s)); } @@ -510,6 +512,8 @@ static int process_cached(struct state *state, struct die *cache, while (df) { switch (df->type) { case STRING: + die_debug_b("cache %p STRING '%s'", cache, + df->data.str); check(process(state, NULL, df->data.str)); break; case LINEBREAK: @@ -522,6 +526,8 @@ static int process_cached(struct state *state, struct die *cache, error("dwarf_die_addr_die failed"); return -1; } + die_debug_b("cache %p DIE addr %" PRIxPTR " tag %d", + cache, df->data.addr, dwarf_tag(&child)); check(process_type(state, NULL, &child)); break; default: @@ -619,6 +625,9 @@ static int process_type(struct state *state, struct die *parent, Dwarf_Die *die) check(die_map_get(die, want_state, &cache)); if (cache->state == want_state) { + die_debug_g("cached addr %p tag %d -- %s", die->addr, tag, + die_state_name(cache->state)); + if (want_state == COMPLETE && is_expanded_type(tag)) check(cache_mark_expanded(&state->expansion_cache, die->addr)); @@ -630,6 +639,9 @@ static int process_type(struct state *state, struct die *parent, Dwarf_Die *die) return 0; } + die_debug_g("addr %p tag %d -- INCOMPLETE -> %s", die->addr, tag, + die_state_name(want_state)); + switch (tag) { /* Type modifiers */ PROCESS_TYPE(atomic) @@ -665,6 +677,9 @@ static int process_type(struct state *state, struct die *parent, Dwarf_Die *die) return -1; } + die_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->tag = tag; cache->state = want_state; diff --git a/scripts/gendwarfksyms/gendwarfksyms.c b/scripts/gendwarfksyms/gendwarfksyms.c index 55a7fc902bf4..1349e592783b 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.c +++ b/scripts/gendwarfksyms/gendwarfksyms.c @@ -16,6 +16,10 @@ /* Print out debugging information to stderr */ bool debug; +/* Print out die_map contents */ +bool dump_dies; +/* Print out inline debugging information about die_map changes */ +bool dump_die_map; static const struct { const char *arg; @@ -23,6 +27,8 @@ static const struct { const char **param; } options[] = { { "--debug", &debug, NULL }, + { "--dump-dies", &dump_dies, NULL }, + { "--dump-die-map", &dump_die_map, NULL }, }; static int usage(void) @@ -111,6 +117,9 @@ int main(int argc, const char **argv) if (parse_options(argc, argv) < 0) return usage(); + if (dump_die_map) + dump_dies = true; + check(symbol_read_exports(stdin)); for (n = 0; n < object_count; n++) { diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index 6482503e7d6e..7cd907e3d5e3 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -20,6 +20,8 @@ * Options -- in gendwarfksyms.c */ extern bool debug; +extern bool dump_dies; +extern bool dump_die_map; #define MAX_INPUT_FILES 128 @@ -40,6 +42,18 @@ extern bool debug; #define warn(format, ...) __println("warning: ", format, ##__VA_ARGS__) #define error(format, ...) __println("error: ", format, ##__VA_ARGS__) +#define __die_debug(color, format, ...) \ + do { \ + if (dump_dies && dump_die_map) \ + fprintf(stderr, \ + "\033[" #color "m<" format ">\033[39m", \ + __VA_ARGS__); \ + } while (0) + +#define die_debug_r(format, ...) __die_debug(91, format, __VA_ARGS__) +#define die_debug_g(format, ...) __die_debug(92, format, __VA_ARGS__) +#define die_debug_b(format, ...) __die_debug(94, format, __VA_ARGS__) + /* * Error handling helpers */ From patchwork Thu Aug 15 17:39:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765028 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 81A481BDA9E for ; Thu, 15 Aug 2024 17:39:37 +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=1723743579; cv=none; b=MU/lUBSlzHQFlrpnI2RSRmnI/FlnIW1HOFIP5bOOyRdi6VsA6DfvyaPY75fB38VT0mdBoSrltZc9GUEVZu5Am+VImiNF/slv0jlZ/IEhl9aNsAcgor2Zorzt8+lmtBaRHQCwv/Q/1zks18is+6Zw9uIZoHK3AR04JTvIfsL3tbI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743579; c=relaxed/simple; bh=3OGd53ci+q4WoJQ7zoiq5FjPRZnrf/+Zl9zq4u0fJ80=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Um+MYjCc09pyC/rOe4BIbU8yIlG0XagrvrgRCb2nOzDYith9rQ+XAXNx/2vIiMWO5gqQZazfJqioV1ROF0G9Xv5kSQO4z6h460+iAsvAcWxJ7INY2w5O/OTTh4TcmKynq0GInjB3NlZylq5DWohqDu9jTR8cPmSDbZo4YHPPyoA= 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=zHOvvhAy; 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="zHOvvhAy" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-7c6a4d99dbdso1043375a12.0 for ; Thu, 15 Aug 2024 10:39:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743577; x=1724348377; 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=R0+ZG5cfBXWxYUBN+iDOhSdjTCyCSwKpy98HChPuRi4=; b=zHOvvhAy8NrVa5Ur3z+Fwcj2vV0mJjZMOd2T43zbCL5N9LottMfeDQfm4uqctHdBXp BrOrmRGYXUKxYC88lMPuLdDbh63rLfipdSJti2pnSqhDonFiiGkEY1zK8gLdP/6XU+rH 4uzNqpOlTTsrL3hnZtMrovkYY6Fx1uBz27EefoKkAG1D2x6VQ0oInJ26KC+Xtg6qiuEH /zyhc5pHGwENjQFigF6DU9zslLzbH9HAN8q5jivR5HVUyhlMiPQ8Qs2pdVkXTXaWTRzy TA23/KBZd0Gu/aECnkbyT3zAMG5JUP2dNlAJCCXmsvil8TAC3MMnTY0age94Z5d8CauY 8jwQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743577; x=1724348377; 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=R0+ZG5cfBXWxYUBN+iDOhSdjTCyCSwKpy98HChPuRi4=; b=qYMInnP88CZGESUQ1gePSrqC1MLPyWNr5vIUls7gAYjhr1bh95ABi0ClykdyHb9Kw/ cmcFDScsaHBozG7di7dsY6ZnW4Tqoqy9hbh3LvQiwiH2dyjEZXjWh/Fpd0XRhttpdVfv t5ODrJB3LGBCiw7/Ei204SUsmAMfXnVp59sntvYT32cKjfGJ4Tm/sVz2dqfSyKXJPPAu BFSvKf+XVksGd4BDKjojLSbYGsWLY9+psGBPOBWHexsXQcfETUvPemiJbrRi8KA4bPxB TX/a7mz3xIL0BK6S8Ctoo3tHehUHEbC5XTQed1BvC5OCxGc5oiBFZ4NJ/VX1Fmc5REOE iwQA== X-Forwarded-Encrypted: i=1; AJvYcCXG1Id338ieNzMmZPdOfz0vaoZB5MYhRYrwBed+ZbChHrSC0vICjhiHSOQ/kMsgVRicr4sDiTZXp/qfZhuhmwRkNu8q0xtfQvl9tUABqQ== X-Gm-Message-State: AOJu0YwaYc4qVQyZwa9IF2hVZHLI1To6rHNooQ6kn3reBKCJS1zwBQ3F 5dSS3Ah49XNokbXvg1my0x9ZQxG6mD5zAX0T5640U+HI8tvigHXqNImwrn3hdGArI+VVT6imOB+ 9RKH+vSDviPwBEZ+TmV4lwglYow== X-Google-Smtp-Source: AGHT+IEepXE2gDbPPAKQup7O1RDQKgqeMe4NyUQa83ZG0Cq67RXgdeF+09vux/MkGzQQSEDEiZkeA0UJvZni1RWq4M4= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a17:90b:19cf:b0:2d3:b3d3:9268 with SMTP id 98e67ed59e1d1-2d3dfac6178mr3402a91.0.1723743576435; Thu, 15 Aug 2024 10:39:36 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:17 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=19478; i=samitolvanen@google.com; h=from:subject; bh=3OGd53ci+q4WoJQ7zoiq5FjPRZnrf/+Zl9zq4u0fJ80=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj05aX7jT8BakrBurFol6kOrSU66GOurimWs6 hHHTgRIJ2aJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OQAKCRBMtfaEi7xW 7ksSC/wJar82tdMdN5LwANOWeWbfeG8Ec0lJY4txtaBNntno/uLr2yeatJ8+//KE93k7EY5zted fmIfp56jRtaytcegBrL2CXrZeiWy85zecrQNsF7bAltiDgGLGOYonIGF4mQVrxQWZXPVALA9g+o Kpdct6Aahpy0UHLYEiMq9rAh92DqeC1ZC9GOg7YlkPPEZiipNGNfmXYd9IWZBsyM2tCxwcVR2jU qAQwhR7IC00bI4m6WaKGo6zGVOz8ANRMEfj3HwjsZTc7iCN/SNJRjBfOtaMrtZR27Zi3PxoNhWO dGvRx5dd/XxeEID3lnbfPT286/Md7M8+FBN5wSGkXngY4FoubjUrFJ9AeH23YVtHKNidBfLCza5 xWuvqbraXKi1+AAd3y1l1J9E5Zb1qC/Yx845vakV0KtzuIdDQM+EJlmCX76+fkSlsXM0eyp7c7G rIsV3upLFnFtE7gKgu7Kin0Ptl6zTJbkn9xM6jlsEsutrqiLblqgBAX5QA/lhhM7ZTveA= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-34-samitolvanen@google.com> Subject: [PATCH v2 13/19] gendwarfksyms: Add symtypes output From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , 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 producing genksyms-style symtypes files. Process die_map to find the longest expansions for each type, and use symtypes references in type definitions. The basic file format is similar to genksyms, with two notable exceptions: 1. Type names with spaces (common with Rust) in references are wrapped in single quotes. E.g.: s#'core::result::Result' 2. The actual type definition is the simple parsed DWARF format we output with --dump-dies, not the preprocessed C-style format genksyms produces. Signed-off-by: Sami Tolvanen --- scripts/gendwarfksyms/Makefile | 1 + scripts/gendwarfksyms/die.c | 13 + scripts/gendwarfksyms/dwarf.c | 14 +- scripts/gendwarfksyms/gendwarfksyms.c | 28 +- scripts/gendwarfksyms/gendwarfksyms.h | 21 +- scripts/gendwarfksyms/symbols.c | 11 +- scripts/gendwarfksyms/types.c | 439 ++++++++++++++++++++++++++ 7 files changed, 517 insertions(+), 10 deletions(-) create mode 100644 scripts/gendwarfksyms/types.c diff --git a/scripts/gendwarfksyms/Makefile b/scripts/gendwarfksyms/Makefile index 681b42441840..4866a2fd0e46 100644 --- a/scripts/gendwarfksyms/Makefile +++ b/scripts/gendwarfksyms/Makefile @@ -5,6 +5,7 @@ gendwarfksyms-objs += cache.o gendwarfksyms-objs += die.o gendwarfksyms-objs += dwarf.o gendwarfksyms-objs += symbols.o +gendwarfksyms-objs += types.o HOST_EXTRACFLAGS := -I $(srctree)/tools/include HOSTLDLIBS_gendwarfksyms := -ldw -lelf diff --git a/scripts/gendwarfksyms/die.c b/scripts/gendwarfksyms/die.c index fdd52df88fdd..e40f04b70f7f 100644 --- a/scripts/gendwarfksyms/die.c +++ b/scripts/gendwarfksyms/die.c @@ -85,6 +85,19 @@ static void reset_die(struct die *cd) cd->list = NULL; } +int die_map_for_each(die_map_callback_t func, void *arg) +{ + struct die *cd; + struct hlist_node *tmp; + int i; + + hash_for_each_safe(die_map, i, tmp, cd, hash) { + check(func(cd, arg)); + } + + return 0; +} + void die_map_free(void) { struct hlist_node *tmp; diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index 9bca21a71639..62241cc97a76 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -60,11 +60,11 @@ static bool is_export_symbol(struct state *state, Dwarf_Die *die) if (get_ref_die_attr(die, DW_AT_abstract_origin, &origin)) source = &origin; - state->sym = symbol_get(get_name(die)); + state->sym = symbol_get_unprocessed(get_name(die)); /* Look up using the origin name if there are no matches. */ if (!state->sym && source != die) - state->sym = symbol_get(get_name(source)); + state->sym = symbol_get_unprocessed(get_name(source)); state->die = *source; return !!state->sym; @@ -384,6 +384,7 @@ static int process_subroutine_type(struct state *state, struct die *cache, return check(__process_subroutine_type(state, cache, die, "subroutine_type")); } + static int process_variant_type(struct state *state, struct die *cache, Dwarf_Die *die) { @@ -695,14 +696,16 @@ static int process_type(struct state *state, struct die *parent, Dwarf_Die *die) static int process_subprogram(struct state *state, Dwarf_Die *die) { check(__process_subroutine_type(state, NULL, die, "subprogram")); - return check(process(state, NULL, ";\n")); + state->sym->state = MAPPED; + return 0; } static int process_variable(struct state *state, Dwarf_Die *die) { check(process(state, NULL, "variable ")); check(process_type_attr(state, NULL, die)); - return check(process(state, NULL, ";\n")); + state->sym->state = MAPPED; + return 0; } static int process_symbol_ptr(struct state *state, Dwarf_Die *die) @@ -757,6 +760,9 @@ static int process_exported_symbols(struct state *state, struct die *cache, else check(process_variable(state, &state->die)); + if (dump_dies) + fputs("\n", stderr); + cache_clear_expanded(&state->expansion_cache); return 0; default: diff --git a/scripts/gendwarfksyms/gendwarfksyms.c b/scripts/gendwarfksyms/gendwarfksyms.c index 1349e592783b..6a219a54c342 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.c +++ b/scripts/gendwarfksyms/gendwarfksyms.c @@ -20,6 +20,11 @@ bool debug; bool dump_dies; /* Print out inline debugging information about die_map changes */ bool dump_die_map; +/* Print out type_map contents */ +bool dump_types; +/* Produce a symtypes file */ +bool symtypes; +static const char *symtypes_file; static const struct { const char *arg; @@ -29,6 +34,8 @@ static const struct { { "--debug", &debug, NULL }, { "--dump-dies", &dump_dies, NULL }, { "--dump-die-map", &dump_die_map, NULL }, + { "--dump-types", &dump_types, NULL }, + { "--symtypes", &symtypes, &symtypes_file }, }; static int usage(void) @@ -79,6 +86,7 @@ static int process_modules(Dwfl_Module *mod, void **userdata, const char *name, Dwarf_Die cudie; Dwarf_CU *cu = NULL; Dwarf *dbg; + FILE *symfile = arg; int res; debug("%s", name); @@ -100,6 +108,10 @@ static int process_modules(Dwfl_Module *mod, void **userdata, const char *name, check(process_module(mod, dbg, &cudie)); } while (cu); + /* + * Use die_map to expand type strings and write them to `symfile`. + */ + check(generate_symtypes(symfile)); die_map_free(); return DWARF_CB_OK; @@ -112,6 +124,7 @@ static const Dwfl_Callbacks callbacks = { int main(int argc, const char **argv) { + FILE *symfile = NULL; unsigned int n; if (parse_options(argc, argv) < 0) @@ -122,6 +135,16 @@ int main(int argc, const char **argv) check(symbol_read_exports(stdin)); + if (symtypes_file) { + symfile = fopen(symtypes_file, "w+"); + + if (!symfile) { + error("fopen failed for '%s': %s", symtypes_file, + strerror(errno)); + return -1; + } + } + for (n = 0; n < object_count; n++) { Dwfl *dwfl; int fd; @@ -151,7 +174,7 @@ int main(int argc, const char **argv) dwfl_report_end(dwfl, NULL, NULL); - if (dwfl_getmodules(dwfl, &process_modules, NULL, 0)) { + if (dwfl_getmodules(dwfl, &process_modules, symfile, 0)) { error("dwfl_getmodules failed for '%s'", object_files[n]); return -1; @@ -161,5 +184,8 @@ int main(int argc, const char **argv) close(fd); } + if (symfile) + fclose(symfile); + return 0; } diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index 7cd907e3d5e3..6edbd6478e0f 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -22,6 +22,8 @@ extern bool debug; extern bool dump_dies; extern bool dump_die_map; +extern bool dump_types; +extern bool symtypes; #define MAX_INPUT_FILES 128 @@ -89,6 +91,12 @@ extern bool dump_die_map; #define SYMBOL_PTR_PREFIX "__gendwarfksyms_ptr_" #define SYMBOL_PTR_PREFIX_LEN (sizeof(SYMBOL_PTR_PREFIX) - 1) +/* See dwarf.c:is_declaration */ +#define SYMBOL_DECLONLY_PREFIX "__gendwarfksyms_declonly_" +#define SYMBOL_DECLONLY_PREFIX_LEN (sizeof(SYMBOL_DECLONLY_PREFIX) - 1) + +enum symbol_state { UNPROCESSED, MAPPED }; + struct symbol_addr { uint32_t section; Elf64_Addr address; @@ -109,12 +117,14 @@ struct symbol { struct symbol_addr addr; struct hlist_node addr_hash; struct hlist_node name_hash; + enum symbol_state state; + uintptr_t die_addr; }; extern bool is_symbol_ptr(const char *name); extern int symbol_read_exports(FILE *file); extern int symbol_read_symtab(int fd); -extern struct symbol *symbol_get(const char *name); +extern struct symbol *symbol_get_unprocessed(const char *name); /* * die.c @@ -157,12 +167,15 @@ struct die { struct hlist_node hash; }; +typedef int (*die_map_callback_t)(struct die *, void *arg); + extern int __die_map_get(uintptr_t addr, enum die_state state, struct die **res); extern int die_map_get(Dwarf_Die *die, enum die_state state, struct die **res); extern int die_map_add_string(struct die *pd, const char *str); extern int die_map_add_linebreak(struct die *pd, int linebreak); extern int die_map_add_die(struct die *pd, struct die *child); +extern int die_map_for_each(die_map_callback_t func, void *arg); extern void die_map_free(void); /* @@ -222,4 +235,10 @@ extern int process_die_container(struct state *state, struct die *cache, extern int process_module(Dwfl_Module *mod, Dwarf *dbg, Dwarf_Die *cudie); +/* + * types.c + */ + +extern int generate_symtypes(FILE *file); + #endif /* __GENDWARFKSYMS_H */ diff --git a/scripts/gendwarfksyms/symbols.c b/scripts/gendwarfksyms/symbols.c index d6d016458ae1..8cc04e6295a7 100644 --- a/scripts/gendwarfksyms/symbols.c +++ b/scripts/gendwarfksyms/symbols.c @@ -117,6 +117,7 @@ int symbol_read_exports(FILE *file) sym->name = name; sym->addr.section = SHN_UNDEF; + sym->state = UNPROCESSED; name = NULL; hash_add(symbol_names, &sym->name_hash, name_hash(sym->name)); @@ -132,19 +133,21 @@ int symbol_read_exports(FILE *file) return 0; } -static int get_symbol(struct symbol *sym, void *arg) +static int get_unprocessed(struct symbol *sym, void *arg) { struct symbol **res = arg; - *res = sym; + if (sym->state == UNPROCESSED) + *res = sym; + return 0; } -struct symbol *symbol_get(const char *name) +struct symbol *symbol_get_unprocessed(const char *name) { struct symbol *sym = NULL; - for_each(name, false, get_symbol, &sym); + for_each(name, false, get_unprocessed, &sym); return sym; } diff --git a/scripts/gendwarfksyms/types.c b/scripts/gendwarfksyms/types.c new file mode 100644 index 000000000000..7b9997d8322d --- /dev/null +++ b/scripts/gendwarfksyms/types.c @@ -0,0 +1,439 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2024 Google LLC + */ + +#include "gendwarfksyms.h" +#include "crc32.h" + +static struct expansion_cache expansion_cache; + +/* + * A simple linked list of shared or owned strings to avoid copying strings + * around when not necessary. + */ +struct type_list { + const char *str; + void *owned; + struct type_list *next; +}; + +static struct type_list *type_list_alloc(void) +{ + struct type_list *list; + + list = calloc(1, sizeof(struct type_list)); + if (!list) + error("calloc failed"); + + return list; +} + +static void type_list_free(struct type_list *list) +{ + struct type_list *tmp; + + while (list) { + if (list->owned) + free(list->owned); + + tmp = list; + list = list->next; + free(tmp); + } +} + +static int type_list_append(struct type_list *list, const char *s, void *owned) +{ + if (!list || !s) + return 0; + + while (list->next) + list = list->next; + + if (list->str) { + list->next = type_list_alloc(); + + if (!list->next) { + error("type_list_alloc failed"); + return -1; + } + + list = list->next; + } + + list->str = s; + list->owned = owned; + + return strlen(list->str); +} + +static int type_list_write(struct type_list *list, FILE *file) +{ + while (list) { + if (list->str) + checkp(fputs(list->str, file)); + list = list->next; + } + + return 0; +} + +/* + * An expanded type string in symtypes format. + */ +struct type_expansion { + char *name; + struct type_list *expanded; + struct type_list *last; + size_t len; + struct hlist_node hash; +}; + +static int type_expansion_init(struct type_expansion *type, bool alloc) +{ + memset(type, 0, sizeof(struct type_expansion)); + if (alloc) { + type->expanded = type_list_alloc(); + if (!type->expanded) + return -1; + + type->last = type->expanded; + } + return 0; +} + +static inline void type_expansion_free(struct type_expansion *type) +{ + free(type->name); + type_list_free(type->expanded); + type_expansion_init(type, false); +} + +static int type_expansion_append(struct type_expansion *type, const char *s, + void *owned) +{ + type->len += checkp(type_list_append(type->last, s, owned)); + + if (type->last->next) + type->last = type->last->next; + + return 0; +} + +/* + * type_map -- the longest expansions for each type. + * + * const char *name -> struct type_expansion * + */ +#define TYPE_HASH_BITS 16 +static DEFINE_HASHTABLE(type_map, TYPE_HASH_BITS); + +static int type_map_get(const char *name, struct type_expansion **res) +{ + struct type_expansion *e; + + hash_for_each_possible(type_map, e, hash, name_hash(name)) { + if (!strcmp(name, e->name)) { + *res = e; + return 0; + } + } + + return -1; +} + +static int type_map_add(const char *name, struct type_expansion *type) +{ + struct type_expansion *e; + + if (type_map_get(name, &e)) { + e = malloc(sizeof(struct type_expansion)); + if (!e) { + error("malloc failed"); + return -1; + } + + type_expansion_init(e, false); + + e->name = strdup(name); + if (!e->name) { + error("strdup failed"); + return -1; + } + + hash_add(type_map, &e->hash, name_hash(e->name)); + + if (dump_types) + debug("adding %s", e->name); + } else { + /* Use the longest available expansion */ + if (type->len <= e->len) + return 0; + + type_list_free(e->expanded); + + if (dump_types) + debug("replacing %s", e->name); + } + + /* Take ownership of type->expanded */ + e->expanded = type->expanded; + e->last = type->last; + e->len = type->len; + type->expanded = NULL; + type->last = NULL; + type->len = 0; + + if (dump_types) { + fputs(e->name, stderr); + fputs(" ", stderr); + type_list_write(e->expanded, stderr); + fputs("\n", stderr); + } + + return 0; +} + +static int type_map_write(FILE *file) +{ + struct type_expansion *e; + struct hlist_node *tmp; + int i; + + if (!file) + return 0; + + hash_for_each_safe(type_map, i, tmp, e, hash) { + checkp(fputs(e->name, file)); + checkp(fputs(" ", file)); + type_list_write(e->expanded, file); + checkp(fputs("\n", file)); + } + + return 0; +} + +static void type_map_free(void) +{ + struct type_expansion *e; + struct hlist_node *tmp; + int i; + + hash_for_each_safe(type_map, i, tmp, e, hash) { + type_expansion_free(e); + free(e); + } + + hash_init(type_map); +} + +/* + * Type reference format: #, where prefix: + * s -> structure + * u -> union + * e -> enum + * t -> typedef + * + * Names with spaces are additionally wrapped in single quotes. + */ +static inline bool is_type_prefix(const char *s) +{ + return (s[0] == 's' || s[0] == 'u' || s[0] == 'e' || s[0] == 't') && + s[1] == '#'; +} + +static char get_type_prefix(int tag) +{ + switch (tag) { + case DW_TAG_class_type: + case DW_TAG_structure_type: + return 's'; + case DW_TAG_union_type: + return 'u'; + case DW_TAG_enumeration_type: + return 'e'; + case DW_TAG_typedef_type: + return 't'; + default: + return 0; + } +} + +static char *get_type_name(struct die *cache) +{ + const char *format; + char prefix; + char *name; + size_t len; + + if (cache->state == INCOMPLETE) { + warn("found incomplete cache entry: %p", cache); + return NULL; + } + if (!cache->fqn) + return NULL; + + prefix = get_type_prefix(cache->tag); + if (!prefix) + return NULL; + + /* #\0 */ + len = 2 + strlen(cache->fqn) + 1; + + /* Wrap names with spaces in single quotes */ + if (strstr(cache->fqn, " ")) { + format = "%c#'%s'"; + len += 2; + } else { + format = "%c#%s"; + } + + name = malloc(len); + if (!name) { + error("malloc failed"); + return NULL; + } + + if (snprintf(name, len, format, prefix, cache->fqn) >= len) { + error("snprintf failed for '%s' (length %zu)", cache->fqn, + len); + free(name); + return NULL; + } + + return name; +} + +static int __type_expand(struct die *cache, struct type_expansion *type, + bool recursive); + +static int type_expand_child(struct die *cache, struct type_expansion *type, + bool recursive) +{ + struct type_expansion child; + char *name; + + name = get_type_name(cache); + if (!name) + return check(__type_expand(cache, type, recursive)); + + if (recursive && !__cache_was_expanded(&expansion_cache, cache->addr)) { + check(__cache_mark_expanded(&expansion_cache, cache->addr)); + check(type_expansion_init(&child, true)); + check(__type_expand(cache, &child, true)); + check(type_map_add(name, &child)); + type_expansion_free(&child); + } + + check(type_expansion_append(type, name, name)); + return 0; +} + +static int __type_expand(struct die *cache, struct type_expansion *type, + bool recursive) +{ + struct die_fragment *df = cache->list; + struct die *child; + + while (df) { + switch (df->type) { + case STRING: + check(type_expansion_append(type, df->data.str, NULL)); + break; + case DIE: + /* Use a complete die_map expansion if available */ + if (__die_map_get(df->data.addr, COMPLETE, &child) && + __die_map_get(df->data.addr, UNEXPANDED, &child)) { + error("unknown child: %" PRIxPTR, + df->data.addr); + return -1; + } + + check(type_expand_child(child, type, recursive)); + break; + case LINEBREAK: + /* + * Keep whitespace in the symtypes format, but avoid + * repeated spaces. + */ + if (!df->next || df->next->type != LINEBREAK) + check(type_expansion_append(type, " ", NULL)); + break; + default: + error("empty die_fragment in %p", cache); + return -1; + } + + df = df->next; + } + + return 0; +} + +static int type_expand(struct die *cache, struct type_expansion *type, + bool recursive) +{ + check(type_expansion_init(type, true)); + check(__type_expand(cache, type, recursive)); + cache_clear_expanded(&expansion_cache); + return 0; +} + +static int expand_type(struct die *cache, void *arg) +{ + struct type_expansion type; + char *name; + + /* + * Skip unexpanded die_map entries if there's a complete + * expansion available for this DIE. + */ + if (cache->state == UNEXPANDED) + __die_map_get(cache->addr, COMPLETE, &cache); + + if (cache->mapped) + return 0; + + cache->mapped = true; + + name = get_type_name(cache); + if (!name) + return 0; + + debug("%s", name); + check(type_expand(cache, &type, true)); + check(type_map_add(name, &type)); + + type_expansion_free(&type); + free(name); + + return 0; +} + +int generate_symtypes(FILE *file) +{ + hash_init(expansion_cache.cache); + + /* + * die_map processing: + * + * 1. die_map contains all types referenced in exported symbol + * signatures, but can contain duplicates just like the original + * DWARF, and some references may not be fully expanded depending + * on how far we processed the DIE tree for that specific symbol. + * + * For each die_map entry, find the longest available expansion, + * and add it to type_map. + */ + check(die_map_for_each(expand_type, NULL)); + + /* + * 2. If a symtypes file is requested, write type_map contents to + * the file. + */ + check(type_map_write(file)); + type_map_free(); + + return 0; +} From patchwork Thu Aug 15 17:39:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765029 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 551B81BE236 for ; Thu, 15 Aug 2024 17:39:39 +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=1723743581; cv=none; b=ewSFhuvEWVcguhSeCZh3EhLUyk0EQQK0UOViohaM8TjFpT72pSAQeqYpGqJ/jkB7G66X3SqYYneELpZqc26xkek6X1r4H7TVsyZZeRXLCCSO8aqSq/c9Tmtx8/06z3Vc/fnz9CBiGkwcMLCPz2+6tR/XhTMzHSW2/TU1J3s6cm8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743581; c=relaxed/simple; bh=b0pFv5khycwPrpj+Sp91w4FE2mSAFUzDjAXnCfWTad8=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=mdTdS0KN7VO+kSJuruYVb5wQtqeYCvv3CKJBwsQTSdDcDi2Rwwz+IK+5zUKSKQsNHiSUmT2Lh6MZTyFAexaa2XhXUJcMryvRh5TTwgV+5weaq7kXSwb3ef0168+f/ieGCWvWh8GJWMPRFB/GS5gsDuECXyTn0P71ZIpp8ukMDZ0= 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=2WDURSWZ; 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="2WDURSWZ" Received: by mail-pl1-f202.google.com with SMTP id d9443c01a7336-1fc6db23c74so11075725ad.0 for ; Thu, 15 Aug 2024 10:39:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743579; x=1724348379; 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=YxqJQnTjz3Mvxi0XpqIt/w4r1X6ESLhfJAqdHv9SK3k=; b=2WDURSWZGnV8NNHidNd/E1hD8BRHqKjyN1xojqZFGbfU412VdvnxhS8YxGur3INVOT N0pRjXrnlsQsvLSwlM1LT495RtE2D4LF+9QSHL9vOWNCazSLaOfq4n+tlSiZf0h+qjA2 f+Lf+8Ds5XaOQ4GiaL+ZBx1M9T2vhU5C68GzHF+SQQKhngZMPJ8uM5/k8tM8YQcXsQYy dafAGjWmJS691OyQk+8ygU3xGNX2jmm2kdBSQzDI6GMzL8DiozvBh5R/5kMqZLj6zmk0 2CdvXdkRzq5P7Pfl1I6aEv+3YEFdTUbuAdEyc13oukoGrhjOr/zGyzBvbtydORswDY8w WO4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743579; x=1724348379; 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=YxqJQnTjz3Mvxi0XpqIt/w4r1X6ESLhfJAqdHv9SK3k=; b=TnLm7DlmL9KxdjwgC8vTGFTWQTUvGDsFAUcQHY3FIeB8eez8JqsjQze86XQFx3LviY fp/rQ8jtVvlbAT86T7ZOlCZu2biFHxTbgwdJhxXoafqW8uBcolJ+l4qSgRwg4d0It6XM Xy92HZ5BnAikBi3DoVcAx0UQIALPT3aeWa/yP9krIdHxIuWsJ+02jb96LajRAKRXHb2U 5b0vvE8e3Y8KtQyLYHXhjOknGPfdYwDNOAGX2TduwWewp4THQ9gyj0Zu7j1Fg4UhvyVF eNXAQ8X6sXHziJpccmYEBO4DfaRsdE/2XiZU5LptKSQKTihwytHPheAsTTkE+KHf2Eet AGMw== X-Forwarded-Encrypted: i=1; AJvYcCUcNMPBNOMTQb6ENLdPP3Ytm0L1QVDj5tGaEwhlcx50ukl4xFJiWRNq5ZpN4wRrOyTwLeQN+7k4UM0swIU5Y6xYD5RuD/VO051G5Exw6Q== X-Gm-Message-State: AOJu0Ywz4OrqnIzZoZmWRBABxOZ+abJ2KW6vYZtf+YnO+TseeE5MljB8 jBXH6sjy9jfrWJkTm1998ff8jxEv032unwS+1Hv0qX9F5i9L4biLrXqRs0at3uLIaqFVP8+k0BO rKhnpvM7DuJdirACCOyJW9rZ3NQ== X-Google-Smtp-Source: AGHT+IGF3I1u9mSx+8xCf1DA450XBvZOmSvJwKdoxJ1GRnRyz1OEjqQVcI5TNj2KVF0Ba1LZT+LRkrCRzG1G2A961vk= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a17:902:ce91:b0:1fb:57e7:5bbf with SMTP id d9443c01a7336-20203f35821mr339605ad.11.1723743578505; Thu, 15 Aug 2024 10:39:38 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:18 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=19079; i=samitolvanen@google.com; h=from:subject; bh=b0pFv5khycwPrpj+Sp91w4FE2mSAFUzDjAXnCfWTad8=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj05IDIGHnL6HkFJ0lHzVWy/qfqDTrqWKCAAn wzncuwsoq+JAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OQAKCRBMtfaEi7xW 7nU3C/48GVfofDpfkjx+EcecVtIoLr+wvOn5J9Ks6YegliWjbSfiI+WXC8XKL7rZoeyIbN1ZhTc kC/dRkyFXKtg4iyAEjeuN9ZQ6zdvh8UgVPo2A+Bn0a6bmgyBZNvpRLZi9i8w5yCHOT3jgb8as/W vQmLP01/vBvaGaiq2fR+ZW0TNRoNGdggWojQzDp3FiLm7pd6twAL2sc9PxsgI0WdbwSj1AlKFzw phDtvlhG+Ot928zpCuT2hKJH12/KIRf/TwIsIDBE81NZSy5Z3ki7a4o42e5zB1s15TbsPTy9ZDp HsbdP06W5AAz8UJsSftWcQDjLkKB5oOtYsmMBGuOLhu4paULacgvv1sW7pGUVeb6zMrg8cgoQHW ShLfv4R0Vws8j7Q3zxaRXU3hYfrktMDy3i1KZOk1UTnF6hm+bEXCA+lLyktt+Pt0oJOBME+K3eD kOv9irZT9n9lDhsht9OW/n5AJ/23VK5sdue06S8I9IOwIatjOo7o+f/fmmh4s+yWjoFXs= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-35-samitolvanen@google.com> Subject: [PATCH v2 14/19] gendwarfksyms: Add symbol versioning From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , 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 symtypes strings in type_map. Signed-off-by: Sami Tolvanen --- scripts/gendwarfksyms/Makefile | 1 + scripts/gendwarfksyms/crc32.c | 69 ++++++++++++++ scripts/gendwarfksyms/crc32.h | 34 +++++++ scripts/gendwarfksyms/dwarf.c | 47 ++++++++-- scripts/gendwarfksyms/gendwarfksyms.c | 10 ++- scripts/gendwarfksyms/gendwarfksyms.h | 15 +++- scripts/gendwarfksyms/symbols.c | 65 ++++++++++++++ scripts/gendwarfksyms/types.c | 124 +++++++++++++++++++++++++- 8 files changed, 348 insertions(+), 17 deletions(-) create mode 100644 scripts/gendwarfksyms/crc32.c create mode 100644 scripts/gendwarfksyms/crc32.h diff --git a/scripts/gendwarfksyms/Makefile b/scripts/gendwarfksyms/Makefile index 4866a2fd0e46..2043601df736 100644 --- a/scripts/gendwarfksyms/Makefile +++ b/scripts/gendwarfksyms/Makefile @@ -2,6 +2,7 @@ hostprogs-always-y += gendwarfksyms gendwarfksyms-objs += gendwarfksyms.o gendwarfksyms-objs += cache.o +gendwarfksyms-objs += crc32.o gendwarfksyms-objs += die.o gendwarfksyms-objs += dwarf.o gendwarfksyms-objs += symbols.o diff --git a/scripts/gendwarfksyms/crc32.c b/scripts/gendwarfksyms/crc32.c new file mode 100644 index 000000000000..23b328cd74f2 --- /dev/null +++ b/scripts/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/scripts/gendwarfksyms/crc32.h b/scripts/gendwarfksyms/crc32.h new file mode 100644 index 000000000000..89e4454b2a70 --- /dev/null +++ b/scripts/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/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index 62241cc97a76..677190ae18ef 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -693,18 +693,51 @@ static int process_type(struct state *state, struct die *parent, Dwarf_Die *die) /* * Exported symbol processing */ +static int get_symbol_cache(struct state *state, Dwarf_Die *die, + struct die **cache) +{ + checkp(symbol_set_die(state->sym, die)); + check(die_map_get(die, SYMBOL, cache)); + + if ((*cache)->state != INCOMPLETE) + return 1; /* We already processed a symbol for this DIE */ + + (*cache)->tag = dwarf_tag(die); + return 0; +} + static int process_subprogram(struct state *state, Dwarf_Die *die) { - check(__process_subroutine_type(state, NULL, die, "subprogram")); - state->sym->state = MAPPED; + struct die *cache; + + if (checkp(get_symbol_cache(state, die, &cache)) > 0) + return 0; + + debug("%s", state->sym->name); + check(__process_subroutine_type(state, cache, die, "subprogram")); + cache->state = SYMBOL; + + if (dump_dies) + fputs("\n", stderr); + return 0; } static int process_variable(struct state *state, Dwarf_Die *die) { - check(process(state, NULL, "variable ")); - check(process_type_attr(state, NULL, die)); - state->sym->state = MAPPED; + struct die *cache; + + if (checkp(get_symbol_cache(state, die, &cache)) > 0) + return 0; + + debug("%s", state->sym->name); + check(process(state, cache, "variable ")); + check(process_type_attr(state, cache, die)); + cache->state = SYMBOL; + + if (dump_dies) + fputs("\n", stderr); + return 0; } @@ -750,7 +783,6 @@ static int process_exported_symbols(struct state *state, struct die *cache, if (!is_export_symbol(state, die)) return 0; - debug("%s", state->sym->name); state_init(state); if (is_symbol_ptr(get_name(&state->die))) @@ -760,9 +792,6 @@ static int process_exported_symbols(struct state *state, struct die *cache, else check(process_variable(state, &state->die)); - if (dump_dies) - fputs("\n", stderr); - cache_clear_expanded(&state->expansion_cache); return 0; default: diff --git a/scripts/gendwarfksyms/gendwarfksyms.c b/scripts/gendwarfksyms/gendwarfksyms.c index 6a219a54c342..4a160d19d7df 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.c +++ b/scripts/gendwarfksyms/gendwarfksyms.c @@ -22,6 +22,8 @@ bool dump_dies; bool dump_die_map; /* Print out type_map contents */ bool dump_types; +/* Print out expanded type strings used for version calculations */ +bool dump_versions; /* Produce a symtypes file */ bool symtypes; static const char *symtypes_file; @@ -35,6 +37,7 @@ static const struct { { "--dump-dies", &dump_dies, NULL }, { "--dump-die-map", &dump_die_map, NULL }, { "--dump-types", &dump_types, NULL }, + { "--dump-versions", &dump_versions, NULL }, { "--symtypes", &symtypes, &symtypes_file }, }; @@ -109,9 +112,10 @@ static int process_modules(Dwfl_Module *mod, void **userdata, const char *name, } while (cu); /* - * Use die_map to expand type strings and write them to `symfile`. + * Use die_map to expand type strings, write them to `symfile`, and + * calculate symbol versions. */ - check(generate_symtypes(symfile)); + check(generate_symtypes_and_versions(symfile)); die_map_free(); return DWARF_CB_OK; @@ -187,5 +191,7 @@ int main(int argc, const char **argv) if (symfile) fclose(symfile); + symbol_print_versions(); + return 0; } diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index 6edbd6478e0f..f85e080a8634 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -23,6 +23,7 @@ extern bool debug; extern bool dump_dies; extern bool dump_die_map; extern bool dump_types; +extern bool dump_versions; extern bool symtypes; #define MAX_INPUT_FILES 128 @@ -95,7 +96,7 @@ extern bool symtypes; #define SYMBOL_DECLONLY_PREFIX "__gendwarfksyms_declonly_" #define SYMBOL_DECLONLY_PREFIX_LEN (sizeof(SYMBOL_DECLONLY_PREFIX) - 1) -enum symbol_state { UNPROCESSED, MAPPED }; +enum symbol_state { UNPROCESSED, MAPPED, PROCESSED }; struct symbol_addr { uint32_t section; @@ -119,18 +120,25 @@ struct symbol { struct hlist_node name_hash; enum symbol_state state; uintptr_t die_addr; + unsigned long crc; }; +typedef int (*symbol_callback_t)(struct symbol *, void *arg); + extern bool is_symbol_ptr(const char *name); extern int symbol_read_exports(FILE *file); extern int symbol_read_symtab(int fd); extern struct symbol *symbol_get_unprocessed(const char *name); +extern int symbol_set_die(struct symbol *sym, Dwarf_Die *die); +extern int symbol_set_crc(struct symbol *sym, unsigned long crc); +extern int symbol_for_each(symbol_callback_t func, void *arg); +extern void symbol_print_versions(void); /* * die.c */ -enum die_state { INCOMPLETE, UNEXPANDED, COMPLETE, LAST = COMPLETE }; +enum die_state { INCOMPLETE, UNEXPANDED, COMPLETE, SYMBOL, LAST = SYMBOL }; enum die_fragment_type { EMPTY, STRING, LINEBREAK, DIE }; struct die_fragment { @@ -154,6 +162,7 @@ static inline const char *die_state_name(enum die_state state) CASE_CONST_TO_STR(INCOMPLETE) CASE_CONST_TO_STR(UNEXPANDED) CASE_CONST_TO_STR(COMPLETE) + CASE_CONST_TO_STR(SYMBOL) } } @@ -239,6 +248,6 @@ extern int process_module(Dwfl_Module *mod, Dwarf *dbg, Dwarf_Die *cudie); * types.c */ -extern int generate_symtypes(FILE *file); +extern int generate_symtypes_and_versions(FILE *file); #endif /* __GENDWARFKSYMS_H */ diff --git a/scripts/gendwarfksyms/symbols.c b/scripts/gendwarfksyms/symbols.c index 8cc04e6295a7..c9889cfa89c4 100644 --- a/scripts/gendwarfksyms/symbols.c +++ b/scripts/gendwarfksyms/symbols.c @@ -84,6 +84,38 @@ static int for_each(const char *name, bool name_only, symbol_callback_t func, return 0; } +static int set_crc(struct symbol *sym, void *data) +{ + unsigned long *crc = data; + + if (sym->state == PROCESSED && sym->crc != *crc) + warn("overriding version for symbol %s (crc %lx vs. %lx)", + sym->name, sym->crc, *crc); + + sym->state = PROCESSED; + sym->crc = *crc; + return 0; +} + +int symbol_set_crc(struct symbol *sym, unsigned long crc) +{ + if (checkp(for_each(sym->name, false, set_crc, &crc)) > 0) + return 0; + return -1; +} + +static int set_die(struct symbol *sym, void *data) +{ + sym->die_addr = (uintptr_t)((Dwarf_Die *)data)->addr; + sym->state = MAPPED; + return 0; +} + +int symbol_set_die(struct symbol *sym, Dwarf_Die *die) +{ + return checkp(for_each(sym->name, false, set_die, die)); +} + static bool is_exported(const char *name) { return checkp(for_each(name, true, NULL, NULL)) > 0; @@ -151,6 +183,19 @@ struct symbol *symbol_get_unprocessed(const char *name) return sym; } +int symbol_for_each(symbol_callback_t func, void *arg) +{ + struct hlist_node *tmp; + struct symbol *sym; + int i; + + hash_for_each_safe(symbol_names, i, tmp, sym, name_hash) { + check(func(sym, arg)); + } + + return 0; +} + typedef int (*elf_symbol_callback_t)(const char *name, GElf_Sym *sym, Elf32_Word xndx, void *arg); @@ -264,3 +309,23 @@ int symbol_read_symtab(int fd) { return elf_for_each_symbol(fd, process_symbol, NULL); } + +void symbol_print_versions(void) +{ + struct hlist_node *tmp; + struct symbol *sym; + int i; + + hash_for_each_safe(symbol_names, i, tmp, sym, name_hash) { + if (sym->state != PROCESSED) + warn("no information for symbol %s", sym->name); + + 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/scripts/gendwarfksyms/types.c b/scripts/gendwarfksyms/types.c index 7b9997d8322d..6411b1279a28 100644 --- a/scripts/gendwarfksyms/types.c +++ b/scripts/gendwarfksyms/types.c @@ -228,6 +228,34 @@ static void type_map_free(void) hash_init(type_map); } +/* + * CRC for a type, with an optional fully expanded type string for + * debugging. + */ +struct version { + struct type_expansion type; + unsigned long crc; +}; + +static int version_init(struct version *version) +{ + version->crc = 0xffffffff; + return check(type_expansion_init(&version->type, dump_versions)); +} + +static void version_free(struct version *version) +{ + type_expansion_free(&version->type); +} + +static int version_add(struct version *version, const char *s) +{ + version->crc = partial_crc32(s, version->crc); + if (dump_versions) + checkp(type_expansion_append(&version->type, s, NULL)); + return 0; +} + /* * Type reference format: #, where prefix: * s -> structure @@ -271,7 +299,7 @@ static char *get_type_name(struct die *cache) warn("found incomplete cache entry: %p", cache); return NULL; } - if (!cache->fqn) + if (cache->state == SYMBOL || !cache->fqn) return NULL; prefix = get_type_prefix(cache->tag); @@ -305,6 +333,45 @@ static char *get_type_name(struct die *cache) return name; } +static int __calculate_version(struct version *version, struct type_list *list) +{ + struct type_expansion *e; + + /* Calculate a CRC over an expanded type string */ + while (list) { + if (is_type_prefix(list->str)) { + check(type_map_get(list->str, &e)); + + /* + * It's sufficient to expand each type reference just + * once to detect changes. + */ + if (cache_was_expanded(&expansion_cache, e)) { + check(version_add(version, list->str)); + } else { + check(cache_mark_expanded(&expansion_cache, e)); + check(__calculate_version(version, + e->expanded)); + } + } else { + check(version_add(version, list->str)); + } + + list = list->next; + } + + return 0; +} + +static int calculate_version(struct version *version, const char *name, + struct type_list *list) +{ + check(version_init(version)); + check(__calculate_version(version, list)); + cache_clear_expanded(&expansion_cache); + return 0; +} + static int __type_expand(struct die *cache, struct type_expansion *type, bool recursive); @@ -411,7 +478,51 @@ static int expand_type(struct die *cache, void *arg) return 0; } -int generate_symtypes(FILE *file) +static int expand_symbol(struct symbol *sym, void *arg) +{ + struct type_expansion type; + struct version version; + struct die *cache; + + /* + * No need to expand again unless we want a symtypes file entry + * for the symbol. Note that this means `sym` has the same address + * as another symbol that was already processed. + */ + if (!symtypes && sym->state == PROCESSED) + return 0; + + if (__die_map_get(sym->die_addr, SYMBOL, &cache)) + return 0; /* We'll warn about missing CRCs later. */ + + check(type_expand(cache, &type, false)); + + /* If the symbol already has a version, don't calculate it again. */ + if (sym->state != PROCESSED) { + check(calculate_version(&version, sym->name, type.expanded)); + check(symbol_set_crc(sym, version.crc)); + debug("%s = %lx", sym->name, version.crc); + + if (dump_versions) { + fputs(sym->name, stderr); + fputs(" ", stderr); + type_list_write(version.type.expanded, stderr); + fputs("\n", stderr); + } + + version_free(&version); + } + + /* These aren't needed in type_map unless we want a symtypes file. */ + if (symtypes) + check(type_map_add(sym->name, &type)); + + type_expansion_free(&type); + + return 0; +} + +int generate_symtypes_and_versions(FILE *file) { hash_init(expansion_cache.cache); @@ -429,7 +540,14 @@ int generate_symtypes(FILE *file) check(die_map_for_each(expand_type, NULL)); /* - * 2. If a symtypes file is requested, write type_map contents to + * 2. For each exported symbol, expand the die_cache type, and use + * type_map expansions to calculate a symbol version from the + * fully expanded type string. + */ + check(symbol_for_each(expand_symbol, NULL)); + + /* + * 3. If a symtypes file is requested, write type_map contents to * the file. */ check(type_map_write(file)); From patchwork Thu Aug 15 17:39:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 13765030 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (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 25E6C1BE863 for ; Thu, 15 Aug 2024 17:39:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743583; cv=none; b=sVK+xaXESEezZY5U0Inv70AgR+KOvrnAVpYNaGSyoaJfRXAyTZKre7k+VPOwdsBV+YSWg6eozWxkQVm5DVjpn3pcEHde2yQ99SbLy/0mCCUsav1CYM4tbm6VpWLJS3oT/d/7tVix3U045tQHOYGEEfzPMv08tZEmUHJ+98lM+og= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743583; c=relaxed/simple; bh=MdCZyANU3cpN1KbL2Y+c7u2dfSk3DjTqLm/uKatG+wg=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=Qh3N9MvrhCMa5ClAZlv7KObBnZ24Rz7Pm0ueHOsKikrKJtsyB4UUeTWDnM1ctjI9ts/8l+K8MqgppfsenovWXYg3LUEBVO5bELm/fK2uK3JN45uVDEqECNYWMHXbdflK1XUBmUOlad0mb4vZ4+g7MVFRtkKwbXzGD8DmttWVbc8= 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=g25wtdYC; arc=none smtp.client-ip=209.85.216.74 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="g25wtdYC" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-2cb4c2276b6so1085701a91.1 for ; Thu, 15 Aug 2024 10:39:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743580; x=1724348380; 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=AM5wUjQsWxirPWho62bBzTbFDQPnvqvSrS68y5t7Rps=; b=g25wtdYCK/iMouWOVcx7e1hCQOD0bM7F76zWaDAbirFuagb9QWCFdfc/7FmqaFtIhY XLTW4nOp/MnqCms2ykWPUyS+nSydXpetPf7mwj8pHrVUEzlktqSgBZvlEsHY5wYRWWdt /gCvUzZ3Zlqe7RG/Z2oLkDfTU8C88QCd8mP4u+pgzxUVoSjigsZRMxi4+Lwygu4psTEm hgOuoohwdsPtmluIujVn1L16CFB1pbN3mX+GP+RygmC7Ci6GpJ2PUJiKp6vEWbOiahyy bH9Sk5AcTaxFQgitEZ5E+ee1nAwuKPuK0SyqCRvzh5VkFjYtk71cYIszsMtKByGQDq5m QU/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743580; x=1724348380; 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=AM5wUjQsWxirPWho62bBzTbFDQPnvqvSrS68y5t7Rps=; b=ve51zy9Uz5UHP/Ql91umbM6je72KO7MbC1JW/wWsC1LU8SqcTmC163nWav1zAWqRK0 prYtTyIzvJEreUJ0sULsfdax/nWYA3SKcmlyXYJFlztzpt3ihEIuabHlA4EqWXXJjIHX nLXvXV8cKs6XB4oN3JTbHKiLimtW+sGt/70kknbXqm34vwNPYmMVn4MmCv7aPyGoztZP CJlYsyVUKCyErjMUwzWOUDvJ5ihxUejVjHtWEOaRqQBomBTtuSE1M75OYMsrBiCIAgkr zgeyJ7RNbWnfPt8Ok6FMPk1P1pBdn8sKC0KIys48ui3dMtUObJQ4mW32eG1LgGpuqEsW 5mSA== X-Forwarded-Encrypted: i=1; AJvYcCVhPphe8YtzrEcwP7mCQCa1jaKhotl8ooMhsxUXq7NwNENARaJuhnjYYSlszBi8f9uKLR+LphkDyDMxv7I3Hzk2F59lKoZeOH3wvmCqyQ== X-Gm-Message-State: AOJu0YykpJWpxpZZcjmX8mRl0PvY1+SNdkaBoJkYp7MNzIqO+F3FPQsh DVxSHjJeq5F2PIW73ycjRcjK7jVJ/iBKucF1p4AuuhexbutpHxZfgvgoZn0MRdl+9SDfs9oHBna jyHeH9Sxgk3jLeFrIFUOWWrOOTw== X-Google-Smtp-Source: AGHT+IEa9IerFI45JnVORaoGhFuJF7bDHYfiVGOl6IiBF/KgDfLV7Sw3ufSt/NO4uLL5N9tOaKwbVaiwWR+mCH6/ASI= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a17:90b:4f86:b0:2d3:c743:1e5d with SMTP id 98e67ed59e1d1-2d3e041c0b8mr731a91.7.1723743580335; Thu, 15 Aug 2024 10:39:40 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:19 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=9841; i=samitolvanen@google.com; h=from:subject; bh=MdCZyANU3cpN1KbL2Y+c7u2dfSk3DjTqLm/uKatG+wg=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj059Pg7Q9O8Q4oa1rF1r5AuRgbl0eRJ6dE4O uywCFA1ZmSJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OQAKCRBMtfaEi7xW 7qQQDACID+wzctpfuYuBToMDEYH6MiGIl/f2n24YCbYmOVyDavrd7LRzjV//CF9n+3CGV9VuhXS kesyXvcYQKKXs11p6qVm5EuQPtfjdz8+vyLWdJMSkgj55gm+6AnFDRGjWxdu2HMuweUCayScGq/ XZ1MxNLeqivVdMKu/eBFtwl+tfkm8eJdp4us7naIn6HFSUNnIWqxvVhldGu8nzXGxaEeoFvUhFr XITZTFrFFdwJu+tYSmWDFtpwdJ89ws42Sy3Y7Gd+E1k2Pui8jsPiebDDx29/DZS9WdzSgtiXMIv rKTTFkjTLuhjt1RD3LaeGn0Lv7uMeyjiYt3v9Fv90FoXrn7+U/OQrGdrRt+iTNmP63b+cQ1qzcF VGn3xmRmpwkwj4AGdHWouTtfVjWCwJeS4HvzAOwWPnPDLvbWRPj92G6gtjRkxMlPqPgmcEQinZ5 1dMxt7RsMAUVcT4N31VZiBGv/tTaHMHWfrKE34kZIq7+qDUec82xYk+NrHzHa5MTSksuI= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-36-samitolvanen@google.com> Subject: [PATCH v2 15/19] gendwarfksyms: Add support for declaration-only data structures From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen If a source file refers to an opaque data structure, the DWARF debugging information in the resulting object file will only contain a structure declation, which means the contents of the structure are not included when computing symbol versions. For example: Source code: struct struct0; int func(struct struct0 *); gendwarfksyms --debug: subprogram( formal_parameter pointer_type { structure_type struct0 { } } byte_size(8), ) -> base_type int byte_size(4) encoding(5); #SYMVER func 0x7e8284f9 The declaration can change into a full definition when an additional include is added to the TU, which changes the version CRC, even though the ABI has not changed. If this happens during an LTS update, a distribution that wants to maintain a stable ABI needs a way to ensure symbol versions remain unchanged. With genksyms, the usual solution is to use #ifndef __GENKSYMS__ to skip the newly added header file when computing symbol versions, but that's not an option when we're processing a precompiled object file. To support this use case, add a --stable command line flag that gates kABI stability features that are not needed in mainline, but can be useful for distributions, and add support for symbol annotations that allow structures to always be treated as declarations when versions are computed. If a __gendwarfksyms_declonly_ symbol exists in the object file's symbol table, the "structname" structure is treated as a declaration only, and not expanded when computing versions. The symbol can be defined using the following macro, for example, which discards it from the final kernel binary: #define GENDWARFKSYMS_DECLONLY(structname) \ static void *__gendwarfksyms_declonly_##structname __used \ __section(".discard.gendwarfksyms") Now, if we include struct0 definition in our source code, and add a declaration-only annotation, we have: struct struct0 { int a; }; GENDWARFKSYMS_DECLONLY(struct0); int func(struct struct0 *); gendwarfksyms --debug reflects the added definition: subprogram( formal_parameter pointer_type { structure_type struct0 { member base_type int byte_size(4) encoding(5) data_member_location(0), } byte_size(4) } byte_size(8), ) -> base_type int byte_size(4) encoding(5); #SYMVER func 0xc0de983d But with --debug --stable, the definition is ignored and we again have the original symbol version: subprogram( formal_parameter pointer_type { structure_type struct0 { } } byte_size(8), ) -> base_type int byte_size(4) encoding(5); #SYMVER func 0x7e8284f9 Signed-off-by: Sami Tolvanen --- scripts/gendwarfksyms/dwarf.c | 25 +++++++++- scripts/gendwarfksyms/examples/declonly.c | 31 ++++++++++++ scripts/gendwarfksyms/gendwarfksyms.c | 4 ++ scripts/gendwarfksyms/gendwarfksyms.h | 4 ++ scripts/gendwarfksyms/symbols.c | 61 +++++++++++++++++++++++ 5 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 scripts/gendwarfksyms/examples/declonly.c diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index 677190ae18ef..bf28946c321e 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -74,7 +74,30 @@ static bool is_declaration(Dwarf_Die *die) { bool value; - return get_flag_attr(die, DW_AT_declaration, &value) && value; + /* + * If the object file has a __gendwarfksyms_declonly_ + * symbol, we treat structures named "structname" as declarations, + * i.e. they won't be expanded when calculating symbol versions. + * This helps distributions maintain a stable kABI e.g., if extra + * includes change a declaration into a definition. + * + * A simple way to mark a structure declaration-only in the source + * code is to define a discarded symbol: + * + * #define GENDWARFKSYMS_DECLONLY(structname) \ + * static void *__gendwarfksyms_declonly_##structname __used \ + * __section(".discard.gendwarfksyms") + * + * For example: + * + * struct struct0 { int a; } + * GENDWARFKSYMS_DECLONLY(struct0); + * + * Here, struct0 would be always be considered a declaration even + * though the definition is visible. + */ + return (get_flag_attr(die, DW_AT_declaration, &value) && value) || + is_struct_declonly(get_name(die)); } /* diff --git a/scripts/gendwarfksyms/examples/declonly.c b/scripts/gendwarfksyms/examples/declonly.c new file mode 100644 index 000000000000..b1b889e582da --- /dev/null +++ b/scripts/gendwarfksyms/examples/declonly.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2024 Google LLC + * + * Declaration-only data structure example. See dwarf.c:is_declaration + * for details. + * + * $ gcc -g -c examples/declonly.c + * $ echo exported | ./gendwarfksyms --dump-dies declonly.o + * variable structure_type struct0 { + * member base_type int byte_size(4) encoding(5) data_member_location(0), + * } byte_size(4) + * + * With --stable, struct0 is treated as a declaration: + * + * $ echo exported | ./gendwarfksyms --stable --dump-dies declonly.o + * variable structure_type struct0 { + * } + */ + +#define GENDWARFKSYMS_DECLONLY(structname) \ + static void *__gendwarfksyms_declonly_##structname \ + __attribute__((__used__)) \ + __attribute__((__section__(".discard.gendwarfksyms"))); + +struct struct0 { + int a; +}; + +struct struct0 exported; +GENDWARFKSYMS_DECLONLY(struct0); diff --git a/scripts/gendwarfksyms/gendwarfksyms.c b/scripts/gendwarfksyms/gendwarfksyms.c index 4a160d19d7df..10d1470383be 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.c +++ b/scripts/gendwarfksyms/gendwarfksyms.c @@ -24,6 +24,8 @@ bool dump_die_map; bool dump_types; /* Print out expanded type strings used for version calculations */ bool dump_versions; +/* Support kABI stability features */ +bool stable; /* Produce a symtypes file */ bool symtypes; static const char *symtypes_file; @@ -38,6 +40,7 @@ static const struct { { "--dump-die-map", &dump_die_map, NULL }, { "--dump-types", &dump_types, NULL }, { "--dump-versions", &dump_versions, NULL }, + { "--stable", &stable, NULL }, { "--symtypes", &symtypes, &symtypes_file }, }; @@ -186,6 +189,7 @@ int main(int argc, const char **argv) dwfl_end(dwfl); close(fd); + symbol_free_declonly(); } if (symfile) diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index f85e080a8634..05b5c01b1c2a 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -24,6 +24,7 @@ extern bool dump_dies; extern bool dump_die_map; extern bool dump_types; extern bool dump_versions; +extern bool stable; extern bool symtypes; #define MAX_INPUT_FILES 128 @@ -134,6 +135,9 @@ extern int symbol_set_crc(struct symbol *sym, unsigned long crc); extern int symbol_for_each(symbol_callback_t func, void *arg); extern void symbol_print_versions(void); +extern bool is_struct_declonly(const char *name); +extern void symbol_free_declonly(void); + /* * die.c */ diff --git a/scripts/gendwarfksyms/symbols.c b/scripts/gendwarfksyms/symbols.c index c9889cfa89c4..03ba93ef9eac 100644 --- a/scripts/gendwarfksyms/symbols.c +++ b/scripts/gendwarfksyms/symbols.c @@ -5,12 +5,20 @@ #include "gendwarfksyms.h" +struct declonly { + const char *name; + struct hlist_node hash; +}; + #define SYMBOL_HASH_BITS 15 +#define DECLONLY_HASH_BITS 10 /* struct symbol_addr -> struct symbol */ static DEFINE_HASHTABLE(symbol_addrs, SYMBOL_HASH_BITS); /* name -> struct symbol */ static DEFINE_HASHTABLE(symbol_names, SYMBOL_HASH_BITS); +/* name -> struct declonly */ +static DEFINE_HASHTABLE(declonly_structs, DECLONLY_HASH_BITS); static inline u32 symbol_addr_hash(const struct symbol_addr *addr) { @@ -296,12 +304,36 @@ static int process_symbol(const char *name, GElf_Sym *sym, Elf32_Word xndx, void *arg) { struct symbol_addr addr = { .section = xndx, .address = sym->st_value }; + struct declonly *d; /* Set addresses for exported symbols */ if (GELF_ST_BIND(sym->st_info) != STB_LOCAL && addr.section != SHN_UNDEF) checkp(for_each(name, true, set_symbol_addr, &addr)); + if (!stable) + return 0; + + /* Process declonly structs */ + if (strncmp(name, SYMBOL_DECLONLY_PREFIX, SYMBOL_DECLONLY_PREFIX_LEN)) + return 0; + + d = malloc(sizeof(struct declonly)); + if (!d) { + error("malloc failed"); + return -1; + } + + name += SYMBOL_DECLONLY_PREFIX_LEN; + d->name = strdup(name); + if (!d->name) { + error("strdup failed"); + return -1; + } + + hash_add(declonly_structs, &d->hash, name_hash(d->name)); + debug("declaration-only: %s", d->name); + return 0; } @@ -310,6 +342,35 @@ int symbol_read_symtab(int fd) return elf_for_each_symbol(fd, process_symbol, NULL); } +bool is_struct_declonly(const char *name) +{ + struct declonly *d; + + if (!stable || !name) + return false; + + hash_for_each_possible(declonly_structs, d, hash, name_hash(name)) { + if (!strcmp(name, d->name)) + return true; + } + + return false; +} + +void symbol_free_declonly(void) +{ + struct hlist_node *tmp; + struct declonly *d; + int i; + + hash_for_each_safe(declonly_structs, i, tmp, d, hash) { + free((void *)d->name); + free(d); + } + + hash_init(declonly_structs); +} + void symbol_print_versions(void) { struct hlist_node *tmp; From patchwork Thu Aug 15 17:39: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: 13765031 Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.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 573901BE860 for ; Thu, 15 Aug 2024 17:39:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743585; cv=none; b=kKU5EFWpB26T+XN7q/yTKVBEAHCO7nRtCVXr0W0cFZdlEhGgO7yCy4lby+eB6xWtPiTGH35xVE/44hAxUOnZepUfItdKtAndbECzeoENi4VZMupZC6rhdjlNuCWBpe3lYzF7yMyO59Mr4c9AmGI1nTgaWmZ1hiJNHzZ4vSyQoRs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743585; c=relaxed/simple; bh=6usSpOjyoB85v1SyjtEau1KushdvZAC0dNnzubRF5CM=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=G2oz/RNtBUhZpGPQq7bIm7OidSfW+XnssJESMT20dcNf8B55E4xHzHIA59m37V2V4z3egcnZsxGjEkL4KLy+88Vgsd5zzuZgTZTeN6pcf1I8fgQv3+WDH8byyA/R0OrxZXJdhMr1iuCorLlh7kPtOzvzC4/Jys+4GUySBLu4oWU= 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=jO236v+7; arc=none smtp.client-ip=209.85.128.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="jO236v+7" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-6886cd07673so20930677b3.3 for ; Thu, 15 Aug 2024 10:39:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743582; x=1724348382; 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=2sPCSdATuewk8L2vh2ELF65Db7EveWl5UV4XCGQQVag=; b=jO236v+7UYB3Gp+aCNM29b3TpE4gidBBH3dSFfKxespEXI18DasXqFlUe5j3cJSgLn nCNM4xZm9D6VmU3pja6jIglkRNAQDgseFpgHWgXPK9of/TvX2hmMfEixuc4bcxBvWw2R 3d4jgcyjyZBgaUQ3w7y7EivtNUuzurIL9s2uAJux9vHy9lOG5GNXck1URya4yfVtooIb 96ZC3XCr86EhpzCuS9ujjzicSsszrPxjzzzJPkOc+fQG4IhY5NdDyCW0rDLR445KNwzV f7ITApuAL8tXX4YDxAFPYu8zEcLR6iYkyG3hTPXGTU8bmLDhGteu1Nt/ukQw75yVC1DD N7Kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743582; x=1724348382; 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=2sPCSdATuewk8L2vh2ELF65Db7EveWl5UV4XCGQQVag=; b=SGia8Ezat4HyHeHSJTJsZVKhad2WI0u7lAotMr0Lf2a6mdQzSF2apdRaIgx+szX/wm RpKQfidOP6wl6vGUna3uqtbkG7aaO1DG3dQTYhpgAsEoqiWs2rJAvCsK6kwbjwEZRpIB qs+f64YD/gXGpozPJ/MjKWQspUrGJVQNCozE6lrz09TMsHl9B0COLjN5p3mVLTG4ky6L kXzORBjq99HVKeTGkob4MXZTBZ6Mi+RREV75cIOtbWoUtB/l5QvmeihHC0xxZBgjjbzz z4bjtACMsjq6GNu1FbjYAvGqa5+j7Z2rCfW3JB9BBTKnusMSpFtxBGHfUh291uIb9wLC u/Rw== X-Forwarded-Encrypted: i=1; AJvYcCWNR6poBmiXH3JgQqmpFFX2CkXfiULCSGFGtcwQyB7fZzcctuf+E1ZmzMEY4YqHjpzvpOodJB7phBRHI8SsxOR4VWNR2ZMAQsqyrSk6Ag== X-Gm-Message-State: AOJu0Yzc9ki9/8CY9DsS+hfkjFgT29zI3X1kSvjAJt7HBmQcXKk1CaWk OfWDFBJZpRbQhfPwjpLkt24nWYrW646LVaEgZ6sLEmS0Y0F37W/632hHl1VaqVcNOOOaAaH/PCv dR/yBPo8AOjoOCUbKkmSVTH+arA== X-Google-Smtp-Source: AGHT+IGwomnqFK9vxpKveGL73310JYatfAzfvmWx1tXBSFjJAlloAq4/X3L67g58vXf4su4on0aLpKym7vCztU318gc= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a25:b206:0:b0:e11:7039:ff92 with SMTP id 3f1490d57ef6-e1180f85427mr578276.11.1723743582318; Thu, 15 Aug 2024 10:39:42 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:20 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=10779; i=samitolvanen@google.com; h=from:subject; bh=6usSpOjyoB85v1SyjtEau1KushdvZAC0dNnzubRF5CM=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj05/oGe5klinNb5fzf3qC/b17XaP5+AUar/1 rfb+HhZKKSJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OQAKCRBMtfaEi7xW 7knjC/9Rj2rfRBLkbJQwNXdd+nLnKm+A7ijeY86ZAot9zhxhsC+79B78LgVqGAM763CtUyRBomL HoVlsjF+VA8PgDH2FYjBG7AneizoXz+8X3I6nutdyvpcjvCjdvLGdWM/sg5WMSMRh1GC1tlfSFd jzNdwm0xuaBDj/KRkaAag8d2mf8vWUH6H3wrKfPLb+pJrFh+N0jLSun+8aWCvueKV18lNC7E+RA QkMEDucNM1meSnviUaK9lTKvvJ4Js5cEwv1uwR561At+8NNGMowtw7Owh0Mwi7DeEvHOgTos08P 84Nju5yb8MVr4ibghgyWlHay6Cxn9fWsKsYomxZ4yoO9AFM21g4/BbNTa2q1aF1p2sxvIor1+IM QVk0eXSaJ4ucxSXxMpFYik77snFO1eFSx6Bp0+ipixkC3/HR7aMRWZfe/X+M0QQkTukH72nwFPG JWo674hXsfpS95FMkR8Io242ryKuayIhchn/NpPgF4PtEI8OaDI/0trSYUe5vLA87aoL4= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-37-samitolvanen@google.com> Subject: [PATCH v2 16/19] gendwarfksyms: Add support for reserved structure fields From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen Distributions that want to maintain a stable kABI need the ability to add reserved fields to kernel data structures that they anticipate will be modified during the ABI support timeframe, either by LTS updates or backports. With genksyms, developers would typically hide changes to the reserved fields from version calculation with #ifndef __GENKSYMS__, which would result in the symbol version not changing even though the actual type of the reserved field changes. When we process precompiled object files, this is again not an option. To support stable symbol versions for reserved fields, change the union type processing to recognize field name prefixes, and if the union contains a field name that starts with __kabi_reserved, only use the type of that field for computing symbol versions. In other words, let's assume we have a structure where we want to reserve space for future changes: struct struct1 { long a; long __kabi_reserved_0; /* reserved for future use */ }; struct struct1 exported; gendwarfksyms --debug produces the following output: variable structure_type struct1 { member base_type long int byte_size(8) encoding(5) data_member_location(0), member base_type long int byte_size(8) encoding(5) data_member_location(8), } byte_size(16); #SYMVER exported 0x67997f89 To take the reserved field into use, a distribution would replace it with a union, with one of the fields keeping the __kabi_reserved name prefix for the original type: struct struct1 { long a; union { long __kabi_reserved_0; struct { int b; int v; }; }; gendwarfksyms --debug now produces the following output: variable structure_type struct1 { member base_type long int byte_size(8) encoding(5) data_member_location(0), member union_type { member base_type long int byte_size(8) encoding(5), member structure_type { member base_type int byte_size(4) encoding(5) data_member_location(0), member base_type int byte_size(4) encoding(5) data_member_location(4), } byte_size(8), } byte_size(8) data_member_location(8), } byte_size(16); #SYMVER exported 0x66916c41 But with --stable, gendwarfksyms only uses the reserved field for the version calculation, thus leaving the symbol version unchanged: variable structure_type struct1 { member base_type long int byte_size(8) encoding(5) data_member_location(0), member base_type long int byte_size(8) encoding(5) data_member_location(8), } byte_size(16); #SYMVER exported 0x67997f89 Signed-off-by: Sami Tolvanen --- scripts/gendwarfksyms/dwarf.c | 148 +++++++++++++++++++++- scripts/gendwarfksyms/examples/reserved.c | 66 ++++++++++ scripts/gendwarfksyms/gendwarfksyms.h | 18 +++ 3 files changed, 229 insertions(+), 3 deletions(-) create mode 100644 scripts/gendwarfksyms/examples/reserved.c diff --git a/scripts/gendwarfksyms/dwarf.c b/scripts/gendwarfksyms/dwarf.c index bf28946c321e..d6252194692d 100644 --- a/scripts/gendwarfksyms/dwarf.c +++ b/scripts/gendwarfksyms/dwarf.c @@ -274,8 +274,12 @@ int process_die_container(struct state *state, struct die *cache, res = checkp(dwarf_child(die, ¤t)); while (!res) { - if (match(¤t)) - check(func(state, cache, ¤t)); + if (match(¤t)) { + /* <0 = error, 0 = continue, >0 = stop */ + res = checkp(func(state, cache, ¤t)); + if (res) + return res; + } res = checkp(dwarf_siblingof(¤t, ¤t)); } @@ -490,7 +494,145 @@ static int __process_structure_type(struct state *state, struct die *cache, DEFINE_PROCESS_STRUCTURE_TYPE(class) DEFINE_PROCESS_STRUCTURE_TYPE(structure) -DEFINE_PROCESS_STRUCTURE_TYPE(union) + +static bool is_reserved_member(Dwarf_Die *die) +{ + const char *name = get_name(die); + + return name && !strncmp(name, RESERVED_PREFIX, RESERVED_PREFIX_LEN); +} + +static int __process_reserved_struct(struct state *state, struct die *cache, + Dwarf_Die *die) +{ + Dwarf_Die type; + + /* + * If the union member is a struct, expect the placeholder type to + * be the first member, i.e.: + * + * union { + * type replaced_member; + * struct { + * type placeholder; // <- type + * } + * }; + * + * Stop processing if this member isn't reserved. + */ + if (!is_reserved_member(die)) + return NOT_RESERVED; + + if (!get_ref_die_attr(die, DW_AT_type, &type)) { + error("structure member missing a type?"); + return -1; + } + + check(process_type(state, cache, &type)); + return RESERVED; +} + +static int __process_reserved_union(struct state *state, struct die *cache, + Dwarf_Die *die) +{ + int res = NOT_RESERVED; + Dwarf_Die type; + + if (!get_ref_die_attr(die, DW_AT_type, &type)) { + error("union member missing a type?"); + return -1; + } + + /* + * We expect a union with two members. Check if either of them + * has the reserved name prefix, i.e.: + * + * union { + * ... + * type memberN; // <- type, N = {0,1} + * ... + * }; + * + * The member can also be a structure type, in which case we'll + * check the first structure member. + * + * Stop processing after we've seen two members. + */ + if (is_reserved_member(die)) { + check(process_type(state, cache, &type)); + return RESERVED; + } + + if (dwarf_tag(&type) == DW_TAG_structure_type) + res = checkp(process_die_container(state, cache, &type, + __process_reserved_struct, + match_member_type)); + if (res != RESERVED && ++state->reserved.members < 2) + return 0; /* Continue */ + + return res; +} + +static int process_reserved(struct state *state, struct die *cache, + Dwarf_Die *die) +{ + if (!stable) + return NOT_RESERVED; + + /* + * To maintain a stable kABI, distributions may choose to reserve + * space in structs for later use by adding placeholder members, + * for example: + * + * struct s { + * u64 a; + * // placeholder + * u64 __kabi_reserved_0; + * }; + * + * When the reserved member is taken into use, the type change + * would normally cause the symbol version to change as well, but + * if the replacement uses the following convention, gendwarfksyms + * continues to use the placeholder type for versioning instead, + * thus maintaining the same symbol version: + * + * struct s { + * u64 a; + * union { + * // replaced member + * struct t b; + * struct { + * // original placeholder + * u64 __kabi_reserved_0; + * }; + * }; + * }; + * + * I.e., as long as the replaced member is in a union, and the + * placeholder has a __kabi_reserved name prefix, we'll continue + * to use the placeholder type (here u64) for version calculation + * instead of the union type. + * + * Note that the user is responsible for ensuring that the + * replacement type is ABI compatible with the placeholder type. + */ + state->reserved.members = 0; + + return checkp(process_die_container(state, cache, die, + __process_reserved_union, + match_member_type)); +} + +static int process_union_type(struct state *state, struct die *cache, + Dwarf_Die *die) +{ + if (checkp(process_reserved(state, cache, die)) == RESERVED) + return 0; + + return check(__process_structure_type(state, cache, die, "union_type ", + ___process_structure_type, + match_all)); +} static int process_enumerator_type(struct state *state, struct die *cache, Dwarf_Die *die) diff --git a/scripts/gendwarfksyms/examples/reserved.c b/scripts/gendwarfksyms/examples/reserved.c new file mode 100644 index 000000000000..1e8de7ccd7d2 --- /dev/null +++ b/scripts/gendwarfksyms/examples/reserved.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2024 Google LLC + * + * Reserved data structure field example. See dwarf.c:process_reserved + * for details. + * + * $ gcc -g -c examples/reserved.c + * + * With --stable, only the reserved field placeholder is used for calculating + * symbol versions. + * + * $ echo exported0 | ./gendwarfksyms --stable --dump-dies reserved.o + * variable structure_type struct0 { + * member base_type int byte_size(4) encoding(5) data_member_location(0), + * member base_type long int byte_size(8) encoding(5) data_member_location(8), + * } byte_size(16) + * + * $ echo exported1 | ./gendwarfksyms --stable --dump-dies reserved.o + * variable structure_type struct1 { + * member base_type int byte_size(4) encoding(5) data_member_location(0), + * member base_type long int byte_size(8) encoding(5) data_member_location(8), + * } byte_size(16) + * + * $ echo exported2 | ./gendwarfksyms --stable --dump-dies reserved.o + * variable structure_type struct2 { + * member base_type int byte_size(4) encoding(5) data_member_location(0), + * member base_type long int byte_size(8) encoding(5) data_member_location(8), + * } byte_size(16) + */ + +struct struct0 { + int a; + union { + long __kabi_reserved_0; + struct { + int b; + int c; + }; + }; +}; + +struct struct1 { + int a; + union { + struct { + int b; + int c; + }; + long __kabi_reserved_1; + }; +}; + +struct struct2 { + int a; + union { + unsigned long b; + struct { + long __kabi_reserved_1; + }; + }; +}; + +struct struct0 exported0; +struct struct1 exported1; +struct struct2 exported2; diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h index 05b5c01b1c2a..963a07167892 100644 --- a/scripts/gendwarfksyms/gendwarfksyms.h +++ b/scripts/gendwarfksyms/gendwarfksyms.h @@ -220,12 +220,27 @@ extern void cache_clear_expanded(struct expansion_cache *ec); /* * dwarf.c */ + +/* See dwarf.c:process_reserved */ +#define RESERVED_PREFIX "__kabi_reserved" +#define RESERVED_PREFIX_LEN (sizeof(RESERVED_PREFIX) - 1) + struct expansion_state { bool expand; bool in_pointer_type; unsigned int ptr_expansion_depth; }; +enum reserved_status { + /* >0 to stop DIE processing */ + NOT_RESERVED = 1, + RESERVED +}; + +struct reserved_state { + int members; +}; + struct state { Dwfl_Module *mod; Dwarf *dbg; @@ -235,6 +250,9 @@ struct state { /* Structure expansion */ struct expansion_state expand; struct expansion_cache expansion_cache; + + /* Reserved members */ + struct reserved_state reserved; }; typedef int (*die_callback_t)(struct state *state, struct die *cache, From patchwork Thu Aug 15 17:39: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: 13765032 Received: from mail-yw1-f202.google.com (mail-yw1-f202.google.com [209.85.128.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 BD9B76BFC7 for ; Thu, 15 Aug 2024 17:39:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.202 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743586; cv=none; b=bothdZg9mfnqtqbzvGTazJ8VN/zFnYZ0zcpPU/Onhrh7BcnEqFQ2qLcxpuNP7WJ1pPX82sDjkBsbAQ1ZtYD9ObK2E+T/fRYg5OwTVs7hxYJ/Iogd3c+093e3oOu0fwNOTOmRzk39Ou1SYhe+HVGQEwaf4aUMiUEOHifFRWhGJr0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743586; c=relaxed/simple; bh=u2NAoGPKAPKT+TpiqoFdPon2GiyhMXZdDU3h7zflpd4=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=llSTwy3yUwIilU6pBkUChaDQyDCsV6hS+T4wut8tkUpGSTKuExqZkNyARu05vVA/COI2WgwwoDkuUnkcgsoLMvOgtjLv2VC3It0KYTgH//kPQ7mL+cbkeUGNLAm1NQrXmL0hMdxU5pxi7S3zb71LYQmFXcdlhNdQymbJ9hJQLPY= 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=vlQ+e9jU; arc=none smtp.client-ip=209.85.128.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="vlQ+e9jU" Received: by mail-yw1-f202.google.com with SMTP id 00721157ae682-6ad660add0fso15097417b3.0 for ; Thu, 15 Aug 2024 10:39:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743584; x=1724348384; 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=rvkihQVxilci4ahNE1D8FzulqWknfQTNlLMa6I6x8hA=; b=vlQ+e9jUjZcOlUACbuVApWiv2hKkg+gCV9rYJJBOuMYl5PzhW4Z4uf6aaqNVol20iu 1xi/gaIuNtbwHL0hiXzWRLGbfxuwAbOx1kGWHS2ocDL2u+lTUOmowzYOfq14uaHoGW7V CRodc+WHbq9O0/q1KsvjTlBu+EspBPsu0FFFBkGIoUmbUc9WXN1sS+x8bX+JqShdwdqf mXjeswQOAwf57XDpfMQV+V923uLusqdIY6yA1YojOqk39DOTE+j0bjrh7iXx3W2NnMON H4eISkeXe0yFarXA0drBDsCupet+gy7adwGmLo2iglCKwDWtuqsdjnrsx0l5IUoBqsf/ 1DlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743584; x=1724348384; 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=rvkihQVxilci4ahNE1D8FzulqWknfQTNlLMa6I6x8hA=; b=j6WYjwi4qJik+a3HC17qNFrCRInPQEEvgLV4//GgBTxMzqa8PfUTbLcrc9E+QA418G stjliizGBiyL0iiUMPHifueA4nT/qkBC33aPl3T3NvFRUEA7Ir5WNsMjZfvwL/SLedgT WbW9z2YC9TefGngUgvBGfIrj+l7S+ahwJFpJIu0T4ZuT4oepIOQUEtCMAaRbRR6ZKSNK 7REXNa/LKMIRCQUTXm18B7lFG+/k2vmyL+8xAmeugLHu5dQONDyrsZFwQSUOwLOjOcxp T7o5R+tbNeznVmRmE0l7YHjzCSMfDdPJrFNetQfTWOrjxQJON2qWGgDI5KKva9LBOgVX MPMg== X-Forwarded-Encrypted: i=1; AJvYcCXhJG5WqC8W8AYa1TP6UrRO5exsY9zEc+DhIGMA1Y4OmOYh3czRvWCVM5yKeBUuN3B/EvcZODZQn5CQWo/kPuwYaOp42/5uX5gMHsQBTQ== X-Gm-Message-State: AOJu0Yx6WLKhm9nfbU8Qn/15OQMP3EDynF/b75Wnp/qCvOJF89dWcIof c9PO6rqkO4J3Q7HyRCUyepGkYmPsa4JVIx3uSXGdraig2vIouAUpPgX5j8YL0LRm7NKOapNpxYr Jevy+8i4HW0abK247siQ+mZkI8Q== X-Google-Smtp-Source: AGHT+IG9S2PSLwKc0udu8I+6MHxXANcYb3L8yRqmH7TB0UIAP0u33tVkU9SrPY57CXk2d2U4eRcDrYniR8MuW7MasLc= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a05:690c:6208:b0:68e:edf4:7b42 with SMTP id 00721157ae682-6b1d42694c8mr59377b3.2.1723743583755; Thu, 15 Aug 2024 10:39:43 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:21 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=2005; i=samitolvanen@google.com; h=from:subject; bh=u2NAoGPKAPKT+TpiqoFdPon2GiyhMXZdDU3h7zflpd4=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj06nYnAUNx8o66EBLX4cU2eInAJSpLP8qYpz sKtbF+ZNs+JAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OgAKCRBMtfaEi7xW 7h06DACM546WdYBdw7Q9mrV/mD1RWAUpswtCJqVQxJ1f5GKGao7eEcXupGQuIPnw5Ey1+gEthL/ zUx8fmz4IOOWvMPnn54qc/0OYW6/yOLHQwIOrDeJJf1hMUgHTEdAad87xgKJCve78B3TGIfh2nK 0yG7q7yEEOxwnfzUWqETFg86JLzNqDLEcF+Le7QPYIg1crSXxPSGj6Qiq+dIClVReWIE6CEXm6A jWmn1/KCkWAGpc279+B+yrNNeukRQIgxYLJ88G+cLlgO31F4vU6302m5gBkhobfa5+qVTq3iPBi l2Qpx22OOHSDBGGwUufoz7aw+kwon3jhDBACj7QQTb+EJlImWNzKGwUtNj/9Meh0Z3Xr4ZEiquw A0WEfBnHtAuLfLpMfn2gsfq/4/5XA4sjbgrBgGBx5xR+Oa1fZwoL0dsfPIBqAXw9LoxbFAMytxK plh5XkQf3fItnk4E4Zyj5I8eM3vUaUZ4Mr52o+5/5O182vI0Y8C1VVTNzQiI1HDbrRaK8= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-38-samitolvanen@google.com> Subject: [PATCH v2 17/19] export: Add __gendwarfksyms_ptr_ references to exported symbols From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen With gendwarfksyms, we need each TU where the EXPORT_SYMBOL() macro is used to also contain DWARF type information for the symbols it exports. However, as a TU can also export external symbols and compilers may choose not to emit debugging information for symbols not defined in the current TU, the missing types will result in missing symbol versions. Stand-alone assembly code also doesn't contain type information for exported symbols, so we need to compile a temporary object file with asm-prototypes.h instead, and similarly need to ensure the DWARF in the temporary object file contains the necessary types. To always emit type information for external exports, add explicit __gendwarfksyms_ptr_ references to them in EXPORT_SYMBOL(). gendwarfksyms will use the type information for __gendwarfksyms_ptr_* if needed. Discard the pointers from the final binary to avoid further bloat. Signed-off-by: Sami Tolvanen --- include/linux/export.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/linux/export.h b/include/linux/export.h index 0bbd02fd351d..cf71d3202e5b 100644 --- a/include/linux/export.h +++ b/include/linux/export.h @@ -52,9 +52,24 @@ #else +#ifdef CONFIG_GENDWARFKSYMS +/* + * With CONFIG_GENDWARFKSYMS, ensure the compiler emits debugging + * information for all exported symbols, including those defined in + * different TUs, by adding a __gendwarfksyms_ptr_ pointer + * that's discarded during the final link. + */ +#define __GENDWARFKSYMS_EXPORT(sym) \ + static typeof(sym) *__gendwarfksyms_ptr_##sym __used \ + __section(".discard.gendwarfksyms") = &sym; +#else +#define __GENDWARFKSYMS_EXPORT(sym) +#endif + #define __EXPORT_SYMBOL(sym, license, ns) \ extern typeof(sym) sym; \ __ADDRESSABLE(sym) \ + __GENDWARFKSYMS_EXPORT(sym) \ asm(__stringify(___EXPORT_SYMBOL(sym, license, ns))) #endif From patchwork Thu Aug 15 17:39: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: 13765033 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 B6CFA7174F for ; Thu, 15 Aug 2024 17:39:46 +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=1723743588; cv=none; b=u+n/MKFvXDiBU1CB2C1T9/F/sASGfTonmitRVMBGwNrW0ZCWV6tIWMOODslfj1S3Po7wsnc/HKzEjgDH8SmB1n2Gc1rChPxZVVfhzDIFd5/ayeDyzOaxVLyIc9v9ULpJxaKK5Dwq9Z+K3gdtYvEipU+HOeRQNULXlEqMWV7Nc4A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743588; c=relaxed/simple; bh=JdHnM47y3DGHzd+8iOwDpRmp/jKwcxYBnVNDUzIM1Ts=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=FEQTRkg6DA4ki4dbdz7q6xHxFO2W2P/lxLS1Grq5qNXdC1IGtMUjO2QiSD9NfrkLEM9iVOyNDFmWckDX1iEopsUPfGCmyelTBgs3Zn3bPMYSZGZQtr09GmrKoT7PVO1yvMEPulRmavDYWXPvlKsYXDNn25Dx2R/WM9TIazG+o6E= 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=ZM1lGGhX; 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="ZM1lGGhX" Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-e0e8826e03bso2038301276.3 for ; Thu, 15 Aug 2024 10:39:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743586; x=1724348386; 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=Nzfrcr5/2Jg+dBktFb/j3BHPnQVbNwPzVAym41fmhTI=; b=ZM1lGGhXjiDPhgK4at+h2mr3e1tDaZuDEHY6ZxxARgVSpnrHK1cTG+x9yd2V+ANGD/ 1U3IZfMP720YfOFQRWr6cButoOk765Ba/O23/T+KeTyJHVxH+yM5M2o1cbB60AqwZLsU uk2FRvf2K7HzzOlcK3RQSu02JfWftOCqkX/IVCQN/UDEPprGRzc+C1wFk96bonWWls6r 0dAvuVwg0io3YD0RvI1WBaL70Oi2AF/FC2Gvu59u/OFBHXgsZBfWALkXzhZoIahf52pc h/+7/KfBaJyE+s5mgVygIieH/TOg9ORrVqUEQ5XKn3QP6ksR4nGJiieUCJpXgmI1ceVN MACw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743586; x=1724348386; 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=Nzfrcr5/2Jg+dBktFb/j3BHPnQVbNwPzVAym41fmhTI=; b=I812FWGkhv1Jp6utDwrpH32fkH5jCMlGu7/Z5/AXIJQpUfU4Stp2LJDQ8lHgzuBNbi SeAZZwnq8Wf77x60NhpnDlOq3Esd7EYRu6I7xhTWXhddvHmpVcxg7e9aA8kmB7CGBxJr JZjp5r0YyN+/RGPy3fV/EyRODPRzZCjDuDQdefQnNm7oMa9ccB+6E4Cl+XSZ8k6RJjNy +7qVr840k5mIH2LFqKKMw4f9KabuL0+sRb+pxeylRdM3YPr7Qip7FeHeF2g1615Q1k9j dCj55o2zjHCjGNgphYv5TozGgPW0n3QqTGyrQFckdVDqAW3OenKEW3ZpT9e6pHDBKtsn pMiA== X-Forwarded-Encrypted: i=1; AJvYcCU5AZKraq1rgQ7RFq28qfq52Wmp89fWMOu0Rp34DUa1mcR2ZYeshccl78WJ1DDLwzTuw3sigzPHWtfvaHkUe4dzroVqqNB+mTMjddWZcA== X-Gm-Message-State: AOJu0Yw+7Q60yLQO2RwPfD+kBZ4arKVMVXHw3diX/8hP7lJI3d8ESwyY mz5WUunaOtxrq7gw290GptFRTBc8ysTLwXRmcibjXvcLA6NP7dHScWkmZD8UL8LN41lnpoT5Yu+ zPaC9/yhaPpnofiV88vQTZMptuA== X-Google-Smtp-Source: AGHT+IEyPYGVIGctM8flGqu9QR91NaZgOu+gmaEjFyDcEPukNhfYOFghBSH/3RMkvc9pPV1ROu/JBf6StL4PXETlzNk= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a25:aad0:0:b0:e0b:ab63:b9c8 with SMTP id 3f1490d57ef6-e1180fa06d5mr496276.11.1723743585775; Thu, 15 Aug 2024 10:39:45 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:22 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=635; i=samitolvanen@google.com; h=from:subject; bh=JdHnM47y3DGHzd+8iOwDpRmp/jKwcxYBnVNDUzIM1Ts=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj06AdeqULMg79EuNtCXP+0M0mvzmV7eGmEL1 TuO+ezyrdOJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OgAKCRBMtfaEi7xW 7lvXC/9FcJ2/EUgwUrKKscdKY50Al5IkUmE5/+LjfwqoQUfzZ3RY4s6dV6KbAcj4/Bhr2Xb4dt/ 2e9OMOyAkxPtsaxq2meNZWjTCOs5B1S9dt4YHoHFuFH7zcjd6gWIMJI8k1mlaXiZlcaS4yy3/fU 3JI5uzSOu/9bidigVxQV1rgTfC5cAw8PKaMpTuiZ1mgPWAUrADAZMBpdO8sSULOKFzef1yk32ya 89z7CW/fL0vwVz+9RZktwxObxSFIvAgmq5UkMp/Q0PS/lsj6kCbKsje6YaKlpgZys5otmjCXA47 cwLMLAhG/Yr79l5URg1O0tiij11q9zeoKn+2tGUH/qOls7UpOgHzoGaqcBaQBhLm7heKDc4DG+Y ZT0AQdp9myWj0erPLfH9Slv3EbXdbYBX1fN1lQvOb2LGm0vExdj1vlXX2J5PPetMZ9f9eSKN21G bKZcAaEPBGqMik8HlMXvCBOIAs2VM0OkWTxp3tQE5pgq0BPWeb8KEp9M9H3mEzX8UeiQs= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-39-samitolvanen@google.com> Subject: [PATCH v2 18/19] x86/asm-prototypes: Include From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen refers to struct pt_regs, make sure it's visible. Signed-off-by: Sami Tolvanen --- arch/x86/include/asm/asm-prototypes.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/include/asm/asm-prototypes.h b/arch/x86/include/asm/asm-prototypes.h index 25466c4d2134..c82e68c8b7c2 100644 --- a/arch/x86/include/asm/asm-prototypes.h +++ b/arch/x86/include/asm/asm-prototypes.h @@ -1,4 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0 */ +#include #include #include #include From patchwork Thu Aug 15 17:39: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: 13765034 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 288DC1C232A for ; Thu, 15 Aug 2024 17:39:48 +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=1723743590; cv=none; b=Oce8Dyd6Bp1rFOHFdUbyZ54dwIzMyuG6E9YBVFdTGgWzLi1fwmmZUc0VU+8ZPob3YU+gpOsvQ0BurQ2uza16ypBJo7Uex5y7YX4RVggheZhxce6N0AFT1gKBmvVXRLjW7WAfC29OZl1L3XGyQVY1mZh8m90Y1jsHIKgNOUM76LY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1723743590; c=relaxed/simple; bh=mz7nffxN7wId2ePyNyx2gbUj67IvJCbAVk8B4r6F3JI=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=g0NavwamnOdU3/54ys1Rax638Fn07k0TBkq0UB4/2TO4eI3LjcgEZ0yzgWvLT/PYXstGlzRQGjv9pkz6FfMc0XXWnXk2F3O95zT2zzySEJuR3C1TtgAJLQ9k54Z5xxclYKun6zyKoYqr8AZVPZPYcdo9gjmpKzEL8AxcdpI55k8= 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=LnEwPMPV; 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="LnEwPMPV" Received: by mail-pg1-f202.google.com with SMTP id 41be03b00d2f7-7a2787eb33dso965685a12.1 for ; Thu, 15 Aug 2024 10:39:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1723743588; x=1724348388; 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=cHfKDENnTQm8ek88L2arGqWCp64m5+2eabNApwrdQWY=; b=LnEwPMPVbeoeSua6GvHxSbd3y5TvC2a1MGWzskd+CAB2jSmEQa8CFFFLIy6KQf+stt KPs5p0wata407FkfAeh+TrsfxbWSMeVI47oY0UtRDCZqEkGG6Q8vomsxLgPcEhS+jubq DP3IXpU2WOeva7q8t6nABbuE9Gfz9CnfTizVomTQxZeCV3kG8+C1O8BOP7R0PQgsNas8 Cgf1NePbfo6Gdc46iUvnj0rLIXoed2aQPAlwNYtSONobR4kxE/8lkvpbQqwJ9jvpguA8 LpNKXd25NKk0vS11OS8q5sM4XNjMrpkOtuRfyBXjVvcRctbXRpJREZ4butLsRUR1ktIY 3ZLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723743588; x=1724348388; 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=cHfKDENnTQm8ek88L2arGqWCp64m5+2eabNApwrdQWY=; b=uQ3dUk9/2LyaB9FTGq7yRXiTuAz/MxyRpnnUzAPVsTYpdLgBDqILxelaJqHnL7yebn VYUYYdtZjoDfo/F27Lxmn8/WUU9Jl6mnb0Oo0BT44Pm8qzxdj9ZDWtXZKDViAti+Ub6T uuHam6QSXURCnDCeOriyVYcbzQadca3+e0gIXXLlR3itb/bxGE36uTTbT4VuhVwCJ2DT 7rhKruZFdC0evuKovsqC9dkJK9SC0+w19NffMHiKVl7lYysdcV+O3aYjsvbDT++T8SoY 4ZGyp4Mzll4goLbeaJ0oJI2QNtk/nrM37p+m9fzi6Kx2n1BUAfDr7xideP9v7rQRcDbs qIeg== X-Forwarded-Encrypted: i=1; AJvYcCU3Eo7g4XcUs0rthlGNox7bGt5QwAqKW/lJK/6cpkayT3y/WGVgpNv/eYBVZMqWv6FUjg+6qCtL26oMY/VCaTudO3yq/qt080bQEWfRBw== X-Gm-Message-State: AOJu0YxLKPhLRAVgu3TpuE/46tZyHbS0WXfW0I0SYijMRf/PXYeN8PnR cmABVz8zwce7iEnCd/BWZCGrx6XuAfzvijmFe+52XCCVXF4/BKD32y1KFZbKp+Is6WZnJ/VU2Td 6Rh2RLcALw3dSkXBg+EeElc5zpw== X-Google-Smtp-Source: AGHT+IFTAkXFaRwAV/SQwqCeTGEycib4FiTINhjKTaFPZbrPJmJ+KMbkdPWYs8+NjnMSf4VPl8XwcMRzylf5jVza6Gs= X-Received: from samitolvanen.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:4f92]) (user=samitolvanen job=sendgmr) by 2002:a63:af1c:0:b0:75e:cf19:8f83 with SMTP id 41be03b00d2f7-7c9796d8a56mr125a12.3.1723743587293; Thu, 15 Aug 2024 10:39:47 -0700 (PDT) Date: Thu, 15 Aug 2024 17:39:23 +0000 In-Reply-To: <20240815173903.4172139-21-samitolvanen@google.com> Precedence: bulk X-Mailing-List: linux-modules@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240815173903.4172139-21-samitolvanen@google.com> X-Developer-Key: i=samitolvanen@google.com; a=openpgp; fpr=35CCFB63B283D6D3AEB783944CB5F6848BBC56EE X-Developer-Signature: v=1; a=openpgp-sha256; l=4761; i=samitolvanen@google.com; h=from:subject; bh=mz7nffxN7wId2ePyNyx2gbUj67IvJCbAVk8B4r6F3JI=; b=owEB7QES/pANAwAKAUy19oSLvFbuAcsmYgBmvj06CUaKOoKTE/x4zhmMUl5+xK4VKhS9egsRZ EV60/RxPFeJAbMEAAEKAB0WIQQ1zPtjsoPW0663g5RMtfaEi7xW7gUCZr49OgAKCRBMtfaEi7xW 7rzZDACSD3JRn+H/NSXRZE7PImLTyCeLXiFaUKPrqH9OX1i0VZRE+Ujk3Fwuv1EQvYxnkTXOGSQ 4pzHAXhRMgHLUw9Pj6WaFvL15HccicXnzBlDKBCRbchKw1xRa1hgd5BD1dOVLal2i2yGJ5wjWj0 w7hogl6gH6uVQcLpDQAhAGHCzMprB+Joyc/Yp+xwhcPTqCWeElf4fcBwKR8i+IpLf9hRgmG6p6y AqDez4vPKDD85j4xvlyhkuasvReQEsWWB3j/2swrrMVBprrGZnIIje8us1UinjDhg521N+mtV5X WWIOKRhrhCyv8kmHEKUOgoBp2zNSJEGIimSkz/3s7lrkIrlCdwmFsd3vgNEMbaS5mR/AkgDcqyv 5XaOmdjdfTVLCvqAPWx3Px2kXJ2M1bx1VAZNuzXWuQPsCaMOWd9yEpuyXnor1R7Aoaw9hG6nYHy l/aa9uwh9DOgnzHvAaeyx1TKhEx+sIF5Gh3O3D2TvLFWr5TNOv0agadESGCu/jUR5jhUs= X-Mailer: git-send-email 2.46.0.184.g6999bdac58-goog Message-ID: <20240815173903.4172139-40-samitolvanen@google.com> Subject: [PATCH v2 19/19] kbuild: Add gendwarfksyms as an alternative to genksyms From: Sami Tolvanen To: Masahiro Yamada , Luis Chamberlain , Miguel Ojeda , Greg Kroah-Hartman Cc: Matthew Maurer , Alex Gaynor , Wedson Almeida Filho , Gary Guo , Petr Pavlu , Neal Gompa , Hector Martin , Janne Grunau , Asahi Linux , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-modules@vger.kernel.org, rust-for-linux@vger.kernel.org, Sami Tolvanen When MODVERSIONS is enabled, allow selecting gendwarfksyms as the implementation, but default to genksyms. Signed-off-by: Sami Tolvanen --- kernel/module/Kconfig | 25 ++++++++++++++++++++++++- scripts/Makefile | 2 +- scripts/Makefile.build | 34 ++++++++++++++++++++++++++++------ 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig index a506d4ac660f..80b2e9b0596b 100644 --- a/kernel/module/Kconfig +++ b/kernel/module/Kconfig @@ -168,13 +168,36 @@ config MODVERSIONS make them incompatible with the kernel you are running. If unsure, say N. +choice + prompt "Module versioning implementation" + depends on MODVERSIONS + default GENKSYMS + help + Select the tool used to calculate symbol versions for modules. + + If unsure, select GENKSYMS. + +config GENKSYMS + bool "genksyms (from source code)" + help + Calculate symbol versions from pre-processed source code using + genksyms. + + If unsure, say Y. + config GENDWARFKSYMS - bool + bool "gendwarfksyms (from debugging information)" depends on DEBUG_INFO # Requires full debugging information, split DWARF not supported. depends on !DEBUG_INFO_REDUCED && !DEBUG_INFO_SPLIT # Requires ELF object files. depends on !LTO + help + Calculate symbol versions from DWARF debugging information using + gendwarfksyms. Requires DEBUG_INFO to be enabled. + + If unsure, say N. +endchoice config ASM_MODVERSIONS bool diff --git a/scripts/Makefile b/scripts/Makefile index 2fd0199662e9..52db4f1f37c4 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -53,7 +53,7 @@ hostprogs += unifdef targets += module.lds subdir-$(CONFIG_GCC_PLUGINS) += gcc-plugins -subdir-$(CONFIG_MODVERSIONS) += genksyms +subdir-$(CONFIG_GENKSYMS) += genksyms subdir-$(CONFIG_GENDWARFKSYMS) += gendwarfksyms subdir-$(CONFIG_SECURITY_SELINUX) += selinux diff --git a/scripts/Makefile.build b/scripts/Makefile.build index efacca63c897..985e4ba7b813 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -122,13 +122,22 @@ cmd_cpp_i_c = $(CPP) $(c_flags) -o $@ $< $(obj)/%.i: $(obj)/%.c FORCE $(call if_changed_dep,cpp_i_c) +gendwarfksyms := scripts/gendwarfksyms/gendwarfksyms +getexportsymbols = $(NM) $(1) | sed -n 's/.* __export_symbol_\(.*\)/$(2)/p' + genksyms = scripts/genksyms/genksyms \ $(if $(1), -T $(2)) \ $(if $(KBUILD_PRESERVE), -p) \ -r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null) # These mirror gensymtypes_S and co below, keep them in synch. +ifdef CONFIG_GENDWARFKSYMS +cmd_gensymtypes_c = $(if $(skip_gendwarfksyms),, \ + $(call getexportsymbols,$(2:.symtypes=.o),\1) | \ + $(gendwarfksyms) $(2:.symtypes=.o) $(if $(1), --symtypes $(2))) +else cmd_gensymtypes_c = $(CPP) -D__GENKSYMS__ $(c_flags) $< | $(genksyms) +endif # CONFIG_GENDWARFKSYMS quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@ cmd_cc_symtypes_c = $(call cmd_gensymtypes_c,true,$@) >/dev/null @@ -324,14 +333,27 @@ $(obj)/%.ll: $(obj)/%.rs FORCE # This is convoluted. The .S file must first be preprocessed to run guards and # expand names, then the resulting exports must be constructed into plain # EXPORT_SYMBOL(symbol); to build our dummy C file, and that gets preprocessed -# to make the genksyms input. +# to make the genksyms input or compiled into an object for gendwarfksyms. # # These mirror gensymtypes_c and co above, keep them in synch. -cmd_gensymtypes_S = \ - { echo "\#include " ; \ - echo "\#include " ; \ - $(NM) $@ | sed -n 's/.* __export_symbol_\(.*\)/EXPORT_SYMBOL(\1);/p' ; } | \ - $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | $(genksyms) +getasmexports = \ + { echo "\#include " ; \ + echo "\#include " ; \ + echo "\#include " ; \ + $(call getexportsymbols,$@,EXPORT_SYMBOL(\1);) ; } + +ifdef CONFIG_GENDWARFKSYMS +cmd_gensymtypes_S = \ + $(getasmexports) | \ + $(CC) $(c_flags) -c -o $(@:.o=.gendwarfksyms.o) -xc -; \ + $(call getexportsymbols,$@,\1) | \ + $(gendwarfksyms) $(@:.o=.gendwarfksyms.o) \ + $(if $(1), --symtypes $(2)) +else +cmd_gensymtypes_S = \ + $(getasmexports) | \ + $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | $(genksyms) +endif # CONFIG_GENDWARFKSYMS quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@ cmd_cc_symtypes_S = $(call cmd_gensymtypes_S,true,$@) >/dev/null