2 * kp_load.c - loader for ktap bytecode chunk file
4 * This file is part of ktap by Jovi Zhangwei.
6 * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
8 * Copyright (C) 1994-2013 Lua.org, PUC-Rio.
9 * - The part of code in this file is copied from lua initially.
10 * - lua's MIT license is compatible with GPL.
12 * ktap is free software; you can redistribute it and/or modify it
13 * under the terms and conditions of the GNU General Public License,
14 * version 2, as published by the Free Software Foundation.
16 * ktap is distributed in the hope it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21 * You should have received a copy of the GNU General Public License along with
22 * this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
26 #include <linux/slab.h>
27 #include "../include/ktap_types.h"
28 #include "../include/ktap_ffi.h"
36 #define KTAPC_TAIL "\x19\x93\r\n\x1a\n"
44 #define READ_CHAR(S) (S->buff[S->pos++])
45 #define READ_BYTE(S) READ_CHAR(S)
46 #define READ_INT(S) load_int(S)
47 #define READ_NUMBER(S) load_number(S)
48 #define READ_STRING(S) load_string(S)
49 #define READ_VECTOR(S, dst, size) \
51 memcpy(dst, &S->buff[S->pos], size); \
55 #define NEW_VECTOR(S, size) kp_malloc(S->ks, size)
56 #define FREE_VECTOR(S, v) kp_free(S->ks, v)
57 #define GET_CURRENT(S) &S->buff[S->pos]
58 #define ADD_POS(S, size) S->pos += size
61 static int load_function(struct load_state *S, ktap_proto *f);
64 static int load_int(struct load_state *S)
68 READ_VECTOR(S, &x, sizeof(int));
72 static long load_number(struct load_state *S)
76 READ_VECTOR(S, &x, sizeof(ktap_number));
80 static ktap_string *load_string(struct load_state *S)
90 char *s = GET_CURRENT(S);
92 /* remove trailing '\0' */
93 ts = kp_tstring_newlstr(S->ks, s, size - 1);
99 static int load_code(struct load_state *S, ktap_proto *f)
104 f->code = NEW_VECTOR(S, n * sizeof(ktap_instruction));
105 READ_VECTOR(S, f->code, n * sizeof(ktap_instruction));
110 static int load_constants(struct load_state *S, ktap_proto *f)
117 f->k = NEW_VECTOR(S, n * sizeof(ktap_value));
118 for (i = 0; i < n; i++)
121 for (i=0; i < n; i++) {
122 ktap_value *o = &f->k[i];
124 int t = READ_CHAR(S);
130 set_boolean(o, READ_CHAR(S));
134 * todo: kernel not support fp, check double when
137 set_number(o, READ_NUMBER(S));
140 set_string(o, READ_STRING(S));
143 kp_error(S->ks, "ktap: load_constants: "
144 "unknow ktap_value\n");
151 f->p = NEW_VECTOR(S, n * sizeof(ktap_proto));
153 for (i = 0; i < n; i++)
155 for (i = 0; i < n; i++) {
156 f->p[i] = kp_newproto(S->ks);
157 if (load_function(S, f->p[i]))
165 static int load_upvalues(struct load_state *S, ktap_proto *f)
170 f->upvalues = NEW_VECTOR(S, n * sizeof(ktap_upvaldesc));
173 for (i = 0; i < n; i++)
174 f->upvalues[i].name = NULL;
176 for (i = 0; i < n; i++) {
177 f->upvalues[i].instack = READ_BYTE(S);
178 f->upvalues[i].idx = READ_BYTE(S);
184 static int load_debuginfo(struct load_state *S, ktap_proto *f)
188 f->source = READ_STRING(S);
191 f->lineinfo = NEW_VECTOR(S, n * sizeof(int));
192 READ_VECTOR(S, f->lineinfo, n * sizeof(int));
194 f->locvars = NEW_VECTOR(S, n * sizeof(struct ktap_locvar));
196 for (i = 0; i < n; i++)
197 f->locvars[i].varname = NULL;
198 for (i = 0; i < n; i++) {
199 f->locvars[i].varname = READ_STRING(S);
200 f->locvars[i].startpc = READ_INT(S);
201 f->locvars[i].endpc = READ_INT(S);
204 for (i = 0; i < n; i++)
205 f->upvalues[i].name = READ_STRING(S);
210 static int load_function(struct load_state *S, ktap_proto *f)
212 f->linedefined = READ_INT(S);
213 f->lastlinedefined = READ_INT(S);
214 f->numparams = READ_BYTE(S);
215 f->is_vararg = READ_BYTE(S);
216 f->maxstacksize = READ_BYTE(S);
219 if (load_constants(S, f))
221 if (load_upvalues(S, f))
223 if (load_debuginfo(S, f))
230 #define error(S, why) \
231 kp_error(S->ks, "load failed: %s precompiled chunk\n", why)
233 #define N0 KTAPC_HEADERSIZE
234 #define N1 (sizeof(KTAP_SIGNATURE) - sizeof(char))
238 static int load_header(struct load_state *S)
240 u8 h[KTAPC_HEADERSIZE];
241 u8 s[KTAPC_HEADERSIZE];
244 READ_VECTOR(S, s, KTAPC_HEADERSIZE);
246 if (memcmp(h, s, N0) == 0)
248 if (memcmp(h, s, N1) != 0)
250 else if (memcmp(h, s, N2) != 0)
251 error(S, "version mismatch in");
252 else if (memcmp(h, s, N3) != 0)
253 error(S, "incompatible");
255 error(S,"corrupted");
260 #ifdef CONFIG_KTAP_FFI
261 void ffi_set_csym_arr(ktap_state *ks, int cs_nr, csymbol *new_arr);
263 static void load_csymbol_func(struct load_state *S, csymbol *cs)
265 csymbol_func *csf = csym_func(cs);
266 int arg_nr = csymf_arg_nr(csf);
269 csf->arg_ids = NEW_VECTOR(S, arg_nr*sizeof(int));
270 READ_VECTOR(S, csf->arg_ids, arg_nr*sizeof(int));
276 static void load_csymbol_struct(struct load_state *S, csymbol *cs)
278 csymbol_struct *csst = csym_struct(cs);
279 int mb_nr = csymst_mb_nr(csst);
281 csst->members = NEW_VECTOR(S, mb_nr*sizeof(struct_member));
282 READ_VECTOR(S, csst->members, mb_nr*sizeof(struct_member));
285 static int load_csymbols(struct load_state *S)
287 csymbol *cs_arr, *cs;
290 /* read number of csymbols */
291 csym_nr = READ_INT(S);
293 ffi_set_csym_arr(S->ks, 0, NULL);
297 /* csymbol size safty check */
298 if (sizeof(csymbol) != READ_INT(S)) {
299 kp_error(S->ks, "invalid csymbol size in chunk\n");
303 cs_arr = NEW_VECTOR(S, sizeof(csymbol)*csym_nr);
304 for (i = 0; i < csym_nr; i++) {
306 READ_VECTOR(S, cs, sizeof(csymbol));
309 load_csymbol_func(S, cs);
312 load_csymbol_struct(S, cs);
319 ffi_set_csym_arr(S->ks, csym_nr, cs_arr);
324 static int load_csymbols(struct load_state *S)
326 int csym_nr = READ_INT(S);
328 /* if FFI is disabled in ktapc, csym_nr should be 0 */
330 /* skip corrupted csymbol chunk */
331 int cs_size = READ_INT(S);
332 ADD_POS(S, cs_size*csym_nr);
333 kp_error(S->ks, "VM compiled without FFI support!\n");
341 static int verify_code(struct load_state *S, ktap_proto *f)
343 /* not support now */
348 ktap_closure *kp_load(ktap_state *ks, unsigned char *buff)
358 ret = load_header(&S);
362 ret = load_csymbols(&S);
366 cl = kp_newclosure(ks, 1);
370 /* put closure on the top, prepare to run with this closure */
371 set_closure(ks->top, cl);
374 cl->p = kp_newproto(ks);
375 if (load_function(&S, cl->p))
378 if (cl->p->sizeupvalues != 1) {
379 ktap_proto *p = cl->p;
380 cl = kp_newclosure(ks, cl->p->sizeupvalues);
382 set_closure(ks->top - 1, cl);
385 for (i = 0; i < cl->nupvalues; i++) { /* initialize upvalues */
386 ktap_upval *up = kp_newupval(ks);
390 /* set global table as 1st upvalue of 'f' */
391 if (cl->nupvalues == 1) {
392 ktap_tab *reg = hvalue(&G(ks)->registry);
393 const ktap_value *gt = kp_tab_getint(reg, KTAP_RIDX_GLOBALS);
394 set_obj(cl->upvals[0]->v, gt);
397 verify_code(&S, cl->p);