ETISS 0.11.2
ExtendableTranslatingInstructionSetSimulator(version0.11.2)
Loading...
Searching...
No Matches
VirtualStruct.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2//
3// This file is part of ETISS. It is licensed under the BSD 3-Clause License; you may not use this file except in
4// compliance with the License. You should have received a copy of the license along with this project. If not, see the
5// LICENSE file.
6
10#include "etiss/fault/Fault.h"
11
12namespace etiss
13{
14
16
17VirtualStruct::Field::Field(VirtualStruct &parent, const std::string &name, const std::string &prettyname, int flags,
18 size_t width, size_t bitwidth)
19 : parent_(parent)
20 , name_(name)
21 , prettyname_(prettyname)
22 , flags_(flags)
23 , width_(width)
24 , bitwidth_(bitwidth ? bitwidth : width * 8)
26{
27}
28
29VirtualStruct::Field::Field(VirtualStruct &parent, const std::string &name, const std::string &prettyname, int flags,
30 size_t width, bool virtual_enabled, std::function<uint64_t()> lread,
31 std::function<void(uint64_t)> lwrite, size_t bitwidth)
32 : parent_(parent)
33 , name_(name)
34 , prettyname_(prettyname)
35 , flags_(flags)
36 , width_(width)
37 , bitwidth_(bitwidth ? bitwidth : width * 8)
38 , accessMode_(virtual_enabled ? VirtualStruct::Field::PREFER_LAMBDA : VirtualStruct::Field::LAMBDA)
39 , lread(lread)
40 , lwrite(lwrite)
41{
42}
43
45
47{
48
49 if (!(flags_ & R))
50 std::runtime_error("VirtualStruct::Field::write called but the write flag is not set");
51
52 uint64_t ret;
53 switch (accessMode_)
54 {
55 case LAMBDA:
56 if (lread)
57 {
58 ret = lread();
59 }
60 else
61 {
62 throw std::runtime_error(
63 "VirtualStruct is configured to use lambda expressions but no read function was provided.");
64 }
65 break;
66 case PREFER_LAMBDA:
67 if (lread)
68 {
69 ret = lread();
70 break;
71 }
72 case VIRTUAL:
73 ret = _read(offset);
74 break;
75 default:
76 throw std::runtime_error("invalid enum value");
77 }
78 // call listeners
79
80 return ret;
81}
82void VirtualStruct::Field::write(uint64_t val, size_t offset)
83{
84
85 if (!(flags_ & W))
86 throw std::runtime_error("VirtualStruct::Field::write called but the write flag is not set");
87
88 if (accessMode_ == LAMBDA && !lwrite) // throw error before calling listeners
89 throw std::runtime_error(
90 "VirtualStruct is configured to use lambda expressions but no read function was provided.");
91
92 switch (accessMode_)
93 {
94 case LAMBDA:
95 if (lwrite)
96 {
97 lwrite(val);
98 }
99 else
100 {
101 // throw std::runtime_error("VirtualStruct is configured to use lambda expressions but no read function was
102 // provided."); moved to start of function
103 }
104 break;
105 case PREFER_LAMBDA:
106 if (lwrite)
107 {
108 lwrite(val);
109 break;
110 }
111 case VIRTUAL:
112 _write(val, offset);
113 break;
114 }
115
116 signalWrite();
117}
118
120{
121 for (auto l : listeners)
122 {
123 if (l.first)
124 {
125 l.first->write(*this, read());
126 }
127 }
128}
129
130bool VirtualStruct::Field::applyBitflip(unsigned position, uint64_t fault_id)
131{
132 if (!(flags_ & F))
133 return false;
134
135 switch (accessMode_)
136 {
137 case LAMBDA:
138 case PREFER_LAMBDA:
139 case VIRTUAL:
140 return _applyBitflip(position, fault_id);
141 }
142 return false;
143}
144
146 std::string &errormsg)
147{
148 if (!(flags_ & (A | F)))
149 {
150 errormsg = "field doesn't support action handling";
151 return false;
152 }
153 return _applyAction(f, a, errormsg);
154}
155
157{
158 throw std::runtime_error("VirtualStruct::Field::_read called but not implemented");
159}
161{
162 throw std::runtime_error("VirtualStruct::Field::_write called but not implemented");
163}
164bool VirtualStruct::Field::_applyBitflip(unsigned position, uint64_t fault_id)
165{
166 if (!(flags_ & F))
167 return false;
168 if (lapplyBitflip)
169 return lapplyBitflip(position, fault_id);
170 if ((flags_ & RW) != RW)
171 return false;
172 uint64_t val = read();
173 uint64_t errval = ((uint64_t)1) << position;
174 errval = val ^ errval;
175 write(errval);
176 std::stringstream ss;
177 ss << "Injected bitflip in " << name_ << " 0x" << std::hex << val << "->0x" << errval << std::dec;
178 etiss::log(etiss::INFO, ss.str());
179 return true;
180}
182 std::string &errormsg)
183{
184 if (a.getType() == +etiss::fault::Action::type_t::MASK)
185 {
186 uint64_t mask_value = a.getMaskValue();
187 uint64_t val = read();
188 uint64_t errval = val;
189 switch (a.getMaskOp())
190 {
191 case etiss::fault::Action::mask_op_t::AND:
192 errval = (val & mask_value);
193 break;
194 case etiss::fault::Action::mask_op_t::OR:
195 errval = (val | mask_value);
196 break;
197 case etiss::fault::Action::mask_op_t::XOR:
198 errval = (val ^ mask_value);
199 break;
200 case etiss::fault::Action::mask_op_t::NAND:
201 errval = ~(val & mask_value);
202 break;
203 case etiss::fault::Action::mask_op_t::NOR:
204 errval = ~(val | mask_value);
205 break;
206 case etiss::fault::Action::mask_op_t::NOP:
207 errval = val;
208 break;
209 }
210 write(errval);
211 std::stringstream ss;
212 ss << "Injected mask fault in " << name_ << " 0x" << std::hex << val << " " << a.getMaskOp() << " 0x"
213 << mask_value << "->0x" << errval << std::dec;
214 etiss::log(etiss::INFO, ss.str());
215 return true;
216 }
217 else if (a.getType() == +etiss::fault::Action::type_t::BITFLIP)
218 {
219 return applyBitflip(a.getTargetBit(), f.id_);
220 }
221 return false;
222}
223
224bool VirtualStruct::Field::addListener(Listener *listener, std::shared_ptr<Listener> ref)
225{
226 if (!(flags_ & Field::L))
227 return false;
228 listeners.insert(std::pair<Listener *, std::shared_ptr<Listener>>(listener, ref));
229 return true;
230}
231void VirtualStruct::Field::removeListener(Listener *listener, std::shared_ptr<Listener> ref)
232{
233 listeners.erase(std::pair<Listener *, std::shared_ptr<Listener>>(listener, ref));
234}
235
236VirtualStruct::VirtualStruct(void *structure, std::function<void(Field *)> dtor)
237 : structure_(structure), dtor_(dtor), closed(false)
238{
239}
241{
242 close(); // VSSync is locked in close. IF THIS CHANGES VSSync MUST BE INSTANTIATED HERE
243 for (auto iter = fields_.begin(); iter != fields_.end(); ++iter)
244 {
245 if (*iter)
246 {
247 if ((*iter)->delete_)
248 {
249 std::function<void(Field *)> del_ = (*iter)->delete_;
250 del_(*iter);
251 }
252 else
253 {
254 if (dtor_)
255 {
256 dtor_(*iter);
257 }
258 else
259 {
260 etiss::log(etiss::ERROR, "The delete function passed to etiss::VirtualStruct is null. This will "
261 "likely result in a memory leak.");
262 }
263 }
264 }
265 }
266}
267
269{
270
271 if (f == 0)
272 {
273 if (!noerrorprint)
274 etiss::log(etiss::VERBOSE, "NULL pointer passed to etiss::VirtualStruct::addField", ETISS_SRCLOC);
275 return false;
276 }
277
278 if (f->name_.empty())
279 {
280 if (!noerrorprint)
281 etiss::log(etiss::ERROR, "Failed to add an field to etiss::VirtualStruct due to empty name", f->name_,
283 return false;
284 }
285 if (fieldNames_.find(f->name_) != fieldNames_.end())
286 {
287 if (!noerrorprint)
288 etiss::log(etiss::ERROR, "Failed to add an field to etiss::VirtualStruct due to duplicated name", f->name_,
290 return false;
291 }
292 if ((!f->prettyname_.empty()) && (fieldPrettyNames_.find(f->prettyname_) != fieldPrettyNames_.end()))
293 {
294 if (!noerrorprint)
295 etiss::log(etiss::ERROR, "Failed to add an field to etiss::VirtualStruct due to duplicated prettyname",
297 return false;
298 }
299
300 fields_.push_back(f);
301 fieldNames_.insert(std::make_pair(f->name_, f));
302 if (!f->prettyname_.empty())
303 fieldPrettyNames_.insert(std::make_pair(f->prettyname_, f));
304 return true;
305}
306
307std::shared_ptr<VirtualStruct::Field> VirtualStruct::findName(const std::string &name) const
308{
309 VSSync lock;
310 if (closed)
311 return 0;
312
313 auto find = fieldNames_.find(name);
314 if (find != fieldNames_.end())
315 {
316 std::shared_ptr<const VirtualStruct> pref = shared_from_this();
317 return std::shared_ptr<VirtualStruct::Field>(find->second, [pref](VirtualStruct::Field *) {});
318 }
319 return std::shared_ptr<VirtualStruct::Field>();
320}
321std::shared_ptr<VirtualStruct::Field> VirtualStruct::findPrettyName(const std::string &name) const
322{
323 VSSync lock;
324 if (closed)
325 return 0;
326 auto find = fieldPrettyNames_.find(name);
327 if (find != fieldPrettyNames_.end())
328 {
329 std::shared_ptr<const VirtualStruct> pref = shared_from_this();
330 return std::shared_ptr<VirtualStruct::Field>(find->second, [pref](VirtualStruct::Field *) {});
331 }
332 return 0;
333}
334void VirtualStruct::foreachField(const std::function<void(std::shared_ptr<Field>)> &func)
335{
336 VSSync lock;
337 if (closed)
338 return;
339 std::shared_ptr<const VirtualStruct> pref = shared_from_this();
340 for (Field *f : fields_)
341 {
342 func(std::shared_ptr<Field>(f, [pref](VirtualStruct::Field *) {}));
343 }
344}
346{
348 {
349 return acceleratedTrigger_(t, fault_id);
350 }
351 else
352 {
353 }
354 return false;
355}
356bool VirtualStruct::mountStruct(const std::string &name, std::shared_ptr<VirtualStruct> vs)
357{
358 if (!vs)
359 return false;
360 VSSync lock;
361 // check for existing
362 {
363 auto find = subStructs_.find(name);
364 if (find != subStructs_.end())
365 {
366 if (find->second.lock())
367 {
368 return false;
369 }
370 }
371 }
372 if (vs->parent_) // already mounted elsewere
373 return false;
374 vs->parent_ = shared_from_this();
375 subStructs_.insert(std::pair<std::string, std::weak_ptr<VirtualStruct>>(name, vs));
376 return true;
377}
378std::shared_ptr<VirtualStruct> VirtualStruct::findStruct(const std::string &name)
379{
380 VSSync lock;
381 auto find = subStructs_.find(name);
382 if (find != subStructs_.end())
383 return find->second.lock();
384 return std::shared_ptr<VirtualStruct>();
385}
386void VirtualStruct::foreachStruct(const std::function<void(const std::string &name, VirtualStruct &vs)> &func)
387{
388 VSSync lock;
389 for (auto e : subStructs_)
390 {
391 auto sp = e.second.lock();
392 auto p = sp.get();
393 if (p)
394 {
395 func(e.first, *p);
396 }
397 }
398}
399
401{
402 VSSync lock;
403 closed = true;
404 // dont't delete fields here.
405}
407{
408 VSSync lock;
409 return closed;
410}
411
412std::list<std::string> VirtualStruct::listFields()
413{
414 std::list<std::string> ret;
416 [&ret](std::shared_ptr<Field> f)
417 {
418 if (f)
419 ret.push_back(f->name_);
420 });
421 return ret;
422}
423std::list<std::string> VirtualStruct::listSubInjectors()
424{
425 std::list<std::string> ret;
426 foreachStruct([&ret](const std::string &name, VirtualStruct &vs) { ret.push_back(name); });
427 return ret;
428}
429
430std::shared_ptr<etiss::fault::Injector> VirtualStruct::getSubInjector(const std::string &name)
431{
432 return findStruct(name);
433}
434std::shared_ptr<etiss::fault::Injector> VirtualStruct::getParentInjector()
435{
436 return parent_;
437}
438
439void *VirtualStruct::fastFieldAccessPtr(const std::string &name, std::string &errormsg)
440{
441 VSSync lock;
442 {
443 auto iter = fieldNames_.find(name);
444 if (iter != fieldNames_.end())
445 return iter->second;
446 }
447 {
448 auto iter = fieldPrettyNames_.find(name);
449 if (iter != fieldPrettyNames_.end())
450 return iter->second;
451 }
452 return 0;
453}
454bool VirtualStruct::readField(void *fastfieldaccessptr, uint64_t &val, std::string &errormsg)
455{
456 Field *f = (Field *)fastfieldaccessptr;
457 if (!f)
458 {
459 errormsg = "No such field";
460 return false;
461 }
462 if (!(f->flags_ & Field::R))
463 {
464 errormsg = "No read access";
465 return false;
466 }
467 val = f->read();
468 return true;
469}
471 std::string &errormsg)
472{
473 switch (action.getType())
474 {
475 case +etiss::fault::Action::type_t::COMMAND: // handle command
476 {
478 {
479 errormsg = getInjectorPath() +
480 ": VirtualStruct::applyCustomAction function not set. cannot handle custom actions.";
481 return false;
482 }
483 return applyCustomAction(fault, action, errormsg);
484 }
485 case +etiss::fault::Action::type_t::MASK:
486#if __cplusplus >= 201703L // in case of c++17 present we can use explicit fallthrough etc.
487 [[fallthrough]];
488#endif
489 case +etiss::fault::Action::type_t::BITFLIP: // handle bitflip
490 {
491 Field *f;
492 auto find = fieldNames_.find(action.getTargetField());
493 if (find == fieldNames_.end())
494 {
495 find = fieldPrettyNames_.find(action.getTargetField());
496 if (find == fieldPrettyNames_.end())
497 {
498 f = 0;
499 }
500 else
501 {
502 f = find->second;
503 }
504 }
505 else
506 {
507 f = find->second;
508 }
509
510 if (!f)
511 {
512 errormsg = std::string("No such field: ") + getInjectorPath() + "." + action.getTargetField();
513 return false;
514 }
515 if (f->flags_ & (Field::A | Field::F))
516 {
517 return f->applyAction(fault, action, errormsg);
518 }
519 }
520 return false;
521 default:
522 return false;
523 }
524}
525
526bool VirtualStruct::update_field_access_rights(const etiss::fault::Action &action, std::string &errormsg)
527{
528 Field *f = nullptr;
529 auto find = fieldNames_.find(action.getTargetField());
530 if (find == fieldNames_.end())
531 {
532 find = fieldPrettyNames_.find(action.getTargetField());
533 if (find != fieldPrettyNames_.end())
534 {
535 f = find->second;
536 }
537 }
538 else
539 {
540 f = find->second;
541 }
542
543 if (f)
544 {
545 switch (action.getType())
546 {
547 case +etiss::fault::Action::type_t::MASK:
548#if __cplusplus >= 201703L // in case of c++17 present we can use explicit fallthrough etc.
549 [[fallthrough]];
550#endif
551 case +etiss::fault::Action::type_t::BITFLIP:
552 f->flags_ |= Field::F;
553 break;
554 default:
555 break;
556 }
557 }
558 else
559 {
560 errormsg =
561 std::string("VirtualStruct:update_field_access_rights(): Required field not a field in VirtualStruct!");
562 return false;
563 }
564 return true;
565}
566
568{
569 mutex().lock();
570}
572{
573 mutex().unlock();
574}
575std::recursive_mutex &VSSync::mutex()
576{
577 static std::recursive_mutex mu;
578 return mu;
579}
580
581void copy(VirtualStruct &dst, VirtualStruct &src, std::list<std::shared_ptr<VirtualStruct::Field>> &notPresent,
582 std::list<std::shared_ptr<VirtualStruct::Field>> &notWriteable,
583 std::list<std::shared_ptr<VirtualStruct::Field>> unknown, bool pretend,
584 std::list<std::shared_ptr<VirtualStruct::Field>> *src_private,
585 std::list<std::shared_ptr<VirtualStruct::Field>> *dst_private)
586{
587
588 []() {}();
589
590 std::set<std::shared_ptr<VirtualStruct::Field>> dst_known;
591
592 src.foreachField(
593 [&](std::shared_ptr<VirtualStruct::Field> srcf)
594 {
595 if (srcf->flags_ & VirtualStruct::Field::P)
596 {
597 if (src_private)
598 src_private->push_back(srcf);
599 return;
600 }
601
602 auto dstf = dst.findName(srcf->name_);
603 if (dstf == 0)
604 {
605 notPresent.push_back(srcf);
606 return;
607 }
608
609 if (dstf->flags_ & VirtualStruct::Field::P)
610 {
611 notPresent.push_back(srcf);
612 return;
613 }
614
615 dst_known.insert(dstf);
616
617 if (!(dstf->flags_ & VirtualStruct::Field::W))
618 {
619 notWriteable.push_back(dstf);
620 return;
621 }
622
623 if (!pretend)
624 dstf->write(srcf->read()); // copy value
625 });
626
627 dst.foreachField(
628 [&](std::shared_ptr<VirtualStruct::Field> dstf)
629 {
630 if (dst_known.find(dstf) == dst_known.end())
631 {
632 if (dstf->flags_ & VirtualStruct::Field::P)
633 {
634 if (dst_private)
635 {
636 dst_private->push_back(dstf);
637 }
638 }
639 else
640 {
641 unknown.push_back(dstf);
642 }
643 }
644 });
645}
646
647std::shared_ptr<VirtualStruct> VirtualStruct::allocate(void *structure, std::function<void(Field *)> delete_)
648{
649 VirtualStruct *ret = new VirtualStruct(structure, delete_);
650
651 return std::shared_ptr<VirtualStruct>(ret, [](VirtualStruct *vs) { delete vs; });
652}
653
654std::shared_ptr<VirtualStruct> VirtualStruct::root()
655{
656 static std::shared_ptr<VirtualStruct> r = allocate(0, [](Field *) {});
657 return r;
658}
659
660std::shared_ptr<VirtualStruct> VirtualStruct::getVirtualStruct(const std::string &path)
661{
662 if (path.empty())
663 return shared_from_this();
664 std::shared_ptr<VirtualStruct> ret;
665 if (path.find_first_of(".") != std::string::npos)
666 {
667 // error
668 return ret;
669 }
670 auto pp1 = path.find("::");
671
672 if (pp1 == 0) // absolute path
673 {
674 auto ptr = parent_;
675 auto prev = shared_from_this();
676 while (ptr)
677 {
678 prev = ptr;
679 ptr = ptr->parent_;
680 }
681 return prev->getVirtualStruct(path.substr(pp1 + 2));
682 }
683
684 {
685 VSSync lock;
686 auto find = subStructs_.find((pp1 == std::string::npos) ? path : path.substr(0, pp1));
687 if (find != subStructs_.end())
688 {
689 ret = find->second.lock();
690 }
691 }
692
693 if (!ret)
694 return ret;
695
696 if (pp1 == std::string::npos)
697 {
698 return ret;
699 }
700 else
701 {
702 return ret->getVirtualStruct(path.substr(pp1 + 2));
703 }
704}
705
706std::shared_ptr<etiss::fault::Injector> etiss::fault::Injector::get(const std::string &path)
707{
708 return std::shared_ptr<etiss::fault::Injector>(VirtualStruct::root()->getVirtualStruct(path));
709}
710
711std::shared_ptr<VirtualStruct::Field> VirtualStruct::getResolvedField(const std::string &path)
712{
713 auto pp1 = path.find_first_of(".");
714 if (pp1 == std::string::npos) // if no point exists the this is not a path
715 return std::shared_ptr<VirtualStruct::Field>();
716
717 auto m = getVirtualStruct(path.substr(0, pp1));
718 if (!m)
719 return std::shared_ptr<VirtualStruct::Field>();
720
721 auto ret = m->findName(path.substr(pp1 + 1));
722 if (!ret)
723 ret = m->findPrettyName(path.substr(pp1 + 1));
724
725 return ret;
726}
727
728} // namespace etiss
contains an action class that describes actions associated with a fault
contains the fault container class that stores triggers and actions for fault injection
#define ETISS_SRCLOC
Definition Misc.h:202
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
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
uint64_t read(size_t offset=0) const
function to read bits/a value from the Field.
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
virtual void _write(uint64_t, size_t offset=0)
override this function to implement writes in case of AccessMode::VIRTUAL / AccessMode::PREFER_LAMBDA
const size_t width_
width in bytes (rounded up if neccessary)
virtual uint64_t _read(size_t offset=0) const
override this function to implement reads in case of AccessMode::VIRTUAL / AccessMode::PREFER_LAMBDA
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...
VirtualStruct & parent_
reference to parent virtual struct
int flags_
read write flags as specified by the static const int parameters of Field: R,W,L
bool addListener(Listener *listener, std::shared_ptr< Listener > ref=nullptr)
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
static const int R
read flag
static const int F
supports fault injection/tracing
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 size_t bitwidth_
width in bits
void write(uint64_t, size_t offset=0)
function to write bits/a value to the Field.
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
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).
virtual bool update_field_access_rights(const etiss::fault::Action &action, std::string &errormsg)
Update the field of injector with access rights to allow action (used to get type of action).
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.
const mask_op_t & getMaskOp() const
MASK only.
Definition Action.cpp:189
uint64_t getMaskValue() const
Definition Action.cpp:197
const std::string & getTargetField() const
BITFLIP only.
Definition Action.cpp:164
const type_t & getType() const
Definition Action.cpp:139
unsigned getTargetBit() const
BITFLIP only.
Definition Action.cpp:173
virtual std::string getInjectorPath()
returns the path of the current object.
Definition Injector.cpp:122
static ptr get(const std::string &injectorPath)
forwards: include/jit/*
Definition Benchmark.h:17
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:87
@ VERBOSE
Definition Misc.h:88
@ ERROR
Definition Misc.h:85
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition Misc.cpp:94
#define false
Definition stdbool.h:17