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