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