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