summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2014-07-24 15:05:05 +0200
committerClifford Wolf <clifford@clifford.at>2014-07-24 15:05:05 +0200
commit7679000673f7a5c07037dfd3373162cbbcdb0624 (patch)
treeb8e9d2c112efbafa6f2cff69ac101d5e5d33b661
parent22ede43b3f5016784b2e22c0ea95b7f718d7598e (diff)
Now using a dedicated ELF section for all coverage counters
-rw-r--r--kernel/driver.cc6
-rw-r--r--kernel/log.cc2
-rw-r--r--kernel/log.h39
3 files changed, 21 insertions, 26 deletions
diff --git a/kernel/driver.cc b/kernel/driver.cc
index 9749ff30..64165737 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("<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)
diff --git a/kernel/log.cc b/kernel/log.cc
index 26414d49..949bf432 100644
--- a/kernel/log.cc
+++ b/kernel/log.cc
@@ -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;
diff --git a/kernel/log.h b/kernel/log.h
index 51780806..80417590 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