]> sourceware.org Git - systemtap.git/blame - dwflpp.cxx
PR4186 cont'd: clarify ARCH naming in NEWS too
[systemtap.git] / dwflpp.cxx
CommitLineData
440f755a
JS
1// C++ interface to dwfl
2// Copyright (C) 2005-2009 Red Hat Inc.
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"
440f755a
JS
25
26#include <cstdlib>
27#include <algorithm>
28#include <deque>
29#include <iostream>
30#include <map>
440f755a
JS
31#include <set>
32#include <sstream>
33#include <stdexcept>
34#include <vector>
35#include <cstdarg>
36#include <cassert>
37#include <iomanip>
38#include <cerrno>
39
40extern "C" {
41#include <fcntl.h>
42#include <elfutils/libdwfl.h>
43#include <elfutils/libdw.h>
44#include <dwarf.h>
45#include <elf.h>
46#include <obstack.h>
47#include <regex.h>
48#include <glob.h>
49#include <fnmatch.h>
50#include <stdio.h>
51#include <sys/types.h>
52
53#include "loc2c.h"
54#define __STDC_FORMAT_MACROS
55#include <inttypes.h>
56}
57
58
59using namespace std;
60using namespace __gnu_cxx;
61
62
63static string TOK_KERNEL("kernel");
64
65
ae2552da 66dwflpp::dwflpp(systemtap_session & session, const string& name, bool kernel_p):
d0b4a5ff
JS
67 sess(session), module(NULL), module_bias(0), mod_info(NULL),
68 module_start(0), module_end(0), cu(NULL), dwfl(NULL),
c8ad0687
JS
69 module_dwarf(NULL), function(NULL), blacklist_enabled(false),
70 pc_cached_scopes(0), num_cached_scopes(0), cached_scopes(NULL)
440f755a 71{
ae2552da
FCE
72 if (kernel_p)
73 setup_kernel(name);
440f755a 74 else
0c16d512
JS
75 {
76 vector<string> modules;
77 modules.push_back(name);
78 setup_user(modules);
79 }
80}
81
82
83dwflpp::dwflpp(systemtap_session & session, const vector<string>& names):
84 sess(session), module(NULL), module_bias(0), mod_info(NULL),
85 module_start(0), module_end(0), cu(NULL), dwfl(NULL),
86 module_dwarf(NULL), function(NULL), blacklist_enabled(false),
87 pc_cached_scopes(0), num_cached_scopes(0), cached_scopes(NULL)
88{
89 setup_user(names);
440f755a
JS
90}
91
92
93dwflpp::~dwflpp()
94{
c8ad0687 95 free(cached_scopes);
440f755a
JS
96 if (dwfl)
97 dwfl_end(dwfl);
98}
99
100
440f755a
JS
101void
102dwflpp::get_module_dwarf(bool required, bool report)
103{
104 module_dwarf = dwfl_module_getdwarf(module, &module_bias);
105 mod_info->dwarf_status = (module_dwarf ? info_present : info_absent);
106 if (!module_dwarf && report)
107 {
108 string msg = "cannot find ";
109 if (module_name == "")
110 msg += "kernel";
111 else
112 msg += string("module ") + module_name;
113 msg += " debuginfo";
114
115 int i = dwfl_errno();
116 if (i)
117 msg += string(": ") + dwfl_errmsg (i);
118
2ed04863
WC
119 /* add module_name to list to find rpm */
120 find_debug_rpms(sess, module_name.c_str());
121
440f755a
JS
122 if (required)
123 throw semantic_error (msg);
83ca3872 124 else if (! sess.suppress_warnings)
440f755a
JS
125 cerr << "WARNING: " << msg << "\n";
126 }
127}
128
129
130void
131dwflpp::focus_on_module(Dwfl_Module * m, module_info * mi)
132{
133 module = m;
134 mod_info = mi;
135 if (m)
136 {
f517ee24
JS
137 module_name = dwfl_module_info(module, NULL, &module_start, &module_end,
138 NULL, NULL, NULL, NULL) ?: "module";
440f755a
JS
139 }
140 else
141 {
142 assert(mi && mi->name && mi->name == TOK_KERNEL);
143 module_name = mi->name;
144 module_start = 0;
145 module_end = 0;
146 module_bias = mi->bias;
147 }
148
149 // Reset existing pointers and names
150
151 module_dwarf = NULL;
152
153 cu_name.clear();
154 cu = NULL;
155
156 function_name.clear();
157 function = NULL;
158}
159
160
161void
162dwflpp::focus_on_cu(Dwarf_Die * c)
163{
164 assert(c);
165 assert(module);
166
167 cu = c;
f517ee24 168 cu_name = dwarf_diename(c) ?: "CU";
440f755a
JS
169
170 // Reset existing pointers and names
171 function_name.clear();
172 function = NULL;
c8ad0687
JS
173
174 free(cached_scopes);
175 cached_scopes = NULL;
440f755a
JS
176}
177
178
179void
180dwflpp::focus_on_function(Dwarf_Die * f)
181{
182 assert(f);
183 assert(module);
184 assert(cu);
185
186 function = f;
f517ee24 187 function_name = dwarf_diename(function) ?: "function";
440f755a
JS
188}
189
190
1f8592d1
MW
191/* Return the Dwarf_Die for the given address in the current module.
192 * The address should be in the module address address space (this
193 * function will take care of any dw bias).
194 */
1adf8ef1
JS
195Dwarf_Die *
196dwflpp::query_cu_containing_address(Dwarf_Addr a)
440f755a
JS
197{
198 Dwarf_Addr bias;
199 assert(dwfl);
b6fa229b 200 assert(module);
440f755a 201 get_module_dwarf();
b6fa229b 202
440f755a 203 Dwarf_Die* cudie = dwfl_module_addrdie(module, a, &bias);
440f755a 204 assert(bias == module_bias);
1adf8ef1 205 return cudie;
440f755a
JS
206}
207
208
440f755a 209bool
5f4c8c6e 210dwflpp::module_name_matches(const string& pattern)
440f755a
JS
211{
212 bool t = (fnmatch(pattern.c_str(), module_name.c_str(), 0) == 0);
213 if (t && sess.verbose>3)
214 clog << "pattern '" << pattern << "' "
215 << "matches "
216 << "module '" << module_name << "'" << "\n";
217 return t;
218}
219
220
221bool
665e1256 222dwflpp::name_has_wildcard (const string& pattern)
440f755a
JS
223{
224 return (pattern.find('*') != string::npos ||
225 pattern.find('?') != string::npos ||
226 pattern.find('[') != string::npos);
227}
228
229
230bool
5f4c8c6e 231dwflpp::module_name_final_match(const string& pattern)
440f755a
JS
232{
233 // Assume module_name_matches(). Can there be any more matches?
234 // Not unless the pattern is a wildcard, since module names are
235 // presumed unique.
236 return !name_has_wildcard(pattern);
237}
238
239
240bool
5f4c8c6e 241dwflpp::function_name_matches_pattern(const string& name, const string& pattern)
440f755a
JS
242{
243 bool t = (fnmatch(pattern.c_str(), name.c_str(), 0) == 0);
244 if (t && sess.verbose>3)
245 clog << "pattern '" << pattern << "' "
246 << "matches "
247 << "function '" << name << "'" << "\n";
248 return t;
249}
250
251
252bool
5f4c8c6e 253dwflpp::function_name_matches(const string& pattern)
440f755a
JS
254{
255 assert(function);
256 return function_name_matches_pattern(function_name, pattern);
257}
258
259
260bool
5f4c8c6e 261dwflpp::function_name_final_match(const string& pattern)
440f755a
JS
262{
263 return module_name_final_match (pattern);
264}
265
266
ae2552da
FCE
267static const char *offline_search_modname = NULL;
268static int offline_search_match_p = 0;
269
270static int dwfl_report_offline_predicate (const char* modname, const char* filename)
271{
272 if (pending_interrupts)
273 return -1;
274
ae2552da
FCE
275 assert (offline_search_modname);
276
fd6fef3d
FCE
277 // elfutils sends us NULL filenames sometimes if it can't find dwarf
278 if (filename == NULL)
279 return 0;
280
665e1256
FCE
281 if (dwflpp::name_has_wildcard (offline_search_modname)) {
282 int match_p = !fnmatch(offline_search_modname, modname, 0);
283 // In the wildcard case, we don't short-circuit (return -1) upon
284 // offline_search_match_p, analogously to dwflpp::module_name_final_match().
285
286 if (match_p)
ae2552da 287 offline_search_match_p ++;
665e1256
FCE
288
289 return match_p;
290 } else { /* non-wildcard mode */
291 if (offline_search_match_p)
292 return -1;
293
294 /* Reject mismatching module names */
295 if (strcmp(modname, offline_search_modname))
296 return 0;
297 else
298 {
299 offline_search_match_p ++;
300 return 1;
301 }
302 }
ae2552da
FCE
303}
304
305
440f755a 306void
ae2552da 307dwflpp::setup_kernel(const string& name, bool debuginfo_needed)
440f755a
JS
308{
309 // XXX: See also translate.cxx:emit_symbol_data
310
311 if (! sess.module_cache)
312 sess.module_cache = new module_cache ();
313
314 static const char *debuginfo_path_arr = "+:.debug:/usr/lib/debug:build";
315 static const char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH");
316 static const char *debuginfo_path = (debuginfo_env_arr ?: debuginfo_path_arr );
317
318 static const Dwfl_Callbacks kernel_callbacks =
319 {
320 dwfl_linux_kernel_find_elf,
321 dwfl_standard_find_debuginfo,
322 dwfl_offline_section_address,
323 (char **) & debuginfo_path
324 };
325
326 dwfl = dwfl_begin (&kernel_callbacks);
327 if (!dwfl)
328 throw semantic_error ("cannot open dwfl");
329 dwfl_report_begin (dwfl);
330
331 // We have a problem with -r REVISION vs -r BUILDDIR here. If
332 // we're running against a fedora/rhel style kernel-debuginfo
333 // tree, s.kernel_build_tree is not the place where the unstripped
334 // vmlinux will be installed. Rather, it's over yonder at
335 // /usr/lib/debug/lib/modules/$REVISION/. It seems that there is
336 // no way to set the dwfl_callback.debuginfo_path and always
337 // passs the plain kernel_release here. So instead we have to
338 // hard-code this magic here.
339 string elfutils_kernel_path;
340 if (sess.kernel_build_tree == string("/lib/modules/" + sess.kernel_release + "/build"))
341 elfutils_kernel_path = sess.kernel_release;
342 else
343 elfutils_kernel_path = sess.kernel_build_tree;
344
ae2552da
FCE
345 offline_search_modname = name.c_str();
346 offline_search_match_p = 0;
440f755a
JS
347 int rc = dwfl_linux_kernel_report_offline (dwfl,
348 elfutils_kernel_path.c_str(),
349 &dwfl_report_offline_predicate);
ae2552da
FCE
350 offline_search_modname = NULL;
351
352 (void) rc; /* Ignore since the predicate probably returned -1 at some point,
353 And libdwfl interprets that as "whole query failed" rather than
354 "found it already, stop looking". */
440f755a 355
ae2552da
FCE
356 /* But we still need to check whether the module was itself found. One could
357 do an iterate_modules() search over the resulting dwfl and count hits. Or
358 one could rely on the match_p flag being set just before. */
359 if (! offline_search_match_p)
360 {
361 if (debuginfo_needed) {
362 // Suggest a likely kernel dir to find debuginfo rpm for
363 string dir = string("/lib/modules/" + sess.kernel_release );
364 find_debug_rpms(sess, dir.c_str());
365 }
366 throw semantic_error (string("missing ") + sess.architecture +
367 string(" kernel/module debuginfo under '") +
368 sess.kernel_build_tree + string("'"));
209dd533 369 }
440f755a 370
440f755a
JS
371 // NB: the result of an _offline call is the assignment of
372 // virtualized addresses to relocatable objects such as
373 // modules. These have to be converted to real addresses at
374 // run time. See the dwarf_derived_probe ctor and its caller.
375
376 dwfl_assert ("dwfl_report_end", dwfl_report_end(dwfl, NULL, NULL));
27646582
JS
377
378 build_blacklist();
440f755a
JS
379}
380
381
382void
0c16d512 383dwflpp::setup_user(const vector<string>& modules, bool debuginfo_needed)
440f755a
JS
384{
385 if (! sess.module_cache)
386 sess.module_cache = new module_cache ();
387
388 static const char *debuginfo_path_arr = "+:.debug:/usr/lib/debug:build";
389 static const char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH");
390 // NB: kernel_build_tree doesn't enter into this, as it's for
391 // kernel-side modules only.
392 static const char *debuginfo_path = (debuginfo_env_arr ?: debuginfo_path_arr);
393
394 static const Dwfl_Callbacks user_callbacks =
395 {
396 NULL, /* dwfl_linux_kernel_find_elf, */
397 dwfl_standard_find_debuginfo,
398 dwfl_offline_section_address,
399 (char **) & debuginfo_path
400 };
401
402 dwfl = dwfl_begin (&user_callbacks);
403 if (!dwfl)
404 throw semantic_error ("cannot open dwfl");
405 dwfl_report_begin (dwfl);
406
0c16d512
JS
407 vector<string>::const_iterator it;
408 for (it = modules.begin(); it != modules.end(); ++it)
409 {
410 // XXX: should support buildid-based naming
411
412 const string& module_name = *it;
413 Dwfl_Module *mod = dwfl_report_offline (dwfl,
414 module_name.c_str(),
415 module_name.c_str(),
416 -1);
0c16d512
JS
417
418 if (debuginfo_needed)
419 dwfl_assert (string("missing process ") +
420 module_name +
421 string(" ") +
422 sess.architecture +
423 string(" debuginfo"),
424 mod);
425 }
440f755a
JS
426
427 // NB: the result of an _offline call is the assignment of
428 // virtualized addresses to relocatable objects such as
429 // modules. These have to be converted to real addresses at
430 // run time. See the dwarf_derived_probe ctor and its caller.
431
432 dwfl_assert ("dwfl_report_end", dwfl_report_end(dwfl, NULL, NULL));
433}
434
435
436void
437dwflpp::iterate_over_modules(int (* callback)(Dwfl_Module *, void **,
438 const char *, Dwarf_Addr,
439 void *),
440 base_query *data)
441{
0e14e079
JS
442 dwfl_getmodules (dwfl, callback, data, 0);
443
440f755a
JS
444 // Don't complain if we exited dwfl_getmodules early.
445 // This could be a $target variable error that will be
446 // reported soon anyway.
447 // dwfl_assert("dwfl_getmodules", off == 0);
448
449 // PR6864 XXX: For dwarfless case (if .../vmlinux is missing), then the
450 // "kernel" module is not reported in the loop above. However, we
451 // may be able to make do with symbol table data.
452}
453
454
440f755a
JS
455void
456dwflpp::iterate_over_cus (int (*callback)(Dwarf_Die * die, void * arg),
457 void * data)
458{
459 get_module_dwarf(false);
460 Dwarf *dw = module_dwarf;
461 if (!dw) return;
462
463 vector<Dwarf_Die>* v = module_cu_cache[dw];
464 if (v == 0)
465 {
466 v = new vector<Dwarf_Die>;
467 module_cu_cache[dw] = v;
468
469 Dwarf_Off off = 0;
470 size_t cuhl;
471 Dwarf_Off noff;
472 while (dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
473 {
474 if (pending_interrupts) return;
475 Dwarf_Die die_mem;
476 Dwarf_Die *die;
477 die = dwarf_offdie (dw, off + cuhl, &die_mem);
478 v->push_back (*die); /* copy */
479 off = noff;
480 }
481 }
482
483 for (unsigned i = 0; i < v->size(); i++)
484 {
485 if (pending_interrupts) return;
486 Dwarf_Die die = v->at(i);
487 int rc = (*callback)(& die, data);
488 if (rc != DWARF_CB_OK) break;
489 }
490}
491
492
493bool
494dwflpp::func_is_inline()
495{
496 assert (function);
497 return dwarf_func_inline (function) != 0;
498}
499
500
501int
502dwflpp::cu_inl_function_caching_callback (Dwarf_Die* func, void *arg)
503{
504 vector<Dwarf_Die>* v = static_cast<vector<Dwarf_Die>*>(arg);
505 v->push_back (* func);
506 return DWARF_CB_OK;
507}
508
509
510void
511dwflpp::iterate_over_inline_instances (int (* callback)(Dwarf_Die * die, void * arg),
512 void * data)
513{
514 assert (function);
515 assert (func_is_inline ());
516
517 string key = module_name + ":" + cu_name + ":" + function_name;
518 vector<Dwarf_Die>* v = cu_inl_function_cache[key];
519 if (v == 0)
520 {
521 v = new vector<Dwarf_Die>;
522 cu_inl_function_cache[key] = v;
523 dwarf_func_inline_instances (function, cu_inl_function_caching_callback, v);
524 }
525
526 for (unsigned i=0; i<v->size(); i++)
527 {
528 if (pending_interrupts) return;
529 Dwarf_Die die = v->at(i);
530 int rc = (*callback)(& die, data);
531 if (rc != DWARF_CB_OK) break;
532 }
533}
534
535
536int
537dwflpp::global_alias_caching_callback(Dwarf_Die *die, void *arg)
538{
539 cu_function_cache_t *cache = static_cast<cu_function_cache_t*>(arg);
540 const char *name = dwarf_diename(die);
541
542 if (!name)
543 return DWARF_CB_OK;
544
545 string structure_name = name;
546
547 if (!dwarf_hasattr(die, DW_AT_declaration) &&
548 cache->find(structure_name) == cache->end())
549 (*cache)[structure_name] = *die;
550
551 return DWARF_CB_OK;
552}
553
554
555Dwarf_Die *
556dwflpp::declaration_resolve(const char *name)
557{
558 if (!name)
559 return NULL;
560
561 string key = module_name + ":" + cu_name;
562 cu_function_cache_t *v = global_alias_cache[key];
563 if (v == 0) // need to build the cache, just once per encountered module/cu
564 {
565 v = new cu_function_cache_t;
566 global_alias_cache[key] = v;
567 iterate_over_globals(global_alias_caching_callback, v);
568 if (sess.verbose > 4)
569 clog << "global alias cache " << key << " size " << v->size() << endl;
570 }
571
572 // XXX: it may be desirable to search other modules' declarations
573 // too, in case a module/shared-library processes a
574 // forward-declared pointer type only, where the actual definition
575 // may only be in vmlinux or the application.
576
577 // XXX: it is probably desirable to search other CU's declarations
578 // in the same module.
579
580 if (v->find(name) == v->end())
581 return NULL;
582
583 return & ((*v)[name]);
584}
585
586
587int
588dwflpp::cu_function_caching_callback (Dwarf_Die* func, void *arg)
589{
590 cu_function_cache_t* v = static_cast<cu_function_cache_t*>(arg);
591 const char *name = dwarf_diename(func);
592 if (!name)
593 return DWARF_CB_OK;
594
595 string function_name = name;
596 (*v)[function_name] = * func;
597 return DWARF_CB_OK;
598}
599
600
601int
602dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query * q),
603 base_query * q, const string& function,
604 bool has_statement_num)
605{
606 int rc = DWARF_CB_OK;
607 assert (module);
608 assert (cu);
609
610 string key = module_name + ":" + cu_name;
611 cu_function_cache_t *v = cu_function_cache[key];
612 if (v == 0)
613 {
614 v = new cu_function_cache_t;
615 cu_function_cache[key] = v;
616 dwarf_getfuncs (cu, cu_function_caching_callback, v, 0);
617 if (sess.verbose > 4)
618 clog << "function cache " << key << " size " << v->size() << endl;
1c6b77e5 619 mod_info->update_symtab(v);
440f755a
JS
620 }
621
5f4c8c6e
JS
622 cu_function_cache_t::iterator it = v->find(function);
623 if (it != v->end())
440f755a 624 {
1c6b77e5 625 Dwarf_Die& die = it->second;
440f755a 626 if (sess.verbose > 4)
5f4c8c6e 627 clog << "function cache " << key << " hit " << function << endl;
440f755a
JS
628 return (*callback)(& die, q);
629 }
5f4c8c6e 630 else if (name_has_wildcard (function))
440f755a 631 {
5f4c8c6e 632 for (it = v->begin(); it != v->end(); it++)
440f755a 633 {
1c6b77e5
JS
634 if (pending_interrupts) return DWARF_CB_ABORT;
635 const string& func_name = it->first;
636 Dwarf_Die& die = it->second;
5f4c8c6e 637 if (function_name_matches_pattern (func_name, function))
440f755a
JS
638 {
639 if (sess.verbose > 4)
640 clog << "function cache " << key << " match " << func_name << " vs "
5f4c8c6e 641 << function << endl;
440f755a
JS
642
643 rc = (*callback)(& die, q);
644 if (rc != DWARF_CB_OK) break;
645 }
646 }
647 }
648 else if (has_statement_num) // searching all for kernel.statement
649 {
650 for (cu_function_cache_t::iterator it = v->begin(); it != v->end(); it++)
651 {
652 Dwarf_Die die = it->second;
653 rc = (*callback)(& die, q);
654 if (rc != DWARF_CB_OK) break;
655 }
656 }
657 else // not a wildcard and no match in this CU
658 {
659 // do nothing
660 }
661 return rc;
662}
663
664
665/* This basically only goes one level down from the compile unit so it
666 * only picks up top level stuff (i.e. nothing in a lower scope) */
667int
668dwflpp::iterate_over_globals (int (* callback)(Dwarf_Die *, void *),
669 void * data)
670{
671 int rc = DWARF_CB_OK;
672 Dwarf_Die die;
673
674 assert (module);
675 assert (cu);
676 assert (dwarf_tag(cu) == DW_TAG_compile_unit);
677
678 if (dwarf_child(cu, &die) != 0)
679 return rc;
680
681 do
682 /* We're only currently looking for named types,
683 * although other types of declarations exist */
684 switch (dwarf_tag(&die))
685 {
686 case DW_TAG_base_type:
687 case DW_TAG_enumeration_type:
688 case DW_TAG_structure_type:
9c119951 689 case DW_TAG_class_type:
440f755a
JS
690 case DW_TAG_typedef:
691 case DW_TAG_union_type:
692 rc = (*callback)(&die, data);
693 break;
694 }
695 while (rc == DWARF_CB_OK && dwarf_siblingof(&die, &die) == 0);
696
697 return rc;
698}
699
700
701// This little test routine represents an unfortunate breakdown in
702// abstraction between dwflpp (putatively, a layer right on top of
703// elfutils), and dwarf_query (interpreting a systemtap probe point).
704// It arises because we sometimes try to fix up slightly-off
705// .statement() probes (something we find out in fairly low-level).
706//
707// An alternative would be to put some more intelligence into query_cu(),
708// and have it print additional suggestions after finding that
709// q->dw.iterate_over_srcfile_lines resulted in no new finished_results.
710
711bool
712dwflpp::has_single_line_record (dwarf_query * q, char const * srcfile, int lineno)
713{
714 if (lineno < 0)
715 return false;
716
717 Dwarf_Line **srcsp = NULL;
718 size_t nsrcs = 0;
719
720 dwarf_assert ("dwarf_getsrc_file",
721 dwarf_getsrc_file (module_dwarf,
722 srcfile, lineno, 0,
723 &srcsp, &nsrcs));
724
725 if (nsrcs != 1)
726 {
727 if (sess.verbose>4)
728 clog << "alternative line " << lineno << " rejected: nsrcs=" << nsrcs << endl;
729 return false;
730 }
731
732 // We also try to filter out lines that leave the selected
733 // functions (if any).
734
735 dwarf_line_t line(srcsp[0]);
736 Dwarf_Addr addr = line.addr();
737
738 func_info_map_t *filtered_functions = get_filtered_functions(q);
739 for (func_info_map_t::iterator i = filtered_functions->begin();
740 i != filtered_functions->end(); ++i)
741 {
742 if (die_has_pc (i->die, addr))
743 {
744 if (sess.verbose>4)
745 clog << "alternative line " << lineno << " accepted: fn=" << i->name << endl;
746 return true;
747 }
748 }
749
750 inline_instance_map_t *filtered_inlines = get_filtered_inlines(q);
751 for (inline_instance_map_t::iterator i = filtered_inlines->begin();
752 i != filtered_inlines->end(); ++i)
753 {
754 if (die_has_pc (i->die, addr))
755 {
756 if (sess.verbose>4)
757 clog << "alternative line " << lineno << " accepted: ifn=" << i->name << endl;
758 return true;
759 }
760 }
761
762 if (sess.verbose>4)
763 clog << "alternative line " << lineno << " rejected: leaves selected fns" << endl;
764 return false;
765}
766
767
768void
769dwflpp::iterate_over_srcfile_lines (char const * srcfile,
770 int lines[2],
771 bool need_single_match,
772 enum line_t line_type,
773 void (* callback) (const dwarf_line_t& line,
774 void * arg),
9b988eff 775 const std::string& func_pattern,
440f755a
JS
776 void *data)
777{
778 Dwarf_Line **srcsp = NULL;
779 size_t nsrcs = 0;
780 dwarf_query * q = static_cast<dwarf_query *>(data);
781 int lineno = lines[0];
782 auto_free_ref<Dwarf_Line**> free_srcsp(srcsp);
783
784 get_module_dwarf();
e679283a
WH
785 if (!this->function)
786 return;
440f755a
JS
787
788 if (line_type == RELATIVE)
789 {
790 Dwarf_Addr addr;
791 Dwarf_Line *line;
792 int line_number;
793
794 dwarf_assert ("dwarf_entrypc", dwarf_entrypc (this->function, &addr));
795 line = dwarf_getsrc_die (this->cu, addr);
796 dwarf_assert ("dwarf_getsrc_die", line == NULL);
797 dwarf_assert ("dwarf_lineno", dwarf_lineno (line, &line_number));
798 lineno += line_number;
799 }
800 else if (line_type == WILDCARD)
801 function_line (&lineno);
1123a74a
WH
802 else if (line_type == RANGE) { /* correct lineno */
803 int start_lineno;
804
9b988eff
WH
805 if (name_has_wildcard(func_pattern)) /* PR10294: wider range like statement("*@foo.c") */
806 start_lineno = lineno;
807 else
808 function_line (&start_lineno);
1123a74a
WH
809 lineno = lineno < start_lineno ? start_lineno : lineno;
810 if (lineno > lines[1]) { /* invalid line range */
811 stringstream advice;
812 advice << "Invalid line range (" << lines[0] << "-" << lines[1] << ")";
813 if (start_lineno > lines[1])
814 advice << ", the end line number " << lines[1] << " < " << start_lineno;
815 throw semantic_error (advice.str());
816 }
817 }
818
440f755a
JS
819
820 for (int l = lineno; ; l = l + 1)
821 {
822 set<int> lines_probed;
823 pair<set<int>::iterator,bool> line_probed;
1123a74a
WH
824 int ret = 0;
825
826 ret = dwarf_getsrc_file (module_dwarf, srcfile, l, 0,
827 &srcsp, &nsrcs);
828 if (line_type != WILDCARD && line_type != RANGE)
829 dwarf_assert ("dwarf_getsrc_file", ret);
830
440f755a
JS
831 if (line_type == WILDCARD || line_type == RANGE)
832 {
833 Dwarf_Addr line_addr;
1123a74a
WH
834
835 if (ret != 0) /* tolerate invalid line number */
836 break;
837
440f755a 838 dwarf_lineno (srcsp [0], &lineno);
1123a74a
WH
839 /* Maybe lineno will exceed the input end */
840 if (line_type == RANGE && lineno > lines[1])
841 break;
440f755a
JS
842 line_probed = lines_probed.insert(lineno);
843 if (lineno != l || line_probed.second == false || nsrcs > 1)
844 continue;
845 dwarf_lineaddr (srcsp [0], &line_addr);
9b988eff 846 if (!function_name_matches(func_pattern) && dwarf_haspc (function, line_addr) != 1)
440f755a
JS
847 break;
848 }
849
850 // NB: Formerly, we used to filter, because:
851
852 // dwarf_getsrc_file gets one *near hits* for line numbers, not
853 // exact matches. For example, an existing file but a nonexistent
854 // line number will be rounded up to the next definition in that
855 // file. This may be similar to the GDB breakpoint algorithm, but
856 // we don't want to be so fuzzy in systemtap land. So we filter.
857
858 // But we now see the error of our ways, and skip this filtering.
859
860 // XXX: the code also fails to match e.g. inline function
861 // definitions when the srcfile is a header file rather than the
862 // CU name.
863
864 size_t remaining_nsrcs = nsrcs;
865
866 if (need_single_match && remaining_nsrcs > 1)
867 {
868 // We wanted a single line record (a unique address for the
869 // line) and we got a bunch of line records. We're going to
870 // skip this probe (throw an exception) but before we throw
871 // we're going to look around a bit to see if there's a low or
872 // high line number nearby which *doesn't* have this problem,
873 // so we can give the user some advice.
874
875 int lo_try = -1;
876 int hi_try = -1;
877 for (size_t i = 1; i < 6; ++i)
878 {
879 if (lo_try == -1 && has_single_line_record(q, srcfile, lineno - i))
880 lo_try = lineno - i;
881
882 if (hi_try == -1 && has_single_line_record(q, srcfile, lineno + i))
883 hi_try = lineno + i;
884 }
885
886 stringstream advice;
887 advice << "multiple addresses for " << srcfile << ":" << lineno;
888 if (lo_try > 0 || hi_try > 0)
889 {
890 advice << " (try ";
891 if (lo_try > 0)
892 advice << srcfile << ":" << lo_try;
893 if (lo_try > 0 && hi_try > 0)
894 advice << " or ";
895 if (hi_try > 0)
896 advice << srcfile << ":" << hi_try;
897 advice << ")";
898 }
899 throw semantic_error (advice.str());
900 }
901
902 for (size_t i = 0; i < nsrcs; ++i)
903 {
904 if (pending_interrupts) return;
905 if (srcsp [i]) // skip over mismatched lines
906 callback (dwarf_line_t(srcsp[i]), data);
907 }
908
909 if (line_type == ABSOLUTE || line_type == RELATIVE)
910 break;
911 else if (line_type == RANGE && l == lines[1])
912 break;
913 }
914}
915
916
917void
918dwflpp::iterate_over_labels (Dwarf_Die *begin_die,
919 const char *sym,
920 const char *symfunction,
921 void *data,
922 void (* callback)(const string &,
923 const char *,
924 int,
925 Dwarf_Die *,
926 Dwarf_Addr,
927 dwarf_query *))
928{
929 dwarf_query * q __attribute__ ((unused)) = static_cast<dwarf_query *>(data) ;
930
931 get_module_dwarf();
932
933 Dwarf_Die die;
934 int res = dwarf_child (begin_die, &die);
935 if (res != 0)
936 return; // die without children, bail out.
937
938 static string function_name = dwarf_diename (begin_die);
939 do
940 {
440f755a 941 int tag = dwarf_tag(&die);
de9a66e3 942 const char *name = dwarf_diename (&die);
440f755a
JS
943 switch (tag)
944 {
945 case DW_TAG_label:
30868aad
MW
946 if (name)
947 break;
948 else
949 continue; // Cannot handle unnamed label.
440f755a
JS
950 break;
951 case DW_TAG_subprogram:
30868aad 952 if (!dwarf_hasattr(&die, DW_AT_declaration) && name)
440f755a
JS
953 function_name = name;
954 else
955 continue;
30868aad
MW
956 case DW_TAG_inlined_subroutine:
957 if (name)
958 function_name = name;
440f755a
JS
959 default:
960 if (dwarf_haschildren (&die))
961 iterate_over_labels (&die, sym, symfunction, q, callback);
962 continue;
963 }
964
965 if (strcmp(function_name.c_str(), symfunction) == 0
966 || (name_has_wildcard(symfunction)
967 && function_name_matches (symfunction)))
968 {
969 }
970 else
971 continue;
972 if (strcmp(name, sym) == 0
973 || (name_has_wildcard(sym)
974 && function_name_matches_pattern (name, sym)))
975 {
976 const char *file = dwarf_decl_file (&die);
7f17af5c 977
440f755a 978 // Get the line number for this label
7f17af5c
JS
979 int dline;
980 dwarf_decl_line (&die, &dline);
981
440f755a
JS
982 Dwarf_Addr stmt_addr;
983 if (dwarf_lowpc (&die, &stmt_addr) != 0)
30868aad 984 continue; // Don't try to be smart. Just drop no addr labels.
440f755a
JS
985
986 Dwarf_Die *scopes;
987 int nscopes = 0;
988 nscopes = dwarf_getscopes_die (&die, &scopes);
989 if (nscopes > 1)
990 {
991 callback(function_name.c_str(), file,
7f17af5c 992 dline, &scopes[1], stmt_addr, q);
440f755a
JS
993 add_label_name(q, name);
994 }
995 }
996 }
997 while (dwarf_siblingof (&die, &die) == 0);
998}
999
1000
1001void
1002dwflpp::collect_srcfiles_matching (string const & pattern,
bd25380d 1003 set<string> & filtered_srcfiles)
440f755a
JS
1004{
1005 assert (module);
1006 assert (cu);
1007
1008 size_t nfiles;
1009 Dwarf_Files *srcfiles;
1010
1011 // PR 5049: implicit * in front of given path pattern.
1012 // NB: fnmatch() is used without FNM_PATHNAME.
1013 string prefixed_pattern = string("*/") + pattern;
1014
1015 dwarf_assert ("dwarf_getsrcfiles",
1016 dwarf_getsrcfiles (cu, &srcfiles, &nfiles));
1017 {
1018 for (size_t i = 0; i < nfiles; ++i)
1019 {
1020 char const * fname = dwarf_filesrc (srcfiles, i, NULL, NULL);
1021 if (fnmatch (pattern.c_str(), fname, 0) == 0 ||
1022 fnmatch (prefixed_pattern.c_str(), fname, 0) == 0)
1023 {
1024 filtered_srcfiles.insert (fname);
1025 if (sess.verbose>2)
1026 clog << "selected source file '" << fname << "'\n";
1027 }
1028 }
1029 }
1030}
1031
1032
1033void
1034dwflpp::resolve_prologue_endings (func_info_map_t & funcs)
1035{
1036 // This heuristic attempts to pick the first address that has a
1037 // source line distinct from the function declaration's. In a
1038 // perfect world, this would be the first statement *past* the
1039 // prologue.
1040
1041 assert(module);
1042 assert(cu);
1043
1044 size_t nlines = 0;
1045 Dwarf_Lines *lines = NULL;
1046
1047 /* trouble cases:
1048 malloc do_symlink in init/initramfs.c tail-recursive/tiny then no-prologue
1049 sys_get?id in kernel/timer.c no-prologue
1050 sys_exit_group tail-recursive
1051 {do_,}sys_open extra-long-prologue (gcc 3.4)
1052 cpu_to_logical_apicid NULL-decl_file
1053 */
1054
1055 // Fetch all srcline records, sorted by address.
1056 dwarf_assert ("dwarf_getsrclines",
1057 dwarf_getsrclines(cu, &lines, &nlines));
1058 // XXX: free lines[] later, but how?
1059
1060 for(func_info_map_t::iterator it = funcs.begin(); it != funcs.end(); it++)
1061 {
1062#if 0 /* someday */
1063 Dwarf_Addr* bkpts = 0;
1064 int n = dwarf_entry_breakpoints (& it->die, & bkpts);
1065 // ...
1066 free (bkpts);
1067#endif
1068
1069 Dwarf_Addr entrypc = it->entrypc;
1070 Dwarf_Addr highpc; // NB: highpc is exclusive: [entrypc,highpc)
1071 dwfl_assert ("dwarf_highpc", dwarf_highpc (& it->die,
1072 & highpc));
1073
1074 if (it->decl_file == 0) it->decl_file = "";
1075
1076 unsigned entrypc_srcline_idx = 0;
1077 dwarf_line_t entrypc_srcline;
1078 // open-code binary search for exact match
1079 {
1080 unsigned l = 0, h = nlines;
1081 while (l < h)
1082 {
1083 entrypc_srcline_idx = (l + h) / 2;
1084 const dwarf_line_t lr(dwarf_onesrcline(lines,
1085 entrypc_srcline_idx));
1086 Dwarf_Addr addr = lr.addr();
1087 if (addr == entrypc) { entrypc_srcline = lr; break; }
1088 else if (l + 1 == h) { break; } // ran off bottom of tree
1089 else if (addr < entrypc) { l = entrypc_srcline_idx; }
1090 else { h = entrypc_srcline_idx; }
1091 }
1092 }
1093 if (!entrypc_srcline)
1094 {
1095 if (sess.verbose > 2)
1096 clog << "missing entrypc dwarf line record for function '"
1097 << it->name << "'\n";
1098 // This is probably an inlined function. We'll end up using
1099 // its lowpc as a probe address.
1100 continue;
1101 }
1102
1103 if (sess.verbose>2)
1104 clog << "prologue searching function '" << it->name << "'"
1105 << " 0x" << hex << entrypc << "-0x" << highpc << dec
1106 << "@" << it->decl_file << ":" << it->decl_line
1107 << "\n";
1108
1109 // Now we go searching for the first line record that has a
1110 // file/line different from the one in the declaration.
1111 // Normally, this will be the next one. BUT:
1112 //
1113 // We may have to skip a few because some old compilers plop
1114 // in dummy line records for longer prologues. If we go too
1115 // far (addr >= highpc), we take the previous one. Or, it may
1116 // be the first one, if the function had no prologue, and thus
1117 // the entrypc maps to a statement in the body rather than the
1118 // declaration.
1119
1120 unsigned postprologue_srcline_idx = entrypc_srcline_idx;
1121 bool ranoff_end = false;
1122 while (postprologue_srcline_idx < nlines)
1123 {
1124 dwarf_line_t lr(dwarf_onesrcline(lines, postprologue_srcline_idx));
1125 Dwarf_Addr postprologue_addr = lr.addr();
1126 const char* postprologue_file = lr.linesrc();
1127 int postprologue_lineno = lr.lineno();
1128
1129 if (sess.verbose>2)
1130 clog << "checking line record 0x" << hex << postprologue_addr << dec
1131 << "@" << postprologue_file << ":" << postprologue_lineno << "\n";
1132
1133 if (postprologue_addr >= highpc)
1134 {
1135 ranoff_end = true;
1136 postprologue_srcline_idx --;
1137 continue;
1138 }
1139 if (ranoff_end ||
1140 (strcmp (postprologue_file, it->decl_file) || // We have a winner!
1141 (postprologue_lineno != it->decl_line)))
1142 {
1143 it->prologue_end = postprologue_addr;
1144
1145 if (sess.verbose>2)
1146 {
1147 clog << "prologue found function '" << it->name << "'";
1148 // Add a little classification datum
1149 if (postprologue_srcline_idx == entrypc_srcline_idx) clog << " (naked)";
1150 if (ranoff_end) clog << " (tail-call?)";
1151 clog << " = 0x" << hex << postprologue_addr << dec << "\n";
1152 }
1153
1154 break;
1155 }
1156
1157 // Let's try the next srcline.
1158 postprologue_srcline_idx ++;
1159 } // loop over srclines
1160
1161 // if (strlen(it->decl_file) == 0) it->decl_file = NULL;
1162
1163 } // loop over functions
1164
1165 // XXX: how to free lines?
1166}
1167
1168
1169bool
1170dwflpp::function_entrypc (Dwarf_Addr * addr)
1171{
1172 assert (function);
1173 return (dwarf_entrypc (function, addr) == 0);
440f755a
JS
1174}
1175
1176
1177bool
1178dwflpp::die_entrypc (Dwarf_Die * die, Dwarf_Addr * addr)
1179{
1180 int rc = 0;
1181 string lookup_method;
1182
1183 * addr = 0;
1184
1185 lookup_method = "dwarf_entrypc";
1186 rc = dwarf_entrypc (die, addr);
1187
440f755a
JS
1188 if (rc)
1189 {
1190 lookup_method = "dwarf_ranges";
1191
1192 Dwarf_Addr base;
1193 Dwarf_Addr begin;
1194 Dwarf_Addr end;
1195 ptrdiff_t offset = dwarf_ranges (die, 0, &base, &begin, &end);
1196 if (offset < 0) rc = -1;
1197 else if (offset > 0)
1198 {
1199 * addr = begin;
1200 rc = 0;
1201
1202 // Now we need to check that there are no more ranges
1203 // associated with this function, which could conceivably
1204 // happen if a function is inlined, then pieces of it are
1205 // split amongst different conditional branches. It's not
1206 // obvious which of them to favour. As a heuristic, we
1207 // pick the beginning of the first range, and ignore the
1208 // others (but with a warning).
1209
1210 unsigned extra = 0;
1211 while ((offset = dwarf_ranges (die, offset, &base, &begin, &end)) > 0)
1212 extra ++;
1213 if (extra)
1214 lookup_method += ", ignored " + lex_cast<string>(extra) + " more";
1215 }
1216 }
1217
1218 if (sess.verbose > 2)
1219 clog << "entry-pc lookup (" << lookup_method << ") = 0x" << hex << *addr << dec
1220 << " (rc " << rc << ")"
1221 << endl;
1222 return (rc == 0);
1223}
1224
1225
1226void
1227dwflpp::function_die (Dwarf_Die *d)
1228{
1229 assert (function);
1230 *d = *function;
1231}
1232
1233
1234void
1235dwflpp::function_file (char const ** c)
1236{
1237 assert (function);
1238 assert (c);
1239 *c = dwarf_decl_file (function);
1240}
1241
1242
1243void
1244dwflpp::function_line (int *linep)
1245{
1246 assert (function);
1247 dwarf_decl_line (function, linep);
1248}
1249
1250
1251bool
1252dwflpp::die_has_pc (Dwarf_Die & die, Dwarf_Addr pc)
1253{
1254 int res = dwarf_haspc (&die, pc);
1255 // dwarf_ranges will return -1 if a function die has no DW_AT_ranges
1256 // if (res == -1)
1257 // dwarf_assert ("dwarf_haspc", res);
1258 return res == 1;
1259}
1260
1261
1262void
1263dwflpp::loc2c_error (void *, const char *fmt, ...)
1264{
1265 const char *msg = "?";
1266 char *tmp = NULL;
1267 int rc;
1268 va_list ap;
1269 va_start (ap, fmt);
1270 rc = vasprintf (& tmp, fmt, ap);
1271 if (rc < 0)
1272 msg = "?";
1273 else
1274 msg = tmp;
1275 va_end (ap);
1276 throw semantic_error (msg);
1277}
1278
1279
1280// This function generates code used for addressing computations of
1281// target variables.
1282void
1283dwflpp::emit_address (struct obstack *pool, Dwarf_Addr address)
1284{
1285 #if 0
1286 // The easy but incorrect way is to just print a hard-wired
1287 // constant.
1288 obstack_printf (pool, "%#" PRIx64 "UL", address);
1289 #endif
1290
1291 // Turn this address into a section-relative offset if it should be one.
1292 // We emit a comment approximating the variable+offset expression that
1293 // relocatable module probing code will need to have.
1294 Dwfl_Module *mod = dwfl_addrmodule (dwfl, address);
1295 dwfl_assert ("dwfl_addrmodule", mod);
1296 const char *modname = dwfl_module_info (mod, NULL, NULL, NULL,
1297 NULL, NULL, NULL, NULL);
1298 int n = dwfl_module_relocations (mod);
1299 dwfl_assert ("dwfl_module_relocations", n >= 0);
1300 Dwarf_Addr reloc_address = address;
1301 int i = dwfl_module_relocate_address (mod, &reloc_address);
1302 dwfl_assert ("dwfl_module_relocate_address", i >= 0);
1303 dwfl_assert ("dwfl_module_info", modname);
1304 const char *secname = dwfl_module_relocation_info (mod, i, NULL);
1305
1306 if (sess.verbose > 2)
1307 {
1308 clog << "emit dwarf addr 0x" << hex << address << dec
1309 << " => module " << modname
1310 << " section " << (secname ?: "null")
1311 << " relocaddr 0x" << hex << reloc_address << dec
1312 << endl;
1313 }
1314
1315 if (n > 0 && !(n == 1 && secname == NULL))
1316 {
1317 dwfl_assert ("dwfl_module_relocation_info", secname);
1318 if (n > 1 || secname[0] != '\0')
1319 {
1320 // This gives us the module name, and section name within the
1321 // module, for a kernel module (or other ET_REL module object).
1322 obstack_printf (pool, "({ static unsigned long addr = 0; ");
1323 obstack_printf (pool, "if (addr==0) addr = _stp_module_relocate (\"%s\",\"%s\",%#" PRIx64 "); ",
1324 modname, secname, reloc_address);
1325 obstack_printf (pool, "addr; })");
1326 }
1327 else if (n == 1 && module_name == TOK_KERNEL && secname[0] == '\0')
1328 {
1329 // elfutils' way of telling us that this is a relocatable kernel address, which we
1330 // need to treat the same way here as dwarf_query::add_probe_point does: _stext.
1331 address -= sess.sym_stext;
1332 secname = "_stext";
1333 obstack_printf (pool, "({ static unsigned long addr = 0; ");
1334 obstack_printf (pool, "if (addr==0) addr = _stp_module_relocate (\"%s\",\"%s\",%#" PRIx64 "); ",
1335 modname, secname, address); // PR10000 NB: not reloc_address
1336 obstack_printf (pool, "addr; })");
1337 }
1338 else
1339 {
1340 throw semantic_error ("cannot relocate user-space dso (?) address");
1341#if 0
1342 // This would happen for a Dwfl_Module that's a user-level DSO.
1343 obstack_printf (pool, " /* %s+%#" PRIx64 " */",
1344 modname, address);
1345#endif
1346 }
1347 }
1348 else
1349 obstack_printf (pool, "%#" PRIx64 "UL", address); // assume as constant
1350}
1351
1352
1353void
1354dwflpp::loc2c_emit_address (void *arg, struct obstack *pool,
1355 Dwarf_Addr address)
1356{
c94efd63 1357 static_cast<dwflpp *>(arg)->emit_address (pool, address);
440f755a
JS
1358}
1359
1360
1361void
1362dwflpp::print_locals(Dwarf_Die *die, ostream &o)
1363{
1364 // Try to get the first child of die.
1365 Dwarf_Die child;
1366 if (dwarf_child (die, &child) == 0)
1367 {
1368 do
1369 {
1370 const char *name;
1371 // Output each sibling's name (that is a variable or
1372 // parameter) to 'o'.
1373 switch (dwarf_tag (&child))
1374 {
1375 case DW_TAG_variable:
1376 case DW_TAG_formal_parameter:
1377 name = dwarf_diename (&child);
1378 if (name)
1379 o << " " << name;
1380 break;
1381 default:
1382 break;
1383 }
1384 }
1385 while (dwarf_siblingof (&child, &child) == 0);
1386 }
1387}
1388
1389
1390Dwarf_Attribute *
1391dwflpp::find_variable_and_frame_base (Dwarf_Die *scope_die,
1392 Dwarf_Addr pc,
1393 string const & local,
1394 const target_symbol *e,
1395 Dwarf_Die *vardie,
1396 Dwarf_Attribute *fb_attr_mem)
1397{
1398 Dwarf_Die *scopes;
1399 int nscopes = 0;
1400 Dwarf_Attribute *fb_attr = NULL;
1401
1402 assert (cu);
1403
c8ad0687 1404 nscopes = dwarf_getscopes_cached (pc, &scopes);
440f755a
JS
1405 if (nscopes <= 0)
1406 {
1407 throw semantic_error ("unable to find any scopes containing "
1408 + lex_cast_hex<string>(pc)
1409 + ((scope_die == NULL) ? ""
1410 : (string (" in ")
1411 + (dwarf_diename(scope_die) ?: "<unknown>")
1412 + "(" + (dwarf_diename(cu) ?: "<unknown>")
1413 + ")"))
1414 + " while searching for local '" + local + "'",
1415 e->tok);
1416 }
1417
1418 int declaring_scope = dwarf_getscopevar (scopes, nscopes,
1419 local.c_str(),
1420 0, NULL, 0, 0,
1421 vardie);
1422 if (declaring_scope < 0)
1423 {
1424 stringstream alternatives;
1425 print_locals (scopes, alternatives);
1426 throw semantic_error ("unable to find local '" + local + "'"
1427 + " near pc " + lex_cast_hex<string>(pc)
1428 + ((scope_die == NULL) ? ""
1429 : (string (" in ")
1430 + (dwarf_diename(scope_die) ?: "<unknown>")
1431 + "(" + (dwarf_diename(cu) ?: "<unknown>")
1432 + ")"))
1433 + (alternatives.str() == "" ? "" : (" (alternatives:" + alternatives.str () + ")")),
1434 e->tok);
1435 }
1436
7bce6f87
MW
1437 /* We start out walking the "lexical scopes" as returned by
1438 * as returned by dwarf_getscopes for the address, starting with the
1439 * declaring_scope that the variable was found in.
1440 */
1441 for (int inner = declaring_scope;
1442 inner < nscopes && fb_attr == NULL;
1443 ++inner)
440f755a
JS
1444 {
1445 switch (dwarf_tag (&scopes[inner]))
1446 {
1447 default:
1448 continue;
1449 case DW_TAG_subprogram:
1450 case DW_TAG_entry_point:
7bce6f87
MW
1451 fb_attr = dwarf_attr_integrate (&scopes[inner],
1452 DW_AT_frame_base,
1453 fb_attr_mem);
1454 break;
1455 case DW_TAG_inlined_subroutine:
1456 /* Unless we already are going through the "pyshical die tree",
1457 * we now need to start walking the die tree where this
1458 * subroutine is inlined to find the appropriate frame base. */
1459 if (declaring_scope != -1)
1460 {
1461 nscopes = dwarf_getscopes_die (&scopes[inner], &scopes);
1462 if (nscopes == -1)
1463 throw semantic_error ("unable to get die scopes for '" +
1464 local + "' in an inlined subroutines",
1465 e->tok);
1466 inner = 0; // zero is current scope, for look will increase.
1467 declaring_scope = -1;
1468 }
440f755a
JS
1469 break;
1470 }
1471 }
7bce6f87 1472
440f755a
JS
1473 return fb_attr;
1474}
1475
1476
1477struct location *
1478dwflpp::translate_location(struct obstack *pool,
1479 Dwarf_Attribute *attr, Dwarf_Addr pc,
1480 Dwarf_Attribute *fb_attr,
1481 struct location **tail,
1482 const target_symbol *e)
1483{
619d9aaf
MW
1484
1485 /* DW_AT_data_member_location, can be either constant offsets
1486 (struct member fields), or full blown location expressions. */
1487 if (dwarf_whatattr (attr) == DW_AT_data_member_location)
1488 {
1489 unsigned int form = dwarf_whatform (attr);
1490 if (form == DW_FORM_data1 || form == DW_FORM_data2
1491 || form == DW_FORM_sdata || form == DW_FORM_udata)
1492 {
1493 Dwarf_Sword off;
1494 if (dwarf_formsdata (attr, &off) != 0)
1495 throw semantic_error (string ("dwarf_formsdata failed, ")
1496 + string (dwarf_errmsg (-1)), e->tok);
1497 c_translate_add_offset (pool, 1, NULL, off, tail);
1498 return *tail;
1499 }
1500 }
1501
440f755a
JS
1502 Dwarf_Op *expr;
1503 size_t len;
1504
1505 /* PR9768: formerly, we added pc+module_bias here. However, that bias value
1506 is not present in the pc value by the time we get it, so adding it would
1507 result in false negatives of variable reachibility. In other instances
1508 further below, the c_translate_FOO functions, the module_bias value used
1509 to be passed in, but instead should now be zero for the same reason. */
1510
1511 switch (dwarf_getlocation_addr (attr, pc /*+ module_bias*/, &expr, &len, 1))
1512 {
1513 case 1: /* Should always happen. */
1514 if (len > 0)
1515 break;
1516 /* Fall through. */
1517
1518 case 0: /* Shouldn't happen. */
1519 throw semantic_error ("not accessible at this address", e->tok);
1520
1521 default: /* Shouldn't happen. */
1522 case -1:
619d9aaf 1523 throw semantic_error (string ("dwarf_getlocation_addr failed, ") +
440f755a
JS
1524 string (dwarf_errmsg (-1)),
1525 e->tok);
1526 }
1527
88eaee9f
MW
1528 // get_cfa_ops works on the dw address space, pc is relative to current
1529 // module, so add do need to add module_bias.
1530 Dwarf_Op *cfa_ops = get_cfa_ops (pc + module_bias);
440f755a
JS
1531 return c_translate_location (pool, &loc2c_error, this,
1532 &loc2c_emit_address,
1533 1, 0 /* PR9768 */,
00b01a99 1534 pc, expr, len, tail, fb_attr, cfa_ops);
440f755a
JS
1535}
1536
1537
1538void
1539dwflpp::print_members(Dwarf_Die *vardie, ostream &o)
1540{
1541 const int typetag = dwarf_tag (vardie);
1542
9c119951
JS
1543 if (typetag != DW_TAG_structure_type &&
1544 typetag != DW_TAG_class_type &&
1545 typetag != DW_TAG_union_type)
440f755a
JS
1546 {
1547 o << " Error: "
f1c8f8a5 1548 << dwarf_type_name(vardie)
9c119951 1549 << " isn't a struct/class/union";
440f755a
JS
1550 return;
1551 }
1552
1553 // Try to get the first child of vardie.
1554 Dwarf_Die die_mem;
1555 Dwarf_Die *die = &die_mem;
1556 switch (dwarf_child (vardie, die))
1557 {
1558 case 1: // No children.
f1c8f8a5 1559 o << dwarf_type_name(vardie)
440f755a
JS
1560 << " is empty";
1561 break;
1562
1563 case -1: // Error.
1564 default: // Shouldn't happen.
f1c8f8a5 1565 o << dwarf_type_name(vardie)
440f755a
JS
1566 << ": " << dwarf_errmsg (-1);
1567 break;
1568
1569 case 0: // Success.
1570 break;
1571 }
1572
1573 // Output each sibling's name to 'o'.
9c119951 1574 do
440f755a 1575 {
9c119951
JS
1576 int tag = dwarf_tag(die);
1577 if (tag != DW_TAG_member && tag != DW_TAG_inheritance)
1578 continue;
1579
23d106b9 1580 const char *member = dwarf_diename (die) ;
440f755a 1581
9c119951 1582 if ( tag == DW_TAG_member && member != NULL )
440f755a
JS
1583 o << " " << member;
1584 else
1585 {
f1c8f8a5 1586 Dwarf_Die temp_die;
3d1ad340 1587 if (!dwarf_attr_die (die, DW_AT_type, &temp_die))
440f755a 1588 {
f1c8f8a5
JS
1589 string source = dwarf_decl_file(die) ?: "<unknown source>";
1590 int line = -1;
1591 dwarf_decl_line(die, &line);
1592 clog << "\n Error in obtaining type attribute for anonymous member at "
1593 << source << ":" << line;
440f755a
JS
1594 return;
1595 }
1596
1597 print_members(&temp_die,o);
1598 }
1599
440f755a 1600 }
9c119951 1601 while (dwarf_siblingof (die, die) == 0);
440f755a
JS
1602}
1603
1604
1605bool
c67847a0 1606dwflpp::find_struct_member(const target_symbol::component& c,
440f755a 1607 Dwarf_Die *parentdie,
440f755a
JS
1608 Dwarf_Die *memberdie,
1609 vector<Dwarf_Attribute>& locs)
1610{
1611 Dwarf_Attribute attr;
b57ba9b8 1612 Dwarf_Die die;
440f755a 1613
b57ba9b8 1614 switch (dwarf_child (parentdie, &die))
440f755a
JS
1615 {
1616 case 0: /* First child found. */
1617 break;
1618 case 1: /* No children. */
1619 return false;
1620 case -1: /* Error. */
1621 default: /* Shouldn't happen */
f1c8f8a5 1622 throw semantic_error (dwarf_type_name(parentdie) + ": "
440f755a 1623 + string (dwarf_errmsg (-1)),
c67847a0 1624 c.tok);
440f755a
JS
1625 }
1626
1627 do
1628 {
9c119951
JS
1629 int tag = dwarf_tag(&die);
1630 if (tag != DW_TAG_member && tag != DW_TAG_inheritance)
440f755a
JS
1631 continue;
1632
23d106b9 1633 const char *name = dwarf_diename(&die);
9c119951 1634 if (name == NULL || tag == DW_TAG_inheritance)
440f755a 1635 {
9c119951
JS
1636 // need to recurse for anonymous structs/unions and
1637 // for inherited members
440f755a 1638 Dwarf_Die subdie;
3d1ad340
JS
1639 if (dwarf_attr_die (&die, DW_AT_type, &subdie) &&
1640 find_struct_member(c, &subdie, memberdie, locs))
440f755a
JS
1641 goto success;
1642 }
c67847a0 1643 else if (name == c.member)
440f755a
JS
1644 {
1645 *memberdie = die;
1646 goto success;
1647 }
1648 }
1649 while (dwarf_siblingof (&die, &die) == 0);
1650
1651 return false;
1652
1653success:
1654 /* As we unwind the recursion, we need to build the chain of
1655 * locations that got to the final answer. */
1656 if (dwarf_attr_integrate (&die, DW_AT_data_member_location, &attr))
1657 locs.insert(locs.begin(), attr);
1658
1659 /* Union members don't usually have a location,
1660 * but just use the containing union's location. */
1661 else if (dwarf_tag(parentdie) != DW_TAG_union_type)
c67847a0 1662 throw semantic_error ("no location for field '" + c.member
440f755a 1663 + "': " + string(dwarf_errmsg (-1)),
c67847a0 1664 c.tok);
440f755a
JS
1665
1666 return true;
1667}
1668
1669
1670Dwarf_Die *
1671dwflpp::translate_components(struct obstack *pool,
1672 struct location **tail,
1673 Dwarf_Addr pc,
1674 const target_symbol *e,
1675 Dwarf_Die *vardie,
1676 Dwarf_Die *die_mem,
1677 Dwarf_Attribute *attr_mem)
1678{
1679 Dwarf_Die *die = NULL;
1680
1681 unsigned i = 0;
1682
1683 if (vardie)
1684 *die_mem = *vardie;
1685
1686 if (e->components.empty())
1687 return die_mem;
1688
1689 while (i < e->components.size())
1690 {
c67847a0
JS
1691 const target_symbol::component& c = e->components[i];
1692
440f755a
JS
1693 /* XXX: This would be desirable, but we don't get the target_symbol token,
1694 and printing that gives us the file:line number too early anyway. */
1695#if 0
1696 // Emit a marker to note which field is being access-attempted, to give
1697 // better error messages if deref() fails.
1698 string piece = string(...target_symbol token...) + string ("#") + stringify(components[i].second);
1699 obstack_printf (pool, "c->last_stmt = %s;", lex_cast_qstring(piece).c_str());
1700#endif
1701
1702 die = die ? dwarf_formref_die (attr_mem, die_mem) : die_mem;
1703 const int typetag = dwarf_tag (die);
1704 switch (typetag)
1705 {
1706 case DW_TAG_typedef:
1707 case DW_TAG_const_type:
1708 case DW_TAG_volatile_type:
1709 /* Just iterate on the referent type. */
1710 break;
1711
9c119951
JS
1712 case DW_TAG_reference_type:
1713 case DW_TAG_rvalue_reference_type:
1714 c_translate_pointer (pool, 1, 0 /* PR9768*/, die, tail);
1715 break;
1716
440f755a 1717 case DW_TAG_pointer_type:
c4dddae6
JS
1718 /* A pointer with no type is a void* -- can't dereference it. */
1719 if (!dwarf_hasattr_integrate (die, DW_AT_type))
1720 throw semantic_error ("invalid access '" + lex_cast<string>(c)
1721 + "' vs. " + dwarf_type_name(die),
1722 c.tok);
1723
440f755a 1724 c_translate_pointer (pool, 1, 0 /* PR9768*/, die, tail);
6fda2dff
JS
1725 if (c.type != target_symbol::comp_literal_array_index &&
1726 c.type != target_symbol::comp_expression_array_index)
d52761f8
JS
1727 break;
1728 /* else fall through as an array access */
440f755a
JS
1729
1730 case DW_TAG_array_type:
c67847a0 1731 if (c.type == target_symbol::comp_literal_array_index)
440f755a
JS
1732 {
1733 c_translate_array (pool, 1, 0 /* PR9768 */, die, tail,
c67847a0 1734 NULL, c.num_index);
440f755a
JS
1735 ++i;
1736 }
6fda2dff
JS
1737 else if (c.type == target_symbol::comp_expression_array_index)
1738 {
1739 string index = "THIS->index" + lex_cast<string>(i);
1740 c_translate_array (pool, 1, 0 /* PR9768 */, die, tail,
1741 index.c_str(), 0);
1742 ++i;
1743 }
440f755a 1744 else
c67847a0
JS
1745 throw semantic_error ("invalid access '"
1746 + lex_cast<string>(c)
1747 + "' for array type",
1748 c.tok);
440f755a
JS
1749 break;
1750
1751 case DW_TAG_structure_type:
1752 case DW_TAG_union_type:
9c119951 1753 case DW_TAG_class_type:
c67847a0
JS
1754 if (c.type != target_symbol::comp_struct_member)
1755 throw semantic_error ("invalid access '"
1756 + lex_cast<string>(c)
f1c8f8a5 1757 + "' for " + dwarf_type_name(die),
c67847a0
JS
1758 c.tok);
1759
440f755a
JS
1760 if (dwarf_hasattr(die, DW_AT_declaration))
1761 {
1762 Dwarf_Die *tmpdie = dwflpp::declaration_resolve(dwarf_diename(die));
1763 if (tmpdie == NULL)
f1c8f8a5 1764 throw semantic_error ("unresolved " + dwarf_type_name(die),
c67847a0 1765 c.tok);
440f755a
JS
1766 *die_mem = *tmpdie;
1767 }
1768
1769 {
b57ba9b8 1770 Dwarf_Die parentdie = *die;
440f755a 1771 vector<Dwarf_Attribute> locs;
b57ba9b8 1772 if (!find_struct_member(c, &parentdie, die, locs))
440f755a 1773 {
72c5ecc2
JS
1774 /* Add a file:line hint for anonymous types */
1775 string source;
1776 if (!dwarf_hasattr_integrate(&parentdie, DW_AT_name))
1777 {
1778 int line;
1779 const char *file = dwarf_decl_file(&parentdie);
1780 if (file && dwarf_decl_line(&parentdie, &line) == 0)
1781 source = " (" + string(file) + ":"
1782 + lex_cast<string>(line) + ")";
1783 }
1784
440f755a
JS
1785 string alternatives;
1786 stringstream members;
b57ba9b8 1787 print_members(&parentdie, members);
440f755a 1788 if (members.str().size() != 0)
72c5ecc2 1789 alternatives = " (alternatives:" + members.str() + ")";
440f755a 1790 throw semantic_error("unable to find member '" +
f1c8f8a5
JS
1791 c.member + "' for "
1792 + dwarf_type_name(&parentdie)
72c5ecc2 1793 + source + alternatives,
c67847a0 1794 c.tok);
440f755a
JS
1795 }
1796
1797 for (unsigned j = 0; j < locs.size(); ++j)
1798 translate_location (pool, &locs[j], pc, NULL, tail, e);
1799 }
1800
1801 ++i;
1802 break;
1803
1804 case DW_TAG_enumeration_type:
440f755a 1805 case DW_TAG_base_type:
c67847a0
JS
1806 throw semantic_error ("invalid access '"
1807 + lex_cast<string>(c)
f1c8f8a5 1808 + "' vs. " + dwarf_type_name(die),
c67847a0 1809 c.tok);
440f755a 1810 break;
f1c8f8a5 1811
440f755a
JS
1812 case -1:
1813 throw semantic_error ("cannot find type: " + string(dwarf_errmsg (-1)),
c67847a0 1814 c.tok);
440f755a
JS
1815 break;
1816
1817 default:
f1c8f8a5 1818 throw semantic_error (dwarf_type_name(die) + ": unexpected type tag "
440f755a 1819 + lex_cast<string>(dwarf_tag (die)),
c67847a0 1820 c.tok);
440f755a
JS
1821 break;
1822 }
1823
1824 /* Now iterate on the type in DIE's attribute. */
1825 if (dwarf_attr_integrate (die, DW_AT_type, attr_mem) == NULL)
c67847a0
JS
1826 throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)),
1827 c.tok);
440f755a 1828 }
d52761f8
JS
1829
1830 /* For an array index, we need to dereference the final DIE */
6fda2dff
JS
1831 if (e->components.back().type == target_symbol::comp_literal_array_index ||
1832 e->components.back().type == target_symbol::comp_expression_array_index)
d52761f8
JS
1833 die = dwarf_formref_die (attr_mem, die_mem);
1834
440f755a
JS
1835 return die;
1836}
1837
1838
1839Dwarf_Die *
1840dwflpp::resolve_unqualified_inner_typedie (Dwarf_Die *typedie_mem,
1841 Dwarf_Attribute *attr_mem,
1842 const target_symbol *e)
1843{
1844 Dwarf_Die *typedie;
1845 int typetag = 0;
1846 while (1)
1847 {
1848 typedie = dwarf_formref_die (attr_mem, typedie_mem);
1849 if (typedie == NULL)
1850 throw semantic_error ("cannot get type: " + string(dwarf_errmsg (-1)), e->tok);
1851 typetag = dwarf_tag (typedie);
1852 if (typetag != DW_TAG_typedef &&
1853 typetag != DW_TAG_const_type &&
1854 typetag != DW_TAG_volatile_type)
1855 break;
1856 if (dwarf_attr_integrate (typedie, DW_AT_type, attr_mem) == NULL)
1857 throw semantic_error ("cannot get type of pointee: " + string(dwarf_errmsg (-1)), e->tok);
1858 }
1859 return typedie;
1860}
1861
1862
1863void
1864dwflpp::translate_final_fetch_or_store (struct obstack *pool,
1865 struct location **tail,
1866 Dwarf_Addr module_bias,
1867 Dwarf_Die *die,
1868 Dwarf_Attribute *attr_mem,
1869 bool lvalue,
1870 const target_symbol *e,
1871 string &,
1872 string &,
1873 exp_type & ty)
1874{
1875 /* First boil away any qualifiers associated with the type DIE of
1876 the final location to be accessed. */
1877
1878 Dwarf_Die typedie_mem;
1879 Dwarf_Die *typedie;
1880 int typetag;
440f755a
JS
1881
1882 typedie = resolve_unqualified_inner_typedie (&typedie_mem, attr_mem, e);
1883 typetag = dwarf_tag (typedie);
1884
03c75a4a
JS
1885 /* If we're looking for an address, then we can just provide what
1886 we computed to this point, without using a fetch/store. */
1887 if (e->addressof)
1888 {
1889 if (lvalue)
1890 throw semantic_error ("cannot write to member address", e->tok);
1891
1892 if (dwarf_hasattr_integrate (die, DW_AT_bit_offset))
1893 throw semantic_error ("cannot take address of bit-field", e->tok);
1894
1895 c_translate_addressof (pool, 1, 0, 0, die, tail, "THIS->__retvalue");
1896 ty = pe_long;
1897 return;
1898 }
1899
440f755a
JS
1900 /* Then switch behavior depending on the type of fetch/store we
1901 want, and the type and pointer-ness of the final location. */
1902
1903 switch (typetag)
1904 {
1905 default:
440f755a
JS
1906 throw semantic_error ("unsupported type tag "
1907 + lex_cast<string>(typetag)
9c119951 1908 + " for " + dwarf_type_name(typedie), e->tok);
440f755a
JS
1909 break;
1910
1911 case DW_TAG_structure_type:
9c119951 1912 case DW_TAG_class_type:
440f755a 1913 case DW_TAG_union_type:
9c119951 1914 throw semantic_error ("'" + dwarf_type_name(typedie)
f1c8f8a5 1915 + "' is being accessed instead of a member", e->tok);
440f755a
JS
1916 break;
1917
1918 case DW_TAG_enumeration_type:
1919 case DW_TAG_base_type:
1920
1921 // Reject types we can't handle in systemtap
1922 {
440f755a
JS
1923 Dwarf_Attribute encoding_attr;
1924 Dwarf_Word encoding = (Dwarf_Word) -1;
1925 dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, &encoding_attr),
1926 & encoding);
1927 if (encoding < 0)
1928 {
1929 // clog << "bad type1 " << encoding << " diestr" << endl;
1930 throw semantic_error ("unsupported type (mystery encoding " + lex_cast<string>(encoding) + ")" +
9c119951 1931 " for " + dwarf_type_name(typedie), e->tok);
440f755a
JS
1932 }
1933
1934 if (encoding == DW_ATE_float
1935 || encoding == DW_ATE_complex_float
1936 /* XXX || many others? */)
1937 {
1938 // clog << "bad type " << encoding << " diestr" << endl;
1939 throw semantic_error ("unsupported type (encoding " + lex_cast<string>(encoding) + ")" +
9c119951 1940 " for " + dwarf_type_name(typedie), e->tok);
440f755a
JS
1941 }
1942 }
1943
1944 ty = pe_long;
1945 if (lvalue)
1946 c_translate_store (pool, 1, 0 /* PR9768 */, die, typedie, tail,
1947 "THIS->value");
1948 else
1949 c_translate_fetch (pool, 1, 0 /* PR9768 */, die, typedie, tail,
1950 "THIS->__retvalue");
1951 break;
1952
1953 case DW_TAG_array_type:
1954 case DW_TAG_pointer_type:
9c119951
JS
1955 case DW_TAG_reference_type:
1956 case DW_TAG_rvalue_reference_type:
440f755a
JS
1957
1958 {
1959 Dwarf_Die pointee_typedie_mem;
1960 Dwarf_Die *pointee_typedie;
1961 Dwarf_Word pointee_encoding;
1962 Dwarf_Word pointee_byte_size = 0;
1963
1964 pointee_typedie = resolve_unqualified_inner_typedie (&pointee_typedie_mem, attr_mem, e);
1965
1966 if (dwarf_attr_integrate (pointee_typedie, DW_AT_byte_size, attr_mem))
1967 dwarf_formudata (attr_mem, &pointee_byte_size);
1968
1969 dwarf_formudata (dwarf_attr_integrate (pointee_typedie, DW_AT_encoding, attr_mem),
1970 &pointee_encoding);
1971
1972 if (lvalue)
1973 {
1974 ty = pe_long;
1975 if (typetag == DW_TAG_array_type)
1976 throw semantic_error ("cannot write to array address", e->tok);
9c119951
JS
1977 if (typetag == DW_TAG_reference_type ||
1978 typetag == DW_TAG_rvalue_reference_type)
1979 throw semantic_error ("cannot write to reference", e->tok);
440f755a
JS
1980 assert (typetag == DW_TAG_pointer_type);
1981 c_translate_pointer_store (pool, 1, 0 /* PR9768 */, typedie, tail,
1982 "THIS->value");
1983 }
1984 else
1985 {
1986 // We have the pointer: cast it to an integral type via &(*(...))
1987
1988 // NB: per bug #1187, at one point char*-like types were
1989 // automagically converted here to systemtap string values.
1990 // For several reasons, this was taken back out, leaving
1991 // pointer-to-string "conversion" (copying) to tapset functions.
1992
1993 ty = pe_long;
1994 if (typetag == DW_TAG_array_type)
1995 c_translate_array (pool, 1, 0 /* PR9768 */, typedie, tail, NULL, 0);
1996 else
1997 c_translate_pointer (pool, 1, 0 /* PR9768 */, typedie, tail);
1998 c_translate_addressof (pool, 1, 0 /* PR9768 */, NULL, pointee_typedie, tail,
1999 "THIS->__retvalue");
2000 }
2001 }
2002 break;
2003 }
2004}
2005
2006
2007string
2008dwflpp::express_as_string (string prelude,
2009 string postlude,
2010 struct location *head)
2011{
2012 size_t bufsz = 1024;
2013 char *buf = static_cast<char*>(malloc(bufsz));
2014 assert(buf);
2015
2016 FILE *memstream = open_memstream (&buf, &bufsz);
2017 assert(memstream);
2018
2019 fprintf(memstream, "{\n");
2020 fprintf(memstream, "%s", prelude.c_str());
2021 bool deref = c_emit_location (memstream, head, 1);
2022 fprintf(memstream, "%s", postlude.c_str());
2023 fprintf(memstream, " goto out;\n");
2024
2025 // dummy use of deref_fault label, to disable warning if deref() not used
2026 fprintf(memstream, "if (0) goto deref_fault;\n");
2027
2028 // XXX: deref flag not reliable; emit fault label unconditionally
2029 (void) deref;
2030 fprintf(memstream,
2031 "deref_fault:\n"
2032 " goto out;\n");
2033 fprintf(memstream, "}\n");
2034
2035 fclose (memstream);
2036 string result(buf);
2037 free (buf);
2038 return result;
2039}
2040
2041
2042string
2043dwflpp::literal_stmt_for_local (Dwarf_Die *scope_die,
2044 Dwarf_Addr pc,
2045 string const & local,
2046 const target_symbol *e,
2047 bool lvalue,
2048 exp_type & ty)
2049{
2050 Dwarf_Die vardie;
2051 Dwarf_Attribute fb_attr_mem, *fb_attr = NULL;
2052
2053 fb_attr = find_variable_and_frame_base (scope_die, pc, local, e,
2054 &vardie, &fb_attr_mem);
2055
2056 if (sess.verbose>2)
2057 clog << "finding location for local '" << local
2058 << "' near address 0x" << hex << pc
2059 << ", module bias 0x" << module_bias << dec
2060 << "\n";
2061
2062 Dwarf_Attribute attr_mem;
2063 if (dwarf_attr_integrate (&vardie, DW_AT_location, &attr_mem) == NULL)
2064 {
2065 throw semantic_error("failed to retrieve location "
2066 "attribute for local '" + local
2067 + "' (dieoffset: "
2068 + lex_cast_hex<string>(dwarf_dieoffset (&vardie))
2069 + ")",
2070 e->tok);
2071 }
2072
2073#define obstack_chunk_alloc malloc
2074#define obstack_chunk_free free
2075
2076 struct obstack pool;
2077 obstack_init (&pool);
2078 struct location *tail = NULL;
2079
2080 /* Given $foo->bar->baz[NN], translate the location of foo. */
2081
2082 struct location *head = translate_location (&pool,
2083 &attr_mem, pc, fb_attr, &tail,
2084 e);
2085
2086 if (dwarf_attr_integrate (&vardie, DW_AT_type, &attr_mem) == NULL)
2087 throw semantic_error("failed to retrieve type "
2088 "attribute for local '" + local + "'",
2089 e->tok);
2090
2091 /* Translate the ->bar->baz[NN] parts. */
2092
2093 Dwarf_Die die_mem, *die = dwarf_formref_die (&attr_mem, &die_mem);
2094 die = translate_components (&pool, &tail, pc, e,
2095 die, &die_mem, &attr_mem);
2096
2097 /* Translate the assignment part, either
2098 x = $foo->bar->baz[NN]
2099 or
2100 $foo->bar->baz[NN] = x
2101 */
2102
2103 string prelude, postlude;
2104 translate_final_fetch_or_store (&pool, &tail, module_bias,
2105 die, &attr_mem, lvalue, e,
2106 prelude, postlude, ty);
2107
2108 /* Write the translation to a string. */
2109 return express_as_string(prelude, postlude, head);
2110}
2111
2112
2113string
2114dwflpp::literal_stmt_for_return (Dwarf_Die *scope_die,
2115 Dwarf_Addr pc,
2116 const target_symbol *e,
2117 bool lvalue,
2118 exp_type & ty)
2119{
2120 if (sess.verbose>2)
2121 clog << "literal_stmt_for_return: finding return value for "
2122 << (dwarf_diename(scope_die) ?: "<unknown>")
2123 << "("
2124 << (dwarf_diename(cu) ?: "<unknown>")
2125 << ")\n";
2126
2127 struct obstack pool;
2128 obstack_init (&pool);
2129 struct location *tail = NULL;
2130
2131 /* Given $return->bar->baz[NN], translate the location of return. */
2132 const Dwarf_Op *locops;
2133 int nlocops = dwfl_module_return_value_location (module, scope_die,
2134 &locops);
2135 if (nlocops < 0)
2136 {
2137 throw semantic_error("failed to retrieve return value location"
2138 " for "
2139 + string(dwarf_diename(scope_die) ?: "<unknown>")
2140 + "(" + string(dwarf_diename(cu) ?: "<unknown>")
2141 + ")",
2142 e->tok);
2143 }
2144 // the function has no return value (e.g. "void" in C)
2145 else if (nlocops == 0)
2146 {
2147 throw semantic_error("function "
2148 + string(dwarf_diename(scope_die) ?: "<unknown>")
2149 + "(" + string(dwarf_diename(cu) ?: "<unknown>")
2150 + ") has no return value",
2151 e->tok);
2152 }
2153
2154 struct location *head = c_translate_location (&pool, &loc2c_error, this,
2155 &loc2c_emit_address,
2156 1, 0 /* PR9768 */,
2157 pc, locops, nlocops,
00b01a99 2158 &tail, NULL, NULL);
440f755a
JS
2159
2160 /* Translate the ->bar->baz[NN] parts. */
2161
2162 Dwarf_Attribute attr_mem;
2163 if (dwarf_attr_integrate (scope_die, DW_AT_type, &attr_mem) == NULL)
2164 throw semantic_error("failed to retrieve return value type attribute for "
2165 + string(dwarf_diename(scope_die) ?: "<unknown>")
2166 + "(" + string(dwarf_diename(cu) ?: "<unknown>")
2167 + ")",
2168 e->tok);
2169
2170 Dwarf_Die die_mem, *die = dwarf_formref_die (&attr_mem, &die_mem);
2171 die = translate_components (&pool, &tail, pc, e,
2172 die, &die_mem, &attr_mem);
2173
2174 /* Translate the assignment part, either
2175 x = $return->bar->baz[NN]
2176 or
2177 $return->bar->baz[NN] = x
2178 */
2179
2180 string prelude, postlude;
2181 translate_final_fetch_or_store (&pool, &tail, module_bias,
2182 die, &attr_mem, lvalue, e,
2183 prelude, postlude, ty);
2184
2185 /* Write the translation to a string. */
2186 return express_as_string(prelude, postlude, head);
2187}
2188
2189
2190string
2191dwflpp::literal_stmt_for_pointer (Dwarf_Die *type_die,
2192 const target_symbol *e,
2193 bool lvalue,
2194 exp_type & ty)
2195{
2196 if (sess.verbose>2)
2197 clog << "literal_stmt_for_pointer: finding value for "
f1c8f8a5 2198 << dwarf_type_name(type_die)
440f755a
JS
2199 << "("
2200 << (dwarf_diename(cu) ?: "<unknown>")
2201 << ")\n";
2202
2203 struct obstack pool;
2204 obstack_init (&pool);
2205 struct location *head = c_translate_argument (&pool, &loc2c_error, this,
2206 &loc2c_emit_address,
2207 1, "THIS->pointer");
2208 struct location *tail = head;
2209
2210 /* Translate the ->bar->baz[NN] parts. */
2211
2212 Dwarf_Attribute attr_mem;
2213 Dwarf_Die die_mem, *die = NULL;
2214 die = translate_components (&pool, &tail, 0, e,
2215 type_die, &die_mem, &attr_mem);
2216
2217 /* Translate the assignment part, either
2218 x = (THIS->pointer)->bar->baz[NN]
2219 or
2220 (THIS->pointer)->bar->baz[NN] = x
2221 */
2222
2223 string prelude, postlude;
2224 translate_final_fetch_or_store (&pool, &tail, module_bias,
2225 die, &attr_mem, lvalue, e,
2226 prelude, postlude, ty);
2227
2228 /* Write the translation to a string. */
2229 return express_as_string(prelude, postlude, head);
2230}
2231
2232
27646582
JS
2233static bool
2234in_kprobes_function(systemtap_session& sess, Dwarf_Addr addr)
2235{
2236 if (sess.sym_kprobes_text_start != 0 && sess.sym_kprobes_text_end != 0)
2237 {
2238 // If the probe point address is anywhere in the __kprobes
2239 // address range, we can't use this probe point.
2240 if (addr >= sess.sym_kprobes_text_start && addr < sess.sym_kprobes_text_end)
2241 return true;
2242 }
2243 return false;
2244}
2245
2246
2247bool
2248dwflpp::blacklisted_p(const string& funcname,
2249 const string& filename,
2250 int,
2251 const string& module,
2252 const string& section,
2253 Dwarf_Addr addr,
2254 bool has_return)
2255{
2256 if (!blacklist_enabled)
2257 return false; // no blacklist for userspace
2258
2259 if (section.substr(0, 6) == string(".init.") ||
2260 section.substr(0, 6) == string(".exit.") ||
2261 section.substr(0, 9) == string(".devinit.") ||
2262 section.substr(0, 9) == string(".devexit.") ||
2263 section.substr(0, 9) == string(".cpuinit.") ||
2264 section.substr(0, 9) == string(".cpuexit.") ||
2265 section.substr(0, 9) == string(".meminit.") ||
2266 section.substr(0, 9) == string(".memexit."))
2267 {
2268 // NB: module .exit. routines could be probed in theory:
2269 // if the exit handler in "struct module" is diverted,
2270 // first inserting the kprobes
2271 // then allowing the exit code to run
2272 // then removing these kprobes
2273 if (sess.verbose>1)
2274 clog << " skipping - init/exit";
2275 return true;
2276 }
2277
2278 // Check for function marked '__kprobes'.
2279 if (module == TOK_KERNEL && in_kprobes_function(sess, addr))
2280 {
2281 if (sess.verbose>1)
2282 clog << " skipping - __kprobes";
2283 return true;
2284 }
2285
2286 // Check probe point against blacklist.
2287 int goodfn = regexec (&blacklist_func, funcname.c_str(), 0, NULL, 0);
2288 if (has_return)
2289 goodfn = goodfn && regexec (&blacklist_func_ret, funcname.c_str(), 0, NULL, 0);
2290 int goodfile = regexec (&blacklist_file, filename.c_str(), 0, NULL, 0);
2291
2292 if (! (goodfn && goodfile))
2293 {
2294 if (sess.guru_mode)
2295 {
2296 if (sess.verbose>1)
2297 clog << " guru mode enabled - ignoring blacklist";
2298 }
2299 else
2300 {
2301 if (sess.verbose>1)
2302 clog << " skipping - blacklisted";
2303 return true;
2304 }
2305 }
2306
2307 // This probe point is not blacklisted.
2308 return false;
2309}
2310
2311
2312void
2313dwflpp::build_blacklist()
2314{
2315 // We build up the regexps in these strings
2316
2317 // Add ^ anchors at the front; $ will be added just before regcomp.
2318
2319 string blfn = "^(";
2320 string blfn_ret = "^(";
2321 string blfile = "^(";
2322
2323 blfile += "kernel/kprobes.c"; // first alternative, no "|"
2324 blfile += "|arch/.*/kernel/kprobes.c";
2325 // Older kernels need ...
2326 blfile += "|include/asm/io.h";
2327 blfile += "|include/asm/bitops.h";
2328 // While newer ones need ...
2329 blfile += "|arch/.*/include/asm/io.h";
2330 blfile += "|arch/.*/include/asm/bitops.h";
2331 blfile += "|drivers/ide/ide-iops.c";
2332
2333 // XXX: it would be nice if these blacklisted functions were pulled
2334 // in dynamically, instead of being statically defined here.
2335 // Perhaps it could be populated from script files. A "noprobe
2336 // kernel.function("...")" construct might do the trick.
2337
2338 // Most of these are marked __kprobes in newer kernels. We list
2339 // them here (anyway) so the translator can block them on older
2340 // kernels that don't have the __kprobes function decorator. This
2341 // also allows detection of problems at translate- rather than
2342 // run-time.
2343
2344 blfn += "atomic_notifier_call_chain"; // first blfn; no "|"
2345 blfn += "|default_do_nmi";
2346 blfn += "|__die";
2347 blfn += "|die_nmi";
2348 blfn += "|do_debug";
2349 blfn += "|do_general_protection";
2350 blfn += "|do_int3";
2351 blfn += "|do_IRQ";
2352 blfn += "|do_page_fault";
2353 blfn += "|do_sparc64_fault";
2354 blfn += "|do_trap";
2355 blfn += "|dummy_nmi_callback";
2356 blfn += "|flush_icache_range";
2357 blfn += "|ia64_bad_break";
2358 blfn += "|ia64_do_page_fault";
2359 blfn += "|ia64_fault";
2360 blfn += "|io_check_error";
2361 blfn += "|mem_parity_error";
2362 blfn += "|nmi_watchdog_tick";
2363 blfn += "|notifier_call_chain";
2364 blfn += "|oops_begin";
2365 blfn += "|oops_end";
2366 blfn += "|program_check_exception";
2367 blfn += "|single_step_exception";
2368 blfn += "|sync_regs";
2369 blfn += "|unhandled_fault";
2370 blfn += "|unknown_nmi_error";
2371
2372 // Lots of locks
2373 blfn += "|.*raw_.*lock.*";
2374 blfn += "|.*read_.*lock.*";
2375 blfn += "|.*write_.*lock.*";
2376 blfn += "|.*spin_.*lock.*";
2377 blfn += "|.*rwlock_.*lock.*";
2378 blfn += "|.*rwsem_.*lock.*";
2379 blfn += "|.*mutex_.*lock.*";
2380 blfn += "|raw_.*";
2381 blfn += "|.*seq_.*lock.*";
2382
2383 // atomic functions
2384 blfn += "|atomic_.*";
2385 blfn += "|atomic64_.*";
2386
2387 // few other problematic cases
2388 blfn += "|get_bh";
2389 blfn += "|put_bh";
2390
2391 // Experimental
2392 blfn += "|.*apic.*|.*APIC.*";
2393 blfn += "|.*softirq.*";
2394 blfn += "|.*IRQ.*";
2395 blfn += "|.*_intr.*";
2396 blfn += "|__delay";
2397 blfn += "|.*kernel_text.*";
2398 blfn += "|get_current";
2399 blfn += "|current_.*";
2400 blfn += "|.*exception_tables.*";
2401 blfn += "|.*setup_rt_frame.*";
2402
2403 // PR 5759, CONFIG_PREEMPT kernels
2404 blfn += "|.*preempt_count.*";
2405 blfn += "|preempt_schedule";
2406
2407 // These functions don't return, so return probes would never be recovered
2408 blfn_ret += "do_exit"; // no "|"
2409 blfn_ret += "|sys_exit";
2410 blfn_ret += "|sys_exit_group";
2411
2412 // __switch_to changes "current" on x86_64 and i686, so return probes
2413 // would cause kernel panic, and it is marked as "__kprobes" on x86_64
2414 if (sess.architecture == "x86_64")
2415 blfn += "|__switch_to";
2416 if (sess.architecture == "i686")
2417 blfn_ret += "|__switch_to";
2418
2419 blfn += ")$";
2420 blfn_ret += ")$";
2421 blfile += ")$";
2422
2423 if (sess.verbose > 2)
2424 {
2425 clog << "blacklist regexps:" << endl;
2426 clog << "blfn: " << blfn << endl;
2427 clog << "blfn_ret: " << blfn_ret << endl;
2428 clog << "blfile: " << blfile << endl;
2429 }
2430
2431 int rc = regcomp (& blacklist_func, blfn.c_str(), REG_NOSUB|REG_EXTENDED);
2432 if (rc) throw semantic_error ("blacklist_func regcomp failed");
2433 rc = regcomp (& blacklist_func_ret, blfn_ret.c_str(), REG_NOSUB|REG_EXTENDED);
2434 if (rc) throw semantic_error ("blacklist_func_ret regcomp failed");
2435 rc = regcomp (& blacklist_file, blfile.c_str(), REG_NOSUB|REG_EXTENDED);
2436 if (rc) throw semantic_error ("blacklist_file regcomp failed");
2437
2438 blacklist_enabled = true;
2439}
2440
2441
2442string
2443dwflpp::get_blacklist_section(Dwarf_Addr addr)
2444{
2445 string blacklist_section;
2446 Dwarf_Addr bias;
2447 // We prefer dwfl_module_getdwarf to dwfl_module_getelf here,
2448 // because dwfl_module_getelf can force costly section relocations
2449 // we don't really need, while either will do for this purpose.
2450 Elf* elf = (dwarf_getelf (dwfl_module_getdwarf (module, &bias))
2451 ?: dwfl_module_getelf (module, &bias));
2452
2453 Dwarf_Addr offset = addr - bias;
2454 if (elf)
2455 {
2456 Elf_Scn* scn = 0;
2457 size_t shstrndx;
fcc30d6d 2458 dwfl_assert ("getshdrstrndx", elf_getshdrstrndx (elf, &shstrndx));
27646582
JS
2459 while ((scn = elf_nextscn (elf, scn)) != NULL)
2460 {
2461 GElf_Shdr shdr_mem;
2462 GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
2463 if (! shdr)
2464 continue; // XXX error?
2465
2466 if (!(shdr->sh_flags & SHF_ALLOC))
2467 continue;
2468
2469 GElf_Addr start = shdr->sh_addr;
2470 GElf_Addr end = start + shdr->sh_size;
2471 if (! (offset >= start && offset < end))
2472 continue;
2473
2474 blacklist_section = elf_strptr (elf, shstrndx, shdr->sh_name);
2475 break;
2476 }
2477 }
2478 return blacklist_section;
2479}
2480
2481
2482Dwarf_Addr
d2309c6c 2483dwflpp::relocate_address(Dwarf_Addr dw_addr,
27646582
JS
2484 string& reloc_section,
2485 string& blacklist_section)
2486{
d2309c6c
MW
2487 // PR10273
2488 // libdw address, so adjust for bias gotten from dwfl_module_getdwarf
2489 Dwarf_Addr reloc_addr = dw_addr + module_bias;
27646582
JS
2490 if (!module)
2491 {
2492 assert(module_name == TOK_KERNEL);
2493 reloc_section = "";
2494 blacklist_section = "";
2495 }
2496 else if (dwfl_module_relocations (module) > 0)
2497 {
2498 // This is a relocatable module; libdwfl already knows its
2499 // sections, so we can relativize addr.
2500 int idx = dwfl_module_relocate_address (module, &reloc_addr);
2501 const char* r_s = dwfl_module_relocation_info (module, idx, NULL);
2502 if (r_s)
2503 reloc_section = r_s;
2504 blacklist_section = reloc_section;
2505
2506 if (reloc_section == "" && dwfl_module_relocations (module) == 1)
2507 {
d2309c6c 2508 blacklist_section = get_blacklist_section(dw_addr);
27646582 2509 reloc_section = ".dynamic";
27646582
JS
2510 }
2511 }
2512 else
2513 {
d2309c6c 2514 blacklist_section = get_blacklist_section(dw_addr);
27646582
JS
2515 reloc_section = ".absolute";
2516 }
2517 return reloc_addr;
2518}
2519
1f8592d1
MW
2520/* Converts a "global" literal address to the module symbol address
2521 * space. If necessary (not for kernel and executables using absolute
2522 * addresses), this adjust the address for the current module symbol
2523 * bias. Literal addresses are provided by the user (or contained on
2524 * the .probes section) based on the "on disk" layout of the module.
2525 */
2526Dwarf_Addr
2527dwflpp::literal_addr_to_sym_addr(Dwarf_Addr lit_addr)
2528{
88eaee9f
MW
2529 if (sess.verbose > 2)
2530 clog << "literal_addr_to_sym_addr 0x" << hex << lit_addr << dec << endl;
2531
1f8592d1
MW
2532 // Assume the address came from the symbol list.
2533 // If we cannot get the symbol bias fall back on the dw bias.
2534 // The kernel (and other absolute executable modules) is special though.
2535 if (module_name != TOK_KERNEL
2536 && dwfl_module_relocations (module) > 0)
2537 {
2538 Dwarf_Addr symbias = ~0;
2539 if (dwfl_module_getsymtab (module) != -1)
2540 dwfl_module_info (module, NULL, NULL, NULL, NULL,
2541 &symbias, NULL, NULL);
88eaee9f
MW
2542
2543 if (sess.verbose > 3)
2544 clog << "symbias 0x" << hex << symbias << dec
2545 << ", dwbias 0x" << hex << module_bias << dec << endl;
2546
1f8592d1
MW
2547 if (symbias == (Dwarf_Addr) ~0)
2548 symbias = module_bias;
2549
2550 lit_addr += symbias;
2551 }
2552
88eaee9f
MW
2553 if (sess.verbose > 2)
2554 clog << "literal_addr_to_sym_addr ret 0x" << hex << lit_addr << dec << endl;
2555
1f8592d1
MW
2556 return lit_addr;
2557}
27646582 2558
c8ad0687
JS
2559int
2560dwflpp::dwarf_getscopes_cached (Dwarf_Addr pc, Dwarf_Die **scopes)
2561{
2562 if (!cached_scopes || pc != pc_cached_scopes)
2563 {
2564 free(cached_scopes);
2565 cached_scopes = NULL;
2566 pc_cached_scopes = pc;
2567 num_cached_scopes = dwarf_getscopes(cu, pc, &cached_scopes);
2568 }
2569 *scopes = cached_scopes;
2570 return num_cached_scopes;
2571}
2572
88eaee9f
MW
2573/* Returns the call frame address operations for the given program counter
2574 * in the libdw address space.
2575 */
00b01a99
MW
2576Dwarf_Op *
2577dwflpp::get_cfa_ops (Dwarf_Addr pc)
2578{
2579 Dwarf_Op *cfa_ops = NULL;
2580
88eaee9f
MW
2581 if (sess.verbose > 2)
2582 clog << "get_cfa_ops @0x" << hex << pc << dec
2583 << ", module_start @0x" << hex << module_start << dec << endl;
2584
00b01a99 2585#if _ELFUTILS_PREREQ(0,142)
6a38401c 2586 // Try debug_frame first, then fall back on eh_frame.
4a8636a3 2587 size_t cfa_nops;
00b01a99
MW
2588 Dwarf_Addr bias;
2589 Dwarf_CFI *cfi = dwfl_module_dwarf_cfi (module, &bias);
2590 if (cfi != NULL)
2591 {
88eaee9f
MW
2592 if (sess.verbose > 3)
2593 clog << "got dwarf cfi bias: 0x" << hex << bias << dec << endl;
00b01a99 2594 Dwarf_Frame *frame = NULL;
88eaee9f 2595 if (dwarf_cfi_addrframe (cfi, pc - bias, &frame) == 0)
97f529ab 2596 dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops);
88eaee9f
MW
2597 else if (sess.verbose > 3)
2598 clog << "dwarf_cfi_addrframe failed: " << dwarf_errmsg(-1) << endl;
00b01a99 2599 }
88eaee9f
MW
2600 else if (sess.verbose > 3)
2601 clog << "dwfl_module_dwarf_cfi failed: " << dwfl_errmsg(-1) << endl;
2602
00b01a99
MW
2603 if (cfa_ops == NULL)
2604 {
2605 cfi = dwfl_module_eh_cfi (module, &bias);
2606 if (cfi != NULL)
2607 {
88eaee9f
MW
2608 if (sess.verbose > 3)
2609 clog << "got eh cfi bias: 0x" << hex << bias << dec << endl;
00b01a99 2610 Dwarf_Frame *frame = NULL;
88eaee9f 2611 if (dwarf_cfi_addrframe (cfi, pc - bias, &frame) == 0)
97f529ab 2612 dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops);
88eaee9f
MW
2613 else if (sess.verbose > 3)
2614 clog << "dwarf_cfi_addrframe failed: " << dwarf_errmsg(-1) << endl;
00b01a99 2615 }
88eaee9f
MW
2616 else if (sess.verbose > 3)
2617 clog << "dwfl_module_eh_cfi failed: " << dwfl_errmsg(-1) << endl;
2618
00b01a99 2619 }
00b01a99
MW
2620#endif
2621
88eaee9f
MW
2622 if (sess.verbose > 2)
2623 clog << (cfa_ops == NULL ? "not " : " ") << "found cfa" << endl;
2624
00b01a99
MW
2625 return cfa_ops;
2626}
c8ad0687 2627
440f755a 2628/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.325688 seconds and 5 git commands to generate.