? "/usr/libexec/abrt-action-install-debuginfo-to-abrt-cache"
: ""));
-// The module name is the basename (without the extension) of the
-// module path, with ',' and '-' replaced by '_'.
-static string
+// The module name is the basename (without the extension) of the module path,
+// with ',' and '-' replaced by '_'. This is a (more or less safe) heuristic:
+// the actual name by which the module is known once inside the kernel is not
+// derived from the path, but from the .gnu.linkonce.this_module section of the
+// KO. In practice, modules in /lib/modules/ respect this convention, and we
+// require it as well for out-of-tree kernel modules.
+string
modname_from_path(const string &path)
{
size_t dot = path.rfind('.');
#include <elfutils/libdwfl.h>
}
+std::string modname_from_path(const std::string &path);
+
Dwfl *setup_dwfl_kernel(const std::string &name,
unsigned *found,
systemtap_session &s);
// module & section specify a relocation
// base for <addr>, unless section==""
// (equivalently module=="kernel")
+ // for userspace, it's a full path, for
+ // modules, it's either a full path, or
+ // the basename (e.g. 'btrfs')
const string& module,
const string& section,
// NB: dwfl_addr is the virtualized
saved_longs(0), saved_strings(0),
entry_handler(0)
{
+ // If we were given a fullpath to a kernel module, then get the simple name
+ if (q.has_module && is_fully_resolved(module, q.dw.sess.sysroot, q.dw.sess.sysenv))
+ this->module = modname_from_path(module);
+
if (user_lib.size() != 0)
has_library = true;
check->args[0]->tok = this->tok;
check->args.push_back(new literal_number(level));
check->args[1]->tok = this->tok;
- check->args.push_back(new literal_string(module));
+ check->args.push_back(new literal_string(this->module));
check->args[2]->tok = this->tok;
check->args.push_back(new literal_string(caller_section));
check->args[3]->tok = this->tok;
// For kernel modules just the name itself.
string mainpath = resolve_path(mainfile);
string mainname;
- if (modname[0] == '/') // userspace
+ if (is_user_module(modname)) // userspace
mainname = lex_cast_qstring (path_remove_sysroot(c->session,mainpath));
else
- mainname = lex_cast_qstring (modname);
+ { // kernel module
+
+ // If the module name is the full path to the ko, then we have to retrieve
+ // the actual name by which the module will be known inside the kernel.
+ // Otherwise, section relocations would be mismatched.
+ if (is_fully_resolved(modname, c->session.sysroot, c->session.sysenv))
+ mainname = lex_cast_qstring (modname_from_path(modname));
+ else
+ mainname = lex_cast_qstring (modname);
+ }
c->output << "static struct _stp_module _stp_module_" << stpmod_idx << " = {\n";
c->output << ".name = " << mainname.c_str() << ",\n";