From: Clifford Wolf Date: Thu, 24 Jul 2014 13:05:05 +0000 (+0200) Subject: Now using a dedicated ELF section for all coverage counters X-Git-Tag: yosys-0.4~454 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7679000673f7a5c07037dfd3373162cbbcdb0624;p=yosys.git Now using a dedicated ELF section for all coverage counters --- diff --git a/kernel/driver.cc b/kernel/driver.cc index 9749ff305..64165737e 100644 --- a/kernel/driver.cc +++ b/kernel/driver.cc @@ -760,7 +760,7 @@ int main(int argc, char **argv) f = fdopen(mkstemps(filename_buffer, 4), "w"); } else { snprintf(filename_buffer, 4096, "%s", getenv("YOSYS_COVER_FILE")); - f = fopen(filename_buffer, "w"); + f = fopen(filename_buffer, "a+"); } if (f == NULL) @@ -769,11 +769,11 @@ int main(int argc, char **argv) log("\n", filename_buffer); std::map> coverage_data; - for (CoverAgent *p = CoverAgent::first_cover_agent; p; p = p->next_cover_agent) { + for (CoverData *p = __start_yosys_cover_list; p != __stop_yosys_cover_list; p++) { if (coverage_data.count(p->id)) log("WARNING: found duplicate coverage id \"%s\".\n", p->id); coverage_data[p->id].first = stringf("%s:%d:%s", p->file, p->line, p->func); - coverage_data[p->id].second += p->ticks; + coverage_data[p->id].second += p->counter; } for (auto &it : coverage_data) diff --git a/kernel/log.cc b/kernel/log.cc index 26414d493..949bf4327 100644 --- a/kernel/log.cc +++ b/kernel/log.cc @@ -29,8 +29,6 @@ #include #include -CoverAgent *CoverAgent::first_cover_agent = NULL; - std::vector log_files; FILE *log_errfile = NULL; bool log_time = false; diff --git a/kernel/log.h b/kernel/log.h index 517808061..804175909 100644 --- a/kernel/log.h +++ b/kernel/log.h @@ -63,34 +63,31 @@ void log_cell(RTLIL::Cell *cell, std::string indent = ""); #define log_assert(_assert_expr_) do { if (_assert_expr_) break; log_error("Assert `%s' failed in %s:%d.\n", #_assert_expr_, __FILE__, __LINE__); } while (0) #define log_ping() log("-- %s:%d %s --\n", __FILE__, __LINE__, __PRETTY_FUNCTION__) + +// --------------------------------------------------- +// This is the magic behind the code coverage counters +// --------------------------------------------------- + +struct CoverData { + const char *file, *func, *id; + int line, counter; +} __attribute__ ((packed)); + +// this two symbols are created by the linker for the "yosys_cover_list" ELF section +#ifndef NDEBUG +extern "C" struct CoverData __start_yosys_cover_list[]; +extern "C" struct CoverData __stop_yosys_cover_list[]; +#endif + #ifndef NDEBUG # define cover(_id) do { \ - static CoverAgent _cover_agent(__FILE__, __LINE__, __FUNCTION__, _id); \ - _cover_agent.ticks++; \ + static CoverData __d __attribute__((section("yosys_cover_list"), aligned(1))) = { __FILE__, __FUNCTION__, _id, __LINE__, 0 }; \ + __d.counter++; \ } while (0) #else # define cover(_id) do { } while (0) #endif -struct CoverAgent -{ - static struct CoverAgent *first_cover_agent; - struct CoverAgent *next_cover_agent; - - const char *file; - int line; - const char *func; - const char *id; - int ticks; - - CoverAgent(const char *file, int line, const char *func, const char *id) : - file(file), line(line), func(func), id(id), ticks(0) - { - next_cover_agent = first_cover_agent; - first_cover_agent = this; - }; -}; - // ------------------------------------------------------------ // everything below this line are utilities for troubleshooting