diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2010-03-18 09:35:28 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2010-03-18 09:35:28 -0400 |
commit | 70e6d6c94781870f7c11fb3cd62bd8ea69e91a85 (patch) | |
tree | 6071600746cdbe4ff8f15ab7c026ef93c9f062e2 | |
parent | 7acbe85634102f8df073e149a01158d8dcdbf0ee (diff) | |
download | systemtap-steved-70e6d6c94781870f7c11fb3cd62bd8ea69e91a85.tar.gz systemtap-steved-70e6d6c94781870f7c11fb3cd62bd8ea69e91a85.tar.xz systemtap-steved-70e6d6c94781870f7c11fb3cd62bd8ea69e91a85.zip |
PR909: store kernel exported symbols in session object
* session.h (kernel_exports): New field.
* main.cxx (parse_kernel_exports): Fill it.
* tapset-perfmon.cxx (perf_builder::build): Check it for our pal
perf_event_create_kernel_counter.
-rw-r--r-- | main.cxx | 39 | ||||
-rw-r--r-- | session.h | 3 | ||||
-rw-r--r-- | tapset-perfmon.cxx | 2 |
3 files changed, 40 insertions, 4 deletions
@@ -471,6 +471,38 @@ int parse_kernel_config (systemtap_session &s) return 0; } + +int parse_kernel_exports (systemtap_session &s) +{ + string kernel_exports_file = s.kernel_build_tree + "/Module.symvers"; + struct stat st; + int rc = stat(kernel_exports_file.c_str(), &st); + if (rc != 0) + { + clog << "Checking \"" << kernel_exports_file << "\" failed: " << strerror(errno) << endl + << "Ensure kernel development headers & makefiles are installed." << endl; + return rc; + } + + ifstream kef (kernel_exports_file.c_str()); + string line; + while (getline (kef, line)) + { + vector<string> tokens; + tokenize (line, tokens, "\t"); + if (tokens.size() == 4 && + tokens[2] == "vmlinux" && + tokens[3].substr(0,13) == string("EXPORT_SYMBOL")) + s.kernel_exports.insert (tokens[1]); + } + if (s.verbose > 2) + clog << "Parsed kernel \"" << kernel_exports_file << "\", number of vmlinux exports: " << s.kernel_exports.size() << endl; + + kef.close(); + return 0; +} + + /* * Returns a string describing memory resource usage. * Since it seems getrusage() doesn't maintain the mem related fields, @@ -1129,9 +1161,10 @@ main (int argc, char * const argv []) // Now that no further changes to s.kernel_build_tree can occur, let's use it. if (parse_kernel_config (s) != 0) - { - exit (1); - } + exit (1); + + if (parse_kernel_exports (s) != 0) + exit (1); // Create the name of the C source file within the temporary @@ -1,5 +1,5 @@ // -*- C++ -*- -// Copyright (C) 2005-2009 Red Hat Inc. +// Copyright (C) 2005-2010 Red Hat Inc. // // This file is part of systemtap, and is free software. You can // redistribute it and/or modify it under the terms of the GNU General @@ -90,6 +90,7 @@ struct systemtap_session std::string kernel_base_release; std::string kernel_build_tree; std::map<std::string,std::string> kernel_config; + std::set<std::string> kernel_exports; std::string architecture; std::string runtime_path; std::string data_path; diff --git a/tapset-perfmon.cxx b/tapset-perfmon.cxx index 81d6c2d7..9078dfd9 100644 --- a/tapset-perfmon.cxx +++ b/tapset-perfmon.cxx @@ -198,6 +198,8 @@ perf_builder::build(systemtap_session & sess, { // XXX need additional version checks too? // --- perhaps look for export of perf_event_create_kernel_counter + if (sess.kernel_exports.find("perf_event_create_kernel_counter") == sess.kernel_exports.end()) + throw semantic_error ("perf probes not available without exported perf_event_create_kernel_counter"); if (sess.kernel_config["CONFIG_PERF_EVENTS"] != "y") throw semantic_error ("perf probes not available without CONFIG_PERF_EVENTS"); |