ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
TCCJIT.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 "TCCJIT.h"
44 #include "etiss/Misc.h"
45 #include "etiss/config.h"
46 
47 #include "libtcc.h"
48 #if ETISS_USE_GETPROC
49 #include "etiss/ETISS.h"
50 #include <windows.h>
51 #include <dbghelp.h>
52 #include <iostream>
53 
54 BOOL CALLBACK etiss_tcc_allsym(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)
55 {
56  std::map<std::string, void *> &map = *(std::map<std::string, void *> *)UserContext;
58  map.insert(std::pair<std::string, void *>(pSymInfo->Name, (void *)pSymInfo->Address));
59  std::cout << "Found Symbol: " << pSymInfo->Name << "@0x" << std::hex << (void *)pSymInfo->Address << std::endl;
60  return TRUE;
61 }
62 
63 static void addAllSymbols(std::map<std::string, void *> &ptrs)
64 {
65 
66  HANDLE hProcess = GetCurrentProcess();
67  // DWORD64 BaseOfDll;
68  BOOL status;
69 
70  status = SymInitialize(hProcess, NULL, TRUE);
71  if (status == FALSE)
72  {
73  return;
74  }
75 
76  auto libs = etiss::listLibraryPrefixes();
77  for (auto lib : libs)
78  {
79  std::string filter;
80  filter = std::string("*!") + lib + "_*";
81  std::cout << "searching in library " << lib << std::endl;
82  if (SymEnumSymbols(hProcess, // Process handle from SymInitialize.
83  NULL, // Base address of module.
84  filter.c_str(), // Name of symbols to match.
85  etiss_tcc_allsym, // Symbol handler procedure.
86  (PVOID)&ptrs)) // User context.
87  {
88  // SymEnumSymbols succeeded
89  }
90  else
91  {
92  std::cout << "Failed to iterate over all symbols for library " << lib << ":" << GetLastError() << std::endl;
93  }
94  }
95 
96  SymCleanup(hProcess);
97 }
98 
99 #endif
100 
101 TCCJIT::TCCJIT() : JIT("tcc")
102 {
103 #if ETISS_USE_GETPROC
104  addAllSymbols(extsymbols);
105 #endif
106 }
107 
108 void *TCCJIT::translate(std::string code, std::set<std::string> headerpaths, std::set<std::string> librarypaths,
109  std::set<std::string> libraries, std::string &error, bool debug)
110 {
111 
112  TCCState *s = tcc_new();
113  if (!s)
114  {
115  error = "Could not create tcc state";
116  return 0;
117  }
118 
119  /* if tcclib.h and libtcc1.a are not installed, where can we find them */
120  tcc_set_lib_path(s, (etiss::jitFiles() + "/tcc").c_str());
121 
122  // init
123  tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
124 
125  // init headers
126  for (auto iter = headerpaths.begin(); iter != headerpaths.end(); iter++)
127  {
128  tcc_add_include_path(s, iter->c_str());
129  }
130  tcc_add_include_path(s, (etiss::jitFiles() + "/tcc_stdlib").c_str());
131 
132  if (tcc_compile_string(s, code.c_str()) == -1)
133  { // compile
134  error = "Failed to compile code: \n";
135  error += code;
136  return 0;
137  }
138 
139 #if ETISS_USE_GETPROC
140  for (auto sym : extsymbols)
141  {
142  tcc_add_symbol(s, sym.first.c_str(), sym.second);
143  }
144  for (const auto &jitPath : etiss::jitExtLibPaths())
145  {
147  }
148 #endif
149 
150  // init libs
151  for (const auto &libpath : librarypaths)
152  {
153  if (tcc_add_library_path(s, libpath.c_str()))
154  {
155  error += "could not add library path: " + libpath;
156  return 0;
157  }
158  }
159  for (const auto &lib : libraries)
160  {
161  if (tcc_add_library(s, lib.c_str()))
162  {
163  error += "could not add library: " + lib;
164  return 0;
165  }
166  }
167 
168  /* relocate the code */
169  if (tcc_relocate(s, TCC_RELOCATE_AUTO) < 0)
170  { // link
171  error = "Failed to link";
172  return 0;
173  }
174 
175  /* return TCCState as handle*/
176  return (void *)s;
177 }
178 void *TCCJIT::getFunction(void *handle, std::string name, std::string &error)
179 {
180 
181  return tcc_get_symbol((TCCState *)handle, name.c_str());
182 }
183 void TCCJIT::free(void *handle)
184 {
185  tcc_delete((TCCState *)handle);
186 }
Header file of the ETISS library.
general configuration and logging
__device__ __2f16 float bool s
std::map< std::string, void * > extsymbols
only use for windows.
Definition: TCCJIT.h:56
virtual void free(void *handle)
clean up handled returned by etiss::JIT::translate
Definition: TCCJIT.cpp:183
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=false)
translate C code to executable code and return a handle/pointer that identifies the compilation resul...
Definition: TCCJIT.cpp:108
virtual void * getFunction(void *handle, std::string name, std::string &error)
returns a function pointer to a compiled function from the handle returned by etiss::JIT::translate
Definition: TCCJIT.cpp:178
TCCJIT()
Definition: TCCJIT.cpp:101
static void addSearchPath(const std::string &path)
contains defines to configure ETISS.
std::set< std::string > listLibraryPrefixes()
Create a set with strings of the library names.
Definition: ETISS.cpp:333
@ FALSE
Definition: milieu.h:57
@ TRUE
Definition: milieu.h:58
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
#define NULL