foreach runtime [get_runtime_list] {
if {$runtime != ""} {
- stap_run $test no_load (${all_pass_string}){5} \
+ stap_run $test no_load (${all_pass_string}){6} \
--runtime=$runtime $srcdir/$subdir/$test.stp
} else {
- stap_run $test no_load (${all_pass_string}){5} $srcdir/$subdir/$test.stp
+ stap_run $test no_load (${all_pass_string}){6} $srcdir/$subdir/$test.stp
}
}
+
+set ok 0
+set cmd "bash -c {$env(SYSTEMTAP_PATH)/stap --runtime=$runtime -v -v -p3 $srcdir/$subdir/$test.stp |& grep -A 1 'function_names_over_128'}"
+eval spawn $cmd
+expect {
+ -timeout 180
+ # Match shortened function declaration, definition, and reference
+ -re { function_[0-9] } { incr ok; exp_continue }
+ eof { }
+}
+
+if {$ok == 3} {
+ pass "$test function name shorten"
+} else {
+ fail "$test function name shorten ($ok!=3)"
+}
#define STAP_T_06 _("\"empty aggregate\";")
#define STAP_T_07 _("\"histogram index out of range\";")
+// This matches MAX_NAME_LEN in linux objtool/elf.c used by kbuild
+#define MAX_NAME_LEN 128
+
using namespace std;
class var;
virtual string c_localname (const string& e, bool mangle_oldstyle = false);
virtual string c_globalname (const string &e);
virtual string c_funcname (const string &e);
+ virtual string c_funcname (const string &e, bool &funcname_shortened);
string c_arg_define (const string& e);
string c_arg_undef (const string& e);
void
c_unparser::emit_functionsig (functiondecl* v)
{
- o->newline() << "static void " << c_funcname(v->name)
+ bool funcname_shortened;
+ string funcname = c_funcname (v->name, funcname_shortened);
+ if (funcname_shortened)
+ o->newline() << "/* " << v->name << " */";
+ o->newline() << "static void " << funcname
<< " (struct context * __restrict__ c);";
}
// indent the dummy output as if we were already in a block
this->o->indent (1);
- o->newline() << "struct " << c_funcname (fd->name) << "_locals {";
+ bool funcname_shortened;
+ string funcname = c_funcname (fd->name, funcname_shortened);
+ if (funcname_shortened)
+ o->newline() << "/* " << fd->name << " */";
+ o->newline() << "struct " << funcname << "_locals {";
o->indent(1);
for (unsigned j=0; j<fd->locals.size(); j++)
this->action_counter = 0;
this->already_checked_action_count = false;
- o->newline() << "static void " << c_funcname (v->name)
+ bool funcname_shortened;
+ string funcname = c_funcname (v->name, funcname_shortened);
+ if (funcname_shortened)
+ o->newline() << "/* " << v->name << " */";
+ o->newline() << "static void " << funcname
<< " (struct context* __restrict__ c) {";
o->indent(1);
string
-c_unparser::c_funcname (const string& e)
+c_unparser::c_funcname (const string& e, bool& funcname_shortened)
{
+ const string function_prefix = "function_";
// XXX uncomment to test custom mangling:
- // return "function_" + e + "_" + lex_cast(do_hash(e.c_str()));
- return "function_" + e;
+ // return function_prefix + e + "_" + lex_cast(do_hash(e.c_str()));
+
+ // The kernel objtool used by kbuild has a hardcoded function length limit
+ if (e.length() > MAX_NAME_LEN - function_prefix.length())
+ {
+ int function_index = 0;
+ for (map<string,functiondecl*>::iterator it = session->functions.begin();
+ it != session->functions.end(); it++)
+ {
+ if (it->first == e)
+ {
+ funcname_shortened = true;
+ return function_prefix + to_string(function_index);
+ }
+ function_index += 1;
+ }
+ throw SEMANTIC_ERROR (_("unresolved symbol: ") + e); // should not happen
+ }
+ else
+ {
+ funcname_shortened = false;
+ return function_prefix + e;
+ }
+}
+
+
+string
+c_unparser::c_funcname (const string& e)
+{
+ bool funcname_shortened;
+ return c_funcname (e, funcname_shortened);
}