diff options
Diffstat (limited to 'hash.cxx')
-rw-r--r-- | hash.cxx | 84 |
1 files changed, 70 insertions, 14 deletions
@@ -48,6 +48,20 @@ hash::add(const unsigned char *buffer, size_t size) void +hash::add_file(const std::string& filename) +{ + struct stat st; + + if (stat(filename.c_str(), &st) == 0) + { + add(filename); + add(st.st_size); + add(st.st_mtime); + } +} + + +void hash::result(string& r) { ostringstream rstream; @@ -68,37 +82,40 @@ hash::result(string& r) static void get_base_hash (systemtap_session& s, hash& h) { - struct stat st; - // Hash kernel release and arch. h.add(s.kernel_release); h.add(s.kernel_build_tree); h.add(s.architecture); + // Hash a few kernel version/build-id files too + // (useful for kernel developers reusing a single source tree) + h.add_file(s.kernel_build_tree + "/.config"); + h.add_file(s.kernel_build_tree + "/.version"); + h.add_file(s.kernel_build_tree + "/include/linux/compile.h"); + h.add_file(s.kernel_build_tree + "/include/linux/version.h"); + h.add_file(s.kernel_build_tree + "/include/linux/utsrelease.h"); + + // If the kernel is a git working directory, then add the git HEAD + // revision to our hash as well. + // XXX avoiding this for now, because it's potentially expensive and has + // uncertain gain. The only corner case that this may help is if a developer + // is switching the source tree without rebuilding the kernel... + ///h.add(git_revision(s.kernel_build_tree)); + // Hash runtime path (that gets added in as "-R path"). h.add(s.runtime_path); // 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 // better. - string gcc_path = find_executable ("gcc"); - if (stat(gcc_path.c_str(), &st) == 0) - { - h.add(gcc_path); - h.add(st.st_size); - h.add(st.st_mtime); - } + h.add_file(find_executable("gcc")); // Hash the systemtap size and mtime. We could use VERSION/DATE, // 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. - if (stat("/proc/self/exe", &st) == 0) - { - h.add(st.st_size); - h.add(st.st_mtime); - } + h.add_file("/proc/self/exe"); } @@ -157,6 +174,7 @@ find_script_hash (systemtap_session& s, const string& script, const hash &base) h.add(s.ignore_vmlinux); // --ignore-vmlinux h.add(s.ignore_dwarf); // --ignore-dwarf h.add(s.consult_symtab); // --kelf, --kmap + h.add(s.skip_badvars); // --skip-badvars if (!s.kernel_symtab_path.empty()) // --kmap { h.add(s.kernel_symtab_path); @@ -237,4 +255,42 @@ find_hash (systemtap_session& s, const string& script) find_script_hash(s, script, base); } + +void +find_tracequery_hash (systemtap_session& s) +{ + hash h; + get_base_hash(s, h); + + // The basic hash should be good enough for the tracepoint query module + + // Get the directory path to store our cached module + string result, hashdir; + h.result(result); + if (!create_hashdir(s, result, hashdir)) + return; + + s.tracequery_path = hashdir + "/tracequery_" + result + ".ko"; +} + + +void +find_typequery_hash (systemtap_session& s, const string& name, string& module) +{ + hash h; + get_base_hash(s, h); + + // Add the typequery name to distinguish the hash + h.add(name); + + // Get the directory path to store our cached module + string result, hashdir; + h.result(result); + if (!create_hashdir(s, result, hashdir)) + return; + + module = hashdir + "/typequery_" + result + + (name[0] == 'k' ? ".ko" : ".so"); +} + /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ |