1da0c48c4Sopenharmony_ci/* Copyright (C) 2005 Red Hat, Inc. 2da0c48c4Sopenharmony_ci This file is part of elfutils. 3da0c48c4Sopenharmony_ci 4da0c48c4Sopenharmony_ci This file is free software; you can redistribute it and/or modify 5da0c48c4Sopenharmony_ci it under the terms of the GNU General Public License as published by 6da0c48c4Sopenharmony_ci the Free Software Foundation; either version 3 of the License, or 7da0c48c4Sopenharmony_ci (at your option) any later version. 8da0c48c4Sopenharmony_ci 9da0c48c4Sopenharmony_ci elfutils is distributed in the hope that it will be useful, but 10da0c48c4Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 11da0c48c4Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12da0c48c4Sopenharmony_ci GNU General Public License for more details. 13da0c48c4Sopenharmony_ci 14da0c48c4Sopenharmony_ci You should have received a copy of the GNU General Public License 15da0c48c4Sopenharmony_ci along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16da0c48c4Sopenharmony_ci 17da0c48c4Sopenharmony_ci#ifdef HAVE_CONFIG_H 18da0c48c4Sopenharmony_ci# include <config.h> 19da0c48c4Sopenharmony_ci#endif 20da0c48c4Sopenharmony_ci 21da0c48c4Sopenharmony_ci#include <inttypes.h> 22da0c48c4Sopenharmony_ci#include <assert.h> 23da0c48c4Sopenharmony_ci#include ELFUTILS_HEADER(dwfl) 24da0c48c4Sopenharmony_ci#include <argp.h> 25da0c48c4Sopenharmony_ci#include <stdio.h> 26da0c48c4Sopenharmony_ci#include <locale.h> 27da0c48c4Sopenharmony_ci#include <stdlib.h> 28da0c48c4Sopenharmony_ci#include <string.h> 29da0c48c4Sopenharmony_ci#include "system.h" 30da0c48c4Sopenharmony_ci 31da0c48c4Sopenharmony_ci 32da0c48c4Sopenharmony_cistatic void 33da0c48c4Sopenharmony_ciprint_address (Dwfl_Module *mod, Dwarf_Addr address) 34da0c48c4Sopenharmony_ci{ 35da0c48c4Sopenharmony_ci int n = dwfl_module_relocations (mod); 36da0c48c4Sopenharmony_ci if (n < 0) 37da0c48c4Sopenharmony_ci error (0, 0, "dwfl_module_relocations: %s", dwfl_errmsg (-1)); 38da0c48c4Sopenharmony_ci else if (n > 0) 39da0c48c4Sopenharmony_ci { 40da0c48c4Sopenharmony_ci int i = dwfl_module_relocate_address (mod, &address); 41da0c48c4Sopenharmony_ci if (i < 0) 42da0c48c4Sopenharmony_ci error (0, 0, "dwfl_module_relocate_address: %s", dwfl_errmsg (-1)); 43da0c48c4Sopenharmony_ci else 44da0c48c4Sopenharmony_ci { 45da0c48c4Sopenharmony_ci const char *modname = dwfl_module_info (mod, NULL, NULL, NULL, 46da0c48c4Sopenharmony_ci NULL, NULL, NULL, NULL); 47da0c48c4Sopenharmony_ci const char *secname = dwfl_module_relocation_info (mod, i, NULL); 48da0c48c4Sopenharmony_ci if (n > 1 || secname[0] != '\0') 49da0c48c4Sopenharmony_ci printf ("%s(%s)+%#" PRIx64, modname, secname, address); 50da0c48c4Sopenharmony_ci else 51da0c48c4Sopenharmony_ci printf ("%s+%#" PRIx64, modname, address); 52da0c48c4Sopenharmony_ci return; 53da0c48c4Sopenharmony_ci } 54da0c48c4Sopenharmony_ci } 55da0c48c4Sopenharmony_ci 56da0c48c4Sopenharmony_ci printf ("%#" PRIx64, address); 57da0c48c4Sopenharmony_ci} 58da0c48c4Sopenharmony_ci 59da0c48c4Sopenharmony_ci 60da0c48c4Sopenharmony_cistruct args 61da0c48c4Sopenharmony_ci{ 62da0c48c4Sopenharmony_ci const char *arg; 63da0c48c4Sopenharmony_ci char *file; 64da0c48c4Sopenharmony_ci int line; 65da0c48c4Sopenharmony_ci}; 66da0c48c4Sopenharmony_ci 67da0c48c4Sopenharmony_cistatic int 68da0c48c4Sopenharmony_cihandle_module (Dwfl_Module *mod __attribute__ ((unused)), 69da0c48c4Sopenharmony_ci void **udata __attribute__ ((unused)), 70da0c48c4Sopenharmony_ci const char *modname, Dwarf_Addr base __attribute__ ((unused)), 71da0c48c4Sopenharmony_ci Dwarf *dbg __attribute__ ((unused)), 72da0c48c4Sopenharmony_ci Dwarf_Addr bias __attribute__ ((unused)), void *arg) 73da0c48c4Sopenharmony_ci{ 74da0c48c4Sopenharmony_ci const struct args *const a = arg; 75da0c48c4Sopenharmony_ci 76da0c48c4Sopenharmony_ci Dwfl_Line **lines = NULL; 77da0c48c4Sopenharmony_ci size_t nlines = 0; 78da0c48c4Sopenharmony_ci 79da0c48c4Sopenharmony_ci if (dwfl_module_getsrc_file (mod, a->file, a->line, 0, &lines, &nlines) == 0) 80da0c48c4Sopenharmony_ci { 81da0c48c4Sopenharmony_ci for (size_t inner = 0; inner < nlines; ++inner) 82da0c48c4Sopenharmony_ci { 83da0c48c4Sopenharmony_ci Dwarf_Addr addr; 84da0c48c4Sopenharmony_ci int line = a->line, col = 0; 85da0c48c4Sopenharmony_ci const char *file = dwfl_lineinfo (lines[inner], &addr, &line, &col, 86da0c48c4Sopenharmony_ci NULL, NULL); 87da0c48c4Sopenharmony_ci if (file != NULL) 88da0c48c4Sopenharmony_ci { 89da0c48c4Sopenharmony_ci printf ("%s -> ", a->arg); 90da0c48c4Sopenharmony_ci print_address (mod, addr); 91da0c48c4Sopenharmony_ci if (modname[0] != '\0') 92da0c48c4Sopenharmony_ci printf (" (%s:", modname); 93da0c48c4Sopenharmony_ci if (strcmp (file, a->file) || line != a->line || col != 0) 94da0c48c4Sopenharmony_ci printf (" %s%s:%d", modname[0] != '\0' ? "" : "(", 95da0c48c4Sopenharmony_ci file, line); 96da0c48c4Sopenharmony_ci if (col != 0) 97da0c48c4Sopenharmony_ci printf (":%d", col); 98da0c48c4Sopenharmony_ci if (modname[0] != '\0' 99da0c48c4Sopenharmony_ci || strcmp (file, a->file) || line != a->line || col != 0) 100da0c48c4Sopenharmony_ci puts (")"); 101da0c48c4Sopenharmony_ci else 102da0c48c4Sopenharmony_ci puts (""); 103da0c48c4Sopenharmony_ci } 104da0c48c4Sopenharmony_ci } 105da0c48c4Sopenharmony_ci free (lines); 106da0c48c4Sopenharmony_ci } 107da0c48c4Sopenharmony_ci 108da0c48c4Sopenharmony_ci return DWARF_CB_OK; 109da0c48c4Sopenharmony_ci} 110da0c48c4Sopenharmony_ci 111da0c48c4Sopenharmony_ciint 112da0c48c4Sopenharmony_cimain (int argc, char *argv[]) 113da0c48c4Sopenharmony_ci{ 114da0c48c4Sopenharmony_ci int cnt; 115da0c48c4Sopenharmony_ci 116da0c48c4Sopenharmony_ci /* Set locale. */ 117da0c48c4Sopenharmony_ci (void) setlocale (LC_ALL, ""); 118da0c48c4Sopenharmony_ci 119da0c48c4Sopenharmony_ci Dwfl *dwfl = NULL; 120da0c48c4Sopenharmony_ci (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &cnt, &dwfl); 121da0c48c4Sopenharmony_ci assert (dwfl != NULL); 122da0c48c4Sopenharmony_ci 123da0c48c4Sopenharmony_ci for (; cnt < argc; ++cnt) 124da0c48c4Sopenharmony_ci { 125da0c48c4Sopenharmony_ci struct args a = { .arg = argv[cnt] }; 126da0c48c4Sopenharmony_ci 127da0c48c4Sopenharmony_ci switch (sscanf (a.arg, "%m[^:]:%d", &a.file, &a.line)) 128da0c48c4Sopenharmony_ci { 129da0c48c4Sopenharmony_ci default: 130da0c48c4Sopenharmony_ci case 0: 131da0c48c4Sopenharmony_ci printf ("ignored %s\n", argv[cnt]); 132da0c48c4Sopenharmony_ci continue; 133da0c48c4Sopenharmony_ci case 1: 134da0c48c4Sopenharmony_ci a.line = 0; 135da0c48c4Sopenharmony_ci break; 136da0c48c4Sopenharmony_ci case 2: 137da0c48c4Sopenharmony_ci break; 138da0c48c4Sopenharmony_ci } 139da0c48c4Sopenharmony_ci 140da0c48c4Sopenharmony_ci (void) dwfl_getdwarf (dwfl, &handle_module, &a, 0); 141da0c48c4Sopenharmony_ci 142da0c48c4Sopenharmony_ci free (a.file); 143da0c48c4Sopenharmony_ci } 144da0c48c4Sopenharmony_ci 145da0c48c4Sopenharmony_ci dwfl_end (dwfl); 146da0c48c4Sopenharmony_ci 147da0c48c4Sopenharmony_ci return 0; 148da0c48c4Sopenharmony_ci} 149