]> sourceware.org Git - systemtap.git/blame - dwflpp.cxx
Logger PMDA can now handle multiple clients.
[systemtap.git] / dwflpp.cxx
CommitLineData
440f755a 1// C++ interface to dwfl
fea74777 2// Copyright (C) 2005-2010 Red Hat Inc.
440f755a
JS
3// Copyright (C) 2005-2007 Intel Corporation.
4// Copyright (C) 2008 James.Bottomley@HansenPartnership.com
5//
6// This file is part of systemtap, and is free software. You can
7// redistribute it and/or modify it under the terms of the GNU General
8// Public License (GPL); either version 2, or (at your option) any
9// later version.
10
11#include "dwflpp.h"
12#include "config.h"
13#include "staptree.h"
14#include "elaborate.h"
15#include "tapsets.h"
16#include "task_finder.h"
17#include "translate.h"
18#include "session.h"
19#include "util.h"
20#include "buildrun.h"
21#include "dwarf_wrappers.h"
22#include "auto_free.h"
23#include "hash.h"
2ed04863 24#include "rpm_finder.h"
3db9c843 25#include "setupdwfl.h"
440f755a
JS
26
27#include <cstdlib>
28#include <algorithm>
29#include <deque>
30#include <iostream>
31#include <map>
440f755a
JS
32#include <set>
33#include <sstream>
34#include <stdexcept>
35#include <vector>
36#include <cstdarg>
37#include <cassert>
38#include <iomanip>
39#include <cerrno>
40
41extern "C" {
42#include <fcntl.h>
43#include <elfutils/libdwfl.h>
44#include <elfutils/libdw.h>
45#include <dwarf.h>
46#include <elf.h>
47#include <obstack.h>
48#include <regex.h>
49#include <glob.h>
50#include <fnmatch.h>
51#include <stdio.h>
52#include <sys/types.h>
53
54#include "loc2c.h"
55#define __STDC_FORMAT_MACROS
56#include <inttypes.h>
57}
58
59
9aa8ffce
JS
60// debug flag to compare to the uncached version from libdw
61// #define DEBUG_DWFLPP_GETSCOPES 1
62
63
440f755a
JS
64using namespace std;
65using namespace __gnu_cxx;
66
67
68static string TOK_KERNEL("kernel");
69
70
ae2552da 71dwflpp::dwflpp(systemtap_session & session, const string& name, bool kernel_p):
d0b4a5ff 72 sess(session), module(NULL), module_bias(0), mod_info(NULL),
68983551 73 module_start(0), module_end(0), cu(NULL),
729455a7 74 module_dwarf(NULL), function(NULL), blacklist_enabled(false)
440f755a 75{
ae2552da
FCE
76 if (kernel_p)
77 setup_kernel(name);
440f755a 78 else
0c16d512
JS
79 {
80 vector<string> modules;
81 modules.push_back(name);
82 setup_user(modules);
83 }
84}
85
59c11f91
MW
86dwflpp::dwflpp(systemtap_session & session, const vector<string>& names,
87 bool kernel_p):
0c16d512 88 sess(session), module(NULL), module_bias(0), mod_info(NULL),
68983551 89 module_start(0), module_end(0), cu(NULL),
729455a7 90 module_dwarf(NULL), function(NULL), blacklist_enabled(false)
0c16d512 91{
59c11f91
MW
92 if (kernel_p)
93 setup_kernel(names);
94 else
95 setup_user(names);
440f755a
JS
96}
97
440f755a
JS
98dwflpp::~dwflpp()
99{
c9efa5c9
JS
100 delete_map(module_cu_cache);
101 delete_map(cu_function_cache);
4df79aaf 102 delete_map(mod_function_cache);
c9efa5c9
JS
103 delete_map(cu_inl_function_cache);
104 delete_map(global_alias_cache);
105 delete_map(cu_die_parent_cache);
9aa8ffce 106
68983551 107 dwfl_ptr.reset();
435f53a7
FCE
108 // NB: don't "delete mod_info;", as that may be shared
109 // between dwflpp instances, and are stored in
110 // session.module_cache[] anyway.
111}
112
113
114module_cache::~module_cache ()
115{
116 delete_map(cache);
440f755a
JS
117}
118
119
440f755a
JS
120void
121dwflpp::get_module_dwarf(bool required, bool report)
122{
123 module_dwarf = dwfl_module_getdwarf(module, &module_bias);
124 mod_info->dwarf_status = (module_dwarf ? info_present : info_absent);
125 if (!module_dwarf && report)
126 {
f9bbd346 127 string msg = _("cannot find ");
440f755a
JS
128 if (module_name == "")
129 msg += "kernel";
130 else
131 msg += string("module ") + module_name;
132 msg += " debuginfo";
133
134 int i = dwfl_errno();
135 if (i)
136 msg += string(": ") + dwfl_errmsg (i);
137
2ed04863
WC
138 /* add module_name to list to find rpm */
139 find_debug_rpms(sess, module_name.c_str());
140
440f755a
JS
141 if (required)
142 throw semantic_error (msg);
83ca3872 143 else if (! sess.suppress_warnings)
f9bbd346 144 cerr << _("WARNING: ") << msg << "\n";
440f755a
JS
145 }
146}
147
148
149void
150dwflpp::focus_on_module(Dwfl_Module * m, module_info * mi)
151{
152 module = m;
153 mod_info = mi;
154 if (m)
155 {
f517ee24
JS
156 module_name = dwfl_module_info(module, NULL, &module_start, &module_end,
157 NULL, NULL, NULL, NULL) ?: "module";
440f755a
JS
158 }
159 else
160 {
161 assert(mi && mi->name && mi->name == TOK_KERNEL);
162 module_name = mi->name;
163 module_start = 0;
164 module_end = 0;
165 module_bias = mi->bias;
166 }
167
168 // Reset existing pointers and names
169
170 module_dwarf = NULL;
171
440f755a
JS
172 cu = NULL;
173
174 function_name.clear();
175 function = NULL;
176}
177
178
179void
180dwflpp::focus_on_cu(Dwarf_Die * c)
181{
182 assert(c);
183 assert(module);
184
185 cu = c;
440f755a
JS
186
187 // Reset existing pointers and names
188 function_name.clear();
189 function = NULL;
190}
191
192
54417494
JS
193string
194dwflpp::cu_name(void)
195{
196 return dwarf_diename(cu) ?: "<unknown source>";
197}
198
199
440f755a
JS
200void
201dwflpp::focus_on_function(Dwarf_Die * f)
202{
203 assert(f);
204 assert(module);
205 assert(cu);
206
207 function = f;
f517ee24 208 function_name = dwarf_diename(function) ?: "function";
440f755a
JS
209}
210
211
1f8592d1
MW
212/* Return the Dwarf_Die for the given address in the current module.
213 * The address should be in the module address address space (this
214 * function will take care of any dw bias).
215 */
1adf8ef1
JS
216Dwarf_Die *
217dwflpp::query_cu_containing_address(Dwarf_Addr a)
440f755a
JS
218{
219 Dwarf_Addr bias;
68983551 220 assert(dwfl_ptr.get()->dwfl);
b6fa229b 221 assert(module);
440f755a 222 get_module_dwarf();
b6fa229b 223
440f755a 224 Dwarf_Die* cudie = dwfl_module_addrdie(module, a, &bias);
440f755a 225 assert(bias == module_bias);
1adf8ef1 226 return cudie;
440f755a
JS
227}
228
229
440f755a 230bool
5f4c8c6e 231dwflpp::module_name_matches(const string& pattern)
440f755a
JS
232{
233 bool t = (fnmatch(pattern.c_str(), module_name.c_str(), 0) == 0);
234 if (t && sess.verbose>3)
f9bbd346
LB
235 clog << _F("pattern '%s' matches module '%s'\n",
236 pattern.c_str(), module_name.c_str());
440f755a
JS
237 return t;
238}
239
240
241bool
665e1256 242dwflpp::name_has_wildcard (const string& pattern)
440f755a
JS
243{
244 return (pattern.find('*') != string::npos ||
245 pattern.find('?') != string::npos ||
246 pattern.find('[') != string::npos);
247}
248
249
250bool
5f4c8c6e 251dwflpp::module_name_final_match(const string& pattern)
440f755a
JS
252{
253 // Assume module_name_matches(). Can there be any more matches?
254 // Not unless the pattern is a wildcard, since module names are
255 // presumed unique.
256 return !name_has_wildcard(pattern);
257}
258
259
260bool
5f4c8c6e 261dwflpp::function_name_matches_pattern(const string& name, const string& pattern)
440f755a
JS
262{
263 bool t = (fnmatch(pattern.c_str(), name.c_str(), 0) == 0);
264 if (t && sess.verbose>3)
f9bbd346 265 clog << _F("pattern '%s' matches function '%s'\n", pattern.c_str(), name.c_str());
440f755a
JS
266 return t;
267}
268
269
270bool
5f4c8c6e 271dwflpp::function_name_matches(const string& pattern)
440f755a
JS
272{
273 assert(function);
274 return function_name_matches_pattern(function_name, pattern);
275}
276
277
7d6d0afc 278bool
c646240d 279dwflpp::function_scope_matches(const vector<string>& scopes)
7d6d0afc
JS
280{
281 // walk up the containing scopes
282 Dwarf_Die* die = function;
283 for (int i = scopes.size() - 1; i >= 0; --i)
284 {
285 die = get_parent_scope(die);
286
287 // check if this scope matches, and prepend it if so
288 // NB: a NULL die is the global scope, compared as ""
289 string name = dwarf_diename(die) ?: "";
290 if (name_has_wildcard(scopes[i]) ?
291 function_name_matches_pattern(name, scopes[i]) :
292 name == scopes[i])
293 function_name = name + "::" + function_name;
294 else
295 return false;
296
297 // make sure there's no more if we're at the global scope
298 if (!die && i > 0)
299 return false;
300 }
301 return true;
302}
303
304
440f755a 305void
ae2552da 306dwflpp::setup_kernel(const string& name, bool debuginfo_needed)
440f755a 307{
440f755a
JS
308 if (! sess.module_cache)
309 sess.module_cache = new module_cache ();
310
3db9c843 311 unsigned offline_search_matches = 0;
68983551 312 dwfl_ptr = setup_dwfl_kernel(name, &offline_search_matches, sess);
440f755a 313
3db9c843 314 if (offline_search_matches < 1)
ae2552da
FCE
315 {
316 if (debuginfo_needed) {
317 // Suggest a likely kernel dir to find debuginfo rpm for
318 string dir = string("/lib/modules/" + sess.kernel_release );
319 find_debug_rpms(sess, dir.c_str());
320 }
f9bbd346
LB
321 throw semantic_error (_F("missing %s kernel/module debuginfo under '%s'",
322 sess.architecture.c_str(), sess.kernel_build_tree.c_str()));
209dd533 323 }
440f755a 324
27646582 325 build_blacklist();
440f755a
JS
326}
327
59c11f91
MW
328void
329dwflpp::setup_kernel(const vector<string> &names, bool debuginfo_needed)
330{
331 if (! sess.module_cache)
332 sess.module_cache = new module_cache ();
333
334 unsigned offline_search_matches = 0;
335 set<string> offline_search_names(names.begin(), names.end());
68983551
MW
336 dwfl_ptr = setup_dwfl_kernel(offline_search_names,
337 &offline_search_matches,
338 sess);
59c11f91
MW
339
340 if (offline_search_matches < offline_search_names.size())
341 {
342 if (debuginfo_needed) {
343 // Suggest a likely kernel dir to find debuginfo rpm for
344 string dir = string("/lib/modules/" + sess.kernel_release );
345 find_debug_rpms(sess, dir.c_str());
346 }
f9bbd346
LB
347 throw semantic_error (_F("missing %s kernel/module debuginfo under '%s'",
348 sess.architecture.c_str(), sess.kernel_build_tree.c_str()));
59c11f91
MW
349 }
350
351 build_blacklist();
352}
353
440f755a
JS
354
355void
0c16d512 356dwflpp::setup_user(const vector<string>& modules, bool debuginfo_needed)
440f755a
JS
357{
358 if (! sess.module_cache)
359 sess.module_cache = new module_cache ();
360
5f8ca04f 361 vector<string>::const_iterator it = modules.begin();
68983551 362 dwfl_ptr = setup_dwfl_user(it, modules.end(), debuginfo_needed);
5f8ca04f 363 if (debuginfo_needed && it != modules.end())
f9bbd346 364 dwfl_assert (string(_("missing process ")) +
5f8ca04f
MW
365 *it +
366 string(" ") +
367 sess.architecture +
368 string(" debuginfo"),
68983551 369 dwfl_ptr.get()->dwfl);
440f755a
JS
370}
371
440f755a
JS
372void
373dwflpp::iterate_over_modules(int (* callback)(Dwfl_Module *, void **,
374 const char *, Dwarf_Addr,
375 void *),
376 base_query *data)
377{
68983551 378 dwfl_getmodules (dwfl_ptr.get()->dwfl, callback, data, 0);
0e14e079 379
440f755a
JS
380 // Don't complain if we exited dwfl_getmodules early.
381 // This could be a $target variable error that will be
382 // reported soon anyway.
383 // dwfl_assert("dwfl_getmodules", off == 0);
384
385 // PR6864 XXX: For dwarfless case (if .../vmlinux is missing), then the
386 // "kernel" module is not reported in the loop above. However, we
387 // may be able to make do with symbol table data.
388}
389
390
440f755a
JS
391void
392dwflpp::iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg),
393 void * data)
394{
395 get_module_dwarf(false);
396 Dwarf *dw = module_dwarf;
397 if (!dw) return;
398
399 vector<Dwarf_Die>* v = module_cu_cache[dw];
400 if (v == 0)
401 {
402 v = new vector<Dwarf_Die>;
403 module_cu_cache[dw] = v;
404
405 Dwarf_Off off = 0;
406 size_t cuhl;
407 Dwarf_Off noff;
408 while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
409 {
85007c04 410 if (pending_interrupts) return;
440f755a
JS
411 Dwarf_Die die_mem;
412 Dwarf_Die *die;
413 die = dwarf_offdie (dw, off + cuhl, &die_mem);
414 v->push_back (*die); /* copy */
415 off = noff;
416 }
417 }
418
c1c5bb9a 419 for (vector<Dwarf_Die>::iterator i = v->begin(); i != v->end(); ++i)
440f755a 420 {
c1c5bb9a 421 int rc = (*callback)(&*i, data);
85007c04 422 if (rc != DWARF_CB_OK || pending_interrupts)
c1c5bb9a 423 break;
440f755a
JS
424 }
425}
426
427
428bool
429dwflpp::func_is_inline()
430{
431 assert (function);
432 return dwarf_func_inline (function) != 0;
433}
434
435
8d7a7bd9
JS
436void
437dwflpp::cache_inline_instances (Dwarf_Die* die)
440f755a 438{
8d7a7bd9
JS
439 // If this is an inline instance, link it back to its origin
440 Dwarf_Die origin;
441 if (dwarf_tag(die) == DW_TAG_inlined_subroutine &&
442 dwarf_attr_die(die, DW_AT_abstract_origin, &origin))
443 {
444 vector<Dwarf_Die>*& v = cu_inl_function_cache[origin.addr];
445 if (!v)
446 v = new vector<Dwarf_Die>;
447 v->push_back(*die);
448 }
449
450 // Recurse through other scopes that may contain inlines
451 Dwarf_Die child, import;
452 if (dwarf_child(die, &child) == 0)
453 do
454 {
455 switch (dwarf_tag (&child))
456 {
457 // tags that could contain inlines
458 case DW_TAG_compile_unit:
459 case DW_TAG_module:
460 case DW_TAG_lexical_block:
461 case DW_TAG_with_stmt:
462 case DW_TAG_catch_block:
463 case DW_TAG_try_block:
464 case DW_TAG_entry_point:
465 case DW_TAG_inlined_subroutine:
466 case DW_TAG_subprogram:
467 cache_inline_instances(&child);
468 break;
469
470 // imported dies should be followed
471 case DW_TAG_imported_unit:
472 if (dwarf_attr_die(&child, DW_AT_import, &import))
473 cache_inline_instances(&import);
474 break;
475
476 // nothing to do for other tags
477 default:
478 break;
479 }
480 }
481 while (dwarf_siblingof(&child, &child) == 0);
440f755a
JS
482}
483
484
485void
486dwflpp::iterate_over_inline_instances (int (* callback)(Dwarf_Die * die, void * arg),
487 void * data)
488{
489 assert (function);
490 assert (func_is_inline ());
491
8d7a7bd9
JS
492 if (cu_inl_function_cache_done.insert(cu->addr).second)
493 cache_inline_instances(cu);
494
d089f5b2 495 vector<Dwarf_Die>* v = cu_inl_function_cache[function->addr];
8d7a7bd9
JS
496 if (!v)
497 return;
440f755a 498
c1c5bb9a 499 for (vector<Dwarf_Die>::iterator i = v->begin(); i != v->end(); ++i)
440f755a 500 {
c1c5bb9a 501 int rc = (*callback)(&*i, data);
85007c04 502 if (rc != DWARF_CB_OK || pending_interrupts)
c1c5bb9a 503 break;
440f755a
JS
504 }
505}
506
507
9aa8ffce
JS
508void
509dwflpp::cache_die_parents(cu_die_parent_cache_t* parents, Dwarf_Die* die)
510{
511 // Record and recurse through DIEs we care about
512 Dwarf_Die child, import;
513 if (dwarf_child(die, &child) == 0)
514 do
515 {
516 switch (dwarf_tag (&child))
517 {
518 // normal tags to recurse
519 case DW_TAG_compile_unit:
520 case DW_TAG_module:
521 case DW_TAG_lexical_block:
522 case DW_TAG_with_stmt:
523 case DW_TAG_catch_block:
524 case DW_TAG_try_block:
525 case DW_TAG_entry_point:
526 case DW_TAG_inlined_subroutine:
527 case DW_TAG_subprogram:
7d6d0afc
JS
528 case DW_TAG_namespace:
529 case DW_TAG_class_type:
530 case DW_TAG_structure_type:
9aa8ffce
JS
531 parents->insert(make_pair(child.addr, *die));
532 cache_die_parents(parents, &child);
533 break;
534
535 // record only, nothing to recurse
536 case DW_TAG_label:
537 parents->insert(make_pair(child.addr, *die));
538 break;
539
540 // imported dies should be followed
541 case DW_TAG_imported_unit:
542 if (dwarf_attr_die(&child, DW_AT_import, &import))
543 {
544 parents->insert(make_pair(import.addr, *die));
545 cache_die_parents(parents, &import);
546 }
547 break;
548
549 // nothing to do for other tags
550 default:
551 break;
552 }
553 }
554 while (dwarf_siblingof(&child, &child) == 0);
555}
556
557
729455a7
JS
558cu_die_parent_cache_t*
559dwflpp::get_die_parents()
9aa8ffce
JS
560{
561 assert (cu);
562
729455a7 563 cu_die_parent_cache_t *& parents = cu_die_parent_cache[cu->addr];
9aa8ffce
JS
564 if (!parents)
565 {
566 parents = new cu_die_parent_cache_t;
9aa8ffce
JS
567 cache_die_parents(parents, cu);
568 if (sess.verbose > 4)
f9bbd346
LB
569 clog << _F("die parent cache %s:%s size %zu", module_name.c_str(),
570 cu_name().c_str(), parents->size()) << endl;
9aa8ffce 571 }
729455a7
JS
572 return parents;
573}
574
575
576vector<Dwarf_Die>
577dwflpp::getscopes_die(Dwarf_Die* die)
578{
579 cu_die_parent_cache_t *parents = get_die_parents();
9aa8ffce
JS
580
581 vector<Dwarf_Die> scopes;
729455a7
JS
582 Dwarf_Die *scope = die;
583 cu_die_parent_cache_t::iterator it;
584 do
585 {
586 scopes.push_back(*scope);
587 it = parents->find(scope->addr);
588 scope = &it->second;
589 }
590 while (it != parents->end());
9aa8ffce
JS
591
592#ifdef DEBUG_DWFLPP_GETSCOPES
729455a7 593 Dwarf_Die *dscopes = NULL;
9aa8ffce
JS
594 int nscopes = dwarf_getscopes_die(die, &dscopes);
595
596 assert(nscopes == (int)scopes.size());
597 for (unsigned i = 0; i < scopes.size(); ++i)
598 assert(scopes[i].addr == dscopes[i].addr);
599 free(dscopes);
600#endif
601
602 return scopes;
603}
604
605
729455a7
JS
606std::vector<Dwarf_Die>
607dwflpp::getscopes(Dwarf_Die* die)
608{
609 cu_die_parent_cache_t *parents = get_die_parents();
610
611 vector<Dwarf_Die> scopes;
612
613 Dwarf_Die origin;
614 Dwarf_Die *scope = die;
615 cu_die_parent_cache_t::iterator it;
616 do
617 {
618 scopes.push_back(*scope);
619 if (dwarf_tag(scope) == DW_TAG_inlined_subroutine &&
620 dwarf_attr_die(scope, DW_AT_abstract_origin, &origin))
621 scope = &origin;
622
623 it = parents->find(scope->addr);
624 scope = &it->second;
625 }
626 while (it != parents->end());
627
628#ifdef DEBUG_DWFLPP_GETSCOPES
629 // there isn't an exact libdw equivalent, but if dwarf_getscopes on the
630 // entrypc returns the same first die, then all the scopes should match
631 Dwarf_Addr pc;
632 if (die_entrypc(die, &pc))
633 {
634 Dwarf_Die *dscopes = NULL;
635 int nscopes = dwarf_getscopes(cu, pc, &dscopes);
636 if (nscopes > 0 && dscopes[0].addr == die->addr)
637 {
638 assert(nscopes == (int)scopes.size());
639 for (unsigned i = 0; i < scopes.size(); ++i)
640 assert(scopes[i].addr == dscopes[i].addr);
641 }
642 free(dscopes);
643 }
644#endif
645
646 return scopes;
647}
648
649
650std::vector<Dwarf_Die>
651dwflpp::getscopes(Dwarf_Addr pc)
652{
653 // The die_parent_cache doesn't help us without knowing where the pc is
654 // contained, so we have to do this one the old fashioned way.
655
656 assert (cu);
657
658 vector<Dwarf_Die> scopes;
659
660 Dwarf_Die* dwarf_scopes;
661 int nscopes = dwarf_getscopes(cu, pc, &dwarf_scopes);
662 if (nscopes > 0)
663 {
664 scopes.assign(dwarf_scopes, dwarf_scopes + nscopes);
665 free(dwarf_scopes);
666 }
667
668#ifdef DEBUG_DWFLPP_GETSCOPES
669 // check that getscopes on the starting die gets the same result
670 if (!scopes.empty())
671 {
672 vector<Dwarf_Die> other = getscopes(&scopes[0]);
673 assert(scopes.size() == other.size());
674 for (unsigned i = 0; i < scopes.size(); ++i)
675 assert(scopes[i].addr == other[i].addr);
676 }
677#endif
678
679 return scopes;
680}
681
682
7d6d0afc
JS
683Dwarf_Die*
684dwflpp::get_parent_scope(Dwarf_Die* die)
685{
686 Dwarf_Die specification;
687 if (dwarf_attr_die(die, DW_AT_specification, &specification))
688 die = &specification;
689
690 cu_die_parent_cache_t *parents = get_die_parents();
691 cu_die_parent_cache_t::iterator it = parents->find(die->addr);
692 while (it != parents->end())
693 {
694 Dwarf_Die* scope = &it->second;
695 switch (dwarf_tag (scope))
696 {
697 case DW_TAG_namespace:
698 case DW_TAG_class_type:
699 case DW_TAG_structure_type:
700 return scope;
701
702 default:
703 break;
704 }
705 it = parents->find(scope->addr);
706 }
707 return NULL;
708}
709
a44a7cb5
JS
710static const char*
711cache_type_prefix(Dwarf_Die* type)
712{
713 switch (dwarf_tag(type))
714 {
715 case DW_TAG_enumeration_type:
716 return "enum ";
717 case DW_TAG_structure_type:
718 case DW_TAG_class_type:
719 // treating struct/class as equals
720 return "struct ";
721 case DW_TAG_union_type:
722 return "union ";
723 }
724 return "";
725}
7d6d0afc 726
440f755a
JS
727int
728dwflpp::global_alias_caching_callback(Dwarf_Die *die, void *arg)
729{
b7478964 730 cu_type_cache_t *cache = static_cast<cu_type_cache_t*>(arg);
440f755a
JS
731 const char *name = dwarf_diename(die);
732
a44a7cb5 733 if (!name || dwarf_hasattr(die, DW_AT_declaration))
440f755a
JS
734 return DWARF_CB_OK;
735
a44a7cb5
JS
736 string type_name = cache_type_prefix(die) + string(name);
737 if (cache->find(type_name) == cache->end())
738 (*cache)[type_name] = *die;
440f755a
JS
739
740 return DWARF_CB_OK;
741}
742
063906a9
MW
743int
744dwflpp::global_alias_caching_callback_cus(Dwarf_Die *die, void *arg)
745{
746 mod_cu_type_cache_t *global_alias_cache;
747 global_alias_cache = &static_cast<dwflpp *>(arg)->global_alias_cache;
748
749 cu_type_cache_t *v = (*global_alias_cache)[die->addr];
750 if (v != 0)
751 return DWARF_CB_OK;
752
753 v = new cu_type_cache_t;
754 (*global_alias_cache)[die->addr] = v;
755 iterate_over_globals(die, global_alias_caching_callback, v);
756
757 return DWARF_CB_OK;
758}
759
760Dwarf_Die *
a44a7cb5 761dwflpp::declaration_resolve_other_cus(const string& name)
063906a9
MW
762{
763 iterate_over_cus(global_alias_caching_callback_cus, this);
764 for (mod_cu_type_cache_t::iterator i = global_alias_cache.begin();
765 i != global_alias_cache.end(); ++i)
766 {
767 cu_type_cache_t *v = (*i).second;
768 if (v->find(name) != v->end())
769 return & ((*v)[name]);
770 }
771
772 return NULL;
773}
440f755a
JS
774
775Dwarf_Die *
a44a7cb5 776dwflpp::declaration_resolve(const string& name)
440f755a 777{
b7478964 778 cu_type_cache_t *v = global_alias_cache[cu->addr];
440f755a
JS
779 if (v == 0) // need to build the cache, just once per encountered module/cu
780 {
b7478964 781 v = new cu_type_cache_t;
54558065 782 global_alias_cache[cu->addr] = v;
063906a9 783 iterate_over_globals(cu, global_alias_caching_callback, v);
440f755a 784 if (sess.verbose > 4)
f9bbd346
LB
785 clog << _F("global alias cache %s:%s size %zu", module_name.c_str(),
786 cu_name().c_str(), v->size()) << endl;
440f755a
JS
787 }
788
789 // XXX: it may be desirable to search other modules' declarations
790 // too, in case a module/shared-library processes a
791 // forward-declared pointer type only, where the actual definition
792 // may only be in vmlinux or the application.
793
440f755a 794 if (v->find(name) == v->end())
063906a9 795 return declaration_resolve_other_cus(name);
440f755a
JS
796
797 return & ((*v)[name]);
798}
799
a44a7cb5
JS
800Dwarf_Die *
801dwflpp::declaration_resolve(Dwarf_Die *type)
802{
803 const char* name = dwarf_diename(type);
804 if (!name)
805 return NULL;
806
807 string type_name = cache_type_prefix(type) + string(name);
808 return declaration_resolve(type_name);
809}
810
440f755a
JS
811
812int
813dwflpp::cu_function_caching_callback (Dwarf_Die* func, void *arg)
814{
815 cu_function_cache_t* v = static_cast<cu_function_cache_t*>(arg);
816 const char *name = dwarf_diename(func);
817 if (!name)
818 return DWARF_CB_OK;
819
b7478964 820 v->insert(make_pair(string(name), *func));
440f755a
JS
821 return DWARF_CB_OK;
822}
823
824
4df79aaf
JS
825int
826dwflpp::mod_function_caching_callback (Dwarf_Die* cu, void *arg)
827{
828 dwarf_getfuncs (cu, cu_function_caching_callback, arg, 0);
829 return DWARF_CB_OK;
830}
831
832
440f755a
JS
833int
834dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query * q),
5898b6e1 835 base_query * q, const string& function)
440f755a
JS
836{
837 int rc = DWARF_CB_OK;
838 assert (module);
839 assert (cu);
840
54558065 841 cu_function_cache_t *v = cu_function_cache[cu->addr];
440f755a
JS
842 if (v == 0)
843 {
844 v = new cu_function_cache_t;
54558065 845 cu_function_cache[cu->addr] = v;
440f755a
JS
846 dwarf_getfuncs (cu, cu_function_caching_callback, v, 0);
847 if (sess.verbose > 4)
f9bbd346
LB
848 clog << _F("function cache %s:%s size %zu", module_name.c_str(),
849 cu_name().c_str(), v->size()) << endl;
1c6b77e5 850 mod_info->update_symtab(v);
440f755a
JS
851 }
852
b7478964
JS
853 cu_function_cache_t::iterator it;
854 cu_function_cache_range_t range = v->equal_range(function);
855 if (range.first != range.second)
440f755a 856 {
b7478964
JS
857 for (it = range.first; it != range.second; ++it)
858 {
859 Dwarf_Die& die = it->second;
860 if (sess.verbose > 4)
f9bbd346
LB
861 clog << _F("function cache %s:%s hit %s", module_name.c_str(),
862 cu_name().c_str(), function.c_str()) << endl;
b7478964
JS
863 rc = (*callback)(& die, q);
864 if (rc != DWARF_CB_OK) break;
865 }
440f755a 866 }
1ffb8bd1
JS
867 else if (startswith(function, "_Z"))
868 {
869 // C++ names are mangled starting with a "_Z" prefix. Most of the time
870 // we can discover the mangled name from a die's MIPS_linkage_name
871 // attribute, so we read that to match against the user's function
872 // pattern. Note that this isn't perfect, as not all will have that
873 // attribute (notably ctors and dtors), but we do what we can...
874 for (it = v->begin(); it != v->end(); ++it)
875 {
876 if (pending_interrupts) return DWARF_CB_ABORT;
877 Dwarf_Die& die = it->second;
157f5dd0 878 const char* linkage_name = NULL;
f450a7e3 879 if ((linkage_name = dwarf_linkage_name (&die))
1ffb8bd1
JS
880 && function_name_matches_pattern (linkage_name, function))
881 {
882 if (sess.verbose > 4)
f9bbd346
LB
883 clog << _F("function cache %s:%s match %s vs %s", module_name.c_str(),
884 cu_name().c_str(), linkage_name, function.c_str()) << endl;
1ffb8bd1
JS
885
886 rc = (*callback)(& die, q);
887 if (rc != DWARF_CB_OK) break;
888 }
889 }
890 }
5f4c8c6e 891 else if (name_has_wildcard (function))
440f755a 892 {
c1c5bb9a 893 for (it = v->begin(); it != v->end(); ++it)
440f755a 894 {
85007c04 895 if (pending_interrupts) return DWARF_CB_ABORT;
1c6b77e5
JS
896 const string& func_name = it->first;
897 Dwarf_Die& die = it->second;
5f4c8c6e 898 if (function_name_matches_pattern (func_name, function))
440f755a
JS
899 {
900 if (sess.verbose > 4)
f9bbd346
LB
901 clog << _F("function cache %s:%s match %s vs %s", module_name.c_str(),
902 cu_name().c_str(), func_name.c_str(), function.c_str()) << endl;
440f755a
JS
903
904 rc = (*callback)(& die, q);
905 if (rc != DWARF_CB_OK) break;
906 }
907 }
908 }
1ffb8bd1 909 else // not a linkage name or wildcard and no match in this CU
440f755a
JS
910 {
911 // do nothing
912 }
913 return rc;
914}
915
916
4df79aaf
JS
917int
918dwflpp::iterate_single_function (int (* callback)(Dwarf_Die * func, base_query * q),
919 base_query * q, const string& function)
920{
921 int rc = DWARF_CB_OK;
922 assert (module);
923
924 get_module_dwarf(false);
925 if (!module_dwarf)
926 return rc;
927
928 cu_function_cache_t *v = mod_function_cache[module_dwarf];
929 if (v == 0)
930 {
931 v = new cu_function_cache_t;
932 mod_function_cache[module_dwarf] = v;
933 iterate_over_cus (mod_function_caching_callback, v);
934 if (sess.verbose > 4)
f9bbd346
LB
935 clog << _F("module function cache %s size %zu", module_name.c_str(),
936 v->size()) << endl;
d1fa8b15 937 mod_info->update_symtab(v);
4df79aaf
JS
938 }
939
940 cu_function_cache_t::iterator it;
941 cu_function_cache_range_t range = v->equal_range(function);
942 if (range.first != range.second)
943 {
944 for (it = range.first; it != range.second; ++it)
945 {
946 Dwarf_Die cu_mem;
947 Dwarf_Die& die = it->second;
948 if (sess.verbose > 4)
f9bbd346
LB
949 clog << _F("module function cache %s hit %s", module_name.c_str(),
950 function.c_str()) << endl;
4df79aaf
JS
951
952 // since we're iterating out of cu-context, we need each focus
953 focus_on_cu(dwarf_diecu(&die, &cu_mem, NULL, NULL));
954
955 rc = (*callback)(& die, q);
956 if (rc != DWARF_CB_OK) break;
957 }
958 }
959
960 // undo the focus_on_cu
961 this->cu = NULL;
962 this->function_name.clear();
963 this->function = NULL;
964
965 return rc;
966}
967
968
440f755a
JS
969/* This basically only goes one level down from the compile unit so it
970 * only picks up top level stuff (i.e. nothing in a lower scope) */
971int
063906a9
MW
972dwflpp::iterate_over_globals (Dwarf_Die *cu_die,
973 int (* callback)(Dwarf_Die *, void *),
440f755a
JS
974 void * data)
975{
976 int rc = DWARF_CB_OK;
977 Dwarf_Die die;
978
063906a9
MW
979 assert (cu_die);
980 assert (dwarf_tag(cu_die) == DW_TAG_compile_unit);
440f755a 981
063906a9 982 if (dwarf_child(cu_die, &die) != 0)
440f755a
JS
983 return rc;
984
985 do
986 /* We're only currently looking for named types,
987 * although other types of declarations exist */
988 switch (dwarf_tag(&die))
989 {
990 case DW_TAG_base_type:
991 case DW_TAG_enumeration_type:
992 case DW_TAG_structure_type:
9c119951 993 case DW_TAG_class_type:
440f755a
JS
994 case DW_TAG_typedef:
995 case DW_TAG_union_type:
996 rc = (*callback)(&die, data);
997 break;
998 }
999 while (rc == DWARF_CB_OK && dwarf_siblingof(&die, &die) == 0);
1000
1001 return rc;
1002}
1003
1004
fea74777
SC
1005/* For each notes section in the current module call 'callback', use
1006 * 'data' for the notes buffer and pass 'object' back in case
1007 * 'callback' is a method */
1008
1009int
1010dwflpp::iterate_over_notes (void *object, void (*callback)(void *object, int type, const char *data, size_t len))
1011{
1012 Dwarf_Addr bias;
1013 Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (module, &bias))
1014 ?: dwfl_module_getelf (module, &bias));
1015 size_t shstrndx;
1016 if (elf_getshdrstrndx (elf, &shstrndx))
1017 return elf_errno();
1018
7f9e468f 1019 GElf_Addr base = (GElf_Addr) -1;
fea74777
SC
1020
1021 Elf_Scn *scn = NULL;
1022
1023 vector<Dwarf_Die> notes;
1024
1025 while ((scn = elf_nextscn (elf, scn)) != NULL)
1026 {
1027 GElf_Shdr shdr;
1028 if (gelf_getshdr (scn, &shdr) == NULL)
1029 continue;
1030 switch (shdr.sh_type)
1031 {
1032 case SHT_NOTE:
1033 if (!(shdr.sh_flags & SHF_ALLOC))
1034 {
1035 if (base == (GElf_Addr) -1)
1036 base = 0;
1037
1038 Elf_Data *data = elf_getdata (scn, NULL);
1039 size_t next;
1040 GElf_Nhdr nhdr;
1041 size_t name_off;
1042 size_t desc_off;
1043 for (size_t offset = 0;
1044 (next = gelf_getnote (data, offset, &nhdr, &name_off, &desc_off)) > 0;
1045 offset = next)
1046 (*callback) (object, nhdr.n_type, (const char*)((long)(data->d_buf) + (long)desc_off), nhdr.n_descsz);
1047 }
1048 break;
1049 }
1050 }
1051 return 0;
1052}
1053
1054
440f755a
JS
1055// This little test routine represents an unfortunate breakdown in
1056// abstraction between dwflpp (putatively, a layer right on top of
1057// elfutils), and dwarf_query (interpreting a systemtap probe point).
1058// It arises because we sometimes try to fix up slightly-off
1059// .statement() probes (something we find out in fairly low-level).
1060//
1061// An alternative would be to put some more intelligence into query_cu(),
1062// and have it print additional suggestions after finding that
1063// q->dw.iterate_over_srcfile_lines resulted in no new finished_results.
1064
1065bool
1066dwflpp::has_single_line_record (dwarf_query * q, char const * srcfile, int lineno)
1067{
1068 if (lineno < 0)
1069 return false;
1070
1071 Dwarf_Line **srcsp = NULL;
1072 size_t nsrcs = 0;
1073
1074 dwarf_assert ("dwarf_getsrc_file",
1075 dwarf_getsrc_file (module_dwarf,
1076 srcfile, lineno, 0,
1077 &srcsp, &nsrcs));
1078
1079 if (nsrcs != 1)
1080 {
1081 if (sess.verbose>4)
f9bbd346 1082 clog << _F("alternative line %d rejected: nsrcs=%zu", lineno, nsrcs) << endl;
440f755a
JS
1083 return false;
1084 }
1085
1086 // We also try to filter out lines that leave the selected
1087 // functions (if any).
1088
1089 dwarf_line_t line(srcsp[0]);
1090 Dwarf_Addr addr = line.addr();
1091
1092 func_info_map_t *filtered_functions = get_filtered_functions(q);
1093 for (func_info_map_t::iterator i = filtered_functions->begin();
1094 i != filtered_functions->end(); ++i)
1095 {
1096 if (die_has_pc (i->die, addr))
1097 {
1098 if (sess.verbose>4)
f9bbd346 1099 clog << _F("alternative line %d accepted: fn=%s", lineno, i->name.c_str()) << endl;
440f755a
JS
1100 return true;
1101 }
1102 }
1103
1104 inline_instance_map_t *filtered_inlines = get_filtered_inlines(q);
1105 for (inline_instance_map_t::iterator i = filtered_inlines->begin();
1106 i != filtered_inlines->end(); ++i)
1107 {
1108 if (die_has_pc (i->die, addr))
1109 {
1110 if (sess.verbose>4)
f9bbd346 1111 clog << _F("alternative line %d accepted: ifn=%s", lineno, i->name.c_str()) << endl;
440f755a
JS
1112 return true;
1113 }
1114 }
1115
1116 if (sess.verbose>4)
f9bbd346 1117 clog << _F("alternative line %d rejected: leaves selected fns", lineno) << endl;
440f755a
JS
1118 return false;
1119}
1120
1121
1122void
1123dwflpp::iterate_over_srcfile_lines (char const * srcfile,
1124 int lines[2],
1125 bool need_single_match,
1126 enum line_t line_type,
1127 void (* callback) (const dwarf_line_t& line,
1128 void * arg),
9b988eff 1129 const std::string& func_pattern,
440f755a
JS
1130 void *data)
1131{
1132 Dwarf_Line **srcsp = NULL;
1133 size_t nsrcs = 0;
1134 dwarf_query * q = static_cast<dwarf_query *>(data);
1135 int lineno = lines[0];
1136 auto_free_ref<Dwarf_Line**> free_srcsp(srcsp);
1137
1138 get_module_dwarf();
e679283a
WH
1139 if (!this->function)
1140 return;
440f755a
JS
1141
1142 if (line_type == RELATIVE)
1143 {
1144 Dwarf_Addr addr;
1145 Dwarf_Line *line;
1146 int line_number;
1147
6a3a5e98
SC
1148 die_entrypc(this->function, &addr);
1149
1150 if (addr != 0)
1151 {
1152 line = dwarf_getsrc_die (this->cu, addr);
1153 dwarf_assert ("dwarf_getsrc_die", line == NULL);
1154 dwarf_assert ("dwarf_lineno", dwarf_lineno (line, &line_number));
1155 }
1156 else if (dwarf_decl_line (this->function, &line_number) != 0)
1157 {
1158 // use DW_AT_decl_line as a fallback method
1159 Dwarf_Attribute type_attr;
1160 Dwarf_Word constant;
1161 if (dwarf_attr_integrate (this->function, DW_AT_decl_line, &type_attr))
1162 {
1163 dwarf_formudata (&type_attr, &constant);
1164 line_number = constant;
1165 }
1166 else
1167 return;
1168 }
440f755a
JS
1169 lineno += line_number;
1170 }
1171 else if (line_type == WILDCARD)
1172 function_line (&lineno);
1123a74a
WH
1173 else if (line_type == RANGE) { /* correct lineno */
1174 int start_lineno;
1175
9b988eff
WH
1176 if (name_has_wildcard(func_pattern)) /* PR10294: wider range like statement("*@foo.c") */
1177 start_lineno = lineno;
1178 else
1179 function_line (&start_lineno);
1123a74a
WH
1180 lineno = lineno < start_lineno ? start_lineno : lineno;
1181 if (lineno > lines[1]) { /* invalid line range */
1182 stringstream advice;
f9bbd346 1183 advice << _("Invalid line range (") << lines[0] << "-" << lines[1] << ")";
1123a74a 1184 if (start_lineno > lines[1])
f9bbd346 1185 advice << _(", the end line number ") << lines[1] << " < " << start_lineno;
1123a74a
WH
1186 throw semantic_error (advice.str());
1187 }
1188 }
1189
440f755a
JS
1190
1191 for (int l = lineno; ; l = l + 1)
1192 {
1193 set<int> lines_probed;
1194 pair<set<int>::iterator,bool> line_probed;
1123a74a
WH
1195 int ret = 0;
1196
b8c632dc
FCE
1197 if (pending_interrupts) break;
1198
1123a74a
WH
1199 ret = dwarf_getsrc_file (module_dwarf, srcfile, l, 0,
1200 &srcsp, &nsrcs);
8aaef2fb
JS
1201 if (ret != 0) /* tolerate invalid line number */
1202 break;
1123a74a 1203
440f755a
JS
1204 if (line_type == WILDCARD || line_type == RANGE)
1205 {
1206 Dwarf_Addr line_addr;
1123a74a 1207
440f755a 1208 dwarf_lineno (srcsp [0], &lineno);
1123a74a
WH
1209 /* Maybe lineno will exceed the input end */
1210 if (line_type == RANGE && lineno > lines[1])
1211 break;
440f755a
JS
1212 line_probed = lines_probed.insert(lineno);
1213 if (lineno != l || line_probed.second == false || nsrcs > 1)
1214 continue;
1215 dwarf_lineaddr (srcsp [0], &line_addr);
9b988eff 1216 if (!function_name_matches(func_pattern) && dwarf_haspc (function, line_addr) != 1)
440f755a
JS
1217 break;
1218 }
1219
1220 // NB: Formerly, we used to filter, because:
1221
1222 // dwarf_getsrc_file gets one *near hits* for line numbers, not
1223 // exact matches. For example, an existing file but a nonexistent
1224 // line number will be rounded up to the next definition in that
1225 // file. This may be similar to the GDB breakpoint algorithm, but
1226 // we don't want to be so fuzzy in systemtap land. So we filter.
1227
1228 // But we now see the error of our ways, and skip this filtering.
1229
1230 // XXX: the code also fails to match e.g. inline function
1231 // definitions when the srcfile is a header file rather than the
1232 // CU name.
1233
1234 size_t remaining_nsrcs = nsrcs;
1235
1236 if (need_single_match && remaining_nsrcs > 1)
1237 {
1238 // We wanted a single line record (a unique address for the
1239 // line) and we got a bunch of line records. We're going to
1240 // skip this probe (throw an exception) but before we throw
1241 // we're going to look around a bit to see if there's a low or
1242 // high line number nearby which *doesn't* have this problem,
1243 // so we can give the user some advice.
1244
1245 int lo_try = -1;
1246 int hi_try = -1;
1247 for (size_t i = 1; i < 6; ++i)
1248 {
1249 if (lo_try == -1 && has_single_line_record(q, srcfile, lineno - i))
1250 lo_try = lineno - i;
1251
1252 if (hi_try == -1 && has_single_line_record(q, srcfile, lineno + i))
1253 hi_try = lineno + i;
1254 }
1255
1256 stringstream advice;
f9bbd346 1257 advice << _F("multiple addresses for %s:%d", srcfile, lineno);
440f755a
JS
1258 if (lo_try > 0 || hi_try > 0)
1259 {
f9bbd346
LB
1260 //TRANSLATORS: Here we are trying to advise what source file
1261 //TRANSLATORS: to attempt.
1262 advice << _(" (try ");
440f755a
JS
1263 if (lo_try > 0)
1264 advice << srcfile << ":" << lo_try;
1265 if (lo_try > 0 && hi_try > 0)
f9bbd346 1266 advice << _(" or ");
440f755a
JS
1267 if (hi_try > 0)
1268 advice << srcfile << ":" << hi_try;
1269 advice << ")";
1270 }
1271 throw semantic_error (advice.str());
1272 }
1273
1274 for (size_t i = 0; i < nsrcs; ++i)
1275 {
85007c04 1276 if (pending_interrupts) return;
440f755a
JS
1277 if (srcsp [i]) // skip over mismatched lines
1278 callback (dwarf_line_t(srcsp[i]), data);
1279 }
1280
1281 if (line_type == ABSOLUTE || line_type == RELATIVE)
1282 break;
1283 else if (line_type == RANGE && l == lines[1])
1284 break;
1285 }
1286}
1287
1288
1289void
1290dwflpp::iterate_over_labels (Dwarf_Die *begin_die,
8096dd7d 1291 const string& sym,
f09d0d1e 1292 const string& function,
8096dd7d 1293 dwarf_query *q,
440f755a 1294 void (* callback)(const string &,
8096dd7d 1295 const char *,
440f755a
JS
1296 const char *,
1297 int,
1298 Dwarf_Die *,
1299 Dwarf_Addr,
f09d0d1e 1300 dwarf_query *))
440f755a 1301{
440f755a
JS
1302 get_module_dwarf();
1303
1304 Dwarf_Die die;
f09d0d1e 1305 const char *name;
440f755a
JS
1306 int res = dwarf_child (begin_die, &die);
1307 if (res != 0)
1308 return; // die without children, bail out.
1309
440f755a
JS
1310 do
1311 {
f09d0d1e 1312 switch (dwarf_tag(&die))
440f755a
JS
1313 {
1314 case DW_TAG_label:
f09d0d1e
JS
1315 name = dwarf_diename (&die);
1316 if (name &&
8096dd7d
JS
1317 (name == sym
1318 || (name_has_wildcard(sym)
1319 && function_name_matches_pattern (name, sym))))
1320 {
8096dd7d
JS
1321 // Don't try to be smart. Just drop no addr labels.
1322 Dwarf_Addr stmt_addr;
1323 if (dwarf_lowpc (&die, &stmt_addr) == 0)
1324 {
f09d0d1e
JS
1325 // Get the file/line number for this label
1326 int dline;
1327 const char *file = dwarf_decl_file (&die);
1328 dwarf_decl_line (&die, &dline);
1329
9aa8ffce
JS
1330 vector<Dwarf_Die> scopes = getscopes_die(&die);
1331 if (scopes.size() > 1)
f5958c8f
JS
1332 {
1333 Dwarf_Die scope;
2a43d5db
JS
1334 if (!inner_die_containing_pc(scopes[1], stmt_addr, scope)
1335 && !sess.suppress_warnings)
1336 {
1337 ostringstream msg;
f9bbd346
LB
1338 msg << _F("label '%s' at address %s (dieoffset: %s) is not "
1339 "contained by its scope '%s' (dieoffset: %s) -- bad"
1340 " debuginfo?", name, lex_cast_hex(stmt_addr).c_str(),
1341 lex_cast_hex(dwarf_dieoffset(&die)).c_str(),
1342 (dwarf_diename(&scope) ?: "<unknown>"),
1343 lex_cast_hex(dwarf_dieoffset(&scope)).c_str());
2a43d5db
JS
1344 sess.print_warning (msg.str());
1345 }
f5958c8f
JS
1346 callback(function, name, file, dline,
1347 &scope, stmt_addr, q);
1348 }
8096dd7d
JS
1349 }
1350 }
440f755a 1351 break;
8096dd7d 1352
440f755a 1353 case DW_TAG_subprogram:
30868aad 1354 case DW_TAG_inlined_subroutine:
f09d0d1e
JS
1355 // Stay within our filtered function
1356 break;
1357
440f755a
JS
1358 default:
1359 if (dwarf_haschildren (&die))
f09d0d1e 1360 iterate_over_labels (&die, sym, function, q, callback);
8096dd7d 1361 break;
440f755a
JS
1362 }
1363 }
1364 while (dwarf_siblingof (&die, &die) == 0);
1365}
1366
1367
1368void
1369dwflpp::collect_srcfiles_matching (string const & pattern,
bd25380d 1370 set<string> & filtered_srcfiles)
440f755a
JS
1371{
1372 assert (module);
1373 assert (cu);
1374
1375 size_t nfiles;
1376 Dwarf_Files *srcfiles;
1377
1378 // PR 5049: implicit * in front of given path pattern.
1379 // NB: fnmatch() is used without FNM_PATHNAME.
1380 string prefixed_pattern = string("*/") + pattern;
1381
1382 dwarf_assert ("dwarf_getsrcfiles",
1383 dwarf_getsrcfiles (cu, &srcfiles, &nfiles));
1384 {
1385 for (size_t i = 0; i < nfiles; ++i)
1386 {
1387 char const * fname = dwarf_filesrc (srcfiles, i, NULL, NULL);
1388 if (fnmatch (pattern.c_str(), fname, 0) == 0 ||
1389 fnmatch (prefixed_pattern.c_str(), fname, 0) == 0)
1390 {
1391 filtered_srcfiles.insert (fname);
1392 if (sess.verbose>2)
f9bbd346 1393 clog << _F("selected source file '%s'\n", fname);
440f755a
JS
1394 }
1395 }
1396 }
1397}
1398
1399
1400void
1401dwflpp::resolve_prologue_endings (func_info_map_t & funcs)
1402{
1403 // This heuristic attempts to pick the first address that has a
1404 // source line distinct from the function declaration's. In a
1405 // perfect world, this would be the first statement *past* the
1406 // prologue.
1407
1408 assert(module);
1409 assert(cu);
1410
1411 size_t nlines = 0;
1412 Dwarf_Lines *lines = NULL;
1413
1414 /* trouble cases:
1415 malloc do_symlink in init/initramfs.c tail-recursive/tiny then no-prologue
1416 sys_get?id in kernel/timer.c no-prologue
1417 sys_exit_group tail-recursive
1418 {do_,}sys_open extra-long-prologue (gcc 3.4)
1419 cpu_to_logical_apicid NULL-decl_file
1420 */
1421
1422 // Fetch all srcline records, sorted by address.
1423 dwarf_assert ("dwarf_getsrclines",
1424 dwarf_getsrclines(cu, &lines, &nlines));
1425 // XXX: free lines[] later, but how?
1426
1427 for(func_info_map_t::iterator it = funcs.begin(); it != funcs.end(); it++)
1428 {
1429#if 0 /* someday */
1430 Dwarf_Addr* bkpts = 0;
1431 int n = dwarf_entry_breakpoints (& it->die, & bkpts);
1432 // ...
1433 free (bkpts);
1434#endif
1435
1436 Dwarf_Addr entrypc = it->entrypc;
1437 Dwarf_Addr highpc; // NB: highpc is exclusive: [entrypc,highpc)
1438 dwfl_assert ("dwarf_highpc", dwarf_highpc (& it->die,
1439 & highpc));
1440
1441 if (it->decl_file == 0) it->decl_file = "";
1442
1443 unsigned entrypc_srcline_idx = 0;
1444 dwarf_line_t entrypc_srcline;
1445 // open-code binary search for exact match
1446 {
1447 unsigned l = 0, h = nlines;
1448 while (l < h)
1449 {
1450 entrypc_srcline_idx = (l + h) / 2;
1451 const dwarf_line_t lr(dwarf_onesrcline(lines,
1452 entrypc_srcline_idx));
1453 Dwarf_Addr addr = lr.addr();
1454 if (addr == entrypc) { entrypc_srcline = lr; break; }
1455 else if (l + 1 == h) { break; } // ran off bottom of tree
1456 else if (addr < entrypc) { l = entrypc_srcline_idx; }
1457 else { h = entrypc_srcline_idx; }
1458 }
1459 }
1460 if (!entrypc_srcline)
1461 {
1462 if (sess.verbose > 2)
f9bbd346
LB
1463 clog << _F("missing entrypc dwarf line record for function '%s'\n",
1464 it->name.c_str());
440f755a
JS
1465 // This is probably an inlined function. We'll end up using
1466 // its lowpc as a probe address.
1467 continue;
1468 }
1469
48390b53
FCE
1470 if (entrypc == 0)
1471 {
1472 if (sess.verbose > 2)
f9bbd346
LB
1473 clog << _F("null entrypc dwarf line record for function '%s'\n",
1474 it->name.c_str());
48390b53
FCE
1475 // This is probably an inlined function. We'll skip this instance;
1476 // it is messed up.
1477 continue;
1478 }
1479
440f755a 1480 if (sess.verbose>2)
f9bbd346
LB
1481 clog << _F("prologue searching function '%s' 0x%#" PRIx64 "-0x%#" PRIx64
1482 "@%s:%d\n", it->name.c_str(), entrypc, highpc, it->decl_file,
1483 it->decl_line);
440f755a
JS
1484
1485 // Now we go searching for the first line record that has a
1486 // file/line different from the one in the declaration.
1487 // Normally, this will be the next one. BUT:
1488 //
1489 // We may have to skip a few because some old compilers plop
1490 // in dummy line records for longer prologues. If we go too
1491 // far (addr >= highpc), we take the previous one. Or, it may
1492 // be the first one, if the function had no prologue, and thus
1493 // the entrypc maps to a statement in the body rather than the
1494 // declaration.
1495
1496 unsigned postprologue_srcline_idx = entrypc_srcline_idx;
1497 bool ranoff_end = false;
1498 while (postprologue_srcline_idx < nlines)
1499 {
1500 dwarf_line_t lr(dwarf_onesrcline(lines, postprologue_srcline_idx));
1501 Dwarf_Addr postprologue_addr = lr.addr();
1502 const char* postprologue_file = lr.linesrc();
1503 int postprologue_lineno = lr.lineno();
1504
1505 if (sess.verbose>2)
f9bbd346
LB
1506 clog << _F("checking line record 0x%#" PRIx64 "@%s:%d\n", postprologue_addr,
1507 postprologue_file, postprologue_lineno);
440f755a
JS
1508
1509 if (postprologue_addr >= highpc)
1510 {
1511 ranoff_end = true;
1512 postprologue_srcline_idx --;
1513 continue;
1514 }
1515 if (ranoff_end ||
1516 (strcmp (postprologue_file, it->decl_file) || // We have a winner!
1517 (postprologue_lineno != it->decl_line)))
1518 {
1519 it->prologue_end = postprologue_addr;
1520
1521 if (sess.verbose>2)
1522 {
f9bbd346 1523 clog << _F("prologue found function '%s'", it->name.c_str());
440f755a 1524 // Add a little classification datum
f9bbd346
LB
1525 //TRANSLATORS: Here we're adding some classification datum
1526 if (postprologue_srcline_idx == entrypc_srcline_idx) clog << _(" (naked)");
1527 //TRANSLATORS: Here we're adding some classification datum
1528 if (ranoff_end) clog << _(" (tail-call?)");
440f755a
JS
1529 clog << " = 0x" << hex << postprologue_addr << dec << "\n";
1530 }
1531
1532 break;
1533 }
1534
1535 // Let's try the next srcline.
1536 postprologue_srcline_idx ++;
1537 } // loop over srclines
1538
1539 // if (strlen(it->decl_file) == 0) it->decl_file = NULL;
1540
1541 } // loop over functions
1542
1543 // XXX: how to free lines?
1544}
1545
1546
1547bool
1548dwflpp::function_entrypc (Dwarf_Addr * addr)
1549{
1550 assert (function);
1551 return (dwarf_entrypc (function, addr) == 0);
440f755a
JS
1552}
1553
1554
1555bool
1556dwflpp::die_entrypc (Dwarf_Die * die, Dwarf_Addr * addr)
1557{
1558 int rc = 0;
1559 string lookup_method;
1560
1561 * addr = 0;
1562
1563 lookup_method = "dwarf_entrypc";
1564 rc = dwarf_entrypc (die, addr);
1565
440f755a
JS
1566 if (rc)
1567 {
1568 lookup_method = "dwarf_ranges";
1569
1570 Dwarf_Addr base;
1571 Dwarf_Addr begin;
1572 Dwarf_Addr end;
1573 ptrdiff_t offset = dwarf_ranges (die, 0, &base, &begin, &end);
1574 if (offset < 0) rc = -1;
1575 else if (offset > 0)
1576 {
1577 * addr = begin;
1578 rc = 0;
1579
1580 // Now we need to check that there are no more ranges
1581 // associated with this function, which could conceivably
1582 // happen if a function is inlined, then pieces of it are
1583 // split amongst different conditional branches. It's not
1584 // obvious which of them to favour. As a heuristic, we
1585 // pick the beginning of the first range, and ignore the
1586 // others (but with a warning).
1587
1588 unsigned extra = 0;
1589 while ((offset = dwarf_ranges (die, offset, &base, &begin, &end)) > 0)
1590 extra ++;
1591 if (extra)
f9bbd346 1592 lookup_method += _F(", ignored %s more", lex_cast(extra).c_str());
440f755a
JS
1593 }
1594 }
1595
4ad42007
FCE
1596 // PR10574: reject subprograms where the entrypc address turns out
1597 // to be 0, since they tend to correspond to duplicate-eliminated
1598 // COMDAT copies of C++ functions.
1599 if (rc == 0 && *addr == 0)
1600 {
f9bbd346 1601 lookup_method += _(" (skip comdat)");
4ad42007
FCE
1602 rc = 1;
1603 }
1604
440f755a 1605 if (sess.verbose > 2)
f9bbd346
LB
1606 clog << _F("entry-pc lookup (%s dieoffset: %s) = 0x%#" PRIx64 " (rc %d", lookup_method.c_str(),
1607 lex_cast_hex(dwarf_dieoffset(die)).c_str(), *addr, rc) << endl;
4ad42007 1608
440f755a
JS
1609 return (rc == 0);
1610}
1611
1612
1613void
1614dwflpp::function_die (Dwarf_Die *d)
1615{
1616 assert (function);
1617 *d = *function;
1618}
1619
1620
1621void
1622dwflpp::function_file (char const ** c)
1623{
1624 assert (function);
1625 assert (c);
1626 *c = dwarf_decl_file (function);
1627}
1628
1629
1630void
1631dwflpp::function_line (int *linep)
1632{
1633 assert (function);
1634 dwarf_decl_line (function, linep);
1635}
1636
1637
1638bool
1639dwflpp::die_has_pc (Dwarf_Die & die, Dwarf_Addr pc)
1640{
1641 int res = dwarf_haspc (&die, pc);
1642 // dwarf_ranges will return -1 if a function die has no DW_AT_ranges
1643 // if (res == -1)
1644 // dwarf_assert ("dwarf_haspc", res);
1645 return res == 1;
1646}
1647
1648
2a43d5db 1649bool
f5958c8f
JS
1650dwflpp::inner_die_containing_pc(Dwarf_Die& scope, Dwarf_Addr addr,
1651 Dwarf_Die& result)
1652{
793f98d5
JS
1653 result = scope;
1654
1655 // Sometimes we're in a bad scope to begin with -- just let it be. This can
1656 // happen for example if the compiler outputs a label PC that's just outside
1657 // the lexical scope. We can't really do anything about that, but variables
1658 // will probably not be accessible in this case.
f5958c8f 1659 if (!die_has_pc(scope, addr))
2a43d5db 1660 return false;
f5958c8f
JS
1661
1662 Dwarf_Die child;
f5958c8f
JS
1663 int rc = dwarf_child(&result, &child);
1664 while (rc == 0)
1665 {
1666 switch (dwarf_tag (&child))
1667 {
1668 // lexical tags to recurse within the same starting scope
1669 // NB: this intentionally doesn't cross into inlines!
1670 case DW_TAG_lexical_block:
1671 case DW_TAG_with_stmt:
1672 case DW_TAG_catch_block:
1673 case DW_TAG_try_block:
1674 case DW_TAG_entry_point:
1675 if (die_has_pc(child, addr))
1676 {
1677 result = child;
1678 rc = dwarf_child(&result, &child);
1679 continue;
1680 }
1681 }
1682 rc = dwarf_siblingof(&child, &child);
1683 }
2a43d5db 1684 return true;
f5958c8f
JS
1685}
1686
1687
440f755a
JS
1688void
1689dwflpp::loc2c_error (void *, const char *fmt, ...)
1690{
1691 const char *msg = "?";
1692 char *tmp = NULL;
1693 int rc;
1694 va_list ap;
1695 va_start (ap, fmt);
1696 rc = vasprintf (& tmp, fmt, ap);
1697 if (rc < 0)
1698 msg = "?";
1699 else
1700 msg = tmp;
1701 va_end (ap);
1702 throw semantic_error (msg);
1703}
1704
1705
1706// This function generates code used for addressing computations of
1707// target variables.
1708void
1709dwflpp::emit_address (struct obstack *pool, Dwarf_Addr address)
1710{
1711 #if 0
1712 // The easy but incorrect way is to just print a hard-wired
1713 // constant.
1714 obstack_printf (pool, "%#" PRIx64 "UL", address);
1715 #endif
1716
1717 // Turn this address into a section-relative offset if it should be one.
1718 // We emit a comment approximating the variable+offset expression that
1719 // relocatable module probing code will need to have.
e2d2c7b8
MW
1720 Dwfl *dwfl = dwfl_ptr.get()->dwfl;
1721 if (! dwfl)
f9bbd346 1722 throw semantic_error (_("emit_address internal error, no dwfl"));
e2d2c7b8
MW
1723
1724 Dwfl_Module *mod = dwfl_addrmodule (dwfl, address);
1725 if (! mod)
1726 {
1727 ostringstream msg;
f9bbd346
LB
1728 msg << _F("emit_address internal error, dwfl_adddrmodule failed, "
1729 "address 0x%#" PRIx64 , address);
e2d2c7b8
MW
1730 const char *err = dwfl_errmsg(0);
1731 if (err)
1732 msg << " (" << err << ")";
1733 throw semantic_error (msg.str());
1734 }
440f755a
JS
1735 const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
1736 NULL, NULL, NULL, NULL);
1737 int n = dwfl_module_relocations (mod);
1738 dwfl_assert ("dwfl_module_relocations", n >= 0);
1739 Dwarf_Addr reloc_address = address;
1740 int i = dwfl_module_relocate_address (mod, &reloc_address);
1741 dwfl_assert ("dwfl_module_relocate_address", i >= 0);
1742 dwfl_assert ("dwfl_module_info", modname);
1743 const char *secname = dwfl_module_relocation_info (mod, i, NULL);
1744
1745 if (sess.verbose > 2)
1746 {
f9bbd346
LB
1747 clog << _F("emit dwarf addr 0x%#" PRIx64 " => module %s section %s relocaddr 0x%#" PRIx64,
1748 address, modname, (secname ?: "null"), reloc_address) << endl;
440f755a
JS
1749 }
1750
1751 if (n > 0 && !(n == 1 && secname == NULL))
1752 {
1753 dwfl_assert ("dwfl_module_relocation_info", secname);
1754 if (n > 1 || secname[0] != '\0')
1755 {
1756 // This gives us the module name, and section name within the
1757 // module, for a kernel module (or other ET_REL module object).
f685b2fe 1758 obstack_printf (pool, "({ unsigned long addr = 0; ");
a049e342 1759 obstack_printf (pool, "addr = _stp_kmodule_relocate (\"%s\",\"%s\",%#" PRIx64 "); ",
440f755a
JS
1760 modname, secname, reloc_address);
1761 obstack_printf (pool, "addr; })");
1762 }
1763 else if (n == 1 && module_name == TOK_KERNEL && secname[0] == '\0')
1764 {
1765 // elfutils' way of telling us that this is a relocatable kernel address, which we
1766 // need to treat the same way here as dwarf_query::add_probe_point does: _stext.
1767 address -= sess.sym_stext;
1768 secname = "_stext";
f685b2fe
MW
1769 // Note we "cache" the result here through a static because the
1770 // kernel will never move after being loaded (unlike modules and
1771 // user-space dynamic share libraries).
440f755a 1772 obstack_printf (pool, "({ static unsigned long addr = 0; ");
a049e342 1773 obstack_printf (pool, "if (addr==0) addr = _stp_kmodule_relocate (\"%s\",\"%s\",%#" PRIx64 "); ",
440f755a
JS
1774 modname, secname, address); // PR10000 NB: not reloc_address
1775 obstack_printf (pool, "addr; })");
1776 }
1777 else
1778 {
a295050e 1779 enable_task_finder (sess);
f685b2fe 1780 obstack_printf (pool, "({ unsigned long addr = 0; ");
a049e342 1781 obstack_printf (pool, "addr = _stp_umodule_relocate (\"%s\",%#" PRIx64 ", current); ",
c92a217d 1782 canonicalize_file_name(modname), reloc_address);
a295050e 1783 obstack_printf (pool, "addr; })");
440f755a
JS
1784 }
1785 }
1786 else
1787 obstack_printf (pool, "%#" PRIx64 "UL", address); // assume as constant
1788}
1789
1790
1791void
1792dwflpp::loc2c_emit_address (void *arg, struct obstack *pool,
1793 Dwarf_Addr address)
1794{
c94efd63 1795 static_cast<dwflpp *>(arg)->emit_address (pool, address);
440f755a
JS
1796}
1797
1798
1799void
729455a7 1800dwflpp::print_locals(vector<Dwarf_Die>& scopes, ostream &o)
440f755a 1801{
729455a7
JS
1802 // XXX Shouldn't this be walking up to outer scopes too?
1803
440f755a
JS
1804 // Try to get the first child of die.
1805 Dwarf_Die child;
729455a7 1806 if (dwarf_child (&scopes[0], &child) == 0)
440f755a
JS
1807 {
1808 do
1809 {
1810 const char *name;
1811 // Output each sibling's name (that is a variable or
1812 // parameter) to 'o'.
1813 switch (dwarf_tag (&child))
1814 {
1815 case DW_TAG_variable:
1816 case DW_TAG_formal_parameter:
1817 name = dwarf_diename (&child);
1818 if (name)
4ca5acc8 1819 o << " $" << name;
440f755a
JS
1820 break;
1821 default:
1822 break;
1823 }
1824 }
1825 while (dwarf_siblingof (&child, &child) == 0);
1826 }
1827}
1828
1829
1830Dwarf_Attribute *
729455a7 1831dwflpp::find_variable_and_frame_base (vector<Dwarf_Die>& scopes,
440f755a
JS
1832 Dwarf_Addr pc,
1833 string const & local,
1834 const target_symbol *e,
1835 Dwarf_Die *vardie,
1836 Dwarf_Attribute *fb_attr_mem)
1837{
729455a7 1838 Dwarf_Die *scope_die = &scopes[0];
440f755a
JS
1839 Dwarf_Attribute *fb_attr = NULL;
1840
1841 assert (cu);
1842
729455a7 1843 int declaring_scope = dwarf_getscopevar (&scopes[0], scopes.size(),
440f755a
JS
1844 local.c_str(),
1845 0, NULL, 0, 0,
1846 vardie);
1847 if (declaring_scope < 0)
1848 {
1849 stringstream alternatives;
1850 print_locals (scopes, alternatives);
f9bbd346
LB
1851 throw semantic_error (_F("unable to find local '%s' near pc %s %s %s %s (%s)", local.c_str(),
1852 lex_cast_hex(pc).c_str(), (scope_die == NULL) ? "" : _(" in "),
1853 (dwarf_diename(scope_die) ?: "<unknown>"),
1854 (dwarf_diename(cu) ?: "<unknown>"),
1855 (alternatives.str() == "" ? "" : (_(" (alternatives:") + alternatives.str())).c_str()), e->tok);
440f755a
JS
1856 }
1857
7bce6f87
MW
1858 /* We start out walking the "lexical scopes" as returned by
1859 * as returned by dwarf_getscopes for the address, starting with the
1860 * declaring_scope that the variable was found in.
1861 */
729455a7
JS
1862 vector<Dwarf_Die> physcopes, *fbscopes = &scopes;
1863 for (size_t inner = declaring_scope;
1864 inner < fbscopes->size() && fb_attr == NULL;
7bce6f87 1865 ++inner)
440f755a 1866 {
729455a7
JS
1867 Dwarf_Die& scope = (*fbscopes)[inner];
1868 switch (dwarf_tag (&scope))
440f755a
JS
1869 {
1870 default:
1871 continue;
1872 case DW_TAG_subprogram:
1873 case DW_TAG_entry_point:
729455a7 1874 fb_attr = dwarf_attr_integrate (&scope,
7bce6f87
MW
1875 DW_AT_frame_base,
1876 fb_attr_mem);
1877 break;
1878 case DW_TAG_inlined_subroutine:
1879 /* Unless we already are going through the "pyshical die tree",
1880 * we now need to start walking the die tree where this
1881 * subroutine is inlined to find the appropriate frame base. */
1882 if (declaring_scope != -1)
1883 {
729455a7
JS
1884 physcopes = getscopes_die(&scope);
1885 if (physcopes.empty())
f9bbd346
LB
1886 throw semantic_error (_F("unable to get die scopes for '%s' in an inlined subroutine",
1887 local.c_str()), e->tok);
729455a7 1888 fbscopes = &physcopes;
7bce6f87
MW
1889 inner = 0; // zero is current scope, for look will increase.
1890 declaring_scope = -1;
1891 }
440f755a
JS
1892 break;
1893 }
1894 }
7bce6f87 1895
440f755a
JS
1896 return fb_attr;
1897}
1898
1899
1900struct location *
1901dwflpp::translate_location(struct obstack *pool,
00730da1
MW
1902 Dwarf_Attribute *attr, Dwarf_Die *die,
1903 Dwarf_Addr pc,
440f755a
JS
1904 Dwarf_Attribute *fb_attr,
1905 struct location **tail,
1906 const target_symbol *e)
1907{
619d9aaf
MW
1908
1909 /* DW_AT_data_member_location, can be either constant offsets
86598ebf
MW
1910 (struct member fields), or full blown location expressions.
1911 In older elfutils, dwarf_getlocation_addr would not handle the
1912 constant for us, but newer ones do. For older ones, we work
1913 it by faking an expression, which is what newer ones do. */
1914#if !_ELFUTILS_PREREQ (0,142)
619d9aaf
MW
1915 if (dwarf_whatattr (attr) == DW_AT_data_member_location)
1916 {
bbc212e1 1917 Dwarf_Op offset_loc;
e9483a80 1918 memset(&offset_loc, 0, sizeof(Dwarf_Op));
bbc212e1 1919 offset_loc.atom = DW_OP_plus_uconst;
86598ebf
MW
1920 if (dwarf_formudata (attr, &offset_loc.number) == 0)
1921 return c_translate_location (pool, &loc2c_error, this,
1922 &loc2c_emit_address, 1, 0, pc,
c9a8b3ed 1923 NULL, &offset_loc, 1, NULL, NULL, NULL);
619d9aaf 1924 }
86598ebf 1925#endif
619d9aaf 1926
03ba05b6
MW
1927 /* There is no location expression, but a constant value instead. */
1928 if (dwarf_whatattr (attr) == DW_AT_const_value)
1929 {
1930 *tail = c_translate_constant (pool, &loc2c_error, this,
1931 &loc2c_emit_address, 0, pc, attr);
1932 return *tail;
1933 }
1934
440f755a
JS
1935 Dwarf_Op *expr;
1936 size_t len;
1937
1938 /* PR9768: formerly, we added pc+module_bias here. However, that bias value
1939 is not present in the pc value by the time we get it, so adding it would
1940 result in false negatives of variable reachibility. In other instances
1941 further below, the c_translate_FOO functions, the module_bias value used
1942 to be passed in, but instead should now be zero for the same reason. */
1943
1944 switch (dwarf_getlocation_addr (attr, pc /*+ module_bias*/, &expr, &len, 1))
1945 {
1946 case 1: /* Should always happen. */
1947 if (len > 0)
1948 break;
1949 /* Fall through. */
1950
1951 case 0: /* Shouldn't happen. */
f9bbd346
LB
1952 throw semantic_error (_F("not accessible at this address (%s, dieoffset: %s)",
1953 lex_cast_hex(pc).c_str(), lex_cast_hex(dwarf_dieoffset(die)).c_str()),
1954 e->tok);
440f755a
JS
1955
1956 default: /* Shouldn't happen. */
1957 case -1:
f9bbd346 1958 throw semantic_error (_F("dwarf_getlocation_addr failed, %s", dwarf_errmsg(-1)), e->tok);
440f755a
JS
1959 }
1960
87748e2b
MW
1961 // pc is in the dw address space of the current module, which is what
1962 // c_translate_location expects. get_cfa_ops wants the global dwfl address.
1963 Dwarf_Addr addr = pc + module_bias;
1964 Dwarf_Op *cfa_ops = get_cfa_ops (addr);
440f755a
JS
1965 return c_translate_location (pool, &loc2c_error, this,
1966 &loc2c_emit_address,
1967 1, 0 /* PR9768 */,
24c7957b 1968 pc, attr, expr, len, tail, fb_attr, cfa_ops);
440f755a
JS
1969}
1970
1971
1972void
1973dwflpp::print_members(Dwarf_Die *vardie, ostream &o)
1974{
1975 const int typetag = dwarf_tag (vardie);
1976
9c119951
JS
1977 if (typetag != DW_TAG_structure_type &&
1978 typetag != DW_TAG_class_type &&
1979 typetag != DW_TAG_union_type)
440f755a 1980 {
f9bbd346 1981 o << _F(" Error: %s isn't a struct/class/union", dwarf_type_name(vardie).c_str());
440f755a
JS
1982 return;
1983 }
1984
1985 // Try to get the first child of vardie.
1986 Dwarf_Die die_mem;
1987 Dwarf_Die *die = &die_mem;
1988 switch (dwarf_child (vardie, die))
1989 {
1990 case 1: // No children.
f9bbd346 1991 o << _F("%s is empty", dwarf_type_name(vardie).c_str());
440f755a
JS
1992 break;
1993
1994 case -1: // Error.
1995 default: // Shouldn't happen.
f1c8f8a5 1996 o << dwarf_type_name(vardie)
440f755a
JS
1997 << ": " << dwarf_errmsg (-1);
1998 break;
1999
2000 case 0: // Success.
2001 break;
2002 }
2003
2004 // Output each sibling's name to 'o'.
9c119951 2005 do
440f755a 2006 {
9c119951
JS
2007 int tag = dwarf_tag(die);
2008 if (tag != DW_TAG_member && tag != DW_TAG_inheritance)
2009 continue;
2010
23d106b9 2011 const char *member = dwarf_diename (die) ;
440f755a 2012
9c119951 2013 if ( tag == DW_TAG_member && member != NULL )
440f755a
JS
2014 o << " " << member;
2015 else
2016 {
f1c8f8a5 2017 Dwarf_Die temp_die;
3d1ad340 2018 if (!dwarf_attr_die (die, DW_AT_type, &temp_die))
440f755a 2019 {
f1c8f8a5
JS
2020 string source = dwarf_decl_file(die) ?: "<unknown source>";
2021 int line = -1;
2022 dwarf_decl_line(die, &line);
f9bbd346
LB
2023 clog << _F("\n Error in obtaining type attribute for anonymous "
2024 "member at %s:%d", source.c_str(), line);
440f755a
JS
2025 return;
2026 }
2027
2028 print_members(&temp_die,o);
2029 }
2030
440f755a 2031 }
9c119951 2032 while (dwarf_siblingof (die, die) == 0);
440f755a
JS
2033}
2034
2035
2036bool
c67847a0 2037dwflpp::find_struct_member(const target_symbol::component& c,
440f755a 2038 Dwarf_Die *parentdie,
440f755a 2039 Dwarf_Die *memberdie,
00730da1 2040 vector<Dwarf_Die>& dies,
440f755a
JS
2041 vector<Dwarf_Attribute>& locs)
2042{
2043 Dwarf_Attribute attr;
b57ba9b8 2044 Dwarf_Die die;
440f755a 2045
b57ba9b8 2046 switch (dwarf_child (parentdie, &die))
440f755a
JS
2047 {
2048 case 0: /* First child found. */
2049 break;
2050 case 1: /* No children. */
2051 return false;
2052 case -1: /* Error. */
2053 default: /* Shouldn't happen */
f1c8f8a5 2054 throw semantic_error (dwarf_type_name(parentdie) + ": "
440f755a 2055 + string (dwarf_errmsg (-1)),
c67847a0 2056 c.tok);
440f755a
JS
2057 }
2058
2059 do
2060 {
9c119951
JS
2061 int tag = dwarf_tag(&die);
2062 if (tag != DW_TAG_member && tag != DW_TAG_inheritance)
440f755a
JS
2063 continue;
2064
23d106b9 2065 const char *name = dwarf_diename(&die);
9c119951 2066 if (name == NULL || tag == DW_TAG_inheritance)
440f755a 2067 {
9c119951
JS
2068 // need to recurse for anonymous structs/unions and
2069 // for inherited members
440f755a 2070 Dwarf_Die subdie;
3d1ad340 2071 if (dwarf_attr_die (&die, DW_AT_type, &subdie) &&
00730da1 2072 find_struct_member(c, &subdie, memberdie, dies, locs))
440f755a
JS
2073 goto success;
2074 }
c67847a0 2075 else if (name == c.member)
440f755a
JS
2076 {
2077 *memberdie = die;
2078 goto success;
2079 }
2080 }
2081 while (dwarf_siblingof (&die, &die) == 0);
2082
2083 return false;
2084
2085success:
2086 /* As we unwind the recursion, we need to build the chain of
2087 * locations that got to the final answer. */
2088 if (dwarf_attr_integrate (&die, DW_AT_data_member_location, &attr))
00730da1
MW
2089 {
2090 dies.insert(dies.begin(), die);
2091 locs.insert(locs.begin(), attr);
2092 }
440f755a
JS
2093
2094 /* Union members don't usually have a location,
2095 * but just use the containing union's location. */
2096 else if (dwarf_tag(parentdie) != DW_TAG_union_type)
f9bbd346
LB
2097 throw semantic_error (_F("no location for field '%s':%s",
2098 c.member.c_str(), dwarf_errmsg(-1)), c.tok);
440f755a
JS
2099
2100 return true;
2101}
2102
2103
6ce303b8
JS
2104static inline void
2105dwarf_die_type (Dwarf_Die *die, Dwarf_Die *typedie_mem, const token *tok=NULL)
2106{
2107 if (!dwarf_attr_die (die, DW_AT_type, typedie_mem))
f9bbd346 2108 throw semantic_error (_F("cannot get type of field: %s", dwarf_errmsg(-1)), tok);
6ce303b8
JS
2109}
2110
2111
2112void
440f755a
JS
2113dwflpp::translate_components(struct obstack *pool,
2114 struct location **tail,
2115 Dwarf_Addr pc,
2116 const target_symbol *e,
2117 Dwarf_Die *vardie,
f3b5366d
JS
2118 Dwarf_Die *typedie,
2119 unsigned first)
440f755a 2120{
f3b5366d 2121 unsigned i = first;
440f755a
JS
2122 while (i < e->components.size())
2123 {
c67847a0
JS
2124 const target_symbol::component& c = e->components[i];
2125
440f755a
JS
2126 /* XXX: This would be desirable, but we don't get the target_symbol token,
2127 and printing that gives us the file:line number too early anyway. */
2128#if 0
2129 // Emit a marker to note which field is being access-attempted, to give
2130 // better error messages if deref() fails.
aca66a36 2131 string piece = string(...target_symbol token...) + string ("#") + lex_cast(components[i].second);
440f755a
JS
2132 obstack_printf (pool, "c->last_stmt = %s;", lex_cast_qstring(piece).c_str());
2133#endif
2134
6ce303b8 2135 switch (dwarf_tag (typedie))
440f755a
JS
2136 {
2137 case DW_TAG_typedef:
2138 case DW_TAG_const_type:
2139 case DW_TAG_volatile_type:
2140 /* Just iterate on the referent type. */
6ce303b8 2141 dwarf_die_type (typedie, typedie, c.tok);
440f755a
JS
2142 break;
2143
9c119951
JS
2144 case DW_TAG_reference_type:
2145 case DW_TAG_rvalue_reference_type:
5f36109e
JS
2146 if (pool)
2147 c_translate_pointer (pool, 1, 0 /* PR9768*/, typedie, tail);
6ce303b8 2148 dwarf_die_type (typedie, typedie, c.tok);
9c119951
JS
2149 break;
2150
440f755a 2151 case DW_TAG_pointer_type:
c4dddae6 2152 /* A pointer with no type is a void* -- can't dereference it. */
6ce303b8 2153 if (!dwarf_hasattr_integrate (typedie, DW_AT_type))
f9bbd346
LB
2154 throw semantic_error (_F("invalid access '%s' vs. %s", lex_cast(c).c_str(),
2155 dwarf_type_name(typedie).c_str()), c.tok);
c4dddae6 2156
5f36109e
JS
2157 if (pool)
2158 c_translate_pointer (pool, 1, 0 /* PR9768*/, typedie, tail);
6fda2dff
JS
2159 if (c.type != target_symbol::comp_literal_array_index &&
2160 c.type != target_symbol::comp_expression_array_index)
6ce303b8
JS
2161 {
2162 dwarf_die_type (typedie, typedie, c.tok);
2163 break;
2164 }
d52761f8 2165 /* else fall through as an array access */
440f755a
JS
2166
2167 case DW_TAG_array_type:
c67847a0 2168 if (c.type == target_symbol::comp_literal_array_index)
5f36109e
JS
2169 {
2170 if (pool)
2171 c_translate_array (pool, 1, 0 /* PR9768 */, typedie, tail,
2172 NULL, c.num_index);
2173 }
6fda2dff
JS
2174 else if (c.type == target_symbol::comp_expression_array_index)
2175 {
aca66a36 2176 string index = "THIS->index" + lex_cast(i);
5f36109e
JS
2177 if (pool)
2178 c_translate_array (pool, 1, 0 /* PR9768 */, typedie, tail,
2179 index.c_str(), 0);
6fda2dff 2180 }
440f755a 2181 else
f9bbd346
LB
2182 throw semantic_error (_F("invalid access '%s' for array type",
2183 lex_cast(c).c_str()), c.tok);
6ce303b8
JS
2184
2185 dwarf_die_type (typedie, typedie, c.tok);
2186 *vardie = *typedie;
2187 ++i;
440f755a
JS
2188 break;
2189
2190 case DW_TAG_structure_type:
2191 case DW_TAG_union_type:
9c119951 2192 case DW_TAG_class_type:
c67847a0 2193 if (c.type != target_symbol::comp_struct_member)
f9bbd346
LB
2194 throw semantic_error (_F("invalid access '%s' for %s",
2195 lex_cast(c).c_str(), dwarf_type_name(typedie).c_str()));
c67847a0 2196
6ce303b8 2197 if (dwarf_hasattr(typedie, DW_AT_declaration))
440f755a 2198 {
a44a7cb5 2199 Dwarf_Die *tmpdie = declaration_resolve(typedie);
440f755a 2200 if (tmpdie == NULL)
f9bbd346 2201 throw semantic_error (_F("unresolved %s", dwarf_type_name(typedie).c_str()), c.tok);
6ce303b8 2202 *typedie = *tmpdie;
440f755a
JS
2203 }
2204
2205 {
00730da1 2206 vector<Dwarf_Die> dies;
440f755a 2207 vector<Dwarf_Attribute> locs;
00730da1 2208 if (!find_struct_member(c, typedie, vardie, dies, locs))
440f755a 2209 {
72c5ecc2
JS
2210 /* Add a file:line hint for anonymous types */
2211 string source;
6ce303b8 2212 if (!dwarf_hasattr_integrate(typedie, DW_AT_name))
72c5ecc2
JS
2213 {
2214 int line;
6ce303b8
JS
2215 const char *file = dwarf_decl_file(typedie);
2216 if (file && dwarf_decl_line(typedie, &line) == 0)
72c5ecc2 2217 source = " (" + string(file) + ":"
aca66a36 2218 + lex_cast(line) + ")";
72c5ecc2
JS
2219 }
2220
440f755a
JS
2221 string alternatives;
2222 stringstream members;
6ce303b8 2223 print_members(typedie, members);
440f755a 2224 if (members.str().size() != 0)
72c5ecc2 2225 alternatives = " (alternatives:" + members.str() + ")";
f9bbd346
LB
2226 throw semantic_error(_F("unable to find member '%s' for %s%s%s", c.member.c_str(),
2227 dwarf_type_name(typedie).c_str(), source.c_str(),
2228 alternatives.c_str()), c.tok);
440f755a
JS
2229 }
2230
2231 for (unsigned j = 0; j < locs.size(); ++j)
5f36109e 2232 if (pool)
00730da1
MW
2233 translate_location (pool, &locs[j], &dies[j],
2234 pc, NULL, tail, e);
440f755a
JS
2235 }
2236
6ce303b8 2237 dwarf_die_type (vardie, typedie, c.tok);
440f755a
JS
2238 ++i;
2239 break;
2240
2241 case DW_TAG_enumeration_type:
440f755a 2242 case DW_TAG_base_type:
1e41115c 2243 throw semantic_error (_F("invalid access '%s' vs. %s", lex_cast(c).c_str(),
f9bbd346 2244 dwarf_type_name(typedie).c_str()), c.tok);
440f755a 2245 break;
f1c8f8a5 2246
440f755a 2247 case -1:
f9bbd346 2248 throw semantic_error (_F("cannot find type: %s", dwarf_errmsg(-1)), c.tok);
440f755a
JS
2249 break;
2250
2251 default:
f9bbd346
LB
2252 throw semantic_error (_F("%s: unexpected type tag %s", dwarf_type_name(typedie).c_str(),
2253 lex_cast(dwarf_tag(typedie)).c_str()), c.tok);
440f755a
JS
2254 break;
2255 }
440f755a 2256 }
440f755a
JS
2257}
2258
2259
6ce303b8
JS
2260void
2261dwflpp::resolve_unqualified_inner_typedie (Dwarf_Die *typedie,
2262 Dwarf_Die *innerdie,
440f755a
JS
2263 const target_symbol *e)
2264{
6ce303b8
JS
2265 int typetag = dwarf_tag (typedie);
2266 *innerdie = *typedie;
2267 while (typetag == DW_TAG_typedef ||
2268 typetag == DW_TAG_const_type ||
2269 typetag == DW_TAG_volatile_type)
440f755a 2270 {
6ce303b8 2271 if (!dwarf_attr_die (innerdie, DW_AT_type, innerdie))
f9bbd346 2272 throw semantic_error (_F("cannot get type of pointee: %s", dwarf_errmsg(-1)), e->tok);
6ce303b8 2273 typetag = dwarf_tag (innerdie);
440f755a 2274 }
440f755a
JS
2275}
2276
2277
2278void
2279dwflpp::translate_final_fetch_or_store (struct obstack *pool,
2280 struct location **tail,
2281 Dwarf_Addr module_bias,
6ce303b8
JS
2282 Dwarf_Die *vardie,
2283 Dwarf_Die *start_typedie,
440f755a
JS
2284 bool lvalue,
2285 const target_symbol *e,
2286 string &,
2287 string &,
2288 exp_type & ty)
2289{
2290 /* First boil away any qualifiers associated with the type DIE of
2291 the final location to be accessed. */
2292
6ce303b8
JS
2293 Dwarf_Die typedie_mem, *typedie = &typedie_mem;
2294 resolve_unqualified_inner_typedie (start_typedie, typedie, e);
440f755a 2295
03c75a4a
JS
2296 /* If we're looking for an address, then we can just provide what
2297 we computed to this point, without using a fetch/store. */
2298 if (e->addressof)
2299 {
2300 if (lvalue)
f9bbd346 2301 throw semantic_error (_("cannot write to member address"), e->tok);
03c75a4a 2302
6ce303b8 2303 if (dwarf_hasattr_integrate (vardie, DW_AT_bit_offset))
f9bbd346 2304 throw semantic_error (_("cannot take address of bit-field"), e->tok);
03c75a4a 2305
6ce303b8 2306 c_translate_addressof (pool, 1, 0, vardie, typedie, tail, "THIS->__retvalue");
03c75a4a
JS
2307 ty = pe_long;
2308 return;
2309 }
2310
440f755a
JS
2311 /* Then switch behavior depending on the type of fetch/store we
2312 want, and the type and pointer-ness of the final location. */
2313
6ce303b8 2314 int typetag = dwarf_tag (typedie);
440f755a
JS
2315 switch (typetag)
2316 {
2317 default:
f9bbd346
LB
2318 throw semantic_error (_F("unsupported type tag %s for %s", lex_cast(typetag).c_str(),
2319 dwarf_type_name(typedie).c_str()), e->tok);
440f755a
JS
2320 break;
2321
2322 case DW_TAG_structure_type:
9c119951 2323 case DW_TAG_class_type:
440f755a 2324 case DW_TAG_union_type:
f9bbd346
LB
2325 throw semantic_error (_F("'%s' is being accessed instead of a member",
2326 dwarf_type_name(typedie).c_str()), e->tok);
440f755a
JS
2327 break;
2328
2329 case DW_TAG_enumeration_type:
2330 case DW_TAG_base_type:
2331
2332 // Reject types we can't handle in systemtap
2333 {
440f755a
JS
2334 Dwarf_Attribute encoding_attr;
2335 Dwarf_Word encoding = (Dwarf_Word) -1;
2336 dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, &encoding_attr),
2337 & encoding);
2338 if (encoding < 0)
2339 {
2340 // clog << "bad type1 " << encoding << " diestr" << endl;
f9bbd346
LB
2341 throw semantic_error (_F("unsupported type (mystery ecoding %s for %s", lex_cast(encoding).c_str(),
2342 dwarf_type_name(typedie).c_str()), e->tok);
440f755a
JS
2343 }
2344
2345 if (encoding == DW_ATE_float
2346 || encoding == DW_ATE_complex_float
2347 /* XXX || many others? */)
2348 {
2349 // clog << "bad type " << encoding << " diestr" << endl;
f9bbd346
LB
2350 throw semantic_error (_F("unsupported type (encoding %s) for %s", lex_cast(encoding).c_str(),
2351 dwarf_type_name(typedie).c_str()), e->tok);
440f755a
JS
2352 }
2353 }
2354
2355 ty = pe_long;
2356 if (lvalue)
6ce303b8 2357 c_translate_store (pool, 1, 0 /* PR9768 */, vardie, typedie, tail,
440f755a
JS
2358 "THIS->value");
2359 else
6ce303b8 2360 c_translate_fetch (pool, 1, 0 /* PR9768 */, vardie, typedie, tail,
440f755a
JS
2361 "THIS->__retvalue");
2362 break;
2363
2364 case DW_TAG_array_type:
2365 case DW_TAG_pointer_type:
9c119951
JS
2366 case DW_TAG_reference_type:
2367 case DW_TAG_rvalue_reference_type:
440f755a 2368
440f755a
JS
2369 if (lvalue)
2370 {
2371 ty = pe_long;
2372 if (typetag == DW_TAG_array_type)
f9bbd346 2373 throw semantic_error (_("cannot write to array address"), e->tok);
9c119951
JS
2374 if (typetag == DW_TAG_reference_type ||
2375 typetag == DW_TAG_rvalue_reference_type)
f9bbd346 2376 throw semantic_error (_("cannot write to reference"), e->tok);
440f755a
JS
2377 assert (typetag == DW_TAG_pointer_type);
2378 c_translate_pointer_store (pool, 1, 0 /* PR9768 */, typedie, tail,
2379 "THIS->value");
2380 }
2381 else
2382 {
2383 // We have the pointer: cast it to an integral type via &(*(...))
2384
2385 // NB: per bug #1187, at one point char*-like types were
2386 // automagically converted here to systemtap string values.
2387 // For several reasons, this was taken back out, leaving
2388 // pointer-to-string "conversion" (copying) to tapset functions.
2389
2390 ty = pe_long;
2391 if (typetag == DW_TAG_array_type)
2392 c_translate_array (pool, 1, 0 /* PR9768 */, typedie, tail, NULL, 0);
2393 else
2394 c_translate_pointer (pool, 1, 0 /* PR9768 */, typedie, tail);
6ce303b8 2395 c_translate_addressof (pool, 1, 0 /* PR9768 */, NULL, NULL, tail,
440f755a
JS
2396 "THIS->__retvalue");
2397 }
440f755a
JS
2398 break;
2399 }
2400}
2401
2402
2403string
2404dwflpp::express_as_string (string prelude,
2405 string postlude,
2406 struct location *head)
2407{
e7899657
FCE
2408 size_t bufsz = 0;
2409 char *buf = 0; // NB: it would leak to pre-allocate a buffer here
440f755a
JS
2410 FILE *memstream = open_memstream (&buf, &bufsz);
2411 assert(memstream);
2412
2413 fprintf(memstream, "{\n");
2414 fprintf(memstream, "%s", prelude.c_str());
ebaa9618 2415
85dfc5c8
RM
2416 unsigned int stack_depth;
2417 bool deref = c_emit_location (memstream, head, 1, &stack_depth);
ebaa9618
JS
2418
2419 // Ensure that DWARF keeps loc2c to a "reasonable" stack size
2420 // 32 intptr_t leads to max 256 bytes on the stack
2421 if (stack_depth > 32)
2422 throw semantic_error("oversized DWARF stack");
2423
440f755a
JS
2424 fprintf(memstream, "%s", postlude.c_str());
2425 fprintf(memstream, " goto out;\n");
2426
2427 // dummy use of deref_fault label, to disable warning if deref() not used
2428 fprintf(memstream, "if (0) goto deref_fault;\n");
2429
2430 // XXX: deref flag not reliable; emit fault label unconditionally
2431 (void) deref;
2432 fprintf(memstream,
2433 "deref_fault:\n"
2434 " goto out;\n");
2435 fprintf(memstream, "}\n");
2436
2437 fclose (memstream);
2438 string result(buf);
2439 free (buf);
2440 return result;
2441}
2442
228af5c4
MW
2443Dwarf_Addr
2444dwflpp::vardie_from_symtable (Dwarf_Die *vardie, Dwarf_Addr *addr)
2445{
f450a7e3 2446 const char *name = dwarf_linkage_name (vardie) ?: dwarf_diename (vardie);
b0490786 2447
228af5c4 2448 if (sess.verbose > 2)
f9bbd346 2449 clog << _F("finding symtable address for %s\n", name);
228af5c4
MW
2450
2451 *addr = 0;
2452 int syms = dwfl_module_getsymtab (module);
f9bbd346 2453 dwfl_assert (_("Getting symbols"), syms >= 0);
228af5c4
MW
2454
2455 for (int i = 0; *addr == 0 && i < syms; i++)
2456 {
2457 GElf_Sym sym;
2458 GElf_Word shndxp;
2459 const char *symname = dwfl_module_getsym(module, i, &sym, &shndxp);
2460 if (symname
2461 && ! strcmp (name, symname)
2462 && sym.st_shndx != SHN_UNDEF
2463 && GELF_ST_TYPE (sym.st_info) == STT_OBJECT)
2464 *addr = sym.st_value;
2465 }
2466
2467 if (sess.verbose > 2)
f9bbd346 2468 clog << _F("found %s @0x%#" PRIx64 "\n", name, *addr);
228af5c4
MW
2469
2470 return *addr;
2471}
440f755a
JS
2472
2473string
729455a7 2474dwflpp::literal_stmt_for_local (vector<Dwarf_Die>& scopes,
440f755a
JS
2475 Dwarf_Addr pc,
2476 string const & local,
2477 const target_symbol *e,
2478 bool lvalue,
2479 exp_type & ty)
2480{
2481 Dwarf_Die vardie;
2482 Dwarf_Attribute fb_attr_mem, *fb_attr = NULL;
2483
729455a7 2484 fb_attr = find_variable_and_frame_base (scopes, pc, local, e,
440f755a
JS
2485 &vardie, &fb_attr_mem);
2486
2487 if (sess.verbose>2)
f9bbd346
LB
2488 clog << _F("finding location for local '%s' near address 0x%#" PRIx64
2489 ", module bias 0x%#" PRIx64 "\n", local.c_str(), pc, module_bias);
440f755a 2490
228af5c4
MW
2491#define obstack_chunk_alloc malloc
2492#define obstack_chunk_free free
2493
2494 struct obstack pool;
2495 obstack_init (&pool);
2496 struct location *tail = NULL;
2497
2498 /* Given $foo->bar->baz[NN], translate the location of foo. */
2499
2500 struct location *head;
2501
440f755a 2502 Dwarf_Attribute attr_mem;
03ba05b6
MW
2503 if (dwarf_attr_integrate (&vardie, DW_AT_const_value, &attr_mem) == NULL
2504 && dwarf_attr_integrate (&vardie, DW_AT_location, &attr_mem) == NULL)
440f755a 2505 {
228af5c4 2506 Dwarf_Op addr_loc;
e9483a80 2507 memset(&addr_loc, 0, sizeof(Dwarf_Op));
228af5c4
MW
2508 addr_loc.atom = DW_OP_addr;
2509 // If it is an external variable try the symbol table. PR10622.
2510 if (dwarf_attr_integrate (&vardie, DW_AT_external, &attr_mem) != NULL
2511 && vardie_from_symtable (&vardie, &addr_loc.number) != 0)
2512 {
2513 head = c_translate_location (&pool, &loc2c_error, this,
2514 &loc2c_emit_address,
2515 1, 0, pc,
2516 NULL, &addr_loc, 1, &tail, NULL, NULL);
2517 }
2518 else
f9bbd346
LB
2519 throw semantic_error (_F("failed to retrieve location attribute for local '%s' (dieoffset: %s)",
2520 local.c_str(), lex_cast_hex(dwarf_dieoffset(&vardie)).c_str()), e->tok);
440f755a 2521 }
228af5c4 2522 else
00730da1 2523 head = translate_location (&pool, &attr_mem, &vardie, pc, fb_attr, &tail, e);
440f755a 2524
6ce303b8
JS
2525 /* Translate the ->bar->baz[NN] parts. */
2526
2527 Dwarf_Die typedie;
2528 if (dwarf_attr_die (&vardie, DW_AT_type, &typedie) == NULL)
f9bbd346 2529 throw semantic_error(_F("failed to retrieve type attribute for local '%s'", local.c_str()), e->tok);
440f755a 2530
6ce303b8 2531 translate_components (&pool, &tail, pc, e, &vardie, &typedie);
440f755a
JS
2532
2533 /* Translate the assignment part, either
2534 x = $foo->bar->baz[NN]
2535 or
2536 $foo->bar->baz[NN] = x
2537 */
2538
2539 string prelude, postlude;
2540 translate_final_fetch_or_store (&pool, &tail, module_bias,
6ce303b8 2541 &vardie, &typedie, lvalue, e,
440f755a
JS
2542 prelude, postlude, ty);
2543
2544 /* Write the translation to a string. */
e7899657
FCE
2545 string result = express_as_string(prelude, postlude, head);
2546 obstack_free (&pool, 0);
2547 return result;
440f755a
JS
2548}
2549
5f36109e
JS
2550Dwarf_Die*
2551dwflpp::type_die_for_local (vector<Dwarf_Die>& scopes,
2552 Dwarf_Addr pc,
2553 string const & local,
2554 const target_symbol *e,
2555 Dwarf_Die *typedie)
2556{
2557 Dwarf_Die vardie;
2558 Dwarf_Attribute attr_mem;
2559
2560 find_variable_and_frame_base (scopes, pc, local, e, &vardie, &attr_mem);
2561
2562 if (dwarf_attr_die (&vardie, DW_AT_type, typedie) == NULL)
f9bbd346 2563 throw semantic_error(_F("failed to retrieve type attribute for local '%s'", local.c_str()), e->tok);
5f36109e
JS
2564
2565 translate_components (NULL, NULL, pc, e, &vardie, typedie);
2566 return typedie;
2567}
2568
440f755a
JS
2569
2570string
2571dwflpp::literal_stmt_for_return (Dwarf_Die *scope_die,
2572 Dwarf_Addr pc,
2573 const target_symbol *e,
2574 bool lvalue,
2575 exp_type & ty)
2576{
2577 if (sess.verbose>2)
f9bbd346
LB
2578 clog << _F("literal_stmt_for_return: finding return value for %s (%s)\n",
2579 (dwarf_diename(scope_die) ?: "<unknown>"), (dwarf_diename(cu) ?: "<unknown>"));
440f755a
JS
2580
2581 struct obstack pool;
2582 obstack_init (&pool);
2583 struct location *tail = NULL;
2584
2585 /* Given $return->bar->baz[NN], translate the location of return. */
2586 const Dwarf_Op *locops;
2587 int nlocops = dwfl_module_return_value_location (module, scope_die,
2588 &locops);
2589 if (nlocops < 0)
2590 {
f9bbd346
LB
2591 throw semantic_error(_F("failed to retrieve return value location for %s (%s)",
2592 (dwarf_diename(scope_die) ?: "<unknown>"),
2593 (dwarf_diename(cu) ?: "<unknown>")), e->tok);
440f755a
JS
2594 }
2595 // the function has no return value (e.g. "void" in C)
2596 else if (nlocops == 0)
2597 {
f9bbd346
LB
2598 throw semantic_error(_F("function %s (%s) has no return value",
2599 (dwarf_diename(scope_die) ?: "<unknown>"),
2600 (dwarf_diename(cu) ?: "<unknown>")), e->tok);
440f755a
JS
2601 }
2602
2603 struct location *head = c_translate_location (&pool, &loc2c_error, this,
2604 &loc2c_emit_address,
2605 1, 0 /* PR9768 */,
24c7957b 2606 pc, NULL, locops, nlocops,
00b01a99 2607 &tail, NULL, NULL);
440f755a
JS
2608
2609 /* Translate the ->bar->baz[NN] parts. */
2610
6ce303b8
JS
2611 Dwarf_Die vardie = *scope_die, typedie;
2612 if (dwarf_attr_die (&vardie, DW_AT_type, &typedie) == NULL)
f9bbd346
LB
2613 throw semantic_error(_F("failed to retrieve return value type attribute for %s (%s)",
2614 (dwarf_diename(&vardie) ?: "<unknown>"),
2615 (dwarf_diename(cu) ?: "<unknown>")), e->tok);
440f755a 2616
6ce303b8 2617 translate_components (&pool, &tail, pc, e, &vardie, &typedie);
440f755a
JS
2618
2619 /* Translate the assignment part, either
2620 x = $return->bar->baz[NN]
2621 or
2622 $return->bar->baz[NN] = x
2623 */
2624
2625 string prelude, postlude;
2626 translate_final_fetch_or_store (&pool, &tail, module_bias,
6ce303b8 2627 &vardie, &typedie, lvalue, e,
440f755a
JS
2628 prelude, postlude, ty);
2629
2630 /* Write the translation to a string. */
e7899657
FCE
2631 string result = express_as_string(prelude, postlude, head);
2632 obstack_free (&pool, 0);
2633 return result;
440f755a
JS
2634}
2635
5f36109e
JS
2636Dwarf_Die*
2637dwflpp::type_die_for_return (Dwarf_Die *scope_die,
2638 Dwarf_Addr pc,
2639 const target_symbol *e,
2640 Dwarf_Die *typedie)
2641{
2642 Dwarf_Die vardie = *scope_die;
2643 if (dwarf_attr_die (&vardie, DW_AT_type, typedie) == NULL)
f9bbd346
LB
2644 throw semantic_error(_F("failed to retrieve return value type attribute for %s (%s)",
2645 (dwarf_diename(&vardie) ?: "<unknown>"),
2646 (dwarf_diename(cu) ?: "<unknown>")), e->tok);
5f36109e
JS
2647
2648 translate_components (NULL, NULL, pc, e, &vardie, typedie);
2649 return typedie;
2650}
2651
440f755a
JS
2652
2653string
6ce303b8 2654dwflpp::literal_stmt_for_pointer (Dwarf_Die *start_typedie,
440f755a
JS
2655 const target_symbol *e,
2656 bool lvalue,
2657 exp_type & ty)
2658{
2659 if (sess.verbose>2)
f9bbd346
LB
2660 clog << _F("literal_stmt_for_pointer: finding value for %s (%s)\n",
2661 dwarf_type_name(start_typedie).c_str(), (dwarf_diename(cu) ?: "<unknown>"));
440f755a
JS
2662
2663 struct obstack pool;
2664 obstack_init (&pool);
2665 struct location *head = c_translate_argument (&pool, &loc2c_error, this,
2666 &loc2c_emit_address,
2667 1, "THIS->pointer");
2668 struct location *tail = head;
2669
2670 /* Translate the ->bar->baz[NN] parts. */
2671
f3b5366d 2672 unsigned first = 0;
6ce303b8 2673 Dwarf_Die typedie = *start_typedie, vardie = typedie;
f3b5366d
JS
2674
2675 /* As a special case when typedie is not an array or pointer, we can allow
2676 * array indexing on THIS->pointer instead (since we do know the pointee type
2677 * and can determine its size). PR11556. */
2678 const target_symbol::component* c =
2679 e->components.empty() ? NULL : &e->components[0];
2680 if (c && (c->type == target_symbol::comp_literal_array_index ||
2681 c->type == target_symbol::comp_expression_array_index))
2682 {
2683 resolve_unqualified_inner_typedie (&typedie, &typedie, e);
2684 int typetag = dwarf_tag (&typedie);
2685 if (typetag != DW_TAG_pointer_type &&
2686 typetag != DW_TAG_array_type)
2687 {
2688 if (c->type == target_symbol::comp_literal_array_index)
2689 c_translate_array_pointer (&pool, 1, &typedie, &tail, NULL, c->num_index);
2690 else
2691 c_translate_array_pointer (&pool, 1, &typedie, &tail, "THIS->index0", 0);
2692 ++first;
2693 }
2694 }
2695
2696 /* Now translate the rest normally. */
2697
2698 translate_components (&pool, &tail, 0, e, &vardie, &typedie, first);
440f755a
JS
2699
2700 /* Translate the assignment part, either
2701 x = (THIS->pointer)->bar->baz[NN]
2702 or
2703 (THIS->pointer)->bar->baz[NN] = x
2704 */
2705
2706 string prelude, postlude;
2707 translate_final_fetch_or_store (&pool, &tail, module_bias,
6ce303b8 2708 &vardie, &typedie, lvalue, e,
440f755a
JS
2709 prelude, postlude, ty);
2710
2711 /* Write the translation to a string. */
e7899657
FCE
2712 string result = express_as_string(prelude, postlude, head);
2713 obstack_free (&pool, 0);
2714 return result;
440f755a
JS
2715}
2716
5f36109e
JS
2717Dwarf_Die*
2718dwflpp::type_die_for_pointer (Dwarf_Die *start_typedie,
2719 const target_symbol *e,
2720 Dwarf_Die *typedie)
2721{
2722 unsigned first = 0;
2723 *typedie = *start_typedie;
2724 Dwarf_Die vardie = *typedie;
2725
2726 /* Handle the same PR11556 case as above. */
2727 const target_symbol::component* c =
2728 e->components.empty() ? NULL : &e->components[0];
2729 if (c && (c->type == target_symbol::comp_literal_array_index ||
2730 c->type == target_symbol::comp_expression_array_index))
2731 {
2732 resolve_unqualified_inner_typedie (typedie, typedie, e);
2733 int typetag = dwarf_tag (typedie);
2734 if (typetag != DW_TAG_pointer_type &&
2735 typetag != DW_TAG_array_type)
2736 ++first;
2737 }
2738
2739 translate_components (NULL, NULL, 0, e, &vardie, typedie, first);
2740 return typedie;
2741}
2742
440f755a 2743
27646582
JS
2744static bool
2745in_kprobes_function(systemtap_session& sess, Dwarf_Addr addr)
2746{
2747 if (sess.sym_kprobes_text_start != 0 && sess.sym_kprobes_text_end != 0)
2748 {
2749 // If the probe point address is anywhere in the __kprobes
2750 // address range, we can't use this probe point.
2751 if (addr >= sess.sym_kprobes_text_start && addr < sess.sym_kprobes_text_end)
2752 return true;
2753 }
2754 return false;
2755}
2756
2757
2758bool
2759dwflpp::blacklisted_p(const string& funcname,
2760 const string& filename,
2761 int,
2762 const string& module,
27646582
JS
2763 Dwarf_Addr addr,
2764 bool has_return)
2765{
2766 if (!blacklist_enabled)
2767 return false; // no blacklist for userspace
2768
789448a3 2769 string section = get_blacklist_section(addr);
178ac3f6 2770 if (!regexec (&blacklist_section, section.c_str(), 0, NULL, 0))
27646582
JS
2771 {
2772 // NB: module .exit. routines could be probed in theory:
2773 // if the exit handler in "struct module" is diverted,
2774 // first inserting the kprobes
2775 // then allowing the exit code to run
2776 // then removing these kprobes
2777 if (sess.verbose>1)
f9bbd346 2778 clog << _(" skipping - init/exit");
27646582
JS
2779 return true;
2780 }
2781
2782 // Check for function marked '__kprobes'.
2783 if (module == TOK_KERNEL && in_kprobes_function(sess, addr))
2784 {
2785 if (sess.verbose>1)
f9bbd346 2786 clog << _(" skipping - __kprobes");
27646582
JS
2787 return true;
2788 }
2789
2790 // Check probe point against blacklist.
2791 int goodfn = regexec (&blacklist_func, funcname.c_str(), 0, NULL, 0);
2792 if (has_return)
2793 goodfn = goodfn && regexec (&blacklist_func_ret, funcname.c_str(), 0, NULL, 0);
2794 int goodfile = regexec (&blacklist_file, filename.c_str(), 0, NULL, 0);
2795
2796 if (! (goodfn && goodfile))
2797 {
2798 if (sess.guru_mode)
2799 {
2800 if (sess.verbose>1)
f9bbd346 2801 clog << _(" guru mode enabled - ignoring blacklist");
27646582
JS
2802 }
2803 else
2804 {
2805 if (sess.verbose>1)
f9bbd346 2806 clog << _(" skipping - blacklisted");
27646582
JS
2807 return true;
2808 }
2809 }
2810
2811 // This probe point is not blacklisted.
2812 return false;
2813}
2814
2815
2816void
2817dwflpp::build_blacklist()
2818{
2819 // We build up the regexps in these strings
2820
2821 // Add ^ anchors at the front; $ will be added just before regcomp.
2822
2823 string blfn = "^(";
2824 string blfn_ret = "^(";
2825 string blfile = "^(";
178ac3f6
JS
2826 string blsection = "^(";
2827
2828 blsection += "\\.init\\."; // first alternative, no "|"
2829 blsection += "|\\.exit\\.";
2830 blsection += "|\\.devinit\\.";
2831 blsection += "|\\.devexit\\.";
2832 blsection += "|\\.cpuinit\\.";
2833 blsection += "|\\.cpuexit\\.";
2834 blsection += "|\\.meminit\\.";
2835 blsection += "|\\.memexit\\.";
27646582 2836
b969d16b
JS
2837 blfile += "kernel/kprobes\\.c"; // first alternative, no "|"
2838 blfile += "|arch/.*/kernel/kprobes\\.c";
27646582 2839 // Older kernels need ...
b969d16b
JS
2840 blfile += "|include/asm/io\\.h";
2841 blfile += "|include/asm/bitops\\.h";
27646582 2842 // While newer ones need ...
b969d16b
JS
2843 blfile += "|arch/.*/include/asm/io\\.h";
2844 blfile += "|arch/.*/include/asm/bitops\\.h";
2845 blfile += "|drivers/ide/ide-iops\\.c";
27646582
JS
2846
2847 // XXX: it would be nice if these blacklisted functions were pulled
2848 // in dynamically, instead of being statically defined here.
2849 // Perhaps it could be populated from script files. A "noprobe
2850 // kernel.function("...")" construct might do the trick.
2851
2852 // Most of these are marked __kprobes in newer kernels. We list
2853 // them here (anyway) so the translator can block them on older
2854 // kernels that don't have the __kprobes function decorator. This
2855 // also allows detection of problems at translate- rather than
2856 // run-time.
2857
2858 blfn += "atomic_notifier_call_chain"; // first blfn; no "|"
2859 blfn += "|default_do_nmi";
2860 blfn += "|__die";
2861 blfn += "|die_nmi";
2862 blfn += "|do_debug";
2863 blfn += "|do_general_protection";
2864 blfn += "|do_int3";
2865 blfn += "|do_IRQ";
2866 blfn += "|do_page_fault";
2867 blfn += "|do_sparc64_fault";
2868 blfn += "|do_trap";
2869 blfn += "|dummy_nmi_callback";
2870 blfn += "|flush_icache_range";
2871 blfn += "|ia64_bad_break";
2872 blfn += "|ia64_do_page_fault";
2873 blfn += "|ia64_fault";
2874 blfn += "|io_check_error";
2875 blfn += "|mem_parity_error";
2876 blfn += "|nmi_watchdog_tick";
2877 blfn += "|notifier_call_chain";
2878 blfn += "|oops_begin";
2879 blfn += "|oops_end";
2880 blfn += "|program_check_exception";
2881 blfn += "|single_step_exception";
2882 blfn += "|sync_regs";
2883 blfn += "|unhandled_fault";
2884 blfn += "|unknown_nmi_error";
2885
2886 // Lots of locks
2887 blfn += "|.*raw_.*lock.*";
2888 blfn += "|.*read_.*lock.*";
2889 blfn += "|.*write_.*lock.*";
2890 blfn += "|.*spin_.*lock.*";
2891 blfn += "|.*rwlock_.*lock.*";
2892 blfn += "|.*rwsem_.*lock.*";
2893 blfn += "|.*mutex_.*lock.*";
2894 blfn += "|raw_.*";
2895 blfn += "|.*seq_.*lock.*";
2896
2897 // atomic functions
2898 blfn += "|atomic_.*";
2899 blfn += "|atomic64_.*";
2900
2901 // few other problematic cases
2902 blfn += "|get_bh";
2903 blfn += "|put_bh";
2904
2905 // Experimental
2906 blfn += "|.*apic.*|.*APIC.*";
2907 blfn += "|.*softirq.*";
2908 blfn += "|.*IRQ.*";
2909 blfn += "|.*_intr.*";
2910 blfn += "|__delay";
2911 blfn += "|.*kernel_text.*";
2912 blfn += "|get_current";
2913 blfn += "|current_.*";
2914 blfn += "|.*exception_tables.*";
2915 blfn += "|.*setup_rt_frame.*";
2916
2917 // PR 5759, CONFIG_PREEMPT kernels
2918 blfn += "|.*preempt_count.*";
2919 blfn += "|preempt_schedule";
2920
2921 // These functions don't return, so return probes would never be recovered
2922 blfn_ret += "do_exit"; // no "|"
2923 blfn_ret += "|sys_exit";
2924 blfn_ret += "|sys_exit_group";
2925
2926 // __switch_to changes "current" on x86_64 and i686, so return probes
2927 // would cause kernel panic, and it is marked as "__kprobes" on x86_64
2928 if (sess.architecture == "x86_64")
2929 blfn += "|__switch_to";
2930 if (sess.architecture == "i686")
2931 blfn_ret += "|__switch_to";
2932
08ee70c3
FCE
2933 // RHEL6 pre-beta 2.6.32-19.el6
2934 blfn += "|special_mapping_.*";
2fd5495a
FCE
2935 blfn += "|.*_pte_.*"; // or "|smaps_pte_range";
2936 blfile += "|fs/seq_file\\.c";
08ee70c3 2937
27646582
JS
2938 blfn += ")$";
2939 blfn_ret += ")$";
2940 blfile += ")$";
178ac3f6 2941 blsection += ")"; // NB: no $, sections match just the beginning
27646582
JS
2942
2943 if (sess.verbose > 2)
2944 {
f9bbd346 2945 clog << _("blacklist regexps:") << endl;
27646582
JS
2946 clog << "blfn: " << blfn << endl;
2947 clog << "blfn_ret: " << blfn_ret << endl;
2948 clog << "blfile: " << blfile << endl;
178ac3f6 2949 clog << "blsection: " << blsection << endl;
27646582
JS
2950 }
2951
2952 int rc = regcomp (& blacklist_func, blfn.c_str(), REG_NOSUB|REG_EXTENDED);
f9bbd346 2953 if (rc) throw semantic_error (_("blacklist_func regcomp failed"));
27646582 2954 rc = regcomp (& blacklist_func_ret, blfn_ret.c_str(), REG_NOSUB|REG_EXTENDED);
f9bbd346 2955 if (rc) throw semantic_error (_("blacklist_func_ret regcomp failed"));
27646582 2956 rc = regcomp (& blacklist_file, blfile.c_str(), REG_NOSUB|REG_EXTENDED);
f9bbd346 2957 if (rc) throw semantic_error (_("blacklist_file regcomp failed"));
178ac3f6 2958 rc = regcomp (& blacklist_section, blsection.c_str(), REG_NOSUB|REG_EXTENDED);
f9bbd346 2959 if (rc) throw semantic_error (_("blacklist_section regcomp failed"));
27646582
JS
2960
2961 blacklist_enabled = true;
2962}
2963
2964
2965string
2966dwflpp::get_blacklist_section(Dwarf_Addr addr)
2967{
2968 string blacklist_section;
2969 Dwarf_Addr bias;
2970 // We prefer dwfl_module_getdwarf to dwfl_module_getelf here,
2971 // because dwfl_module_getelf can force costly section relocations
2972 // we don't really need, while either will do for this purpose.
2973 Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (module, &bias))
2974 ?: dwfl_module_getelf (module, &bias));
2975
2976 Dwarf_Addr offset = addr - bias;
2977 if (elf)
2978 {
2979 Elf_Scn* scn = 0;
2980 size_t shstrndx;
fcc30d6d 2981 dwfl_assert ("getshdrstrndx", elf_getshdrstrndx (elf, &shstrndx));
27646582
JS
2982 while ((scn = elf_nextscn (elf, scn)) != NULL)
2983 {
2984 GElf_Shdr shdr_mem;
2985 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2986 if (! shdr)
2987 continue; // XXX error?
2988
2989 if (!(shdr->sh_flags & SHF_ALLOC))
2990 continue;
2991
2992 GElf_Addr start = shdr->sh_addr;
2993 GElf_Addr end = start + shdr->sh_size;
2994 if (! (offset >= start && offset < end))
2995 continue;
2996
2997 blacklist_section = elf_strptr (elf, shstrndx, shdr->sh_name);
2998 break;
2999 }
3000 }
3001 return blacklist_section;
3002}
3003
3004
fea74777
SC
3005/* Find the section named 'section_name' in the current module
3006 * returning the section header using 'shdr_mem' */
3007
3008GElf_Shdr *
448a86b7 3009dwflpp::get_section(string section_name, GElf_Shdr *shdr_mem, Elf **elf_ret)
fea74777
SC
3010{
3011 GElf_Shdr *shdr = NULL;
3012 Elf* elf;
3013 Dwarf_Addr bias;
3014 size_t shstrndx;
3015
3016 // Explicitly look in the main elf file first.
3017 elf = dwfl_module_getelf (module, &bias);
3018 Elf_Scn *probe_scn = NULL;
3019
3020 dwfl_assert ("getshdrstrndx", elf_getshdrstrndx (elf, &shstrndx));
3021
3022 bool have_section = false;
3023
3024 while ((probe_scn = elf_nextscn (elf, probe_scn)))
3025 {
3026 shdr = gelf_getshdr (probe_scn, shdr_mem);
3027 assert (shdr != NULL);
3028
3029 if (elf_strptr (elf, shstrndx, shdr->sh_name) == section_name)
3030 {
3031 have_section = true;
3032 break;
3033 }
3034 }
3035
3036 // Older versions may put the section in the debuginfo dwarf file,
3037 // so check if it actually exists, if not take a look in the debuginfo file
3038 if (! have_section || (have_section && shdr->sh_type == SHT_NOBITS))
3039 {
3040 elf = dwarf_getelf (dwfl_module_getdwarf (module, &bias));
3041 if (! elf)
448a86b7 3042 return NULL;
fea74777
SC
3043 dwfl_assert ("getshdrstrndx", elf_getshdrstrndx (elf, &shstrndx));
3044 probe_scn = NULL;
3045 while ((probe_scn = elf_nextscn (elf, probe_scn)))
3046 {
3047 shdr = gelf_getshdr (probe_scn, shdr_mem);
3048 if (elf_strptr (elf, shstrndx, shdr->sh_name) == section_name)
3049 {
3050 have_section = true;
3051 break;
3052 }
3053 }
3054 }
3055
3056 if (!have_section)
3057 return NULL;
448a86b7
JS
3058
3059 if (elf_ret)
3060 *elf_ret = elf;
3061 return shdr;
fea74777
SC
3062}
3063
3064
27646582 3065Dwarf_Addr
789448a3 3066dwflpp::relocate_address(Dwarf_Addr dw_addr, string& reloc_section)
27646582 3067{
d2309c6c
MW
3068 // PR10273
3069 // libdw address, so adjust for bias gotten from dwfl_module_getdwarf
3070 Dwarf_Addr reloc_addr = dw_addr + module_bias;
27646582
JS
3071 if (!module)
3072 {
3073 assert(module_name == TOK_KERNEL);
3074 reloc_section = "";
27646582
JS
3075 }
3076 else if (dwfl_module_relocations (module) > 0)
3077 {
3078 // This is a relocatable module; libdwfl already knows its
3079 // sections, so we can relativize addr.
3080 int idx = dwfl_module_relocate_address (module, &reloc_addr);
3081 const char* r_s = dwfl_module_relocation_info (module, idx, NULL);
3082 if (r_s)
3083 reloc_section = r_s;
27646582
JS
3084
3085 if (reloc_section == "" && dwfl_module_relocations (module) == 1)
27646582 3086 reloc_section = ".dynamic";
27646582
JS
3087 }
3088 else
789448a3 3089 reloc_section = ".absolute";
27646582
JS
3090 return reloc_addr;
3091}
3092
88eaee9f
MW
3093/* Returns the call frame address operations for the given program counter
3094 * in the libdw address space.
3095 */
00b01a99
MW
3096Dwarf_Op *
3097dwflpp::get_cfa_ops (Dwarf_Addr pc)
3098{
3099 Dwarf_Op *cfa_ops = NULL;
3100
88eaee9f
MW
3101 if (sess.verbose > 2)
3102 clog << "get_cfa_ops @0x" << hex << pc << dec
3103 << ", module_start @0x" << hex << module_start << dec << endl;
3104
495b9d7c 3105#if _ELFUTILS_PREREQ(0,142)
6a38401c 3106 // Try debug_frame first, then fall back on eh_frame.
87748e2b
MW
3107 size_t cfa_nops = 0;
3108 Dwarf_Addr bias = 0;
3109 Dwarf_Frame *frame = NULL;
00b01a99
MW
3110 Dwarf_CFI *cfi = dwfl_module_dwarf_cfi (module, &bias);
3111 if (cfi != NULL)
3112 {
88eaee9f
MW
3113 if (sess.verbose > 3)
3114 clog << "got dwarf cfi bias: 0x" << hex << bias << dec << endl;
87748e2b 3115 if (dwarf_cfi_addrframe (cfi, pc - bias, &frame) == 0)
97f529ab 3116 dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops);
88eaee9f
MW
3117 else if (sess.verbose > 3)
3118 clog << "dwarf_cfi_addrframe failed: " << dwarf_errmsg(-1) << endl;
00b01a99 3119 }
88eaee9f
MW
3120 else if (sess.verbose > 3)
3121 clog << "dwfl_module_dwarf_cfi failed: " << dwfl_errmsg(-1) << endl;
3122
00b01a99
MW
3123 if (cfa_ops == NULL)
3124 {
3125 cfi = dwfl_module_eh_cfi (module, &bias);
3126 if (cfi != NULL)
3127 {
88eaee9f
MW
3128 if (sess.verbose > 3)
3129 clog << "got eh cfi bias: 0x" << hex << bias << dec << endl;
00b01a99 3130 Dwarf_Frame *frame = NULL;
87748e2b 3131 if (dwarf_cfi_addrframe (cfi, pc - bias, &frame) == 0)
97f529ab 3132 dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops);
88eaee9f
MW
3133 else if (sess.verbose > 3)
3134 clog << "dwarf_cfi_addrframe failed: " << dwarf_errmsg(-1) << endl;
00b01a99 3135 }
88eaee9f
MW
3136 else if (sess.verbose > 3)
3137 clog << "dwfl_module_eh_cfi failed: " << dwfl_errmsg(-1) << endl;
3138
00b01a99 3139 }
00b01a99
MW
3140#endif
3141
88eaee9f 3142 if (sess.verbose > 2)
87748e2b
MW
3143 {
3144 if (cfa_ops == NULL)
f9bbd346 3145 clog << _("not found cfa") << endl;
495b9d7c 3146#if _ELFUTILS_PREREQ(0,142)
87748e2b
MW
3147 else
3148 {
3149 Dwarf_Addr frame_start, frame_end;
3150 bool frame_signalp;
3151 int info = dwarf_frame_info (frame, &frame_start, &frame_end,
3152 &frame_signalp);
f9bbd346
LB
3153 clog << _F("found cfa, info: %d [start: 0x%#" PRIx64 ", end: 0x%#" PRIx64
3154 ", nops: %zu", info, frame_start, frame_end, cfa_nops) << endl;
87748e2b 3155 }
495b9d7c 3156#endif
87748e2b 3157 }
88eaee9f 3158
00b01a99
MW
3159 return cfa_ops;
3160}
c8ad0687 3161
440f755a 3162/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.481619 seconds and 5 git commands to generate.