Merge tag 'v3.14.25' into backport/v3.14.24-ltsi-rc1+v3.14.25/snapshot-merge.wip
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / staging / ktap / runtime / kp_obj.c
1 /*
2  * kp_obj.c - ktap object generic operation
3  *
4  * This file is part of ktap by Jovi Zhangwei.
5  *
6  * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
7  *
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.
11  *
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.
15  *
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
19  * more details.
20  *
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.
24  */
25
26 #include "../include/ktap_types.h"
27 #include "../include/ktap_ffi.h"
28 #include "kp_obj.h"
29 #include "kp_str.h"
30 #include "kp_tab.h"
31
32 #ifdef __KERNEL__
33 #include <linux/slab.h>
34 #include "ktap.h"
35 #include "kp_vm.h"
36 #include "kp_transport.h"
37
38 #define KTAP_ALLOC_FLAGS ((GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN) \
39                          & ~__GFP_WAIT)
40
41 void *kp_malloc(ktap_state *ks, int size)
42 {
43         void *addr;
44
45         /*
46          * Normally we don't want to trace under memory pressure,
47          * so we use a simple rule to handle memory allocation failure:
48          *
49          * retry until allocation success, this will make caller don't need
50          * to handle the unlikely failure case, then ktap exit.
51          *
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.
55          *
56          * Perhaps return pre-allocated stub memory trunk when allocate failed
57          * is a better approch?
58          */
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);
63                 dump_stack();
64                 while (1) {
65                         addr = kmalloc(size, KTAP_ALLOC_FLAGS);
66                         if (addr)
67                                 break;
68                 }
69                 kp_printf(ks, "kmalloc retry success after failed, exit\n");
70         }
71
72         preempt_disable();
73         KTAP_STATS(ks)->nr_mem_allocate += 1;
74         KTAP_STATS(ks)->mem_allocated += size;
75         preempt_enable();
76
77         return addr;
78 }
79
80 void kp_free(ktap_state *ks, void *addr)
81 {
82         preempt_disable();
83         KTAP_STATS(ks)->nr_mem_free += 1;
84         preempt_enable();
85
86         kfree(addr);
87 }
88
89 void *kp_reallocv(ktap_state *ks, void *addr, int oldsize, int newsize)
90 {
91         void *new_addr;
92
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);
97                 dump_stack();
98                 while (1) {
99                         new_addr = krealloc(addr, newsize, KTAP_ALLOC_FLAGS);
100                         if (new_addr)
101                                 break;
102                 }
103                 kp_printf(ks, "krealloc retry success after failed, exit\n");
104         }
105
106         preempt_disable();
107         if (oldsize == 0) {
108                 KTAP_STATS(ks)->nr_mem_allocate += 1;
109         }
110         KTAP_STATS(ks)->mem_allocated += newsize - oldsize;
111         preempt_enable();
112
113         return new_addr;
114 }
115
116 void *kp_zalloc(ktap_state *ks, int size)
117 {
118         void *addr;
119
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);
124                 dump_stack();
125                 while (1) {
126                         addr = kzalloc(size, KTAP_ALLOC_FLAGS);
127                         if (addr)
128                                 break;
129                 }
130                 kp_printf(ks, "kzalloc retry success after failed, exit\n");
131         }
132
133         preempt_disable();
134         KTAP_STATS(ks)->nr_mem_allocate += 1;
135         KTAP_STATS(ks)->mem_allocated += size;
136         preempt_enable();
137
138         return addr;
139 }
140 #endif
141
142 void kp_obj_dump(ktap_state *ks, const ktap_value *v)
143 {
144         switch (ttype(v)) {
145         case KTAP_TNIL:
146                 kp_puts(ks, "NIL");
147                 break;
148         case KTAP_TNUMBER:
149                 kp_printf(ks, "NUMBER %ld", nvalue(v));
150                 break;
151         case KTAP_TBOOLEAN:
152                 kp_printf(ks, "BOOLEAN %d", bvalue(v));
153                 break;
154         case KTAP_TLIGHTUSERDATA:
155                 kp_printf(ks, "LIGHTUSERDATA 0x%lx", (unsigned long)pvalue(v));
156                 break;
157         case KTAP_TCFUNCTION:
158                 kp_printf(ks, "LIGHTCFCUNTION 0x%lx", (unsigned long)fvalue(v));
159                 break;
160         case KTAP_TSHRSTR:
161         case KTAP_TLNGSTR:
162                 kp_printf(ks, "SHRSTR #%s", svalue(v));
163                 break;
164         case KTAP_TTABLE:
165                 kp_printf(ks, "TABLE 0x%lx", (unsigned long)hvalue(v));
166                 break;
167         default:
168                 kp_printf(ks, "GCVALUE 0x%lx", (unsigned long)gcvalue(v));
169                 break;
170         }
171 }
172
173 #ifdef __KERNEL__
174 #include <linux/stacktrace.h>
175 #include <linux/module.h>
176 #include <linux/kallsyms.h>
177
178 static void kp_btrace_dump(ktap_state *ks, ktap_btrace *bt)
179 {
180         char str[KSYM_SYMBOL_LEN];
181         unsigned long *entries = (unsigned long *)(bt + 1);
182         int i;
183
184         for (i = 0; i < bt->nr_entries; i++) {
185                 unsigned long p = entries[i];
186
187                 if (p == ULONG_MAX)
188                         break;
189
190                 SPRINT_SYMBOL(str, p);
191                 kp_printf(ks, "%s\n", str);
192         }
193 }
194
195 static int kp_btrace_equal(ktap_btrace *bt1, ktap_btrace *bt2)
196 {
197         unsigned long *entries1 = (unsigned long *)(bt1 + 1);
198         unsigned long *entries2 = (unsigned long *)(bt2 + 1);
199         int i;
200
201         if (bt1->nr_entries != bt2->nr_entries)
202                 return 0;
203
204         for (i = 0; i < bt1->nr_entries; i++) {
205                 if (entries1[i] != entries2[i])
206                         return 0;
207         }
208
209         return 1;
210 }
211 #endif
212
213 void kp_showobj(ktap_state *ks, const ktap_value *v)
214 {
215         switch (ttype(v)) {
216         case KTAP_TNIL:
217                 kp_puts(ks, "nil");
218                 break;
219         case KTAP_TNUMBER:
220                 kp_printf(ks, "%ld", nvalue(v));
221                 break;
222         case KTAP_TBOOLEAN:
223                 kp_puts(ks, (bvalue(v) == 1) ? "true" : "false");
224                 break;
225         case KTAP_TLIGHTUSERDATA:
226                 kp_printf(ks, "0x%lx", (unsigned long)pvalue(v));
227                 break;
228         case KTAP_TCFUNCTION:
229                 kp_printf(ks, "0x%lx", (unsigned long)fvalue(v));
230                 break;
231         case KTAP_TSHRSTR:
232         case KTAP_TLNGSTR:
233                 kp_puts(ks, svalue(v));
234                 break;
235         case KTAP_TTABLE:
236                 kp_tab_dump(ks, hvalue(v));
237                 break;
238 #ifdef __KERNEL__
239 #ifdef CONFIG_KTAP_FFI
240         case KTAP_TCDATA:
241                 kp_cdata_dump(ks, cdvalue(v));
242                 break;
243 #endif
244         case KTAP_TEVENT:
245                 kp_transport_event_write(ks, evalue(v));
246                 break;
247         case KTAP_TBTRACE:
248                 kp_btrace_dump(ks, btvalue(v));
249                 break;
250         case KTAP_TPTABLE:
251                 kp_ptab_dump(ks, phvalue(v));
252                 break;
253         case KTAP_TSTATDATA:
254                 kp_statdata_dump(ks, sdvalue(v));
255                 break;
256 #endif
257         default:
258                 kp_error(ks, "print unknown value type: %d\n", ttype(v));
259                 break;
260         }
261 }
262
263
264 /*
265  * equality of ktap values. ks == NULL means raw equality
266  */
267 int kp_equalobjv(ktap_state *ks, const ktap_value *t1, const ktap_value *t2)
268 {
269         switch (ttype(t1)) {
270         case KTAP_TNIL:
271                 return 1;
272         case KTAP_TNUMBER:
273                 return nvalue(t1) == nvalue(t2);
274         case KTAP_TBOOLEAN:
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);
280         case KTAP_TSHRSTR:
281                 return eqshrstr(rawtsvalue(t1), rawtsvalue(t2));
282         case KTAP_TLNGSTR:
283                 return kp_tstring_eqlngstr(rawtsvalue(t1), rawtsvalue(t2));
284         case KTAP_TTABLE:
285                 if (hvalue(t1) == hvalue(t2))
286                         return 1;
287                 else if (ks == NULL)
288                         return 0;
289 #ifdef __KERNEL__
290         case KTAP_TBTRACE:
291                 return kp_btrace_equal(btvalue(t1), btvalue(t2));
292 #endif
293         default:
294                 return gcvalue(t1) == gcvalue(t2);
295         }
296
297         return 0;
298 }
299
300 /*
301  * ktap will not use lua's length operator on table meaning,
302  * also # is not for length operator any more in ktap.
303  */
304 int kp_objlen(ktap_state *ks, const ktap_value *v)
305 {
306         switch(v->type) {
307         case KTAP_TTABLE:
308                 return kp_tab_length(ks, hvalue(v));
309         case KTAP_TSTRING:
310                 return rawtsvalue(v)->tsv.len;
311         default:
312                 kp_printf(ks, "cannot get length of type %d\n", v->type);
313                 return -1;
314         }
315         return 0;
316 }
317
318 /* need to protect allgc field? */
319 ktap_gcobject *kp_newobject(ktap_state *ks, int type, size_t size,
320                             ktap_gcobject **list)
321 {
322         ktap_gcobject *o;
323
324         o = kp_malloc(ks, size);
325         if (list == NULL)
326                 list = &G(ks)->allgc;
327
328         gch(o)->tt = type;
329         gch(o)->next = *list;
330         *list = o;
331
332         return o;
333 }
334
335 ktap_upval *kp_newupval(ktap_state *ks)
336 {
337         ktap_upval *uv;
338
339         uv = &kp_newobject(ks, KTAP_TUPVAL, sizeof(ktap_upval), NULL)->uv;
340         uv->v = &uv->u.value;
341         set_nil(uv->v);
342         return uv;
343 }
344
345 static ktap_btrace *kp_newbacktrace(ktap_state *ks, int nr_entries,
346                                     ktap_gcobject **list)
347 {
348         ktap_btrace *bt;
349         int size = sizeof(ktap_btrace) + nr_entries * sizeof(unsigned long);
350
351         bt = &kp_newobject(ks, KTAP_TBTRACE, size, list)->bt;
352         bt->nr_entries = nr_entries;
353         return bt;
354 }
355
356 void kp_objclone(ktap_state *ks, const ktap_value *o, ktap_value *newo,
357                  ktap_gcobject **list)
358 {
359         if (is_btrace(o)) {
360                 int nr_entries = btvalue(o)->nr_entries;
361                 ktap_btrace *bt;
362
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);
367         } else {
368                 kp_error(ks, "cannot clone ktap value type %d\n", ttype(o));
369                 set_nil(newo);
370         }
371 }
372
373 ktap_closure *kp_newclosure(ktap_state *ks, int n)
374 {
375         ktap_closure *cl;
376
377         cl = (ktap_closure *)kp_newobject(ks, KTAP_TCLOSURE, sizeof(*cl), NULL);
378         cl->p = NULL;
379         cl->nupvalues = n;
380         while (n--)
381                 cl->upvals[n] = NULL;
382
383         return cl;
384 }
385
386 static void free_proto(ktap_state *ks, ktap_proto *f)
387 {
388         kp_free(ks, f->code);
389         kp_free(ks, f->p);
390         kp_free(ks, f->k);
391         kp_free(ks, f->lineinfo);
392         kp_free(ks, f->locvars);
393         kp_free(ks, f->upvalues);
394         kp_free(ks, f);
395 }
396
397 ktap_proto *kp_newproto(ktap_state *ks)
398 {
399         ktap_proto *f;
400         f = (ktap_proto *)kp_newobject(ks, KTAP_TPROTO, sizeof(*f), NULL);
401         f->k = NULL;
402         f->sizek = 0;
403         f->p = NULL;
404         f->sizep = 0;
405         f->code = NULL;
406         f->cache = NULL;
407         f->sizecode = 0;
408         f->lineinfo = NULL;
409         f->sizelineinfo = 0;
410         f->upvalues = NULL;
411         f->sizeupvalues = 0;
412         f->numparams = 0;
413         f->is_vararg = 0;
414         f->maxstacksize = 0;
415         f->locvars = NULL;
416         f->sizelocvars = 0;
417         f->linedefined = 0;
418         f->lastlinedefined = 0;
419         f->source = NULL;
420         return f;
421 }
422
423 void kp_free_gclist(ktap_state *ks, ktap_gcobject *o)
424 {
425         while (o) {
426                 ktap_gcobject *next;
427
428                 next = gch(o)->next;
429                 switch (gch(o)->tt) {
430                 case KTAP_TTABLE:
431                         kp_tab_free(ks, (ktap_tab *)o);
432                         break;
433                 case KTAP_TPROTO:
434                         free_proto(ks, (ktap_proto *)o);
435                         break;
436 #ifdef __KERNEL__
437                 case KTAP_TPTABLE:
438                         kp_ptab_free(ks, (ktap_ptab *)o);
439                         break;
440 #endif
441                 default:
442                         kp_free(ks, o);
443                 }
444                 o = next;
445         }
446 }
447
448 void kp_free_all_gcobject(ktap_state *ks)
449 {
450         kp_free_gclist(ks, G(ks)->allgc);
451         G(ks)->allgc = NULL;
452 }
453
454 /******************************************************************************/
455
456 /*
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
460  */
461 void kp_header(u8 *h)
462 {
463         int x = 1;
464
465         memcpy(h, KTAP_SIGNATURE, sizeof(KTAP_SIGNATURE) - sizeof(char));
466         h += sizeof(KTAP_SIGNATURE) - sizeof(char);
467         *h++ = (u8)VERSION;
468         *h++ = (u8)FORMAT;
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));
476 }
477
478