Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/12622

Change subject: systemc: Add some error checks to some classes.
......................................................................

systemc: Add some error checks to some classes.

These check whether those classes are being constructed in legal
circumstances, and avoids a null pointer dereference.

Change-Id: Ied36ee15c3d7bf6ee444351a841c38576780298e
---
M src/systemc/core/sc_export.cc
M src/systemc/core/sc_port.cc
M src/systemc/core/scheduler.cc
M src/systemc/core/scheduler.hh
4 files changed, 76 insertions(+), 4 deletions(-)



diff --git a/src/systemc/core/sc_export.cc b/src/systemc/core/sc_export.cc
index 383552b..252f8c0 100644
--- a/src/systemc/core/sc_export.cc
+++ b/src/systemc/core/sc_export.cc
@@ -29,15 +29,49 @@

 #include "base/logging.hh"
 #include "systemc/core/module.hh"
+#include "systemc/core/scheduler.hh"
 #include "systemc/ext/core/sc_export.hh"
+#include "systemc/ext/core/sc_main.hh"

 namespace sc_core
 {

+namespace
+{
+
+void
+reportError(const char *id, const char *add_msg,
+        const char *name, const char *kind)
+{
+    std::string msg;
+    if (add_msg)
+        msg = csprintf("%s: export '%s' (%s)", add_msg, name, kind);
+    else
+        msg = csprintf("export '%s' (%s)", name, kind);
+
+    SC_REPORT_ERROR(id, msg.c_str());
+}
+
+}
+
 sc_export_base::sc_export_base(const char *n) : sc_object(n)
 {
+    if (sc_is_running()) {
+        reportError("(E121) insert sc_export failed", "simulation running",
+                n, kind());
+    }
+    if (::sc_gem5::scheduler.elaborationDone()) {
+        reportError("(E121) insert sc_export failed", "elaboration done",
+                n, kind());
+    }
+
     ::sc_gem5::Module *m = ::sc_gem5::currentModule();
-    m->exports.push_back(this);
+    if (!m) {
+        reportError("(E122) sc_export specified outside of module",
+                nullptr, n, kind());
+    } else {
+        m->exports.push_back(this);
+    }
 }
 sc_export_base::~sc_export_base() {}

diff --git a/src/systemc/core/sc_port.cc b/src/systemc/core/sc_port.cc
index d10ceea..c822e96 100644
--- a/src/systemc/core/sc_port.cc
+++ b/src/systemc/core/sc_port.cc
@@ -30,16 +30,50 @@
 #include "base/logging.hh"
 #include "systemc/core/bindinfo.hh"
 #include "systemc/core/module.hh"
+#include "systemc/core/scheduler.hh"
+#include "systemc/ext/core/sc_main.hh"
 #include "systemc/ext/core/sc_port.hh"

 namespace sc_core
 {

+namespace
+{
+
+void
+reportError(const char *id, const char *add_msg,
+        const char *name, const char *kind)
+{
+    std::string msg;
+    if (add_msg)
+        msg = csprintf("%s: port '%s' (%s)", add_msg, name, kind);
+    else
+        msg = csprintf("port '%s' (%s)", name, kind);
+
+    SC_REPORT_ERROR(id, msg.c_str());
+}
+
+}
+
 sc_port_base::sc_port_base(const char *name, int n, sc_port_policy p) :
     sc_object(name), _maxSize(n), _size(0), finalized(false)
 {
+    if (sc_is_running()) {
+        reportError("(E110) insert port failed", "simulation running",
+                name, kind());
+    }
+    if (::sc_gem5::scheduler.elaborationDone()) {
+        reportError("(E110) insert port failed", "elaboration done",
+                name, kind());
+    }
+
     ::sc_gem5::Module *m = ::sc_gem5::currentModule();
-    m->ports.push_back(this);
+    if (!m) {
+        reportError("(E100) port specified outside of module",
+                nullptr, name, kind());
+    } else {
+        m->ports.push_back(this);
+    }
 }

 void
diff --git a/src/systemc/core/scheduler.cc b/src/systemc/core/scheduler.cc
index fe00ac0..a0695a3 100644
--- a/src/systemc/core/scheduler.cc
+++ b/src/systemc/core/scheduler.cc
@@ -46,8 +46,8 @@
     stopEvent(this, false, StopPriority),
     scMain(nullptr), _throwToScMain(nullptr),
     starvationEvent(this, false, StarvationPriority),
-    _started(false), _stopNow(false), _status(StatusOther),
-    maxTickEvent(this, false, MaxTickPriority),
+    _elaborationDone(false), _started(false), _stopNow(false),
+    _status(StatusOther), maxTickEvent(this, false, MaxTickPriority),
     _numCycles(0), _changeStamp(0), _current(nullptr), initDone(false),
     runOnce(false), readyList(nullptr)
 {}
diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh
index 0bbc3da..33515ea 100644
--- a/src/systemc/core/scheduler.hh
+++ b/src/systemc/core/scheduler.hh
@@ -338,6 +338,9 @@
         StatusStopped
     };

+    bool elaborationDone() { return _elaborationDone; }
+    void elaborationDone(bool b) { _elaborationDone = b; }
+
     bool paused() { return status() == StatusPaused; }
     bool stopped() { return status() == StatusStopped; }
     bool inDelta() { return status() == StatusDelta; }
@@ -410,6 +413,7 @@
     EventWrapper<Scheduler, &Scheduler::pause> starvationEvent;
     void scheduleStarvationEvent();

+    bool _elaborationDone;
     bool _started;
     bool _stopNow;


--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/12622
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: Ied36ee15c3d7bf6ee444351a841c38576780298e
Gerrit-Change-Number: 12622
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to