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