This source file includes following definitions.
- cu_find_realpath
- cu_get_comp_dir
- cu_find_lineinfo
- cu_walk_functions_at
- die_get_linkage_name
- die_compare_name
- die_match_name
- die_get_call_lineno
- die_get_type
- __die_get_real_type
- die_get_real_type
- die_get_attr_udata
- die_get_attr_sdata
- die_is_signed_type
- die_is_func_def
- die_entrypc
- die_is_func_instance
- die_get_data_member_location
- die_get_call_fileno
- die_get_decl_fileno
- die_get_call_file
- die_find_child
- __die_search_func_tail_cb
- die_find_tailfunc
- __die_search_func_cb
- die_find_realfunc
- __die_find_inline_cb
- die_find_top_inlinefunc
- die_find_inlinefunc
- __die_walk_instances_cb
- die_walk_instances
- __die_walk_funclines_cb
- __die_walk_funclines
- __die_walk_culines_cb
- die_walk_lines
- __die_find_variable_cb
- die_find_variable_at
- __die_find_member_cb
- die_find_member
- die_get_typename
- die_get_varname
- die_get_var_innermost_scope
- die_get_var_range
- die_get_var_range
- die_has_loclist
- die_is_optimized_target
- die_search_idx
- die_get_postprologue_addr
- die_skip_prologue
   1 
   2 
   3 
   4 
   5 
   6 #include <errno.h>
   7 #include <inttypes.h>
   8 #include <stdbool.h>
   9 #include <stdlib.h>
  10 #include "debug.h"
  11 #include "dwarf-aux.h"
  12 #include "strbuf.h"
  13 #include "string2.h"
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname)
  23 {
  24         Dwarf_Files *files;
  25         size_t nfiles, i;
  26         const char *src = NULL;
  27         int ret;
  28 
  29         if (!fname)
  30                 return NULL;
  31 
  32         ret = dwarf_getsrcfiles(cu_die, &files, &nfiles);
  33         if (ret != 0)
  34                 return NULL;
  35 
  36         for (i = 0; i < nfiles; i++) {
  37                 src = dwarf_filesrc(files, i, NULL, NULL);
  38                 if (strtailcmp(src, fname) == 0)
  39                         break;
  40         }
  41         if (i == nfiles)
  42                 return NULL;
  43         return src;
  44 }
  45 
  46 
  47 
  48 
  49 
  50 
  51 
  52 
  53 
  54 const char *cu_get_comp_dir(Dwarf_Die *cu_die)
  55 {
  56         Dwarf_Attribute attr;
  57         if (dwarf_attr(cu_die, DW_AT_comp_dir, &attr) == NULL)
  58                 return NULL;
  59         return dwarf_formstring(&attr);
  60 }
  61 
  62 
  63 
  64 
  65 
  66 
  67 
  68 
  69 
  70 
  71 int cu_find_lineinfo(Dwarf_Die *cu_die, unsigned long addr,
  72                     const char **fname, int *lineno)
  73 {
  74         Dwarf_Line *line;
  75         Dwarf_Addr laddr;
  76 
  77         line = dwarf_getsrc_die(cu_die, (Dwarf_Addr)addr);
  78         if (line && dwarf_lineaddr(line, &laddr) == 0 &&
  79             addr == (unsigned long)laddr && dwarf_lineno(line, lineno) == 0) {
  80                 *fname = dwarf_linesrc(line, NULL, NULL);
  81                 if (!*fname)
  82                         
  83                         *lineno = 0;
  84         }
  85 
  86         return *lineno ?: -ENOENT;
  87 }
  88 
  89 static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data);
  90 
  91 
  92 
  93 
  94 
  95 
  96 
  97 
  98 
  99 
 100 
 101 int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
 102                     int (*callback)(Dwarf_Die *, void *), void *data)
 103 {
 104         Dwarf_Die die_mem;
 105         Dwarf_Die *sc_die;
 106         int ret = -ENOENT;
 107 
 108         
 109         for (sc_die = die_find_realfunc(cu_die, addr, &die_mem);
 110              sc_die != NULL;
 111              sc_die = die_find_child(sc_die, __die_find_inline_cb, &addr,
 112                                      &die_mem)) {
 113                 ret = callback(sc_die, data);
 114                 if (ret)
 115                         break;
 116         }
 117 
 118         return ret;
 119 
 120 }
 121 
 122 
 123 
 124 
 125 
 126 
 127 
 128 
 129 const char *die_get_linkage_name(Dwarf_Die *dw_die)
 130 {
 131         Dwarf_Attribute attr;
 132 
 133         if (dwarf_attr_integrate(dw_die, DW_AT_linkage_name, &attr) == NULL)
 134                 return NULL;
 135         return dwarf_formstring(&attr);
 136 }
 137 
 138 
 139 
 140 
 141 
 142 
 143 
 144 
 145 bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
 146 {
 147         const char *name;
 148 
 149         name = dwarf_diename(dw_die);
 150         return name ? (strcmp(tname, name) == 0) : false;
 151 }
 152 
 153 
 154 
 155 
 156 
 157 
 158 
 159 
 160 
 161 bool die_match_name(Dwarf_Die *dw_die, const char *glob)
 162 {
 163         const char *name;
 164 
 165         name = dwarf_diename(dw_die);
 166         if (name && strglobmatch(name, glob))
 167                 return true;
 168         
 169         name = die_get_linkage_name(dw_die);
 170         if (name && strglobmatch(name, glob))
 171                 return true;
 172 
 173         return false;
 174 }
 175 
 176 
 177 
 178 
 179 
 180 
 181 
 182 
 183 int die_get_call_lineno(Dwarf_Die *in_die)
 184 {
 185         Dwarf_Attribute attr;
 186         Dwarf_Word ret;
 187 
 188         if (!dwarf_attr(in_die, DW_AT_call_line, &attr))
 189                 return -ENOENT;
 190 
 191         dwarf_formudata(&attr, &ret);
 192         return (int)ret;
 193 }
 194 
 195 
 196 
 197 
 198 
 199 
 200 
 201 
 202 
 203 Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
 204 {
 205         Dwarf_Attribute attr;
 206 
 207         if (dwarf_attr_integrate(vr_die, DW_AT_type, &attr) &&
 208             dwarf_formref_die(&attr, die_mem))
 209                 return die_mem;
 210         else
 211                 return NULL;
 212 }
 213 
 214 
 215 static Dwarf_Die *__die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
 216 {
 217         int tag;
 218 
 219         do {
 220                 vr_die = die_get_type(vr_die, die_mem);
 221                 if (!vr_die)
 222                         break;
 223                 tag = dwarf_tag(vr_die);
 224         } while (tag == DW_TAG_const_type ||
 225                  tag == DW_TAG_restrict_type ||
 226                  tag == DW_TAG_volatile_type ||
 227                  tag == DW_TAG_shared_type);
 228 
 229         return vr_die;
 230 }
 231 
 232 
 233 
 234 
 235 
 236 
 237 
 238 
 239 
 240 
 241 
 242 Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem)
 243 {
 244         do {
 245                 vr_die = __die_get_real_type(vr_die, die_mem);
 246         } while (vr_die && dwarf_tag(vr_die) == DW_TAG_typedef);
 247 
 248         return vr_die;
 249 }
 250 
 251 
 252 static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name,
 253                               Dwarf_Word *result)
 254 {
 255         Dwarf_Attribute attr;
 256 
 257         if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
 258             dwarf_formudata(&attr, result) != 0)
 259                 return -ENOENT;
 260 
 261         return 0;
 262 }
 263 
 264 
 265 static int die_get_attr_sdata(Dwarf_Die *tp_die, unsigned int attr_name,
 266                               Dwarf_Sword *result)
 267 {
 268         Dwarf_Attribute attr;
 269 
 270         if (dwarf_attr(tp_die, attr_name, &attr) == NULL ||
 271             dwarf_formsdata(&attr, result) != 0)
 272                 return -ENOENT;
 273 
 274         return 0;
 275 }
 276 
 277 
 278 
 279 
 280 
 281 
 282 
 283 
 284 bool die_is_signed_type(Dwarf_Die *tp_die)
 285 {
 286         Dwarf_Word ret;
 287 
 288         if (die_get_attr_udata(tp_die, DW_AT_encoding, &ret))
 289                 return false;
 290 
 291         return (ret == DW_ATE_signed_char || ret == DW_ATE_signed ||
 292                 ret == DW_ATE_signed_fixed);
 293 }
 294 
 295 
 296 
 297 
 298 
 299 
 300 
 301 
 302 bool die_is_func_def(Dwarf_Die *dw_die)
 303 {
 304         Dwarf_Attribute attr;
 305 
 306         return (dwarf_tag(dw_die) == DW_TAG_subprogram &&
 307                 dwarf_attr(dw_die, DW_AT_declaration, &attr) == NULL);
 308 }
 309 
 310 
 311 
 312 
 313 
 314 
 315 
 316 
 317 
 318 
 319 int die_entrypc(Dwarf_Die *dw_die, Dwarf_Addr *addr)
 320 {
 321         Dwarf_Addr base, end;
 322 
 323         if (!addr)
 324                 return -EINVAL;
 325 
 326         if (dwarf_entrypc(dw_die, addr) == 0)
 327                 return 0;
 328 
 329         return dwarf_ranges(dw_die, 0, &base, addr, &end) < 0 ? -ENOENT : 0;
 330 }
 331 
 332 
 333 
 334 
 335 
 336 
 337 
 338 
 339 
 340 
 341 bool die_is_func_instance(Dwarf_Die *dw_die)
 342 {
 343         Dwarf_Addr tmp;
 344         Dwarf_Attribute attr_mem;
 345         int tag = dwarf_tag(dw_die);
 346 
 347         if (tag != DW_TAG_subprogram &&
 348             tag != DW_TAG_inlined_subroutine)
 349                 return false;
 350 
 351         return dwarf_entrypc(dw_die, &tmp) == 0 ||
 352                 dwarf_attr(dw_die, DW_AT_ranges, &attr_mem) != NULL;
 353 }
 354 
 355 
 356 
 357 
 358 
 359 
 360 
 361 
 362 
 363 int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs)
 364 {
 365         Dwarf_Attribute attr;
 366         Dwarf_Op *expr;
 367         size_t nexpr;
 368         int ret;
 369 
 370         if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL)
 371                 return -ENOENT;
 372 
 373         if (dwarf_formudata(&attr, offs) != 0) {
 374                 
 375                 ret = dwarf_getlocation(&attr, &expr, &nexpr);
 376                 if (ret < 0 || nexpr == 0)
 377                         return -ENOENT;
 378 
 379                 if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) {
 380                         pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n",
 381                                  expr[0].atom, nexpr);
 382                         return -ENOTSUP;
 383                 }
 384                 *offs = (Dwarf_Word)expr[0].number;
 385         }
 386         return 0;
 387 }
 388 
 389 
 390 static int die_get_call_fileno(Dwarf_Die *in_die)
 391 {
 392         Dwarf_Sword idx;
 393 
 394         if (die_get_attr_sdata(in_die, DW_AT_call_file, &idx) == 0)
 395                 return (int)idx;
 396         else
 397                 return -ENOENT;
 398 }
 399 
 400 
 401 static int die_get_decl_fileno(Dwarf_Die *pdie)
 402 {
 403         Dwarf_Sword idx;
 404 
 405         if (die_get_attr_sdata(pdie, DW_AT_decl_file, &idx) == 0)
 406                 return (int)idx;
 407         else
 408                 return -ENOENT;
 409 }
 410 
 411 
 412 
 413 
 414 
 415 
 416 
 417 
 418 const char *die_get_call_file(Dwarf_Die *in_die)
 419 {
 420         Dwarf_Die cu_die;
 421         Dwarf_Files *files;
 422         int idx;
 423 
 424         idx = die_get_call_fileno(in_die);
 425         if (idx < 0 || !dwarf_diecu(in_die, &cu_die, NULL, NULL) ||
 426             dwarf_getsrcfiles(&cu_die, &files, NULL) != 0)
 427                 return NULL;
 428 
 429         return dwarf_filesrc(files, idx, NULL, NULL);
 430 }
 431 
 432 
 433 
 434 
 435 
 436 
 437 
 438 
 439 
 440 
 441 
 442 
 443 
 444 
 445 
 446 
 447 
 448 Dwarf_Die *die_find_child(Dwarf_Die *rt_die,
 449                           int (*callback)(Dwarf_Die *, void *),
 450                           void *data, Dwarf_Die *die_mem)
 451 {
 452         Dwarf_Die child_die;
 453         int ret;
 454 
 455         ret = dwarf_child(rt_die, die_mem);
 456         if (ret != 0)
 457                 return NULL;
 458 
 459         do {
 460                 ret = callback(die_mem, data);
 461                 if (ret == DIE_FIND_CB_END)
 462                         return die_mem;
 463 
 464                 if ((ret & DIE_FIND_CB_CHILD) &&
 465                     die_find_child(die_mem, callback, data, &child_die)) {
 466                         memcpy(die_mem, &child_die, sizeof(Dwarf_Die));
 467                         return die_mem;
 468                 }
 469         } while ((ret & DIE_FIND_CB_SIBLING) &&
 470                  dwarf_siblingof(die_mem, die_mem) == 0);
 471 
 472         return NULL;
 473 }
 474 
 475 struct __addr_die_search_param {
 476         Dwarf_Addr      addr;
 477         Dwarf_Die       *die_mem;
 478 };
 479 
 480 static int __die_search_func_tail_cb(Dwarf_Die *fn_die, void *data)
 481 {
 482         struct __addr_die_search_param *ad = data;
 483         Dwarf_Addr addr = 0;
 484 
 485         if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
 486             !dwarf_highpc(fn_die, &addr) &&
 487             addr == ad->addr) {
 488                 memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));
 489                 return DWARF_CB_ABORT;
 490         }
 491         return DWARF_CB_OK;
 492 }
 493 
 494 
 495 
 496 
 497 
 498 
 499 
 500 
 501 
 502 
 503 
 504 Dwarf_Die *die_find_tailfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
 505                                     Dwarf_Die *die_mem)
 506 {
 507         struct __addr_die_search_param ad;
 508         ad.addr = addr;
 509         ad.die_mem = die_mem;
 510         
 511         if (!dwarf_getfuncs(cu_die, __die_search_func_tail_cb, &ad, 0))
 512                 return NULL;
 513         else
 514                 return die_mem;
 515 }
 516 
 517 
 518 static int __die_search_func_cb(Dwarf_Die *fn_die, void *data)
 519 {
 520         struct __addr_die_search_param *ad = data;
 521 
 522         
 523 
 524 
 525 
 526         if (dwarf_tag(fn_die) == DW_TAG_subprogram &&
 527             dwarf_haspc(fn_die, ad->addr)) {
 528                 memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die));
 529                 return DWARF_CB_ABORT;
 530         }
 531         return DWARF_CB_OK;
 532 }
 533 
 534 
 535 
 536 
 537 
 538 
 539 
 540 
 541 
 542 
 543 Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr,
 544                                     Dwarf_Die *die_mem)
 545 {
 546         struct __addr_die_search_param ad;
 547         ad.addr = addr;
 548         ad.die_mem = die_mem;
 549         
 550         if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0))
 551                 return NULL;
 552         else
 553                 return die_mem;
 554 }
 555 
 556 
 557 static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data)
 558 {
 559         Dwarf_Addr *addr = data;
 560 
 561         if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine &&
 562             dwarf_haspc(die_mem, *addr))
 563                 return DIE_FIND_CB_END;
 564 
 565         return DIE_FIND_CB_CONTINUE;
 566 }
 567 
 568 
 569 
 570 
 571 
 572 
 573 
 574 
 575 
 576 
 577 
 578 
 579 Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
 580                                    Dwarf_Die *die_mem)
 581 {
 582         return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem);
 583 }
 584 
 585 
 586 
 587 
 588 
 589 
 590 
 591 
 592 
 593 
 594 
 595 
 596 Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
 597                                Dwarf_Die *die_mem)
 598 {
 599         Dwarf_Die tmp_die;
 600 
 601         sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, &tmp_die);
 602         if (!sp_die)
 603                 return NULL;
 604 
 605         
 606         while (sp_die) {
 607                 memcpy(die_mem, sp_die, sizeof(Dwarf_Die));
 608                 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr,
 609                                         &tmp_die);
 610         }
 611 
 612         return die_mem;
 613 }
 614 
 615 struct __instance_walk_param {
 616         void    *addr;
 617         int     (*callback)(Dwarf_Die *, void *);
 618         void    *data;
 619         int     retval;
 620 };
 621 
 622 static int __die_walk_instances_cb(Dwarf_Die *inst, void *data)
 623 {
 624         struct __instance_walk_param *iwp = data;
 625         Dwarf_Attribute attr_mem;
 626         Dwarf_Die origin_mem;
 627         Dwarf_Attribute *attr;
 628         Dwarf_Die *origin;
 629         int tmp;
 630 
 631         if (!die_is_func_instance(inst))
 632                 return DIE_FIND_CB_CONTINUE;
 633 
 634         attr = dwarf_attr(inst, DW_AT_abstract_origin, &attr_mem);
 635         if (attr == NULL)
 636                 return DIE_FIND_CB_CONTINUE;
 637 
 638         origin = dwarf_formref_die(attr, &origin_mem);
 639         if (origin == NULL || origin->addr != iwp->addr)
 640                 return DIE_FIND_CB_CONTINUE;
 641 
 642         
 643         if (dwarf_tag(inst) == DW_TAG_inlined_subroutine) {
 644                 dwarf_decl_line(origin, &tmp);
 645                 if (die_get_call_lineno(inst) == tmp) {
 646                         tmp = die_get_decl_fileno(origin);
 647                         if (die_get_call_fileno(inst) == tmp)
 648                                 return DIE_FIND_CB_CONTINUE;
 649                 }
 650         }
 651 
 652         iwp->retval = iwp->callback(inst, iwp->data);
 653 
 654         return (iwp->retval) ? DIE_FIND_CB_END : DIE_FIND_CB_CONTINUE;
 655 }
 656 
 657 
 658 
 659 
 660 
 661 
 662 
 663 
 664 
 665 
 666 
 667 int die_walk_instances(Dwarf_Die *or_die, int (*callback)(Dwarf_Die *, void *),
 668                        void *data)
 669 {
 670         Dwarf_Die cu_die;
 671         Dwarf_Die die_mem;
 672         struct __instance_walk_param iwp = {
 673                 .addr = or_die->addr,
 674                 .callback = callback,
 675                 .data = data,
 676                 .retval = -ENOENT,
 677         };
 678 
 679         if (dwarf_diecu(or_die, &cu_die, NULL, NULL) == NULL)
 680                 return -ENOENT;
 681 
 682         die_find_child(&cu_die, __die_walk_instances_cb, &iwp, &die_mem);
 683 
 684         return iwp.retval;
 685 }
 686 
 687 
 688 struct __line_walk_param {
 689         bool recursive;
 690         line_walk_callback_t callback;
 691         void *data;
 692         int retval;
 693 };
 694 
 695 static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data)
 696 {
 697         struct __line_walk_param *lw = data;
 698         Dwarf_Addr addr = 0;
 699         const char *fname;
 700         int lineno;
 701 
 702         if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) {
 703                 fname = die_get_call_file(in_die);
 704                 lineno = die_get_call_lineno(in_die);
 705                 if (fname && lineno > 0 && die_entrypc(in_die, &addr) == 0) {
 706                         lw->retval = lw->callback(fname, lineno, addr, lw->data);
 707                         if (lw->retval != 0)
 708                                 return DIE_FIND_CB_END;
 709                 }
 710                 if (!lw->recursive)
 711                         return DIE_FIND_CB_SIBLING;
 712         }
 713 
 714         if (addr) {
 715                 fname = dwarf_decl_file(in_die);
 716                 if (fname && dwarf_decl_line(in_die, &lineno) == 0) {
 717                         lw->retval = lw->callback(fname, lineno, addr, lw->data);
 718                         if (lw->retval != 0)
 719                                 return DIE_FIND_CB_END;
 720                 }
 721         }
 722 
 723         
 724         return DIE_FIND_CB_CONTINUE;
 725 }
 726 
 727 
 728 static int __die_walk_funclines(Dwarf_Die *sp_die, bool recursive,
 729                                 line_walk_callback_t callback, void *data)
 730 {
 731         struct __line_walk_param lw = {
 732                 .recursive = recursive,
 733                 .callback = callback,
 734                 .data = data,
 735                 .retval = 0,
 736         };
 737         Dwarf_Die die_mem;
 738         Dwarf_Addr addr;
 739         const char *fname;
 740         int lineno;
 741 
 742         
 743         fname = dwarf_decl_file(sp_die);
 744         if (fname && dwarf_decl_line(sp_die, &lineno) == 0 &&
 745             die_entrypc(sp_die, &addr) == 0) {
 746                 lw.retval = callback(fname, lineno, addr, data);
 747                 if (lw.retval != 0)
 748                         goto done;
 749         }
 750         die_find_child(sp_die, __die_walk_funclines_cb, &lw, &die_mem);
 751 done:
 752         return lw.retval;
 753 }
 754 
 755 static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data)
 756 {
 757         struct __line_walk_param *lw = data;
 758 
 759         
 760 
 761 
 762 
 763         lw->retval = __die_walk_funclines(sp_die, true, lw->callback, lw->data);
 764         if (lw->retval != 0)
 765                 return DWARF_CB_ABORT;
 766 
 767         return DWARF_CB_OK;
 768 }
 769 
 770 
 771 
 772 
 773 
 774 
 775 
 776 
 777 
 778 
 779 
 780 
 781 
 782 int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)
 783 {
 784         Dwarf_Lines *lines;
 785         Dwarf_Line *line;
 786         Dwarf_Addr addr;
 787         const char *fname, *decf = NULL, *inf = NULL;
 788         int lineno, ret = 0;
 789         int decl = 0, inl;
 790         Dwarf_Die die_mem, *cu_die;
 791         size_t nlines, i;
 792         bool flag;
 793 
 794         
 795         if (dwarf_tag(rt_die) != DW_TAG_compile_unit) {
 796                 cu_die = dwarf_diecu(rt_die, &die_mem, NULL, NULL);
 797                 dwarf_decl_line(rt_die, &decl);
 798                 decf = dwarf_decl_file(rt_die);
 799         } else
 800                 cu_die = rt_die;
 801         if (!cu_die) {
 802                 pr_debug2("Failed to get CU from given DIE.\n");
 803                 return -EINVAL;
 804         }
 805 
 806         
 807         if (dwarf_getsrclines(cu_die, &lines, &nlines) != 0) {
 808                 pr_debug2("Failed to get source lines on this CU.\n");
 809                 return -ENOENT;
 810         }
 811         pr_debug2("Get %zd lines from this CU\n", nlines);
 812 
 813         
 814         for (i = 0; i < nlines; i++) {
 815                 line = dwarf_onesrcline(lines, i);
 816                 if (line == NULL ||
 817                     dwarf_lineno(line, &lineno) != 0 ||
 818                     dwarf_lineaddr(line, &addr) != 0) {
 819                         pr_debug2("Failed to get line info. "
 820                                   "Possible error in debuginfo.\n");
 821                         continue;
 822                 }
 823                 
 824                 if (dwarf_lineendsequence(line, &flag) != 0 || flag)
 825                         continue;
 826                 
 827                 if (dwarf_linebeginstatement(line, &flag) != 0 || !flag)
 828                         continue;
 829                 
 830                 if (rt_die != cu_die) {
 831                         
 832 
 833 
 834 
 835 
 836                         if (!dwarf_haspc(rt_die, addr))
 837                                 continue;
 838 
 839                         if (die_find_inlinefunc(rt_die, addr, &die_mem)) {
 840                                 
 841                                 inf = die_get_call_file(&die_mem);
 842                                 if ((inf && !strcmp(inf, decf)) &&
 843                                     die_get_call_lineno(&die_mem) == lineno)
 844                                         goto found;
 845 
 846                                 dwarf_decl_line(&die_mem, &inl);
 847                                 if (inl != decl ||
 848                                     decf != dwarf_decl_file(&die_mem))
 849                                         continue;
 850                         }
 851                 }
 852 found:
 853                 
 854                 fname = dwarf_linesrc(line, NULL, NULL);
 855 
 856                 ret = callback(fname, lineno, addr, data);
 857                 if (ret != 0)
 858                         return ret;
 859         }
 860 
 861         
 862 
 863 
 864 
 865         if (rt_die != cu_die)
 866                 
 867 
 868 
 869 
 870 
 871                 ret = __die_walk_funclines(rt_die, false, callback, data);
 872         else {
 873                 struct __line_walk_param param = {
 874                         .callback = callback,
 875                         .data = data,
 876                         .retval = 0,
 877                 };
 878                 dwarf_getfuncs(cu_die, __die_walk_culines_cb, ¶m, 0);
 879                 ret = param.retval;
 880         }
 881 
 882         return ret;
 883 }
 884 
 885 struct __find_variable_param {
 886         const char *name;
 887         Dwarf_Addr addr;
 888 };
 889 
 890 static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
 891 {
 892         struct __find_variable_param *fvp = data;
 893         Dwarf_Attribute attr;
 894         int tag;
 895 
 896         tag = dwarf_tag(die_mem);
 897         if ((tag == DW_TAG_formal_parameter ||
 898              tag == DW_TAG_variable) &&
 899             die_compare_name(die_mem, fvp->name) &&
 900         
 901             (dwarf_attr(die_mem, DW_AT_external, &attr) ||
 902              dwarf_attr(die_mem, DW_AT_location, &attr)))
 903                 return DIE_FIND_CB_END;
 904         if (dwarf_haspc(die_mem, fvp->addr))
 905                 return DIE_FIND_CB_CONTINUE;
 906         else
 907                 return DIE_FIND_CB_SIBLING;
 908 }
 909 
 910 
 911 
 912 
 913 
 914 
 915 
 916 
 917 
 918 
 919 Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
 920                                 Dwarf_Addr addr, Dwarf_Die *die_mem)
 921 {
 922         struct __find_variable_param fvp = { .name = name, .addr = addr};
 923 
 924         return die_find_child(sp_die, __die_find_variable_cb, (void *)&fvp,
 925                               die_mem);
 926 }
 927 
 928 static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
 929 {
 930         const char *name = data;
 931 
 932         if (dwarf_tag(die_mem) == DW_TAG_member) {
 933                 if (die_compare_name(die_mem, name))
 934                         return DIE_FIND_CB_END;
 935                 else if (!dwarf_diename(die_mem)) {     
 936                         Dwarf_Die type_die, tmp_die;
 937                         if (die_get_type(die_mem, &type_die) &&
 938                             die_find_member(&type_die, name, &tmp_die))
 939                                 return DIE_FIND_CB_END;
 940                 }
 941         }
 942         return DIE_FIND_CB_SIBLING;
 943 }
 944 
 945 
 946 
 947 
 948 
 949 
 950 
 951 
 952 
 953 Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name,
 954                            Dwarf_Die *die_mem)
 955 {
 956         return die_find_child(st_die, __die_find_member_cb, (void *)name,
 957                               die_mem);
 958 }
 959 
 960 
 961 
 962 
 963 
 964 
 965 
 966 
 967 
 968 
 969 
 970 int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf)
 971 {
 972         Dwarf_Die type;
 973         int tag, ret;
 974         const char *tmp = "";
 975 
 976         if (__die_get_real_type(vr_die, &type) == NULL)
 977                 return -ENOENT;
 978 
 979         tag = dwarf_tag(&type);
 980         if (tag == DW_TAG_array_type || tag == DW_TAG_pointer_type)
 981                 tmp = "*";
 982         else if (tag == DW_TAG_subroutine_type) {
 983                 
 984                 return strbuf_add(buf, "(function_type)", 15);
 985         } else {
 986                 if (!dwarf_diename(&type))
 987                         return -ENOENT;
 988                 if (tag == DW_TAG_union_type)
 989                         tmp = "union ";
 990                 else if (tag == DW_TAG_structure_type)
 991                         tmp = "struct ";
 992                 else if (tag == DW_TAG_enumeration_type)
 993                         tmp = "enum ";
 994                 
 995                 return strbuf_addf(buf, "%s%s", tmp, dwarf_diename(&type));
 996         }
 997         ret = die_get_typename(&type, buf);
 998         return ret ? ret : strbuf_addstr(buf, tmp);
 999 }
