Now using a dedicated ELF section for all coverage counters
authorClifford Wolf <clifford@clifford.at>
Thu, 24 Jul 2014 13:05:05 +0000 (15:05 +0200)
committerClifford Wolf <clifford@clifford.at>
Thu, 24 Jul 2014 13:05:05 +0000 (15:05 +0200)
kernel/driver.cc
kernel/log.cc
kernel/log.h

index 9749ff305aa5c7e66a6a6a0647b0ecaecd358181..64165737eac6338a9859e77f6a21379cdaf849a2 100644 (file)
@@ -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("<writing coverage file \"%s\">\n", filename_buffer);
 
                std::map<std::string, std::pair<std::string, int>> 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)
index 26414d49341a5b9035fe5f4373846e1abb00dbd4..949bf43275fd1c5e56937317acb50acc2bf57bca 100644 (file)
@@ -29,8 +29,6 @@
 #include <vector>
 #include <list>
 
-CoverAgent *CoverAgent::first_cover_agent = NULL;
-
 std::vector<FILE*> log_files;
 FILE *log_errfile = NULL;
 bool log_time = false;
index 517808061a7a73cc8d491358c53b659704200fec..804175909c3e4bd266814c741a4593625a6c86f2 100644 (file)
@@ -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