Miasm2
 All Classes Namespaces Files Functions Variables Typedefs Properties Macros
Jittcc.c
Go to the documentation of this file.
1 /*
2 ** Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net>
3 **
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 of the License, or
7 ** (at your option) any later version.
8 **
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ** GNU General Public License for more details.
13 **
14 ** You should have received a copy of the GNU General Public License along
15 ** with this program; if not, write to the Free Software Foundation, Inc.,
16 ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18 #include <Python.h>
19 
20 #include <inttypes.h>
21 #include <libtcc.h>
22 
23 #include <stdint.h>
24 
25 
26 
28 char **include_array = NULL;
29 
30 
32 char **lib_array = NULL;
33 
34 //char *libcodenat_path = NULL;
35 
36 
37 TCCState * tcc_init_state(void)
38 {
39  int i;
40  TCCState *tcc_state = NULL;
41  tcc_state = tcc_new();
42  if (!tcc_state) {
43  fprintf(stderr, "Impossible de creer un contexte TCC\n");
44  exit(1);
45  }
46  tcc_set_output_type(tcc_state, TCC_OUTPUT_MEMORY);
47 
48  //tcc_add_file(tcc_state, libcodenat_path);
49  for (i=0;i<lib_array_count; i++){
50  tcc_add_file(tcc_state, lib_array[i]);
51  }
52 
53  for (i=0;i<include_array_count; i++){
54  tcc_add_include_path(tcc_state, include_array[i]);
55  }
56  return tcc_state;
57 }
58 
59 
60 PyObject* tcc_end(PyObject* self, PyObject* args)
61 {
62  TCCState *tcc_state = NULL;
63  if (!PyArg_ParseTuple(args, "K", &tcc_state))
64  return NULL;
65  tcc_delete(tcc_state);
66 
67  Py_INCREF(Py_None);
68  return Py_None;
69 }
70 
71 PyObject* tcc_set_emul_lib_path(PyObject* self, PyObject* args)
72 {
73  char* include_arg;
74  char* lib_arg;
75 
76  char* str1, * str2, * init_ptr;
77  if (!PyArg_ParseTuple(args, "ss",
78  &include_arg,
79  &lib_arg))
80  return NULL;
81 
82  init_ptr = str2 = strdup(include_arg);
83  while (str2){
84  str1 = strsep(&str2, ";");
85  if (str1){
87  include_array = realloc(include_array,
88  include_array_count * sizeof(char*));
89  include_array[include_array_count-1] = strdup(str1);
90  // fprintf(stderr, "adding include file: %s\n", str1);
91  }
92  }
93  if (init_ptr != NULL)
94  free(init_ptr);
95 
96  init_ptr = str2 = strdup(lib_arg);
97  while (str2){
98  str1 = strsep(&str2, ";");
99  if (str1){
100  lib_array_count ++;
101  lib_array = realloc(lib_array,
102  lib_array_count * sizeof(char*));
103  lib_array[lib_array_count-1] = strdup(str1);
104  // fprintf(stderr, "adding lib file: %s\n", str1);
105  }
106  }
107  if (init_ptr != NULL)
108  free(init_ptr);
109 
110 
111  /*
112  libcodenat_path = (char*)malloc(strlen(libcodenat_path_arg)+1);
113  strcpy(libcodenat_path, libcodenat_path_arg);
114  */
115  Py_INCREF(Py_None);
116 
117 
118  return Py_None;
119 }
120 
121 
122 typedef struct {
123  uint8_t is_local;
124  uint64_t address;
125 } block_id;
126 
127 typedef int (*jitted_func)(block_id*, PyObject*);
128 
129 
130 PyObject* tcc_exec_bloc(PyObject* self, PyObject* args)
131 {
132  jitted_func func;
133  PyObject* jitcpu;
134  PyObject* func_py;
135  PyObject* lbl2ptr;
136  PyObject* breakpoints;
137  PyObject* retaddr = NULL;
138  int status;
139  block_id BlockDst;
140 
141  if (!PyArg_ParseTuple(args, "OOOO", &retaddr, &jitcpu, &lbl2ptr, &breakpoints))
142  return NULL;
143 
144  /* The loop will decref retaddr always once */
145  Py_INCREF(retaddr);
146 
147  for (;;) {
148  // Init
149  BlockDst.is_local = 0;
150  BlockDst.address = 0;
151 
152  // Get the expected jitted function address
153  func_py = PyDict_GetItem(lbl2ptr, retaddr);
154  if (func_py)
155  func = (jitted_func) PyInt_AsLong((PyObject*) func_py);
156  else {
157  if (BlockDst.is_local == 1) {
158  fprintf(stderr, "return on local label!\n");
159  exit(1);
160  }
161  // retaddr is not jitted yet
162  return retaddr;
163  }
164 
165  // Execute it
166  status = func(&BlockDst, jitcpu);
167  Py_DECREF(retaddr);
168  retaddr = PyLong_FromUnsignedLongLong(BlockDst.address);
169 
170  // Check exception
171  if (status)
172  return retaddr;
173 
174  // Check breakpoint
175  if (PyDict_Contains(breakpoints, retaddr))
176  return retaddr;
177  }
178 }
179 
180 PyObject* tcc_compil(PyObject* self, PyObject* args)
181 {
182  char* func_name;
183  char* func_code;
184  int (*entry)(void);
185  TCCState *tcc_state = NULL;
186  PyObject* ret;
187 
188  tcc_state = tcc_init_state();
189 
190  if (!PyArg_ParseTuple(args, "ss", &func_name, &func_code))
191  return NULL;
192 
193  if (tcc_compile_string(tcc_state, func_code) != 0) {
194  fprintf(stderr, "Erreur de compilation !\n");
195  fprintf(stderr, "%s\n", func_code);
196  exit(1);
197  }
198  /* XXX configure tinycc install with --disable-static */
199  if (tcc_relocate(tcc_state, TCC_RELOCATE_AUTO) < 0) {
200  fprintf(stderr, "tcc relocate error\n");
201  exit(1);
202  }
203  entry = tcc_get_symbol(tcc_state, func_name);
204  if (!entry){
205  fprintf(stderr, "Erreur de symbole %s!\n", func_name);
206  fprintf(stderr, "%s\n", func_name);
207  exit(1);
208  }
209 
210  ret = PyTuple_New(2);
211  if (ret == NULL) {
212  fprintf(stderr, "Erreur alloc %s!\n", func_name);
213  fprintf(stderr, "%s\n", func_name);
214  exit(1);
215  }
216 
217  PyTuple_SetItem(ret, 0, PyLong_FromUnsignedLongLong((uint64_t)tcc_state));
218  PyTuple_SetItem(ret, 1, PyLong_FromUnsignedLongLong((uint64_t)entry));
219 
220  return ret;
221 
222 }
223 
224 
225 
226 PyObject* tcc_loop_exec(PyObject* self, PyObject* args)
227 {
228  //PyObject* (*func)(void*, void*);
229  uint64_t* vm;
230  uint64_t* cpu;
231  PyObject* ret;
232  PyObject* func;
233  PyObject* pArgs;
234 
235 
236  if (!PyArg_ParseTuple(args, "OKK", &func, &cpu, &vm))
237  return NULL;
238 
239  while (1) {
240  if (!PyCallable_Check (func)) {
241  fprintf(stderr, "function not callable!\n");
242  exit(0);
243  }
244 
245  pArgs = PyTuple_New(2);
246  PyTuple_SetItem(pArgs, 0, PyLong_FromUnsignedLongLong((uint64_t)cpu));
247  PyTuple_SetItem(pArgs, 1, PyLong_FromUnsignedLongLong((uint64_t)vm));
248  ret = PyObject_CallObject(func, pArgs);
249  Py_DECREF(2);
250 
251  if (ret == Py_None) {
252  Py_INCREF(Py_None);
253  return Py_None;
254  }
255  func = ret;
256  }
257 
258  return ret;
259 }
260 
261 
262 
263 static PyObject *TccError;
264 
265 
266 static PyMethodDef TccMethods[] = {
267  {"tcc_set_emul_lib_path", tcc_set_emul_lib_path, METH_VARARGS,
268  "init tcc path"},
269  {"tcc_exec_bloc", tcc_exec_bloc, METH_VARARGS,
270  "tcc exec bloc"},
271  {"tcc_compil", tcc_compil, METH_VARARGS,
272  "tcc compil"},
273  {"tcc_end", tcc_end, METH_VARARGS,
274  "tcc end"},
275  {NULL, NULL, 0, NULL} /* Sentinel */
276 };
277 
278 PyMODINIT_FUNC
280 {
281  PyObject *m;
282 
283  m = Py_InitModule("Jittcc", TccMethods);
284  if (m == NULL)
285  return;
286 
287  TccError = PyErr_NewException("tcc.error", NULL, NULL);
288  Py_INCREF(TccError);
289  PyModule_AddObject(m, "error", TccError);
290 }
291 
static PyObject * TccError
Definition: Jittcc.c:263
PyObject * tcc_set_emul_lib_path(PyObject *self, PyObject *args)
Definition: Jittcc.c:71
uint8_t is_local
Definition: JitCore.h:89
char ** include_array
Definition: Jittcc.c:28
PyObject * tcc_exec_bloc(PyObject *self, PyObject *args)
Definition: Jittcc.c:130
PyObject * tcc_loop_exec(PyObject *self, PyObject *args)
Definition: Jittcc.c:226
PyMODINIT_FUNC initJittcc(void)
Definition: Jittcc.c:279
char ** lib_array
Definition: Jittcc.c:32
int include_array_count
Definition: Jittcc.c:27
PyObject * tcc_end(PyObject *self, PyObject *args)
Definition: Jittcc.c:60
static PyMethodDef TccMethods[]
Definition: Jittcc.c:266
int lib_array_count
Definition: Jittcc.c:31
PyObject * tcc_compil(PyObject *self, PyObject *args)
Definition: Jittcc.c:180
TCCState * tcc_init_state(void)
Definition: Jittcc.c:37
int(* jitted_func)(block_id *, PyObject *)
Definition: Jittcc.c:127
uint64_t address
Definition: JitCore.h:90