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 --- |