ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
Translation.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/Translation.h"
44 #include <mutex>
45 
46 namespace etiss
47 {
48 
49 BlockLink::BlockLink(etiss::uint64 start, etiss::uint64 end, ExecBlockCall execBlock, std::shared_ptr<void> lib)
50  : start(start), end(end), execBlock(execBlock), jitlib(lib)
51 {
52  refcount = 0;
53  next = 0;
54  branch = 0;
55  valid = true;
56 }
57 
59 {
60  if (next != 0)
62  if (branch != 0)
64 }
65 
66 template <unsigned len, unsigned pos>
68 {
69  return;
70 }
71 template <unsigned len, unsigned pos>
73 {
74  ca[pos]->initCodeBlock(cb);
75  call_initCodeBlock<len, pos + 1>(ca, cb);
76 }
77 
78 template <unsigned len, unsigned pos>
80  CodeBlock &cb)
81 {
82  return;
83 }
84 template <unsigned len, unsigned pos>
86  CodeBlock &cb)
87 {
88  ca[pos]->finalizeCodeBlock(cb);
89  call_finalizeCodeBlock<len, pos + 1>(ca, cb);
90 }
91 
93 {
94  size_t pos = 0;
95  while (ca[pos] != nullptr)
96  {
97  ca[pos++]->initCodeBlock(cb);
98  }
99 }
101 {
102  size_t pos = 0;
103  while (ca[pos] != nullptr)
104  {
105  ca[pos++]->finalizeCodeBlock(cb);
106  }
107 }
108 
110 {
111  static std::mutex mu;
112  static uint64_t id = 0;
113  std::lock_guard<std::mutex> lock(mu);
114  return id++;
115 }
116 
117 Translation::Translation(std::shared_ptr<etiss::CPUArch> &arch, std::shared_ptr<etiss::JIT> &jit,
118  std::list<std::shared_ptr<etiss::Plugin>> &plugins, ETISS_System &system, ETISS_CPU &cpu)
119  : archptr_(arch)
120  , jitptr_(jit)
121  , arch_(archptr_.get())
122  , jit_(jitptr_.get())
123  , plugins_(plugins)
124  , system_(system)
125  , cpu_(cpu)
126  , plugins_array_(0)
127  , plugins_handle_array_(0)
128  , mis_(0)
129 #if ETISS_TRANSLATOR_STAT
130  , next_count_(0)
131  , branch_count_(0)
132  , miss_count_(0)
133 #endif
134  , id(genTranslationId())
135 {
136  tblockcount = 0;
137 }
138 
140 {
141  unloadBlocks(0, (uint64_t)((int64_t)-1));
142  delete[] plugins_array_;
143  delete[] plugins_handle_array_;
144  delete mis_;
145 }
146 
148 {
149  delete[] plugins_array_;
150  plugins_array_ = 0;
151  delete[] plugins_handle_array_;
153  delete mis_;
154  mis_ = 0;
155 
156  if (arch_ == nullptr)
157  return nullptr;
158 
159  if (jit_ == nullptr)
160  return nullptr;
161 
162  // First plugin to more to tmpl list is the architecture plugin
164 
165  std::vector<etiss::TranslationPlugin *> tmpl;
166 
167  tmpl.push_back(arch_);
168 
169  // Followed by all plugins, which are of type translation plugin
170  for (auto iter = plugins_.begin(); iter != plugins_.end(); iter++)
171  {
172  etiss::Plugin *p = iter->get();
173  if (p != nullptr)
174  {
176  if (tp != nullptr)
177  {
178  tmpl.push_back(tp);
179  }
180  }
181  }
182 
183  // Build up the plugin lists
184  plugins_array_ = new etiss::TranslationPlugin *[tmpl.size() + 1];
185  plugins_array_[tmpl.size()] = nullptr;
186  plugins_handle_array_ = new void *[tmpl.size()];
187  plugins_array_size_ = tmpl.size();
188 
189  for (size_t i = 0; i < tmpl.size(); i++)
190  {
191  plugins_array_[i] = tmpl[i];
193  /* During execution of each code block, the list plugin_handle_, which
194  returned by the function init, is passed again as parameter with name
195  plugin_pointers
196  -> plugin_pointers is the name of the list of translation plugin in the
197  generated c-code of all code blocks
198  */
199  plugins_array_[i]->pointerCode = std::string("(plugin_pointers[") + toString(i) + "])";
200  }
201 
202  // Call the function initInstrSet for all translation plugins
203  for (size_t i = 0; i < tmpl.size(); i++)
204  {
206  }
207  // Call the function finalizeInstrSet( for all translation plugins
208  for (int i = (int)tmpl.size() - 1; i >= 0; i--)
209  {
211  }
212 
214 
215  if (!mis_->compile())
216  {
217  etiss::log(etiss::ERROR, "Failed to compile instruction set");
218  delete[] plugins_array_;
219  plugins_array_ = 0;
220  delete[] plugins_handle_array_;
222  delete mis_;
223  mis_ = 0;
224  }
225 
226  // Builds the function for function pointer plugins_initCodeBlock_ It calls_initCodeBlock functions of all
227  // translation plugins Builds the functions plugins_finalizeCodeBlock_ It calls_finalizeCodeBlock functions of all
228  // translation plugins
229  switch (plugins_array_size_)
230  {
231  case 1:
232  plugins_initCodeBlock_ = &(call_initCodeBlock<1, 0>);
233  plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<1, 0>);
234  break;
235  case 2:
236  plugins_initCodeBlock_ = &(call_initCodeBlock<2, 0>);
237  plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<2, 0>);
238  break;
239  case 3:
240  plugins_initCodeBlock_ = &(call_initCodeBlock<3, 0>);
241  plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<3, 0>);
242  break;
243  case 4:
244  plugins_initCodeBlock_ = &(call_initCodeBlock<4, 0>);
245  plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<4, 0>);
246  break;
247  case 5:
248  plugins_initCodeBlock_ = &(call_initCodeBlock<5, 0>);
249  plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<5, 0>);
250  break;
251  case 6:
252  plugins_initCodeBlock_ = &(call_initCodeBlock<6, 0>);
253  plugins_finalizeCodeBlock_ = &(call_finalizeCodeBlock<6, 0>);
254  break;
255  default:
258  }
259 
260  return plugins_handle_array_;
261 }
262 
263 BlockLink *Translation::getBlock(BlockLink *prev, const etiss::uint64 &instructionindex)
264 {
265 
266  std::string error;
267 
268  if (prev != 0 && !prev->valid)
269  {
270  prev = 0;
271  }
272 
273  // search block in cache
274  std::list<BlockLink *> &list = blockmap_[instructionindex >> 9];
275  for (std::list<BlockLink *>::iterator iter = list.begin(); iter != list.end();) // iter++ moved into block
276  {
277  BlockLink *iterbl = (*iter);
278  if (iterbl != 0)
279  {
280  if (iterbl->valid) // check for valid block
281  {
282  if (iterbl->start <= instructionindex && iterbl->end > instructionindex)
283  {
284  if (prev != 0)
285  {
286  if (prev->end == iterbl->start)
287  {
288  BlockLink::updateRef(prev->next, iterbl);
289  }
290  else
291  {
292  BlockLink::updateRef(prev->branch, iterbl);
293  }
294  }
295  return *iter;
296  }
297  iter++;
298  }
299  else // cleanup
300  {
301  BlockLink::updateRef(iterbl->next, 0);
302  BlockLink::updateRef(iterbl->branch, 0);
303  list.erase(iter++);
305  iterbl); // remove reference of map // prev remains valid because this blocklink needs to be invalid
306  continue;
307  }
308  }
309  }
310 
311  // generate block
312 
313  std::string blockfunctionname;
314  {
315  std::stringstream ss;
316  ss << "_t" << id << "c" << tblockcount++ << "_block_" << instructionindex;
317  blockfunctionname = ss.str();
318  }
319 
320  CodeBlock block(instructionindex);
321  block.fileglobalCode().insert("#include \"etiss/jit/CPU.h\"\n"
322  "#include \"etiss/jit/System.h\"\n"
323  "#include \"etiss/jit/libresources.h\"\n"
324  "#include \"etiss/jit/libsemihost.h\"\n"
325  "#include \"etiss/jit/ReturnCode.h\"\n"
326  "#include \"etiss/jit/libCSRCounters.h\"\n");
327 
328  for(auto &it: jitExtHeaders()){
329  if(it != "") block.fileglobalCode().insert("#include \"" + it + "\"\n");
330  }
331 
332  block.functionglobalCode().insert("if (cpu->mode != " + toString(cpu_.mode) +
333  ") return ETISS_RETURNCODE_RELOADCURRENTBLOCK;");
334 
336 
337  etiss::int32 transerror = translateBlock(block);
338 
339  if (transerror != ETISS_RETURNCODE_NOERROR)
340  {
341  etiss::log(etiss::ERROR, "Failed to translate block");
342  return nullptr;
343  }
344 
346 
347  std::string code;
348  {
349  std::stringstream ss;
350  block.toCode(ss, blockfunctionname, nullptr);
351  code = ss.str();
352  }
353 
354  // various includes
355  std::set<std::string> headers;
356  headers.insert(etiss::jitFiles());
357  headers.insert(arch_->getIncludePath());
358  for(auto & it: jitExtHeaderPaths()){
359  if(it != "") headers.insert(it);
360  }
361 
362  std::set<std::string> libloc;
363  libloc.insert(arch_->getIncludePath());
364  libloc.insert(etiss::cfg().get<std::string>("etiss_path", "./"));
365  libloc.insert(etiss::jitFiles());
366  libloc.insert(etiss::jitFiles() + "/etiss/jit");
367  for(auto & it: jitExtLibPaths()){
368  if(it != "") libloc.insert(etiss::jitFiles() + it);
369  }
370 
371  std::set<std::string> libs;
372  //libs.insert("ETISS");
373  libs.insert("resources");
374  libs.insert("semihost");
375  libs.insert("CSRCounters");
376  for(auto & it: jitExtLibraries()){
377  if(it != "") libs.insert(it);
378  }
379  /* DEBUG HELPER: write code files to work directory
380  {
381  static unsigned count = 0;
382  std::stringstream ss;
383  ss << "code" << ++count;
384  std::ofstream out;
385  out.open(ss.str().c_str());
386  out << code;
387  std::cout << "Code file " << count << std::endl;
388  }
389  */
390 #ifndef ETISS_DEBUG
391 #define ETISS_DEBUG 1
392 #endif
393  // compile library
394  void *funcs =
395  jit_->translate(code, headers, libloc, libs, error, etiss::cfg().get<bool>("jit.debug", ETISS_DEBUG) != 0);
396 
397  if (funcs == 0)
398  {
399  etiss::log(etiss::ERROR, error);
400  return 0;
401  }
402 
403  // wrap library handle for cleanup
404  auto local_jit = jit_;
405  std::shared_ptr<void> lib(funcs, [local_jit](void *p) { local_jit->free(p); });
406 
407  // check function/library handle
408  if (lib.get() != 0)
409  {
410  // std::cout<<"blockfunctionname:"<<blockfunctionname<<std::endl;
411  ExecBlockCall execBlock = (ExecBlockCall)jit_->getFunction(lib.get(), blockfunctionname.c_str(), error);
412  if (execBlock != 0)
413  {
414  BlockLink *nbl = new BlockLink(block.startindex_, block.endaddress_, execBlock, lib);
415  uint64 ii9 = instructionindex >> 9;
416  do
417  {
418  blockmap_[ii9].push_back(nbl);
419  BlockLink::incrRef(nbl); // map holds a reference
420  ii9++;
421  } while ((ii9 << 9) < block.endaddress_);
422 
423  if (prev != 0)
424  {
425  if (nbl->start == prev->end)
426  {
427  BlockLink::updateRef(prev->next, nbl);
428  }
429  else
430  {
431  BlockLink::updateRef(prev->branch, nbl);
432  }
433  }
434  return nbl;
435  }
436  else
437  {
438  etiss::log(etiss::ERROR, std::string("Failed to acquire function pointer from compiled library:") + error);
439  return 0;
440  }
441  }
442 
443  return 0;
444 }
448 {
449  cb.endaddress_ = cb.startindex_;
450 
452 
453  context.cf_delay_slot_ = 0;
454  context.force_block_end_ = false;
455 
456  unsigned count = 0;
457  const unsigned maxcount = etiss::cfg().get<unsigned>("etiss.max_block_size", 100);
458  cb.reserve(maxcount);
459 
461 
462  if (vis_ == nullptr)
463  {
464  return etiss::RETURNCODE::GENERALERROR;
465  }
466 
467  etiss::instr::BitArray mainba(vis_->width_);
468  etiss::instr::Buffer buffer;
469 
470  do
471  {
472  context.force_append_next_instr_ = false;
473  context.force_block_end_ = false;
474  context.current_address_ = cb.endaddress_;
476  context.instr_width_fully_evaluated_ = true;
477  context.is_not_default_width_ = false;
478  context.instr_width_ = vis_->width_;
479 
480  etiss::instr::BitArray errba(32, 0);
481 
482  buffer = etiss::instr::Buffer(mainba.intCount());
483  // read instruction
484  etiss::int32 ret = (*system_.dbg_read)(system_.handle, cb.endaddress_, (etiss_uint8*)buffer.internalBuffer(), mainba.byteCount()); // read instruction
485  mainba.set_value(buffer.data());
486  if (ret == etiss::RETURNCODE::IBUS_READ_ERROR || ret == etiss::RETURNCODE::DBUS_READ_ERROR)
487  {
488  std::cout << "Instruction bus read error while translating!" << std::endl;
489  errba.set_value(etiss::RETURNCODE::IBUS_READ_ERROR);
490  // std::cout << "mainba.byteCount = " << mainba.byteCount() << std::endl;
491  auto instr = &vis_->getMain()->getInvalid();
492  CodeBlock::Line &line = cb.append(cb.endaddress_); // allocate codeset for instruction
493  bool ok = instr->translate(errba, line.getCodeSet(), context);
494  if (unlikely(!ok)) {
495  return etiss::RETURNCODE::GENERALERROR;
496  }
497  cb.endaddress_ += mainba.byteCount(); // update end address
499  }
500  if (ret != etiss::RETURNCODE::NOERROR)
501  {
502  if (count == 0)
503  {
504  return ret; // empty block -> return error
505  }
506  else
507  {
508  break; // non empty block -> compile pending
509  }
510  }
511 
512  arch_->compensateEndianess(&cpu_, mainba);
513  vis_->length_updater_(*vis_, context, mainba);
514 
515  // continue reading instruction data if neccessary
516  if (unlikely(context.is_not_default_width_))
517  {
518  etiss::instr::BitArray *secba = nullptr;
519  do
520  {
521  if (secba)
522  delete secba;
523  secba = new etiss::instr::BitArray(context.instr_width_);
524 
525  buffer = etiss::instr::Buffer(secba->intCount());
526  ret = (*system_.dbg_read)(system_.handle, cb.endaddress_, (etiss_uint8*)buffer.internalBuffer(), secba->byteCount()); // read instruction
527  secba->set_value(buffer.data());
528 
529  if (ret != etiss::RETURNCODE::NOERROR)
530  {
531  if (count == 0)
532  {
533  delete secba;
534  return ret; // empty block -> return error
535  }
536  else
537  {
538  break; // non empty block -> compile pending
539  }
540  }
541  arch_->compensateEndianess(&cpu_, *secba);
542  vis_->length_updater_(*vis_, context, *secba);
543  } while (!context.instr_width_fully_evaluated_);
544 
546  etiss::instr::InstructionSet *instrSet = vis_->get(secba->size());
547  if (unlikely(!instrSet))
548  {
549  errba.set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
550  instr = &vis_->getMain()->getInvalid();
551  }
552  else
553  {
554  instr = instrSet->resolve(*secba);
555  if (unlikely(!instr))
556  {
557  errba.set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
558  instr = &instrSet->getInvalid();
559  }
560  }
561  CodeBlock::Line &line = cb.append(cb.endaddress_); // allocate codeset for instruction
562  bool ok = instr->translate(errba != etiss::instr::BitArray(32, 0) ? errba : *secba, line.getCodeSet(), context);
563  if (unlikely(!ok))
564  {
565  delete secba;
566  return etiss::RETURNCODE::GENERALERROR;
567  }
568  cb.endaddress_ += secba->byteCount(); // update end address
569  delete secba;
570  }
571  else
572  {
573  etiss::instr::InstructionSet *instrSet = vis_->getMain();
574  etiss::instr::Instruction *instr = instrSet->resolve(mainba);
575  if (unlikely(instr == 0))
576  {
577  errba.set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
578  instr = &instrSet->getInvalid();
579  }
580  CodeBlock::Line &line = cb.append(cb.endaddress_); // allocate codeset for instruction
581  bool ok = instr->translate(errba != etiss::instr::BitArray(32, 0) ? errba : mainba, line.getCodeSet(), context);
582  if (unlikely(!ok))
583  {
584  return etiss::RETURNCODE::GENERALERROR;
585  }
586  cb.endaddress_ += mainba.byteCount(); // update end address
587  }
588 
589  count++;
590  } while ((count < maxcount && !context.force_block_end_) || context.force_append_next_instr_);
591 
593 }
594 
596 {
597  for (auto &entry:blockmap_)
598  {
599  entry.second.erase(std::remove_if(entry.second.begin(), entry.second.end(),
600  [](auto &bl)
601  {
602  bl->valid = false;
603  BlockLink::updateRef(bl->next, 0);
604  BlockLink::updateRef(bl->branch, 0);
605  BlockLink::decrRef(bl); // remove reference of map
606  return true;
607  }),
608  entry.second.end());
609  }
610  blockmap_.clear();
611 }
612 
614 {
615  // Hotfix: if everything needs to be deleted, new function unloadBlocksAll()
616  if (startindex == 0 && endindex == ((etiss::uint64)((etiss::int64)-1)))
617  {
618  unloadBlocksAll();
619  return;
620  }
621 
622  const etiss::uint64 startindexblock = startindex >> 9;
623  const etiss::uint64 endindexblock = (endindex >> 9) + ((((endindex >> 9) << 9) == endindex) ? 0 : 1);
624  for (etiss::uint64 block = startindexblock; block < endindexblock; block++)
625  {
626  if (blockmap_.empty())
627  break;
628  auto entry = blockmap_.find(block);
629  if (entry != blockmap_.end())
630  {
631  for (std::list<BlockLink *>::iterator iter = entry->second.begin(); iter != entry->second.end();)
632  {
633  BlockLink *bl = *iter;
634  if (bl->start < endindex || bl->end > startindex)
635  {
636  bl->valid = false;
637  BlockLink::updateRef(bl->next, 0);
639  entry->second.erase(iter++);
640  BlockLink::decrRef(bl); // remove reference of map
641  }
642  else
643  {
644  iter++;
645  }
646  }
647  if (entry->second.empty())
648  blockmap_.erase(entry);
649  }
650  }
651 }
652 
653 std::string Translation::disasm(uint8_t *buf, unsigned len, int &append)
654 {
655  etiss::instr::BitArray mainba(len * 8);
656  etiss::instr::Buffer buffer(mainba.intCount());
657 
658  memcpy(buffer.internalBuffer(), buf, len);
659  mainba.set_value(buffer.data());
660 
661  // TODO implement propper instruction selection with append requests is neccessary
662 
664 
665  if (vis == 0)
666  return "UNKNOWN";
667 
668  etiss::instr::InstructionSet *is = vis->get(len * 8);
669 
670  if (is == 0)
671  return "UNKNOWN";
672 
673  etiss::instr::Instruction *instr = is->resolve(mainba);
674 
675  if (instr == 0)
676  return "UNKNOWN";
677 
678  return instr->printASM(mainba);
679 }
680 
681 } // namespace etiss
etiss_int32 int32
Definition: 386-GCC.h:81
etiss_int64 int64
Definition: 386-GCC.h:83
etiss_uint64 uint64
Definition: 386-GCC.h:82
#define ETISS_DEBUG
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
if(__y==0) return __x
static __inline__ uint64_t
Definition: arm_cde.h:31
static __inline__ uint8_t
Definition: arm_mve.h:323
#define unlikely(x)
Definition: types.h:74
uint8_t etiss_uint8
Definition: types.h:87
virtual std::string getIncludePath()
returns a path that will be used to look up header files
Definition: CPUArch.cpp:150
virtual void compensateEndianess(ETISS_CPU *cpu, etiss::instr::BitArray &ba) const
this function should compensate for any endianess on a BitArray so that bit 0 is always the LSB.
Definition: CPUArch.cpp:188
std::string getName() const
returns the name of this architecture.
Definition: CPUArch.h:184
equivalent of a translated instruction
Definition: CodePart.h:578
CodeSet & getCodeSet()
Definition: CodePart.h:585
A list of CodeSets.
Definition: CodePart.h:570
void toCode(std::stringstream &out, const std::string &funcname, std::set< std::string > *fileglobalcode)
Definition: CodePart.cpp:146
std::set< std::string > & functionglobalCode()
Definition: CodePart.h:605
std::set< std::string > & fileglobalCode()
Definition: CodePart.h:604
void reserve(int num)
Definition: CodePart.h:596
Line & append(etiss::uint64 addr)
Definition: CodePart.h:598
etiss::uint64 endaddress_
Definition: CodePart.h:611
etiss::uint64 startindex_
Definition: CodePart.h:610
T get(const std::string &key, T default_, bool *default_used=0)
template function to read the value of a configuration key.
Definition: Misc.h:349
virtual void * translate(std::string code, std::set< std::string > headerpaths, std::set< std::string > librarypaths, std::set< std::string > libraries, std::string &error, bool debug=true)=0
translate C code to executable code and return a handle/pointer that identifies the compilation resul...
virtual void * getFunction(void *handle, std::string name, std::string &error)=0
returns a function pointer to a compiled function from the handle returned by etiss::JIT::translate
base plugin class that provides access to different plugin functions if present
Definition: Plugin.h:77
TranslationPlugin * getTranslationPlugin()
Definition: Plugin.h:125
allows to add code to the translation of instructions
Definition: Plugin.h:262
virtual void initCodeBlock(etiss::CodeBlock &) const
called before instructions are translated for the code block
Definition: Plugin.cpp:93
virtual void finalizeInstrSet(etiss::instr::ModedInstructionSet &) const
called after all instructions have been added to allow last changes
Definition: Plugin.cpp:92
virtual void finalizeCodeBlock(etiss::CodeBlock &) const
called after all instructions have been translated for the code block
Definition: Plugin.cpp:94
virtual void initInstrSet(etiss::instr::ModedInstructionSet &) const
called to add instructions to the instruction set
Definition: Plugin.cpp:91
std::string pointerCode
Definition: Plugin.h:288
virtual void * getPluginHandle()
called to get the handle that is available in translated code via getPoinerCode()....
Definition: Plugin.cpp:96
Translation(std::shared_ptr< etiss::CPUArch > &arch, std::shared_ptr< etiss::JIT > &jit, std::list< std::shared_ptr< etiss::Plugin >> &plugins, ETISS_System &system, ETISS_CPU &cpu)
std::string disasm(uint8_t *buf, unsigned len, int &append)
etiss::instr::ModedInstructionSet * mis_
Definition: Translation.h:148
etiss::JIT *const jit_
Definition: Translation.h:127
uint64_t tblockcount
countes translated blocks. needed to guarantee unique block function names
Definition: Translation.h:222
std::list< std::shared_ptr< etiss::Plugin > > & plugins_
Definition: Translation.h:128
size_t plugins_array_size_
Definition: Translation.h:133
etiss::TranslationPlugin ** plugins_array_
Definition: Translation.h:131
void unloadBlocks(etiss::uint64 startindex=0, etiss::uint64 endindex=((etiss::uint64)((etiss::int64) -1)))
etiss::CPUArch *const arch_
Definition: Translation.h:126
void ** plugins_handle_array_
Definition: Translation.h:132
std::unordered_map< etiss::uint64, std::list< BlockLink * > > blockmap_
Definition: Translation.h:150
ETISS_CPU & cpu_
Definition: Translation.h:130
etiss::int32 translateBlock(CodeBlock &cb)
void(* plugins_finalizeCodeBlock_)(etiss::TranslationPlugin **, CodeBlock &)
Function pointer, the function is getting defined in Translation::init via template function etiss::c...
Definition: Translation.h:146
BlockLink * getBlock(BlockLink *prev, const etiss::uint64 &instructionindex)
void(* plugins_initCodeBlock_)(etiss::TranslationPlugin **, CodeBlock &)
Function pointer, the function is getting defined in Translation::init via template function etiss::c...
Definition: Translation.h:140
ETISS_System & system_
Definition: Translation.h:129
stores a bit vector
Definition: Instruction.h:161
void set_value(size_type width, unsigned long value)
change the value the object is holding
unsigned byteCount() const
unsigned intCount() const
Buffer for reading data from memory while instructions are being fetched.
Definition: Instruction.h:92
char * internalBuffer()
get the internal buffer
Definition: Instruction.cpp:69
this class contains parameters that persist in between instruction lookpus/translation within a trans...
Definition: Instruction.h:337
uint64_t current_local_address_
address within the current block
Definition: Instruction.h:367
bool is_not_default_width_
if true the this instruction is not as long as the width of the variable instruction set
Definition: Instruction.h:346
bool force_block_end_
if true then the block ends after the current instruction.
Definition: Instruction.h:353
bool instr_width_fully_evaluated_
if true the length_updater_ function will be called again after instr_width_ bits are available
Definition: Instruction.h:349
uint64_t current_address_
start address of current instruction
Definition: Instruction.h:366
bool force_append_next_instr_
if true then the block will continue with the next instruction and cannot be terminated
Definition: Instruction.h:351
holds etiss::instr::Instruction instances and handles automatic instruction tree creation.
Definition: Instruction.h:442
Instruction * resolve(BitArray &instr)
holds information and translation callbacks for an instruction.
Definition: Instruction.h:393
bool translate(BitArray &, CodeSet &cs, InstructionContext &context)
std::string printASM(BitArray &)
holds etiss::instr::VariableInstructionSet instances for different modes.
Definition: Instruction.h:562
VariableInstructionSet * get(uint32_t mode)
holds etiss::instr::InstructionSet instances with different bit widths.
Definition: Instruction.h:500
InstructionSet * get(unsigned width)
std::function< void(VariableInstructionSet &, InstructionContext &, BitArray &)> length_updater_
Definition: Instruction.h:508
MM_EXPORT const int32_t NOERROR
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
Definition: Benchmark.h:53
std::string jitFiles()
Get ETISS JIT files path.
Definition: Misc.cpp:592
std::vector< std::string > jitExtLibPaths()
Get ETISS JIT external path.
Definition: Misc.cpp:618
std::string toString(const T &val)
conversion of type T to std::string.
Definition: Misc.h:174
static uint64_t genTranslationId()
static std::enable_if< len==pos, void >::type call_initCodeBlock(etiss::TranslationPlugin **ca, CodeBlock &cb)
Definition: Translation.cpp:67
etiss::int32(* ExecBlockCall)(ETISS_CPU *cpu, ETISS_System *system, void **plugin_pointers)
Definition: Translation.h:57
std::vector< std::string > jitExtLibraries()
Get ETISS JIT external libraries.
Definition: Misc.cpp:604
std::vector< std::string > jitExtHeaders()
Get ETISS JIT external headers.
Definition: Misc.cpp:597
std::vector< std::string > jitExtHeaderPaths()
Get ETISS JIT external path.
Definition: Misc.cpp:611
@ ERROR
Definition: Misc.h:127
Configuration & cfg(const std::string &cfgName)
Get reference of the global ETISS configuration object.
Definition: Misc.cpp:560
static void call_initCodeBlock_ul(etiss::TranslationPlugin **ca, CodeBlock &cb)
Definition: Translation.cpp:92
static std::enable_if< len==pos, void >::type call_finalizeCodeBlock(etiss::TranslationPlugin **ca, CodeBlock &cb)
Definition: Translation.cpp:79
static void call_finalizeCodeBlock_ul(etiss::TranslationPlugin **ca, CodeBlock &cb)
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition: Misc.cpp:125
basic cpu state structure needed for execution of any cpu architecture.
Definition: CPU.h:89
etiss_uint32 mode
instruction set mode of the processor
Definition: CPU.h:109
memory access and time synchronization functions.
Definition: System.h:78
void * handle
custom handle that will be passed to the functions of this structure
Definition: System.h:116
etiss_int32(* dbg_read)(void *handle, etiss_uint64 addr, etiss_uint8 *buffer, etiss_uint32 length)
direct debug read
Definition: System.h:104
char Buffer[8]
Definition: xray_records.h:28