summaryrefslogtreecommitdiffstats
path: root/tapsets.cxx
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-04-20 16:45:26 -0700
committerJosh Stone <jistone@redhat.com>2009-04-20 16:45:26 -0700
commitfb0274bc9ad5b82caffa33fbd077104b0b7f3b4e (patch)
treed986d2b12fb2d471a25cc635018e778fa7b61bf9 /tapsets.cxx
parent462c90c3a1de9e8472bc84f9c9f8d5192aebd778 (diff)
downloadsystemtap-steved-fb0274bc9ad5b82caffa33fbd077104b0b7f3b4e.tar.gz
systemtap-steved-fb0274bc9ad5b82caffa33fbd077104b0b7f3b4e.tar.xz
systemtap-steved-fb0274bc9ad5b82caffa33fbd077104b0b7f3b4e.zip
PR10055: generate dummy modules w/ types for @cast
The module field in @cast can now also be "kmod<path/to/header.h>" or "umod<path/to/header.h>" to generate a kernel or user module which includes the specified header. The appropriate compiler flags are used to save all possible type debuginfo from the header.
Diffstat (limited to 'tapsets.cxx')
-rw-r--r--tapsets.cxx56
1 files changed, 56 insertions, 0 deletions
diff --git a/tapsets.cxx b/tapsets.cxx
index ee799e74..5a62d47f 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -5104,9 +5104,64 @@ struct dwarf_cast_expanding_visitor: public var_expanding_visitor
dwarf_cast_expanding_visitor(systemtap_session& s, dwarf_builder& db):
s(s), db(db) {}
void visit_cast_op (cast_op* e);
+ void filter_special_modules(string& module);
};
+void dwarf_cast_expanding_visitor::filter_special_modules(string& module)
+{
+ // look for "kmod<path/to/header>" or "umod<path/to/header>"
+ // for those cases, build a module including that header
+ if (module.rfind('>') == module.size() - 1 &&
+ (module.compare(0, 5, "kmod<") == 0 ||
+ module.compare(0, 5, "umod<") == 0))
+ {
+ string cached_module;
+ if (s.use_cache)
+ {
+ // see if the cached module exists
+ find_typequery_hash(s, module, cached_module);
+ if (!cached_module.empty())
+ {
+ int fd = open(cached_module.c_str(), O_RDONLY);
+ if (fd != -1)
+ {
+ if (s.verbose > 2)
+ clog << "Pass 2: using cached " << cached_module << endl;
+ module = cached_module;
+ close(fd);
+ return;
+ }
+ }
+ }
+
+ // no cached module, time to make it
+ int rc;
+ string new_module, header = module.substr(5, module.size() - 6);
+ if (module[0] == 'k')
+ rc = make_typequery_kmod(s, header, new_module);
+ else
+ rc = make_typequery_umod(s, header, new_module);
+ if (rc == 0)
+ {
+ module = new_module;
+
+ if (s.use_cache)
+ {
+ // try to save typequery in the cache
+ if (s.verbose > 2)
+ clog << "Copying " << new_module
+ << " to " << cached_module << endl;
+ if (copy_file(new_module.c_str(),
+ cached_module.c_str()) != 0)
+ cerr << "Copy failed (\"" << new_module << "\" to \""
+ << cached_module << "\"): " << strerror(errno) << endl;
+ }
+ }
+ }
+}
+
+
void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e)
{
bool lvalue = is_active_lvalue(e);
@@ -5125,6 +5180,7 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e)
size_t mod_begin = mod_end + 1;
mod_end = e->module.find(':', mod_begin);
string module = e->module.substr(mod_begin, mod_end - mod_begin);
+ filter_special_modules(module);
// NB: This uses '/' to distinguish between kernel modules and userspace,
// which means that userspace modules won't get any PATH searching.