// Copyright (C) Andrew Tridgell 2002 (original file)
-// Copyright (C) 2006-2011 Red Hat Inc. (systemtap changes)
+// Copyright (C) 2006-2014 Red Hat Inc. (systemtap changes)
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
using namespace std;
-class hash
+class stap_hash
{
private:
struct mdfour md4;
std::ostringstream parm_stream;
public:
- hash() { start(); }
- hash(const hash &base) { md4 = base.md4; parm_stream << base.parm_stream.str(); }
+ stap_hash() { start(); }
+ stap_hash(const stap_hash &base) { md4 = base.md4; parm_stream << base.parm_stream.str(); }
void start();
void
-hash::start()
+stap_hash::start()
{
mdfour_begin(&md4);
}
void
-hash::add(const std::string& description, const unsigned char *buffer, size_t size)
+stap_hash::add(const std::string& description, const unsigned char *buffer, size_t size)
{
parm_stream << description << buffer << endl;
mdfour_update(&md4, buffer, size);
template <typename T> void
-hash::add(const std::string& d, const T& x)
+stap_hash::add(const std::string& d, const T& x)
{
parm_stream << d << x << endl;
mdfour_update(&md4, (const unsigned char *)&x, sizeof(x));
void
-hash::add_path(const std::string& description, const std::string& path)
+stap_hash::add_path(const std::string& description, const std::string& path)
{
struct stat st;
memset (&st, 0, sizeof(st));
void
-hash::result(string& r)
+stap_hash::result(string& r)
{
ostringstream rstream;
unsigned char sum[16];
log_file.close();
}
-static const hash&
+static const stap_hash&
get_base_hash (systemtap_session& s)
{
if (s.base_hash)
return *s.base_hash;
- s.base_hash = new hash();
- hash& h = *s.base_hash;
+ s.base_hash = new stap_hash();
+ stap_hash& h = *s.base_hash;
+
+ // Hash systemtap version
+ h.add("Systemtap version: ", s.version_string());
// Hash kernel release and arch.
h.add("Kernel Release: ", s.kernel_release);
// Hash runtime path (that gets added in as "-R path").
h.add_path("Runtime ", s.runtime_path);
+ h.add_path("Runtime transport ", s.runtime_path + "/transport");
+ h.add_path("Runtime unwind ", s.runtime_path + "/unwind");
+ h.add_path("Runtime sub ", s.runtime_path +
+ (s.runtime_usermode_p() ? "/dyninst" : "/linux"));
// Hash compiler path, size, and mtime. We're just going to assume
// we'll be using gcc. XXX: getting kbuild to spit out out would be
// but when developing systemtap that doesn't work well (since you
// can compile systemtap multiple times in 1 day). Since we don't
// know exactly where we're getting run from, we'll use
- // /proc/self/exe.
- // XXX well almost exactly -- valgrind throws this off
- h.add_path("Systemtap ", "/proc/self/exe");
+ // /proc/self/exe (and we resolve it ourselves to help valgrind).
+ h.add_path("Systemtap ", get_self_path());
return h;
}
hashdir += string("/") + result[i*2] + result[i*2 + 1];
if (create_dir(hashdir.c_str()) != 0)
{
- if (! s.suppress_warnings)
- cerr << _F("Warning: failed to create cache directory (\"%s\") %s, disabling cache support",
- hashdir.c_str(), strerror(errno)) << endl;
+ s.print_warning("failed to create cache directory (\"" + hashdir + "\") " + strerror(errno) + ", disabling cache support");
s.use_cache = s.use_script_cache = false;
return false;
}
void
find_script_hash (systemtap_session& s, const string& script)
{
- hash h(get_base_hash(s));
- struct stat st;
+ stap_hash h(get_base_hash(s));
// Hash getuid. This really shouldn't be necessary (since who you
// are doesn't change the generated output), but the hash gets used
h.add("UID: ", getuid());
// Hash user-specified arguments (that change the generated module).
- h.add("Bulk Mode (-b): ", s.bulk_mode); // '-b'
- h.add("Timing (-t): ", s.timing); // '-t'
- h.add("Prologue Searching (-P): ", s.prologue_searching); // '-P'
- h.add("Ignore Vmlinux (--ignore-vmlinux): ", s.ignore_vmlinux); // --ignore-vmlinux
- h.add("Ignore Dwarf (--ignore-dwarf): ", s.ignore_dwarf); // --ignore-dwarf
- h.add("Consult Symtab (--kelf, --kmap): ", s.consult_symtab); // --kelf, --kmap
- h.add("Skip Badvars (--skip-badvars): ", s.skip_badvars); // --skip-badvars
- h.add("Unprivileged (--unprivileged): ", s.privilege); // --unprivileged
- h.add("Compatible (--compatible): ", s.compatible); // --compatible
- h.add("Omit Werror (undocumented): ", s.omit_werror); // undocumented, evil
- if (!s.kernel_symtab_path.empty()) // --kmap
- {
- h.add("Kernel Symtab Path: ", s.kernel_symtab_path);
- if (stat(s.kernel_symtab_path.c_str(), &st) == 0)
- {
- // NB: stat of /proc/kallsyms always returns size=0, mtime=now...
- // which is a good reason to use the default /boot/System.map-2.6.xx
- // instead.
- h.add("Kernel Symtab Size: ", st.st_size);
- h.add("Kernel Symtab Timestamp: ", st.st_mtime);
- }
- }
- for (unsigned i = 0; i < s.macros.size(); i++)
- h.add("Macros: ", s.macros[i]);
+ h.add("Bulk Mode (-b): ", s.bulk_mode);
+ h.add("Timing (-t): ", s.timing);
+ h.add("Skip Badvars (--skip-badvars): ", s.skip_badvars);
+ h.add("Privilege (--privilege): ", s.privilege);
+ h.add("Compatible (--compatible): ", s.compatible);
+ h.add("Omit Werror (undocumented): ", s.omit_werror);
+ h.add("Error suppression (--suppress-handler-errors): ", s.suppress_handler_errors);
+ h.add("Suppress Time Limits (--suppress-time-limits): ", s.suppress_time_limits);
+ h.add("Prologue Searching (--prologue-searching[=WHEN]): ", int(s.prologue_searching_mode));
+
+ for (unsigned i = 0; i < s.c_macros.size(); i++)
+ h.add("Macros: ", s.c_macros[i]);
// Add any custom kbuild flags (-B)
for (unsigned i = 0; i < s.kbuildflags.size(); i++)
h.add("Kbuildflags: ", s.kbuildflags[i]);
+ // Add any custom --modinfo strings
+ for (unsigned i = 0; i < s.modinfos.size(); i++)
+ h.add("MODULE_INFO: ", s.modinfos[i]);
+
// -d MODULE
for (set<string>::iterator it = s.unwindsym_modules.begin();
it != s.unwindsym_modules.end();
// We're using the following so that the module can be used straight
// from the cache if desired. This ends up looking like this:
// ~/.stap_cache/A/B/stap_ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF_XXX.ko
- s.hash_path = hashdir + "/" + s.module_name + ".ko";
+ s.hash_path = hashdir + "/" + s.module_filename();
// Update C source name with new module_name.
- s.translated_source = string(s.tmpdir) + "/" + s.module_name + ".c";
+ s.translated_source = string(s.tmpdir) + "/" + s.module_name + "_src.c";
create_hash_log(string("script_hash"), h.get_parms(), result,
hashdir + "/" + s.module_name + "_hash.log");
}
void
find_stapconf_hash (systemtap_session& s)
{
- hash h(get_base_hash(s));
+ stap_hash h(get_base_hash(s));
// Add any custom kbuild flags
for (unsigned i = 0; i < s.kbuildflags.size(); i++)
string
find_tracequery_hash (systemtap_session& s, const string& header)
{
- hash h(get_base_hash(s));
+ stap_hash h(get_base_hash(s));
// Add the tracepoint header to the computed hash
h.add_path("Header ", header);
string
find_typequery_hash (systemtap_session& s, const string& name)
{
- hash h(get_base_hash(s));
+ stap_hash h(get_base_hash(s));
// Add the typequery name to distinguish the hash
h.add("Typequery Name: ", name);
string
find_uprobes_hash (systemtap_session& s)
{
- hash h(get_base_hash(s));
+ stap_hash h(get_base_hash(s));
// Hash runtime uprobes paths
- h.add_path("Uprobes Runtime Path /uprobes ", s.runtime_path + "/uprobes");
- h.add_path("Uprobes Runtime Path /uprobes2 ", s.runtime_path + "/uprobes2");
+ h.add_path("Uprobes Runtime Path /uprobes ", s.runtime_path + "/linux/uprobes");
+ h.add_path("Uprobes Runtime Path /uprobes2 ", s.runtime_path + "/linux/uprobes2");
// Add any custom kbuild flags
for (unsigned i = 0; i < s.kbuildflags.size(); i++)
h.add("Kbuildflags: ", s.kbuildflags[i]);
+ // Add any custom --modinfo strings
+ for (unsigned i = 0; i < s.modinfos.size(); i++)
+ h.add("MODULE_INFO: ", s.modinfos[i]);
+
// Get the directory path to store our cached module
string result, hashdir;
h.result(result);