From f7a2c41be0e94a308da30c685a88006a763bb93f Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 11 Sep 2018 16:16:49 -0700 Subject: [PATCH] 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 Maintainer: Gabe Black --- src/systemc/core/sc_export.cc | 36 ++++++++++++++++++++++++++++++++++- src/systemc/core/sc_port.cc | 36 ++++++++++++++++++++++++++++++++++- src/systemc/core/scheduler.cc | 4 ++-- src/systemc/core/scheduler.hh | 4 ++++ 4 files changed, 76 insertions(+), 4 deletions(-) diff --git a/src/systemc/core/sc_export.cc b/src/systemc/core/sc_export.cc index 383552b1a..252f8c0ff 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 d10ceeab3..c822e966e 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 fe00ac0f8..a0695a395 100644 --- a/src/systemc/core/scheduler.cc +++ b/src/systemc/core/scheduler.cc @@ -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) {} diff --git a/src/systemc/core/scheduler.hh b/src/systemc/core/scheduler.hh index 0bbc3dac6..33515ea43 100644 --- a/src/systemc/core/scheduler.hh +++ b/src/systemc/core/scheduler.hh @@ -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 starvationEvent; void scheduleStarvationEvent(); + bool _elaborationDone; bool _started; bool _stopNow; -- 2.30.2