1 /* Test program for libdwfl basic module tracking, relocation.
2 Copyright (C) 2005, 2007 Red Hat, Inc.
3 This file is part of Red Hat elfutils.
5 Red Hat elfutils is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by the
7 Free Software Foundation; version 2 of the License.
9 Red Hat elfutils is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License along
15 with Red Hat elfutils; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
18 Red Hat elfutils is an included package of the Open Invention Network.
19 An included package of the Open Invention Network is a package for which
20 Open Invention Network licensees cross-license their patents. No patent
21 license is granted, either expressly or impliedly, by designation as an
22 included package. Should you wish to participate in the Open Invention
23 Network licensing program, please visit www.openinventionnetwork.com
24 <http://www.openinventionnetwork.com>. */
29 #include <sys/types.h>
31 #include <stdio_ext.h>
37 #include ELFUTILS_HEADER(dwfl)
40 static bool show_inlines;
49 print_instance (Dwarf_Die *instance, void *arg)
51 const struct info *info = arg;
56 if (dwarf_getsrcfiles (info->cudie, &files, NULL) == 0)
58 Dwarf_Attribute attr_mem;
60 if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_file,
61 &attr_mem), &val) == 0)
63 const char *file = dwarf_filesrc (files, val, NULL, NULL);
64 int lineno = 0, colno = 0;
65 if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_line,
66 &attr_mem), &val) == 0)
68 if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_column,
69 &attr_mem), &val) == 0)
74 printf (" from %s", file);
77 printf (" at %s:%u", file, lineno);
79 printf (" at %s:%u:%u", file, lineno, colno);
83 Dwarf_Addr lo = -1, hi = -1, entry = -1;
84 if (dwarf_lowpc (instance, &lo) == 0)
87 printf (" (lowpc => %s)", dwarf_errmsg (-1));
88 if (dwarf_highpc (instance, &hi) == 0)
91 printf (" (highpc => %s)", dwarf_errmsg (-1));
93 Dwarf_Attribute attr_mem;
94 Dwarf_Attribute *attr = dwarf_attr (instance, DW_AT_entry_pc, &attr_mem);
97 if (dwarf_formaddr (attr, &entry) == 0)
98 entry += info->dwbias;
100 printf (" (entrypc => %s)", dwarf_errmsg (-1));
103 if (lo != (Dwarf_Addr) -1 || hi != (Dwarf_Addr) -1)
104 printf (" %#" PRIx64 "..%#" PRIx64, lo, hi);
105 if (entry != (Dwarf_Addr) -1)
106 printf (" => %#" PRIx64 "\n", entry);
114 print_inline (Dwarf_Die *func, void *arg)
116 if (dwarf_func_inline_instances (func, &print_instance, arg) != 0)
117 printf (" error finding instances: %s\n", dwarf_errmsg (-1));
121 print_func (Dwarf_Die *func, void *arg)
123 const struct info *info = arg;
125 const char *file = dwarf_decl_file (func);
127 dwarf_decl_line (func, &line);
128 const char *fct = dwarf_diename (func);
130 printf (" %s:%d: %s:", file, line, fct);
132 if (dwarf_func_inline (func))
134 puts (" inline function");
136 print_inline (func, arg);
140 Dwarf_Addr lo = -1, hi = -1, entry = -1;
141 if (dwarf_lowpc (func, &lo) == 0)
144 printf (" (lowpc => %s)", dwarf_errmsg (-1));
145 if (dwarf_highpc (func, &hi) == 0)
148 printf (" (highpc => %s)", dwarf_errmsg (-1));
149 if (dwarf_entrypc (func, &entry) == 0)
150 entry += info->dwbias;
152 printf (" (entrypc => %s)", dwarf_errmsg (-1));
154 if (lo != (Dwarf_Addr) -1 || hi != (Dwarf_Addr) -1
155 || entry != (Dwarf_Addr) -1)
156 printf (" %#" PRIx64 "..%#" PRIx64 " => %#" PRIx64 "\n",
166 list_module (Dwfl_Module *mod __attribute__ ((unused)),
167 void **userdata __attribute__ ((unused)),
168 const char *name, Dwarf_Addr base,
169 void *arg __attribute__ ((unused)))
175 if (dwfl_module_info (mod, NULL, &start, &end,
176 NULL, NULL, &file, &debug) != name
179 printf ("module: %30s %08" PRIx64 "..%08" PRIx64 " %s %s\n",
180 name, start, end, file, debug);
185 print_module (Dwfl_Module *mod __attribute__ ((unused)),
186 void **userdata __attribute__ ((unused)),
187 const char *name, Dwarf_Addr base,
188 Dwarf *dw, Dwarf_Addr bias,
191 printf ("module: %30s %08" PRIx64 " %s %" PRIx64 " (%s)\n",
192 name, base, dw == NULL ? "no" : "DWARF", bias, dwfl_errmsg (-1));
194 if (dw != NULL && *(const bool *) arg)
200 while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
203 struct info info = { dwarf_offdie (dw, off + cuhl, &die_mem), bias };
204 (void) dwarf_getfuncs (info.cudie, print_func, &info, 0);
213 static bool show_functions;
215 /* gettext helper macro. */
219 static const struct argp_option options[] =
221 { "functions", 'f', NULL, 0, N_("Additionally show function names"), 0 },
222 { "inlines", 'i', NULL, 0, N_("Show instances of inlined functions"), 0 },
223 { NULL, 0, NULL, 0, NULL, 0 }
227 parse_opt (int key, char *arg __attribute__ ((unused)),
228 struct argp_state *state __attribute__ ((unused)))
233 state->child_inputs[0] = state->input;
237 show_functions = true;
241 show_inlines = show_functions = true;
245 return ARGP_ERR_UNKNOWN;
251 main (int argc, char **argv)
253 /* We use no threads here which can interfere with handling a stream. */
254 (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
257 (void) setlocale (LC_ALL, "");
260 const struct argp_child argp_children[] =
262 { .argp = dwfl_standard_argp () },
265 const struct argp argp =
267 options, parse_opt, NULL, NULL, argp_children, NULL, NULL
269 (void) argp_parse (&argp, argc, argv, 0, NULL, &dwfl);
270 assert (dwfl != NULL);
274 p = dwfl_getmodules (dwfl, &list_module, NULL, p);
277 error (2, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));
280 p = dwfl_getdwarf (dwfl, &print_module, &show_functions, p);
283 error (2, 0, "dwfl_getdwarf: %s", dwfl_errmsg (-1));
287 p = dwfl_getmodules (dwfl, &list_module, NULL, p);
290 error (2, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));