2 * kp_obj.c - ktap object generic operation
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 "../include/ktap_types.h"
27 #include "../include/ktap_ffi.h"
33 #include <linux/slab.h>
36 #include "kp_transport.h"
38 #define KTAP_ALLOC_FLAGS ((GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN) \
41 void *kp_malloc(ktap_state *ks, int size)
46 * Normally we don't want to trace under memory pressure,
47 * so we use a simple rule to handle memory allocation failure:
49 * retry until allocation success, this will make caller don't need
50 * to handle the unlikely failure case, then ktap exit.
52 * In this approach, if user find there have memory allocation failure,
53 * user should re-run the ktap script, or fix the memory pressure
54 * issue, or figure out why the script need so many memory.
56 * Perhaps return pre-allocated stub memory trunk when allocate failed
57 * is a better approch?
59 addr = kmalloc(size, KTAP_ALLOC_FLAGS);
60 if (unlikely(!addr)) {
61 kp_error(ks, "kmalloc size %d failed, retry again\n", size);
62 printk("ktap kmalloc size %d failed, retry again\n", size);
65 addr = kmalloc(size, KTAP_ALLOC_FLAGS);
69 kp_printf(ks, "kmalloc retry success after failed, exit\n");
73 KTAP_STATS(ks)->nr_mem_allocate += 1;
74 KTAP_STATS(ks)->mem_allocated += size;
80 void kp_free(ktap_state *ks, void *addr)
83 KTAP_STATS(ks)->nr_mem_free += 1;
89 void *kp_reallocv(ktap_state *ks, void *addr, int oldsize, int newsize)
93 new_addr = krealloc(addr, newsize, KTAP_ALLOC_FLAGS);
94 if (unlikely(!new_addr)) {
95 kp_error(ks, "krealloc size %d failed, retry again\n", newsize);
96 printk("ktap krealloc size %d failed, retry again\n", newsize);
99 new_addr = krealloc(addr, newsize, KTAP_ALLOC_FLAGS);
103 kp_printf(ks, "krealloc retry success after failed, exit\n");
108 KTAP_STATS(ks)->nr_mem_allocate += 1;
110 KTAP_STATS(ks)->mem_allocated += newsize - oldsize;
116 void *kp_zalloc(ktap_state *ks, int size)
120 addr = kzalloc(size, KTAP_ALLOC_FLAGS);
121 if (unlikely(!addr)) {
122 kp_error(ks, "kzalloc size %d failed, retry again\n", size);
123 printk("ktap kzalloc size %d failed, retry again\n", size);
126 addr = kzalloc(size, KTAP_ALLOC_FLAGS);
130 kp_printf(ks, "kzalloc retry success after failed, exit\n");
134 KTAP_STATS(ks)->nr_mem_allocate += 1;
135 KTAP_STATS(ks)->mem_allocated += size;
142 void kp_obj_dump(ktap_state *ks, const ktap_value *v)
149 kp_printf(ks, "NUMBER %ld", nvalue(v));
152 kp_printf(ks, "BOOLEAN %d", bvalue(v));
154 case KTAP_TLIGHTUSERDATA:
155 kp_printf(ks, "LIGHTUSERDATA 0x%lx", (unsigned long)pvalue(v));
157 case KTAP_TCFUNCTION:
158 kp_printf(ks, "LIGHTCFCUNTION 0x%lx", (unsigned long)fvalue(v));
162 kp_printf(ks, "SHRSTR #%s", svalue(v));
165 kp_printf(ks, "TABLE 0x%lx", (unsigned long)hvalue(v));
168 kp_printf(ks, "GCVALUE 0x%lx", (unsigned long)gcvalue(v));
174 #include <linux/stacktrace.h>
175 #include <linux/module.h>
176 #include <linux/kallsyms.h>
178 static void kp_btrace_dump(ktap_state *ks, ktap_btrace *bt)
180 char str[KSYM_SYMBOL_LEN];
181 unsigned long *entries = (unsigned long *)(bt + 1);
184 for (i = 0; i < bt->nr_entries; i++) {
185 unsigned long p = entries[i];
190 SPRINT_SYMBOL(str, p);
191 kp_printf(ks, "%s\n", str);
195 static int kp_btrace_equal(ktap_btrace *bt1, ktap_btrace *bt2)
197 unsigned long *entries1 = (unsigned long *)(bt1 + 1);
198 unsigned long *entries2 = (unsigned long *)(bt2 + 1);
201 if (bt1->nr_entries != bt2->nr_entries)
204 for (i = 0; i < bt1->nr_entries; i++) {
205 if (entries1[i] != entries2[i])
213 void kp_showobj(ktap_state *ks, const ktap_value *v)
220 kp_printf(ks, "%ld", nvalue(v));
223 kp_puts(ks, (bvalue(v) == 1) ? "true" : "false");
225 case KTAP_TLIGHTUSERDATA:
226 kp_printf(ks, "0x%lx", (unsigned long)pvalue(v));
228 case KTAP_TCFUNCTION:
229 kp_printf(ks, "0x%lx", (unsigned long)fvalue(v));
233 kp_puts(ks, svalue(v));
236 kp_tab_dump(ks, hvalue(v));
239 #ifdef CONFIG_KTAP_FFI
241 kp_cdata_dump(ks, cdvalue(v));
245 kp_transport_event_write(ks, evalue(v));
248 kp_btrace_dump(ks, btvalue(v));
251 kp_ptab_dump(ks, phvalue(v));
254 kp_statdata_dump(ks, sdvalue(v));
258 kp_error(ks, "print unknown value type: %d\n", ttype(v));
265 * equality of ktap values. ks == NULL means raw equality
267 int kp_equalobjv(ktap_state *ks, const ktap_value *t1, const ktap_value *t2)
273 return nvalue(t1) == nvalue(t2);
275 return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
276 case KTAP_TLIGHTUSERDATA:
277 return pvalue(t1) == pvalue(t2);
278 case KTAP_TCFUNCTION:
279 return fvalue(t1) == fvalue(t2);
281 return eqshrstr(rawtsvalue(t1), rawtsvalue(t2));
283 return kp_tstring_eqlngstr(rawtsvalue(t1), rawtsvalue(t2));
285 if (hvalue(t1) == hvalue(t2))
291 return kp_btrace_equal(btvalue(t1), btvalue(t2));
294 return gcvalue(t1) == gcvalue(t2);
301 * ktap will not use lua's length operator on table meaning,
302 * also # is not for length operator any more in ktap.
304 int kp_objlen(ktap_state *ks, const ktap_value *v)
308 return kp_tab_length(ks, hvalue(v));
310 return rawtsvalue(v)->tsv.len;
312 kp_printf(ks, "cannot get length of type %d\n", v->type);
318 /* need to protect allgc field? */
319 ktap_gcobject *kp_newobject(ktap_state *ks, int type, size_t size,
320 ktap_gcobject **list)
324 o = kp_malloc(ks, size);
326 list = &G(ks)->allgc;
329 gch(o)->next = *list;
335 ktap_upval *kp_newupval(ktap_state *ks)
339 uv = &kp_newobject(ks, KTAP_TUPVAL, sizeof(ktap_upval), NULL)->uv;
340 uv->v = &uv->u.value;
345 static ktap_btrace *kp_newbacktrace(ktap_state *ks, int nr_entries,
346 ktap_gcobject **list)
349 int size = sizeof(ktap_btrace) + nr_entries * sizeof(unsigned long);
351 bt = &kp_newobject(ks, KTAP_TBTRACE, size, list)->bt;
352 bt->nr_entries = nr_entries;
356 void kp_objclone(ktap_state *ks, const ktap_value *o, ktap_value *newo,
357 ktap_gcobject **list)
360 int nr_entries = btvalue(o)->nr_entries;
363 bt = kp_newbacktrace(ks, nr_entries, list);
364 memcpy((unsigned long *)(bt + 1), btvalue(o) + 1,
365 nr_entries * sizeof(unsigned long));
366 set_btrace(newo, bt);
368 kp_error(ks, "cannot clone ktap value type %d\n", ttype(o));
373 ktap_closure *kp_newclosure(ktap_state *ks, int n)
377 cl = (ktap_closure *)kp_newobject(ks, KTAP_TCLOSURE, sizeof(*cl), NULL);
381 cl->upvals[n] = NULL;
386 static void free_proto(ktap_state *ks, ktap_proto *f)
388 kp_free(ks, f->code);
391 kp_free(ks, f->lineinfo);
392 kp_free(ks, f->locvars);
393 kp_free(ks, f->upvalues);
397 ktap_proto *kp_newproto(ktap_state *ks)
400 f = (ktap_proto *)kp_newobject(ks, KTAP_TPROTO, sizeof(*f), NULL);
418 f->lastlinedefined = 0;
423 void kp_free_gclist(ktap_state *ks, ktap_gcobject *o)
429 switch (gch(o)->tt) {
431 kp_tab_free(ks, (ktap_tab *)o);
434 free_proto(ks, (ktap_proto *)o);
438 kp_ptab_free(ks, (ktap_ptab *)o);
448 void kp_free_all_gcobject(ktap_state *ks)
450 kp_free_gclist(ks, G(ks)->allgc);
454 /******************************************************************************/
457 * make header for precompiled chunks
458 * if you change the code below be sure to update load_header and FORMAT above
459 * and KTAPC_HEADERSIZE in ktap_types.h
461 void kp_header(u8 *h)
465 memcpy(h, KTAP_SIGNATURE, sizeof(KTAP_SIGNATURE) - sizeof(char));
466 h += sizeof(KTAP_SIGNATURE) - sizeof(char);
469 *h++ = (u8)(*(char*)&x); /* endianness */
470 *h++ = (u8)(sizeof(int));
471 *h++ = (u8)(sizeof(size_t));
472 *h++ = (u8)(sizeof(ktap_instruction));
473 *h++ = (u8)(sizeof(ktap_number));
474 *h++ = (u8)(((ktap_number)0.5) == 0); /* is ktap_number integral? */
475 memcpy(h, KTAPC_TAIL, sizeof(KTAPC_TAIL) - sizeof(char));