From 42f6be76c9b79c4501ed766177e634bbe44198d4 Mon Sep 17 00:00:00 2001 From: Chris Johns Date: Tue, 9 Sep 2014 08:20:41 +1000 Subject: rtems-tld: Add entry and exit trace support. --- rld-config.cpp | 15 ++++++++++++++- rld-config.h | 5 +++++ rtems-tld.cpp | 49 +++++++++++++++++++++++++++++++++++++++---------- rtld-base.ini | 16 ++++++++++++++-- 4 files changed, 72 insertions(+), 13 deletions(-) diff --git a/rld-config.cpp b/rld-config.cpp index 3a372ad..c106120 100644 --- a/rld-config.cpp +++ b/rld-config.cpp @@ -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 diff --git a/rld-config.h b/rld-config.h index 52153d2..4bcb964 100644 --- a/rld-config.h +++ b/rld-config.h @@ -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. */ diff --git a/rtems-tld.cpp b/rtems-tld.cpp index 8e3d7c7..ea9518c 100644 --- a/rtems-tld.cpp +++ b/rtems-tld.cpp @@ -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 + '"'); diff --git a/rtld-base.ini b/rtld-base.ini index b15f4cd..badb40d 100644 --- a/rtld-base.ini +++ b/rtld-base.ini @@ -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 = <<> %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); -- cgit v1.2.3