]> sourceware.org Git - systemtap.git/blame - dwflpp.cxx
Fix: stap/staprun deadlocks when probing ends.
[systemtap.git] / dwflpp.cxx
CommitLineData
440f755a 1// C++ interface to dwfl
4c5d9906 2// Copyright (C) 2005-2013 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
ae4163d9
MW
59// Older glibc elf.h don't know about this new constant.
60#ifndef STB_GNU_UNIQUE
61#define STB_GNU_UNIQUE 10
62#endif
63
440f755a 64
9aa8ffce
JS
65// debug flag to compare to the uncached version from libdw
66// #define DEBUG_DWFLPP_GETSCOPES 1
67
68
440f755a
JS
69using namespace std;
70using namespace __gnu_cxx;
71
72
73static string TOK_KERNEL("kernel");
74
75
ae2552da 76dwflpp::dwflpp(systemtap_session & session, const string& name, bool kernel_p):
d0b4a5ff 77 sess(session), module(NULL), module_bias(0), mod_info(NULL),
68983551 78 module_start(0), module_end(0), cu(NULL),
74fe61bc
LB
79 module_dwarf(NULL), function(NULL), blacklist_func(), blacklist_func_ret(),
80 blacklist_file(), blacklist_enabled(false)
440f755a 81{
ae2552da 82 if (kernel_p)
2eb99c62 83 setup_kernel(name, session);
440f755a 84 else
0c16d512
JS
85 {
86 vector<string> modules;
87 modules.push_back(name);
88 setup_user(modules);
89 }
90}
91
59c11f91
MW
92dwflpp::dwflpp(systemtap_session & session, const vector<string>& names,
93 bool kernel_p):
0c16d512 94 sess(session), module(NULL), module_bias(0), mod_info(NULL),
68983551 95 module_start(0), module_end(0), cu(NULL),
729455a7 96 module_dwarf(NULL), function(NULL), blacklist_enabled(false)
0c16d512 97{
59c11f91
MW
98 if (kernel_p)
99 setup_kernel(names);
100 else
101 setup_user(names);
440f755a
JS
102}
103
440f755a
JS
104dwflpp::~dwflpp()
105{
c9efa5c9
JS
106 delete_map(module_cu_cache);
107 delete_map(cu_function_cache);
4df79aaf 108 delete_map(mod_function_cache);
c9efa5c9
JS
109 delete_map(cu_inl_function_cache);
110 delete_map(global_alias_cache);
111 delete_map(cu_die_parent_cache);
9aa8ffce 112
68983551 113 dwfl_ptr.reset();
435f53a7
FCE
114 // NB: don't "delete mod_info;", as that may be shared
115 // between dwflpp instances, and are stored in
116 // session.module_cache[] anyway.
117}
118
119
120module_cache::~module_cache ()
121{
122 delete_map(cache);
440f755a
JS
123}
124
125
440f755a
JS
126void
127dwflpp::get_module_dwarf(bool required, bool report)
128{
129 module_dwarf = dwfl_module_getdwarf(module, &module_bias);
130 mod_info->dwarf_status = (module_dwarf ? info_present : info_absent);
131 if (!module_dwarf && report)
132 {
f9bbd346 133 string msg = _("cannot find ");
440f755a
JS
134 if (module_name == "")
135 msg += "kernel";
136 else
137 msg += string("module ") + module_name;
138 msg += " debuginfo";
139
140 int i = dwfl_errno();
141 if (i)
142 msg += string(": ") + dwfl_errmsg (i);
143
555fa669
FCE
144 msg += " [man warning::debuginfo]";
145
2ed04863
WC
146 /* add module_name to list to find rpm */
147 find_debug_rpms(sess, module_name.c_str());
148
440f755a 149 if (required)
dc09353a 150 throw SEMANTIC_ERROR (msg);
2713ea24
CM
151 else
152 sess.print_warning(msg);
440f755a
JS
153 }
154}
155
156
157void
158dwflpp::focus_on_module(Dwfl_Module * m, module_info * mi)
159{
160 module = m;
161 mod_info = mi;
162 if (m)
163 {
f517ee24
JS
164 module_name = dwfl_module_info(module, NULL, &module_start, &module_end,
165 NULL, NULL, NULL, NULL) ?: "module";
440f755a
JS
166 }
167 else
168 {
169 assert(mi && mi->name && mi->name == TOK_KERNEL);
170 module_name = mi->name;
171 module_start = 0;
172 module_end = 0;
173 module_bias = mi->bias;
174 }
175
176 // Reset existing pointers and names
177
178 module_dwarf = NULL;
179
440f755a
JS
180 cu = NULL;
181
182 function_name.clear();
183 function = NULL;
184}
185
186
187void
188dwflpp::focus_on_cu(Dwarf_Die * c)
189{
190 assert(c);
191 assert(module);
192
193 cu = c;
440f755a
JS
194
195 // Reset existing pointers and names
196 function_name.clear();
197 function = NULL;
198}
199
200
54417494
JS
201string
202dwflpp::cu_name(void)
203{
204 return dwarf_diename(cu) ?: "<unknown source>";
205}
206
207
440f755a
JS
208void
209dwflpp::focus_on_function(Dwarf_Die * f)
210{
211 assert(f);
212 assert(module);
213 assert(cu);
214
215 function = f;
f517ee24 216 function_name = dwarf_diename(function) ?: "function";
440f755a
JS
217}
218
219
1f8592d1
MW
220/* Return the Dwarf_Die for the given address in the current module.
221 * The address should be in the module address address space (this
222 * function will take care of any dw bias).
223 */
1adf8ef1
JS
224Dwarf_Die *
225dwflpp::query_cu_containing_address(Dwarf_Addr a)
440f755a
JS
226{
227 Dwarf_Addr bias;
68983551 228 assert(dwfl_ptr.get()->dwfl);
b6fa229b 229 assert(module);
440f755a 230 get_module_dwarf();
b6fa229b 231
440f755a 232 Dwarf_Die* cudie = dwfl_module_addrdie(module, a, &bias);
440f755a 233 assert(bias == module_bias);
1adf8ef1 234 return cudie;
440f755a
JS
235}
236
237
440f755a 238bool
5f4c8c6e 239dwflpp::module_name_matches(const string& pattern)
440f755a
JS
240{
241 bool t = (fnmatch(pattern.c_str(), module_name.c_str(), 0) == 0);
242 if (t && sess.verbose>3)
f9bbd346
LB
243 clog << _F("pattern '%s' matches module '%s'\n",
244 pattern.c_str(), module_name.c_str());
044a265a
FCE
245 if (!t && sess.verbose>4)
246 clog << _F("pattern '%s' does not match module '%s'\n",
247 pattern.c_str(), module_name.c_str());
248
440f755a
JS
249 return t;
250}
251
252
253bool
665e1256 254dwflpp::name_has_wildcard (const string& pattern)
440f755a
JS
255{
256 return (pattern.find('*') != string::npos ||
257 pattern.find('?') != string::npos ||
258 pattern.find('[') != string::npos);
259}
260
261
262bool
5f4c8c6e 263dwflpp::module_name_final_match(const string& pattern)
440f755a
JS
264{
265 // Assume module_name_matches(). Can there be any more matches?
266 // Not unless the pattern is a wildcard, since module names are
267 // presumed unique.
268 return !name_has_wildcard(pattern);
269}
270
271
272bool
5f4c8c6e 273dwflpp::function_name_matches_pattern(const string& name, const string& pattern)
440f755a
JS
274{
275 bool t = (fnmatch(pattern.c_str(), name.c_str(), 0) == 0);
276 if (t && sess.verbose>3)
f9bbd346 277 clog << _F("pattern '%s' matches function '%s'\n", pattern.c_str(), name.c_str());
440f755a
JS
278 return t;
279}
280
281
282bool
5f4c8c6e 283dwflpp::function_name_matches(const string& pattern)
440f755a
JS
284{
285 assert(function);
286 return function_name_matches_pattern(function_name, pattern);
287}
288
289
7d6d0afc 290bool
c646240d 291dwflpp::function_scope_matches(const vector<string>& scopes)
7d6d0afc
JS
292{
293 // walk up the containing scopes
294 Dwarf_Die* die = function;
295 for (int i = scopes.size() - 1; i >= 0; --i)
296 {
297 die = get_parent_scope(die);
298
299 // check if this scope matches, and prepend it if so
300 // NB: a NULL die is the global scope, compared as ""
301 string name = dwarf_diename(die) ?: "";
302 if (name_has_wildcard(scopes[i]) ?
303 function_name_matches_pattern(name, scopes[i]) :
304 name == scopes[i])
305 function_name = name + "::" + function_name;
306 else
307 return false;
308
309 // make sure there's no more if we're at the global scope
310 if (!die && i > 0)
311 return false;
312 }
313 return true;
314}
315
316
440f755a 317void
2eb99c62 318dwflpp::setup_kernel(const string& name, systemtap_session & s, bool debuginfo_needed)
440f755a 319{
440f755a
JS
320 if (! sess.module_cache)
321 sess.module_cache = new module_cache ();
322
3db9c843 323 unsigned offline_search_matches = 0;
68983551 324 dwfl_ptr = setup_dwfl_kernel(name, &offline_search_matches, sess);
440f755a 325
3db9c843 326 if (offline_search_matches < 1)
ae2552da
FCE
327 {
328 if (debuginfo_needed) {
329 // Suggest a likely kernel dir to find debuginfo rpm for
05fb3e0c 330 string dir = string(sess.sysroot + "/lib/modules/" + sess.kernel_release );
ae2552da
FCE
331 find_debug_rpms(sess, dir.c_str());
332 }
dc09353a 333 throw SEMANTIC_ERROR (_F("missing %s kernel/module debuginfo [man warning::debuginfo] under '%s'",
f9bbd346 334 sess.architecture.c_str(), sess.kernel_build_tree.c_str()));
209dd533 335 }
2eb99c62
CM
336 Dwfl *dwfl = dwfl_ptr.get()->dwfl;
337 if (dwfl != NULL)
338 {
339 ptrdiff_t off = 0;
340 do
341 {
e19ebcf7 342 assert_no_interrupts();
2eb99c62
CM
343 off = dwfl_getmodules (dwfl, &add_module_build_id_to_hash, &s, off);
344 }
345 while (off > 0);
346 dwfl_assert("dwfl_getmodules", off == 0);
347 }
440f755a 348
27646582 349 build_blacklist();
440f755a
JS
350}
351
59c11f91
MW
352void
353dwflpp::setup_kernel(const vector<string> &names, bool debuginfo_needed)
354{
355 if (! sess.module_cache)
356 sess.module_cache = new module_cache ();
357
358 unsigned offline_search_matches = 0;
359 set<string> offline_search_names(names.begin(), names.end());
68983551
MW
360 dwfl_ptr = setup_dwfl_kernel(offline_search_names,
361 &offline_search_matches,
362 sess);
59c11f91
MW
363
364 if (offline_search_matches < offline_search_names.size())
365 {
366 if (debuginfo_needed) {
367 // Suggest a likely kernel dir to find debuginfo rpm for
05fb3e0c 368 string dir = string(sess.sysroot + "/lib/modules/" + sess.kernel_release );
59c11f91
MW
369 find_debug_rpms(sess, dir.c_str());
370 }
dc09353a 371 throw SEMANTIC_ERROR (_F("missing %s kernel/module debuginfo [man warning::debuginfo] under '%s'",
f9bbd346 372 sess.architecture.c_str(), sess.kernel_build_tree.c_str()));
59c11f91
MW
373 }
374
375 build_blacklist();
376}
377
440f755a
JS
378
379void
0c16d512 380dwflpp::setup_user(const vector<string>& modules, bool debuginfo_needed)
440f755a
JS
381{
382 if (! sess.module_cache)
383 sess.module_cache = new module_cache ();
384
5f8ca04f 385 vector<string>::const_iterator it = modules.begin();
e1e8b44e 386 dwfl_ptr = setup_dwfl_user(it, modules.end(), debuginfo_needed, sess);
5f8ca04f 387 if (debuginfo_needed && it != modules.end())
ce0f6648
LB
388 dwfl_assert (string(_F("missing process %s %s debuginfo",
389 (*it).c_str(), sess.architecture.c_str())),
390 dwfl_ptr.get()->dwfl);
440f755a
JS
391}
392
06de3a04
JL
393template<> void
394dwflpp::iterate_over_modules<void>(int (*callback)(Dwfl_Module*,
395 void**,
396 const char*,
397 Dwarf_Addr,
398 void*),
399 void *data)
440f755a 400{
68983551 401 dwfl_getmodules (dwfl_ptr.get()->dwfl, callback, data, 0);
0e14e079 402
440f755a
JS
403 // Don't complain if we exited dwfl_getmodules early.
404 // This could be a $target variable error that will be
405 // reported soon anyway.
406 // dwfl_assert("dwfl_getmodules", off == 0);
407
408 // PR6864 XXX: For dwarfless case (if .../vmlinux is missing), then the
409 // "kernel" module is not reported in the loop above. However, we
410 // may be able to make do with symbol table data.
411}
412
413
5c378838
JL
414template<> void
415dwflpp::iterate_over_cus<void>(int (*callback)(Dwarf_Die*, void*),
416 void *data,
417 bool want_types)
440f755a
JS
418{
419 get_module_dwarf(false);
420 Dwarf *dw = module_dwarf;
421 if (!dw) return;
422
423 vector<Dwarf_Die>* v = module_cu_cache[dw];
424 if (v == 0)
425 {
426 v = new vector<Dwarf_Die>;
427 module_cu_cache[dw] = v;
428
429 Dwarf_Off off = 0;
430 size_t cuhl;
431 Dwarf_Off noff;
432 while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
433 {
e19ebcf7 434 assert_no_interrupts();
440f755a
JS
435 Dwarf_Die die_mem;
436 Dwarf_Die *die;
437 die = dwarf_offdie (dw, off + cuhl, &die_mem);
dee830d9
MW
438 /* Skip partial units. */
439 if (dwarf_tag (die) == DW_TAG_compile_unit)
440 v->push_back (*die); /* copy */
440f755a
JS
441 off = noff;
442 }
443 }
444
337b7c44
TT
445 if (want_types && module_tus_read.find(dw) == module_tus_read.end())
446 {
447 // Process type units.
448 Dwarf_Off off = 0;
449 size_t cuhl;
450 Dwarf_Off noff;
451 uint64_t type_signature;
452 while (dwarf_next_unit (dw, off, &noff, &cuhl, NULL, NULL, NULL, NULL,
453 &type_signature, NULL) == 0)
454 {
e19ebcf7 455 assert_no_interrupts();
337b7c44
TT
456 Dwarf_Die die_mem;
457 Dwarf_Die *die;
458 die = dwarf_offdie_types (dw, off + cuhl, &die_mem);
dee830d9
MW
459 /* Skip partial units. */
460 if (dwarf_tag (die) == DW_TAG_type_unit)
461 v->push_back (*die); /* copy */
337b7c44
TT
462 off = noff;
463 }
464 module_tus_read.insert(dw);
465 }
466
c1c5bb9a 467 for (vector<Dwarf_Die>::iterator i = v->begin(); i != v->end(); ++i)
440f755a 468 {
c1c5bb9a 469 int rc = (*callback)(&*i, data);
e19ebcf7 470 assert_no_interrupts();
985892de 471 if (rc != DWARF_CB_OK)
c1c5bb9a 472 break;
440f755a
JS
473 }
474}
475
476
477bool
478dwflpp::func_is_inline()
479{
480 assert (function);
481 return dwarf_func_inline (function) != 0;
482}
483
484
4bda987e
SC
485bool
486dwflpp::func_is_exported()
487{
488 const char *name = dwarf_linkage_name (function) ?: dwarf_diename (function);
489
490 assert (function);
491
492 int syms = dwfl_module_getsymtab (module);
493 dwfl_assert (_("Getting symbols"), syms >= 0);
494
495 for (int i = 0; i < syms; i++)
496 {
497 GElf_Sym sym;
498 GElf_Word shndxp;
499 const char *symname = dwfl_module_getsym(module, i, &sym, &shndxp);
500 if (symname
501 && strcmp (name, symname) == 0)
502 {
503 if (GELF_ST_TYPE(sym.st_info) == STT_FUNC
504 && (GELF_ST_BIND(sym.st_info) == STB_GLOBAL
5c204fc3
SC
505 || GELF_ST_BIND(sym.st_info) == STB_WEAK
506 || GELF_ST_BIND(sym.st_info) == STB_GNU_UNIQUE))
4bda987e
SC
507 return true;
508 else
509 return false;
510 }
511 }
512 return false;
513}
514
8d7a7bd9
JS
515void
516dwflpp::cache_inline_instances (Dwarf_Die* die)
440f755a 517{
8d7a7bd9
JS
518 // If this is an inline instance, link it back to its origin
519 Dwarf_Die origin;
520 if (dwarf_tag(die) == DW_TAG_inlined_subroutine &&
521 dwarf_attr_die(die, DW_AT_abstract_origin, &origin))
522 {
523 vector<Dwarf_Die>*& v = cu_inl_function_cache[origin.addr];
524 if (!v)
525 v = new vector<Dwarf_Die>;
526 v->push_back(*die);
527 }
528
529 // Recurse through other scopes that may contain inlines
530 Dwarf_Die child, import;
531 if (dwarf_child(die, &child) == 0)
532 do
533 {
534 switch (dwarf_tag (&child))
535 {
536 // tags that could contain inlines
537 case DW_TAG_compile_unit:
538 case DW_TAG_module:
539 case DW_TAG_lexical_block:
540 case DW_TAG_with_stmt:
541 case DW_TAG_catch_block:
542 case DW_TAG_try_block:
543 case DW_TAG_entry_point:
544 case DW_TAG_inlined_subroutine:
545 case DW_TAG_subprogram:
546 cache_inline_instances(&child);
547 break;
548
549 // imported dies should be followed
550 case DW_TAG_imported_unit:
551 if (dwarf_attr_die(&child, DW_AT_import, &import))
552 cache_inline_instances(&import);
553 break;
554
555 // nothing to do for other tags
556 default:
557 break;
558 }
559 }
560 while (dwarf_siblingof(&child, &child) == 0);
440f755a
JS
561}
562
563
3956fccb
JL
564template<> void
565dwflpp::iterate_over_inline_instances<void>(int (*callback)(Dwarf_Die*, void*),
566 void *data)
440f755a
JS
567{
568 assert (function);
569 assert (func_is_inline ());
570
8d7a7bd9
JS
571 if (cu_inl_function_cache_done.insert(cu->addr).second)
572 cache_inline_instances(cu);
573
d089f5b2 574 vector<Dwarf_Die>* v = cu_inl_function_cache[function->addr];
8d7a7bd9
JS
575 if (!v)
576 return;
440f755a 577
c1c5bb9a 578 for (vector<Dwarf_Die>::iterator i = v->begin(); i != v->end(); ++i)
440f755a 579 {
c1c5bb9a 580 int rc = (*callback)(&*i, data);
e19ebcf7 581 assert_no_interrupts();
985892de 582 if (rc != DWARF_CB_OK)
c1c5bb9a 583 break;
440f755a
JS
584 }
585}
586
587
9aa8ffce
JS
588void
589dwflpp::cache_die_parents(cu_die_parent_cache_t* parents, Dwarf_Die* die)
590{
591 // Record and recurse through DIEs we care about
592 Dwarf_Die child, import;
593 if (dwarf_child(die, &child) == 0)
594 do
595 {
596 switch (dwarf_tag (&child))
597 {
598 // normal tags to recurse
599 case DW_TAG_compile_unit:
600 case DW_TAG_module:
601 case DW_TAG_lexical_block:
602 case DW_TAG_with_stmt:
603 case DW_TAG_catch_block:
604 case DW_TAG_try_block:
605 case DW_TAG_entry_point:
606 case DW_TAG_inlined_subroutine:
607 case DW_TAG_subprogram:
7d6d0afc
JS
608 case DW_TAG_namespace:
609 case DW_TAG_class_type:
610 case DW_TAG_structure_type:
9aa8ffce
JS
611 parents->insert(make_pair(child.addr, *die));
612 cache_die_parents(parents, &child);
613 break;
614
615 // record only, nothing to recurse
616 case DW_TAG_label:
617 parents->insert(make_pair(child.addr, *die));
618 break;
619
620 // imported dies should be followed
621 case DW_TAG_imported_unit:
622 if (dwarf_attr_die(&child, DW_AT_import, &import))
623 {
624 parents->insert(make_pair(import.addr, *die));
625 cache_die_parents(parents, &import);
626 }
627 break;
628
629 // nothing to do for other tags
630 default:
631 break;
632 }
633 }
634 while (dwarf_siblingof(&child, &child) == 0);
635}
636
637
729455a7
JS
638cu_die_parent_cache_t*
639dwflpp::get_die_parents()
9aa8ffce
JS
640{
641 assert (cu);
642
729455a7 643 cu_die_parent_cache_t *& parents = cu_die_parent_cache[cu->addr];
9aa8ffce
JS
644 if (!parents)
645 {
646 parents = new cu_die_parent_cache_t;
9aa8ffce
JS
647 cache_die_parents(parents, cu);
648 if (sess.verbose > 4)
f9bbd346
LB
649 clog << _F("die parent cache %s:%s size %zu", module_name.c_str(),
650 cu_name().c_str(), parents->size()) << endl;
9aa8ffce 651 }
729455a7
JS
652 return parents;
653}
654
655
656vector<Dwarf_Die>
657dwflpp::getscopes_die(Dwarf_Die* die)
658{
659 cu_die_parent_cache_t *parents = get_die_parents();
9aa8ffce
JS
660
661 vector<Dwarf_Die> scopes;
729455a7
JS
662 Dwarf_Die *scope = die;
663 cu_die_parent_cache_t::iterator it;
664 do
665 {
666 scopes.push_back(*scope);
667 it = parents->find(scope->addr);
668 scope = &it->second;
669 }
670 while (it != parents->end());
9aa8ffce
JS
671
672#ifdef DEBUG_DWFLPP_GETSCOPES
729455a7 673 Dwarf_Die *dscopes = NULL;
9aa8ffce
JS
674 int nscopes = dwarf_getscopes_die(die, &dscopes);
675
676 assert(nscopes == (int)scopes.size());
677 for (unsigned i = 0; i < scopes.size(); ++i)
678 assert(scopes[i].addr == dscopes[i].addr);
679 free(dscopes);
680#endif
681
682 return scopes;
683}
684
685
729455a7
JS
686std::vector<Dwarf_Die>
687dwflpp::getscopes(Dwarf_Die* die)
688{
689 cu_die_parent_cache_t *parents = get_die_parents();
690
691 vector<Dwarf_Die> scopes;
692
693 Dwarf_Die origin;
694 Dwarf_Die *scope = die;
695 cu_die_parent_cache_t::iterator it;
696 do
697 {
698 scopes.push_back(*scope);
699 if (dwarf_tag(scope) == DW_TAG_inlined_subroutine &&
700 dwarf_attr_die(scope, DW_AT_abstract_origin, &origin))
701 scope = &origin;
702
703 it = parents->find(scope->addr);
704 scope = &it->second;
705 }
706 while (it != parents->end());
707
708#ifdef DEBUG_DWFLPP_GETSCOPES
709 // there isn't an exact libdw equivalent, but if dwarf_getscopes on the
710 // entrypc returns the same first die, then all the scopes should match
711 Dwarf_Addr pc;
712 if (die_entrypc(die, &pc))
713 {
714 Dwarf_Die *dscopes = NULL;
715 int nscopes = dwarf_getscopes(cu, pc, &dscopes);
716 if (nscopes > 0 && dscopes[0].addr == die->addr)
717 {
718 assert(nscopes == (int)scopes.size());
719 for (unsigned i = 0; i < scopes.size(); ++i)
720 assert(scopes[i].addr == dscopes[i].addr);
721 }
722 free(dscopes);
723 }
724#endif
725
726 return scopes;
727}
728
729
730std::vector<Dwarf_Die>
731dwflpp::getscopes(Dwarf_Addr pc)
732{
733 // The die_parent_cache doesn't help us without knowing where the pc is
734 // contained, so we have to do this one the old fashioned way.
735
736 assert (cu);
737
738 vector<Dwarf_Die> scopes;
739
740 Dwarf_Die* dwarf_scopes;
741 int nscopes = dwarf_getscopes(cu, pc, &dwarf_scopes);
742 if (nscopes > 0)
743 {
744 scopes.assign(dwarf_scopes, dwarf_scopes + nscopes);
745 free(dwarf_scopes);
746 }
747
748#ifdef DEBUG_DWFLPP_GETSCOPES
749 // check that getscopes on the starting die gets the same result
750 if (!scopes.empty())
751 {
752 vector<Dwarf_Die> other = getscopes(&scopes[0]);
753 assert(scopes.size() == other.size());
754 for (unsigned i = 0; i < scopes.size(); ++i)
755 assert(scopes[i].addr == other[i].addr);
756 }
757#endif
758
759 return scopes;
760}
761
762
7d6d0afc
JS
763Dwarf_Die*
764dwflpp::get_parent_scope(Dwarf_Die* die)
765{
766 Dwarf_Die specification;
767 if (dwarf_attr_die(die, DW_AT_specification, &specification))
768 die = &specification;
769
770 cu_die_parent_cache_t *parents = get_die_parents();
771 cu_die_parent_cache_t::iterator it = parents->find(die->addr);
772 while (it != parents->end())
773 {
774 Dwarf_Die* scope = &it->second;
775 switch (dwarf_tag (scope))
776 {
777 case DW_TAG_namespace:
778 case DW_TAG_class_type:
779 case DW_TAG_structure_type:
780 return scope;
781
782 default:
783 break;
784 }
785 it = parents->find(scope->addr);
786 }
787 return NULL;
788}
789
a44a7cb5
JS
790static const char*
791cache_type_prefix(Dwarf_Die* type)
792{
793 switch (dwarf_tag(type))
794 {
795 case DW_TAG_enumeration_type:
796 return "enum ";
797 case DW_TAG_structure_type:
798 case DW_TAG_class_type:
799 // treating struct/class as equals
800 return "struct ";
801 case DW_TAG_union_type:
802 return "union ";
803 }
804 return "";
805}
7d6d0afc 806
87eeec94
MW
807/* GCC might generate a struct/class without DW_AT_declaration,
808 but that only contains members which have DW_AT_declaration
809 set. We aren't interested in those. PR14434 (GCC bug #54181). */
810static bool
811has_only_decl_members (Dwarf_Die *die)
812{
dee830d9 813 Dwarf_Die child, import;
87eeec94
MW
814 if (dwarf_child(die, &child) != 0)
815 return false; /* no members */
816
817 do
818 {
819 if (! dwarf_hasattr(&child, DW_AT_declaration))
820 return false; /* real member found. */
821 int tag = dwarf_tag(&child);
822 if ((tag == DW_TAG_namespace
823 || tag == DW_TAG_structure_type
824 || tag == DW_TAG_class_type)
825 && ! has_only_decl_members (&child))
826 return false; /* real grand child member found. */
dee830d9
MW
827
828 // Unlikely to ever happen, but if there is an imported unit
829 // then check its children as if they are children of this DIE.
830 if (tag == DW_TAG_imported_unit
831 && dwarf_attr_die(&child, DW_AT_import, &import)
832 && ! has_only_decl_members (&import))
833 return false;
87eeec94
MW
834 }
835 while (dwarf_siblingof(&child, &child) == 0);
836
837 return true; /* Tried all children and grandchildren. */
838}
839
440f755a 840int
3805a31e 841dwflpp::global_alias_caching_callback(Dwarf_Die *die, bool has_inner_types,
bf072c60 842 const string& prefix, cu_type_cache_t *cache)
440f755a 843{
440f755a
JS
844 const char *name = dwarf_diename(die);
845
87eeec94
MW
846 if (!name || dwarf_hasattr(die, DW_AT_declaration)
847 || has_only_decl_members(die))
440f755a
JS
848 return DWARF_CB_OK;
849
3805a31e
JS
850 int tag = dwarf_tag(die);
851 if (has_inner_types && (tag == DW_TAG_namespace
852 || tag == DW_TAG_structure_type
853 || tag == DW_TAG_class_type))
854 iterate_over_types(die, has_inner_types, prefix + name + "::",
bf072c60 855 global_alias_caching_callback, cache);
3805a31e
JS
856
857 if (tag != DW_TAG_namespace)
858 {
859 string type_name = prefix + cache_type_prefix(die) + name;
860 if (cache->find(type_name) == cache->end())
861 (*cache)[type_name] = *die;
862 }
440f755a
JS
863
864 return DWARF_CB_OK;
865}
866
063906a9 867int
5c378838 868dwflpp::global_alias_caching_callback_cus(Dwarf_Die *die, dwflpp *dw)
063906a9
MW
869{
870 mod_cu_type_cache_t *global_alias_cache;
5c378838 871 global_alias_cache = &dw->global_alias_cache;
063906a9
MW
872
873 cu_type_cache_t *v = (*global_alias_cache)[die->addr];
874 if (v != 0)
875 return DWARF_CB_OK;
876
877 v = new cu_type_cache_t;
878 (*global_alias_cache)[die->addr] = v;
879 iterate_over_globals(die, global_alias_caching_callback, v);
880
881 return DWARF_CB_OK;
882}
883
884Dwarf_Die *
a44a7cb5 885dwflpp::declaration_resolve_other_cus(const string& name)
063906a9 886{
337b7c44 887 iterate_over_cus(global_alias_caching_callback_cus, this, true);
063906a9
MW
888 for (mod_cu_type_cache_t::iterator i = global_alias_cache.begin();
889 i != global_alias_cache.end(); ++i)
890 {
891 cu_type_cache_t *v = (*i).second;
892 if (v->find(name) != v->end())
893 return & ((*v)[name]);
894 }
895
896 return NULL;
897}
440f755a
JS
898
899Dwarf_Die *
a44a7cb5 900dwflpp::declaration_resolve(const string& name)
440f755a 901{
b7478964 902 cu_type_cache_t *v = global_alias_cache[cu->addr];
440f755a
JS
903 if (v == 0) // need to build the cache, just once per encountered module/cu
904 {
b7478964 905 v = new cu_type_cache_t;
54558065 906 global_alias_cache[cu->addr] = v;
063906a9 907 iterate_over_globals(cu, global_alias_caching_callback, v);
440f755a 908 if (sess.verbose > 4)
f9bbd346
LB
909 clog << _F("global alias cache %s:%s size %zu", module_name.c_str(),
910 cu_name().c_str(), v->size()) << endl;
440f755a
JS
911 }
912
913 // XXX: it may be desirable to search other modules' declarations
914 // too, in case a module/shared-library processes a
915 // forward-declared pointer type only, where the actual definition
916 // may only be in vmlinux or the application.
917
440f755a 918 if (v->find(name) == v->end())
063906a9 919 return declaration_resolve_other_cus(name);
440f755a
JS
920
921 return & ((*v)[name]);
922}
923
a44a7cb5
JS
924Dwarf_Die *
925dwflpp::declaration_resolve(Dwarf_Die *type)
926{
927 const char* name = dwarf_diename(type);
928 if (!name)
929 return NULL;
930
931 string type_name = cache_type_prefix(type) + string(name);
932 return declaration_resolve(type_name);
933}
934
440f755a
JS
935
936int
5c378838 937dwflpp::cu_function_caching_callback (Dwarf_Die* func, cu_function_cache_t *v)
440f755a 938{
440f755a
JS
939 const char *name = dwarf_diename(func);
940 if (!name)
941 return DWARF_CB_OK;
942
b7478964 943 v->insert(make_pair(string(name), *func));
440f755a
JS
944 return DWARF_CB_OK;
945}
946
947
4df79aaf 948int
5c378838 949dwflpp::mod_function_caching_callback (Dwarf_Die* cu, cu_function_cache_t *v)
4df79aaf 950{
5c378838
JL
951 // need to cast callback to func which accepts void*
952 dwarf_getfuncs (cu, (int (*)(Dwarf_Die*, void*))cu_function_caching_callback,
953 v, 0);
4df79aaf
JS
954 return DWARF_CB_OK;
955}
956
957
7d007451
JL
958template<> int
959dwflpp::iterate_over_functions<void>(int (*callback)(Dwarf_Die*, void*),
960 void *data, const string& function)
440f755a
JS
961{
962 int rc = DWARF_CB_OK;
963 assert (module);
964 assert (cu);
965
54558065 966 cu_function_cache_t *v = cu_function_cache[cu->addr];
440f755a
JS
967 if (v == 0)
968 {
969 v = new cu_function_cache_t;
54558065 970 cu_function_cache[cu->addr] = v;
5c378838
JL
971 // need to cast callback to func which accepts void*
972 dwarf_getfuncs (cu, (int (*)(Dwarf_Die*, void*))cu_function_caching_callback,
973 v, 0);
440f755a 974 if (sess.verbose > 4)
f9bbd346
LB
975 clog << _F("function cache %s:%s size %zu", module_name.c_str(),
976 cu_name().c_str(), v->size()) << endl;
1c6b77e5 977 mod_info->update_symtab(v);
440f755a
JS
978 }
979
b7478964
JS
980 cu_function_cache_t::iterator it;
981 cu_function_cache_range_t range = v->equal_range(function);
982 if (range.first != range.second)
440f755a 983 {
b7478964
JS
984 for (it = range.first; it != range.second; ++it)
985 {
986 Dwarf_Die& die = it->second;
987 if (sess.verbose > 4)
f9bbd346
LB
988 clog << _F("function cache %s:%s hit %s", module_name.c_str(),
989 cu_name().c_str(), function.c_str()) << endl;
7d007451 990 rc = (*callback)(& die, data);
b7478964
JS
991 if (rc != DWARF_CB_OK) break;
992 }
440f755a 993 }
1ffb8bd1
JS
994 else if (startswith(function, "_Z"))
995 {
996 // C++ names are mangled starting with a "_Z" prefix. Most of the time
997 // we can discover the mangled name from a die's MIPS_linkage_name
998 // attribute, so we read that to match against the user's function
999 // pattern. Note that this isn't perfect, as not all will have that
1000 // attribute (notably ctors and dtors), but we do what we can...
1001 for (it = v->begin(); it != v->end(); ++it)
1002 {
1003 if (pending_interrupts) return DWARF_CB_ABORT;
1004 Dwarf_Die& die = it->second;
157f5dd0 1005 const char* linkage_name = NULL;
f450a7e3 1006 if ((linkage_name = dwarf_linkage_name (&die))
1ffb8bd1
JS
1007 && function_name_matches_pattern (linkage_name, function))
1008 {
1009 if (sess.verbose > 4)
f9bbd346
LB
1010 clog << _F("function cache %s:%s match %s vs %s", module_name.c_str(),
1011 cu_name().c_str(), linkage_name, function.c_str()) << endl;
1ffb8bd1 1012
7d007451 1013 rc = (*callback)(& die, data);
1ffb8bd1
JS
1014 if (rc != DWARF_CB_OK) break;
1015 }
1016 }
1017 }
5f4c8c6e 1018 else if (name_has_wildcard (function))
440f755a 1019 {
c1c5bb9a 1020 for (it = v->begin(); it != v->end(); ++it)
440f755a 1021 {
85007c04 1022 if (pending_interrupts) return DWARF_CB_ABORT;
1c6b77e5
JS
1023 const string& func_name = it->first;
1024 Dwarf_Die& die = it->second;
5f4c8c6e 1025 if (function_name_matches_pattern (func_name, function))
440f755a
JS
1026 {
1027 if (sess.verbose > 4)
f9bbd346
LB
1028 clog << _F("function cache %s:%s match %s vs %s", module_name.c_str(),
1029 cu_name().c_str(), func_name.c_str(), function.c_str()) << endl;
440f755a 1030
7d007451 1031 rc = (*callback)(& die, data);
440f755a
JS
1032 if (rc != DWARF_CB_OK) break;
1033 }
1034 }
1035 }
1ffb8bd1 1036 else // not a linkage name or wildcard and no match in this CU
440f755a
JS
1037 {
1038 // do nothing
1039 }
1040 return rc;
1041}
1042
1043
7d007451
JL
1044template<> int
1045dwflpp::iterate_single_function<void>(int (*callback)(Dwarf_Die*, void*),
1046 void *data, const string& function)
4df79aaf
JS
1047{
1048 int rc = DWARF_CB_OK;
1049 assert (module);
1050
1051 get_module_dwarf(false);
1052 if (!module_dwarf)
1053 return rc;
1054
1055 cu_function_cache_t *v = mod_function_cache[module_dwarf];
1056 if (v == 0)
1057 {
1058 v = new cu_function_cache_t;
1059 mod_function_cache[module_dwarf] = v;
337b7c44 1060 iterate_over_cus (mod_function_caching_callback, v, false);
4df79aaf 1061 if (sess.verbose > 4)
f9bbd346
LB
1062 clog << _F("module function cache %s size %zu", module_name.c_str(),
1063 v->size()) << endl;
d1fa8b15 1064 mod_info->update_symtab(v);
4df79aaf
JS
1065 }
1066
1067 cu_function_cache_t::iterator it;
1068 cu_function_cache_range_t range = v->equal_range(function);
1069 if (range.first != range.second)
1070 {
1071 for (it = range.first; it != range.second; ++it)
1072 {
1073 Dwarf_Die cu_mem;
1074 Dwarf_Die& die = it->second;
1075 if (sess.verbose > 4)
f9bbd346
LB
1076 clog << _F("module function cache %s hit %s", module_name.c_str(),
1077 function.c_str()) << endl;
4df79aaf
JS
1078
1079 // since we're iterating out of cu-context, we need each focus
1080 focus_on_cu(dwarf_diecu(&die, &cu_mem, NULL, NULL));
1081
7d007451 1082 rc = (*callback)(& die, data);
4df79aaf
JS
1083 if (rc != DWARF_CB_OK) break;
1084 }
1085 }
1086
1087 // undo the focus_on_cu
1088 this->cu = NULL;
1089 this->function_name.clear();
1090 this->function = NULL;
1091
1092 return rc;
1093}
1094
1095
440f755a
JS
1096/* This basically only goes one level down from the compile unit so it
1097 * only picks up top level stuff (i.e. nothing in a lower scope) */
bf072c60
JL
1098template<> int
1099dwflpp::iterate_over_globals<void>(Dwarf_Die *cu_die,
1100 int (*callback)(Dwarf_Die*,
1101 bool,
1102 const string&,
1103 void*),
1104 void *data)
3805a31e
JS
1105{
1106 assert (cu_die);
337b7c44 1107 assert (dwarf_tag(cu_die) == DW_TAG_compile_unit
dee830d9
MW
1108 || dwarf_tag(cu_die) == DW_TAG_type_unit
1109 || dwarf_tag(cu_die) == DW_TAG_partial_unit);
1110
1111 // Ignore partial_unit, if they get imported by a real unit, then
1112 // iterate_over_types will traverse them.
1113 if (dwarf_tag(cu_die) == DW_TAG_partial_unit)
1114 return DWARF_CB_OK;
3805a31e
JS
1115
1116 // If this is C++, recurse for any inner types
1117 bool has_inner_types = dwarf_srclang(cu_die) == DW_LANG_C_plus_plus;
1118
1119 return iterate_over_types(cu_die, has_inner_types, "", callback, data);
1120}
1121
bf072c60
JL
1122template<> int
1123dwflpp::iterate_over_types<void>(Dwarf_Die *top_die,
1124 bool has_inner_types,
1125 const string& prefix,
1126 int (* callback)(Dwarf_Die*,
1127 bool,
1128 const string&,
1129 void*),
1130 void *data)
440f755a
JS
1131{
1132 int rc = DWARF_CB_OK;
dee830d9 1133 Dwarf_Die die, import;
440f755a 1134
3805a31e 1135 assert (top_die);
440f755a 1136
3805a31e 1137 if (dwarf_child(top_die, &die) != 0)
440f755a
JS
1138 return rc;
1139
1140 do
1141 /* We're only currently looking for named types,
1142 * although other types of declarations exist */
1143 switch (dwarf_tag(&die))
1144 {
1145 case DW_TAG_base_type:
1146 case DW_TAG_enumeration_type:
1147 case DW_TAG_structure_type:
9c119951 1148 case DW_TAG_class_type:
440f755a
JS
1149 case DW_TAG_typedef:
1150 case DW_TAG_union_type:
3805a31e
JS
1151 case DW_TAG_namespace:
1152 rc = (*callback)(&die, has_inner_types, prefix, data);
440f755a 1153 break;
dee830d9
MW
1154
1155 case DW_TAG_imported_unit:
1156 // Follow the imported_unit and iterate over its contents
1157 // (either a partial_unit or a full compile_unit), all its
1158 // children should be treated as if they appear in this place.
1159 if (dwarf_attr_die(&die, DW_AT_import, &import))
1160 rc = iterate_over_types(&import, has_inner_types, prefix,
1161 callback, data);
1162 break;
440f755a
JS
1163 }
1164 while (rc == DWARF_CB_OK && dwarf_siblingof(&die, &die) == 0);
1165
1166 return rc;
1167}
1168
1169
fea74777
SC
1170/* For each notes section in the current module call 'callback', use
1171 * 'data' for the notes buffer and pass 'object' back in case
1172 * 'callback' is a method */
1173
488d3c1b
JL
1174template<> int
1175dwflpp::iterate_over_notes<void>(void *object, void (*callback)(void*,
1176 int,
1177 const char*,
1178 size_t))
fea74777
SC
1179{
1180 Dwarf_Addr bias;
1189063f
MW
1181 // Note we really want the actual elf file, not the dwarf .debug file.
1182 // Older binutils had a bug where they mangled the SHT_NOTE type during
1183 // --keep-debug.
1184 Elf* elf = dwfl_module_getelf (module, &bias);
fea74777
SC
1185 size_t shstrndx;
1186 if (elf_getshdrstrndx (elf, &shstrndx))
1187 return elf_errno();
1188
fea74777
SC
1189 Elf_Scn *scn = NULL;
1190
1191 vector<Dwarf_Die> notes;
1192
1193 while ((scn = elf_nextscn (elf, scn)) != NULL)
1194 {
1195 GElf_Shdr shdr;
1196 if (gelf_getshdr (scn, &shdr) == NULL)
1197 continue;
1198 switch (shdr.sh_type)
1199 {
1200 case SHT_NOTE:
1201 if (!(shdr.sh_flags & SHF_ALLOC))
1202 {
fea74777
SC
1203 Elf_Data *data = elf_getdata (scn, NULL);
1204 size_t next;
1205 GElf_Nhdr nhdr;
1206 size_t name_off;
1207 size_t desc_off;
1208 for (size_t offset = 0;
1209 (next = gelf_getnote (data, offset, &nhdr, &name_off, &desc_off)) > 0;
1210 offset = next)
1211 (*callback) (object, nhdr.n_type, (const char*)((long)(data->d_buf) + (long)desc_off), nhdr.n_descsz);
1212 }
1213 break;
1214 }
1215 }
1216 return 0;
1217}
1218
1219
5d5bd369
SC
1220/* For each entry in the .dynamic section in the current module call 'callback'
1221 * returning 'object' in case 'callback' is a method */
84c84ac4 1222
bbbc7241
JL
1223template<> void
1224dwflpp::iterate_over_libraries<void>(void (*callback)(void*, const char*),
1225 void *data)
84c84ac4
SC
1226{
1227 std::set<std::string> added;
1228 string interpreter;
1229
1230 assert (this->module_name.length() != 0);
1231
1232 Dwarf_Addr bias;
6bbcd339
SC
1233// We cannot use this: dwarf_getelf (dwfl_module_getdwarf (module, &bias))
1234 Elf *elf = dwfl_module_getelf (module, &bias);
c1e8b3af 1235// elf_getphdrnum (elf, &phnum) is not available in all versions of elfutils
e050d62f 1236// needs libelf from elfutils 0.144+
c1e8b3af 1237 for (int i = 0; ; i++)
84c84ac4
SC
1238 {
1239 GElf_Phdr mem;
c1e8b3af
SC
1240 GElf_Phdr *phdr;
1241 phdr = gelf_getphdr (elf, i, &mem);
1242 if (phdr == NULL)
1243 break;
84c84ac4
SC
1244 if (phdr->p_type == PT_INTERP)
1245 {
1246 size_t maxsize;
1247 char *filedata = elf_rawfile (elf, &maxsize);
1248
1249 if (filedata != NULL && phdr->p_offset < maxsize)
1250 interpreter = (char*) (filedata + phdr->p_offset);
84c84ac4
SC
1251 break;
1252 }
1253 }
1254
6bbcd339
SC
1255 if (interpreter.length() == 0)
1256 return;
58502ae4
JS
1257 // If it gets cumbersome to maintain this whitelist, we could just check for
1258 // startswith("/lib/ld") || startswith("/lib64/ld"), and trust that no admin
1259 // would install untrustworthy loaders in those paths.
4ff68987
FCE
1260 // See also http://sourceware.org/git/?p=glibc.git;a=blob;f=shlib-versions;hb=HEAD
1261 if (interpreter != "/lib/ld.so.1" // s390, ppc
1262 && interpreter != "/lib/ld64.so.1" // s390x, ppc64
1263 && interpreter != "/lib64/ld64.so.1"
1264 && interpreter != "/lib/ld-linux-ia64.so.2" // ia64
1265 && interpreter != "/emul/ia32-linux/lib/ld-linux.so.2"
1266 && interpreter != "/lib64/ld-linux-x86-64.so.2" // x8664
1267 && interpreter != "/lib/ld-linux.so.2" // x86
1268 && interpreter != "/lib/ld-linux.so.3" // arm
1269 && interpreter != "/lib/ld-linux-armhf.so.3" // arm
1270 )
d785c8d1 1271 {
2713ea24 1272 sess.print_warning (_F("module %s --ldd skipped: unsupported interpreter: %s",
d785c8d1
FCE
1273 module_name.c_str(), interpreter.c_str()));
1274 return;
1275 }
84c84ac4 1276
58502ae4
JS
1277 vector<string> ldd_command;
1278 ldd_command.push_back("/usr/bin/env");
1279 ldd_command.push_back("LD_TRACE_LOADED_OBJECTS=1");
1280 ldd_command.push_back("LD_WARN=yes");
1281 ldd_command.push_back("LD_BIND_NOW=yes");
1282 ldd_command.push_back(interpreter);
1283 ldd_command.push_back(module_name);
1284
1285 FILE *fp;
1286 int child_fd;
1287 pid_t child = stap_spawn_piped(sess.verbose, ldd_command, NULL, &child_fd);
1288 if (child <= 0 || !(fp = fdopen(child_fd, "r")))
1289 clog << _F("library iteration on %s failed: %s",
1290 module_name.c_str(), strerror(errno)) << endl;
84c84ac4
SC
1291 else
1292 {
1293 while (1) // this parsing loop borrowed from add_unwindsym_ldd
1294 {
1295 char linebuf[256];
1296 char *soname = 0;
1297 char *shlib = 0;
1298 unsigned long int addr = 0;
1299
1300 char *line = fgets (linebuf, 256, fp);
1301 if (line == 0) break; // EOF or error
1302
62a4021d
FCE
1303#if __GLIBC__ >2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)
1304#define MS_FMT "%ms"
1305#else
1306#define MS_FMT "%as"
1307#endif
84c84ac4 1308 // Try soname => shlib (0xaddr)
62a4021d 1309 int nf = sscanf (line, MS_FMT " => " MS_FMT " (0x%lx)",
84c84ac4
SC
1310 &soname, &shlib, &addr);
1311 if (nf != 3 || shlib[0] != '/')
1312 {
1313 // Try shlib (0xaddr)
62a4021d 1314 nf = sscanf (line, " " MS_FMT " (0x%lx)", &shlib, &addr);
84c84ac4
SC
1315 if (nf != 2 || shlib[0] != '/')
1316 continue; // fewer than expected fields, or bad shlib.
1317 }
1318
1319 if (added.find (shlib) == added.end())
1320 {
1321 if (sess.verbose > 2)
1322 {
1323 clog << _F("Added -d '%s", shlib);
1324 if (nf == 3)
1325 clog << _F("' due to '%s'", soname);
1326 else
1327 clog << "'";
1328 clog << endl;
1329 }
1330 added.insert (shlib);
1331 }
1332
1333 free (soname);
1334 free (shlib);
1335 }
2713ea24
CM
1336 if ((fclose(fp) || stap_waitpid(sess.verbose, child)))
1337 sess.print_warning("failed to read libraries from " + module_name + ": " + strerror(errno));
84c84ac4
SC
1338 }
1339
1340 for (std::set<std::string>::iterator it = added.begin();
1341 it != added.end();
1342 it++)
1343 {
1344 string modname = *it;
bbbc7241 1345 (callback) (data, modname.c_str());
84c84ac4
SC
1346 }
1347}
1348
1349
576eaefe
SC
1350/* For each plt section in the current module call 'callback', pass the plt entry
1351 * 'address' and 'name' back, and pass 'object' back in case 'callback' is a method */
1352
45cdb40e
JL
1353template<> int
1354dwflpp::iterate_over_plt<void>(void *object, void (*callback)(void*,
1355 const char*,
1356 size_t))
576eaefe
SC
1357{
1358 Dwarf_Addr load_addr;
1359 // Note we really want the actual elf file, not the dwarf .debug file.
1360 Elf* elf = dwfl_module_getelf (module, &load_addr);
1361 size_t shstrndx;
1362 assert (elf_getshdrstrndx (elf, &shstrndx) >= 0);
1363
1364 // Get the load address
1365 for (int i = 0; ; i++)
1366 {
1367 GElf_Phdr mem;
1368 GElf_Phdr *phdr;
1369 phdr = gelf_getphdr (elf, i, &mem);
1370 if (phdr == NULL)
1371 break;
1372 if (phdr->p_type == PT_LOAD)
1373 {
1374 load_addr = phdr->p_vaddr;
1375 break;
1376 }
1377 }
1378
1379 // Get the plt section header
1380 Elf_Scn *scn = NULL;
1381 GElf_Shdr *plt_shdr = NULL;
1382 GElf_Shdr plt_shdr_mem;
1383 while ((scn = elf_nextscn (elf, scn)))
1384 {
1acfc030
JS
1385 GElf_Shdr *shdr = gelf_getshdr (scn, &plt_shdr_mem);
1386 assert (shdr != NULL);
1387 if (strcmp (elf_strptr (elf, shstrndx, shdr->sh_name), ".plt") == 0)
1388 {
1389 plt_shdr = shdr;
1390 break;
1391 }
576eaefe 1392 }
1acfc030
JS
1393 if (plt_shdr == NULL)
1394 return 0;
1395
576eaefe
SC
1396 // Layout of the plt section
1397 int plt0_entry_size;
1398 int plt_entry_size;
1399 GElf_Ehdr ehdr_mem;
1400 GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem);
1401 switch (em->e_machine)
1402 {
4e309f0b 1403 case EM_386: plt0_entry_size = 16; plt_entry_size = 16; break;
576eaefe 1404 case EM_X86_64: plt0_entry_size = 16; plt_entry_size = 16; break;
13b528f4 1405 case EM_ARM: plt0_entry_size = 20; plt_entry_size = 12; break;
576eaefe
SC
1406 case EM_PPC64:
1407 case EM_S390:
1408 case EM_PPC:
1409 default:
dc09353a 1410 throw SEMANTIC_ERROR(".plt is not supported on this architecture");
576eaefe
SC
1411 }
1412
1413 scn = NULL;
1414 while ((scn = elf_nextscn (elf, scn)))
1415 {
1416 GElf_Shdr shdr_mem;
1417 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
e245d57f
SC
1418 bool have_rela = false;
1419 bool have_rel = false;
4e309f0b 1420
576eaefe
SC
1421 if (shdr == NULL)
1422 continue;
1423 assert (shdr != NULL);
1424
4e309f0b
SC
1425 if ((have_rela = (strcmp (elf_strptr (elf, shstrndx, shdr->sh_name), ".rela.plt") == 0))
1426 || (have_rel = (strcmp (elf_strptr (elf, shstrndx, shdr->sh_name), ".rel.plt") == 0)))
576eaefe
SC
1427 {
1428 /* Get the data of the section. */
1429 Elf_Data *data = elf_getdata (scn, NULL);
1430 assert (data != NULL);
1431 /* Get the symbol table information. */
1432 Elf_Scn *symscn = elf_getscn (elf, shdr->sh_link);
1433 GElf_Shdr symshdr_mem;
1434 GElf_Shdr *symshdr = gelf_getshdr (symscn, &symshdr_mem);
1435 assert (symshdr != NULL);
1436 Elf_Data *symdata = elf_getdata (symscn, NULL);
1437 assert (symdata != NULL);
1438
1439 unsigned int nsyms = shdr->sh_size / shdr->sh_entsize;
1440
1441 for (unsigned int cnt = 0; cnt < nsyms; ++cnt)
1442 {
1443 GElf_Ehdr ehdr_mem;
1444 GElf_Ehdr* em = gelf_getehdr (elf, &ehdr_mem);
1445 if (em == 0) { dwfl_assert ("dwfl_getehdr", dwfl_errno()); }
1446
4e309f0b 1447 GElf_Rela relamem;
ffffb6b5 1448 GElf_Rela *rela = NULL;
4e309f0b 1449 GElf_Rel relmem;
ffffb6b5 1450 GElf_Rel *rel = NULL;
4e309f0b
SC
1451 if (have_rela)
1452 {
1453 rela = gelf_getrela (data, cnt, &relamem);
1454 assert (rela != NULL);
1455 }
1456 else if (have_rel)
1457 {
1458 rel = gelf_getrel (data, cnt, &relmem);
1459 assert (rel != NULL);
1460 }
576eaefe
SC
1461 GElf_Sym symmem;
1462 Elf32_Word xndx;
1463 Elf_Data *xndxdata = NULL;
4e309f0b
SC
1464 GElf_Sym *sym =
1465 gelf_getsymshndx (symdata, xndxdata,
1466 GELF_R_SYM (have_rela ? rela->r_info : rel->r_info),
1467 &symmem, &xndx);
576eaefe
SC
1468 assert (sym != NULL);
1469 Dwarf_Addr addr = plt_shdr->sh_offset + plt0_entry_size + cnt * plt_entry_size;
1470
1471 if (elf_strptr (elf, symshdr->sh_link, sym->st_name))
1472 (*callback) (object, elf_strptr (elf, symshdr->sh_link, sym->st_name), addr + load_addr);
1473 }
1474 break; // while scn
1475 }
1476 }
1477 return 0;
1478}
1479
1480
440f755a
JS
1481// This little test routine represents an unfortunate breakdown in
1482// abstraction between dwflpp (putatively, a layer right on top of
1483// elfutils), and dwarf_query (interpreting a systemtap probe point).
1484// It arises because we sometimes try to fix up slightly-off
1485// .statement() probes (something we find out in fairly low-level).
1486//
1487// An alternative would be to put some more intelligence into query_cu(),
1488// and have it print additional suggestions after finding that
1489// q->dw.iterate_over_srcfile_lines resulted in no new finished_results.
1490
1491bool
1492dwflpp::has_single_line_record (dwarf_query * q, char const * srcfile, int lineno)
1493{
1494 if (lineno < 0)
1495 return false;
1496
35c68acb
SC
1497 Dwarf_Line **srcsp = NULL;
1498 size_t nsrcs = 0;
440f755a 1499
35c68acb
SC
1500 dwarf_assert ("dwarf_getsrc_file",
1501 dwarf_getsrc_file (module_dwarf,
1502 srcfile, lineno, 0,
1503 &srcsp, &nsrcs));
440f755a 1504
35c68acb
SC
1505 if (nsrcs != 1)
1506 {
1507 if (sess.verbose>4)
1508 clog << _F("alternative line %d rejected: nsrcs=%zu", lineno, nsrcs) << endl;
1509 return false;
1510 }
440f755a 1511
35c68acb
SC
1512 // We also try to filter out lines that leave the selected
1513 // functions (if any).
440f755a 1514
35c68acb
SC
1515 dwarf_line_t line(srcsp[0]);
1516 Dwarf_Addr addr = line.addr();
440f755a 1517
35c68acb
SC
1518 func_info_map_t *filtered_functions = get_filtered_functions(q);
1519 for (func_info_map_t::iterator i = filtered_functions->begin();
1520 i != filtered_functions->end(); ++i)
1521 {
1522 if (die_has_pc (i->die, addr))
1523 {
1524 if (sess.verbose>4)
1525 clog << _F("alternative line %d accepted: fn=%s", lineno, i->name.c_str()) << endl;
1526 return true;
1527 }
1528 }
440f755a 1529
35c68acb
SC
1530 inline_instance_map_t *filtered_inlines = get_filtered_inlines(q);
1531 for (inline_instance_map_t::iterator i = filtered_inlines->begin();
1532 i != filtered_inlines->end(); ++i)
1533 {
1534 if (die_has_pc (i->die, addr))
1535 {
1536 if (sess.verbose>4)
1537 clog << _F("alternative line %d accepted: ifn=%s", lineno, i->name.c_str()) << endl;
1538 return true;
1539 }
1540 }
440f755a 1541
35c68acb
SC
1542 if (sess.verbose>4)
1543 //TRANSLATORS: given line number leaves (is beyond) given function.
1544 clog << _F("alternative line %d rejected: leaves selected fns", lineno) << endl;
1545 return false;
440f755a
JS
1546}
1547
1548
0e2e28a1
JL
1549template<> void
1550dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
1551 int lines[2],
1552 bool need_single_match,
1553 enum line_t line_type,
1554 void (* callback) (const dwarf_line_t& line,
1555 void * arg),
1556 const std::string& func_pattern,
1557 void *data)
440f755a
JS
1558{
1559 Dwarf_Line **srcsp = NULL;
1560 size_t nsrcs = 0;
0e2e28a1
JL
1561 // XXX: MUST GET RID OF THIS (see also comment block before
1562 // has_single_line_record())
440f755a
JS
1563 dwarf_query * q = static_cast<dwarf_query *>(data);
1564 int lineno = lines[0];
1565 auto_free_ref<Dwarf_Line**> free_srcsp(srcsp);
1566
1567 get_module_dwarf();
e679283a
WH
1568 if (!this->function)
1569 return;
440f755a
JS
1570
1571 if (line_type == RELATIVE)
1572 {
1573 Dwarf_Addr addr;
1574 Dwarf_Line *line;
1575 int line_number;
1576
1bbf3f90
JS
1577 if (!die_entrypc(this->function, &addr))
1578 return;
6a3a5e98
SC
1579
1580 if (addr != 0)
1581 {
1582 line = dwarf_getsrc_die (this->cu, addr);
1583 dwarf_assert ("dwarf_getsrc_die", line == NULL);
1584 dwarf_assert ("dwarf_lineno", dwarf_lineno (line, &line_number));
1585 }
1586 else if (dwarf_decl_line (this->function, &line_number) != 0)
1587 {
1588 // use DW_AT_decl_line as a fallback method
1589 Dwarf_Attribute type_attr;
1590 Dwarf_Word constant;
1591 if (dwarf_attr_integrate (this->function, DW_AT_decl_line, &type_attr))
1592 {
1593 dwarf_formudata (&type_attr, &constant);
1594 line_number = constant;
1595 }
1596 else
1597 return;
1598 }
440f755a
JS
1599 lineno += line_number;
1600 }
78e2a671
DT
1601 else if (line_type == WILDCARD) {
1602 if (name_has_wildcard(func_pattern)) /* PR14774: look at whole file if function name is wildcard */
1603 lineno = 0;
1604 else
1605 function_line (&lineno);
1606 }
1123a74a
WH
1607 else if (line_type == RANGE) { /* correct lineno */
1608 int start_lineno;
1609
9b988eff
WH
1610 if (name_has_wildcard(func_pattern)) /* PR10294: wider range like statement("*@foo.c") */
1611 start_lineno = lineno;
1612 else
1613 function_line (&start_lineno);
1123a74a
WH
1614 lineno = lineno < start_lineno ? start_lineno : lineno;
1615 if (lineno > lines[1]) { /* invalid line range */
1616 stringstream advice;
f9bbd346 1617 advice << _("Invalid line range (") << lines[0] << "-" << lines[1] << ")";
1123a74a 1618 if (start_lineno > lines[1])
f9bbd346 1619 advice << _(", the end line number ") << lines[1] << " < " << start_lineno;
dc09353a 1620 throw SEMANTIC_ERROR (advice.str());
1123a74a
WH
1621 }
1622 }
1623
440f755a
JS
1624
1625 for (int l = lineno; ; l = l + 1)
1626 {
1627 set<int> lines_probed;
1628 pair<set<int>::iterator,bool> line_probed;
1123a74a
WH
1629 int ret = 0;
1630
e19ebcf7 1631 assert_no_interrupts();
b8c632dc 1632
35c68acb 1633 nsrcs = 0;
1123a74a
WH
1634 ret = dwarf_getsrc_file (module_dwarf, srcfile, l, 0,
1635 &srcsp, &nsrcs);
8aaef2fb
JS
1636 if (ret != 0) /* tolerate invalid line number */
1637 break;
1123a74a 1638
440f755a
JS
1639 if (line_type == WILDCARD || line_type == RANGE)
1640 {
1641 Dwarf_Addr line_addr;
1123a74a 1642
440f755a 1643 dwarf_lineno (srcsp [0], &lineno);
1123a74a
WH
1644 /* Maybe lineno will exceed the input end */
1645 if (line_type == RANGE && lineno > lines[1])
1646 break;
440f755a
JS
1647 line_probed = lines_probed.insert(lineno);
1648 if (lineno != l || line_probed.second == false || nsrcs > 1)
1649 continue;
1650 dwarf_lineaddr (srcsp [0], &line_addr);
9b988eff 1651 if (!function_name_matches(func_pattern) && dwarf_haspc (function, line_addr) != 1)
440f755a
JS
1652 break;
1653 }
1654
1655 // NB: Formerly, we used to filter, because:
1656
1657 // dwarf_getsrc_file gets one *near hits* for line numbers, not
1658 // exact matches. For example, an existing file but a nonexistent
1659 // line number will be rounded up to the next definition in that
1660 // file. This may be similar to the GDB breakpoint algorithm, but
1661 // we don't want to be so fuzzy in systemtap land. So we filter.
1662
1663 // But we now see the error of our ways, and skip this filtering.
1664
1665 // XXX: the code also fails to match e.g. inline function
1666 // definitions when the srcfile is a header file rather than the
1667 // CU name.
1668
1669 size_t remaining_nsrcs = nsrcs;
1670
1671 if (need_single_match && remaining_nsrcs > 1)
1672 {
1673 // We wanted a single line record (a unique address for the
1674 // line) and we got a bunch of line records. We're going to
1675 // skip this probe (throw an exception) but before we throw
1676 // we're going to look around a bit to see if there's a low or
1677 // high line number nearby which *doesn't* have this problem,
1678 // so we can give the user some advice.
1679
1680 int lo_try = -1;
1681 int hi_try = -1;
1682 for (size_t i = 1; i < 6; ++i)
1683 {
1684 if (lo_try == -1 && has_single_line_record(q, srcfile, lineno - i))
1685 lo_try = lineno - i;
1686
1687 if (hi_try == -1 && has_single_line_record(q, srcfile, lineno + i))
1688 hi_try = lineno + i;
1689 }
1690
1691 stringstream advice;
4c5d9906 1692 advice << _F("multiple addresses for %s:%d [man error::dwarf]", srcfile, lineno);
440f755a
JS
1693 if (lo_try > 0 || hi_try > 0)
1694 {
f9bbd346
LB
1695 //TRANSLATORS: Here we are trying to advise what source file
1696 //TRANSLATORS: to attempt.
1697 advice << _(" (try ");
440f755a
JS
1698 if (lo_try > 0)
1699 advice << srcfile << ":" << lo_try;
1700 if (lo_try > 0 && hi_try > 0)
f9bbd346 1701 advice << _(" or ");
440f755a
JS
1702 if (hi_try > 0)
1703 advice << srcfile << ":" << hi_try;
1704 advice << ")";
1705 }
dc09353a 1706 throw SEMANTIC_ERROR (advice.str());
440f755a
JS
1707 }
1708
1709 for (size_t i = 0; i < nsrcs; ++i)
1710 {
e19ebcf7 1711 assert_no_interrupts();
440f755a
JS
1712 if (srcsp [i]) // skip over mismatched lines
1713 callback (dwarf_line_t(srcsp[i]), data);
1714 }
1715
1716 if (line_type == ABSOLUTE || line_type == RELATIVE)
1717 break;
1718 else if (line_type == RANGE && l == lines[1])
1719 break;
1720 }
1721}
1722
1723
147a2577
JL
1724template<> void
1725dwflpp::iterate_over_labels<void>(Dwarf_Die *begin_die,
1726 const string& sym,
1727 const string& function,
1728 void *data,
1729 void (* callback)(const string&,
1730 const char*,
1731 const char*,
1732 int,
1733 Dwarf_Die*,
1734 Dwarf_Addr,
1735 void*))
440f755a 1736{
440f755a
JS
1737 get_module_dwarf();
1738
dee830d9 1739 Dwarf_Die die, import;
f09d0d1e 1740 const char *name;
440f755a
JS
1741 int res = dwarf_child (begin_die, &die);
1742 if (res != 0)
1743 return; // die without children, bail out.
1744
440f755a
JS
1745 do
1746 {
f09d0d1e 1747 switch (dwarf_tag(&die))
440f755a
JS
1748 {
1749 case DW_TAG_label:
f09d0d1e
JS
1750 name = dwarf_diename (&die);
1751 if (name &&
8096dd7d
JS
1752 (name == sym
1753 || (name_has_wildcard(sym)
1754 && function_name_matches_pattern (name, sym))))
1755 {
8096dd7d
JS
1756 // Don't try to be smart. Just drop no addr labels.
1757 Dwarf_Addr stmt_addr;
1758 if (dwarf_lowpc (&die, &stmt_addr) == 0)
1759 {
f09d0d1e
JS
1760 // Get the file/line number for this label
1761 int dline;
c60517ca 1762 const char *file = dwarf_decl_file (&die) ?: "<unknown source>";
f09d0d1e
JS
1763 dwarf_decl_line (&die, &dline);
1764
9aa8ffce
JS
1765 vector<Dwarf_Die> scopes = getscopes_die(&die);
1766 if (scopes.size() > 1)
f5958c8f
JS
1767 {
1768 Dwarf_Die scope;
2713ea24 1769 if (!inner_die_containing_pc(scopes[1], stmt_addr, scope))
2a43d5db 1770 {
7e456f65
LB
1771 sess.print_warning(_F("label '%s' at address %s (dieoffset: %s) is not "
1772 "contained by its scope '%s' (dieoffset: %s) -- bad"
4c5d9906 1773 " debuginfo? [man error::dwarf]", name, lex_cast_hex(stmt_addr).c_str(),
7e456f65
LB
1774 lex_cast_hex(dwarf_dieoffset(&die)).c_str(),
1775 (dwarf_diename(&scope) ?: "<unknown>"),
1776 lex_cast_hex(dwarf_dieoffset(&scope)).c_str()));
2a43d5db 1777 }
f5958c8f 1778 callback(function, name, file, dline,
147a2577 1779 &scope, stmt_addr, data);
f5958c8f 1780 }
8096dd7d
JS
1781 }
1782 }
440f755a 1783 break;
8096dd7d 1784
440f755a 1785 case DW_TAG_subprogram:
30868aad 1786 case DW_TAG_inlined_subroutine:
f09d0d1e
JS
1787 // Stay within our filtered function
1788 break;
1789
dee830d9
MW
1790 case DW_TAG_imported_unit:
1791 // Iterate over the children of the imported unit as if they
1792 // were inserted in place.
1793 if (dwarf_attr_die(&die, DW_AT_import, &import))
147a2577 1794 iterate_over_labels (&import, sym, function, data, callback);
dee830d9
MW
1795 break;
1796
440f755a
JS
1797 default:
1798 if (dwarf_haschildren (&die))
147a2577 1799 iterate_over_labels (&die, sym, function, data, callback);
8096dd7d 1800 break;
440f755a
JS
1801 }
1802 }
1803 while (dwarf_siblingof (&die, &die) == 0);
1804}
1805
67959c62
JL
1806// Mini 'query-like' struct to help us navigate callbacks during
1807// external function resolution
1808struct external_function_query {
1809 dwflpp* dw;
1810 const char* name;
1811 Dwarf_Die die;
1812 Dwarf_Addr addr;
1813 bool resolved;
1814 external_function_query(dwflpp* dw, const char* name):
1815 dw(dw), name(name), resolved(false) {}
1816};
1817
1818int
5c378838 1819dwflpp::external_function_cu_callback (Dwarf_Die* cu, external_function_query *efq)
67959c62 1820{
67959c62
JL
1821 efq->dw->focus_on_cu(cu);
1822 return efq->dw->iterate_over_functions(external_function_func_callback,
1823 efq, efq->name);
1824}
1825
1826int
7d007451 1827dwflpp::external_function_func_callback (Dwarf_Die* func, external_function_query *efq)
67959c62 1828{
67959c62
JL
1829 Dwarf_Attribute external;
1830 Dwarf_Addr func_addr;
1831 if (dwarf_attr_integrate(func, DW_AT_external, &external) != NULL &&
1832 dwarf_lowpc(func, &func_addr) == 0)
1833 {
1834 efq->die = *func;
1835 efq->addr = func_addr;
1836 efq->resolved = true;
1837 return DWARF_CB_ABORT; // we found it so stop here
1838 }
1839 return DWARF_CB_OK;
1840}
1841
172688cb
JL
1842template<> void
1843dwflpp::iterate_over_callees<void>(Dwarf_Die *begin_die,
1844 const string& sym,
1845 long recursion_depth,
1846 void *data,
1847 void (* callback)(const char*,
1848 const char*,
1849 int,
1850 Dwarf_Die*,
1851 Dwarf_Addr,
80a63be6 1852 Dwarf_Die*,
172688cb
JL
1853 stack<Dwarf_Addr>*,
1854 void*),
80a63be6
JL
1855 stack<Dwarf_Addr> *callers,
1856 Dwarf_Die *parent_die)
67959c62
JL
1857{
1858 get_module_dwarf();
1859
1860 Dwarf_Die die, import;
1861
1862 // DIE of abstract_origin found in die
1863 Dwarf_Die origin;
1864
1865 // callee's entry pc (= where we'll probe)
1866 Dwarf_Addr func_addr;
1867
1868 // caller's unwind pc during call (to match against bt for filtering)
1869 Dwarf_Addr caller_uw_addr;
1870
1871 Dwarf_Attribute attr;
1872
1873 int dline;
1874 const char *name, *file;
1875 if (dwarf_child(begin_die, &die) != 0)
1876 return; // die without children, bail out.
1877
1878 bool free_callers = false;
1879 if (callers == NULL) /* first call */
1880 {
1881 callers = new stack<Dwarf_Addr>();
1882 free_callers = true;
1883 }
1884
80a63be6
JL
1885 // parent_die tracks the DIE of the parent subprogram/inlined_subroutine. This
1886 // is not always begin_die since we recurse on other things such as
1887 // imported_unit and whatever else has children.
1888 if (parent_die == NULL)
1889 parent_die = begin_die;
1890
67959c62
JL
1891 do
1892 {
1893 bool inlined = false;
1894 switch (dwarf_tag(&die))
1895 {
1896 case DW_TAG_inlined_subroutine:
1897 inlined = true;
1898 case DW_TAG_GNU_call_site:
1899 name = dwarf_diename (&die);
1900 if (!name)
1901 continue;
1902 if (name != sym)
1903 {
1904 if (!name_has_wildcard(sym))
1905 continue;
1906 if (!function_name_matches_pattern(name, sym))
1907 continue;
1908 }
1909
1910 /* In both cases (call sites and inlines), we want the
1911 * abstract_origin. The difference is that in inlines, the addr is
1912 * in the die itself, whereas for call sites, the addr is in the
1913 * abstract_origin's die.
1914 * Note that in the case of inlines, we're only calling back
1915 * for that inline instance, not all. This is what we want, since
1916 * it will only be triggered when 'called' from the target func,
1917 * which is something we have to emulate for non-inlined funcs
1918 * (which is the purpose of the caller_uw_addr below) */
1919 if (dwarf_attr_die(&die, DW_AT_abstract_origin, &origin) == NULL)
1920 continue;
1921
1922 // the low_pc of the die in either cases is the pc that would
1923 // show up in a backtrace (inlines are a special case in which
1924 // the die's low_pc is also the abstract_origin's low_pc = the
1925 // 'start' of the inline instance)
1926 if (dwarf_lowpc(&die, &caller_uw_addr) != 0)
1927 continue;
1928
1929 if (inlined)
1930 func_addr = caller_uw_addr;
1931 else if (dwarf_lowpc(&origin, &func_addr) != 0)
1932 {
1933 // function doesn't have a low_pc, is it external?
1934 if (dwarf_attr_integrate(&origin, DW_AT_external,
1935 &attr) != NULL)
1936 {
1937 // let's iterate over the CUs and find it. NB: it's
1938 // possible we could have also done this by creating a
1939 // probe point with .exported tacked on and rerunning it
1940 // through derive_probe(). But since we're already on the
1941 // dwflpp side of things, and we already have access to
1942 // everything we need, let's try to be self-sufficient.
1943
1944 // remember old focus
1945 Dwarf_Die *old_cu = cu;
80a63be6 1946 Dwarf_Die *old_function = function;
67959c62
JL
1947
1948 external_function_query efq(this, dwarf_linkage_name(&origin) ?: name);
1949 iterate_over_cus(external_function_cu_callback, &efq, false);
1950
1951 // restore focus
80a63be6
JL
1952 if (old_cu)
1953 focus_on_cu(old_cu);
1954 if (old_function)
1955 focus_on_function(old_function);
67959c62
JL
1956
1957 if (!efq.resolved) // did we resolve it?
1958 continue;
1959
1960 func_addr = efq.addr;
1961 origin = efq.die;
1962 }
1963 // non-external function without low_pc, jump ship
1964 else continue;
1965 }
1966
1967 // We now have the addr to probe in func_addr, and the DIE
1968 // from which to obtain file/line info in origin
1969
1970 // Get the file/line number for this callee
1971 file = dwarf_decl_file (&origin) ?: "<unknown source>";
1972 dwarf_decl_line (&origin, &dline);
1973
1974 // add as a caller to match against
1975 if (!inlined)
1976 callers->push(caller_uw_addr);
1977
1978 callback(name, file, dline, inlined ? &die : &origin,
80a63be6 1979 func_addr, parent_die, callers, data);
67959c62
JL
1980
1981 // If it's a tail call, print a warning that it may not be caught
1982 if (!inlined
1983 && dwarf_attr_integrate(&die, DW_AT_GNU_tail_call, &attr) != NULL)
1984 sess.print_warning (_F("Callee \"%s\" in function \"%s\" is a tail call: "
1985 ".callee probe may not fire. Try placing the probe "
1986 "directly on the callee function instead.", name,
1987 dwarf_diename(begin_die)));
1988
1989 if (recursion_depth > 1) // .callees(N)
1990 iterate_over_callees(inlined ? &die : &origin,
172688cb 1991 sym, recursion_depth-1, data,
67959c62
JL
1992 callback, callers);
1993
1994 if (!inlined)
1995 callers->pop();
1996 break;
1997
1998 case DW_TAG_subprogram:
1999 break; // don't leave our filtered func
2000
2001 case DW_TAG_imported_unit:
2002 // Iterate over the children of the imported unit as if they
2003 // were inserted in place.
2004 if (dwarf_attr_die(&die, DW_AT_import, &import))
80a63be6
JL
2005 iterate_over_callees (&import, sym, recursion_depth, data,
2006 callback, callers, parent_die);
67959c62
JL
2007 break;
2008
2009 default:
2010 if (dwarf_haschildren (&die))
80a63be6
JL
2011 iterate_over_callees (&die, sym, recursion_depth, data,
2012 callback, callers, parent_die);
67959c62
JL
2013 break;
2014 }
2015 }
2016 while (dwarf_siblingof (&die, &die) == 0);
2017
2018 if (free_callers && callers != NULL)
2019 delete callers;
2020}
2021
440f755a
JS
2022
2023void
2024dwflpp::collect_srcfiles_matching (string const & pattern,
bd25380d 2025 set<string> & filtered_srcfiles)
440f755a
JS
2026{
2027 assert (module);
2028 assert (cu);
2029
2030 size_t nfiles;
2031 Dwarf_Files *srcfiles;
2032
2033 // PR 5049: implicit * in front of given path pattern.
2034 // NB: fnmatch() is used without FNM_PATHNAME.
2035 string prefixed_pattern = string("*/") + pattern;
2036
2037 dwarf_assert ("dwarf_getsrcfiles",
2038 dwarf_getsrcfiles (cu, &srcfiles, &nfiles));
2039 {
2040 for (size_t i = 0; i < nfiles; ++i)
2041 {
2042 char const * fname = dwarf_filesrc (srcfiles, i, NULL, NULL);
2043 if (fnmatch (pattern.c_str(), fname, 0) == 0 ||
2044 fnmatch (prefixed_pattern.c_str(), fname, 0) == 0)
2045 {
2046 filtered_srcfiles.insert (fname);
2047 if (sess.verbose>2)
f9bbd346 2048 clog << _F("selected source file '%s'\n", fname);
440f755a
JS
2049 }
2050 }
2051 }
2052}
2053
2054
2055void
2056dwflpp::resolve_prologue_endings (func_info_map_t & funcs)
2057{
02a15be0
JL
2058 // When a program is compiled with no optimization, GCC does no variable
2059 // tracking, which means that location info is actually only really valid
2060 // after the prologue, even though GCC reports it as valid during. So we need
2061 // to find the prologue ends to get accurate info. This may or may not be the
2062 // first address that has a source line distinct from the function
2063 // declaration's.
440f755a
JS
2064
2065 assert(module);
2066 assert(cu);
2067
2068 size_t nlines = 0;
2069 Dwarf_Lines *lines = NULL;
2070
2071 /* trouble cases:
2072 malloc do_symlink in init/initramfs.c tail-recursive/tiny then no-prologue
2073 sys_get?id in kernel/timer.c no-prologue
2074 sys_exit_group tail-recursive
2075 {do_,}sys_open extra-long-prologue (gcc 3.4)
2076 cpu_to_logical_apicid NULL-decl_file
2077 */
2078
2079 // Fetch all srcline records, sorted by address.
2080 dwarf_assert ("dwarf_getsrclines",
2081 dwarf_getsrclines(cu, &lines, &nlines));
2082 // XXX: free lines[] later, but how?
2083
ac3d3735
JL
2084 // We normally ignore a function's decl_line, since it is associated with the
2085 // line at which the identifier appears in the declaration, and has no
2086 // meaningful relation to the lineno associated with the entrypc (which is
2087 // normally the lineno of '{', which could occur at the same line as the
2088 // declaration, or lower down).
2089 // However, if the CU was compiled using GCC < 4.4, then the decl_line
2090 // actually represents the lineno of '{' as well, in which case if the lineno
2091 // associated with the entrypc is != to the decl_line, it means the compiler
2092 // scraped/optimized off some of the beginning of the function and the safest
2093 // thing we can do is consider it naked.
2094 bool consider_decl_line = false;
7d31f657
JL
2095 {
2096 string prod, vers;
2097 if (is_gcc_producer(cu, prod, vers)
2098 && strverscmp(vers.c_str(), "4.4.0") < 0)
2099 consider_decl_line = true;
2100 }
ac3d3735 2101
440f755a
JS
2102 for(func_info_map_t::iterator it = funcs.begin(); it != funcs.end(); it++)
2103 {
2104#if 0 /* someday */
2105 Dwarf_Addr* bkpts = 0;
2106 int n = dwarf_entry_breakpoints (& it->die, & bkpts);
2107 // ...
2108 free (bkpts);
2109#endif
2110
2111 Dwarf_Addr entrypc = it->entrypc;
2112 Dwarf_Addr highpc; // NB: highpc is exclusive: [entrypc,highpc)
2113 dwfl_assert ("dwarf_highpc", dwarf_highpc (& it->die,
2114 & highpc));
2115
2116 if (it->decl_file == 0) it->decl_file = "";
2117
2118 unsigned entrypc_srcline_idx = 0;
2119 dwarf_line_t entrypc_srcline;
2120 // open-code binary search for exact match
2121 {
2122 unsigned l = 0, h = nlines;
2123 while (l < h)
2124 {
2125 entrypc_srcline_idx = (l + h) / 2;
2126 const dwarf_line_t lr(dwarf_onesrcline(lines,
2127 entrypc_srcline_idx));
2128 Dwarf_Addr addr = lr.addr();
2129 if (addr == entrypc) { entrypc_srcline = lr; break; }
2130 else if (l + 1 == h) { break; } // ran off bottom of tree
2131 else if (addr < entrypc) { l = entrypc_srcline_idx; }
2132 else { h = entrypc_srcline_idx; }
2133 }
2134 }
2135 if (!entrypc_srcline)
2136 {
2137 if (sess.verbose > 2)
f9bbd346
LB
2138 clog << _F("missing entrypc dwarf line record for function '%s'\n",
2139 it->name.c_str());
440f755a
JS
2140 // This is probably an inlined function. We'll end up using
2141 // its lowpc as a probe address.
2142 continue;
2143 }
2144
48390b53
FCE
2145 if (entrypc == 0)
2146 {
2147 if (sess.verbose > 2)
f9bbd346
LB
2148 clog << _F("null entrypc dwarf line record for function '%s'\n",
2149 it->name.c_str());
48390b53
FCE
2150 // This is probably an inlined function. We'll skip this instance;
2151 // it is messed up.
2152 continue;
2153 }
2154
440f755a 2155 if (sess.verbose>2)
2a97f50b 2156 clog << _F("searching for prologue of function '%s' %#" PRIx64 "-%#" PRIx64
f9bbd346
LB
2157 "@%s:%d\n", it->name.c_str(), entrypc, highpc, it->decl_file,
2158 it->decl_line);
440f755a 2159
02a15be0
JL
2160 // For each function, we look for the prologue-end marker (e.g. clang
2161 // outputs one). If there is no explicit marker (e.g. GCC does not), we
2162 // accept a bigger or equal lineno as a prologue end (this catches GCC's
2163 // 0-line advances).
02a15be0 2164
440f755a
JS
2165 // We may have to skip a few because some old compilers plop
2166 // in dummy line records for longer prologues. If we go too
2167 // far (addr >= highpc), we take the previous one. Or, it may
2168 // be the first one, if the function had no prologue, and thus
2169 // the entrypc maps to a statement in the body rather than the
2170 // declaration.
2171
a43d3fbf
JL
2172 int entrypc_srcline_lineno = entrypc_srcline.lineno();
2173 unsigned postprologue_srcline_idx = entrypc_srcline_idx;
158f2f12 2174 dwarf_line_t postprologue_srcline;
02a15be0 2175
440f755a
JS
2176 while (postprologue_srcline_idx < nlines)
2177 {
158f2f12
JL
2178 postprologue_srcline = dwarf_onesrcline(lines,
2179 postprologue_srcline_idx);
2180 Dwarf_Addr lineaddr = postprologue_srcline.addr();
2181 const char* linesrc = postprologue_srcline.linesrc();
2182 int lineno = postprologue_srcline.lineno();
2183 bool lineprologue_end = postprologue_srcline.is_prologue_end();
440f755a
JS
2184
2185 if (sess.verbose>2)
158f2f12
JL
2186 clog << _F("checking line record %#" PRIx64 "@%s:%d%s\n", lineaddr,
2187 linesrc, lineno, lineprologue_end ? " (marked)" : "");
440f755a 2188
158f2f12
JL
2189 // have we passed the function?
2190 if (lineaddr >= highpc)
2191 break;
2192 // is there an explicit prologue_end marker?
2193 if (lineprologue_end)
2194 break;
2195 // is it a different file?
2196 if (strcmp(linesrc, it->decl_file))
2197 break;
2198 // OK, it's the same file, but is it a different line?
2199 if (lineno != entrypc_srcline_lineno)
2200 break;
2201 // Same file and line, is this a second line record (e.g. 0-line advance)?
2202 if (postprologue_srcline_idx != entrypc_srcline_idx)
2203 break;
2204 // This is the first iteration. Is decl_line meaningful and is the
2205 // lineno past the decl_line?
2206 if (consider_decl_line && lineno != it->decl_line)
2207 break;
440f755a
JS
2208
2209 // Let's try the next srcline.
2210 postprologue_srcline_idx ++;
158f2f12 2211
440f755a
JS
2212 } // loop over srclines
2213
158f2f12
JL
2214 Dwarf_Addr postprologue_addr = postprologue_srcline.addr();
2215 if (postprologue_addr >= highpc)
2216 {
2217 // pick addr of previous line record
2218 dwarf_line_t lr(dwarf_onesrcline(lines, postprologue_srcline_idx-1));
2219 postprologue_addr = lr.addr();
2220 }
2221
2222 it->prologue_end = postprologue_addr;
2223
2224 if (sess.verbose>2)
2225 {
2226 clog << _F("prologue found function '%s'", it->name.c_str());
2227 // Add a little classification datum
2228 //TRANSLATORS: Here we're adding some classification datum (ie Prologue Free)
2229 if (postprologue_addr == entrypc) clog << _(" (naked)");
2230 //TRANSLATORS: Here we're adding some classification datum (ie we went over)
2231 if (postprologue_srcline.addr() >= highpc) clog << _(" (tail-call?)");
2232 //TRANSLATORS: Here we're adding some classification datum (ie it was marked)
2233 if (postprologue_srcline.is_prologue_end()) clog << _(" (marked)");
2234 clog << " = 0x" << hex << postprologue_addr << dec << "\n";
2235 }
440f755a
JS
2236
2237 } // loop over functions
2238
2239 // XXX: how to free lines?
2240}
2241
2242
2243bool
2244dwflpp::function_entrypc (Dwarf_Addr * addr)
2245{
2246 assert (function);
1bbf3f90
JS
2247 // PR10574: reject 0, which tends to be eliminated COMDAT
2248 return (dwarf_entrypc (function, addr) == 0 && *addr != 0);
440f755a
JS
2249}
2250
2251
2252bool
2253dwflpp::die_entrypc (Dwarf_Die * die, Dwarf_Addr * addr)
2254{
2255 int rc = 0;
2256 string lookup_method;
2257
2258 * addr = 0;
2259
2260 lookup_method = "dwarf_entrypc";
2261 rc = dwarf_entrypc (die, addr);
2262
440f755a
JS
2263 if (rc)
2264 {
2265 lookup_method = "dwarf_ranges";
2266
2267 Dwarf_Addr base;
2268 Dwarf_Addr begin;
2269 Dwarf_Addr end;
2270 ptrdiff_t offset = dwarf_ranges (die, 0, &base, &begin, &end);
2271 if (offset < 0) rc = -1;
2272 else if (offset > 0)
2273 {
2274 * addr = begin;
2275 rc = 0;
2276
2277 // Now we need to check that there are no more ranges
2278 // associated with this function, which could conceivably
2279 // happen if a function is inlined, then pieces of it are
2280 // split amongst different conditional branches. It's not
2281 // obvious which of them to favour. As a heuristic, we
2282 // pick the beginning of the first range, and ignore the
2283 // others (but with a warning).
2284
2285 unsigned extra = 0;
2286 while ((offset = dwarf_ranges (die, offset, &base, &begin, &end)) > 0)
2287 extra ++;
2288 if (extra)
f9bbd346 2289 lookup_method += _F(", ignored %s more", lex_cast(extra).c_str());
440f755a
JS
2290 }
2291 }
2292
4ad42007
FCE
2293 // PR10574: reject subprograms where the entrypc address turns out
2294 // to be 0, since they tend to correspond to duplicate-eliminated
2295 // COMDAT copies of C++ functions.
2296 if (rc == 0 && *addr == 0)
2297 {
f9bbd346 2298 lookup_method += _(" (skip comdat)");
4ad42007
FCE
2299 rc = 1;
2300 }
2301
440f755a 2302 if (sess.verbose > 2)
e045bb07 2303 clog << _F("entry-pc lookup (%s dieoffset: %s) = %#" PRIx64 " (rc %d)", lookup_method.c_str(),
f9bbd346 2304 lex_cast_hex(dwarf_dieoffset(die)).c_str(), *addr, rc) << endl;
4ad42007 2305
440f755a
JS
2306 return (rc == 0);
2307}
2308
2309
2310void
2311dwflpp::function_die (Dwarf_Die *d)
2312{
2313 assert (function);
2314 *d = *function;
2315}
2316
2317
2318void
2319dwflpp::function_file (char const ** c)
2320{
2321 assert (function);
2322 assert (c);
c60517ca 2323 *c = dwarf_decl_file (function) ?: "<unknown source>";
440f755a
JS
2324}
2325
2326
2327void
2328dwflpp::function_line (int *linep)
2329{
2330 assert (function);
2331 dwarf_decl_line (function, linep);
2332}
2333
2334
2335bool
2336dwflpp::die_has_pc (Dwarf_Die & die, Dwarf_Addr pc)
2337{
2338 int res = dwarf_haspc (&die, pc);
2339 // dwarf_ranges will return -1 if a function die has no DW_AT_ranges
2340 // if (res == -1)
2341 // dwarf_assert ("dwarf_haspc", res);
2342 return res == 1;
2343}
2344
2345
2a43d5db 2346bool
f5958c8f
JS
2347dwflpp::inner_die_containing_pc(Dwarf_Die& scope, Dwarf_Addr addr,
2348 Dwarf_Die& result)
2349{
793f98d5
JS
2350 result = scope;
2351
2352 // Sometimes we're in a bad scope to begin with -- just let it be. This can
2353 // happen for example if the compiler outputs a label PC that's just outside
2354 // the lexical scope. We can't really do anything about that, but variables
2355 // will probably not be accessible in this case.
f5958c8f 2356 if (!die_has_pc(scope, addr))
2a43d5db 2357 return false;
f5958c8f 2358
dee830d9 2359 Dwarf_Die child, import;
f5958c8f
JS
2360 int rc = dwarf_child(&result, &child);
2361 while (rc == 0)
2362 {
2363 switch (dwarf_tag (&child))
2364 {
dee830d9
MW
2365 case DW_TAG_imported_unit:
2366 // The children of the imported unit need to be treated as if
2367 // they are inserted here. So look inside and set result if
2368 // found.
2369 if (dwarf_attr_die(&child, DW_AT_import, &import))
2370 {
2371 Dwarf_Die import_result;
2372 if (inner_die_containing_pc(import, addr, import_result))
2373 {
2374 result = import_result;
2375 return true;
2376 }
2377 }
2378 break;
2379
f5958c8f
JS
2380 // lexical tags to recurse within the same starting scope
2381 // NB: this intentionally doesn't cross into inlines!
2382 case DW_TAG_lexical_block:
2383 case DW_TAG_with_stmt:
2384 case DW_TAG_catch_block:
2385 case DW_TAG_try_block:
2386 case DW_TAG_entry_point:
2387 if (die_has_pc(child, addr))
2388 {
2389 result = child;
2390 rc = dwarf_child(&result, &child);
2391 continue;
2392 }
2393 }
2394 rc = dwarf_siblingof(&child, &child);
2395 }
2a43d5db 2396 return true;
f5958c8f
JS
2397}
2398
2399
440f755a
JS
2400void
2401dwflpp::loc2c_error (void *, const char *fmt, ...)
2402{
2403 const char *msg = "?";
2404 char *tmp = NULL;
2405 int rc;
2406 va_list ap;
2407 va_start (ap, fmt);
2408 rc = vasprintf (& tmp, fmt, ap);
2409 if (rc < 0)
2410 msg = "?";
2411 else
2412 msg = tmp;
2413 va_end (ap);
dc09353a 2414 throw SEMANTIC_ERROR (msg);
440f755a
JS
2415}
2416
2417
2418// This function generates code used for addressing computations of
2419// target variables.
2420void
2421dwflpp::emit_address (struct obstack *pool, Dwarf_Addr address)
2422{
2d7232ca 2423 int n = dwfl_module_relocations (module);
440f755a
JS
2424 dwfl_assert ("dwfl_module_relocations", n >= 0);
2425 Dwarf_Addr reloc_address = address;
2d7232ca
MW
2426 const char *secname = "";
2427 if (n > 1)
2428 {
2429 int i = dwfl_module_relocate_address (module, &reloc_address);
2430 dwfl_assert ("dwfl_module_relocate_address", i >= 0);
2431 secname = dwfl_module_relocation_info (module, i, NULL);
2432 }
440f755a
JS
2433
2434 if (sess.verbose > 2)
2435 {
2a97f50b 2436 clog << _F("emit dwarf addr %#" PRIx64 " => module %s section %s relocaddr %#" PRIx64,
2d7232ca
MW
2437 address, module_name.c_str (), (secname ?: "null"),
2438 reloc_address) << endl;
440f755a
JS
2439 }
2440
2441 if (n > 0 && !(n == 1 && secname == NULL))
2442 {
2443 dwfl_assert ("dwfl_module_relocation_info", secname);
2444 if (n > 1 || secname[0] != '\0')
2445 {
2446 // This gives us the module name, and section name within the
2447 // module, for a kernel module (or other ET_REL module object).
f685b2fe 2448 obstack_printf (pool, "({ unsigned long addr = 0; ");
a049e342 2449 obstack_printf (pool, "addr = _stp_kmodule_relocate (\"%s\",\"%s\",%#" PRIx64 "); ",
2d7232ca 2450 module_name.c_str(), secname, reloc_address);
440f755a
JS
2451 obstack_printf (pool, "addr; })");
2452 }
2453 else if (n == 1 && module_name == TOK_KERNEL && secname[0] == '\0')
2454 {
2455 // elfutils' way of telling us that this is a relocatable kernel address, which we
2456 // need to treat the same way here as dwarf_query::add_probe_point does: _stext.
2457 address -= sess.sym_stext;
2458 secname = "_stext";
f685b2fe
MW
2459 // Note we "cache" the result here through a static because the
2460 // kernel will never move after being loaded (unlike modules and
2461 // user-space dynamic share libraries).
440f755a 2462 obstack_printf (pool, "({ static unsigned long addr = 0; ");
a049e342 2463 obstack_printf (pool, "if (addr==0) addr = _stp_kmodule_relocate (\"%s\",\"%s\",%#" PRIx64 "); ",
2d7232ca 2464 module_name.c_str(), secname, address); // PR10000 NB: not reloc_address
440f755a
JS
2465 obstack_printf (pool, "addr; })");
2466 }
2467 else
2468 {
7f085e3f 2469 obstack_printf (pool, "/* pragma:vma */");
f685b2fe 2470 obstack_printf (pool, "({ unsigned long addr = 0; ");
a049e342 2471 obstack_printf (pool, "addr = _stp_umodule_relocate (\"%s\",%#" PRIx64 ", current); ",
5bca76a8 2472 resolve_path(module_name.c_str()).c_str(), address);
a295050e 2473 obstack_printf (pool, "addr; })");
440f755a
JS
2474 }
2475 }
2476 else
2477 obstack_printf (pool, "%#" PRIx64 "UL", address); // assume as constant
2478}
2479
2480
2481void
2482dwflpp::loc2c_emit_address (void *arg, struct obstack *pool,
2483 Dwarf_Addr address)
2484{
c94efd63 2485 static_cast<dwflpp *>(arg)->emit_address (pool, address);
440f755a
JS
2486}
2487
2488
2489void
2b4f27bd 2490dwflpp::get_locals(vector<Dwarf_Die>& scopes, set<string>& locals)
440f755a 2491{
729455a7
JS
2492 // XXX Shouldn't this be walking up to outer scopes too?
2493
2b4f27bd 2494 get_locals_die(scopes[0], locals);
dee830d9
MW
2495}
2496
2497void
2b4f27bd 2498dwflpp::get_locals_die(Dwarf_Die& die, set<string>& locals)
dee830d9 2499{
440f755a 2500 // Try to get the first child of die.
dee830d9
MW
2501 Dwarf_Die child, import;
2502 if (dwarf_child (&die, &child) == 0)
440f755a
JS
2503 {
2504 do
2505 {
2506 const char *name;
2507 // Output each sibling's name (that is a variable or
2508 // parameter) to 'o'.
2509 switch (dwarf_tag (&child))
2510 {
2511 case DW_TAG_variable:
2512 case DW_TAG_formal_parameter:
2513 name = dwarf_diename (&child);
2514 if (name)
2b4f27bd 2515 locals.insert(string("$") + name);
440f755a 2516 break;
dee830d9
MW
2517 case DW_TAG_imported_unit:
2518 // Treat the imported unit children as if they are
2519 // children of the given DIE.
2520 if (dwarf_attr_die(&child, DW_AT_import, &import))
2b4f27bd 2521 get_locals_die (import, locals);
dee830d9 2522 break;
440f755a
JS
2523 default:
2524 break;
2525 }
2526 }
2527 while (dwarf_siblingof (&child, &child) == 0);
2528 }
2529}
2530
2531
2532Dwarf_Attribute *
729455a7 2533dwflpp::find_variable_and_frame_base (vector<Dwarf_Die>& scopes,
440f755a
JS
2534 Dwarf_Addr pc,
2535 string const & local,
2536 const target_symbol *e,
2537 Dwarf_Die *vardie,
2538 Dwarf_Attribute *fb_attr_mem)
2539{
729455a7 2540 Dwarf_Die *scope_die = &scopes[0];
440f755a
JS
2541 Dwarf_Attribute *fb_attr = NULL;
2542
2543 assert (cu);
2544
729455a7 2545 int declaring_scope = dwarf_getscopevar (&scopes[0], scopes.size(),
440f755a
JS
2546 local.c_str(),
2547 0, NULL, 0, 0,
2548 vardie);
2549 if (declaring_scope < 0)
2550 {
2b4f27bd
JL
2551 set<string> locals;
2552 get_locals(scopes, locals);
2553 string sugs = levenshtein_suggest(local, locals); // probably not that many, so no limit
bd1fcbad 2554 if (pc)
dc09353a 2555 throw SEMANTIC_ERROR (_F("unable to find local '%s', [man error::dwarf] dieoffset %s in %s, near pc %s %s %s %s (%s)",
3d9381fc 2556 local.c_str(),
54bc3392
MW
2557 lex_cast_hex(dwarf_dieoffset(scope_die)).c_str(),
2558 module_name.c_str(),
3d9381fc
MW
2559 lex_cast_hex(pc).c_str(),
2560 (scope_die == NULL) ? "" : _("in"),
2561 (dwarf_diename(scope_die) ?: "<unknown>"),
2562 (dwarf_diename(cu) ?: "<unknown>"),
2b4f27bd 2563 (sugs.empty()
3d9381fc 2564 ? (_("<no alternatives>"))
2b4f27bd 2565 : (_("alternatives: ") + sugs + ")")).c_str()),
3d9381fc
MW
2566 e->tok);
2567 else
dc09353a 2568 throw SEMANTIC_ERROR (_F("unable to find global '%s', [man error::dwarf] dieoffset %s in %s, %s %s %s (%s)",
3d9381fc 2569 local.c_str(),
54bc3392
MW
2570 lex_cast_hex(dwarf_dieoffset(scope_die)).c_str(),
2571 module_name.c_str(),
3d9381fc
MW
2572 (scope_die == NULL) ? "" : _("in"),
2573 (dwarf_diename(scope_die) ?: "<unknown>"),
bd1fcbad 2574 cu_name().c_str(),
2b4f27bd 2575 (sugs.empty()
3d9381fc 2576 ? (_("<no alternatives>"))
2b4f27bd 2577 : (_("alternatives: ") + sugs + ")")).c_str()),
3d9381fc 2578 e->tok);
440f755a
JS
2579 }
2580
4d51e8ca
MW
2581 /* Some GCC versions would output duplicate external variables, one
2582 without a location attribute. If so, try to find the other if it
2583 exists in the same scope. See GCC PR51410. */
2584 Dwarf_Attribute attr_mem;
2585 if (dwarf_attr_integrate (vardie, DW_AT_const_value, &attr_mem) == NULL
2586 && dwarf_attr_integrate (vardie, DW_AT_location, &attr_mem) == NULL
2587 && dwarf_attr_integrate (vardie, DW_AT_external, &attr_mem) != NULL
2588 && dwarf_tag(&scopes[declaring_scope]) == DW_TAG_compile_unit)
2589 {
ea484b93 2590 Dwarf_Die orig_vardie = *vardie;
4d51e8ca
MW
2591 bool alt_found = false;
2592 if (dwarf_child(&scopes[declaring_scope], vardie) == 0)
2593 do
2594 {
dee830d9
MW
2595 // Note, not handling DW_TAG_imported_unit, assuming GCC
2596 // version is recent enough to not need this workaround if
2597 // we would see an imported unit.
4d51e8ca
MW
2598 if (dwarf_tag (vardie) == DW_TAG_variable
2599 && strcmp (dwarf_diename (vardie), local.c_str ()) == 0
2600 && (dwarf_attr_integrate (vardie, DW_AT_external, &attr_mem)
2601 != NULL)
2602 && ((dwarf_attr_integrate (vardie, DW_AT_const_value, &attr_mem)
2603 != NULL)
2604 || (dwarf_attr_integrate (vardie, DW_AT_location, &attr_mem)
2605 != NULL)))
2606 alt_found = true;
2607 }
2608 while (!alt_found && dwarf_siblingof(vardie, vardie) == 0);
2609
2610 if (! alt_found)
ea484b93 2611 *vardie = orig_vardie;
4d51e8ca
MW
2612 }
2613
3965e105 2614 // Global vars don't need (cannot use) frame base in location descriptor.
bd1fcbad 2615 if (pc == 0)
3965e105
MW
2616 return NULL;
2617
7bce6f87
MW
2618 /* We start out walking the "lexical scopes" as returned by
2619 * as returned by dwarf_getscopes for the address, starting with the
2620 * declaring_scope that the variable was found in.
2621 */
729455a7
JS
2622 vector<Dwarf_Die> physcopes, *fbscopes = &scopes;
2623 for (size_t inner = declaring_scope;
2624 inner < fbscopes->size() && fb_attr == NULL;
7bce6f87 2625 ++inner)
440f755a 2626 {
729455a7
JS
2627 Dwarf_Die& scope = (*fbscopes)[inner];
2628 switch (dwarf_tag (&scope))
440f755a
JS
2629 {
2630 default:
2631 continue;
2632 case DW_TAG_subprogram:
2633 case DW_TAG_entry_point:
729455a7 2634 fb_attr = dwarf_attr_integrate (&scope,
7bce6f87
MW
2635 DW_AT_frame_base,
2636 fb_attr_mem);
2637 break;
2638 case DW_TAG_inlined_subroutine:
2639 /* Unless we already are going through the "pyshical die tree",
2640 * we now need to start walking the die tree where this
2641 * subroutine is inlined to find the appropriate frame base. */
2642 if (declaring_scope != -1)
2643 {
729455a7
JS
2644 physcopes = getscopes_die(&scope);
2645 if (physcopes.empty())
dc09353a 2646 throw SEMANTIC_ERROR (_F("unable to get die scopes for '%s' in an inlined subroutine",
f9bbd346 2647 local.c_str()), e->tok);
729455a7 2648 fbscopes = &physcopes;
7bce6f87
MW
2649 inner = 0; // zero is current scope, for look will increase.
2650 declaring_scope = -1;
2651 }
440f755a
JS
2652 break;
2653 }
2654 }
7bce6f87 2655
440f755a
JS
2656 return fb_attr;
2657}
2658
2659
2660struct location *
2661dwflpp::translate_location(struct obstack *pool,
00730da1
MW
2662 Dwarf_Attribute *attr, Dwarf_Die *die,
2663 Dwarf_Addr pc,
440f755a
JS
2664 Dwarf_Attribute *fb_attr,
2665 struct location **tail,
2666 const target_symbol *e)
2667{
619d9aaf
MW
2668
2669 /* DW_AT_data_member_location, can be either constant offsets
e050d62f 2670 (struct member fields), or full blown location expressions. */
619d9aaf 2671
03ba05b6
MW
2672 /* There is no location expression, but a constant value instead. */
2673 if (dwarf_whatattr (attr) == DW_AT_const_value)
2674 {
2675 *tail = c_translate_constant (pool, &loc2c_error, this,
2676 &loc2c_emit_address, 0, pc, attr);
2677 return *tail;
2678 }
2679
440f755a
JS
2680 Dwarf_Op *expr;
2681 size_t len;
2682
2683 /* PR9768: formerly, we added pc+module_bias here. However, that bias value
2684 is not present in the pc value by the time we get it, so adding it would
2685 result in false negatives of variable reachibility. In other instances
2686 further below, the c_translate_FOO functions, the module_bias value used
2687 to be passed in, but instead should now be zero for the same reason. */
2688
45b02a36 2689 retry:
440f755a
JS
2690 switch (dwarf_getlocation_addr (attr, pc /*+ module_bias*/, &expr, &len, 1))
2691 {
2692 case 1: /* Should always happen. */
2693 if (len > 0)
2694 break;
2695 /* Fall through. */
2696
45b02a36
FCE
2697 case 0: /* Shouldn't happen.... but can, e.g. due to PR15123. */
2698 {
2699 Dwarf_Addr pc2 = pr15123_retry_addr (pc, die);
2700 if (pc2 != 0) {
2701 pc = pc2;
2702 goto retry;
2703 }
2704 }
2705
2706 /* FALLTHROUGH */
dc09353a 2707 throw SEMANTIC_ERROR (_F("not accessible at this address [man error::dwarf] (%s, dieoffset: %s)",
f9bbd346
LB
2708 lex_cast_hex(pc).c_str(), lex_cast_hex(dwarf_dieoffset(die)).c_str()),
2709 e->tok);
440f755a
JS
2710
2711 default: /* Shouldn't happen. */
2712 case -1:
dc09353a 2713 throw SEMANTIC_ERROR (_F("dwarf_getlocation_addr failed [man error::dwarf] , %s", dwarf_errmsg(-1)), e->tok);
440f755a
JS
2714 }
2715
3965e105 2716 Dwarf_Op *cfa_ops;
87748e2b
MW
2717 // pc is in the dw address space of the current module, which is what
2718 // c_translate_location expects. get_cfa_ops wants the global dwfl address.
3965e105 2719 // cfa_ops only make sense for locals.
bd1fcbad 2720 if (pc)
3965e105
MW
2721 {
2722 Dwarf_Addr addr = pc + module_bias;
2723 cfa_ops = get_cfa_ops (addr);
2724 }
2725 else
2726 cfa_ops = NULL;
2727
440f755a
JS
2728 return c_translate_location (pool, &loc2c_error, this,
2729 &loc2c_emit_address,
2730 1, 0 /* PR9768 */,
24c7957b 2731 pc, attr, expr, len, tail, fb_attr, cfa_ops);
440f755a
JS
2732}
2733
2734
2735void
f5f03f5d 2736dwflpp::get_members(Dwarf_Die *typedie, set<string>& members, set<string> &dupes)
440f755a 2737{
28a494df 2738 const int typetag = dwarf_tag (typedie);
440f755a 2739
dee830d9
MW
2740 /* compile and partial unit included for recursion through
2741 imported_unit below. */
9c119951
JS
2742 if (typetag != DW_TAG_structure_type &&
2743 typetag != DW_TAG_class_type &&
dee830d9
MW
2744 typetag != DW_TAG_union_type &&
2745 typetag != DW_TAG_compile_unit &&
2746 typetag != DW_TAG_partial_unit)
440f755a 2747 {
f5f03f5d
JL
2748 throw SEMANTIC_ERROR(_F("Type %s isn't a struct/class/union",
2749 dwarf_type_name(typedie).c_str()));
440f755a
JS
2750 }
2751
2752 // Try to get the first child of vardie.
dee830d9 2753 Dwarf_Die die_mem, import;
440f755a 2754 Dwarf_Die *die = &die_mem;
28a494df 2755 switch (dwarf_child (typedie, die))
440f755a
JS
2756 {
2757 case 1: // No children.
f5f03f5d 2758 throw SEMANTIC_ERROR(_F("Type %s is empty", dwarf_type_name(typedie).c_str()));
440f755a
JS
2759
2760 case -1: // Error.
2761 default: // Shouldn't happen.
f5f03f5d
JL
2762 throw SEMANTIC_ERROR(_F("Type %s: %s", dwarf_type_name(typedie).c_str(),
2763 dwarf_errmsg(-1)));
440f755a
JS
2764
2765 case 0: // Success.
2766 break;
2767 }
2768
f5f03f5d 2769 // Add each sibling's name to members set
9c119951 2770 do
440f755a 2771 {
9c119951 2772 int tag = dwarf_tag(die);
dee830d9
MW
2773
2774 /* The children of an imported_unit should be treated as members too. */
2775 if (tag == DW_TAG_imported_unit
2776 && dwarf_attr_die(die, DW_AT_import, &import))
f5f03f5d 2777 get_members(&import, members, dupes);
dee830d9 2778
9c119951
JS
2779 if (tag != DW_TAG_member && tag != DW_TAG_inheritance)
2780 continue;
2781
23d106b9 2782 const char *member = dwarf_diename (die) ;
440f755a 2783
9c119951 2784 if ( tag == DW_TAG_member && member != NULL )
1de6dd7a
JS
2785 {
2786 // Only output if this is new, to avoid inheritance dupes.
2787 if (dupes.insert(member).second)
f5f03f5d 2788 members.insert(member);
1de6dd7a 2789 }
440f755a
JS
2790 else
2791 {
f1c8f8a5 2792 Dwarf_Die temp_die;
3d1ad340 2793 if (!dwarf_attr_die (die, DW_AT_type, &temp_die))
440f755a 2794 {
f1c8f8a5
JS
2795 string source = dwarf_decl_file(die) ?: "<unknown source>";
2796 int line = -1;
2797 dwarf_decl_line(die, &line);
f5f03f5d
JL
2798 throw SEMANTIC_ERROR(_F("Couldn't obtain type attribute for anonymous "
2799 "member at %s:%d", source.c_str(), line));
440f755a
JS
2800 }
2801
f5f03f5d 2802 get_members(&temp_die, members, dupes);
440f755a
JS
2803 }
2804
440f755a 2805 }
9c119951 2806 while (dwarf_siblingof (die, die) == 0);
440f755a
JS
2807}
2808
2809
2810bool
c67847a0 2811dwflpp::find_struct_member(const target_symbol::component& c,
440f755a 2812 Dwarf_Die *parentdie,
440f755a 2813 Dwarf_Die *memberdie,
00730da1 2814 vector<Dwarf_Die>& dies,
440f755a
JS
2815 vector<Dwarf_Attribute>& locs)
2816{
2817 Dwarf_Attribute attr;
b57ba9b8 2818 Dwarf_Die die;
440f755a 2819
e5a573c0
JS
2820 /* With inheritance, a subclass may mask member names of parent classes, so
2821 * our search among the inheritance tree must be breadth-first rather than
2822 * depth-first (recursive). The parentdie is still our starting point. */
2823 deque<Dwarf_Die> inheritees(1, *parentdie);
2824 for (; !inheritees.empty(); inheritees.pop_front())
440f755a 2825 {
e5a573c0 2826 switch (dwarf_child (&inheritees.front(), &die))
440f755a 2827 {
e5a573c0
JS
2828 case 0: /* First child found. */
2829 break;
2830 case 1: /* No children. */
2831 continue;
2832 case -1: /* Error. */
2833 default: /* Shouldn't happen */
dc09353a 2834 throw SEMANTIC_ERROR (dwarf_type_name(&inheritees.front()) + ": "
e5a573c0
JS
2835 + string (dwarf_errmsg (-1)),
2836 c.tok);
440f755a 2837 }
e5a573c0
JS
2838
2839 do
440f755a 2840 {
e5a573c0 2841 int tag = dwarf_tag(&die);
dee830d9
MW
2842 /* recurse into imported units as if they are anonymoust structs */
2843 Dwarf_Die import;
2844 if (tag == DW_TAG_imported_unit
2845 && dwarf_attr_die(&die, DW_AT_import, &import)
2846 && find_struct_member(c, &import, memberdie, dies, locs))
2847 goto success;
2848
e5a573c0
JS
2849 if (tag != DW_TAG_member && tag != DW_TAG_inheritance)
2850 continue;
2851
2852 const char *name = dwarf_diename(&die);
2853 if (tag == DW_TAG_inheritance)
2854 {
2855 /* Remember inheritee for breadth-first search. */
2856 Dwarf_Die inheritee;
2857 if (dwarf_attr_die (&die, DW_AT_type, &inheritee))
2858 inheritees.push_back(inheritee);
2859 }
2860 else if (name == NULL)
2861 {
2862 /* Need to recurse for anonymous structs/unions. */
2863 Dwarf_Die subdie;
2864 if (dwarf_attr_die (&die, DW_AT_type, &subdie) &&
2865 find_struct_member(c, &subdie, memberdie, dies, locs))
2866 goto success;
2867 }
2868 else if (name == c.member)
2869 {
2870 *memberdie = die;
2871 goto success;
2872 }
440f755a 2873 }
e5a573c0 2874 while (dwarf_siblingof (&die, &die) == 0);
440f755a 2875 }
440f755a
JS
2876
2877 return false;
2878
2879success:
2880 /* As we unwind the recursion, we need to build the chain of
2881 * locations that got to the final answer. */
2882 if (dwarf_attr_integrate (&die, DW_AT_data_member_location, &attr))
00730da1
MW
2883 {
2884 dies.insert(dies.begin(), die);
2885 locs.insert(locs.begin(), attr);
2886 }
440f755a
JS
2887
2888 /* Union members don't usually have a location,
2889 * but just use the containing union's location. */
2890 else if (dwarf_tag(parentdie) != DW_TAG_union_type)
dc09353a 2891 throw SEMANTIC_ERROR (_F("no location for field '%s':%s",
f9bbd346 2892 c.member.c_str(), dwarf_errmsg(-1)), c.tok);
440f755a
JS
2893
2894 return true;
2895}
2896
2897
6ce303b8
JS
2898static inline void
2899dwarf_die_type (Dwarf_Die *die, Dwarf_Die *typedie_mem, const token *tok=NULL)
2900{
2901 if (!dwarf_attr_die (die, DW_AT_type, typedie_mem))
dc09353a 2902 throw SEMANTIC_ERROR (_F("cannot get type of field: %s", dwarf_errmsg(-1)), tok);
6ce303b8
JS
2903}
2904
2905
2906void
440f755a
JS
2907dwflpp::translate_components(struct obstack *pool,
2908 struct location **tail,
2909 Dwarf_Addr pc,
2910 const target_symbol *e,
2911 Dwarf_Die *vardie,
f3b5366d
JS
2912 Dwarf_Die *typedie,
2913 unsigned first)
440f755a 2914{
f3b5366d 2915 unsigned i = first;
440f755a
JS
2916 while (i < e->components.size())
2917 {
c67847a0
JS
2918 const target_symbol::component& c = e->components[i];
2919
440f755a
JS
2920 /* XXX: This would be desirable, but we don't get the target_symbol token,
2921 and printing that gives us the file:line number too early anyway. */
2922#if 0
2923 // Emit a marker to note which field is being access-attempted, to give
2924 // better error messages if deref() fails.
aca66a36 2925 string piece = string(...target_symbol token...) + string ("#") + lex_cast(components[i].second);
440f755a
JS
2926 obstack_printf (pool, "c->last_stmt = %s;", lex_cast_qstring(piece).c_str());
2927#endif
2928
6ce303b8 2929 switch (dwarf_tag (typedie))
440f755a
JS
2930 {
2931 case DW_TAG_typedef:
2932 case DW_TAG_const_type:
2933 case DW_TAG_volatile_type:
2934 /* Just iterate on the referent type. */
6ce303b8 2935 dwarf_die_type (typedie, typedie, c.tok);
440f755a
JS
2936 break;
2937
9c119951
JS
2938 case DW_TAG_reference_type:
2939 case DW_TAG_rvalue_reference_type:
5f36109e
JS
2940 if (pool)
2941 c_translate_pointer (pool, 1, 0 /* PR9768*/, typedie, tail);
6ce303b8 2942 dwarf_die_type (typedie, typedie, c.tok);
9c119951
JS
2943 break;
2944
440f755a 2945 case DW_TAG_pointer_type:
c4dddae6 2946 /* A pointer with no type is a void* -- can't dereference it. */
6ce303b8 2947 if (!dwarf_hasattr_integrate (typedie, DW_AT_type))
dc09353a 2948 throw SEMANTIC_ERROR (_F("invalid access '%s' vs '%s'", lex_cast(c).c_str(),
f9bbd346 2949 dwarf_type_name(typedie).c_str()), c.tok);
c4dddae6 2950
5f36109e
JS
2951 if (pool)
2952 c_translate_pointer (pool, 1, 0 /* PR9768*/, typedie, tail);
6fda2dff
JS
2953 if (c.type != target_symbol::comp_literal_array_index &&
2954 c.type != target_symbol::comp_expression_array_index)
6ce303b8
JS
2955 {
2956 dwarf_die_type (typedie, typedie, c.tok);
2957 break;
2958 }
d52761f8 2959 /* else fall through as an array access */
440f755a
JS
2960
2961 case DW_TAG_array_type:
c67847a0 2962 if (c.type == target_symbol::comp_literal_array_index)
5f36109e
JS
2963 {
2964 if (pool)
2965 c_translate_array (pool, 1, 0 /* PR9768 */, typedie, tail,
2966 NULL, c.num_index);
2967 }
6fda2dff
JS
2968 else if (c.type == target_symbol::comp_expression_array_index)
2969 {
0386bbcf 2970 string index = "STAP_ARG_index" + lex_cast(i);
5f36109e
JS
2971 if (pool)
2972 c_translate_array (pool, 1, 0 /* PR9768 */, typedie, tail,
2973 index.c_str(), 0);
6fda2dff 2974 }
440f755a 2975 else
dc09353a 2976 throw SEMANTIC_ERROR (_F("invalid access '%s' for array type",
f9bbd346 2977 lex_cast(c).c_str()), c.tok);
6ce303b8
JS
2978
2979 dwarf_die_type (typedie, typedie, c.tok);
2980 *vardie = *typedie;
2981 ++i;
440f755a
JS
2982 break;
2983
2984 case DW_TAG_structure_type:
2985 case DW_TAG_union_type:
9c119951 2986 case DW_TAG_class_type:
c67847a0 2987 if (c.type != target_symbol::comp_struct_member)
dc09353a 2988 throw SEMANTIC_ERROR (_F("invalid access '%s' for %s",
f9bbd346 2989 lex_cast(c).c_str(), dwarf_type_name(typedie).c_str()));
c67847a0 2990
6ce303b8 2991 if (dwarf_hasattr(typedie, DW_AT_declaration))
440f755a 2992 {
a44a7cb5 2993 Dwarf_Die *tmpdie = declaration_resolve(typedie);
440f755a 2994 if (tmpdie == NULL)
dc09353a 2995 throw SEMANTIC_ERROR (_F("unresolved %s", dwarf_type_name(typedie).c_str()), c.tok);
6ce303b8 2996 *typedie = *tmpdie;
440f755a
JS
2997 }
2998
2999 {
00730da1 3000 vector<Dwarf_Die> dies;
440f755a 3001 vector<Dwarf_Attribute> locs;
00730da1 3002 if (!find_struct_member(c, typedie, vardie, dies, locs))
440f755a 3003 {
72c5ecc2
JS
3004 /* Add a file:line hint for anonymous types */
3005 string source;
6ce303b8 3006 if (!dwarf_hasattr_integrate(typedie, DW_AT_name))
72c5ecc2
JS
3007 {
3008 int line;
6ce303b8
JS
3009 const char *file = dwarf_decl_file(typedie);
3010 if (file && dwarf_decl_line(typedie, &line) == 0)
72c5ecc2 3011 source = " (" + string(file) + ":"
aca66a36 3012 + lex_cast(line) + ")";
72c5ecc2
JS
3013 }
3014
f5f03f5d
JL
3015 set<string> members, member_dupes;
3016 get_members(typedie, members, member_dupes);
3017 string sugs = levenshtein_suggest(c.member, members);
3018 if (!sugs.empty())
3019 sugs = " (alternatives: " + sugs + ")";
dc09353a 3020 throw SEMANTIC_ERROR(_F("unable to find member '%s' for %s%s%s", c.member.c_str(),
f9bbd346 3021 dwarf_type_name(typedie).c_str(), source.c_str(),
f5f03f5d 3022 sugs.c_str()), c.tok);
440f755a
JS
3023 }
3024
3025 for (unsigned j = 0; j < locs.size(); ++j)
5f36109e 3026 if (pool)
00730da1
MW
3027 translate_location (pool, &locs[j], &dies[j],
3028 pc, NULL, tail, e);
440f755a
JS
3029 }
3030
6ce303b8 3031 dwarf_die_type (vardie, typedie, c.tok);
440f755a
JS
3032 ++i;
3033 break;
3034
3035 case DW_TAG_enumeration_type:
440f755a 3036 case DW_TAG_base_type:
dc09353a 3037 throw SEMANTIC_ERROR (_F("invalid access '%s' vs. %s", lex_cast(c).c_str(),
f9bbd346 3038 dwarf_type_name(typedie).c_str()), c.tok);
440f755a 3039 break;
f1c8f8a5 3040
440f755a 3041 case -1:
dc09353a 3042 throw SEMANTIC_ERROR (_F("cannot find type: %s", dwarf_errmsg(-1)), c.tok);
440f755a
JS
3043 break;
3044
3045 default:
dc09353a 3046 throw SEMANTIC_ERROR (_F("%s: unexpected type tag %s", dwarf_type_name(typedie).c_str(),
f9bbd346 3047 lex_cast(dwarf_tag(typedie)).c_str()), c.tok);
440f755a
JS
3048 break;
3049 }
440f755a 3050 }
440f755a
JS
3051}
3052
3053
6ce303b8
JS
3054void
3055dwflpp::resolve_unqualified_inner_typedie (Dwarf_Die *typedie,
3056 Dwarf_Die *innerdie,
440f755a
JS
3057 const target_symbol *e)
3058{
6ce303b8
JS
3059 int typetag = dwarf_tag (typedie);
3060 *innerdie = *typedie;
3061 while (typetag == DW_TAG_typedef ||
3062 typetag == DW_TAG_const_type ||
3063 typetag == DW_TAG_volatile_type)
440f755a 3064 {
6ce303b8 3065 if (!dwarf_attr_die (innerdie, DW_AT_type, innerdie))
dc09353a 3066 throw SEMANTIC_ERROR (_F("cannot get type of pointee: %s", dwarf_errmsg(-1)), e->tok);
6ce303b8 3067 typetag = dwarf_tag (innerdie);
440f755a 3068 }
440f755a
JS
3069}
3070
3071
3072void
3073dwflpp::translate_final_fetch_or_store (struct obstack *pool,
3074 struct location **tail,
822a6a3d 3075 Dwarf_Addr /*module_bias*/,
6ce303b8
JS
3076 Dwarf_Die *vardie,
3077 Dwarf_Die *start_typedie,
440f755a
JS
3078 bool lvalue,
3079 const target_symbol *e,
3080 string &,
3081 string &,
3082 exp_type & ty)
3083{
3084 /* First boil away any qualifiers associated with the type DIE of
3085 the final location to be accessed. */
3086
6ce303b8
JS
3087 Dwarf_Die typedie_mem, *typedie = &typedie_mem;
3088 resolve_unqualified_inner_typedie (start_typedie, typedie, e);
440f755a 3089
03c75a4a
JS
3090 /* If we're looking for an address, then we can just provide what
3091 we computed to this point, without using a fetch/store. */
3092 if (e->addressof)
3093 {
3094 if (lvalue)
dc09353a 3095 throw SEMANTIC_ERROR (_("cannot write to member address"), e->tok);
03c75a4a 3096
6ce303b8 3097 if (dwarf_hasattr_integrate (vardie, DW_AT_bit_offset))
dc09353a 3098 throw SEMANTIC_ERROR (_("cannot take address of bit-field"), e->tok);
03c75a4a 3099
0386bbcf 3100 c_translate_addressof (pool, 1, 0, vardie, typedie, tail, "STAP_RETVALUE");
03c75a4a
JS
3101 ty = pe_long;
3102 return;
3103 }
3104
440f755a
JS
3105 /* Then switch behavior depending on the type of fetch/store we
3106 want, and the type and pointer-ness of the final location. */
3107
6ce303b8 3108 int typetag = dwarf_tag (typedie);
440f755a
JS
3109 switch (typetag)
3110 {
3111 default:
dc09353a 3112 throw SEMANTIC_ERROR (_F("unsupported type tag %s for %s", lex_cast(typetag).c_str(),
f9bbd346 3113 dwarf_type_name(typedie).c_str()), e->tok);
440f755a
JS
3114 break;
3115
3116 case DW_TAG_structure_type:
9c119951 3117 case DW_TAG_class_type:
440f755a 3118 case DW_TAG_union_type:
dc09353a 3119 throw SEMANTIC_ERROR (_F("'%s' is being accessed instead of a member",
f9bbd346 3120 dwarf_type_name(typedie).c_str()), e->tok);
440f755a
JS
3121 break;
3122
440f755a
JS
3123 case DW_TAG_base_type:
3124
3125 // Reject types we can't handle in systemtap
3126 {
440f755a
JS
3127 Dwarf_Attribute encoding_attr;
3128 Dwarf_Word encoding = (Dwarf_Word) -1;
3129 dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, &encoding_attr),
3130 & encoding);
822a6a3d 3131 if (encoding == (Dwarf_Word) -1)
440f755a
JS
3132 {
3133 // clog << "bad type1 " << encoding << " diestr" << endl;
dc09353a 3134 throw SEMANTIC_ERROR (_F("unsupported type (mystery encoding %s for %s", lex_cast(encoding).c_str(),
f9bbd346 3135 dwarf_type_name(typedie).c_str()), e->tok);
440f755a
JS
3136 }
3137
3138 if (encoding == DW_ATE_float
3139 || encoding == DW_ATE_complex_float
3140 /* XXX || many others? */)
3141 {
3142 // clog << "bad type " << encoding << " diestr" << endl;
dc09353a 3143 throw SEMANTIC_ERROR (_F("unsupported type (encoding %s) for %s", lex_cast(encoding).c_str(),
f9bbd346 3144 dwarf_type_name(typedie).c_str()), e->tok);
440f755a
JS
3145 }
3146 }
5c7ef8e7
MW
3147 // Fallthrough. enumeration_types are always scalar.
3148 case DW_TAG_enumeration_type:
440f755a
JS
3149
3150 ty = pe_long;
3151 if (lvalue)
6ce303b8 3152 c_translate_store (pool, 1, 0 /* PR9768 */, vardie, typedie, tail,
0386bbcf 3153 "STAP_ARG_value");
440f755a 3154 else
6ce303b8 3155 c_translate_fetch (pool, 1, 0 /* PR9768 */, vardie, typedie, tail,
0386bbcf 3156 "STAP_RETVALUE");
440f755a
JS
3157 break;
3158
3159 case DW_TAG_array_type:
3160 case DW_TAG_pointer_type:
9c119951
JS
3161 case DW_TAG_reference_type:
3162 case DW_TAG_rvalue_reference_type:
440f755a 3163
440f755a
JS
3164 if (lvalue)
3165 {
3166 ty = pe_long;
3167 if (typetag == DW_TAG_array_type)
dc09353a 3168 throw SEMANTIC_ERROR (_("cannot write to array address"), e->tok);
9c119951
JS
3169 if (typetag == DW_TAG_reference_type ||
3170 typetag == DW_TAG_rvalue_reference_type)
dc09353a 3171 throw SEMANTIC_ERROR (_("cannot write to reference"), e->tok);
440f755a
JS
3172 assert (typetag == DW_TAG_pointer_type);
3173 c_translate_pointer_store (pool, 1, 0 /* PR9768 */, typedie, tail,
0386bbcf 3174 "STAP_ARG_value");
440f755a
JS
3175 }
3176 else
3177 {
3178 // We have the pointer: cast it to an integral type via &(*(...))
3179
3180 // NB: per bug #1187, at one point char*-like types were
3181 // automagically converted here to systemtap string values.
3182 // For several reasons, this was taken back out, leaving
3183 // pointer-to-string "conversion" (copying) to tapset functions.
3184
3185 ty = pe_long;
3186 if (typetag == DW_TAG_array_type)
3187 c_translate_array (pool, 1, 0 /* PR9768 */, typedie, tail, NULL, 0);
3188 else
3189 c_translate_pointer (pool, 1, 0 /* PR9768 */, typedie, tail);
6ce303b8 3190 c_translate_addressof (pool, 1, 0 /* PR9768 */, NULL, NULL, tail,
0386bbcf 3191 "STAP_RETVALUE");
440f755a 3192 }
440f755a
JS
3193 break;
3194 }
3195}
3196
3197
3198string
3199dwflpp::express_as_string (string prelude,
3200 string postlude,
3201 struct location *head)
3202{
e7899657
FCE
3203 size_t bufsz = 0;
3204 char *buf = 0; // NB: it would leak to pre-allocate a buffer here
440f755a
JS
3205 FILE *memstream = open_memstream (&buf, &bufsz);
3206 assert(memstream);
3207
3208 fprintf(memstream, "{\n");
3209 fprintf(memstream, "%s", prelude.c_str());
ebaa9618 3210
85dfc5c8
RM
3211 unsigned int stack_depth;
3212 bool deref = c_emit_location (memstream, head, 1, &stack_depth);
ebaa9618
JS
3213
3214 // Ensure that DWARF keeps loc2c to a "reasonable" stack size
3215 // 32 intptr_t leads to max 256 bytes on the stack
3216 if (stack_depth > 32)
dc09353a 3217 throw SEMANTIC_ERROR("oversized DWARF stack");
ebaa9618 3218
440f755a
JS
3219 fprintf(memstream, "%s", postlude.c_str());
3220 fprintf(memstream, " goto out;\n");
3221
3222 // dummy use of deref_fault label, to disable warning if deref() not used
3223 fprintf(memstream, "if (0) goto deref_fault;\n");
3224
3225 // XXX: deref flag not reliable; emit fault label unconditionally
3226 (void) deref;
3227 fprintf(memstream,
3228 "deref_fault:\n"
3229 " goto out;\n");
3230 fprintf(memstream, "}\n");
3231
3232 fclose (memstream);
3233 string result(buf);
3234 free (buf);
3235 return result;
3236}
3237
228af5c4
MW
3238Dwarf_Addr
3239dwflpp::vardie_from_symtable (Dwarf_Die *vardie, Dwarf_Addr *addr)
3240{
f450a7e3 3241 const char *name = dwarf_linkage_name (vardie) ?: dwarf_diename (vardie);
b0490786 3242
228af5c4 3243 if (sess.verbose > 2)
f9bbd346 3244 clog << _F("finding symtable address for %s\n", name);
228af5c4
MW
3245
3246 *addr = 0;
3247 int syms = dwfl_module_getsymtab (module);
f9bbd346 3248 dwfl_assert (_("Getting symbols"), syms >= 0);
228af5c4
MW
3249
3250 for (int i = 0; *addr == 0 && i < syms; i++)
3251 {
3252 GElf_Sym sym;
3253 GElf_Word shndxp;
3254 const char *symname = dwfl_module_getsym(module, i, &sym, &shndxp);
3255 if (symname
3256 && ! strcmp (name, symname)
3257 && sym.st_shndx != SHN_UNDEF
d124d4de
MW
3258 && (GELF_ST_TYPE (sym.st_info) == STT_NOTYPE // PR13284
3259 || GELF_ST_TYPE (sym.st_info) == STT_OBJECT))
228af5c4
MW
3260 *addr = sym.st_value;
3261 }
3262
2d7232ca
MW
3263 // Don't relocate for the kernel, or kernel modules we handle those
3264 // specially in emit_address.
3265 if (dwfl_module_relocations (module) == 1 && module_name != TOK_KERNEL)
3266 dwfl_module_relocate_address (module, addr);
3267
228af5c4 3268 if (sess.verbose > 2)
2a97f50b 3269 clog << _F("found %s @%#" PRIx64 "\n", name, *addr);
228af5c4
MW
3270
3271 return *addr;
3272}
440f755a
JS
3273
3274string
729455a7 3275dwflpp::literal_stmt_for_local (vector<Dwarf_Die>& scopes,
440f755a
JS
3276 Dwarf_Addr pc,
3277 string const & local,
3278 const target_symbol *e,
3279 bool lvalue,
3280 exp_type & ty)
3281{
3282 Dwarf_Die vardie;
3283 Dwarf_Attribute fb_attr_mem, *fb_attr = NULL;
3284
729455a7 3285 fb_attr = find_variable_and_frame_base (scopes, pc, local, e,
440f755a
JS
3286 &vardie, &fb_attr_mem);
3287
3288 if (sess.verbose>2)
3d9381fc 3289 {
bd1fcbad 3290 if (pc)
3d9381fc
MW
3291 clog << _F("finding location for local '%s' near address %#" PRIx64
3292 ", module bias %#" PRIx64 "\n", local.c_str(), pc,
3293 module_bias);
3294 else
3295 clog << _F("finding location for global '%s' in CU '%s'\n",
bd1fcbad 3296 local.c_str(), cu_name().c_str());
3d9381fc
MW
3297 }
3298
440f755a 3299
228af5c4
MW
3300#define obstack_chunk_alloc malloc
3301#define obstack_chunk_free free
3302
3303 struct obstack pool;
3304 obstack_init (&pool);
3305 struct location *tail = NULL;
3306
3307 /* Given $foo->bar->baz[NN], translate the location of foo. */
3308
3309 struct location *head;
3310
440f755a 3311 Dwarf_Attribute attr_mem;
03ba05b6
MW
3312 if (dwarf_attr_integrate (&vardie, DW_AT_const_value, &attr_mem) == NULL
3313 && dwarf_attr_integrate (&vardie, DW_AT_location, &attr_mem) == NULL)
440f755a 3314 {
228af5c4 3315 Dwarf_Op addr_loc;
e9483a80 3316 memset(&addr_loc, 0, sizeof(Dwarf_Op));
228af5c4
MW
3317 addr_loc.atom = DW_OP_addr;
3318 // If it is an external variable try the symbol table. PR10622.
3319 if (dwarf_attr_integrate (&vardie, DW_AT_external, &attr_mem) != NULL
3320 && vardie_from_symtable (&vardie, &addr_loc.number) != 0)
3321 {
3322 head = c_translate_location (&pool, &loc2c_error, this,
3323 &loc2c_emit_address,
3324 1, 0, pc,
3325 NULL, &addr_loc, 1, &tail, NULL, NULL);
3326 }
3327 else
dc09353a 3328 throw SEMANTIC_ERROR (_F("failed to retrieve location attribute for '%s' [man error::dwarf] (dieoffset: %s)",
f9bbd346 3329 local.c_str(), lex_cast_hex(dwarf_dieoffset(&vardie)).c_str()), e->tok);
440f755a 3330 }
228af5c4 3331 else
00730da1 3332 head = translate_location (&pool, &attr_mem, &vardie, pc, fb_attr, &tail, e);
440f755a 3333
6ce303b8
JS
3334 /* Translate the ->bar->baz[NN] parts. */
3335
3336 Dwarf_Die typedie;
3337 if (dwarf_attr_die (&vardie, DW_AT_type, &typedie) == NULL)
dc09353a 3338 throw SEMANTIC_ERROR(_F("failed to retrieve type attribute for '%s' [man error::dwarf] (dieoffset: %s)", local.c_str(), lex_cast_hex(dwarf_dieoffset(&vardie)).c_str()), e->tok);
440f755a 3339
6ce303b8 3340 translate_components (&pool, &tail, pc, e, &vardie, &typedie);
440f755a
JS
3341
3342 /* Translate the assignment part, either
3343 x = $foo->bar->baz[NN]
3344 or
3345 $foo->bar->baz[NN] = x
3346 */
3347
3348 string prelude, postlude;
3349 translate_final_fetch_or_store (&pool, &tail, module_bias,
6ce303b8 3350 &vardie, &typedie, lvalue, e,
440f755a
JS
3351 prelude, postlude, ty);
3352
3353 /* Write the translation to a string. */
e7899657
FCE
3354 string result = express_as_string(prelude, postlude, head);
3355 obstack_free (&pool, 0);
3356 return result;
440f755a
JS
3357}
3358
5f36109e
JS
3359Dwarf_Die*
3360dwflpp::type_die_for_local (vector<Dwarf_Die>& scopes,
3361 Dwarf_Addr pc,
3362 string const & local,
3363 const target_symbol *e,
3364 Dwarf_Die *typedie)
3365{
3366 Dwarf_Die vardie;
3367 Dwarf_Attribute attr_mem;
3368
3369 find_variable_and_frame_base (scopes, pc, local, e, &vardie, &attr_mem);
3370
3371 if (dwarf_attr_die (&vardie, DW_AT_type, typedie) == NULL)
dc09353a 3372 throw SEMANTIC_ERROR(_F("failed to retrieve type attribute for '%s' [man error::dwarf]", local.c_str()), e->tok);
5f36109e
JS
3373
3374 translate_components (NULL, NULL, pc, e, &vardie, typedie);
3375 return typedie;
3376}
3377
440f755a
JS
3378
3379string
3380dwflpp::literal_stmt_for_return (Dwarf_Die *scope_die,
3381 Dwarf_Addr pc,
3382 const target_symbol *e,
3383 bool lvalue,
3384 exp_type & ty)
3385{
3386 if (sess.verbose>2)
f9bbd346
LB
3387 clog << _F("literal_stmt_for_return: finding return value for %s (%s)\n",
3388 (dwarf_diename(scope_die) ?: "<unknown>"), (dwarf_diename(cu) ?: "<unknown>"));
440f755a
JS
3389
3390 struct obstack pool;
3391 obstack_init (&pool);
3392 struct location *tail = NULL;
3393
3394 /* Given $return->bar->baz[NN], translate the location of return. */
3395 const Dwarf_Op *locops;
3396 int nlocops = dwfl_module_return_value_location (module, scope_die,
3397 &locops);
3398 if (nlocops < 0)
3399 {
dc09353a 3400 throw SEMANTIC_ERROR(_F("failed to retrieve return value location for %s [man error::dwarf] (%s)",
f9bbd346
LB
3401 (dwarf_diename(scope_die) ?: "<unknown>"),
3402 (dwarf_diename(cu) ?: "<unknown>")), e->tok);
440f755a
JS
3403 }
3404 // the function has no return value (e.g. "void" in C)
3405 else if (nlocops == 0)
3406 {
dc09353a 3407 throw SEMANTIC_ERROR(_F("function %s (%s) has no return value",
f9bbd346
LB
3408 (dwarf_diename(scope_die) ?: "<unknown>"),
3409 (dwarf_diename(cu) ?: "<unknown>")), e->tok);
440f755a
JS
3410 }
3411
3412 struct location *head = c_translate_location (&pool, &loc2c_error, this,
3413 &loc2c_emit_address,
3414 1, 0 /* PR9768 */,
24c7957b 3415 pc, NULL, locops, nlocops,
00b01a99 3416 &tail, NULL, NULL);
440f755a
JS
3417
3418 /* Translate the ->bar->baz[NN] parts. */
3419
6ce303b8
JS
3420 Dwarf_Die vardie = *scope_die, typedie;
3421 if (dwarf_attr_die (&vardie, DW_AT_type, &typedie) == NULL)
dc09353a 3422 throw SEMANTIC_ERROR(_F("failed to retrieve return value type attribute for %s [man error::dwarf] (%s)",
f9bbd346
LB
3423 (dwarf_diename(&vardie) ?: "<unknown>"),
3424 (dwarf_diename(cu) ?: "<unknown>")), e->tok);
440f755a 3425
6ce303b8 3426 translate_components (&pool, &tail, pc, e, &vardie, &typedie);
440f755a
JS
3427
3428 /* Translate the assignment part, either
3429 x = $return->bar->baz[NN]
3430 or
3431 $return->bar->baz[NN] = x
3432 */
3433
3434 string prelude, postlude;
3435 translate_final_fetch_or_store (&pool, &tail, module_bias,
6ce303b8 3436 &vardie, &typedie, lvalue, e,
440f755a
JS
3437 prelude, postlude, ty);
3438
3439 /* Write the translation to a string. */
e7899657
FCE
3440 string result = express_as_string(prelude, postlude, head);
3441 obstack_free (&pool, 0);
3442 return result;
440f755a
JS
3443}
3444
5f36109e
JS
3445Dwarf_Die*
3446dwflpp::type_die_for_return (Dwarf_Die *scope_die,
3447 Dwarf_Addr pc,
3448 const target_symbol *e,
3449 Dwarf_Die *typedie)
3450{
3451 Dwarf_Die vardie = *scope_die;
3452 if (dwarf_attr_die (&vardie, DW_AT_type, typedie) == NULL)
dc09353a 3453 throw SEMANTIC_ERROR(_F("failed to retrieve return value type attribute for %s [man error::dwarf] (%s)",
f9bbd346
LB
3454 (dwarf_diename(&vardie) ?: "<unknown>"),
3455 (dwarf_diename(cu) ?: "<unknown>")), e->tok);
5f36109e
JS
3456
3457 translate_components (NULL, NULL, pc, e, &vardie, typedie);
3458 return typedie;
3459}
3460
440f755a
JS
3461
3462string
6ce303b8 3463dwflpp::literal_stmt_for_pointer (Dwarf_Die *start_typedie,
440f755a
JS
3464 const target_symbol *e,
3465 bool lvalue,
3466 exp_type & ty)
3467{
3468 if (sess.verbose>2)
f9bbd346
LB
3469 clog << _F("literal_stmt_for_pointer: finding value for %s (%s)\n",
3470 dwarf_type_name(start_typedie).c_str(), (dwarf_diename(cu) ?: "<unknown>"));
440f755a
JS
3471
3472 struct obstack pool;
3473 obstack_init (&pool);
3474 struct location *head = c_translate_argument (&pool, &loc2c_error, this,
3475 &loc2c_emit_address,
0386bbcf 3476 1, "STAP_ARG_pointer");
440f755a
JS
3477 struct location *tail = head;
3478
3479 /* Translate the ->bar->baz[NN] parts. */
3480
f3b5366d 3481 unsigned first = 0;
6ce303b8 3482 Dwarf_Die typedie = *start_typedie, vardie = typedie;
f3b5366d 3483
0386bbcf
SM
3484 /* As a special case when typedie is not an array or pointer, we can
3485 * allow array indexing on STAP_ARG_pointer instead (since we do
3486 * know the pointee type and can determine its size). PR11556. */
f3b5366d
JS
3487 const target_symbol::component* c =
3488 e->components.empty() ? NULL : &e->components[0];
3489 if (c && (c->type == target_symbol::comp_literal_array_index ||
3490 c->type == target_symbol::comp_expression_array_index))
3491 {
3492 resolve_unqualified_inner_typedie (&typedie, &typedie, e);
3493 int typetag = dwarf_tag (&typedie);
3494 if (typetag != DW_TAG_pointer_type &&
3495 typetag != DW_TAG_array_type)
3496 {
3497 if (c->type == target_symbol::comp_literal_array_index)
3498 c_translate_array_pointer (&pool, 1, &typedie, &tail, NULL, c->num_index);
3499 else
0386bbcf 3500 c_translate_array_pointer (&pool, 1, &typedie, &tail, "STAP_ARG_index0", 0);
f3b5366d
JS
3501 ++first;
3502 }
3503 }
3504
3505 /* Now translate the rest normally. */
3506
3507 translate_components (&pool, &tail, 0, e, &vardie, &typedie, first);
440f755a
JS
3508
3509 /* Translate the assignment part, either
0386bbcf 3510 x = (STAP_ARG_pointer)->bar->baz[NN]
440f755a 3511 or
0386bbcf 3512 (STAP_ARG_pointer)->bar->baz[NN] = x
440f755a
JS
3513 */
3514
3515 string prelude, postlude;
3516 translate_final_fetch_or_store (&pool, &tail, module_bias,
6ce303b8 3517 &vardie, &typedie, lvalue, e,
440f755a
JS
3518 prelude, postlude, ty);
3519
3520 /* Write the translation to a string. */
e7899657
FCE
3521 string result = express_as_string(prelude, postlude, head);
3522 obstack_free (&pool, 0);
3523 return result;
440f755a
JS
3524}
3525
5f36109e
JS
3526Dwarf_Die*
3527dwflpp::type_die_for_pointer (Dwarf_Die *start_typedie,
3528 const target_symbol *e,
3529 Dwarf_Die *typedie)
3530{
3531 unsigned first = 0;
3532 *typedie = *start_typedie;
3533 Dwarf_Die vardie = *typedie;
3534
3535 /* Handle the same PR11556 case as above. */
3536 const target_symbol::component* c =
3537 e->components.empty() ? NULL : &e->components[0];
3538 if (c && (c->type == target_symbol::comp_literal_array_index ||
3539 c->type == target_symbol::comp_expression_array_index))
3540 {
3541 resolve_unqualified_inner_typedie (typedie, typedie, e);
3542 int typetag = dwarf_tag (typedie);
3543 if (typetag != DW_TAG_pointer_type &&
3544 typetag != DW_TAG_array_type)
3545 ++first;
3546 }
3547
3548 translate_components (NULL, NULL, 0, e, &vardie, typedie, first);
3549 return typedie;
3550}
3551
440f755a 3552
27646582
JS
3553static bool
3554in_kprobes_function(systemtap_session& sess, Dwarf_Addr addr)
3555{
3556 if (sess.sym_kprobes_text_start != 0 && sess.sym_kprobes_text_end != 0)
3557 {
3558 // If the probe point address is anywhere in the __kprobes
3559 // address range, we can't use this probe point.
3560 if (addr >= sess.sym_kprobes_text_start && addr < sess.sym_kprobes_text_end)
3561 return true;
3562 }
3563 return false;
3564}
3565
3566
3567bool
3568dwflpp::blacklisted_p(const string& funcname,
3569 const string& filename,
3570 int,
3571 const string& module,
27646582
JS
3572 Dwarf_Addr addr,
3573 bool has_return)
3574{
3575 if (!blacklist_enabled)
3576 return false; // no blacklist for userspace
3577
6ac012fc
FCE
3578 bool blacklisted = false;
3579
3580 // check against section blacklist
789448a3 3581 string section = get_blacklist_section(addr);
ac08441a
FCE
3582 // PR6503: modules don't need special init/exit treatment
3583 if (module == TOK_KERNEL && !regexec (&blacklist_section, section.c_str(), 0, NULL, 0))
27646582 3584 {
6ac012fc 3585 blacklisted = true;
27646582 3586 if (sess.verbose>1)
6ac012fc 3587 clog << _(" init/exit");
27646582
JS
3588 }
3589
3590 // Check for function marked '__kprobes'.
3591 if (module == TOK_KERNEL && in_kprobes_function(sess, addr))
3592 {
6ac012fc 3593 blacklisted = true;
27646582 3594 if (sess.verbose>1)
6ac012fc 3595 clog << _(" __kprobes");
27646582
JS
3596 }
3597
6ac012fc 3598 // Check probe point against file/function blacklists.
27646582
JS
3599 int goodfn = regexec (&blacklist_func, funcname.c_str(), 0, NULL, 0);
3600 if (has_return)
3601 goodfn = goodfn && regexec (&blacklist_func_ret, funcname.c_str(), 0, NULL, 0);
3602 int goodfile = regexec (&blacklist_file, filename.c_str(), 0, NULL, 0);
3603
3604 if (! (goodfn && goodfile))
3605 {
6ac012fc
FCE
3606 blacklisted = true;
3607 if (sess.verbose>1)
3608 clog << _(" file/function blacklist");
27646582
JS
3609 }
3610
6ac012fc
FCE
3611 if (sess.guru_mode && blacklisted)
3612 {
3613 blacklisted = false;
3614 if (sess.verbose>1)
3615 clog << _(" - not skipped (guru mode enabled)");
3616 }
3617
3618 if (blacklisted && sess.verbose>1)
3619 clog << _(" - skipped");
3620
27646582 3621 // This probe point is not blacklisted.
6ac012fc 3622 return blacklisted;
27646582
JS
3623}
3624
3625
3626void
3627dwflpp::build_blacklist()
3628{
3629 // We build up the regexps in these strings
3630
3631 // Add ^ anchors at the front; $ will be added just before regcomp.
3632
3633 string blfn = "^(";
3634 string blfn_ret = "^(";
3635 string blfile = "^(";
178ac3f6
JS
3636 string blsection = "^(";
3637
3638 blsection += "\\.init\\."; // first alternative, no "|"
3639 blsection += "|\\.exit\\.";
3640 blsection += "|\\.devinit\\.";
3641 blsection += "|\\.devexit\\.";
3642 blsection += "|\\.cpuinit\\.";
3643 blsection += "|\\.cpuexit\\.";
3644 blsection += "|\\.meminit\\.";
3645 blsection += "|\\.memexit\\.";
27646582 3646
44a7e76a
MW
3647 /* NOTE all include/asm .h blfile patterns might need "full path"
3648 so prefix those with '.*' - see PR13108 and PR13112. */
b969d16b
JS
3649 blfile += "kernel/kprobes\\.c"; // first alternative, no "|"
3650 blfile += "|arch/.*/kernel/kprobes\\.c";
44a7e76a 3651 blfile += "|.*/include/asm/io\\.h";
4a507da2 3652 blfile += "|.*/include/asm/io_64\\.h";
44a7e76a 3653 blfile += "|.*/include/asm/bitops\\.h";
b969d16b 3654 blfile += "|drivers/ide/ide-iops\\.c";
1b438943
MW
3655 // paravirt ops
3656 blfile += "|arch/.*/kernel/paravirt\\.c";
4a507da2 3657 blfile += "|.*/include/asm/paravirt\\.h";
27646582
JS
3658
3659 // XXX: it would be nice if these blacklisted functions were pulled
3660 // in dynamically, instead of being statically defined here.
3661 // Perhaps it could be populated from script files. A "noprobe
3662 // kernel.function("...")" construct might do the trick.
3663
3664 // Most of these are marked __kprobes in newer kernels. We list
3665 // them here (anyway) so the translator can block them on older
3666 // kernels that don't have the __kprobes function decorator. This
3667 // also allows detection of problems at translate- rather than
3668 // run-time.
3669
3670 blfn += "atomic_notifier_call_chain"; // first blfn; no "|"
3671 blfn += "|default_do_nmi";
3672 blfn += "|__die";
3673 blfn += "|die_nmi";
3674 blfn += "|do_debug";
3675 blfn += "|do_general_protection";
3676 blfn += "|do_int3";
3677 blfn += "|do_IRQ";
3678 blfn += "|do_page_fault";
3679 blfn += "|do_sparc64_fault";
3680 blfn += "|do_trap";
3681 blfn += "|dummy_nmi_callback";
3682 blfn += "|flush_icache_range";
3683 blfn += "|ia64_bad_break";
3684 blfn += "|ia64_do_page_fault";
3685 blfn += "|ia64_fault";
3686 blfn += "|io_check_error";
3687 blfn += "|mem_parity_error";
3688 blfn += "|nmi_watchdog_tick";
3689 blfn += "|notifier_call_chain";
3690 blfn += "|oops_begin";
3691 blfn += "|oops_end";
3692 blfn += "|program_check_exception";
3693 blfn += "|single_step_exception";
3694 blfn += "|sync_regs";
3695 blfn += "|unhandled_fault";
3696 blfn += "|unknown_nmi_error";
48aad766
FCE
3697 blfn += "|xen_[gs]et_debugreg";
3698 blfn += "|xen_irq_.*";
3699 blfn += "|xen_.*_fl_direct.*";
10d96538
TJL
3700 blfn += "|check_events";
3701 blfn += "|xen_adjust_exception_frame";
48aad766
FCE
3702 blfn += "|xen_iret.*";
3703 blfn += "|xen_sysret64.*";
3704 blfn += "|test_ti_thread_flag.*";
10d96538
TJL
3705 blfn += "|inat_get_opcode_attribute";
3706 blfn += "|system_call_after_swapgs";
5db0d1ab
TJL
3707 blfn += "|HYPERVISOR_[gs]et_debugreg";
3708 blfn += "|HYPERVISOR_event_channel_op";
3709 blfn += "|hash_64";
3710 blfn += "|hash_ptr";
3711 blfn += "|native_set_pte";
27646582
JS
3712
3713 // Lots of locks
65d79153
MW
3714 blfn += "|.*raw_.*_lock.*";
3715 blfn += "|.*raw_.*_unlock.*";
3716 blfn += "|.*raw_.*_trylock.*";
3717 blfn += "|.*read_lock.*";
3718 blfn += "|.*read_unlock.*";
3719 blfn += "|.*read_trylock.*";
3720 blfn += "|.*write_lock.*";
3721 blfn += "|.*write_unlock.*";
3722 blfn += "|.*write_trylock.*";
3723 blfn += "|.*write_seqlock.*";
3724 blfn += "|.*write_sequnlock.*";
3725 blfn += "|.*spin_lock.*";
3726 blfn += "|.*spin_unlock.*";
3727 blfn += "|.*spin_trylock.*";
3728 blfn += "|.*spin_is_locked.*";
3729 blfn += "|rwsem_.*lock.*";
27646582
JS
3730 blfn += "|.*mutex_.*lock.*";
3731 blfn += "|raw_.*";
27646582
JS
3732
3733 // atomic functions
3734 blfn += "|atomic_.*";
3735 blfn += "|atomic64_.*";
3736
3737 // few other problematic cases
3738 blfn += "|get_bh";
3739 blfn += "|put_bh";
3740
3741 // Experimental
3742 blfn += "|.*apic.*|.*APIC.*";
3743 blfn += "|.*softirq.*";
3744 blfn += "|.*IRQ.*";
3745 blfn += "|.*_intr.*";
3746 blfn += "|__delay";
3747 blfn += "|.*kernel_text.*";
3748 blfn += "|get_current";
3749 blfn += "|current_.*";
3750 blfn += "|.*exception_tables.*";
3751 blfn += "|.*setup_rt_frame.*";
3752
3753 // PR 5759, CONFIG_PREEMPT kernels
3754 blfn += "|.*preempt_count.*";
3755 blfn += "|preempt_schedule";
3756
3757 // These functions don't return, so return probes would never be recovered
3758 blfn_ret += "do_exit"; // no "|"
3759 blfn_ret += "|sys_exit";
3760 blfn_ret += "|sys_exit_group";
3761
3762 // __switch_to changes "current" on x86_64 and i686, so return probes
3763 // would cause kernel panic, and it is marked as "__kprobes" on x86_64
3764 if (sess.architecture == "x86_64")
3765 blfn += "|__switch_to";
3766 if (sess.architecture == "i686")
3767 blfn_ret += "|__switch_to";
3768
08ee70c3
FCE
3769 // RHEL6 pre-beta 2.6.32-19.el6
3770 blfn += "|special_mapping_.*";
2fd5495a
FCE
3771 blfn += "|.*_pte_.*"; // or "|smaps_pte_range";
3772 blfile += "|fs/seq_file\\.c";
08ee70c3 3773
27646582
JS
3774 blfn += ")$";
3775 blfn_ret += ")$";
3776 blfile += ")$";
178ac3f6 3777 blsection += ")"; // NB: no $, sections match just the beginning
27646582
JS
3778
3779 if (sess.verbose > 2)
3780 {
f9bbd346 3781 clog << _("blacklist regexps:") << endl;
27646582
JS
3782 clog << "blfn: " << blfn << endl;
3783 clog << "blfn_ret: " << blfn_ret << endl;
3784 clog << "blfile: " << blfile << endl;
178ac3f6 3785 clog << "blsection: " << blsection << endl;
27646582
JS
3786 }
3787
3788 int rc = regcomp (& blacklist_func, blfn.c_str(), REG_NOSUB|REG_EXTENDED);
dc09353a 3789 if (rc) throw SEMANTIC_ERROR (_("blacklist_func regcomp failed"));
27646582 3790 rc = regcomp (& blacklist_func_ret, blfn_ret.c_str(), REG_NOSUB|REG_EXTENDED);
dc09353a 3791 if (rc) throw SEMANTIC_ERROR (_("blacklist_func_ret regcomp failed"));
27646582 3792 rc = regcomp (& blacklist_file, blfile.c_str(), REG_NOSUB|REG_EXTENDED);
dc09353a 3793 if (rc) throw SEMANTIC_ERROR (_("blacklist_file regcomp failed"));
178ac3f6 3794 rc = regcomp (& blacklist_section, blsection.c_str(), REG_NOSUB|REG_EXTENDED);
dc09353a 3795 if (rc) throw SEMANTIC_ERROR (_("blacklist_section regcomp failed"));
27646582
JS
3796
3797 blacklist_enabled = true;
3798}
3799
3800
3801string
3802dwflpp::get_blacklist_section(Dwarf_Addr addr)
3803{
3804 string blacklist_section;
3805 Dwarf_Addr bias;
3806 // We prefer dwfl_module_getdwarf to dwfl_module_getelf here,
3807 // because dwfl_module_getelf can force costly section relocations
3808 // we don't really need, while either will do for this purpose.
3809 Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (module, &bias))
3810 ?: dwfl_module_getelf (module, &bias));
3811
3812 Dwarf_Addr offset = addr - bias;
3813 if (elf)
3814 {
3815 Elf_Scn* scn = 0;
3816 size_t shstrndx;
fcc30d6d 3817 dwfl_assert ("getshdrstrndx", elf_getshdrstrndx (elf, &shstrndx));
27646582
JS
3818 while ((scn = elf_nextscn (elf, scn)) != NULL)
3819 {
3820 GElf_Shdr shdr_mem;
3821 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
3822 if (! shdr)
3823 continue; // XXX error?
3824
3825 if (!(shdr->sh_flags & SHF_ALLOC))
3826 continue;
3827
3828 GElf_Addr start = shdr->sh_addr;
3829 GElf_Addr end = start + shdr->sh_size;
3830 if (! (offset >= start && offset < end))
3831 continue;
3832
3833 blacklist_section = elf_strptr (elf, shstrndx, shdr->sh_name);
3834 break;
3835 }
3836 }
3837 return blacklist_section;
3838}
3839
3840
fea74777
SC
3841/* Find the section named 'section_name' in the current module
3842 * returning the section header using 'shdr_mem' */
3843
3844GElf_Shdr *
448a86b7 3845dwflpp::get_section(string section_name, GElf_Shdr *shdr_mem, Elf **elf_ret)
fea74777
SC
3846{
3847 GElf_Shdr *shdr = NULL;
3848 Elf* elf;
3849 Dwarf_Addr bias;
3850 size_t shstrndx;
3851
3852 // Explicitly look in the main elf file first.
3853 elf = dwfl_module_getelf (module, &bias);
3854 Elf_Scn *probe_scn = NULL;
3855
3856 dwfl_assert ("getshdrstrndx", elf_getshdrstrndx (elf, &shstrndx));
3857
3858 bool have_section = false;
3859
3860 while ((probe_scn = elf_nextscn (elf, probe_scn)))
3861 {
3862 shdr = gelf_getshdr (probe_scn, shdr_mem);
3863 assert (shdr != NULL);
3864
3865 if (elf_strptr (elf, shstrndx, shdr->sh_name) == section_name)
3866 {
3867 have_section = true;
3868 break;
3869 }
3870 }
3871
3872 // Older versions may put the section in the debuginfo dwarf file,
3873 // so check if it actually exists, if not take a look in the debuginfo file
3874 if (! have_section || (have_section && shdr->sh_type == SHT_NOBITS))
3875 {
3876 elf = dwarf_getelf (dwfl_module_getdwarf (module, &bias));
3877 if (! elf)
448a86b7 3878 return NULL;
fea74777
SC
3879 dwfl_assert ("getshdrstrndx", elf_getshdrstrndx (elf, &shstrndx));
3880 probe_scn = NULL;
3881 while ((probe_scn = elf_nextscn (elf, probe_scn)))
3882 {
3883 shdr = gelf_getshdr (probe_scn, shdr_mem);
3884 if (elf_strptr (elf, shstrndx, shdr->sh_name) == section_name)
3885 {
3886 have_section = true;
3887 break;
3888 }
3889 }
3890 }
3891
3892 if (!have_section)
3893 return NULL;
448a86b7
JS
3894
3895 if (elf_ret)
3896 *elf_ret = elf;
3897 return shdr;
fea74777
SC
3898}
3899
3900
27646582 3901Dwarf_Addr
789448a3 3902dwflpp::relocate_address(Dwarf_Addr dw_addr, string& reloc_section)
27646582 3903{
d2309c6c
MW
3904 // PR10273
3905 // libdw address, so adjust for bias gotten from dwfl_module_getdwarf
3906 Dwarf_Addr reloc_addr = dw_addr + module_bias;
27646582
JS
3907 if (!module)
3908 {
3909 assert(module_name == TOK_KERNEL);
3910 reloc_section = "";
27646582
JS
3911 }
3912 else if (dwfl_module_relocations (module) > 0)
3913 {
3914 // This is a relocatable module; libdwfl already knows its
3915 // sections, so we can relativize addr.
3916 int idx = dwfl_module_relocate_address (module, &reloc_addr);
3917 const char* r_s = dwfl_module_relocation_info (module, idx, NULL);
3918 if (r_s)
3919 reloc_section = r_s;
27646582
JS
3920
3921 if (reloc_section == "" && dwfl_module_relocations (module) == 1)
27646582 3922 reloc_section = ".dynamic";
27646582
JS
3923 }
3924 else
789448a3 3925 reloc_section = ".absolute";
27646582
JS
3926 return reloc_addr;
3927}
3928
88eaee9f
MW
3929/* Returns the call frame address operations for the given program counter
3930 * in the libdw address space.
3931 */
00b01a99
MW
3932Dwarf_Op *
3933dwflpp::get_cfa_ops (Dwarf_Addr pc)
3934{
3935 Dwarf_Op *cfa_ops = NULL;
3936
88eaee9f
MW
3937 if (sess.verbose > 2)
3938 clog << "get_cfa_ops @0x" << hex << pc << dec
3939 << ", module_start @0x" << hex << module_start << dec << endl;
3940
6a38401c 3941 // Try debug_frame first, then fall back on eh_frame.
87748e2b
MW
3942 size_t cfa_nops = 0;
3943 Dwarf_Addr bias = 0;
3944 Dwarf_Frame *frame = NULL;
00b01a99
MW
3945 Dwarf_CFI *cfi = dwfl_module_dwarf_cfi (module, &bias);
3946 if (cfi != NULL)
3947 {
88eaee9f
MW
3948 if (sess.verbose > 3)
3949 clog << "got dwarf cfi bias: 0x" << hex << bias << dec << endl;
87748e2b 3950 if (dwarf_cfi_addrframe (cfi, pc - bias, &frame) == 0)
97f529ab 3951 dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops);
88eaee9f
MW
3952 else if (sess.verbose > 3)
3953 clog << "dwarf_cfi_addrframe failed: " << dwarf_errmsg(-1) << endl;
00b01a99 3954 }
88eaee9f
MW
3955 else if (sess.verbose > 3)
3956 clog << "dwfl_module_dwarf_cfi failed: " << dwfl_errmsg(-1) << endl;
3957
00b01a99
MW
3958 if (cfa_ops == NULL)
3959 {
3960 cfi = dwfl_module_eh_cfi (module, &bias);
3961 if (cfi != NULL)
3962 {
88eaee9f
MW
3963 if (sess.verbose > 3)
3964 clog << "got eh cfi bias: 0x" << hex << bias << dec << endl;
00b01a99 3965 Dwarf_Frame *frame = NULL;
87748e2b 3966 if (dwarf_cfi_addrframe (cfi, pc - bias, &frame) == 0)
97f529ab 3967 dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops);
88eaee9f
MW
3968 else if (sess.verbose > 3)
3969 clog << "dwarf_cfi_addrframe failed: " << dwarf_errmsg(-1) << endl;
00b01a99 3970 }
88eaee9f
MW
3971 else if (sess.verbose > 3)
3972 clog << "dwfl_module_eh_cfi failed: " << dwfl_errmsg(-1) << endl;
3973
00b01a99 3974 }
00b01a99 3975
88eaee9f 3976 if (sess.verbose > 2)
87748e2b
MW
3977 {
3978 if (cfa_ops == NULL)
f9bbd346 3979 clog << _("not found cfa") << endl;
87748e2b
MW
3980 else
3981 {
3982 Dwarf_Addr frame_start, frame_end;
3983 bool frame_signalp;
3984 int info = dwarf_frame_info (frame, &frame_start, &frame_end,
3985 &frame_signalp);
2a97f50b 3986 clog << _F("found cfa, info: %d [start: %#" PRIx64 ", end: %#" PRIx64
f9bbd346 3987 ", nops: %zu", info, frame_start, frame_end, cfa_nops) << endl;
87748e2b
MW
3988 }
3989 }
88eaee9f 3990
00b01a99
MW
3991 return cfa_ops;
3992}
c8ad0687 3993
2eb99c62
CM
3994int
3995dwflpp::add_module_build_id_to_hash (Dwfl_Module *m,
3996 void **userdata __attribute__ ((unused)),
3997 const char *name,
3998 Dwarf_Addr base,
3999 void *arg)
4000{
4001 string modname = name;
4002 systemtap_session * s = (systemtap_session *)arg;
4003 if (pending_interrupts)
4004 return DWARF_CB_ABORT;
4005
4006 // Extract the build ID
4007 const unsigned char *bits;
4008 GElf_Addr vaddr;
4009 int bits_length = dwfl_module_build_id(m, &bits, &vaddr);
4010 if(bits_length > 0)
4011 {
4012 // Convert the binary bits to a hex string
4013 string hex = hex_dump(bits, bits_length);
4014
4015 // Store the build ID in the session
4016 s->build_ids.push_back(hex);
4017 }
4018
4019 return DWARF_CB_OK;
4020}
4021
45b02a36
FCE
4022
4023
4024// Perform PR15123 heuristic for given variable at given address.
4025// Return alternate pc address to do location-list lookup at, or 0 if
4026// inapplicable.
4027//
4028Dwarf_Addr
4029dwflpp::pr15123_retry_addr (Dwarf_Addr pc, Dwarf_Die* die)
4030{
4031 // For PR15123, we'd like to detect the situation where the
4032 // incoming PC may point to a couple-of-byte instruction
4033 // sequence that gcc emits for CFLAGS=-mfentry, and where
4034 // context variables are in fact available throughout, *but* due
4035 // to the bug, the dwarf debuginfo location-list only starts a
4036 // few instructions later. Prologue searching does not resolve
4037 // this as a line-record is in place at the -mfentry prologue.
4038 //
4039 // Detecting this is complicated because ...
4040 // - we only want to do this if -mfentry was actually used
4041 // - if <pc> points to the a function entry point
4042 // - if the architecture is familiar enough that we can have a
4043 // hard-coded constant to skip over the prologue.
4044 //
98df4dae
VB
4045 // Otherwise, we could give a false-positive - return corrupted
4046 // data.
4047 //
4048 // Use of -mfentry is detectable only if CFLAGS=-grecord-gcc-switches
4049 // was used. Without it, set the PR15123_ASSUME_MFENTRY environment
4050 // variable to override the -mfentry test.
45b02a36
FCE
4051
4052 if (getenv ("PR15123_DISABLE"))
4053 return 0;
4054
98df4dae 4055 if (!getenv ("PR15123_ASSUME_MFENTRY")) {
7d31f657
JL
4056 Dwarf_Die cudie;
4057 string producer, version;
4058 dwarf_diecu (die, &cudie, NULL, NULL);
4059 if (!is_gcc_producer(&cudie, producer, version))
98df4dae 4060 return 0;
7d31f657 4061 if (producer.find("-mfentry") == string::npos)
98df4dae
VB
4062 return 0;
4063 }
45b02a36
FCE
4064
4065 // Determine if this pc maps to the beginning of a
4066 // real function (not some inlined doppelganger. This
4067 // is made tricker by this->function may not be
4068 // pointing at the right DIE (say e.g. stap encountered
4069 // the inlined copy first, so was focus_on_function'd).
4070 vector<Dwarf_Die> scopes = getscopes(pc);
4071 if (scopes.size() == 0)
4072 return 0;
4073
4074 Dwarf_Die outer_function_die = scopes[0];
4075 Dwarf_Addr entrypc;
1bbf3f90
JS
4076 if (!die_entrypc(& outer_function_die, &entrypc) || entrypc != pc)
4077 return 0; // (will fail on retry, so we won't loop more than once)
45b02a36
FCE
4078
4079 if (sess.architecture == "i386" ||
4080 sess.architecture == "x86_64") {
4081 /* pull the trigger */
4082 if (sess.verbose > 2)
4083 clog << _("retrying variable location-list lookup at address pc+5\n");
4084 return pc + 5;
4085 }
4086
4087 return 0;
4088}
4089
c5810d31
LB
4090bool
4091dwflpp::has_gnu_debugdata ()
4092{
4093 Dwarf_Addr load_addr;
4094 // Note we really want the actual elf file, not the dwarf .debug file.
4095 Elf* elf = dwfl_module_getelf (module, &load_addr);
4096 size_t shstrndx;
4097 assert (elf_getshdrstrndx (elf, &shstrndx) >= 0);
4098
4099 // Get the gnu_debugdata section header
4100 Elf_Scn *scn = NULL;
4101 GElf_Shdr *gnu_debugdata_shdr = NULL;
4102 GElf_Shdr gnu_debugdata_shdr_mem;
4103 while ((scn = elf_nextscn (elf, scn)))
4104 {
4105 gnu_debugdata_shdr = gelf_getshdr (scn, &gnu_debugdata_shdr_mem);
4106 assert (gnu_debugdata_shdr != NULL);
4107 if (strcmp (elf_strptr (elf, shstrndx, gnu_debugdata_shdr->sh_name), ".gnu_debugdata") == 0)
4108 return true;
4109 }
4110 return false;
4111}
4112
7d31f657
JL
4113// If not GCC, return false. Otherwise, return true and set vers.
4114bool
4115dwflpp::is_gcc_producer(Dwarf_Die *cudie, string& producer, string& version)
4116{
4117 Dwarf_Attribute producer_attr;
4118 if (!dwarf_attr_integrate(cudie, DW_AT_producer, &producer_attr))
4119 return false;
4120
4121 // GNU {C|C++|...} x.x.x YYYYMMDD ...
4122 const char *cproducer = dwarf_formstring(&producer_attr);
4123 if (!cproducer)
4124 return false;
4125 producer = cproducer;
4126
4127 vector<string> tokens;
4128 tokenize(producer, tokens);
4129
4130 if (tokens.size() < 3
4131 || tokens[0] != "GNU"
4132 || tokens[2].find_first_not_of(".0123456789") != string::npos)
4133 return false;
4134
4135 version = tokens[2];
4136 return true;
4137}
45b02a36 4138
277a2b96
JL
4139static bool
4140die_has_loclist(Dwarf_Die *begin_die)
4141{
4142 Dwarf_Die die;
4143 Dwarf_Attribute loc;
4144
4145 if (dwarf_child(begin_die, &die) != 0)
4146 return false;
4147
4148 do
4149 {
4150 switch (dwarf_tag(&die))
4151 {
4152 case DW_TAG_formal_parameter:
4153 case DW_TAG_variable:
4154 if (dwarf_attr_integrate(&die, DW_AT_location, &loc)
4155 && dwarf_whatform(&loc) == DW_FORM_sec_offset)
4156 return true;
4157 break;
4158 default:
4159 if (dwarf_haschildren (&die))
4160 if (die_has_loclist(&die))
4161 return true;
4162 break;
4163 }
4164 }
4165 while (dwarf_siblingof (&die, &die) == 0);
4166
4167 return false;
4168}
4169
4170bool
4171dwflpp::has_valid_locs ()
4172{
4173 assert(cu);
4174
4175 // The current CU has valid location info (implying we do not need to skip the
4176 // prologue) if
4177 // - it was compiled with -O2 -g (in which case, GCC outputs proper location
4178 // info for the prologue), and
4179 // - it was compiled by GCC >= 4.5 (previous versions could have had invalid
4180 // debug info in the prologue, see GDB's PR13777)
3d0efc99
JL
4181 // Note that clang behaves similarly to GCC here: non-optimized code does not
4182 // have location lists, while optimized code does. In the check below, even if
4183 // the producer is not GCC, we assume that it is valid to do the loclist check
4184 // afterwards (which it is for clang).
277a2b96
JL
4185
4186 string prod, vers;
4187 if (is_gcc_producer(cu, prod, vers)
4188 && strverscmp(vers.c_str(), "4.5") < 0)
4189 return false;
4190
4191 // We determine if the current CU has been optimized with -O2 -g by looking
4192 // for any data objects whose DW_AT_location is a location list. This is also
4193 // how GDB determines whether to skip the prologue or not. See GDB's PR12573
4194 // and also RHBZ612253#c6.
4195 if (!die_has_loclist(cu))
4196 return false;
4197
4198 if (sess.verbose > 2)
4199 clog << _F("CU '%s' in module '%s' has valid locs",
4200 cu_name().c_str(), module_name.c_str()) << endl;
4201
4202 return true;
4203}
4204
440f755a 4205/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.602356 seconds and 5 git commands to generate.