1 /**************************************************************************
5 Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
7 Contact: Boram Park <boram1288.park@samsung.com>
8 Sangjin LEE <lsj119@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
35 #include <sys/types.h>
36 #include <sys/fcntl.h>
44 #include "xdbg_types.h"
45 #include "xdbg_evlog.h"
46 #include "bool_exp_rule_checker.h"
47 #include <X11/Xlibint.h>
55 static char *evt_type[] = { "Event", "Request", "Reply", "Flush", "Error" };
56 static char *evt_dir[] = { "<====", "---->", "<----", "*****", "<----"};
58 static RULE_CHECKER rc = NULL;
61 _mergeArgs (char * target, int argc, const char ** argv)
66 for (i=0; i<argc; i++)
68 len = sprintf (target, "%s", argv[i]);
77 _strcasecmp(const char *str1, const char *str2)
79 const u_char *us1 = (const u_char *) str1, *us2 = (const u_char *) str2;
81 while (tolower(*us1) == tolower(*us2)) {
87 return (tolower(*us1) - tolower(*us2));
91 xDbgEvlogGetCmd (char *path)
96 p = strrchr (path, '/');
101 xDbgEvlogRuleSet (const int argc, const char **argv, char *reply, int *len)
103 const char * command;
106 rc = rulechecker_init();
110 rulechecker_print_rule (rc, reply);
116 if (!_strcasecmp (command, "add"))
118 POLICY_TYPE policy_type;
119 RC_RESULT_TYPE result;
120 const char * policy = argv[1];
121 char merge[8192], rule[8192]={0,};
127 REPLY ("Error : Too few arguments.\n");
131 if (!_strcasecmp (policy, "ALLOW"))
133 else if (!_strcasecmp (policy, "DENY"))
137 REPLY ("Error : Unknown policy : [%s].\n Policy should be ALLOW or DENY.\n", policy);
141 _mergeArgs (merge, argc - 2, &(argv[2]));
143 for (i = 0 ; i < strlen(merge) ; i++)
145 if(merge[i] == '\"' || merge[i] == '\'')
157 const char* plus = "|| type=reply || type=error";
160 index += strlen(plus);
166 rule[index++] = merge[i];
169 result = rulechecker_add_rule (rc, policy_type, rule);
170 if (result == RC_ERR_TOO_MANY_RULES)
172 REPLY ("Error : Too many rules were added.\n");
175 else if (result == RC_ERR_PARSE_ERROR)
177 REPLY ("Error : An error occured during parsing the rule [%s]\n", rule);
181 REPLY ("The rule was successfully added.\n\n");
182 rulechecker_print_rule (rc, reply);
185 else if (!_strcasecmp (command, "remove"))
187 const char * remove_idx;
192 REPLY ("Error : Too few arguments.\n");
196 for (i=0; i<argc - 1; i++)
198 remove_idx = argv[i+1];
200 if (!_strcasecmp (remove_idx, "all"))
202 rulechecker_destroy (rc);
203 rc = rulechecker_init();
204 REPLY ("Every rules were successfully removed.\n");
208 int index = atoi (remove_idx);
209 if (isdigit (*remove_idx) && rulechecker_remove_rule (rc, index) == 0)
210 REPLY ("The rule [%d] was successfully removed.\n", index);
212 REPLY ("Rule remove fail : No such rule [%s].\n", remove_idx);
215 rulechecker_print_rule (rc, reply);
218 else if (!_strcasecmp (command, "print"))
220 rulechecker_print_rule (rc, reply);
223 else if (!_strcasecmp (command, "help"))
225 REPLY ("%s", rulechecker_print_usage());
229 REPLY ("%s\nUnknown command : [%s].\n\n", rulechecker_print_usage(), command);
235 xDbgEvlogRuleValidate (EvlogInfo *evinfo)
237 const char *evlog_name = "";
241 rc = rulechecker_init ();
245 XDBG_LOG ("failed: create rulechecker\n");
249 cmd = xDbgEvlogGetCmd (evinfo->client.command);
251 if (evinfo->type == REQUEST)
252 evlog_name = evinfo->req.name;
253 else if (evinfo->type == EVENT)
254 evlog_name = evinfo->evt.name;
255 else if (evinfo ->type == REPLY)
256 evlog_name = evinfo->rep.name;
258 return rulechecker_validate_rule (rc,
267 ExtensionInfo Evlog_extensions[] = {
268 {xDbgEvlogCompositeGetBase, 0, 0, 0, NULL, NULL},
269 {xDbgEvlogDamageGetBase, 0, 0, 0, NULL, NULL},
270 {xDbgEvlogDri2GetBase, 0, 0, 0, NULL, NULL},
271 {xDbgEvlogGestureGetBase, 0, 0, 0, NULL, NULL},
272 {xDbgEvlogXinputGetBase, 0, 0, 0, NULL, NULL},
273 {xDbgEvlogRandrGetBase, 0, 0, 0, NULL, NULL},
274 {xDbgEvlogXextDpmsGetBase, 0, 0, 0, NULL, NULL},
275 {xDbgEvlogXextShmGetBase, 0, 0, 0, NULL, NULL},
276 {xDbgEvlogXextSyncGetBase, 0, 0, 0, NULL, NULL},
277 {xDbgEvlogXextXtestGetBase, 0, 0, 0, NULL, NULL},
278 {xDbgEvlogXextXtestExt1GetBase, 0, 0, 0, NULL, NULL},
279 {xDbgEvlogXvGetBase, 0, 0, 0, NULL, NULL}
281 ExtensionInfo* Sorted_Evlog_extensions;
282 int Extensions_size = 0;
285 _ExtensionsSwap(ExtensionInfo* first, ExtensionInfo* second)
295 _SortEvlogExtensions ()
300 Sorted_Evlog_extensions = (ExtensionInfo*)malloc(sizeof(Evlog_extensions));
301 RETURN_VAL_IF_FAIL (Sorted_Evlog_extensions != NULL, FALSE);
303 memcpy(Sorted_Evlog_extensions, Evlog_extensions, sizeof(Evlog_extensions));
305 for (i = 0 ; i < Extensions_size - 1 ; i++)
308 for (j = 1 ; j < Extensions_size - i ; j++)
310 if(Sorted_Evlog_extensions[j-1].evt_base > Sorted_Evlog_extensions[j].evt_base)
312 _ExtensionsSwap(&Sorted_Evlog_extensions[j-1], &Sorted_Evlog_extensions[j]);
324 xDbgEvlogGetExtensionEntry ()
327 static Bool success = FALSE;
334 Extensions_size = sizeof(Evlog_extensions) / sizeof (ExtensionInfo);
336 for (i = 0 ; i < Extensions_size ; i++)
338 Evlog_extensions[i].get_base_func (Evlog_extensions + i);
341 if(!_SortEvlogExtensions ())
352 xDbgEvlogFillLog (EvlogInfo *evinfo, int detail_level, char *reply, int *len)
356 RETURN_VAL_IF_FAIL (evinfo->type >= 0 && (sizeof (evt_dir) / sizeof (char*)), FALSE);
357 RETURN_VAL_IF_FAIL (evinfo->type >= 0 && (sizeof (evt_type) / sizeof (char*)), FALSE);
359 if (evinfo->type == REPLY && !evinfo->rep.isStart)
361 if (detail_level >= EVLOG_PRINT_REPLY_DETAIL)
367 REPLY ("[%10.3f][%5ld] %22s(%2d:%5d) %s %7s ",
368 evinfo->time / 1000.0,
370 xDbgEvlogGetCmd (evinfo->client.command),
371 evinfo->client.index,
373 evt_dir[evinfo->type],
374 evt_type[evinfo->type]);
376 if (evinfo->type == REQUEST)
379 reply = xDbgEvlogReqeust (evinfo, detail_level, reply, len);
382 else if (evinfo->type == EVENT)
384 evinfo->evt.size = sizeof (xEvent);
386 reply = xDbgEvlogEvent (evinfo, detail_level, reply, len);
389 else if (evinfo->type == REPLY)
392 reply = xDbgEvlogReply (evinfo, detail_level, reply, len);
395 else if (evinfo->type == ERROR)
397 REPLY("(ErrorCode(0x%02x) resourceID(0x%lx) majorCode(%d) minorCode(%d))",
398 evinfo->err.errorCode,
399 evinfo->err.resourceID,
400 evinfo->err.majorCode,
401 evinfo->err.minorCode);
405 const char *evlog_name = "";
406 if (evinfo->type == REQUEST)
407 evlog_name = evinfo->req.name;
408 else if (evinfo->type == EVENT)
409 evlog_name = evinfo->evt.name;
410 else if (evinfo->type == REPLY)
411 evlog_name = evinfo->rep.name;
412 REPLY ("(%s)", evlog_name);
423 void xDbgDistroyAtomList (EvlogInfo *evinfo)
425 EvlogAtomTable *cur, *next;
427 if (!evinfo->evatom.init)
430 xorg_list_for_each_entry_safe(cur, next, &evinfo->evatom.list, link)
432 xorg_list_del(&cur->link);
436 evinfo->evatom.init = 0;
437 evinfo->evatom.size = 0;
440 void xDbgDistroyRegionList (EvlogInfo *evinfo)
442 EvlogRegionTable *cur, *next;
444 if (!evinfo->evregion.init)
447 xorg_list_for_each_entry_safe(cur, next, &evinfo->evregion.list, link)
449 xorg_list_del(&cur->link);
453 evinfo->evregion.init = 0;
454 evinfo->evregion.size = 0;
457 char* xDbgGetAtom(Atom atom, EvlogInfo *evinfo, char *reply, int *len)
459 EvlogAtomTable *table;
461 table = malloc (sizeof(EvlogAtomTable));
465 evinfo->mask |= EVLOG_MASK_ATOM;
468 if (!evinfo->evatom.init)
470 xorg_list_init(&evinfo->evatom.list);
471 evinfo->evatom.init = 1;
474 if (NameForAtom(atom))
475 snprintf (table->buf, XDBG_BUF_SIZE, "%s", (char*)NameForAtom(atom));
477 snprintf (table->buf, XDBG_BUF_SIZE, "0x%lx", atom);
479 xorg_list_add(&table->link, &evinfo->evatom.list);
480 evinfo->evatom.size++;
482 xorg_list_for_each_entry(table, &evinfo->evatom.list, link)
483 if(table->xid == atom)
485 REPLY ("(%s)", table->buf);
492 char* xDbgGetRegion(XserverRegion region, EvlogInfo *evinfo, char *reply, int *len)
494 EvlogRegionTable *table;
496 extern _X_EXPORT RESTYPE RegionResType;
501 int err = dixLookupResourceByType((pointer *) &pRegion, region,
502 RegionResType, (ClientPtr)evinfo->client.pClient,
505 evinfo->mask |= EVLOG_MASK_REGION;
507 if (!evinfo->evregion.init)
509 xorg_list_init(&evinfo->evregion.list);
510 evinfo->evregion.init = 1;
515 table = malloc (sizeof(EvlogAtomTable));
521 snprintf (table->buf, XDBG_BUF_SIZE, "0x%lx", region);
522 xorg_list_add(&table->link, &evinfo->evregion.list);
523 evinfo->evregion.size++;
527 nrect = RegionNumRects(pRegion);
528 rects = RegionRects(pRegion);
530 for (i = 0; i < nrect; i++)
532 table = malloc (sizeof(EvlogAtomTable));
539 s += snprintf (table->buf + s, XDBG_BUF_SIZE - s,
543 rects[i].x2 - rects[i].x1,
544 rects[i].y2 - rects[i].y1);
545 xorg_list_add(&table->link, &evinfo->evregion.list);
546 evinfo->evregion.size++;
552 xorg_list_for_each_entry(table, &evinfo->evregion.list, link)
553 if(table->xid == region)
555 REPLY ("%s", table->buf);
556 if(table != xorg_list_last_entry(&evinfo->evregion.list, EvlogRegionTable, link))