probe-finder.c (c13aca79ff3c4af5fd31a5b2743a90eba6e36a26) probe-finder.c (1e032f7cfa141b4424827b0ecb0ea899f84e182e)
1/*
2 * probe-finder.c : C expression to kprobe event converter
3 *
4 * Written by Masami Hiramatsu <mhiramat@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or

--- 280 unchanged lines hidden (view full) ---

289 }
290 return ret2;
291}
292
293#define BYTES_TO_BITS(nb) ((nb) * BITS_PER_LONG / sizeof(long))
294
295static int convert_variable_type(Dwarf_Die *vr_die,
296 struct probe_trace_arg *tvar,
1/*
2 * probe-finder.c : C expression to kprobe event converter
3 *
4 * Written by Masami Hiramatsu <mhiramat@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or

--- 280 unchanged lines hidden (view full) ---

289 }
290 return ret2;
291}
292
293#define BYTES_TO_BITS(nb) ((nb) * BITS_PER_LONG / sizeof(long))
294
295static int convert_variable_type(Dwarf_Die *vr_die,
296 struct probe_trace_arg *tvar,
297 const char *cast)
297 const char *cast, bool user_access)
298{
299 struct probe_trace_arg_ref **ref_ptr = &tvar->ref;
300 Dwarf_Die type;
301 char buf[16];
302 char sbuf[STRERR_BUFSIZE];
303 int bsize, boffs, total;
304 int ret;
305 char prefix;

--- 23 unchanged lines hidden (view full) ---

329 pr_warning("Failed to get a type information of %s.\n",
330 dwarf_diename(vr_die));
331 return -ENOENT;
332 }
333
334 pr_debug("%s type is %s.\n",
335 dwarf_diename(vr_die), dwarf_diename(&type));
336
298{
299 struct probe_trace_arg_ref **ref_ptr = &tvar->ref;
300 Dwarf_Die type;
301 char buf[16];
302 char sbuf[STRERR_BUFSIZE];
303 int bsize, boffs, total;
304 int ret;
305 char prefix;

--- 23 unchanged lines hidden (view full) ---

329 pr_warning("Failed to get a type information of %s.\n",
330 dwarf_diename(vr_die));
331 return -ENOENT;
332 }
333
334 pr_debug("%s type is %s.\n",
335 dwarf_diename(vr_die), dwarf_diename(&type));
336
337 if (cast && strcmp(cast, "string") == 0) { /* String type */
337 if (cast && (!strcmp(cast, "string") || !strcmp(cast, "ustring"))) {
338 /* String type */
338 ret = dwarf_tag(&type);
339 if (ret != DW_TAG_pointer_type &&
340 ret != DW_TAG_array_type) {
341 pr_warning("Failed to cast into string: "
342 "%s(%s) is not a pointer nor array.\n",
343 dwarf_diename(vr_die), dwarf_diename(&type));
344 return -EINVAL;
345 }

--- 6 unchanged lines hidden (view full) ---

352 while (*ref_ptr)
353 ref_ptr = &(*ref_ptr)->next;
354 /* Add new reference with offset +0 */
355 *ref_ptr = zalloc(sizeof(struct probe_trace_arg_ref));
356 if (*ref_ptr == NULL) {
357 pr_warning("Out of memory error\n");
358 return -ENOMEM;
359 }
339 ret = dwarf_tag(&type);
340 if (ret != DW_TAG_pointer_type &&
341 ret != DW_TAG_array_type) {
342 pr_warning("Failed to cast into string: "
343 "%s(%s) is not a pointer nor array.\n",
344 dwarf_diename(vr_die), dwarf_diename(&type));
345 return -EINVAL;
346 }

--- 6 unchanged lines hidden (view full) ---

353 while (*ref_ptr)
354 ref_ptr = &(*ref_ptr)->next;
355 /* Add new reference with offset +0 */
356 *ref_ptr = zalloc(sizeof(struct probe_trace_arg_ref));
357 if (*ref_ptr == NULL) {
358 pr_warning("Out of memory error\n");
359 return -ENOMEM;
360 }
361 (*ref_ptr)->user_access = user_access;
360 }
361 if (!die_compare_name(&type, "char") &&
362 !die_compare_name(&type, "unsigned char")) {
363 pr_warning("Failed to cast into string: "
364 "%s is not (unsigned) char *.\n",
365 dwarf_diename(vr_die));
366 return -EINVAL;
367 }

--- 38 unchanged lines hidden (view full) ---

406 if (tvar->type == NULL)
407 return -ENOMEM;
408 return 0;
409}
410
411static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
412 struct perf_probe_arg_field *field,
413 struct probe_trace_arg_ref **ref_ptr,
362 }
363 if (!die_compare_name(&type, "char") &&
364 !die_compare_name(&type, "unsigned char")) {
365 pr_warning("Failed to cast into string: "
366 "%s is not (unsigned) char *.\n",
367 dwarf_diename(vr_die));
368 return -EINVAL;
369 }

--- 38 unchanged lines hidden (view full) ---

