summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2015-03-27 20:21:33 +1100
committerChris Johns <chrisj@rtems.org>2015-03-27 20:21:33 +1100
commitd499e6df8977c1da66504a7e4120814ee2dfe3d3 (patch)
tree51efe9e87029b6e0d20211e965a0ebe55f41f724
parentrtems-tester: Remove repeated install line in wscript. (diff)
downloadrtems-tools-d499e6df8977c1da66504a7e4120814ee2dfe3d3.tar.bz2
trace-linker: Add the trace function signatures to the wrapper code.
This gives the tools the ability to extract all needed data from the executable.
-rw-r--r--linkers/rtems-tld.cpp189
1 files changed, 164 insertions, 25 deletions
diff --git a/linkers/rtems-tld.cpp b/linkers/rtems-tld.cpp
index 3582a27..ad567ca 100644
--- a/linkers/rtems-tld.cpp
+++ b/linkers/rtems-tld.cpp
@@ -268,6 +268,11 @@ namespace rld
void generate_names (rld::process::tempfile& c);
/**
+ * Generate the trace signature tables.
+ */
+ void generate_signatures (rld::process::tempfile& c);
+
+ /**
* Generate the enabled trace bitmap.
*/
void generate_enables (rld::process::tempfile& c);
@@ -278,6 +283,11 @@ namespace rld
void generate_triggers (rld::process::tempfile& c);
/**
+ * Generate the functions.
+ */
+ void generate_functions (rld::process::tempfile& c);
+
+ /**
* Generate the trace functions.
*/
void generate_traces (rld::process::tempfile& c);
@@ -291,6 +301,18 @@ namespace rld
const bool global_set);
/**
+ * Function macro replace.
+ */
+ void macro_func_replace (std::string& text,
+ const signature& sig,
+ const std::string& index);
+
+ /**
+ * Find the function given a name.
+ */
+ const function& find_function (const std::string& name) const;
+
+ /**
* Get the traces.
*/
const rld::strings& get_traces () const;
@@ -918,7 +940,9 @@ namespace rld
c.write_lines (generator_.defines);
c.write_lines (generator_.headers);
c.write_line ("");
+ generate_functions (c);
generate_names (c);
+ generate_signatures (c);
generate_enables (c);
generate_triggers (c);
c.write_line ("");
@@ -979,6 +1003,120 @@ namespace rld
}
void
+ tracer::generate_signatures (rld::process::tempfile& c)
+ {
+ const std::string opt = get_option ("gen-sigs");
+
+ if (opt == "disable")
+ return;
+
+ c.write_line ("");
+ c.write_line ("/*");
+ c.write_line (" * Signatures.");
+ c.write_line (" */");
+ c.write_line ("");
+ c.write_line ("typedef struct {");
+ c.write_line (" uint32_t size;");
+ c.write_line (" const char* const type;");
+ c.write_line ("} __rtld_sig_arg;");
+ c.write_line ("");
+ c.write_line ("typedef struct {");
+ c.write_line (" uint32_t argc;");
+ c.write_line (" const __rtld_sig_arg* args;");
+ c.write_line ("} __rtld_sig;");
+ c.write_line ("");
+
+ std::stringstream sss;
+
+ for (rld::strings::const_iterator ti = traces.begin ();
+ ti != traces.end ();
+ ++ti)
+ {
+ const std::string& trace = *ti;
+ bool found = false;
+
+ for (functions::const_iterator fi = functions_.begin ();
+ !found && (fi != functions_.end ());
+ ++fi)
+ {
+ const function& funcs = *fi;
+ signatures::const_iterator si = funcs.signatures_.find (trace);
+
+ if (si != funcs.signatures_.end ())
+ {
+ found = true;
+
+ const signature& sig = (*si).second;
+
+ size_t argc = 1 + (sig.args.size () == 0 ? 1 : sig.args.size ());
+
+ sss.str (std::string ());
+
+ sss << "const __rtld_sig_arg __rtld_sig_args_" << trace
+ << "[" << argc << "] =" << std::endl
+ << "{" << std::endl;
+
+ if (sig.has_ret ())
+ sss << " { sizeof (" << sig.ret << "), \"" << sig.ret << "\" }," << std::endl;
+ else
+ sss << " { 0, \"void\" }," << std::endl;
+
+ if (sig.has_args ())
+ {
+ for (size_t a = 0; a < sig.args.size (); ++a)
+ {
+ sss << " { sizeof (" << sig.args[a] << "), \"" << sig.args[a] << "\" },"
+ << std::endl;
+ }
+ }
+ else
+ sss << " { 0, \"void\" }," << std::endl;
+
+ sss << "};" << std::endl;
+
+ c.write_line (sss.str ());
+ }
+ }
+
+ if (!found)
+ throw rld::error ("not found", "trace function: " + trace);
+ }
+
+ sss.str (std::string ());
+
+ sss << "const __rtld_sig __rtld_signatures[" << traces.size () << "] = "
+ << "{" << std::endl;
+
+ for (rld::strings::const_iterator ti = traces.begin ();
+ ti != traces.end ();
+ ++ti)
+ {
+ const std::string& trace = *ti;
+
+ for (functions::const_iterator fi = functions_.begin ();
+ fi != functions_.end ();
+ ++fi)
+ {
+ const function& funcs = *fi;
+ signatures::const_iterator si = funcs.signatures_.find (trace);
+
+ if (si != funcs.signatures_.end ())
+ {
+ const signature& sig = (*si).second;
+ size_t argc = 1 + (sig.args.size () == 0 ? 1 : sig.args.size ());
+ sss << " { " << argc << ", __rtld_sig_args_" << trace << " }," << std::endl;
+ }
+
+ break;
+ }
+ }
+
+ sss << "};" << std::endl;
+
+ c.write_line (sss.str ());
+ }
+
+ void
tracer::generate_enables (rld::process::tempfile& c)
{
const std::string opt = get_option ("gen-enables");
@@ -1021,8 +1159,12 @@ namespace rld
}
void
- tracer::generate_traces (rld::process::tempfile& c)
+ tracer::generate_functions (rld::process::tempfile& c)
{
+ c.write_line ("/*");
+ c.write_line (" * Functions.");
+ c.write_line (" */");
+
for (functions::const_iterator fi = functions_.begin ();
fi != functions_.end ();
++fi)
@@ -1048,8 +1190,11 @@ namespace rld
}
}
}
+ }
- c.write_line ("");
+ void
+ tracer::generate_traces (rld::process::tempfile& c)
+ {
c.write_line ("/*");
c.write_line (" * Wrappers.");
c.write_line (" */");
@@ -1157,12 +1302,7 @@ namespace rld
if (!generator_.entry_alloc.empty ())
{
l = " " + generator_.entry_alloc;
- l = rld::find_replace (l, "@FUNC_NAME@", '"' + sig.name + '"');
- l = rld::find_replace (l, "@FUNC_INDEX@", lss.str ());
- l = rld::find_replace (l, "@FUNC_LABEL@", sig.name);
- l = rld::find_replace (l, "@FUNC_DATA_SIZE@", "FUNC_DATA_SIZE_" + sig.name);
- l = rld::find_replace (l, "@FUNC_DATA_ENTRY_SIZE@", "FUNC_DATA_ENTRY_SIZE_" + sig.name);
- l = rld::find_replace (l, "@FUNC_DATA_RET_SIZE@", "FUNC_DATA_RET_SIZE_" + sig.name);
+ macro_func_replace (l, sig, lss.str ());
c.write_line(l);
}
@@ -1172,12 +1312,7 @@ namespace rld
if (!generator_.entry_trace.empty ())
{
l = " " + generator_.entry_trace;
- l = rld::find_replace (l, "@FUNC_NAME@", '"' + sig.name + '"');
- l = rld::find_replace (l, "@FUNC_INDEX@", lss.str ());
- l = rld::find_replace (l, "@FUNC_LABEL@", sig.name);
- l = rld::find_replace (l, "@FUNC_DATA_SIZE@", "FUNC_DATA_SIZE_" + sig.name);
- l = rld::find_replace (l, "@FUNC_DATA_ENTRY_SIZE@", "FUNC_DATA_ENTRY_SIZE_" + sig.name);
- l = rld::find_replace (l, "@FUNC_DATA_RET_SIZE@", "FUNC_DATA_RET_SIZE_" + sig.name);
+ macro_func_replace (l, sig, lss.str ());
c.write_line(l);
}
@@ -1219,12 +1354,7 @@ namespace rld
if (!generator_.exit_alloc.empty ())
{
l = " " + generator_.exit_alloc;
- l = rld::find_replace (l, "@FUNC_NAME@", '"' + sig.name + '"');
- l = rld::find_replace (l, "@FUNC_INDEX@", lss.str ());
- l = rld::find_replace (l, "@FUNC_LABEL@", sig.name);
- l = rld::find_replace (l, "@FUNC_DATA_SIZE@", "FUNC_DATA_SIZE_" + sig.name);
- l = rld::find_replace (l, "@FUNC_DATA_ENTRY_SIZE@", "FUNC_DATA_ENTRY_SIZE_" + sig.name);
- l = rld::find_replace (l, "@FUNC_DATA_RET_SIZE@", "FUNC_DATA_RET_SIZE_" + sig.name);
+ macro_func_replace (l, sig, lss.str ());
c.write_line(l);
}
@@ -1234,11 +1364,7 @@ namespace rld
if (!generator_.exit_trace.empty ())
{
l = " " + generator_.exit_trace;
- l = rld::find_replace (l, "@FUNC_NAME@", '"' + sig.name + '"');
- l = rld::find_replace (l, "@FUNC_INDEX@", lss.str ());
- l = rld::find_replace (l, "@FUNC_LABEL@", sig.name);
- l = rld::find_replace (l, "@FUNC_DATA_ENTRY_SIZE@", "FUNC_DATA_ENTRY_SIZE_" + sig.name);
- l = rld::find_replace (l, "@FUNC_DATA_RET_SIZE@", "FUNC_DATA_RET_SIZE_" + sig.name);
+ macro_func_replace (l, sig, lss.str ());
c.write_line(l);
}
@@ -1317,6 +1443,19 @@ namespace rld
c.write_line ("};");
}
+ void
+ tracer::macro_func_replace (std::string& text,
+ const signature& sig,
+ const std::string& index)
+ {
+ text = rld::find_replace (text, "@FUNC_NAME@", '"' + sig.name + '"');
+ text = rld::find_replace (text, "@FUNC_INDEX@", index);
+ text = rld::find_replace (text, "@FUNC_LABEL@", sig.name);
+ text = rld::find_replace (text, "@FUNC_DATA_SIZE@", "FUNC_DATA_SIZE_" + sig.name);
+ text = rld::find_replace (text, "@FUNC_DATA_ENTRY_SIZE@", "FUNC_DATA_ENTRY_SIZE_" + sig.name);
+ text = rld::find_replace (text, "@FUNC_DATA_RET_SIZE@", "FUNC_DATA_RET_SIZE_" + sig.name);
+ }
+
const rld::strings&
tracer::get_traces () const
{