1 /* Simple test program for loc2c code. */
14 #include <elfutils/libdwfl.h>
15 #ifdef HAVE_ELFUTILS_VERSION_H
16 #include <elfutils/version.h>
24 #if !defined(_ELFUTILS_PREREQ)
25 // make a dummy PREREQ check for elfutils < 0.138
26 #define _ELFUTILS_PREREQ(major, minor) (0 >= 1)
31 static void __attribute__ ((noreturn
))
32 fail (void *arg
__attribute__ ((unused
)), const char *fmt
, ...)
36 fprintf (stderr
, "%s: ", program_invocation_short_name
);
39 vfprintf (stderr
, _(fmt
), ap
);
42 fprintf (stderr
, "\n");
47 static const Dwarf_Op
*
48 get_location (Dwarf_Addr dwbias
, Dwarf_Addr pc
, Dwarf_Attribute
*loc_attr
,
53 switch (dwarf_getlocation_addr (loc_attr
, pc
- dwbias
, &expr
, len
, 1))
55 case 1: /* Should always happen. */
60 default: /* Shouldn't happen. */
62 fail (NULL
, _("dwarf_getlocation_addr (form %#x): %s"),
63 dwarf_whatform (loc_attr
), dwarf_errmsg (-1));
66 case 0: /* Shouldn't happen. */
68 fail (NULL
, _("not accessible at this address"));
76 handle_variable (Dwarf_Die
*lscopes
, int lnscopes
, int out
,
77 Dwarf_Addr cubias
, Dwarf_Die
*vardie
, Dwarf_Addr pc
,
78 Dwarf_Op
*cfa_ops
, char **fields
)
80 #define obstack_chunk_alloc malloc
81 #define obstack_chunk_free free
85 /* Figure out the appropriate frame base for accessing this variable.
86 * XXX not handling nested functions
88 Dwarf_Attribute fb_attr_mem
, *fb_attr
= NULL
;
90 /* We start out walking the "lexical scopes" as returned by
91 * as returned by dwarf_getscopes for the address, starting with the
92 * 'out' scope that the variable was found in.
94 Dwarf_Die
*scopes
= lscopes
;
95 int nscopes
= lnscopes
;
96 for (inner
= out
; inner
< nscopes
&& fb_attr
== NULL
; ++inner
)
98 switch (dwarf_tag (&scopes
[inner
]))
102 case DW_TAG_subprogram
:
103 case DW_TAG_entry_point
:
104 fb_attr
= dwarf_attr_integrate (&scopes
[inner
],
108 case DW_TAG_inlined_subroutine
:
109 /* Unless we already are going through the "pyshical die tree",
110 * we now need to start walking the die tree where this
111 * subroutine is inlined to find the appropriate frame base. */
114 nscopes
= dwarf_getscopes_die (&scopes
[inner
], &scopes
);
116 error (2, 0, _("cannot get die scopes inlined_subroutine: %s"),
118 inner
= 0; // zero is current scope, for look will increase.
125 struct location
*head
, *tail
= NULL
;
127 Dwarf_Attribute attr_mem
;
128 if (dwarf_attr_integrate (vardie
, DW_AT_const_value
, &attr_mem
) != NULL
)
129 /* There is no location expression, but a constant value instead. */
130 head
= tail
= c_translate_constant (&pool
, &fail
, NULL
, NULL
,
131 1, cubias
, &attr_mem
);
135 if (dwarf_attr_integrate (vardie
, DW_AT_location
, &attr_mem
) == NULL
)
136 error (2, 0, _("cannot get location of variable: %s"),
140 const Dwarf_Op
*locexpr
= get_location (cubias
, pc
,
141 &attr_mem
, &locexpr_len
);
143 head
= c_translate_location (&pool
, &fail
, NULL
, NULL
,
144 1, cubias
, pc
, &attr_mem
,
145 locexpr
, locexpr_len
,
146 &tail
, fb_attr
, cfa_ops
);
149 if (dwarf_attr_integrate (vardie
, DW_AT_type
, &attr_mem
) == NULL
)
150 error (2, 0, _("cannot get type of variable: %s"),
154 Dwarf_Die die_mem
, *die
= vardie
;
155 while (*fields
!= NULL
)
157 if (!strcmp (*fields
, "="))
160 if (fields
[1] != NULL
)
161 error (2, 0, _("extra fields after ="));
165 die
= dwarf_formref_die (&attr_mem
, &die_mem
);
167 const int typetag
= dwarf_tag (die
);
171 case DW_TAG_const_type
:
172 case DW_TAG_volatile_type
:
173 /* Just iterate on the referent type. */
176 case DW_TAG_pointer_type
:
179 /* A "" field means explicit pointer dereference and we consume it.
180 Otherwise the next field implicitly gets the dereference. */
181 if (**fields
== '\0')
183 c_translate_pointer (&pool
, 1, cubias
, die
, &tail
);
186 case DW_TAG_array_type
:
190 char *endp
= *fields
+ 1;
191 uintmax_t idx
= strtoumax (*fields
+ 1, &endp
, 0);
192 if (endp
== NULL
|| endp
== *fields
|| *endp
!= '\0')
193 c_translate_array (&pool
, 1, cubias
, die
, &tail
,
196 c_translate_array (&pool
, 1, cubias
, die
, &tail
,
201 error (2, 0, _("bad field for array type: %s"), *fields
);
204 case DW_TAG_structure_type
:
205 case DW_TAG_union_type
:
206 switch (dwarf_child (die
, &die_mem
))
208 case 1: /* No children. */
209 error (2, 0, _("empty struct %s"),
210 dwarf_diename (die
) ?: "<anonymous>");
212 case -1: /* Error. */
213 default: /* Shouldn't happen */
214 error (2, 0, _("%s %s: %s"),
215 typetag
== DW_TAG_union_type
? "union" : "struct",
216 dwarf_diename (die
) ?: "<anonymous>",
223 while (dwarf_tag (die
) != DW_TAG_member
224 || ({ const char *member
= dwarf_diename (die
);
225 member
== NULL
|| strcmp (member
, *fields
); }))
226 if (dwarf_siblingof (die
, &die_mem
) != 0)
227 error (2, 0, _("field name %s not found"), *fields
);
229 if (dwarf_attr_integrate (die
, DW_AT_data_member_location
,
232 /* Union members don't usually have a location,
233 but just use the containing union's location. */
234 if (typetag
!= DW_TAG_union_type
)
235 error (2, 0, _("no location for field %s: %s"),
236 *fields
, dwarf_errmsg (-1));
240 /* We expect a block or a constant. In older elfutils,
241 dwarf_getlocation_addr would not handle the constant for
242 us, but newer ones do. For older ones, we work around
243 it by faking an expression, which is what newer ones do. */
244 #if !_ELFUTILS_PREREQ (0,142)
245 Dwarf_Op offset_loc
= { .atom
= DW_OP_plus_uconst
};
246 if (dwarf_formudata (&attr_mem
, &offset_loc
.number
) == 0)
247 c_translate_location (&pool
, NULL
, NULL
, NULL
,
248 1, cubias
, pc
, &attr_mem
,
255 const Dwarf_Op
*locexpr
= get_location (cubias
, pc
, &attr_mem
,
257 c_translate_location (&pool
, NULL
, NULL
, NULL
,
258 1, cubias
, pc
, &attr_mem
,
259 locexpr
, locexpr_len
,
266 case DW_TAG_base_type
:
267 error (2, 0, _("field %s vs base type %s"),
268 *fields
, dwarf_diename (die
) ?: "<anonymous type>");
272 error (2, 0, _("cannot find type: %s"), dwarf_errmsg (-1));
276 error (2, 0, _("%s: unexpected type tag %#x"),
277 dwarf_diename (die
) ?: "<anonymous type>",
282 /* Now iterate on the type in DIE's attribute. */
283 if (dwarf_attr_integrate (die
, DW_AT_type
, &attr_mem
) == NULL
)
284 error (2, 0, _("cannot get type of field: %s"), dwarf_errmsg (-1));
287 /* Fetch the type DIE corresponding to the final location to be accessed.
288 It must be a base type or a typedef for one. */
290 Dwarf_Die typedie_mem
;
295 typedie
= dwarf_formref_die (&attr_mem
, &typedie_mem
);
297 error (2, 0, _("cannot get type of field: %s"), dwarf_errmsg (-1));
298 typetag
= dwarf_tag (typedie
);
299 if (typetag
!= DW_TAG_typedef
&&
300 typetag
!= DW_TAG_const_type
&&
301 typetag
!= DW_TAG_volatile_type
)
303 if (dwarf_attr_integrate (typedie
, DW_AT_type
, &attr_mem
) == NULL
)
304 error (2, 0, _("cannot get type of field: %s"), dwarf_errmsg (-1));
309 case DW_TAG_base_type
:
311 c_translate_store (&pool
, 1, cubias
, die
, typedie
, &tail
, "value");
313 c_translate_fetch (&pool
, 1, cubias
, die
, typedie
, &tail
, "value");
316 case DW_TAG_pointer_type
:
317 case DW_TAG_reference_type
:
319 error (2, 0, _("store not supported for pointer type"));
320 c_translate_pointer (&pool
, 1, cubias
, typedie
, &tail
);
321 c_translate_addressof (&pool
, 1, cubias
, die
, typedie
, &tail
, "value");
326 error (2, 0, _("store supported only for base type"));
328 error (2, 0, _("fetch supported only for base type or pointer"));
332 printf ("#define PROBEADDR %#" PRIx64
"ULL\n", pc
);
335 ? "static void set_value(struct pt_regs *regs, intptr_t value)\n{"
336 : "static void print_value(struct pt_regs *regs)\n"
340 unsigned int stack_depth
;
341 bool deref
= c_emit_location (stdout
, head
, 1, &stack_depth
);
343 obstack_free (&pool
, NULL
);
345 printf (" /* max expression stack depth %u */\n", stack_depth
);
347 puts (store
? " return;" :
348 " printk (\" ---> %ld\\n\", (unsigned long) value);\n"
354 " printk (\" => BAD ACCESS\\n\");");
360 paddr (const char *prefix
, Dwarf_Addr addr
, Dwfl_Line
*line
)
365 && (src
= dwfl_lineinfo (line
, &addr
, &lineno
, &linecol
,
366 NULL
, NULL
)) != NULL
)
369 printf ("%s%#" PRIx64
" (%s:%d:%d)",
370 prefix
, addr
, src
, lineno
, linecol
);
372 printf ("%s%#" PRIx64
" (%s:%d)",
373 prefix
, addr
, src
, lineno
);
376 printf ("%s%#" PRIx64
, prefix
, addr
);
380 print_type (Dwarf_Die
*typedie
, char space
)
383 printf ("%c<no type>", space
);
386 const char *name
= dwarf_diename (typedie
);
388 printf ("%c%s", space
, name
);
391 Dwarf_Attribute attr_mem
;
393 Dwarf_Die
*die
= dwarf_formref_die
394 (dwarf_attr_integrate (typedie
, DW_AT_type
, &attr_mem
), &die_mem
);
395 int tag
= dwarf_tag (typedie
);
398 case DW_TAG_pointer_type
:
399 print_type (die
, space
);
402 case DW_TAG_array_type
:
403 print_type (die
, space
);
406 case DW_TAG_const_type
:
407 print_type (die
, space
);
410 case DW_TAG_volatile_type
:
411 print_type (die
, space
);
412 printf (" volatile");
415 printf ("%c<unknown %#x>", space
, tag
);
423 print_vars (unsigned int indent
, Dwarf_Die
*die
)
426 Dwarf_Attribute attr_mem
;
427 Dwarf_Die typedie_mem
;
429 if (dwarf_child (die
, &child
) == 0)
431 switch (dwarf_tag (&child
))
433 case DW_TAG_variable
:
434 case DW_TAG_formal_parameter
:
435 printf ("%*s%-30s[%6" PRIx64
"]", indent
, "",
436 dwarf_diename (&child
),
437 (uint64_t) dwarf_dieoffset (&child
));
438 typedie
= dwarf_formref_die
439 (dwarf_attr_integrate (&child
, DW_AT_type
, &attr_mem
),
441 print_type (typedie
, '\t');
447 while (dwarf_siblingof (&child
, &child
) == 0);
453 main (int argc
, char **argv
)
455 /* We use no threads here which can interfere with handling a stream. */
456 (void) __fsetlocking (stdout
, FSETLOCKING_BYCALLER
);
459 (void) setlocale (LC_ALL
, "");
463 (void) argp_parse (dwfl_standard_argp (), argc
, argv
, 0, &argi
, &dwfl
);
464 assert (dwfl
!= NULL
);
467 error (2, 0, "need address argument");
470 uintmax_t pc
= strtoumax (argv
[argi
], &endp
, 0);
471 if (endp
== argv
[argi
])
472 error (2, 0, "bad address argument");
475 Dwarf_Die
*cudie
= dwfl_addrdie (dwfl
, pc
, &cubias
);
477 error (EXIT_FAILURE
, 0, "dwfl_addrdie: %s", dwfl_errmsg (-1));
480 int n
= dwarf_getscopes (cudie
, pc
- cubias
, &scopes
);
482 error (EXIT_FAILURE
, 0, "dwarf_getscopes: %s", dwarf_errmsg (-1));
484 error (EXIT_FAILURE
, 0, "%#" PRIx64
": not in any scope\n", pc
);
488 unsigned int indent
= 0;
491 Dwarf_Die
*const die
= &scopes
[n
];
494 printf ("%*s[%6" PRIx64
"] %s (%#x)", indent
, "",
495 dwarf_dieoffset (die
),
496 dwarf_diename (die
) ?: "<unnamed>",
499 Dwarf_Addr lowpc
, highpc
;
500 if (dwarf_lowpc (die
, &lowpc
) == 0
501 && dwarf_highpc (die
, &highpc
) == 0)
505 Dwfl_Line
*loline
= dwfl_getsrc (dwfl
, lowpc
);
506 Dwfl_Line
*hiline
= dwfl_getsrc (dwfl
, highpc
);
507 paddr (": ", lowpc
, loline
);
509 paddr (" .. ", lowpc
, hiline
== loline
? NULL
: hiline
);
513 print_vars (indent
+ INDENT
, die
);
518 char *spec
= argv
[argi
++];
520 int lineno
= 0, colno
= 0, shadow
= 0;
521 char *at
= strchr (spec
, '@');
525 if (sscanf (at
, "%*[^:]:%i:%i", &lineno
, &colno
) < 1)
531 if (sscanf (spec
, "%*[^+]%n+%i", &len
, &shadow
) == 2)
536 int out
= dwarf_getscopevar (scopes
, n
, spec
, shadow
, at
, lineno
, colno
,
539 error (0, 0, "no match for %s (+%d, %s:%d:%d)",
540 spec
, shadow
, at
, lineno
, colno
);
542 error (0, 0, "dwarf_getscopevar: %s (+%d, %s:%d:%d): %s",
543 spec
, shadow
, at
, lineno
, colno
, dwarf_errmsg (-1));
546 Dwarf_Op
*cfa_ops
= NULL
;
548 #if _ELFUTILS_PREREQ(0,142)
551 Dwfl_Module
*module
= dwfl_addrmodule (dwfl
, pc
);
554 // Try debug_frame first, then fall back on eh_frame.
555 Dwarf_CFI
*cfi
= dwfl_module_dwarf_cfi (module
, &bias
);
558 Dwarf_Frame
*frame
= NULL
;
559 if (dwarf_cfi_addrframe (cfi
, pc
- bias
, &frame
) == 0)
560 dwarf_frame_cfa (frame
, &cfa_ops
, &cfa_nops
);
564 cfi
= dwfl_module_eh_cfi (module
, &bias
);
567 Dwarf_Frame
*frame
= NULL
;
568 if (dwarf_cfi_addrframe (cfi
, pc
- bias
, &frame
) == 0)
569 dwarf_frame_cfa (frame
, &cfa_ops
, &cfa_nops
);
575 handle_variable (scopes
, n
, out
, cubias
, &vardie
, pc
, cfa_ops
,
587 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */