blob: 7e454e472860f428d6f5bf6e8bd517dae032d27e [file] [log] [blame]
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00001/* Test program for libdwfl basic module tracking, relocation.
2 Copyright (C) 2005 Red Hat, Inc.
Ulrich Drepper361df7d2006-04-04 21:38:57 +00003 This file is part of Red Hat elfutils.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00004
Ulrich Drepper361df7d2006-04-04 21:38:57 +00005 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.
Ulrich Drepperb08d5a82005-07-26 05:00:05 +00008
Ulrich Drepper361df7d2006-04-04 21:38:57 +00009 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.
13
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,
Ulrich Drepper1e9ef502006-04-04 22:29:06 +000016 Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
Ulrich Drepper361df7d2006-04-04 21:38:57 +000017
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>. */
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000025
26#include <config.h>
27#include <assert.h>
28#include <inttypes.h>
29#include <sys/types.h>
30#include <stdio.h>
31#include <stdio_ext.h>
32#include <stdlib.h>
33#include <string.h>
34#include <error.h>
35#include <locale.h>
36#include <argp.h>
Roland McGrathd7f8d0c2005-11-17 02:32:03 +000037#include ELFUTILS_HEADER(dwfl)
Roland McGrath1ecb6062005-08-15 09:53:04 +000038#include <dwarf.h>
Ulrich Drepperb08d5a82005-07-26 05:00:05 +000039
Roland McGrath1ecb6062005-08-15 09:53:04 +000040static bool show_inlines;
41
42struct info
43{
44 Dwarf_Die *cudie;
45 Dwarf_Addr dwbias;
46};
47
48static int
49print_instance (Dwarf_Die *instance, void *arg)
50{
51 const struct info *info = arg;
52
53 printf (" inlined");
54
55 Dwarf_Files *files;
56 if (dwarf_getsrcfiles (info->cudie, &files, NULL) == 0)
57 {
58 Dwarf_Attribute attr_mem;
59 Dwarf_Word val;
60 if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_file,
61 &attr_mem), &val) == 0)
62 {
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)
67 lineno = val;
68 if (dwarf_formudata (dwarf_attr (instance, DW_AT_call_column,
69 &attr_mem), &val) == 0)
70 colno = val;
71 if (lineno == 0)
72 {
73 if (file != NULL)
74 printf (" from %s", file);
75 }
76 else if (colno == 0)
77 printf (" at %s:%u", file, lineno);
78 else
79 printf (" at %s:%u:%u", file, lineno, colno);
80 }
81 }
82
83 Dwarf_Addr lo = -1, hi = -1, entry = -1;
84 if (dwarf_lowpc (instance, &lo) == 0)
85 lo += info->dwbias;
86 else
87 printf (" (lowpc => %s)", dwarf_errmsg (-1));
88 if (dwarf_highpc (instance, &hi) == 0)
89 hi += info->dwbias;
90 else
91 printf (" (highpc => %s)", dwarf_errmsg (-1));
92
93 Dwarf_Attribute attr_mem;
Roland McGrathd7f8d0c2005-11-17 02:32:03 +000094 Dwarf_Attribute *attr = dwarf_attr (instance, DW_AT_entry_pc, &attr_mem);
Roland McGrath1ecb6062005-08-15 09:53:04 +000095 if (attr != NULL)
96 {
Roland McGrathd7f8d0c2005-11-17 02:32:03 +000097 if (dwarf_formaddr (attr, &entry) == 0)
Roland McGrath1ecb6062005-08-15 09:53:04 +000098 entry += info->dwbias;
99 else
100 printf (" (entrypc => %s)", dwarf_errmsg (-1));
101 }
102
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);
107 else
108 puts ("");
109
110 return DWARF_CB_OK;
111}
112
113static void
Roland McGrath6724c902005-10-28 07:07:19 +0000114print_inline (Dwarf_Die *func, void *arg)
Roland McGrath1ecb6062005-08-15 09:53:04 +0000115{
116 if (dwarf_func_inline_instances (func, &print_instance, arg) != 0)
117 printf (" error finding instances: %s\n", dwarf_errmsg (-1));
118}
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000119
120static int
Roland McGrath6724c902005-10-28 07:07:19 +0000121print_func (Dwarf_Die *func, void *arg)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000122{
Roland McGrath1ecb6062005-08-15 09:53:04 +0000123 const struct info *info = arg;
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000124
Roland McGrath6724c902005-10-28 07:07:19 +0000125 const char *file = dwarf_decl_file (func);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000126 int line = -1;
Roland McGrath6724c902005-10-28 07:07:19 +0000127 dwarf_decl_line (func, &line);
128 const char *fct = dwarf_diename (func);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000129
130 printf (" %s:%d: %s:", file, line, fct);
131
Roland McGrath1ecb6062005-08-15 09:53:04 +0000132 if (dwarf_func_inline (func))
133 {
134 puts (" inline function");
135 if (show_inlines)
136 print_inline (func, arg);
137 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000138 else
Roland McGrath1ecb6062005-08-15 09:53:04 +0000139 {
140 Dwarf_Addr lo = -1, hi = -1, entry = -1;
Roland McGrath6724c902005-10-28 07:07:19 +0000141 if (dwarf_lowpc (func, &lo) == 0)
Roland McGrath1ecb6062005-08-15 09:53:04 +0000142 lo += info->dwbias;
143 else
144 printf (" (lowpc => %s)", dwarf_errmsg (-1));
Roland McGrath6724c902005-10-28 07:07:19 +0000145 if (dwarf_highpc (func, &hi) == 0)
Roland McGrath1ecb6062005-08-15 09:53:04 +0000146 hi += info->dwbias;
147 else
148 printf (" (highpc => %s)", dwarf_errmsg (-1));
Roland McGrath6724c902005-10-28 07:07:19 +0000149 if (dwarf_entrypc (func, &entry) == 0)
Roland McGrath1ecb6062005-08-15 09:53:04 +0000150 entry += info->dwbias;
151 else
152 printf (" (entrypc => %s)", dwarf_errmsg (-1));
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000153
Roland McGrath1ecb6062005-08-15 09:53:04 +0000154 if (lo != (Dwarf_Addr) -1 || hi != (Dwarf_Addr) -1
155 || entry != (Dwarf_Addr) -1)
156 printf (" %#" PRIx64 "..%#" PRIx64 " => %#" PRIx64 "\n",
157 lo, hi, entry);
158 else
159 puts ("");
160 }
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000161
162 return DWARF_CB_OK;
163}
164
165static int
166print_module (Dwfl_Module *mod __attribute__ ((unused)),
167 void **userdata __attribute__ ((unused)),
168 const char *name, Dwarf_Addr base,
169 Dwarf *dw, Dwarf_Addr bias,
Roland McGrath8d18c292005-08-07 21:42:07 +0000170 void *arg)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000171{
172 printf ("module: %30s %08" PRIx64 " %12p %" PRIx64 " (%s)\n",
173 name, base, dw, bias, dwfl_errmsg (-1));
174
Roland McGrath8d18c292005-08-07 21:42:07 +0000175 if (dw != NULL && *(const bool *) arg)
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000176 {
177 Dwarf_Off off = 0;
178 size_t cuhl;
179 Dwarf_Off noff;
180
181 while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
182 {
183 Dwarf_Die die_mem;
Roland McGrath1ecb6062005-08-15 09:53:04 +0000184 struct info info = { dwarf_offdie (dw, off + cuhl, &die_mem), bias };
185 (void) dwarf_getfuncs (info.cudie, print_func, &info, 0);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000186
187 off = noff;
188 }
189 }
190
191 return DWARF_CB_OK;
192}
193
Roland McGrath8d18c292005-08-07 21:42:07 +0000194static bool show_functions;
195
Roland McGrathd7f8d0c2005-11-17 02:32:03 +0000196/* gettext helper macro. */
197#undef N_
198#define N_(Str) Str
199
Roland McGrath8d18c292005-08-07 21:42:07 +0000200static const struct argp_option options[] =
201 {
Roland McGrath1ecb6062005-08-15 09:53:04 +0000202 { "functions", 'f', NULL, 0, N_("Additionally show function names"), 0 },
203 { "inlines", 'i', NULL, 0, N_("Show instances of inlined functions"), 0 },
Roland McGrath8d18c292005-08-07 21:42:07 +0000204 { NULL, 0, NULL, 0, NULL, 0 }
205 };
206
207static error_t
208parse_opt (int key, char *arg __attribute__ ((unused)),
209 struct argp_state *state __attribute__ ((unused)))
210{
211 switch (key)
212 {
213 case ARGP_KEY_INIT:
214 state->child_inputs[0] = state->input;
215 break;
216
217 case 'f':
218 show_functions = true;
219 break;
220
Roland McGrath1ecb6062005-08-15 09:53:04 +0000221 case 'i':
222 show_inlines = show_functions = true;
223 break;
224
Roland McGrath8d18c292005-08-07 21:42:07 +0000225 default:
226 return ARGP_ERR_UNKNOWN;
227 }
228 return 0;
229}
230
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000231int
232main (int argc, char **argv)
233{
234 /* We use no threads here which can interfere with handling a stream. */
235 (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
236
237 /* Set locale. */
238 (void) setlocale (LC_ALL, "");
239
240 Dwfl *dwfl = NULL;
Roland McGrath8d18c292005-08-07 21:42:07 +0000241 const struct argp_child argp_children[] =
242 {
243 { .argp = dwfl_standard_argp () },
244 { .argp = NULL }
245 };
246 const struct argp argp =
247 {
248 options, parse_opt, NULL, NULL, argp_children, NULL, NULL
249 };
250 (void) argp_parse (&argp, argc, argv, 0, NULL, &dwfl);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000251 assert (dwfl != NULL);
252
253 ptrdiff_t p = 0;
254 do
Roland McGrath8d18c292005-08-07 21:42:07 +0000255 p = dwfl_getdwarf (dwfl, &print_module, &show_functions, p);
Ulrich Drepperb08d5a82005-07-26 05:00:05 +0000256 while (p > 0);
257 if (p < 0)
258 error (2, 0, "dwfl_getdwarf: %s", dwfl_errmsg (-1));
259
260 dwfl_end (dwfl);
261
262 return 0;
263}