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
Reviewed-on: https://gem5-review.googlesource.com/c/12622
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
Gabe Black
2018-09-11 16:16:49 -07:00
parent 1f23ce702a
commit f7a2c41be0
4 changed files with 76 additions and 4 deletions

View File

@@ -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() {}

View File

@@ -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

View File

@@ -46,8 +46,8 @@ Scheduler::Scheduler() :
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)
{}

View File

@@ -338,6 +338,9 @@ class Scheduler
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 @@ class Scheduler
EventWrapper<Scheduler, &Scheduler::pause> starvationEvent;
void scheduleStarvationEvent();
bool _elaborationDone;
bool _started;
bool _stopNow;