File Index
Files and directories
Sign in
FILE

gendwarfksyms.c

File preview with syntax highlighting.

linux-6.19.14/scripts/gendwarfksyms/gendwarfksyms.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (C) 2024 Google LLC
  4 */
  5
  6#include <fcntl.h>
  7#include <getopt.h>
  8#include <errno.h>
  9#include <stdarg.h>
 10#include <string.h>
 11#include <unistd.h>
 12#include "gendwarfksyms.h"
 13
 14/*
 15 * Options
 16 */
 17
 18/* Print debugging information to stderr */
 19int debug;
 20/* Dump DIE contents */
 21int dump_dies;
 22/* Print debugging information about die_map changes */
 23int dump_die_map;
 24/* Print out type strings (i.e. type_map) */
 25int dump_types;
 26/* Print out expanded type strings used for symbol versions */
 27int dump_versions;
 28/* Support kABI stability features */
 29int stable;
 30/* Write a symtypes file */
 31int symtypes;
 32static const char *symtypes_file;
 33
 34static void usage(void)
 35{
 36	fputs("Usage: gendwarfksyms [options] elf-object-file ... < symbol-list\n\n"
 37	      "Options:\n"
 38	      "  -d, --debug          Print debugging information\n"
 39	      "      --dump-dies      Dump DWARF DIE contents\n"
 40	      "      --dump-die-map   Print debugging information about die_map changes\n"
 41	      "      --dump-types     Dump type strings\n"
 42	      "      --dump-versions  Dump expanded type strings used for symbol versions\n"
 43	      "  -s, --stable         Support kABI stability features\n"
 44	      "  -T, --symtypes file  Write a symtypes file\n"
 45	      "  -h, --help           Print this message\n"
 46	      "\n",
 47	      stderr);
 48}
 49
 50static int process_module(Dwfl_Module *mod, void **userdata, const char *name,
 51			  Dwarf_Addr base, void *arg)
 52{
 53	Dwarf_Addr dwbias;
 54	Dwarf_Die cudie;
 55	Dwarf_CU *cu = NULL;
 56	Dwarf *dbg;
 57	FILE *symfile = arg;
 58	int res;
 59
 60	debug("%s", name);
 61	dbg = dwfl_module_getdwarf(mod, &dwbias);
 62
 63	/*
 64	 * Look for exported symbols in each CU, follow the DIE tree, and add
 65	 * the entries to die_map.
 66	 */
 67	do {
 68		res = dwarf_get_units(dbg, cu, &cu, NULL, NULL, &cudie, NULL);
 69		if (res < 0)
 70			error("dwarf_get_units failed: no debugging information?");
 71		if (res == 1)
 72			break; /* No more units */
 73
 74		process_cu(&cudie);
 75	} while (cu);
 76
 77	/*
 78	 * Use die_map to expand type strings, write them to `symfile`, and
 79	 * calculate symbol versions.
 80	 */
 81	generate_symtypes_and_versions(symfile);
 82	die_map_free();
 83
 84	return DWARF_CB_OK;
 85}
 86
 87static const Dwfl_Callbacks callbacks = {
 88	.section_address = dwfl_offline_section_address,
 89	.find_debuginfo = dwfl_standard_find_debuginfo,
 90};
 91
 92int main(int argc, char **argv)
 93{
 94	FILE *symfile = NULL;
 95	unsigned int n;
 96	int opt;
 97
 98	static const struct option opts[] = {
 99		{ "debug", 0, NULL, 'd' },
100		{ "dump-dies", 0, &dump_dies, 1 },
101		{ "dump-die-map", 0, &dump_die_map, 1 },
102		{ "dump-types", 0, &dump_types, 1 },
103		{ "dump-versions", 0, &dump_versions, 1 },
104		{ "stable", 0, NULL, 's' },
105		{ "symtypes", 1, NULL, 'T' },
106		{ "help", 0, NULL, 'h' },
107		{ 0, 0, NULL, 0 }
108	};
109
110	while ((opt = getopt_long(argc, argv, "dsT:h", opts, NULL)) != EOF) {
111		switch (opt) {
112		case 0:
113			break;
114		case 'd':
115			debug = 1;
116			break;
117		case 's':
118			stable = 1;
119			break;
120		case 'T':
121			symtypes = 1;
122			symtypes_file = optarg;
123			break;
124		case 'h':
125			usage();
126			return 0;
127		default:
128			usage();
129			return 1;
130		}
131	}
132
133	if (dump_die_map)
134		dump_dies = 1;
135
136	if (optind >= argc) {
137		usage();
138		error("no input files?");
139	}
140
141	if (!symbol_read_exports(stdin))
142		return 0;
143
144	if (symtypes_file) {
145		symfile = fopen(symtypes_file, "w");
146		if (!symfile)
147			error("fopen failed for '%s': %s", symtypes_file,
148			      strerror(errno));
149	}
150
151	for (n = optind; n < argc; n++) {
152		Dwfl *dwfl;
153		int fd;
154
155		fd = open(argv[n], O_RDONLY);
156		if (fd == -1)
157			error("open failed for '%s': %s", argv[n],
158			      strerror(errno));
159
160		symbol_read_symtab(fd);
161		kabi_read_rules(fd);
162
163		dwfl = dwfl_begin(&callbacks);
164		if (!dwfl)
165			error("dwfl_begin failed for '%s': %s", argv[n],
166			      dwarf_errmsg(-1));
167
168		if (!dwfl_report_offline(dwfl, argv[n], argv[n], fd))
169			error("dwfl_report_offline failed for '%s': %s",
170			      argv[n], dwarf_errmsg(-1));
171
172		dwfl_report_end(dwfl, NULL, NULL);
173
174		if (dwfl_getmodules(dwfl, &process_module, symfile, 0))
175			error("dwfl_getmodules failed for '%s'", argv[n]);
176
177		dwfl_end(dwfl);
178		kabi_free();
179	}
180
181	if (symfile)
182		check(fclose(symfile));
183
184	symbol_print_versions();
185	symbol_free();
186
187	return 0;
188}
~/ Read-only file preview.