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 
322  #ifdef ETISS_USE_COREDSL_COVERAGE
323  block.fileglobalCode().insert("#define ETISS_USE_COREDSL_COVERAGE");
324  #endif
325 
326  block.fileglobalCode().insert("#include \"etiss/jit/CPU.h\"\n"
327  "#include \"etiss/jit/System.h\"\n"
328  "#include \"etiss/jit/libresources.h\"\n"
329  "#include \"etiss/jit/libsemihost.h\"\n"
330  "#include \"etiss/jit/ReturnCode.h\"\n"
331  "#include \"etiss/jit/libCSRCounters.h\"\n");
332 
333  for(auto &it: jitExtHeaders()){
334  if(it != "") block.fileglobalCode().insert("#include \"" + it + "\"\n");
335  }
336 
337  block.functionglobalCode().insert("if (cpu->mode != " + toString(cpu_.mode) +
338  ") return ETISS_RETURNCODE_RELOADCURRENTBLOCK;");
339 
341 
342  etiss::int32 transerror = translateBlock(block);
343 
344  if (transerror != ETISS_RETURNCODE_NOERROR)
345  {
346  etiss::log(etiss::ERROR, "Failed to translate block");
347  return nullptr;
348  }
349 
351 
352  std::string code;
353  {
354  std::stringstream ss;
355  block.toCode(ss, blockfunctionname, nullptr);
356  code = ss.str();
357  }
358 
359  // various includes
360  std::set<std::string> headers;
361  headers.insert(etiss::jitFiles());
362  headers.insert(arch_->getIncludePath());
363  for(auto & it: jitExtHeaderPaths()){
364  if(it != "") headers.insert(it);
365  }
366 
367  std::set<std::string> libloc;
368  libloc.insert(arch_->getIncludePath());
369  libloc.insert(etiss::cfg().get<std::string>("etiss_path", "./"));
370  libloc.insert(etiss::jitFiles());
371  libloc.insert(etiss::jitFiles() + "/etiss/jit");
372  for(auto & it: jitExtLibPaths()){
373  if(it != "") libloc.insert(etiss::jitFiles() + it);
374  }
375 
376  std::set<std::string> libs;
377  //libs.insert("ETISS");
378  libs.insert("resources");
379  libs.insert("semihost");
380  libs.insert("CSRCounters");
381  for(auto & it: jitExtLibraries()){
382  if(it != "") libs.insert(it);
383  }
384  /* DEBUG HELPER: write code files to work directory
385  {
386  static unsigned count = 0;
387  std::stringstream ss;
388  ss << "code" << ++count;
389  std::ofstream out;
390  out.open(ss.str().c_str());
391  out << code;
392  std::cout << "Code file " << count << std::endl;
393  }
394  */
395 #ifndef ETISS_DEBUG
396 #define ETISS_DEBUG 1
397 #endif
398  // compile library
399  void *funcs =
400  jit_->translate(code, headers, libloc, libs, error, etiss::cfg().get<bool>("jit.debug", ETISS_DEBUG) != 0);
401 
402  if (funcs == 0)
403  {
404  etiss::log(etiss::ERROR, error);
405  return 0;
406  }
407 
408  // wrap library handle for cleanup
409  auto local_jit = jit_;
410  std::shared_ptr<void> lib(funcs, [local_jit](void *p) { local_jit->free(p); });
411 
412  // check function/library handle
413  if (lib.get() != 0)
414  {
415  // std::cout<<"blockfunctionname:"<<blockfunctionname<<std::endl;
416  ExecBlockCall execBlock = (ExecBlockCall)jit_->getFunction(lib.get(), blockfunctionname.c_str(), error);
417  if (execBlock != 0)
418  {
419  BlockLink *nbl = new BlockLink(block.startindex_, block.endaddress_, execBlock, lib);
420  uint64 ii9 = instructionindex >> 9;
421  do
422  {
423  blockmap_[ii9].push_back(nbl);
424  BlockLink::incrRef(nbl); // map holds a reference
425  ii9++;
426  } while ((ii9 << 9) < block.endaddress_);
427 
428  if (prev != 0)
429  {
430  if (nbl->start == prev->end)
431  {
432  BlockLink::updateRef(prev->next, nbl);
433  }
434  else
435  {
436  BlockLink::updateRef(prev->branch, nbl);
437  }
438  }
439  return nbl;
440  }
441  else
442  {
443  etiss::log(etiss::ERROR, std::string("Failed to acquire function pointer from compiled library:") + error);
444  return 0;
445  }
446  }
447 
448  return 0;
449 }
453 {
454  cb.endaddress_ = cb.startindex_;
455 
457 
458  context.cf_delay_slot_ = 0;
459  context.force_block_end_ = false;
460 
461  unsigned count = 0;
462  const unsigned maxcount = etiss::cfg().get<unsigned>("etiss.max_block_size", 100);
463  cb.reserve(maxcount);
464 
466 
467  if (vis_ == nullptr)
468  {
469  return etiss::RETURNCODE::GENERALERROR;
470  }
471 
472  etiss::instr::BitArray mainba(vis_->width_);
473  etiss::instr::Buffer buffer;
474 
475  do
476  {
477  context.force_append_next_instr_ = false;
478  context.force_block_end_ = false;
479  context.current_address_ = cb.endaddress_;
481  context.instr_width_fully_evaluated_ = true;
482  context.is_not_default_width_ = false;
483  context.instr_width_ = vis_->width_;
484 
485  etiss::instr::BitArray errba(32, 0);
486 
487  buffer = etiss::instr::Buffer(mainba.intCount());
488  // read instruction
489  etiss::int32 ret = (*system_.dbg_read)(system_.handle, cb.endaddress_, (etiss_uint8*)buffer.internalBuffer(), mainba.byteCount()); // read instruction
490  mainba.set_value(buffer.data());
491  if (ret == etiss::RETURNCODE::IBUS_READ_ERROR || ret == etiss::RETURNCODE::DBUS_READ_ERROR)
492  {
493  std::cout << "Instruction bus read error while translating!" << std::endl;
494  errba.set_value(etiss::RETURNCODE::IBUS_READ_ERROR);
495  // std::cout << "mainba.byteCount = " << mainba.byteCount() << std::endl;
496  auto instr = &vis_->getMain()->getInvalid();
497  CodeBlock::Line &line = cb.append(cb.endaddress_); // allocate codeset for instruction
498  bool ok = instr->translate(errba, line.getCodeSet(), context);
499  if (unlikely(!ok)) {
500  return etiss::RETURNCODE::GENERALERROR;
501  }
502  cb.endaddress_ += mainba.byteCount(); // update end address
504  }
505  if (ret != etiss::RETURNCODE::NOERROR)
506  {
507  if (count == 0)
508  {
509  return ret; // empty block -> return error
510  }
511  else
512  {
513  break; // non empty block -> compile pending
514  }
515  }
516 
517  arch_->compensateEndianess(&cpu_, mainba);
518  vis_->length_updater_(*vis_, context, mainba);
519 
520  // continue reading instruction data if neccessary
521  if (unlikely(context.is_not_default_width_))
522  {
523  etiss::instr::BitArray *secba = nullptr;
524  do
525  {
526  if (secba)
527  delete secba;
528  secba = new etiss::instr::BitArray(context.instr_width_);
529 
530  buffer = etiss::instr::Buffer(secba->intCount());
531  ret = (*system_.dbg_read)(system_.handle, cb.endaddress_, (etiss_uint8*)buffer.internalBuffer(), secba->byteCount()); // read instruction
532  secba->set_value(buffer.data());
533 
534  if (ret != etiss::RETURNCODE::NOERROR)
535  {
536  if (count == 0)
537  {
538  delete secba;
539  return ret; // empty block -> return error
540  }
541  else
542  {
543  break; // non empty block -> compile pending
544  }
545  }
546  arch_->compensateEndianess(&cpu_, *secba);
547  vis_->length_updater_(*vis_, context, *secba);
548  } while (!context.instr_width_fully_evaluated_);
549 
551  etiss::instr::InstructionSet *instrSet = vis_->get(secba->size());
552  if (unlikely(!instrSet))
553  {
554  errba.set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
555  instr = &vis_->getMain()->getInvalid();
556  }
557  else
558  {
559  instr = instrSet->resolve(*secba);
560  if (unlikely(!instr))
561  {
562  errba.set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
563  instr = &instrSet->getInvalid();
564  }
565  }
566  CodeBlock::Line &line = cb.append(cb.endaddress_); // allocate codeset for instruction
567  bool ok = instr->translate(errba != etiss::instr::BitArray(32, 0) ? errba : *secba, line.getCodeSet(), context);
568  if (unlikely(!ok))
569  {
570  delete secba;
571  return etiss::RETURNCODE::GENERALERROR;
572  }
573  cb.endaddress_ += secba->byteCount(); // update end address
574  delete secba;
575  }
576  else
577  {
578  etiss::instr::InstructionSet *instrSet = vis_->getMain();
579  etiss::instr::Instruction *instr = instrSet->resolve(mainba);
580  if (unlikely(instr == 0))
581  {
582  errba.set_value(etiss::RETURNCODE::ILLEGALINSTRUCTION);
583  instr = &instrSet->getInvalid();
584  }
585  CodeBlock::Line &line = cb.append(cb.endaddress_); // allocate codeset for instruction
586  bool ok = instr->translate(errba != etiss::instr::BitArray(32, 0) ? errba : mainba, line.getCodeSet(), context);
587  if (unlikely(!ok))
588  {
589  return etiss::RETURNCODE::GENERALERROR;
590  }
591  cb.endaddress_ += mainba.byteCount(); // update end address
592  }
593 
594  count++;
595  } while ((count < maxcount && !context.force_block_end_) || context.force_append_next_instr_);
596 
598 }
599 
601 {
602  for (auto &entry:blockmap_)
603  {
604  entry.second.erase(std::remove_if(entry.second.begin(), entry.second.end(),
605  [](auto &bl)
606  {
607  bl->valid = false;
608  BlockLink::updateRef(bl->next, 0);
609  BlockLink::updateRef(bl->branch, 0);
610  BlockLink::decrRef(bl); // remove reference of map
611  return true;
612  }),
613  entry.second.end());
614  }
615  blockmap_.clear();
616 }
617 
619 {
620  // Hotfix: if everything needs to be deleted, new function unloadBlocksAll()
621  if (startindex == 0 && endindex == ((etiss::uint64)((etiss::int64)-1)))
622  {
623  unloadBlocksAll();
624  return;
625  }
626 
627  const etiss::uint64 startindexblock = startindex >> 9;
628  const etiss::uint64 endindexblock = (endindex >> 9) + ((((endindex >> 9) << 9) == endindex) ? 0 : 1);
629  for (etiss::uint64 block = startindexblock; block < endindexblock; block++)
630  {
631  if (blockmap_.empty())
632  break;
633  auto entry = blockmap_.find(block);
634  if (entry != blockmap_.end())
635  {
636  for (std::list<BlockLink *>::iterator iter = entry->second.begin(); iter != entry->second.end();)
637  {
638  BlockLink *bl = *iter;
639  if (bl->start < endindex || bl->end > startindex)
640  {
641  bl->valid = false;
642  BlockLink::updateRef(bl->next, 0);
644  entry->second.erase(iter++);
645  BlockLink::decrRef(bl); // remove reference of map
646  }
647  else
648  {
649  iter++;
650  }
651  }
652  if (entry->second.empty())
653  blockmap_.erase(entry);
654  }
655  }
656 }
657 
658 std::string Translation::disasm(uint8_t *buf, unsigned len, int &append)
659 {
660  etiss::instr::BitArray mainba(len * 8);
661  etiss::instr::Buffer buffer(mainba.intCount());
662 
663  memcpy(buffer.internalBuffer(), buf, len);
664  mainba.set_value(buffer.data());
665 
666  // TODO implement propper instruction selection with append requests is neccessary
667 
669 
670  if (vis == 0)
671  return "UNKNOWN";
672 
673  etiss::instr::InstructionSet *is = vis->get(len * 8);
674 
675  if (is == 0)
676  return "UNKNOWN";
677 
678  etiss::instr::Instruction *instr = is->resolve(mainba);
679 
680  if (instr == 0)
681  return "UNKNOWN";
682 
683  return instr->printASM(mainba);
684 }
685 
686 } // 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