ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
VirtualStruct.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 #include "etiss/VirtualStruct.h"
44 
45 namespace etiss
46 {
47 
49 
50 VirtualStruct::Field::Field(VirtualStruct &parent, const std::string &name, const std::string &prettyname, int flags,
51  size_t width, size_t bitwidth)
52  : parent_(parent)
53  , name_(name)
54  , prettyname_(prettyname)
55  , flags_(flags)
56  , width_(width)
57  , bitwidth_(bitwidth ? bitwidth : width * 8)
59 {
60 }
61 
62 VirtualStruct::Field::Field(VirtualStruct &parent, const std::string &name, const std::string &prettyname, int flags,
63  size_t width, bool virtual_enabled, std::function<uint64_t()> lread,
64  std::function<void(uint64_t)> lwrite, size_t bitwidth)
65  : parent_(parent)
66  , name_(name)
67  , prettyname_(prettyname)
68  , flags_(flags)
69  , width_(width)
70  , bitwidth_(bitwidth ? bitwidth : width * 8)
71  , accessMode_(virtual_enabled ? VirtualStruct::Field::PREFER_LAMBDA : VirtualStruct::Field::LAMBDA)
72  , lread(lread)
73  , lwrite(lwrite)
74 {
75 }
76 
78 
80 {
81 
82  if (!(flags_ & R))
83  std::runtime_error("VirtualStruct::Field::write called but the write flag is not set");
84 
85  uint64_t ret;
86  switch (accessMode_)
87  {
88  case LAMBDA:
89  if (lread)
90  {
91  ret = lread();
92  }
93  else
94  {
95  throw std::runtime_error(
96  "VirtualStruct is configured to use lambda expressions but no read function was provided.");
97  }
98  break;
99  case PREFER_LAMBDA:
100  if (lread)
101  {
102  ret = lread();
103  break;
104  }
105  case VIRTUAL:
106  ret = _read();
107  break;
108  default:
109  throw std::runtime_error("invalid enum value");
110  }
111  // call listeners
112 
113  return ret;
114 }
116 {
117 
118  if (!(flags_ & W))
119  throw std::runtime_error("VirtualStruct::Field::write called but the write flag is not set");
120 
121  if (accessMode_ == LAMBDA && !lwrite) // throw error before calling listeners
122  throw std::runtime_error(
123  "VirtualStruct is configured to use lambda expressions but no read function was provided.");
124 
125  switch (accessMode_)
126  {
127  case LAMBDA:
128  if (lwrite)
129  {
130  lwrite(val);
131  }
132  else
133  {
134  // throw std::runtime_error("VirtualStruct is configured to use lambda expressions but no read function was
135  // provided."); moved to start of function
136  }
137  break;
138  case PREFER_LAMBDA:
139  if (lwrite)
140  {
141  lwrite(val);
142  break;
143  }
144  case VIRTUAL:
145  _write(val);
146  break;
147  }
148 
149  signalWrite();
150 }
151 
153 {
154  for (auto l : listeners)
155  {
156  if (l.first)
157  {
158  l.first->write(*this, read());
159  }
160  }
161 }
162 
163 bool VirtualStruct::Field::applyBitflip(unsigned position, uint64_t fault_id)
164 {
165  if (!(flags_ & F))
166  return false;
167 
168  switch (accessMode_)
169  {
170  case LAMBDA:
171  case PREFER_LAMBDA:
172  case VIRTUAL:
173  return _applyBitflip(position, fault_id);
174  }
175  return false;
176 }
177 
179  std::string &errormsg)
180 {
181  if (!(flags_ & A))
182  {
183  errormsg = "field doesn't support advanced action handling";
184  return false;
185  }
186  return _applyAction(f, a, errormsg);
187 }
188 
190 {
191  throw std::runtime_error("VirtualStruct::Field::_read called but not implemented");
192 }
194 {
195  throw std::runtime_error("VirtualStruct::Field::_write called but not implemented");
196 }
197 bool VirtualStruct::Field::_applyBitflip(unsigned position, uint64_t fault_id)
198 {
199  if (!(flags_ & F))
200  return false;
201  if (lapplyBitflip)
202  return lapplyBitflip(position, fault_id);
203  if ((flags_ & RW) != RW)
204  return false;
205  uint64_t val = read();
206  uint64_t errval = ((uint64_t)1) << position;
207  errval = val ^ errval;
208  write(errval);
209  std::stringstream ss;
210  ss << "Injected bitflip in " << name_ << " 0x" << std::hex << val << "->0x" << errval << std::dec;
211  etiss::log(etiss::INFO, ss.str());
212  return true;
213 }
215  std::string &errormsg)
216 {
217  return false;
218 }
219 
220 bool VirtualStruct::Field::addListener(Listener *listener, std::shared_ptr<Listener> ref)
221 {
222  if (!(flags_ & Field::L))
223  return false;
224  listeners.insert(std::pair<Listener *, std::shared_ptr<Listener>>(listener, ref));
225  return true;
226 }
227 void VirtualStruct::Field::removeListener(Listener *listener, std::shared_ptr<Listener> ref)
228 {
229  listeners.erase(std::pair<Listener *, std::shared_ptr<Listener>>(listener, ref));
230 }
231 
232 VirtualStruct::VirtualStruct(void *structure, std::function<void(Field *)> dtor)
233  : structure_(structure), dtor_(dtor), closed(false)
234 {
235 }
237 {
238  close(); // VSSync is locked in close. IF THIS CHANGES VSSync MUST BE INSTANTIATED HERE
239  for (auto iter = fields_.begin(); iter != fields_.end(); ++iter)
240  {
241  if (*iter)
242  {
243  if ((*iter)->delete_)
244  {
245  std::function<void(Field *)> del_ = (*iter)->delete_;
246  del_(*iter);
247  }
248  else
249  {
250  if (dtor_)
251  {
252  dtor_(*iter);
253  }
254  else
255  {
256  etiss::log(etiss::ERROR, "The delete function passed to etiss::VirtualStruct is null. This will "
257  "likely result in a memory leak.");
258  }
259  }
260  }
261  }
262 }
263 
265 {
266 
267  if (f == 0)
268  {
269  if (!noerrorprint)
270  etiss::log(etiss::VERBOSE, "NULL pointer passed to etiss::VirtualStruct::addField", ETISS_SRCLOC);
271  return false;
272  }
273 
274  if (f->name_.empty())
275  {
276  if (!noerrorprint)
277  etiss::log(etiss::ERROR, "Failed to add an field to etiss::VirtualStruct due to empty name", f->name_,
279  return false;
280  }
281  if (fieldNames_.find(f->name_) != fieldNames_.end())
282  {
283  if (!noerrorprint)
284  etiss::log(etiss::ERROR, "Failed to add an field to etiss::VirtualStruct due to duplicated name", f->name_,
286  return false;
287  }
288  if ((!f->prettyname_.empty()) && (fieldPrettyNames_.find(f->prettyname_) != fieldPrettyNames_.end()))
289  {
290  if (!noerrorprint)
291  etiss::log(etiss::ERROR, "Failed to add an field to etiss::VirtualStruct due to duplicated prettyname",
292  f->name_, f->prettyname_, ETISS_SRCLOC);
293  return false;
294  }
295 
296  fields_.push_back(f);
297  fieldNames_.insert(std::make_pair(f->name_, f));
298  if (!f->prettyname_.empty())
299  fieldPrettyNames_.insert(std::make_pair(f->prettyname_, f));
300  return true;
301 }
302 
303 std::shared_ptr<VirtualStruct::Field> VirtualStruct::findName(const std::string &name) const
304 {
305  VSSync lock;
306  if (closed)
307  return 0;
308 
309  auto find = fieldNames_.find(name);
310  if (find != fieldNames_.end())
311  {
312  std::shared_ptr<const VirtualStruct> pref = shared_from_this();
313  return std::shared_ptr<VirtualStruct::Field>(find->second, [pref](VirtualStruct::Field *) {});
314  }
315  return std::shared_ptr<VirtualStruct::Field>();
316 }
317 std::shared_ptr<VirtualStruct::Field> VirtualStruct::findPrettyName(const std::string &name) const
318 {
319  VSSync lock;
320  if (closed)
321  return 0;
322  auto find = fieldPrettyNames_.find(name);
323  if (find != fieldPrettyNames_.end())
324  {
325  std::shared_ptr<const VirtualStruct> pref = shared_from_this();
326  return std::shared_ptr<VirtualStruct::Field>(find->second, [pref](VirtualStruct::Field *) {});
327  }
328  return 0;
329 }
330 void VirtualStruct::foreachField(const std::function<void(std::shared_ptr<Field>)> &func)
331 {
332  VSSync lock;
333  if (closed)
334  return;
335  std::shared_ptr<const VirtualStruct> pref = shared_from_this();
336  for (Field *f : fields_)
337  {
338  func(std::shared_ptr<Field>(f, [pref](VirtualStruct::Field *) {}));
339  }
340 }
342 {
344  {
345  return acceleratedTrigger_(t, fault_id);
346  }
347  else
348  {
349  }
350  return false;
351 }
352 bool VirtualStruct::mountStruct(const std::string &name, std::shared_ptr<VirtualStruct> vs)
353 {
354  if (!vs)
355  return false;
356  VSSync lock;
357  // check for existing
358  {
359  auto find = subStructs_.find(name);
360  if (find != subStructs_.end())
361  {
362  if (find->second.lock())
363  {
364  return false;
365  }
366  }
367  }
368  if (vs->parent_) // already mounted elsewere
369  return false;
370  vs->parent_ = shared_from_this();
371  subStructs_.insert(std::pair<std::string, std::weak_ptr<VirtualStruct>>(name, vs));
372  return true;
373 }
374 std::shared_ptr<VirtualStruct> VirtualStruct::findStruct(const std::string &name)
375 {
376  VSSync lock;
377  auto find = subStructs_.find(name);
378  if (find != subStructs_.end())
379  return find->second.lock();
380  return std::shared_ptr<VirtualStruct>();
381 }
382 void VirtualStruct::foreachStruct(const std::function<void(const std::string &name, VirtualStruct &vs)> &func)
383 {
384  VSSync lock;
385  for (auto e : subStructs_)
386  {
387  auto sp = e.second.lock();
388  auto p = sp.get();
389  if (p)
390  {
391  func(e.first, *p);
392  }
393  }
394 }
395 
397 {
398  VSSync lock;
399  closed = true;
400  // dont't delete fields here.
401 }
403 {
404  VSSync lock;
405  return closed;
406 }
407 
408 std::list<std::string> VirtualStruct::listFields()
409 {
410  std::list<std::string> ret;
411  foreachField([&ret](std::shared_ptr<Field> f) {
412  if (f)
413  ret.push_back(f->name_);
414  });
415  return ret;
416 }
417 std::list<std::string> VirtualStruct::listSubInjectors()
418 {
419  std::list<std::string> ret;
420  foreachStruct([&ret](const std::string &name, VirtualStruct &vs) { ret.push_back(name); });
421  return ret;
422 }
423 
424 std::shared_ptr<etiss::fault::Injector> VirtualStruct::getSubInjector(const std::string &name)
425 {
426  return findStruct(name);
427 }
428 std::shared_ptr<etiss::fault::Injector> VirtualStruct::getParentInjector()
429 {
430  return parent_;
431 }
432 
433 void *VirtualStruct::fastFieldAccessPtr(const std::string &name, std::string &errormsg)
434 {
435  VSSync lock;
436  {
437  auto iter = fieldNames_.find(name);
438  if (iter != fieldNames_.end())
439  return iter->second;
440  }
441  {
442  auto iter = fieldPrettyNames_.find(name);
443  if (iter != fieldPrettyNames_.end())
444  return iter->second;
445  }
446  return 0;
447 }
448 bool VirtualStruct::readField(void *fastfieldaccessptr, uint64_t &val, std::string &errormsg)
449 {
450  Field *f = (Field *)fastfieldaccessptr;
451  if (!f)
452  {
453  errormsg = "No such field";
454  return false;
455  }
456  if (!(f->flags_ & Field::R))
457  {
458  errormsg = "No read access";
459  return false;
460  }
461  val = f->read();
462  return true;
463 }
465  std::string &errormsg)
466 {
467  switch (action.getType())
468  {
469  case etiss::fault::Action::COMMAND: // handle command
470  {
471  if (!applyCustomAction)
472  {
473  errormsg = getInjectorPath() +
474  ": VirtualStruct::applyCustomAction function not set. cannot handle custom actions.";
475  return false;
476  }
477  return applyCustomAction(fault, action, errormsg);
478  }
479  case etiss::fault::Action::BITFLIP: // handle bitflip
480  {
481  Field *f;
482  auto find = fieldNames_.find(action.getTargetField());
483  if (find == fieldNames_.end())
484  {
485  find = fieldPrettyNames_.find(action.getTargetField());
486  if (find == fieldPrettyNames_.end())
487  {
488  f = 0;
489  }
490  else
491  {
492  f = find->second;
493  }
494  }
495  else
496  {
497  f = find->second;
498  }
499 
500  if (!f)
501  {
502  errormsg = std::string("No such field: ") + getInjectorPath() + "." + action.getTargetField();
503  return false;
504  }
505  if (f->flags_ & Field::A)
506  {
507  return f->applyAction(fault, action, errormsg);
508  }
509  else if (f->flags_ & Field::F)
510  {
511  return f->applyBitflip(action.getTargetBit(), fault.id_);
512  }
513  }
514  return false;
515  default:
516  return false;
517  }
518 }
519 
521 {
522  mutex().lock();
523 }
525 {
526  mutex().unlock();
527 }
528 std::recursive_mutex &VSSync::mutex()
529 {
530  static std::recursive_mutex mu;
531  return mu;
532 }
533 
534 void copy(VirtualStruct &dst, VirtualStruct &src, std::list<std::shared_ptr<VirtualStruct::Field>> &notPresent,
535  std::list<std::shared_ptr<VirtualStruct::Field>> &notWriteable,
536  std::list<std::shared_ptr<VirtualStruct::Field>> unknown, bool pretend,
537  std::list<std::shared_ptr<VirtualStruct::Field>> *src_private,
538  std::list<std::shared_ptr<VirtualStruct::Field>> *dst_private)
539 {
540 
541  []() {}();
542 
543  std::set<std::shared_ptr<VirtualStruct::Field>> dst_known;
544 
545  src.foreachField([&](std::shared_ptr<VirtualStruct::Field> srcf) {
546  if (srcf->flags_ & VirtualStruct::Field::P)
547  {
548  if (src_private)
549  src_private->push_back(srcf);
550  return;
551  }
552 
553  auto dstf = dst.findName(srcf->name_);
554  if (dstf == 0)
555  {
556  notPresent.push_back(srcf);
557  return;
558  }
559 
560  if (dstf->flags_ & VirtualStruct::Field::P)
561  {
562  notPresent.push_back(srcf);
563  return;
564  }
565 
566  dst_known.insert(dstf);
567 
568  if (!(dstf->flags_ & VirtualStruct::Field::W))
569  {
570  notWriteable.push_back(dstf);
571  return;
572  }
573 
574  if (!pretend)
575  dstf->write(srcf->read()); // copy value
576  });
577 
578  dst.foreachField([&](std::shared_ptr<VirtualStruct::Field> dstf) {
579  if (dst_known.find(dstf) == dst_known.end())
580  {
581  if (dstf->flags_ & VirtualStruct::Field::P)
582  {
583  if (dst_private)
584  {
585  dst_private->push_back(dstf);
586  }
587  }
588  else
589  {
590  unknown.push_back(dstf);
591  }
592  }
593  });
594 }
595 
596 std::shared_ptr<VirtualStruct> VirtualStruct::allocate(void *structure, std::function<void(Field *)> delete_)
597 {
598  VirtualStruct *ret = new VirtualStruct(structure, delete_);
599 
600  return std::shared_ptr<VirtualStruct>(ret, [](VirtualStruct *vs) { delete vs; });
601 }
602 
603 std::shared_ptr<VirtualStruct> VirtualStruct::root()
604 {
605  static std::shared_ptr<VirtualStruct> r = allocate(0, [](Field *) {});
606  return r;
607 }
608 
609 std::shared_ptr<VirtualStruct> VirtualStruct::getVirtualStruct(const std::string &path)
610 {
611  if (path.empty())
612  return shared_from_this();
613  std::shared_ptr<VirtualStruct> ret;
614  if (path.find_first_of(".") != std::string::npos)
615  {
616  // error
617  return ret;
618  }
619  auto pp1 = path.find("::");
620 
621  if (pp1 == 0) // absolute path
622  {
623  auto ptr = parent_;
624  auto prev = shared_from_this();
625  while (ptr)
626  {
627  prev = ptr;
628  ptr = ptr->parent_;
629  }
630  return prev->getVirtualStruct(path.substr(pp1 + 2));
631  }
632 
633  {
634  VSSync lock;
635  auto find = subStructs_.find((pp1 == std::string::npos) ? path : path.substr(0, pp1));
636  if (find != subStructs_.end())
637  {
638  ret = find->second.lock();
639  }
640  }
641 
642  if (!ret)
643  return ret;
644 
645  if (pp1 == std::string::npos)
646  {
647  return ret;
648  }
649  else
650  {
651  return ret->getVirtualStruct(path.substr(pp1 + 2));
652  }
653 }
654 
655 std::shared_ptr<etiss::fault::Injector> etiss::fault::Injector::get(const std::string &path)
656 {
657  return std::shared_ptr<etiss::fault::Injector>(VirtualStruct::root()->getVirtualStruct(path));
658 }
659 
660 std::shared_ptr<VirtualStruct::Field> VirtualStruct::getResolvedField(const std::string &path)
661 {
662  auto pp1 = path.find_first_of(".");
663  if (pp1 == std::string::npos) // if no point exists the this is not a path
664  return std::shared_ptr<VirtualStruct::Field>();
665 
666  auto m = getVirtualStruct(path.substr(0, pp1));
667  if (!m)
668  return std::shared_ptr<VirtualStruct::Field>();
669 
670  auto ret = m->findName(path.substr(pp1 + 1));
671  if (!ret)
672  ret = m->findPrettyName(path.substr(pp1 + 1));
673 
674  return ret;
675 }
676 
677 } // namespace etiss
#define ETISS_SRCLOC
Definition: Misc.h:239
static __inline__ uint64_t
Definition: arm_cde.h:31
static __inline__ int32_t
Definition: arm_mve.h:51
used for synchronization of the tree of virtual structs.
static std::recursive_mutex & mutex()
NOTE: etiss::CPUArch should implement support for Listeners by either using the etiss::VirtualStruct:...
a Field instance represents e.g.
static const int W
write flag
Field(VirtualStruct &parent, const std::string &name, const std::string &prettyname, int flags, size_t width, size_t bitwidth=0)
@ VIRTUAL
uses the virtual _read() / _write functions
bool applyAction(const etiss::fault::Fault &f, const etiss::fault::Action &a, std::string &errormsg)
advanced fault injection. Field must have the A flag to use this.
static const int A
supports advanced fault injection/tracing with the applyAction function
const std::string name_
name of the field.
virtual bool _applyBitflip(unsigned position, uint64_t fault_id)
override this function to implement bitflip applying to a field
const size_t width_
width in bytes (rounded up if neccessary)
void signalWrite()
this function should be called if the listener flag is set and the field changed without using the wr...
void removeListener(Listener *listener, std::shared_ptr< Listener > ref=nullptr)
static const int L
supports listener plugins; used for etiss::RegisterDevicePlugins to determine access to a variable/fi...
virtual uint64_t _read() const
override this function to implement reads in case of AccessMode::VIRTUAL / AccessMode::PREFER_LAMBDA
VirtualStruct & parent_
reference to parent virtual struct
bool addListener(Listener *listener, std::shared_ptr< Listener > ref=nullptr)
void write(uint64_t)
function to write bits/a value to the Field.
static const int P
private field: this flag indicates that this field is an implementation specific field that e....
bool applyBitflip(unsigned position, uint64_t fault_id)
function to write a bitflip to a field
const AccessMode accessMode_
static const int R
read flag
static const int F
supports fault injection/tracing
uint64_t read() const
function to read bits/a value from the Field.
const std::string prettyname_
alternative/human readable name of the field.
virtual bool _applyAction(const etiss::fault::Fault &f, const etiss::fault::Action &a, std::string &errormsg)
override this function to implement advanced action handling
const int flags_
read write flags as specified by the static const int parameters of Field: R,W,L
const size_t bitwidth_
width in bits
virtual void _write(uint64_t)
override this function to implement writes in case of AccessMode::VIRTUAL / AccessMode::PREFER_LAMBDA
abstract representation of an module of a simulation which could be a embedded device of the cpu of a...
virtual bool readField(void *fastfieldaccessptr, uint64_t &val, std::string &errormsg)
read the value of a field
std::map< std::string, Field * > fieldNames_
std::map< std::string, Field * > fieldPrettyNames_
void foreachStruct(const std::function< void(const std::string &name, VirtualStruct &vs)> &func)
bool mountStruct(const std::string &name, const std::shared_ptr< VirtualStruct > vs)
std::shared_ptr< VirtualStruct > getVirtualStruct(const std::string &path)
virtual bool acceleratedTrigger(const etiss::fault::Trigger &, int32_t fault_id)
std::list< Field * > fields_
std::shared_ptr< Field > findName(const std::string &name) const
void *const structure_
virtual bool applyAction(const etiss::fault::Fault &fault, const etiss::fault::Action &action, std::string &errormsg)
static std::shared_ptr< VirtualStruct > root()
std::map< std::string, std::weak_ptr< VirtualStruct > > subStructs_
bool addField(Field *f, bool noerrorprint=false)
static std::shared_ptr< VirtualStruct > allocate(void *structure, std::function< void(Field *)> delete_)
virtual std::list< std::string > listSubInjectors()
list all sub injectors.
virtual std::list< std::string > listFields()
list all fields directly reachable by this injector
std::function< void(Field *)> dtor_
virtual void * fastFieldAccessPtr(const std::string &name, std::string &errormsg)
void foreachField(const std::function< void(std::shared_ptr< Field >)> &func)
std::shared_ptr< VirtualStruct > parent_
std::shared_ptr< VirtualStruct::Field > getResolvedField(const std::string &path)
VirtualStruct(void *structure, std::function< void(Field *)> dtor=[](Field *f) { delete f;})
std::function< bool(const etiss::fault::Trigger &, int32_t)> acceleratedTrigger_
virtual std::shared_ptr< etiss::fault::Injector > getParentInjector()
get a the parent injector (root returns 0).
std::shared_ptr< Field > findPrettyName(const std::string &name) const
std::function< bool(const etiss::fault::Fault &, const etiss::fault::Action &, std::string &)> applyCustomAction
set this function to handle custom commands passed by etiss::fault::Action of the type etiss::fault::...
std::shared_ptr< VirtualStruct > findStruct(const std::string &name)
virtual std::shared_ptr< etiss::fault::Injector > getSubInjector(const std::string &name)
get a sub injector.
@ BITFLIP
applies a bit flip to a bit in a specified field
Definition: Action.h:83
@ COMMAND
commands are targetet at Injectors, not fields.
Definition: Action.h:86
Type getType() const
Definition: Action.cpp:88
const std::string & getTargetField() const
BITFLIP only.
Definition: Action.cpp:105
unsigned getTargetBit() const
BITFLIP only.
Definition: Action.cpp:111
int32_t id_
Definition: Fault.h:99
virtual std::string getInjectorPath()
returns the path of the current object.
Definition: Injector.cpp:142
static ptr get(const std::string &injectorPath)
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
Definition: Benchmark.h:53
void copy(VirtualStruct &dst, VirtualStruct &src, std::list< std::shared_ptr< VirtualStruct::Field >> &dst_notPresent, std::list< std::shared_ptr< VirtualStruct::Field >> &dst_notWriteable, std::list< std::shared_ptr< VirtualStruct::Field >> dst_unknown, bool pretend=false, std::list< std::shared_ptr< VirtualStruct::Field >> *src_private=0, std::list< std::shared_ptr< VirtualStruct::Field >> *dst_private=0)
copies all fields with the same name from the source to the destination structure.
@ INFO
Definition: Misc.h:129
@ VERBOSE
Definition: Misc.h:130
@ ERROR
Definition: Misc.h:127
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition: Misc.cpp:125
#define false
Definition: stdbool.h:17