408 if (tvar->type == NULL)
409 return -ENOMEM;
410 return 0;
411}
412
413static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
414 struct perf_probe_arg_field *field,
415 struct probe_trace_arg_ref **ref_ptr,
414 Dwarf_Die *die_mem)
416 Dwarf_Die *die_mem, bool user_access)
415{
416 struct probe_trace_arg_ref *ref = *ref_ptr;
417 Dwarf_Die type;
418 Dwarf_Word offs;
419 int ret, tag;
420
421 pr_debug("converting %s in %s\n", field->name, varname);
422 if (die_get_real_type(vr_die, &type) == NULL) {

--- 20 unchanged lines hidden (view full) ---

443 if (ref == NULL)
444 return -ENOMEM;
445 if (*ref_ptr)
446 (*ref_ptr)->next = ref;
447 else
448 *ref_ptr = ref;
449 }
450 ref->offset += dwarf_bytesize(&type) * field->index;
417{
418 struct probe_trace_arg_ref *ref = *ref_ptr;
419 Dwarf_Die type;
420 Dwarf_Word offs;
421 int ret, tag;
422
423 pr_debug("converting %s in %s\n", field->name, varname);
424 if (die_get_real_type(vr_die, &type) == NULL) {

--- 20 unchanged lines hidden (view full) ---

445 if (ref == NULL)
446 return -ENOMEM;
447 if (*ref_ptr)
448 (*ref_ptr)->next = ref;
449 else
450 *ref_ptr = ref;
451 }
452 ref->offset += dwarf_bytesize(&type) * field->index;
453 ref->user_access = user_access;
451 goto next;
452 } else if (tag == DW_TAG_pointer_type) {
453 /* Check the pointer and dereference */
454 if (!field->ref) {
455 pr_err("Semantic error: %s must be referred by '->'\n",
456 field->name);
457 return -EINVAL;
458 }

--- 55 unchanged lines hidden (view full) ---

514 ret = die_get_data_member_location(die_mem, &offs);
515 if (ret < 0) {
516 pr_warning("Failed to get the offset of %s.\n",
517 field->name);
518 return ret;
519 }
520 }
521 ref->offset += (long)offs;
454 goto next;
455 } else if (tag == DW_TAG_pointer_type) {
456 /* Check the pointer and dereference */
457 if (!field->ref) {
458 pr_err("Semantic error: %s must be referred by '->'\n",
459 field->name);
460 return -EINVAL;
461 }

--- 55 unchanged lines hidden (view full) ---

517 ret = die_get_data_member_location(die_mem, &offs);
518 if (ret < 0) {
519 pr_warning("Failed to get the offset of %s.\n",
520 field->name);
521 return ret;
522 }
523 }
524 ref->offset += (long)offs;
525 ref->user_access = user_access;
522
523 /* If this member is unnamed, we need to reuse this field */
524 if (!dwarf_diename(die_mem))
525 return convert_variable_fields(die_mem, varname, field,
526
527 /* If this member is unnamed, we need to reuse this field */
528 if (!dwarf_diename(die_mem))
529 return convert_variable_fields(die_mem, varname, field,
526 &ref, die_mem);
530 &ref, die_mem, user_access);
527
528next:
529 /* Converting next field */
530 if (field->next)
531 return convert_variable_fields(die_mem, field->name,
531
532next:
533 /* Converting next field */
534 if (field->next)
535 return convert_variable_fields(die_mem, field->name,
532 field->next, &ref, die_mem);
536 field->next, &ref, die_mem, user_access);
533 else
534 return 0;
535}
536
537/* Show a variables in kprobe event format */
538static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
539{
540 Dwarf_Die die_mem;

--- 9 unchanged lines hidden (view full) ---

550 " Perhaps it has been optimized out.\n"
551 " Use -V with the --range option to show '%s' location range.\n",
552 pf->pvar->var, pf->pvar->var);
553 } else if (ret == -ENOTSUP)
554 pr_err("Sorry, we don't support this variable location yet.\n");
555 else if (ret == 0 && pf->pvar->field) {
556 ret = convert_variable_fields(vr_die, pf->pvar->var,
557 pf->pvar->field, &pf->tvar->ref,
537 else
538 return 0;
539}
540
541/* Show a variables in kprobe event format */
542static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
543{
544 Dwarf_Die die_mem;

--- 9 unchanged lines hidden (view full) ---

554 " Perhaps it has been optimized out.\n"
555 " Use -V with the --range option to show '%s' location range.\n",
556 pf->pvar->var, pf->pvar->var);
557 } else if (ret == -ENOTSUP)
558 pr_err("Sorry, we don't support this variable location yet.\n");
559 else if (ret == 0 && pf->pvar->field) {
560 ret = convert_variable_fields(vr_die, pf->pvar->var,
561 pf->pvar->field, &pf->tvar->ref,
558 &die_mem);
562 &die_mem, pf->pvar->user_access);
559 vr_die = &die_mem;
560 }
561 if (ret == 0)
563 vr_die = &die_mem;
564 }
565 if (ret == 0)
562 ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type);
566 ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type,
567 pf->pvar->user_access);
563 /* *expr will be cached in libdw. Don't free it. */
564 return ret;
565}
566
567/* Find a variable in a scope DIE */
568static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
569{
570 Dwarf_Die vr_die;

--- 1311 unchanged lines hidden ---
568 /* *expr will be cached in libdw. Don't free it. */
569 return ret;
570}
571
572/* Find a variable in a scope DIE */
573static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
574{
575 Dwarf_Die vr_die;

--- 1311 unchanged lines hidden ---