]> sourceware.org Git - systemtap.git/commitdiff
Shorten function names that will exceed the kernel's objtool limit of 128
authorStan Cox <scox@redhat.com>
Thu, 26 Aug 2021 13:46:20 +0000 (09:46 -0400)
committerStan Cox <scox@redhat.com>
Thu, 26 Aug 2021 13:46:20 +0000 (09:46 -0400)
translate.cxx (c_unparser::emit_global_init_type,emit_function) Shorten
 (c_unparser::c_funcname)  Add funcname_shortened parm, shorten
 name if length limit exceeded

testsuite/systemtap.base/func_definition.{exp,stp}  Add shorten funcname test.

testsuite/systemtap.base/func_definition.exp
testsuite/systemtap.base/func_definition.stp
translate.cxx

index 6598aeea55e13ba57632c9b5024fb27fe6e62c69..0aeab4c70e35a37815af09833c02606839c701cf 100644 (file)
@@ -5,9 +5,25 @@ if {![installtest_p]} { untested "$test"; return }
 
 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)"
+}
index eaa8d94c525820aaac1bdea4df6092907d10d8a3..7ed938eb911e3d2b3c86323cc4f4ea90cd4198bb 100644 (file)
@@ -39,6 +39,11 @@ function f5()
     println("systemtap test success")
 }
 
+function function_names_over_128_characters_exceed_MAX_NAME_LEN_in_linux_objtool_which_is_invoked_by_kbuild_and_are_therefore_shortened()
+{
+    return 2021
+}
+
 probe end {
     println("systemtap ending probe")
 
@@ -57,4 +62,7 @@ probe end {
         printf("systemtap test failure - return_value of f4:%d != 2015\n", f4())
 
     f5()
+
+    if (function_names_over_128_characters_exceed_MAX_NAME_LEN_in_linux_objtool_which_is_invoked_by_kbuild_and_are_therefore_shortened() == 2021)
+        println("systemtap test success")
 }
index 59fa2e4a03d1cfbacb88d411c6dd6f310cb4643e..beb7d7acd3c2366214f16f243dd59ba7a04a4825 100644 (file)
@@ -58,6 +58,9 @@ extern "C" {
 #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;
@@ -183,6 +186,7 @@ struct c_unparser: public unparser, public visitor
   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);
@@ -1755,7 +1759,11 @@ c_unparser::emit_global_init_type (vardecl *v)
 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);";
 }
 
@@ -2520,7 +2528,11 @@ c_tmpcounter::emit_function (functiondecl* fd)
   // 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++)
@@ -2615,7 +2627,11 @@ c_unparser::emit_function (functiondecl* v)
   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);
 
@@ -3385,11 +3401,41 @@ c_unparser::c_globalname (const string& e)
 
 
 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);
 }
 
 
This page took 0.039294 seconds and 5 git commands to generate.