1000 
1001 
1002 
1003 
1004 
1005 
1006 
1007 
1008 int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf)
1009 {
1010         int ret;
1011 
1012         ret = die_get_typename(vr_die, buf);
1013         if (ret < 0) {
1014                 pr_debug("Failed to get type, make it unknown.\n");
1015                 ret = strbuf_add(buf, " (unknown_type)", 14);
1016         }
1017 
1018         return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die));
1019 }
1020 
1021 #ifdef HAVE_DWARF_GETLOCATIONS_SUPPORT
1022 
1023 
1024 
1025 
1026 
1027 
1028 
1029 
1030 
1031 static int die_get_var_innermost_scope(Dwarf_Die *sp_die, Dwarf_Die *vr_die,
1032                                 struct strbuf *buf)
1033 {
1034         Dwarf_Die *scopes;
1035         int count;
1036         size_t offset = 0;
1037         Dwarf_Addr base;
1038         Dwarf_Addr start, end;
1039         Dwarf_Addr entry;
1040         int ret;
1041         bool first = true;
1042         const char *name;
1043 
1044         ret = die_entrypc(sp_die, &entry);
1045         if (ret)
1046                 return ret;
1047 
1048         name = dwarf_diename(sp_die);
1049         if (!name)
1050                 return -ENOENT;
1051 
1052         count = dwarf_getscopes_die(vr_die, &scopes);
1053 
1054         
1055         if (count <= 1) {
1056                 ret = -EINVAL;
1057                 goto out;
1058         }
1059 
1060         while ((offset = dwarf_ranges(&scopes[1], offset, &base,
1061                                         &start, &end)) > 0) {
1062                 start -= entry;
1063                 end -= entry;
1064 
1065                 if (first) {
1066                         ret = strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64,
1067                                           name, start, end);
1068                         first = false;
1069                 } else {
1070                         ret = strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64,
1071                                           start, end);
1072                 }
1073                 if (ret < 0)
1074                         goto out;
1075         }
1076 
1077         if (!first)
1078                 ret = strbuf_add(buf, "]>", 2);
1079 
1080 out:
1081         free(scopes);
1082         return ret;
1083 }
1084 
1085 
1086 
1087 
1088 
1089 
1090 
1091 
1092 
1093 
1094 int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf)
1095 {
1096         int ret = 0;
1097         Dwarf_Addr base;
1098         Dwarf_Addr start, end;
1099         Dwarf_Addr entry;
1100         Dwarf_Op *op;
1101         size_t nops;
1102         size_t offset = 0;
1103         Dwarf_Attribute attr;
1104         bool first = true;
1105         const char *name;
1106 
1107         ret = die_entrypc(sp_die, &entry);
1108         if (ret)
1109                 return ret;
1110 
1111         name = dwarf_diename(sp_die);
1112         if (!name)
1113                 return -ENOENT;
1114 
1115         if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL)
1116                 return -EINVAL;
1117 
1118         while ((offset = dwarf_getlocations(&attr, offset, &base,
1119                                         &start, &end, &op, &nops)) > 0) {
1120                 if (start == 0) {
1121                         
1122                         ret = die_get_var_innermost_scope(sp_die, vr_die, buf);
1123                         goto out;
1124                 }
1125 
1126                 
1127                 start -= entry;
1128                 end -= entry;
1129                 if (first) {
1130                         ret = strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64,
1131                                           name, start, end);
1132                         first = false;
1133                 } else {
1134                         ret = strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64,
1135                                           start, end);
1136                 }
1137                 if (ret < 0)
1138                         goto out;
1139         }
1140 
1141         if (!first)
1142                 ret = strbuf_add(buf, "]>", 2);
1143 out:
1144         return ret;
1145 }
1146 #else
1147 int die_get_var_range(Dwarf_Die *sp_die __maybe_unused,
1148                       Dwarf_Die *vr_die __maybe_unused,
1149                       struct strbuf *buf __maybe_unused)
1150 {
1151         return -ENOTSUP;
1152 }
1153 #endif
1154 
1155 
1156 
1157 
1158 
1159 static bool die_has_loclist(Dwarf_Die *vr_die)
1160 {
1161         Dwarf_Attribute loc;
1162         int tag = dwarf_tag(vr_die);
1163 
1164         if (tag != DW_TAG_formal_parameter &&
1165             tag != DW_TAG_variable)
1166                 return false;
1167 
1168         return (dwarf_attr_integrate(vr_die, DW_AT_location, &loc) &&
1169                 dwarf_whatform(&loc) == DW_FORM_sec_offset);
1170 }
1171 
1172 
1173 
1174 
1175 
1176 
1177 
1178 
1179 
1180 
1181 bool die_is_optimized_target(Dwarf_Die *cu_die)
1182 {
1183         Dwarf_Die tmp_die;
1184 
1185         if (die_has_loclist(cu_die))
1186                 return true;
1187 
1188         if (!dwarf_child(cu_die, &tmp_die) &&
1189             die_is_optimized_target(&tmp_die))
1190                 return true;
1191 
1192         if (!dwarf_siblingof(cu_die, &tmp_die) &&
1193             die_is_optimized_target(&tmp_die))
1194                 return true;
1195 
1196         return false;
1197 }
1198 
1199 
1200 
1201 
1202 
1203 
1204 
1205 
1206 
1207 
1208 
1209 
1210 
1211 static bool die_search_idx(Dwarf_Lines *lines, unsigned long nr_lines,
1212                            Dwarf_Addr addr, unsigned long *idx)
1213 {
1214         unsigned long i;
1215         Dwarf_Addr tmp;
1216 
1217         for (i = 0; i < nr_lines; i++) {
1218                 if (dwarf_lineaddr(dwarf_onesrcline(lines, i), &tmp))
1219                         return false;
1220 
1221                 if (tmp == addr) {
1222                         *idx = i;
1223                         return true;
1224                 }
1225         }
1226         return false;
1227 }
1228 
1229 
1230 
1231 
1232 
1233 
1234 
1235 
1236 
1237 
1238 
1239 
1240 static bool die_get_postprologue_addr(unsigned long entrypc_idx,
1241                                       Dwarf_Lines *lines,
1242                                       unsigned long nr_lines,
1243                                       Dwarf_Addr highpc,
1244                                       Dwarf_Addr *postprologue_addr)
1245 {
1246         unsigned long i;
1247         int entrypc_lno, lno;
1248         Dwarf_Line *line;
1249         Dwarf_Addr addr;
1250         bool p_end;
1251 
1252         
1253         line = dwarf_onesrcline(lines, entrypc_idx);
1254         if (dwarf_lineno(line, &entrypc_lno))
1255                 return false;
1256 
1257         for (i = entrypc_idx; i < nr_lines; i++) {
1258                 line = dwarf_onesrcline(lines, i);
1259 
1260                 if (dwarf_lineaddr(line, &addr) ||
1261                     dwarf_lineno(line, &lno)    ||
1262                     dwarf_lineprologueend(line, &p_end))
1263                         return false;
1264 
1265                 
1266                 if (addr >= highpc)
1267                         break;
1268 
1269                 
1270                 if (p_end)
1271                         break;
1272 
1273                 
1274                 if (lno != entrypc_lno)
1275                         break;
1276 
1277                 
1278 
1279 
1280 
1281 
1282 
1283 
1284 
1285                 if (i != entrypc_idx)
1286                         break;
1287         }
1288 
1289         dwarf_lineaddr(line, postprologue_addr);
1290         if (*postprologue_addr >= highpc)
1291                 dwarf_lineaddr(dwarf_onesrcline(lines, i - 1),
1292                                postprologue_addr);
1293 
1294         return true;
1295 }
1296 
1297 
1298 
1299 
1300 
1301 
1302 
1303 
1304 
1305 
1306 
1307 
1308 
1309 void die_skip_prologue(Dwarf_Die *sp_die, Dwarf_Die *cu_die,
1310                        Dwarf_Addr *entrypc)
1311 {
1312         size_t nr_lines = 0;
1313         unsigned long entrypc_idx = 0;
1314         Dwarf_Lines *lines = NULL;
1315         Dwarf_Addr postprologue_addr;
1316         Dwarf_Addr highpc;
1317 
1318         if (dwarf_highpc(sp_die, &highpc))
1319                 return;
1320 
1321         if (dwarf_getsrclines(cu_die, &lines, &nr_lines))
1322                 return;
1323 
1324         if (!die_search_idx(lines, nr_lines, *entrypc, &entrypc_idx))
1325                 return;
1326 
1327         if (!die_get_postprologue_addr(entrypc_idx, lines, nr_lines,
1328                                        highpc, &postprologue_addr))
1329                 return;
1330 
1331         *entrypc = postprologue_addr;
1332 }