[STYLE] add comments
[platform/core/system/swap-probe.git] / include / binproto.h
1 /*
2  *  DA probe
3  *
4  * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact:
7  *
8  * Nikita Kalyazin <n.kalyazin@samsung.com>
9  * Anastasia Lyupa <a.lyupa@samsung.com>
10  *
11  * This library is free software; you can redistribute it and/or modify it under
12  * the terms of the GNU Lesser General Public License as published by the
13  * Free Software Foundation; either version 2.1 of the License, or (at your option)
14  * any later version.
15  *
16  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
17  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
19  * License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * along with this library; if not, write to the Free Software Foundation, Inc., 51
23  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  *
25  * Contributors:
26  * - Samsung RnD Institute Russia
27  *
28  */
29
30 #ifndef __BIN_PROTO_H__
31 #define __BIN_PROTO_H__
32
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdint.h>
37 #include <stdarg.h>
38
39 #include <unistd.h>
40 #include <fcntl.h>
41
42 #include <sys/types.h>
43 #include <sys/stat.h>
44
45 // getpid/gettid
46 #include <sys/types.h>
47 #include <unistd.h>
48 #include <sys/syscall.h>
49
50 #include <sys/time.h>
51
52 #include <sys/socket.h>
53 #include "dahelper.h"
54 #include "api_id_mapping.h"
55
56 #define MSG_PROBE_MEMORY 0x0101
57 #define MSG_PROBE_UICONTROL 0x0102
58 #define MSG_PROBE_UIEVENT 0x0103
59 #define MSG_PROBE_RESOURCE 0x0104
60 #define MSG_PROBE_LIFECYCLE 0x0105
61 #define MSG_PROBE_SCREENSHOT 0x0106
62 #define MSG_PROBE_SCENE 0x0107
63 #define MSG_PROBE_THREAD 0x0108
64 #define MSG_PROBE_CUSTOM 0x0109
65 #define MSG_PROBE_SYNC 0x0110
66 #define MSG_PROBE_NETWORK 0x0111
67 #define MSG_PROBE_GL 0x0112
68
69 #define SCREENSHOT_DIRECTORY    "/tmp/da"
70
71 #define MAX_PACK_FILENAME_LEN (4 * 1024)
72 #define MAX_SHADER_LEN (4 * 1024)
73 #define ADD_LOCAL_BUF_SIZE (1024)
74 #define MAX_GL_CONTEXT_VALUE_SIZE (1024)
75 #define MAX_LOCAL_BUF_SIZE (MAX_SHADER_LEN + ADD_LOCAL_BUF_SIZE)
76 #define LOCAL_BUF msg_buf
77
78 // TODO: remove this copy-paste
79 #define CALLER_ADDRESS                                                  \
80         ((void*) __builtin_extract_return_addr(__builtin_return_address(0)))
81
82 static inline uint64_t voidp_to_uint64(const void *p)
83 {
84         return (uint64_t)(uintptr_t)p;
85 }
86
87 // COMMON
88 static inline char *pack_int32(char *to, uint32_t val)
89 {
90         *(uint32_t *)to = val;
91         return to + sizeof(uint32_t);
92 }
93
94 static inline char *pack_int64(char *to, uint64_t val)
95 {
96         *(uint64_t *)to = val;
97         return to + sizeof(uint64_t);
98 }
99
100 static char __attribute__((used)) *pack_string(char *to, const char *str)
101 {
102         if (!str) {
103                 *to = '\0';
104                 return to + 1;
105         } else {
106                 size_t len = strlen(str) + 1;
107                 strncpy(to, str, len);
108                 return to + len;
109         }
110 }
111
112 static char __attribute__((used)) *pack_bin(char *to, const char *from,
113                                             uint32_t len)
114 {
115         memcpy(to, from, len);
116         return to + len;
117 }
118
119 static inline char *pack_double(char *to, double val)
120 {
121         *(double *)to = val;
122         return to + sizeof(double);
123 }
124
125 static inline char *pack_timestamp(char *to)
126 {
127         struct timeval tv;
128
129         gettimeofday(&tv, NULL);
130         to = pack_int32(to, tv.tv_sec);
131         to = pack_int32(to, tv.tv_usec * 1000);
132
133         return to;
134 }
135
136 ///////////////////////////////////////////////////////////////////
137 // function: pack_array
138 ///////////////////////////////////////////////////////////////////
139 // info:
140 //  Pack array param to buffer
141 // params:
142 //  char *to              - destination buffer
143 //  va_list *args         - array size and array (pointer)
144 //  uint32_t element_size - size of array element
145 // return:
146 //  char *                - destination pointer end after pack
147 static char *pack_array(char *to, va_list *args, uint32_t element_size)
148 {
149         uint32_t d;
150         uint64_t p;
151
152         // get array elements count
153         d = va_arg(*args, uint32_t);
154         // get array pointer
155         p = (unsigned long)(uintptr_t)va_arg(*args, uint64_t);
156
157         // pack original pointer
158         memcpy(to, &p, sizeof(p));
159         to += sizeof(p);
160         // pack array elements count
161         memcpy(to, &d, sizeof(d));
162         to += sizeof(d);
163
164         // pack array elements
165         element_size *= d;
166         memcpy(to, (void *)(long)p, element_size);
167         to += element_size;
168
169         return to;
170 }
171
172 static char __attribute__((used)) *pack_string_to_file(char *to, const char *st,
173                                                        uint32_t data_len,
174                                                        uint32_t max_len)
175 {
176         if (data_len < max_len) {
177                 /* pack string to buffer */
178                 to = pack_string(to, st);
179         } else {
180                 /* pack string to file */
181                 char template_name[] = SCREENSHOT_DIRECTORY "/swap_XXXXXX";
182                 char dst_path_pack[MAX_PATH_LENGTH];
183                 FILE *file;
184                 mktemp(template_name);
185                 file = fopen(template_name, "w");
186                 if (file != NULL) {
187                         fwrite(st, data_len, 1, file);
188                         fclose(file);
189                 }
190                 sprintf(dst_path_pack, "FILE:%s", template_name);
191                 to = pack_string(to, dst_path_pack);
192         }
193         return to;
194 }
195
196 static char __attribute__((used)) *pack_value_by_type(char *to, const char **t, va_list *args)
197 {
198         uint8_t c;
199         uint8_t cs;
200         uint32_t d;
201         uint64_t x;
202         uint64_t p;
203         float f;
204         double w;
205         char *s;
206         int n;
207
208         *to++ = **t;
209
210         switch (**t) {
211         case 'c':
212                 c = (uint8_t)va_arg(*args, uint32_t);
213                 memcpy(to, &c, sizeof(c));
214                 to += sizeof(c);
215                 break;
216         case 'd':
217                 d = va_arg(*args, uint32_t);
218                 memcpy(to, &d, sizeof(d));
219                 to += sizeof(d);
220                 break;
221         case 'x':
222                 x = 0; // real value may be less then uint64_t
223                 x = (unsigned long)(uint64_t)va_arg(*args, uint64_t);
224                 memcpy(to, &x, sizeof(x));
225                 to += sizeof(x);
226                 break;
227         case 'p':
228                 p = 0; // real value may be less then uint64_t
229                 p = (unsigned long)(uintptr_t)va_arg(*args, uint64_t);
230                 memcpy(to, &p, sizeof(p));
231                 to += sizeof(p);
232                 break;
233         case 'f':
234                 f = (float)va_arg(*args, double);
235                 memcpy(to, &f, sizeof(f));
236                 to += sizeof(f);
237                 break;
238         case 'w':
239                 w = va_arg(*args, double);
240                 memcpy(to, &w, sizeof(w));
241                 to += sizeof(w);
242                 break;
243         case 's':
244                 cs = *((*t)+1);
245                 s = va_arg(*args, char *);
246
247                 switch (cs) {
248                         case '4': //"s4" - pack 4K or to file
249                                 (*t)++;
250                                 to = pack_string_to_file(to, s, strlen(s),
251                                                          MAX_PACK_FILENAME_LEN);
252                                 break;
253                         case '0': //"s0" - pack 256 bytes
254                                 (*t)++;
255                                 n = strlen(s) + 1;
256                                 if (n >= 255)
257                                         n = 255;
258                                 strncpy(to, s, n);
259                                 to[n-1] = '\0';
260                                 to += n;
261                                 break;
262                         default: //"s" - pack all string
263                                 n = strlen(s) + 1;
264                                 strncpy(to, s, n);
265                                 to += n;
266                                 break;
267                 }
268
269                 break;
270         case 'v':
271         case 'n':
272                 break;
273         /* pack arrays params */
274         case 'D':
275                 /* array of 'd' uint32_t */
276                 to = pack_array(to, args, sizeof(d));
277                 break;
278         case 'F':
279                 /* array of 'f' float */
280                 to = pack_array(to, args, sizeof(f));
281                 break;
282         case 'W':
283                 /* array of 'w' double */
284                 to = pack_array(to, args, sizeof(w));
285                 break;
286         default: {
287                 char buf[128];
288                 sprintf(buf, "ERROR PACK #%d '%c'!!!", **t, **t);
289                 PRINTERR(buf);
290                 to--;
291                 break;
292                 }
293         }
294
295         (*t)++;
296         return to;
297 }
298
299 static char __attribute__((used)) *pack_args(char *to, const char *fmt, ...)
300 {
301         va_list args;
302         uint32_t num = 0;
303         const char *t = fmt;
304         char *size_p = to;
305
306         //put dummy num value
307         memcpy(to, &num, sizeof(num));
308         to += sizeof(num);
309
310         va_start(args, fmt);
311
312         for (t = fmt; *t != '\0';) {
313                 to = pack_value_by_type(to, &t, &args);
314                 num++;
315         }
316
317         //set real num value
318         memcpy(size_p, &num, sizeof(num));
319
320         va_end(args);
321
322         return to;
323 }
324
325 static char __attribute__((used)) *pack_ret(char *to, char ret_type, ...)
326 {
327         va_list args;
328         char fmt[] = {ret_type, 0};
329         const char *fmtp = (const char *)fmt;
330
331         va_start(args, ret_type);
332         to = pack_value_by_type(to, &fmtp, &args);
333         va_end(args);
334
335         return to;
336 }
337
338 #define BUF_PTR p
339 #define RET_PTR ret_p
340 #define PACK_INT32(val)                         \
341         BUF_PTR = pack_int32(BUF_PTR, val);
342 #define PACK_INT64(val)                         \
343         BUF_PTR = pack_int64(BUF_PTR, val);
344 #define PACK_STRING(str)                        \
345         BUF_PTR = pack_string(BUF_PTR, str);
346
347 #define PACK_COMMON_BEGIN(msg_id, api_id, fmt, ...)             \
348         do {    /* PACK_COMMON_BEGIN*/                          \
349                 BUF_PTR = pack_int32(BUF_PTR, msg_id);          /* msg id */    \
350                 BUF_PTR = pack_int32(BUF_PTR, 0);               /* sequence */  \
351                 BUF_PTR = pack_timestamp(BUF_PTR);              /* timestamp */ \
352                 BUF_PTR = pack_int32(BUF_PTR, 0);               /* length */    \
353                 BUF_PTR = pack_int32(BUF_PTR, api_id);          /* API id */    \
354                 BUF_PTR = pack_int32(BUF_PTR, getpid());        /* PID */       \
355                 BUF_PTR = pack_int32(BUF_PTR, syscall(__NR_gettid));    /* call pc*/\
356                 BUF_PTR = pack_args(BUF_PTR, fmt, __VA_ARGS__); /* args */      \
357                 RET_PTR = BUF_PTR;              \
358         } while (0)
359
360 #define PACK_COMMON_END(ret_type, ret, errn, intern_call)                       \
361         do {    /* PACK_COMMON_END */                                           \
362                 PACK_RETURN_END(ret_type, ret)                                  \
363                 BUF_PTR = pack_int64(BUF_PTR, (uint64_t)errn);  /* errno */     \
364                 BUF_PTR = pack_int32(BUF_PTR, (uint32_t)intern_call);   /* internal call*/      \
365                 BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)CALLER_ADDRESS); /*caller addr*/\
366                 BUF_PTR = pack_int32(BUF_PTR, 0);       /* reserved */          \
367                 BUF_PTR = pack_int32(BUF_PTR, 0);       /* reserved */          \
368         } while (0)
369
370 #define PACK_RETURN_END(ret_type, ret)                                          \
371                 RET_PTR = pack_ret(RET_PTR, ret_type, (uintptr_t)ret); /* return val */
372
373 #define PACK_MEMORY(size, memory_api_type, addr)                                \
374         do {    /* PACK_MEMORY */                                               \
375                 BUF_PTR = pack_int64(BUF_PTR, size);    /* alloc size */        \
376                 BUF_PTR = pack_int32(BUF_PTR, memory_api_type); /* alloc type */\
377                 BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)addr); /* alloc addr */\
378         } while (0)
379
380 #define PACK_UICONTROL(control)                                         \
381         do {                                                            \
382                 if (unlikely(control == NULL)) {                        \
383                         BUF_PTR = pack_string(BUF_PTR, "");             \
384                         BUF_PTR = pack_string(BUF_PTR, "");             \
385                         BUF_PTR = pack_int64(BUF_PTR, 0);               \
386                 } else {                                                \
387                         char *type = NULL, *name = NULL;                \
388                         if (find_uiobject_hash((void*)(control),        \
389                                              &type, &name) == 1) {      \
390                                 BUF_PTR = pack_string(BUF_PTR, type);   \
391                                 BUF_PTR = pack_string(BUF_PTR, name);   \
392                         } else {                                        \
393                                 BUF_PTR = pack_string(BUF_PTR, "");     \
394                                 BUF_PTR = pack_string(BUF_PTR, "");     \
395                         }                                               \
396                         BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)(control)); \
397                 }                                                       \
398         } while(0)
399
400 #define PACK_UIEVENT(event_type, detail_type, x, y, info1, info2)       \
401         do {    /* PACK_UIEVENT */                                      \
402                 BUF_PTR = pack_int32(BUF_PTR, event_type);              \
403                 BUF_PTR = pack_int32(BUF_PTR, detail_type);             \
404                 BUF_PTR = pack_int32(BUF_PTR, x);                       \
405                 BUF_PTR = pack_int32(BUF_PTR, y);                       \
406                 BUF_PTR = pack_string(BUF_PTR, info1);                  \
407                 BUF_PTR = pack_int32(BUF_PTR, info2);                   \
408         } while (0)
409
410 #define PACK_RESOURCE(size, fd_value, fd_api_type, file_size,   \
411                       file_path)                                        \
412         do {    /* PACK_RESOURCE */                                     \
413                 BUF_PTR = pack_int64(BUF_PTR, size);                    \
414                 BUF_PTR = pack_int64(BUF_PTR, fd_value);                \
415                 BUF_PTR = pack_int32(BUF_PTR, fd_api_type);             \
416                 BUF_PTR = pack_int64(BUF_PTR, file_size);               \
417                 BUF_PTR = pack_string_to_file(BUF_PTR, file_path,       \
418                                               strlen(file_path),        \
419                                               MAX_PACK_FILENAME_LEN);   \
420         } while (0)
421
422 #define PACK_SCREENSHOT(image_file_path, orientation)                           \
423                 do {    /* PACK_SCREENSHOT */                                   \
424                           BUF_PTR = pack_string(BUF_PTR, image_file_path);      \
425                           BUF_PTR = pack_int32(BUF_PTR, orientation);           \
426                 } while (0)
427
428 #define PACK_SCENE(scene_name, formid, pform, panelid, ppanel, transition, user)        \
429         do {                                                                            \
430                 BUF_PTR = pack_string(BUF_PTR,  scene_name);                            \
431                 if (unlikely(pform == NULL)) {                                          \
432                         BUF_PTR = pack_string(BUF_PTR, "");                             \
433                         BUF_PTR = pack_int64(BUF_PTR, 0);                               \
434                 } else {                                                                \
435                         char *type = NULL, *name = NULL;                                \
436                         if (find_uiobject_hash((void*)(pform), &type, &name) == 1) {    \
437                                 BUF_PTR = pack_string(BUF_PTR, name);                   \
438                         } else {                                                        \
439                                 BUF_PTR = pack_string(BUF_PTR, "");                     \
440                         }                                                               \
441                         BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)pform);                \
442                 }                                                                       \
443                 if (unlikely(ppanel == NULL)) {                                         \
444                         BUF_PTR = pack_string(BUF_PTR, "");                             \
445                         BUF_PTR = pack_int64(BUF_PTR, 0);                               \
446                 } else {                                                                \
447                         char *type = NULL, *name = NULL;                                \
448                         if (find_uiobject_hash((void*)(ppanel), &type, &name) == 1) {   \
449                                 BUF_PTR = pack_string(BUF_PTR, name);                   \
450                         } else {                                                        \
451                                 BUF_PTR = pack_string(BUF_PTR, "");                     \
452                         }                                                               \
453                         BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)(ppanel));             \
454                 }                                                                       \
455                 BUF_PTR = pack_int64(BUF_PTR, transition);                              \
456                 BUF_PTR = pack_int64(BUF_PTR, user);                                    \
457         } while(0)
458
459 #define PACK_THREAD(thread_id, thread_type, api_type, class_name)       \
460          do {                                                           \
461         if(thread_type == THREAD_PTHREAD) {                             \
462             BUF_PTR = pack_int64(BUF_PTR, thread_id);                   \
463             BUF_PTR = pack_int64(BUF_PTR, 0);                           \
464         } else if(thread_type == THREAD_TIZENTHREAD_WORKER              \
465                     || thread_type == THREAD_TIZENTHREAD_EVENTDRIVEN) {   \
466             BUF_PTR = pack_int64(BUF_PTR, 0);                           \
467             BUF_PTR = pack_int64(BUF_PTR, thread_id);                   \
468         } else {                                                        \
469             BUF_PTR = pack_int64(BUF_PTR, 0);                           \
470             BUF_PTR = pack_int64(BUF_PTR, 0);                           \
471         }                                                               \
472         BUF_PTR = pack_int32(BUF_PTR, thread_type);                     \
473         BUF_PTR = pack_int32(BUF_PTR, api_type);                        \
474         BUF_PTR = pack_string(BUF_PTR, class_name);                     \
475         } while (0)
476
477 #define PACK_CUSTOM(handle, type, name, color, value)           \
478         do {                                                    \
479                 BUF_PTR = pack_int32(BUF_PTR, handle);          \
480                 BUF_PTR = pack_int32(BUF_PTR, type);            \
481                 BUF_PTR = pack_string(BUF_PTR, name);           \
482                 BUF_PTR = pack_int32(BUF_PTR, color);           \
483                 BUF_PTR = pack_double(BUF_PTR, value);          \
484         } while (0)
485
486 #define PACK_SYNC(sync_val, sync_type, api_type)                     \
487         do {                                                         \
488                 BUF_PTR = pack_int64(BUF_PTR, (uintptr_t)sync_val);  \
489                 BUF_PTR = pack_int32(BUF_PTR, sync_type);            \
490                 BUF_PTR = pack_int32(BUF_PTR, api_type);             \
491         } while (0)
492
493 #define PREPARE_LOCAL_BUF()                     \
494                 char LOCAL_BUF[MAX_LOCAL_BUF_SIZE];             \
495                 char *BUF_PTR = LOCAL_BUF;                      \
496                 char *RET_PTR = NULL
497
498 #define MSG_LEN_OFFSET 16
499 #define MSG_HDR_LEN 20
500 #define FLUSH_LOCAL_BUF()                                               \
501                 *(uint32_t *)(msg_buf + MSG_LEN_OFFSET) = (p - msg_buf) - MSG_HDR_LEN; \
502                 send(gTraceInfo.socket.daemonSock, msg_buf, (p - msg_buf), 0)
503
504 // =========================== post block macro ===========================
505
506 #define POST_PACK_PROBEBLOCK_BEGIN()                                    \
507         newerrno = errno;                                               \
508         if(postBlockBegin(blockresult)) {
509
510 #define POST_PACK_PROBEBLOCK_END()                                      \
511                 postBlockEnd();                                         \
512         }                                                               \
513         errno = (newerrno != 0) ? newerrno : olderrno
514
515 /* int main(int argc, char **argv) */
516 /* { */
517 /*      char buf[1024]; */
518 /*      char *p = buf; */
519
520 /*      p = PACK_COMMON_BEGIN(p, 42, "cdxpfws", 'a', 10, (uint64_t)80, */
521 /*                            (uint64_t)0, 0.19, 0.33, "hello!"); */
522 /*      p = PACK_COMMON_END('p', p, 0); */
523
524 /*      int fd = creat("out.bin", 0644); */
525 /*      if (fd == -1) { */
526 /*              printf("error\n"); */
527 /*              exit(1); */
528 /*      } */
529
530 /*      write(fd, buf, p - buf); */
531 /*      close(fd); */
532
533 /*      return 0; */
534 /* } */
535
536 extern void _init_(void);
537 extern void _uninit_(void);
538
539 #endif /* __BIN_PROTO_H__ */