ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Fault.cpp
Go to the documentation of this file.
1/*
2
3 @copyright
4
5 <pre>
6
7 Copyright 2018 Infineon Technologies AG
8
9 This file is part of ETISS tool, see <https://github.com/tum-ei-eda/etiss>.
10
11 The initial version of this software has been created with the funding support by the German Federal
12 Ministry of Education and Research (BMBF) in the project EffektiV under grant 01IS13022.
13
14 Redistribution and use in source and binary forms, with or without modification, are permitted
15 provided that the following conditions are met:
16
17 1. Redistributions of source code must retain the above copyright notice, this list of conditions and
18 the following disclaimer.
19
20 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
21 and the following disclaimer in the documentation and/or other materials provided with the distribution.
22
23 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse
24 or promote products derived from this software without specific prior written permission.
25
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
27 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
28 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
29 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 POSSIBILITY OF SUCH DAMAGE.
34
35 </pre>
36
37 @author Chair of Electronic Design Automation, TUM
38
39 @version 0.1
40
41*/
42
43#ifndef NO_ETISS
44#include "etiss/fault/Fault.h"
45#include "etiss/fault/Trigger.h"
48#else
49#include "fault/Fault.h"
50#include "fault/Trigger.h"
51#include "fault/Injector.h"
52#include "fault/xml/pugixml.hpp"
53#endif
54
55#if MUTEX_SUPPORTED
56#include <mutex>
57#endif
58
59#if CXX0X_UP_SUPPORTED == 0
60#define static_assert(x, y)
61#endif
62
63namespace etiss
64{
65namespace fault
66{
67
68// Helper for XML parsing and generating
69namespace xml
70{
71
110static bool getAttribute(const pugi::xml_node &node, const std::string &attr_name, std::string &dst, Diagnostics &diag)
111{
112 bool first = true;
113 for (pugi::xml_attribute attr = node.first_attribute(); attr; attr = attr.next_attribute())
114 {
115 if (hasName(attr, attr_name))
116 {
117 if (first)
118 {
119 dst = attr.value();
120 first = false;
121 }
122 else
123 {
124 diag.unexpectedNode(node, std::string("Duplicated attribute: ") + attr_name);
125 }
126 }
127 }
128 return !first;
129}
130static bool setAttribute(pugi::xml_node &node, const std::string &attr_name, const std::string &src, Diagnostics &diag)
131{
132 node.append_attribute(attr_name.c_str()).set_value(src.c_str());
133 return true;
134}
135static bool getAttribute(const pugi::xml_node &node, const std::string &attr_name, int32_t &dst, Diagnostics &diag)
136{
137 std::string val;
138 if (!getAttribute(node, attr_name, val, diag))
139 return false;
140 std::stringstream(val) >> dst;
141 return true;
142}
143static bool setAttribute(pugi::xml_node &node, const std::string &attr_name, const int32_t &src, Diagnostics &diag)
144{
145 static_assert(sizeof(int32_t) <= sizeof(long long),
146 "pugixml cannot handle int32_t natively. custom string conversion required");
147 node.append_attribute(attr_name.c_str()).set_value((long long)src);
148 return true;
149}
150
151template <>
152bool parse<std::vector<etiss::fault::Fault>>(pugi::xml_node node, std::vector<etiss::fault::Fault> &dst,
153 Diagnostics &diag)
154{
155 etiss::log(etiss::VERBOSE, std::string("etiss::fault::xml::parse<std::vector<etiss::fault::Fault") +
156 std::string("> >(node, vector<Fault>, Diagnostics) called. "));
157
158 bool ret = true;
159 for (pugi::xml_node cnode = node.first_child(); cnode; cnode = cnode.next_sibling())
160 {
161 if (hasName(cnode, "fault"))
162 { // handle fault node
163 Fault f;
164 if (parse<etiss::fault::Fault>(cnode, f, diag))
165 {
166 dst.push_back(f);
167 }
168 else
169 {
170 ret = false;
171 }
172 }
173 else
174 {
175 diag.ignoredNode(cnode, "non \"fault\" node in fault list.");
176 }
177 }
178 return ret;
179}
180
181template <>
182bool write<std::vector<etiss::fault::Fault>>(pugi::xml_node node, const std::vector<etiss::fault::Fault> &src,
183 Diagnostics &diag)
184{
185 etiss::log(etiss::VERBOSE, std::string("etiss::fault::xml::write<std::vector<etiss::fault::Fault") +
186 std::string("> >(node, vector<Fault>, Diagnostics) called. "));
187
188 bool ret = true;
189 for (size_t i = 0; i < src.size(); ++i)
190 {
191 ret = ret && write(node.append_child("fault"), src[i], diag);
192 }
193 return ret;
194}
195
196} // namespace xml
197
198// generates a unique ID for a new Fault
200{
201#if MUTEX_SUPPORTED
202 static std::mutex mu;
203 std::lock_guard<std::mutex> lock(mu);
204#endif
205 static int32_t cid = -1;
206 return cid--;
207}
209{
210 etiss::log(etiss::VERBOSE, std::string("etiss::fault::Fault::Fault() called. "));
211 id_ = uniqueFaultId();
212}
213std::string Fault::toString() const
214{
215
217 doc.load("<?xml version=\"1.0\"?>");
218
219 etiss::fault::xml::Diagnostics diag;
220
221 etiss::fault::xml::write<etiss::fault::Fault>(doc.append_child("fault"), *this, diag);
222
223 std::stringstream ss;
224
225 doc.save(ss);
226
227 return ss.str();
228}
229
231{
232 etiss::log(etiss::VERBOSE, std::string("etiss::fault::Fault::resolveTime(time=") + std::to_string(time) +
233 std::string(") called. "));
234 for (std::vector<Trigger>::iterator iter = triggers.begin(); iter != triggers.end(); ++iter)
235 {
236 iter->resolveTime(time);
237 }
238}
240{
241 for (std::vector<Trigger>::const_iterator iter = triggers.begin(); iter != triggers.end(); ++iter)
242 {
243 if (!iter->isResolved())
244 return false;
245 }
246 return true;
247}
248
249#if ETISS_FAULT_XML
250
251bool parseXML(std::vector<Fault> &vec, std::istream &input, std::ostream &diagnostics_out)
252{
253
254 pugi::xml_document doc; // xml document
255
256 pugi::xml_parse_result pr = doc.load(input); // load from stream
257
258 if (!pr)
259 { // load failure
260 diagnostics_out << "failed to load xml from stream: " << pr.description() << std::endl;
261 return false;
262 }
263
264 etiss::fault::xml::Diagnostics diag;
265
266 bool ret = parse(doc.document_element(), vec, diag); // parse document
267
268 diag.print(diagnostics_out);
269
270 return ret;
271}
272
273bool writeXML(const std::vector<Fault> &vec, std::ostream &out, std::ostream &diagnostics_out)
274{
276
277 doc.load("<?xml version=\"1.0\"?>");
278
279 etiss::fault::xml::Diagnostics diag;
280
281 bool ret = write(doc.append_child("faults"), vec, diag); // write document
282
283 doc.save(out);
284
285 diag.print(diagnostics_out);
286
287 return ret;
288}
289
290namespace xml
291{
292
293template <>
294bool parse<etiss::fault::Fault>(pugi::xml_node node, etiss::fault::Fault &f, Diagnostics &diag)
295{
296 etiss::log(etiss::VERBOSE, std::string("etiss::fault::xml::parse<etiss::fault::Fault>") +
297 std::string("(node, Fault, Diagnostics) called. "));
298 bool ret = true;
299 /*ret = ret &*/ getAttribute(node, "name", f.name_, diag); // optional
300 /*ret = ret &*/ getAttribute(node, "id_", f.id_, diag); // optional
301 for (pugi::xml_node cnode = node.first_child(); cnode; cnode = cnode.next_sibling())
302 {
303 if (hasName(cnode, "triggers"))
304 {
305 for (pugi::xml_node ccnode = cnode.first_child(); ccnode; ccnode = ccnode.next_sibling())
306 {
307 if (hasName(ccnode, "trigger"))
308 {
310 if (parse<etiss::fault::Trigger>(ccnode, t, diag))
311 {
312 f.triggers.push_back(t);
313 }
314 else
315 {
316 ret = false;
317 }
318 }
319 else
320 {
321 diag.ignoredNode(ccnode, "\"trigger\" node expected");
322 }
323 }
324 }
325 else if (hasName(cnode, "actions"))
326 {
327 for (pugi::xml_node ccnode = cnode.first_child(); ccnode; ccnode = ccnode.next_sibling())
328 {
329 if (hasName(ccnode, "action"))
330 {
332 if (parse<etiss::fault::Action>(ccnode, t, diag))
333 {
334 f.actions.push_back(t);
335 }
336 else
337 {
338 ret = false;
339 }
340 }
341 else
342 {
343 diag.ignoredNode(ccnode, "\"trigger\" node expected");
344 }
345 }
346 }
347 else
348 {
349 diag.ignoredNode(cnode, "unknown node");
350 }
351 }
352
353 return ret;
354}
355template <>
356bool write<etiss::fault::Fault>(pugi::xml_node node, const etiss::fault::Fault &f, Diagnostics &diag)
357{
358 etiss::log(etiss::VERBOSE, std::string("etiss::fault::xml::write<etiss::fault::Fault>") +
359 std::string("(node, Fault, Diagnostics) called. "));
360 bool ok = true;
361 ok = ok && setAttribute(node, "name", f.name_, diag);
362 ok = ok && setAttribute(node, "id", f.id_, diag);
363 pugi::xml_node triggers = node.append_child("triggers");
364 for (std::vector<etiss::fault::Trigger>::const_iterator iter = f.triggers.begin(); iter != f.triggers.end(); ++iter)
365 {
366 ok = ok && write<etiss::fault::Trigger>(triggers.append_child("trigger"), *iter, diag);
367 }
368 pugi::xml_node actions = node.append_child("actions");
369 for (std::vector<etiss::fault::Action>::const_iterator iter = f.actions.begin(); iter != f.actions.end(); ++iter)
370 {
371 ok = ok && write<etiss::fault::Action>(actions.append_child("action"), *iter, diag);
372 }
373 return ok;
374}
375
376} // namespace xml
377
378#endif
379
380} // namespace fault
381} // namespace etiss
contains the fault container class that stores triggers and actions for fault injection
contains the fault injector interface class.
contains the Trigger class that defines conditions under which actions of a Fault need to be applied.
static __inline__ uint64_t
Definition arm_cde.h:31
static __inline__ int32_t
Definition arm_mve.h:51
bool isResoved() const
check all Triggers if they are resolved.
Definition Fault.cpp:239
Fault()
Constructor: Generates a new Fault with unique ID.
Definition Fault.cpp:208
std::string toString() const
operator<< can be used.
Definition Fault.cpp:213
std::string name_
Definition Fault.h:98
void resolveTime(uint64_t time)
Resolves time for all its Triggers.
Definition Fault.cpp:230
std::vector< Trigger > triggers
contains the triggers for this fault
Definition Fault.h:100
std::vector< Action > actions
contains the actions for this fault
Definition Fault.h:101
bool set_value(const char_t *rhs)
Definition pugixml.cpp:4507
xml_node document_element() const
Definition pugixml.cpp:6186
xml_parse_result load(std::basic_istream< char, std::char_traits< char > > &stream, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
Definition pugixml.cpp:6051
void save(xml_writer &writer, const char_t *indent=PUGIXML_TEXT("\t"), unsigned int flags=format_default, xml_encoding encoding=encoding_auto) const
Definition pugixml.cpp:6125
xml_node append_child(xml_node_type type=node_element)
Definition pugixml.cpp:4983
xml_node first_child() const
Definition pugixml.cpp:4797
xml_attribute append_attribute(const char_t *name)
Definition pugixml.cpp:4837
xml_node next_sibling() const
Definition pugixml.cpp:4715
xml_attribute first_attribute() const
Definition pugixml.cpp:4787
static bool setAttribute(pugi::xml_node &node, const std::string &attr_name, const std::string &src, Diagnostics &diag)
Definition Fault.cpp:130
static bool getAttribute(const pugi::xml_node &node, const std::string &attr_name, std::string &dst, Diagnostics &diag)
Parser/writer structure:
Definition Fault.cpp:110
static int32_t uniqueFaultId()
Definition Fault.cpp:199
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
Definition Benchmark.h:53
@ VERBOSE
Definition Misc.h:130
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition Misc.cpp:125
const char * description() const
Definition pugixml.cpp:5913