18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * builtin-kallsyms.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Builtin command: Look for a symbol in the running kernel and its modules 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright (C) 2017, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci#include <inttypes.h> 108c2ecf20Sopenharmony_ci#include "builtin.h" 118c2ecf20Sopenharmony_ci#include <linux/compiler.h> 128c2ecf20Sopenharmony_ci#include <subcmd/parse-options.h> 138c2ecf20Sopenharmony_ci#include "debug.h" 148c2ecf20Sopenharmony_ci#include "dso.h" 158c2ecf20Sopenharmony_ci#include "machine.h" 168c2ecf20Sopenharmony_ci#include "map.h" 178c2ecf20Sopenharmony_ci#include "symbol.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistatic int __cmd_kallsyms(int argc, const char **argv) 208c2ecf20Sopenharmony_ci{ 218c2ecf20Sopenharmony_ci int i; 228c2ecf20Sopenharmony_ci struct machine *machine = machine__new_kallsyms(); 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci if (machine == NULL) { 258c2ecf20Sopenharmony_ci pr_err("Couldn't read /proc/kallsyms\n"); 268c2ecf20Sopenharmony_ci return -1; 278c2ecf20Sopenharmony_ci } 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci for (i = 0; i < argc; ++i) { 308c2ecf20Sopenharmony_ci struct map *map; 318c2ecf20Sopenharmony_ci struct symbol *symbol = machine__find_kernel_symbol_by_name(machine, argv[i], &map); 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci if (symbol == NULL) { 348c2ecf20Sopenharmony_ci printf("%s: not found\n", argv[i]); 358c2ecf20Sopenharmony_ci continue; 368c2ecf20Sopenharmony_ci } 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci printf("%s: %s %s %#" PRIx64 "-%#" PRIx64 " (%#" PRIx64 "-%#" PRIx64")\n", 398c2ecf20Sopenharmony_ci symbol->name, map->dso->short_name, map->dso->long_name, 408c2ecf20Sopenharmony_ci map->unmap_ip(map, symbol->start), map->unmap_ip(map, symbol->end), 418c2ecf20Sopenharmony_ci symbol->start, symbol->end); 428c2ecf20Sopenharmony_ci } 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci machine__delete(machine); 458c2ecf20Sopenharmony_ci return 0; 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ciint cmd_kallsyms(int argc, const char **argv) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci const struct option options[] = { 518c2ecf20Sopenharmony_ci OPT_INCR('v', "verbose", &verbose, "be more verbose (show counter open errors, etc)"), 528c2ecf20Sopenharmony_ci OPT_END() 538c2ecf20Sopenharmony_ci }; 548c2ecf20Sopenharmony_ci const char * const kallsyms_usage[] = { 558c2ecf20Sopenharmony_ci "perf kallsyms [<options>] symbol_name", 568c2ecf20Sopenharmony_ci NULL 578c2ecf20Sopenharmony_ci }; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci argc = parse_options(argc, argv, options, kallsyms_usage, 0); 608c2ecf20Sopenharmony_ci if (argc < 1) 618c2ecf20Sopenharmony_ci usage_with_options(kallsyms_usage, options); 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci symbol_conf.sort_by_name = true; 648c2ecf20Sopenharmony_ci symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); 658c2ecf20Sopenharmony_ci if (symbol__init(NULL) < 0) 668c2ecf20Sopenharmony_ci return -1; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci return __cmd_kallsyms(argc, argv); 698c2ecf20Sopenharmony_ci} 70