rtems-tld: Add entry and exit trace support.

This commit is contained in:
Chris Johns 2014-09-09 08:20:41 +10:00
parent 2126ea7ff0
commit 6fb1409215
4 changed files with 72 additions and 13 deletions

View File

@ -42,6 +42,19 @@ namespace rld
{
}
bool
section::has_record (const std::string& name) const
{
for (records::const_iterator ri = recs.begin ();
ri != recs.end ();
++ri)
{
if ((*ri).name == name)
return true;
}
return false;
}
const record&
section::get_record (const std::string& name) const
{
@ -53,7 +66,7 @@ namespace rld
return *ri;
}
throw error ("not found", "config record: " + this->name + '/' + name);
throw rld::error ("not found", "config record: " + this->name + '/' + name);
}
const std::string

View File

@ -86,6 +86,11 @@ namespace rld
std::string name; //< Name of the section.
records recs; //< The section's records.
/**
* Has the section got a record ?
*/
bool has_record (const std::string& name) const;
/**
* Find a record and throw an error if not found.
*/

View File

@ -135,7 +135,9 @@ namespace rld
std::string name; /**< The name of this wrapper. */
rld::strings headers; /**< Include statements. */
rld::strings defines; /**< Define statements. */
std::string entry_trace; /**< Code template to trace the function entry. */
std::string arg_trace; /**< Code template to trace an argument. */
std::string exit_trace; /**< Code template to trace the function exit. */
std::string ret_trace; /**< Code template to trace the return value. */
rld::strings code; /**< Code block inserted before the trace code. */
@ -440,8 +442,14 @@ namespace rld
parse (config, section, "defines", "define", defines);
parse (config, section, "code-blocks", "code", code, false);
arg_trace = rld::dequote (section.get_record_item ("arg-trace"));
ret_trace = rld::dequote (section.get_record_item ("ret-trace"));
if (section.has_record ("entry-trace"))
entry_trace = rld::dequote (section.get_record_item ("entry-trace"));
if (section.has_record ("arg-trace"))
arg_trace = rld::dequote (section.get_record_item ("arg-trace"));
if (section.has_record ("exit-trace"))
exit_trace = rld::dequote (section.get_record_item ("exit-trace"));
if (section.has_record ("ret-trace"))
ret_trace = rld::dequote (section.get_record_item ("ret-trace"));
}
void
@ -639,6 +647,8 @@ namespace rld
const signature& sig = (*si).second;
c.write_line(sig.decl () + ";");
c.write_line("");
c.write_line(sig.decl ("__wrap_"));
c.write_line("{");
@ -654,17 +664,28 @@ namespace rld
std::string l;
for (size_t a = 0; a < sig.args.size (); ++a)
if (!generator_.entry_trace.empty ())
{
std::string l = ' ' + generator_.arg_trace;
std::string n = rld::to_string ((int) (a + 1));
l = rld::find_replace (l, "@ARG_NUM@", n);
l = rld::find_replace (l, "@ARG_TYPE@", '"' + sig.args[0] + '"');
l = rld::find_replace (l, "@ARG_SIZE@", "sizeof(" + sig.args[0] + ')');
l = rld::find_replace (l, "@ARG_LABEL@", "a" + n);
std::string l = ' ' + generator_.entry_trace;
l = rld::find_replace (l, "@FUNC_NAME@", '"' + sig.name + '"');
l = rld::find_replace (l, "@FUNC_LABEL@", sig.name);
c.write_line(l);
}
if (!generator_.arg_trace.empty ())
{
for (size_t a = 0; a < sig.args.size (); ++a)
{
std::string l = ' ' + generator_.arg_trace;
std::string n = rld::to_string ((int) (a + 1));
l = rld::find_replace (l, "@ARG_NUM@", n);
l = rld::find_replace (l, "@ARG_TYPE@", '"' + sig.args[0] + '"');
l = rld::find_replace (l, "@ARG_SIZE@", "sizeof(" + sig.args[0] + ')');
l = rld::find_replace (l, "@ARG_LABEL@", "a" + n);
c.write_line(l);
}
}
l.clear ();
if (has_ret)
@ -680,7 +701,15 @@ namespace rld
l += ");";
c.write_line(l);
if (has_ret)
if (!generator_.exit_trace.empty ())
{
std::string l = ' ' + generator_.exit_trace;
l = rld::find_replace (l, "@FUNC_NAME@", '"' + sig.name + '"');
l = rld::find_replace (l, "@FUNC_LABEL@", sig.name);
c.write_line(l);
}
if (has_ret && !generator_.ret_trace.empty ())
{
std::string l = ' ' + generator_.ret_trace;
l = rld::find_replace (l, "@RET_TYPE@", '"' + sig.ret + '"');

View File

@ -15,25 +15,37 @@ generator = printf-generator
;
[printf-generator]
headers = printf-generator-headers
entry-trace = "rtld_pg_print_entry(@FUNC_NAME@, (void*) &@FUNC_LABEL@);"
arg-trace = "rtld_pg_print_arg(@ARG_NUM@, @ARG_TYPE@, @ARG_SIZE@, (void*) &@ARG_LABEL@);"
exit-trace = "rtld_pg_print_exit(@FUNC_NAME@, (void*) &@FUNC_LABEL@);"
ret-trace = "rtld_pg_print_ret(@RET_TYPE@, @RET_SIZE@, (void*) &@RET_LABEL@);"
code = <<<CODE
static inline void rtld_pg_print_entry(const char* func_name,
void* func_addr)
{
printf (" >> %s (0x%08x)\n", func_name, func_addr);
}
static inline void rtld_pg_print_arg(int arg_num,
const char* arg_type,
int arg_size,
void* arg)
{
const char* p = arg;
const unsigned char* p = arg;
int i;
printf (" %2d] %s(%d) = ", arg_num, arg_type, arg_size);
for (i = 0; i < arg_size; ++i, ++p) printf ("%02x", (unsigned int) *p);
printf ("\n");
}
static inline void rtld_pg_print_exit(const char* func_name,
void* func_addr)
{
printf (" << %s (0x%08x)\n", func_name, func_addr);
}
static inline void rtld_pg_print_ret(const char* ret_type,
int ret_size,
void* ret)
{
const char* p = ret;
const unsigned char* p = ret;
int i;
printf (" rt] %s(%d) = ", ret_type, ret_size);
for (i = 0; i < ret_size; ++i, ++p) printf ("%02x", (unsigned int) *p);