1 /* Test program for libdwfl basic module tracking, relocation.
2 Copyright (C) 2005, 2007 Red Hat, Inc.
3 This file is part of elfutils.
5 This file is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 elfutils is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
21 #include <sys/types.h>
23 #include <stdio_ext.h>
29 #include ELFUTILS_HEADER(dwfl)
32 static bool show_inlines;
41 print_instance (Dwarf_Die *instance, void *arg)
43 const struct info *info = arg;
48 if (dwarf_getsrcfiles (info->cudie, &files, NULL) == 0)
50 Dwarf_Attribute attr_mem;
52 if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_file,
53 &attr_mem), &val) == 0)
55 const char *file = dwarf_filesrc (files, val, NULL, NULL);
56 int lineno = 0, colno = 0;
57 if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_line,
58 &attr_mem), &val) == 0)
60 if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_column,
61 &attr_mem), &val) == 0)
66 printf (" from %s", file);
69 printf (" at %s:%u", file, lineno);
71 printf (" at %s:%u:%u", file, lineno, colno);
75 Dwarf_Addr lo = -1, hi = -1, entry = -1;
76 if (dwarf_lowpc (instance, &lo) == 0)
79 printf (" (lowpc => %s)", dwarf_errmsg (-1));
80 if (dwarf_highpc (instance, &hi) == 0)
83 printf (" (highpc => %s)", dwarf_errmsg (-1));
85 Dwarf_Attribute attr_mem;
86 Dwarf_Attribute *attr = dwarf_attr (instance, DW_AT_entry_pc, &attr_mem);
89 if (dwarf_formaddr (attr, &entry) == 0)
90 entry += info->dwbias;
92 printf (" (entrypc => %s)", dwarf_errmsg (-1));
95 if (lo != (Dwarf_Addr) -1 || hi != (Dwarf_Addr) -1)
96 printf (" %#" PRIx64 "..%#" PRIx64, lo, hi);
97 if (entry != (Dwarf_Addr) -1)
98 printf (" => %#" PRIx64 "\n", entry);
106 print_inline (Dwarf_Die *func, void *arg)
108 if (dwarf_func_inline_instances (func, &print_instance, arg) != 0)
109 printf (" error finding instances: %s\n", dwarf_errmsg (-1));
113 print_func (Dwarf_Die *func, void *arg)
115 const struct info *info = arg;
117 const char *file = dwarf_decl_file (func);
119 dwarf_decl_line (func, &line);
120 const char *fct = dwarf_diename (func);
122 printf (" %s:%d: %s:", file, line, fct);
124 if (dwarf_func_inline (func))
126 puts (" inline function");
128 print_inline (func, arg);
132 Dwarf_Addr lo = -1, hi = -1, entry = -1;
133 if (dwarf_lowpc (func, &lo) == 0)
136 printf (" (lowpc => %s)", dwarf_errmsg (-1));
137 if (dwarf_highpc (func, &hi) == 0)
140 printf (" (highpc => %s)", dwarf_errmsg (-1));
141 if (dwarf_entrypc (func, &entry) == 0)
142 entry += info->dwbias;
144 printf (" (entrypc => %s)", dwarf_errmsg (-1));
146 if (lo != (Dwarf_Addr) -1 || hi != (Dwarf_Addr) -1
147 || entry != (Dwarf_Addr) -1)
148 printf (" %#" PRIx64 "..%#" PRIx64 " => %#" PRIx64 "\n",
158 list_module (Dwfl_Module *mod __attribute__ ((unused)),
159 void **userdata __attribute__ ((unused)),
160 const char *name, Dwarf_Addr base,
161 void *arg __attribute__ ((unused)))
167 if (dwfl_module_info (mod, NULL, &start, &end,
168 NULL, NULL, &file, &debug) != name
171 printf ("module: %30s %08" PRIx64 "..%08" PRIx64 " %s %s\n",
172 name, start, end, file, debug);
177 print_module (Dwfl_Module *mod __attribute__ ((unused)),
178 void **userdata __attribute__ ((unused)),
179 const char *name, Dwarf_Addr base,
180 Dwarf *dw, Dwarf_Addr bias,
183 printf ("module: %30s %08" PRIx64 " %s %" PRIx64 " (%s)\n",
184 name, base, dw == NULL ? "no" : "DWARF", bias, dwfl_errmsg (-1));
186 if (dw != NULL && *(const bool *) arg)
192 while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
195 struct info info = { dwarf_offdie (dw, off + cuhl, &die_mem), bias };
196 (void) dwarf_getfuncs (info.cudie, print_func, &info, 0);
205 static bool show_functions;
207 /* gettext helper macro. */
211 static const struct argp_option options[] =
213 { "functions", 'f', NULL, 0, N_("Additionally show function names"), 0 },
214 { "inlines", 'i', NULL, 0, N_("Show instances of inlined functions"), 0 },
215 { NULL, 0, NULL, 0, NULL, 0 }
219 parse_opt (int key, char *arg __attribute__ ((unused)),
220 struct argp_state *state __attribute__ ((unused)))
225 state->child_inputs[0] = state->input;
229 show_functions = true;
233 show_inlines = show_functions = true;
237 return ARGP_ERR_UNKNOWN;
243 main (int argc, char **argv)
245 /* We use no threads here which can interfere with handling a stream. */
246 (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
249 (void) setlocale (LC_ALL, "");
252 const struct argp_child argp_children[] =
254 { .argp = dwfl_standard_argp () },
257 const struct argp argp =
259 options, parse_opt, NULL, NULL, argp_children, NULL, NULL
261 (void) argp_parse (&argp, argc, argv, 0, NULL, &dwfl);
262 assert (dwfl != NULL);
266 p = dwfl_getmodules (dwfl, &list_module, NULL, p);
269 error (2, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));
272 p = dwfl_getdwarf (dwfl, &print_module, &show_functions, p);
275 error (2, 0, "dwfl_getdwarf: %s", dwfl_errmsg (-1));
279 p = dwfl_getmodules (dwfl, &list_module, NULL, p);
282 error (2, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));