1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * dwarf-aux.c : libdw auxiliary interfaces 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 "dwarf-regs.h" 13 #include "strbuf.h" 14 #include "string2.h" 15 16 /** 17 * cu_find_realpath - Find the realpath of the target file 18 * @cu_die: A DIE(dwarf information entry) of CU(compilation Unit) 19 * @fname: The tail filename of the target file 20 * 21 * Find the real(long) path of @fname in @cu_die. 22 */ 23 const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname) 24 { 25 Dwarf_Files *files; 26 size_t nfiles, i; 27 const char *src = NULL; 28 int ret; 29 30 if (!fname) 31 return NULL; 32 33 ret = dwarf_getsrcfiles(cu_die, &files, &nfiles); 34 if (ret != 0) 35 return NULL; 36 37 for (i = 0; i < nfiles; i++) { 38 src = dwarf_filesrc(files, i, NULL, NULL); 39 if (strtailcmp(src, fname) == 0) 40 break; 41 } 42 if (i == nfiles) 43 return NULL; 44 return src; 45 } 46 47 /** 48 * cu_get_comp_dir - Get the path of compilation directory 49 * @cu_die: a CU DIE 50 * 51 * Get the path of compilation directory of given @cu_die. 52 * Since this depends on DW_AT_comp_dir, older gcc will not 53 * embedded it. In that case, this returns NULL. 54 */ 55 const char *cu_get_comp_dir(Dwarf_Die *cu_die) 56 { 57 Dwarf_Attribute attr; 58 if (dwarf_attr(cu_die, DW_AT_comp_dir, &attr) == NULL) 59 return NULL; 60 return dwarf_formstring(&attr); 61 } 62 63 /* Unlike dwarf_getsrc_die(), cu_getsrc_die() only returns statement line */ 64 static Dwarf_Line *cu_getsrc_die(Dwarf_Die *cu_die, Dwarf_Addr addr) 65 { 66 Dwarf_Addr laddr; 67 Dwarf_Lines *lines; 68 Dwarf_Line *line; 69 size_t nlines, l, u, n; 70 bool flag; 71 72 if (dwarf_getsrclines(cu_die, &lines, &nlines) != 0 || 73 nlines == 0) 74 return NULL; 75 76 /* Lines are sorted by address, use binary search */ 77 l = 0; u = nlines - 1; 78 while (l < u) { 79 n = u - (u - l) / 2; 80 line = dwarf_onesrcline(lines, n); 81 if (!line || dwarf_lineaddr(line, &laddr) != 0) 82 return NULL; 83 if (addr < laddr) 84 u = n - 1; 85 else 86 l = n; 87 } 88 /* Going backward to find the lowest line */ 89 do { 90 line = dwarf_onesrcline(lines, --l); 91 if (!line || dwarf_lineaddr(line, &laddr) != 0) 92 return NULL; 93 } while (laddr == addr); 94 l++; 95 /* Going forward to find the statement line */ 96 do { 97 line = dwarf_onesrcline(lines, l++); 98 if (!line || dwarf_lineaddr(line, &laddr) != 0 || 99 dwarf_linebeginstatement(line, &flag) != 0) 100 return NULL; 101 if (laddr > addr) 102 return NULL; 103 } while (!flag); 104 105 return line; 106 } 107 108 /** 109 * cu_find_lineinfo - Get a line number and file name for given address 110 * @cu_die: a CU DIE 111 * @addr: An address 112 * @fname: a pointer which returns the file name string 113 * @lineno: a pointer which returns the line number 114 * 115 * Find a line number and file name for @addr in @cu_die. 116 */ 117 int cu_find_lineinfo(Dwarf_Die *cu_die, Dwarf_Addr addr, 118 const char **fname, int *lineno) 119 { 120 Dwarf_Line *line; 121 Dwarf_Die die_mem; 122 Dwarf_Addr faddr; 123 124 if (die_find_realfunc(cu_die, addr, &die_mem) 125 && die_entrypc(&die_mem, &faddr) == 0 && 126 faddr == addr) { 127 *fname = die_get_decl_file(&die_mem); 128 dwarf_decl_line(&die_mem, lineno); 129 goto out; 130 } 131 132 line = cu_getsrc_die(cu_die, addr); 133 if (line && dwarf_lineno(line, lineno) == 0) { 134 *fname = dwarf_linesrc(line, NULL, NULL); 135 if (!*fname) 136 /* line number is useless without filename */ 137 *lineno = 0; 138 } 139 140 out: 141 return (*lineno && *fname) ? *lineno : -ENOENT; 142 } 143 144 static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data); 145 146 /** 147 * cu_walk_functions_at - Walk on function DIEs at given address 148 * @cu_die: A CU DIE 149 * @addr: An address 150 * @callback: A callback which called with found DIEs 151 * @data: A user data 152 * 153 * Walk on function DIEs at given @addr in @cu_die. Passed DIEs 154 * should be subprogram or inlined-subroutines. 155 */ 156 int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, 157 int (*callback)(Dwarf_Die *, void *), void *data) 158 { 159 Dwarf_Die die_mem; 160 Dwarf_Die *sc_die; 161 int ret = -ENOENT; 162 163 /* Inlined function could be recursive. Trace it until fail */ 164 for (sc_die = die_find_realfunc(cu_die, addr, &die_mem); 165 sc_die != NULL; 166 sc_die = die_find_child(sc_die, __die_find_inline_cb, &addr, 167 &die_mem)) { 168 ret = callback(sc_die, data); 169 if (ret) 170 break; 171 } 172 173 return ret; 174 175 } 176 177 /** 178 * die_get_linkage_name - Get the linkage name of the object 179 * @dw_die: A DIE of the object 180 * 181 * Get the linkage name attribute of given @dw_die. 182 * For C++ binary, the linkage name will be the mangled symbol. 183 */ 184 const char *die_get_linkage_name(Dwarf_Die *dw_die) 185 { 186 Dwarf_Attribute attr; 187 188 if (dwarf_attr_integrate(dw_die, DW_AT_linkage_name, &attr) == NULL) 189 return NULL; 190 return dwarf_formstring(&attr); 191 } 192 193 /** 194 * die_compare_name - Compare diename and tname 195 * @dw_die: a DIE 196 * @tname: a string of target name 197 * 198 * Compare the name of @dw_die and @tname. Return false if @dw_die has no name. 199 */ 200 bool die_compare_name(Dwarf_Die *dw_die, const char *tname) 201 { 202 const char *name; 203 204 name = dwarf_diename(dw_die); 205 return name ? (strcmp(tname, name) == 0) : false; 206 } 207 208 /** 209 * die_match_name - Match diename/linkage name and glob 210 * @dw_die: a DIE 211 * @glob: a string of target glob pattern 212 * 213 * Glob matching the name of @dw_die and @glob. Return false if matching fail. 214 * This also match linkage name. 215 */ 216 bool die_match_name(Dwarf_Die *dw_die, const char *glob) 217 { 218 const char *name; 219 220 name = dwarf_diename(dw_die); 221 if (name && strglobmatch(name, glob)) 222 return true; 223 /* fall back to check linkage name */ 224 name = die_get_linkage_name(dw_die); 225 if (name && strglobmatch(name, glob)) 226 return true; 227 228 return false; 229 } 230 231 /** 232 * die_get_call_lineno - Get callsite line number of inline-function instance 233 * @in_die: a DIE of an inlined function instance 234 * 235 * Get call-site line number of @in_die. This means from where the inline 236 * function is called. 237 */ 238 int die_get_call_lineno(Dwarf_Die *in_die) 239 { 240 Dwarf_Attribute attr; 241 Dwarf_Word ret; 242 243 if (!dwarf_attr(in_die, DW_AT_call_line, &attr)) 244 return -ENOENT; 245 246 dwarf_formudata(&attr, &ret); 247 return (int)ret; 248 } 249 250 /** 251 * die_get_type - Get type DIE 252 * @vr_die: a DIE of a variable 253 * @die_mem: where to store a type DIE 254 * 255 * Get a DIE of the type of given variable (@vr_die), and store 256 * it to die_mem. Return NULL if fails to get a type DIE. 257 */ 258 Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem) 259 { 260 Dwarf_Attribute attr; 261 262 if (dwarf_attr_integrate(vr_die, DW_AT_type, &attr) && 263 dwarf_formref_die(&attr, die_mem)) 264 return die_mem; 265 else 266 return NULL; 267 } 268 269 /* Get a type die, but skip qualifiers */ 270 Dwarf_Die *__die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem) 271 { 272 int tag; 273 274 do { 275 vr_die = die_get_type(vr_die, die_mem); 276 if (!vr_die) 277 break; 278 tag = dwarf_tag(vr_die); 279 } while (tag == DW_TAG_const_type || 280 tag == DW_TAG_restrict_type || 281 tag == DW_TAG_volatile_type || 282 tag == DW_TAG_shared_type); 283 284 return vr_die; 285 } 286 287 /** 288 * die_get_real_type - Get a type die, but skip qualifiers and typedef 289 * @vr_die: a DIE of a variable 290 * @die_mem: where to store a type DIE 291 * 292 * Get a DIE of the type of given variable (@vr_die), and store 293 * it to die_mem. Return NULL if fails to get a type DIE. 294 * If the type is qualifiers (e.g. const) or typedef, this skips it 295 * and tries to find real type (structure or basic types, e.g. int). 296 */ 297 Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem) 298 { 299 do { 300 vr_die = __die_get_real_type(vr_die, die_mem); 301 } while (vr_die && dwarf_tag(vr_die) == DW_TAG_typedef); 302 303 return vr_die; 304 } 305 306 /* Get attribute and translate it as a udata */ 307 static int die_get_attr_udata(Dwarf_Die *tp_die, unsigned int attr_name, 308 Dwarf_Word *result) 309 { 310 Dwarf_Attribute attr; 311 312 if (dwarf_attr_integrate(tp_die, attr_name, &attr) == NULL || 313 dwarf_formudata(&attr, result) != 0) 314 return -ENOENT; 315 316 return 0; 317 } 318 319 /** 320 * die_is_signed_type - Check whether a type DIE is signed or not 321 * @tp_die: a DIE of a type 322 * 323 * Get the encoding of @tp_die and return true if the encoding 324 * is signed. 325 */ 326 bool die_is_signed_type(Dwarf_Die *tp_die) 327 { 328 Dwarf_Word ret; 329 330 if (die_get_attr_udata(tp_die, DW_AT_encoding, &ret)) 331 return false; 332 333 return (ret == DW_ATE_signed_char || ret == DW_ATE_signed || 334 ret == DW_ATE_signed_fixed); 335 } 336 337 /** 338 * die_is_func_def - Ensure that this DIE is a subprogram and definition 339 * @dw_die: a DIE 340 * 341 * Ensure that this DIE is a subprogram and NOT a declaration. This 342 * returns true if @dw_die is a function definition. 343 **/ 344 bool die_is_func_def(Dwarf_Die *dw_die) 345 { 346 Dwarf_Attribute attr; 347 Dwarf_Addr addr = 0; 348 349 if (dwarf_tag(dw_die) != DW_TAG_subprogram) 350 return false; 351 352 if (dwarf_attr(dw_die, DW_AT_declaration, &attr)) 353 return false; 354 355 /* 356 * DW_AT_declaration can be lost from function declaration 357 * by gcc's bug #97060. 358 * So we need to check this subprogram DIE has DW_AT_inline 359 * or an entry address. 360 */ 361 if (!dwarf_attr(dw_die, DW_AT_inline, &attr) && 362 die_entrypc(dw_die, &addr) < 0) 363 return false; 364 365 return true; 366 } 367 368 /** 369 * die_entrypc - Returns entry PC (the lowest address) of a DIE 370 * @dw_die: a DIE 371 * @addr: where to store entry PC 372 * 373 * Since dwarf_entrypc() does not return entry PC if the DIE has only address 374 * range, we have to use this to retrieve the lowest address from the address 375 * range attribute. 376 */ 377 int die_entrypc(Dwarf_Die *dw_die, Dwarf_Addr *addr) 378 { 379 Dwarf_Addr base, end; 380 Dwarf_Attribute attr; 381 382 if (!addr) 383 return -EINVAL; 384 385 if (dwarf_entrypc(dw_die, addr) == 0) 386 return 0; 387 388 /* 389 * Since the dwarf_ranges() will return 0 if there is no 390 * DW_AT_ranges attribute, we should check it first. 391 */ 392 if (!dwarf_attr(dw_die, DW_AT_ranges, &attr)) 393 return -ENOENT; 394 395 return dwarf_ranges(dw_die, 0, &base, addr, &end) < 0 ? -ENOENT : 0; 396 } 397 398 /** 399 * die_is_func_instance - Ensure that this DIE is an instance of a subprogram 400 * @dw_die: a DIE 401 * 402 * Ensure that this DIE is an instance (which has an entry address). 403 * This returns true if @dw_die is a function instance. If not, the @dw_die 404 * must be a prototype. You can use die_walk_instances() to find actual 405 * instances. 406 **/ 407 bool die_is_func_instance(Dwarf_Die *dw_die) 408 { 409 Dwarf_Addr tmp; 410 Dwarf_Attribute attr_mem; 411 int tag = dwarf_tag(dw_die); 412 413 if (tag != DW_TAG_subprogram && 414 tag != DW_TAG_inlined_subroutine) 415 return false; 416 417 return dwarf_entrypc(dw_die, &tmp) == 0 || 418 dwarf_attr(dw_die, DW_AT_ranges, &attr_mem) != NULL; 419 } 420 421 /** 422 * die_get_data_member_location - Get the data-member offset 423 * @mb_die: a DIE of a member of a data structure 424 * @offs: The offset of the member in the data structure 425 * 426 * Get the offset of @mb_die in the data structure including @mb_die, and 427 * stores result offset to @offs. If any error occurs this returns errno. 428 */ 429 int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs) 430 { 431 Dwarf_Attribute attr; 432 Dwarf_Op *expr; 433 size_t nexpr; 434 int ret; 435 436 if (dwarf_attr(mb_die, DW_AT_data_member_location, &attr) == NULL) 437 return -ENOENT; 438 439 if (dwarf_formudata(&attr, offs) != 0) { 440 /* DW_AT_data_member_location should be DW_OP_plus_uconst */ 441 ret = dwarf_getlocation(&attr, &expr, &nexpr); 442 if (ret < 0 || nexpr == 0) 443 return -ENOENT; 444 445 if (expr[0].atom != DW_OP_plus_uconst || nexpr != 1) { 446 pr_debug("Unable to get offset:Unexpected OP %x (%zd)\n", 447 expr[0].atom, nexpr); 448 return -ENOTSUP; 449 } 450 *offs = (Dwarf_Word)expr[0].number; 451 } 452 return 0; 453 } 454 455 /* Get the call file index number in CU DIE */ 456 static int die_get_call_fileno(Dwarf_Die *in_die) 457 { 458 Dwarf_Word idx; 459 460 if (die_get_attr_udata(in_die, DW_AT_call_file, &idx) == 0) 461 return (int)idx; 462 else 463 return -ENOENT; 464 } 465 466 /* Get the declared file index number in CU DIE */ 467 static int die_get_decl_fileno(Dwarf_Die *pdie) 468 { 469 Dwarf_Word idx; 470 471 if (die_get_attr_udata(pdie, DW_AT_decl_file, &idx) == 0) 472 return (int)idx; 473 else 474 return -ENOENT; 475 } 476 477 /* Return the file name by index */ 478 static const char *die_get_file_name(Dwarf_Die *dw_die, int idx) 479 { 480 Dwarf_Die cu_die; 481 Dwarf_Files *files; 482 Dwarf_Attribute attr_mem; 483 484 if (idx < 0 || !dwarf_attr_integrate(dw_die, DW_AT_decl_file, &attr_mem) || 485 !dwarf_cu_die(attr_mem.cu, &cu_die, NULL, NULL, NULL, NULL, NULL, NULL) || 486 dwarf_getsrcfiles(&cu_die, &files, NULL) != 0) 487 return NULL; 488 489 return dwarf_filesrc(files, idx, NULL, NULL); 490 } 491 492 /** 493 * die_get_call_file - Get callsite file name of inlined function instance 494 * @in_die: a DIE of an inlined function instance 495 * 496 * Get call-site file name of @in_die. This means from which file the inline 497 * function is called. 498 */ 499 const char *die_get_call_file(Dwarf_Die *in_die) 500 { 501 return die_get_file_name(in_die, die_get_call_fileno(in_die)); 502 } 503 504 /** 505 * die_get_decl_file - Find the declared file name of this DIE 506 * @dw_die: a DIE for something declared. 507 * 508 * Get declared file name of @dw_die. 509 * NOTE: Since some version of clang DWARF5 implementation incorrectly uses 510 * file index 0 for DW_AT_decl_file, die_get_decl_file() will return NULL for 511 * such cases. Use this function instead. 512 */ 513 const char *die_get_decl_file(Dwarf_Die *dw_die) 514 { 515 return die_get_file_name(dw_die, die_get_decl_fileno(dw_die)); 516 } 517 518 /** 519 * die_find_child - Generic DIE search function in DIE tree 520 * @rt_die: a root DIE 521 * @callback: a callback function 522 * @data: a user data passed to the callback function 523 * @die_mem: a buffer for result DIE 524 * 525 * Trace DIE tree from @rt_die and call @callback for each child DIE. 526 * If @callback returns DIE_FIND_CB_END, this stores the DIE into 527 * @die_mem and returns it. If @callback returns DIE_FIND_CB_CONTINUE, 528 * this continues to trace the tree. Optionally, @callback can return 529 * DIE_FIND_CB_CHILD and DIE_FIND_CB_SIBLING, those means trace only 530 * the children and trace only the siblings respectively. 531 * Returns NULL if @callback can't find any appropriate DIE. 532 */ 533 Dwarf_Die *die_find_child(Dwarf_Die *rt_die, 534 int (*callback)(Dwarf_Die *, void *), 535 void *data, Dwarf_Die *die_mem) 536 { 537 Dwarf_Die child_die; 538 int ret; 539 540 ret = dwarf_child(rt_die, die_mem); 541 if (ret != 0) 542 return NULL; 543 544 do { 545 ret = callback(die_mem, data); 546 if (ret == DIE_FIND_CB_END) 547 return die_mem; 548 549 if ((ret & DIE_FIND_CB_CHILD) && 550 die_find_child(die_mem, callback, data, &child_die)) { 551 memcpy(die_mem, &child_die, sizeof(Dwarf_Die)); 552 return die_mem; 553 } 554 } while ((ret & DIE_FIND_CB_SIBLING) && 555 dwarf_siblingof(die_mem, die_mem) == 0); 556 557 return NULL; 558 } 559 560 struct __addr_die_search_param { 561 Dwarf_Addr addr; 562 Dwarf_Die *die_mem; 563 }; 564 565 static int __die_search_func_tail_cb(Dwarf_Die *fn_die, void *data) 566 { 567 struct __addr_die_search_param *ad = data; 568 Dwarf_Addr addr = 0; 569 570 if (dwarf_tag(fn_die) == DW_TAG_subprogram && 571 !dwarf_highpc(fn_die, &addr) && 572 addr == ad->addr) { 573 memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die)); 574 return DWARF_CB_ABORT; 575 } 576 return DWARF_CB_OK; 577 } 578 579 /** 580 * die_find_tailfunc - Search for a non-inlined function with tail call at 581 * given address 582 * @cu_die: a CU DIE which including @addr 583 * @addr: target address 584 * @die_mem: a buffer for result DIE 585 * 586 * Search for a non-inlined function DIE with tail call at @addr. Stores the 587 * DIE to @die_mem and returns it if found. Returns NULL if failed. 588 */ 589 Dwarf_Die *die_find_tailfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, 590 Dwarf_Die *die_mem) 591 { 592 struct __addr_die_search_param ad; 593 ad.addr = addr; 594 ad.die_mem = die_mem; 595 /* dwarf_getscopes can't find subprogram. */ 596 if (!dwarf_getfuncs(cu_die, __die_search_func_tail_cb, &ad, 0)) 597 return NULL; 598 else 599 return die_mem; 600 } 601 602 /* die_find callback for non-inlined function search */ 603 static int __die_search_func_cb(Dwarf_Die *fn_die, void *data) 604 { 605 struct __addr_die_search_param *ad = data; 606 607 /* 608 * Since a declaration entry doesn't has given pc, this always returns 609 * function definition entry. 610 */ 611 if (dwarf_tag(fn_die) == DW_TAG_subprogram && 612 dwarf_haspc(fn_die, ad->addr)) { 613 memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die)); 614 return DWARF_CB_ABORT; 615 } 616 return DWARF_CB_OK; 617 } 618 619 /** 620 * die_find_realfunc - Search a non-inlined function at given address 621 * @cu_die: a CU DIE which including @addr 622 * @addr: target address 623 * @die_mem: a buffer for result DIE 624 * 625 * Search a non-inlined function DIE which includes @addr. Stores the 626 * DIE to @die_mem and returns it if found. Returns NULL if failed. 627 */ 628 Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, 629 Dwarf_Die *die_mem) 630 { 631 struct __addr_die_search_param ad; 632 ad.addr = addr; 633 ad.die_mem = die_mem; 634 /* dwarf_getscopes can't find subprogram. */ 635 if (!dwarf_getfuncs(cu_die, __die_search_func_cb, &ad, 0)) 636 return NULL; 637 else 638 return die_mem; 639 } 640 641 /* die_find callback for inline function search */ 642 static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data) 643 { 644 Dwarf_Addr *addr = data; 645 646 if (dwarf_tag(die_mem) == DW_TAG_inlined_subroutine && 647 dwarf_haspc(die_mem, *addr)) 648 return DIE_FIND_CB_END; 649 650 return DIE_FIND_CB_CONTINUE; 651 } 652 653 /** 654 * die_find_top_inlinefunc - Search the top inlined function at given address 655 * @sp_die: a subprogram DIE which including @addr 656 * @addr: target address 657 * @die_mem: a buffer for result DIE 658 * 659 * Search an inlined function DIE which includes @addr. Stores the 660 * DIE to @die_mem and returns it if found. Returns NULL if failed. 661 * Even if several inlined functions are expanded recursively, this 662 * doesn't trace it down, and returns the topmost one. 663 */ 664 Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 665 Dwarf_Die *die_mem) 666 { 667 return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem); 668 } 669 670 /** 671 * die_find_inlinefunc - Search an inlined function at given address 672 * @sp_die: a subprogram DIE which including @addr 673 * @addr: target address 674 * @die_mem: a buffer for result DIE 675 * 676 * Search an inlined function DIE which includes @addr. Stores the 677 * DIE to @die_mem and returns it if found. Returns NULL if failed. 678 * If several inlined functions are expanded recursively, this trace 679 * it down and returns deepest one. 680 */ 681 Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 682 Dwarf_Die *die_mem) 683 { 684 Dwarf_Die tmp_die; 685 686 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, &tmp_die); 687 if (!sp_die) 688 return NULL; 689 690 /* Inlined function could be recursive. Trace it until fail */ 691 while (sp_die) { 692 memcpy(die_mem, sp_die, sizeof(Dwarf_Die)); 693 sp_die = die_find_child(sp_die, __die_find_inline_cb, &addr, 694 &tmp_die); 695 } 696 697 return die_mem; 698 } 699 700 static int __die_find_func_rettype_cb(Dwarf_Die *die_mem, void *data) 701 { 702 const char *func_name; 703 704 if (dwarf_tag(die_mem) != DW_TAG_subprogram) 705 return DIE_FIND_CB_SIBLING; 706 707 func_name = dwarf_diename(die_mem); 708 if (func_name && !strcmp(func_name, data)) 709 return DIE_FIND_CB_END; 710 711 return DIE_FIND_CB_SIBLING; 712 } 713 714 /** 715 * die_find_func_rettype - Search a return type of function 716 * @cu_die: a CU DIE 717 * @name: target function name 718 * @die_mem: a buffer for result DIE 719 * 720 * Search a non-inlined function which matches to @name and stores the 721 * return type of the function to @die_mem and returns it if found. 722 * Returns NULL if failed. Note that it doesn't needs to find a 723 * definition of the function, so it doesn't match with address. 724 * Most likely, it can find a declaration at the top level. Thus the 725 * callback function continues to sibling entries only. 726 */ 727 Dwarf_Die *die_find_func_rettype(Dwarf_Die *cu_die, const char *name, 728 Dwarf_Die *die_mem) 729 { 730 Dwarf_Die tmp_die; 731 732 cu_die = die_find_child(cu_die, __die_find_func_rettype_cb, 733 (void *)name, &tmp_die); 734 if (!cu_die) 735 return NULL; 736 737 if (die_get_real_type(&tmp_die, die_mem) == NULL) 738 return NULL; 739 740 return die_mem; 741 } 742 743 struct __instance_walk_param { 744 void *addr; 745 int (*callback)(Dwarf_Die *, void *); 746 void *data; 747 int retval; 748 }; 749 750 static int __die_walk_instances_cb(Dwarf_Die *inst, void *data) 751 { 752 struct __instance_walk_param *iwp = data; 753 Dwarf_Attribute attr_mem; 754 Dwarf_Die origin_mem; 755 Dwarf_Attribute *attr; 756 Dwarf_Die *origin; 757 int tmp; 758 759 if (!die_is_func_instance(inst)) 760 return DIE_FIND_CB_CONTINUE; 761 762 attr = dwarf_attr(inst, DW_AT_abstract_origin, &attr_mem); 763 if (attr == NULL) 764 return DIE_FIND_CB_CONTINUE; 765 766 origin = dwarf_formref_die(attr, &origin_mem); 767 if (origin == NULL || origin->addr != iwp->addr) 768 return DIE_FIND_CB_CONTINUE; 769 770 /* Ignore redundant instances */ 771 if (dwarf_tag(inst) == DW_TAG_inlined_subroutine) { 772 dwarf_decl_line(origin, &tmp); 773 if (die_get_call_lineno(inst) == tmp) { 774 tmp = die_get_decl_fileno(origin); 775 if (die_get_call_fileno(inst) == tmp) 776 return DIE_FIND_CB_CONTINUE; 777 } 778 } 779 780 iwp->retval = iwp->callback(inst, iwp->data); 781 782 return (iwp->retval) ? DIE_FIND_CB_END : DIE_FIND_CB_CONTINUE; 783 } 784 785 /** 786 * die_walk_instances - Walk on instances of given DIE 787 * @or_die: an abstract original DIE 788 * @callback: a callback function which is called with instance DIE 789 * @data: user data 790 * 791 * Walk on the instances of give @in_die. @in_die must be an inlined function 792 * declaration. This returns the return value of @callback if it returns 793 * non-zero value, or -ENOENT if there is no instance. 794 */ 795 int die_walk_instances(Dwarf_Die *or_die, int (*callback)(Dwarf_Die *, void *), 796 void *data) 797 { 798 Dwarf_Die cu_die; 799 Dwarf_Die die_mem; 800 struct __instance_walk_param iwp = { 801 .addr = or_die->addr, 802 .callback = callback, 803 .data = data, 804 .retval = -ENOENT, 805 }; 806 807 if (dwarf_diecu(or_die, &cu_die, NULL, NULL) == NULL) 808 return -ENOENT; 809 810 die_find_child(&cu_die, __die_walk_instances_cb, &iwp, &die_mem); 811 812 return iwp.retval; 813 } 814 815 /* Line walker internal parameters */ 816 struct __line_walk_param { 817 bool recursive; 818 line_walk_callback_t callback; 819 void *data; 820 int retval; 821 }; 822 823 static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data) 824 { 825 struct __line_walk_param *lw = data; 826 Dwarf_Addr addr = 0; 827 const char *fname; 828 int lineno; 829 830 if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) { 831 fname = die_get_call_file(in_die); 832 lineno = die_get_call_lineno(in_die); 833 if (fname && lineno > 0 && die_entrypc(in_die, &addr) == 0) { 834 lw->retval = lw->callback(fname, lineno, addr, lw->data); 835 if (lw->retval != 0) 836 return DIE_FIND_CB_END; 837 } 838 if (!lw->recursive) 839 return DIE_FIND_CB_SIBLING; 840 } 841 842 if (addr) { 843 fname = die_get_decl_file(in_die); 844 if (fname && dwarf_decl_line(in_die, &lineno) == 0) { 845 lw->retval = lw->callback(fname, lineno, addr, lw->data); 846 if (lw->retval != 0) 847 return DIE_FIND_CB_END; 848 } 849 } 850 851 /* Continue to search nested inlined function call-sites */ 852 return DIE_FIND_CB_CONTINUE; 853 } 854 855 /* Walk on lines of blocks included in given DIE */ 856 static int __die_walk_funclines(Dwarf_Die *sp_die, bool recursive, 857 line_walk_callback_t callback, void *data) 858 { 859 struct __line_walk_param lw = { 860 .recursive = recursive, 861 .callback = callback, 862 .data = data, 863 .retval = 0, 864 }; 865 Dwarf_Die die_mem; 866 Dwarf_Addr addr; 867 const char *fname; 868 int lineno; 869 870 /* Handle function declaration line */ 871 fname = die_get_decl_file(sp_die); 872 if (fname && dwarf_decl_line(sp_die, &lineno) == 0 && 873 die_entrypc(sp_die, &addr) == 0) { 874 lw.retval = callback(fname, lineno, addr, data); 875 if (lw.retval != 0) 876 goto done; 877 } 878 die_find_child(sp_die, __die_walk_funclines_cb, &lw, &die_mem); 879 done: 880 return lw.retval; 881 } 882 883 static int __die_walk_culines_cb(Dwarf_Die *sp_die, void *data) 884 { 885 struct __line_walk_param *lw = data; 886 887 /* 888 * Since inlined function can include another inlined function in 889 * the same file, we need to walk in it recursively. 890 */ 891 lw->retval = __die_walk_funclines(sp_die, true, lw->callback, lw->data); 892 if (lw->retval != 0) 893 return DWARF_CB_ABORT; 894 895 return DWARF_CB_OK; 896 } 897 898 /** 899 * die_walk_lines - Walk on lines inside given DIE 900 * @rt_die: a root DIE (CU, subprogram or inlined_subroutine) 901 * @callback: callback routine 902 * @data: user data 903 * 904 * Walk on all lines inside given @rt_die and call @callback on each line. 905 * If the @rt_die is a function, walk only on the lines inside the function, 906 * otherwise @rt_die must be a CU DIE. 907 * Note that this walks not only dwarf line list, but also function entries 908 * and inline call-site. 909 */ 910 int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data) 911 { 912 Dwarf_Lines *lines; 913 Dwarf_Line *line; 914 Dwarf_Addr addr; 915 const char *fname, *decf = NULL, *inf = NULL; 916 int lineno, ret = 0; 917 int decl = 0, inl; 918 Dwarf_Die die_mem, *cu_die; 919 size_t nlines, i; 920 bool flag; 921 922 /* Get the CU die */ 923 if (dwarf_tag(rt_die) != DW_TAG_compile_unit) { 924 cu_die = dwarf_diecu(rt_die, &die_mem, NULL, NULL); 925 dwarf_decl_line(rt_die, &decl); 926 decf = die_get_decl_file(rt_die); 927 if (!decf) { 928 pr_debug2("Failed to get the declared file name of %s\n", 929 dwarf_diename(rt_die)); 930 return -EINVAL; 931 } 932 } else 933 cu_die = rt_die; 934 if (!cu_die) { 935 pr_debug2("Failed to get CU from given DIE.\n"); 936 return -EINVAL; 937 } 938 939 /* Get lines list in the CU */ 940 if (dwarf_getsrclines(cu_die, &lines, &nlines) != 0) { 941 pr_debug2("Failed to get source lines on this CU.\n"); 942 return -ENOENT; 943 } 944 pr_debug2("Get %zd lines from this CU\n", nlines); 945 946 /* Walk on the lines on lines list */ 947 for (i = 0; i < nlines; i++) { 948 line = dwarf_onesrcline(lines, i); 949 if (line == NULL || 950 dwarf_lineno(line, &lineno) != 0 || 951 dwarf_lineaddr(line, &addr) != 0) { 952 pr_debug2("Failed to get line info. " 953 "Possible error in debuginfo.\n"); 954 continue; 955 } 956 /* Skip end-of-sequence */ 957 if (dwarf_lineendsequence(line, &flag) != 0 || flag) 958 continue; 959 /* Skip Non statement line-info */ 960 if (dwarf_linebeginstatement(line, &flag) != 0 || !flag) 961 continue; 962 /* Filter lines based on address */ 963 if (rt_die != cu_die) { 964 /* 965 * Address filtering 966 * The line is included in given function, and 967 * no inline block includes it. 968 */ 969 if (!dwarf_haspc(rt_die, addr)) 970 continue; 971 972 if (die_find_inlinefunc(rt_die, addr, &die_mem)) { 973 /* Call-site check */ 974 inf = die_get_call_file(&die_mem); 975 if ((inf && !strcmp(inf, decf)) && 976 die_get_call_lineno(&die_mem) == lineno) 977 goto found; 978 979 dwarf_decl_line(&die_mem, &inl); 980 if (inl != decl || 981 decf != die_get_decl_file(&die_mem)) 982 continue; 983 } 984 } 985 found: 986 /* Get source line */ 987 fname = dwarf_linesrc(line, NULL, NULL); 988 989 ret = callback(fname, lineno, addr, data); 990 if (ret != 0) 991 return ret; 992 } 993 994 /* 995 * Dwarf lines doesn't include function declarations and inlined 996 * subroutines. We have to check functions list or given function. 997 */ 998 if (rt_die != cu_die) 999 /* 1000 * Don't need walk inlined functions recursively, because 1001 * inner inlined functions don't have the lines of the 1002 * specified function. 1003 */ 1004 ret = __die_walk_funclines(rt_die, false, callback, data); 1005 else { 1006 struct __line_walk_param param = { 1007 .callback = callback, 1008 .data = data, 1009 .retval = 0, 1010 }; 1011 dwarf_getfuncs(cu_die, __die_walk_culines_cb, ¶m, 0); 1012 ret = param.retval; 1013 } 1014 1015 return ret; 1016 } 1017 1018 struct __find_variable_param { 1019 const char *name; 1020 Dwarf_Addr addr; 1021 }; 1022 1023 static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data) 1024 { 1025 struct __find_variable_param *fvp = data; 1026 Dwarf_Attribute attr; 1027 int tag; 1028 1029 tag = dwarf_tag(die_mem); 1030 if ((tag == DW_TAG_formal_parameter || 1031 tag == DW_TAG_variable) && 1032 die_compare_name(die_mem, fvp->name) && 1033 /* 1034 * Does the DIE have location information or const value 1035 * or external instance? 1036 */ 1037 (dwarf_attr(die_mem, DW_AT_external, &attr) || 1038 dwarf_attr(die_mem, DW_AT_location, &attr) || 1039 dwarf_attr(die_mem, DW_AT_const_value, &attr))) 1040 return DIE_FIND_CB_END; 1041 if (dwarf_haspc(die_mem, fvp->addr)) 1042 return DIE_FIND_CB_CONTINUE; 1043 else 1044 return DIE_FIND_CB_SIBLING; 1045 } 1046 1047 /** 1048 * die_find_variable_at - Find a given name variable at given address 1049 * @sp_die: a function DIE 1050 * @name: variable name 1051 * @addr: address 1052 * @die_mem: a buffer for result DIE 1053 * 1054 * Find a variable DIE called @name at @addr in @sp_die. 1055 */ 1056 Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name, 1057 Dwarf_Addr addr, Dwarf_Die *die_mem) 1058 { 1059 struct __find_variable_param fvp = { .name = name, .addr = addr}; 1060 1061 return die_find_child(sp_die, __die_find_variable_cb, (void *)&fvp, 1062 die_mem); 1063 } 1064 1065 static int __die_find_member_cb(Dwarf_Die *die_mem, void *data) 1066 { 1067 const char *name = data; 1068 1069 if (dwarf_tag(die_mem) == DW_TAG_member) { 1070 if (die_compare_name(die_mem, name)) 1071 return DIE_FIND_CB_END; 1072 else if (!dwarf_diename(die_mem)) { /* Unnamed structure */ 1073 Dwarf_Die type_die, tmp_die; 1074 if (die_get_type(die_mem, &type_die) && 1075 die_find_member(&type_die, name, &tmp_die)) 1076 return DIE_FIND_CB_END; 1077 } 1078 } 1079 return DIE_FIND_CB_SIBLING; 1080 } 1081 1082 /** 1083 * die_find_member - Find a given name member in a data structure 1084 * @st_die: a data structure type DIE 1085 * @name: member name 1086 * @die_mem: a buffer for result DIE 1087 * 1088 * Find a member DIE called @name in @st_die. 1089 */ 1090 Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name, 1091 Dwarf_Die *die_mem) 1092 { 1093 return die_find_child(st_die, __die_find_member_cb, (void *)name, 1094 die_mem); 1095 } 1096 1097 /** 1098 * die_get_typename_from_type - Get the name of given type DIE 1099 * @type_die: a type DIE 1100 * @buf: a strbuf for result type name 1101 * 1102 * Get the name of @type_die and stores it to @buf. Return 0 if succeeded. 1103 * and Return -ENOENT if failed to find type name. 1104 * Note that the result will stores typedef name if possible, and stores 1105 * "*(function_type)" if the type is a function pointer. 1106 */ 1107 int die_get_typename_from_type(Dwarf_Die *type_die, struct strbuf *buf) 1108 { 1109 int tag, ret; 1110 const char *tmp = ""; 1111 1112 tag = dwarf_tag(type_die); 1113 if (tag == DW_TAG_pointer_type) 1114 tmp = "*"; 1115 else if (tag == DW_TAG_array_type) 1116 tmp = "[]"; 1117 else if (tag == DW_TAG_subroutine_type) { 1118 /* Function pointer */ 1119 return strbuf_add(buf, "(function_type)", 15); 1120 } else { 1121 const char *name = dwarf_diename(type_die); 1122 1123 if (tag == DW_TAG_union_type) 1124 tmp = "union "; 1125 else if (tag == DW_TAG_structure_type) 1126 tmp = "struct "; 1127 else if (tag == DW_TAG_enumeration_type) 1128 tmp = "enum "; 1129 else if (name == NULL) 1130 return -ENOENT; 1131 /* Write a base name */ 1132 return strbuf_addf(buf, "%s%s", tmp, name ?: ""); 1133 } 1134 ret = die_get_typename(type_die, buf); 1135 if (ret < 0) { 1136 /* void pointer has no type attribute */ 1137 if (tag == DW_TAG_pointer_type && ret == -ENOENT) 1138 return strbuf_addf(buf, "void*"); 1139 1140 return ret; 1141 } 1142 return strbuf_addstr(buf, tmp); 1143 } 1144 1145 /** 1146 * die_get_typename - Get the name of given variable DIE 1147 * @vr_die: a variable DIE 1148 * @buf: a strbuf for result type name 1149 * 1150 * Get the name of @vr_die and stores it to @buf. Return 0 if succeeded. 1151 * and Return -ENOENT if failed to find type name. 1152 * Note that the result will stores typedef name if possible, and stores 1153 * "*(function_type)" if the type is a function pointer. 1154 */ 1155 int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf) 1156 { 1157 Dwarf_Die type; 1158 1159 if (__die_get_real_type(vr_die, &type) == NULL) 1160 return -ENOENT; 1161 1162 return die_get_typename_from_type(&type, buf); 1163 } 1164 1165 /** 1166 * die_get_varname - Get the name and type of given variable DIE 1167 * @vr_die: a variable DIE 1168 * @buf: a strbuf for type and variable name 1169 * 1170 * Get the name and type of @vr_die and stores it in @buf as "type\tname". 1171 */ 1172 int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf) 1173 { 1174 int ret; 1175 1176 ret = die_get_typename(vr_die, buf); 1177 if (ret < 0) { 1178 pr_debug("Failed to get type, make it unknown.\n"); 1179 ret = strbuf_add(buf, "(unknown_type)", 14); 1180 } 1181 1182 return ret < 0 ? ret : strbuf_addf(buf, "\t%s", dwarf_diename(vr_die)); 1183 } 1184 1185 static int reg_from_dwarf_op(Dwarf_Op *op) 1186 { 1187 switch (op->atom) { 1188 case DW_OP_reg0 ... DW_OP_reg31: 1189 return op->atom - DW_OP_reg0; 1190 case DW_OP_breg0 ... DW_OP_breg31: 1191 return op->atom - DW_OP_breg0; 1192 case DW_OP_regx: 1193 case DW_OP_bregx: 1194 return op->number; 1195 case DW_OP_fbreg: 1196 return DWARF_REG_FB; 1197 default: 1198 break; 1199 } 1200 return -1; 1201 } 1202 1203 static int offset_from_dwarf_op(Dwarf_Op *op) 1204 { 1205 switch (op->atom) { 1206 case DW_OP_reg0 ... DW_OP_reg31: 1207 case DW_OP_regx: 1208 return 0; 1209 case DW_OP_breg0 ... DW_OP_breg31: 1210 case DW_OP_fbreg: 1211 return op->number; 1212 case DW_OP_bregx: 1213 return op->number2; 1214 default: 1215 break; 1216 } 1217 return -1; 1218 } 1219 1220 static bool check_allowed_ops(Dwarf_Op *ops, size_t nops) 1221 { 1222 /* The first op is checked separately */ 1223 ops++; 1224 nops--; 1225 1226 /* 1227 * It needs to make sure if the location expression matches to the given 1228 * register and offset exactly. Thus it rejects any complex expressions 1229 * and only allows a few of selected operators that doesn't change the 1230 * location. 1231 */ 1232 while (nops) { 1233 switch (ops->atom) { 1234 case DW_OP_stack_value: 1235 case DW_OP_deref_size: 1236 case DW_OP_deref: 1237 case DW_OP_piece: 1238 break; 1239 default: 1240 return false; 1241 } 1242 ops++; 1243 nops--; 1244 } 1245 return true; 1246 } 1247 1248 /** 1249 * die_get_var_innermost_scope - Get innermost scope range of given variable DIE 1250 * @sp_die: a subprogram DIE 1251 * @vr_die: a variable DIE 1252 * @buf: a strbuf for variable byte offset range 1253 * 1254 * Get the innermost scope range of @vr_die and stores it in @buf as 1255 * "@<function_name+[NN-NN,NN-NN]>". 1256 */ 1257 static int die_get_var_innermost_scope(Dwarf_Die *sp_die, Dwarf_Die *vr_die, 1258 struct strbuf *buf) 1259 { 1260 Dwarf_Die *scopes; 1261 int count; 1262 size_t offset = 0; 1263 Dwarf_Addr base; 1264 Dwarf_Addr start, end; 1265 Dwarf_Addr entry; 1266 int ret; 1267 bool first = true; 1268 const char *name; 1269 1270 ret = die_entrypc(sp_die, &entry); 1271 if (ret) 1272 return ret; 1273 1274 name = dwarf_diename(sp_die); 1275 if (!name) 1276 return -ENOENT; 1277 1278 count = dwarf_getscopes_die(vr_die, &scopes); 1279 1280 /* (*SCOPES)[1] is the DIE for the scope containing that scope */ 1281 if (count <= 1) { 1282 ret = -EINVAL; 1283 goto out; 1284 } 1285 1286 while ((offset = dwarf_ranges(&scopes[1], offset, &base, 1287 &start, &end)) > 0) { 1288 start -= entry; 1289 end -= entry; 1290 1291 if (first) { 1292 ret = strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64, 1293 name, start, end); 1294 first = false; 1295 } else { 1296 ret = strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64, 1297 start, end); 1298 } 1299 if (ret < 0) 1300 goto out; 1301 } 1302 1303 if (!first) 1304 ret = strbuf_add(buf, "]>", 2); 1305 1306 out: 1307 free(scopes); 1308 return ret; 1309 } 1310 1311 /** 1312 * die_get_var_range - Get byte offset range of given variable DIE 1313 * @sp_die: a subprogram DIE 1314 * @vr_die: a variable DIE 1315 * @buf: a strbuf for type and variable name and byte offset range 1316 * 1317 * Get the byte offset range of @vr_die and stores it in @buf as 1318 * "@<function_name+[NN-NN,NN-NN]>". 1319 */ 1320 int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf) 1321 { 1322 int ret = 0; 1323 Dwarf_Addr base; 1324 Dwarf_Addr start, end; 1325 Dwarf_Addr entry; 1326 Dwarf_Op *op; 1327 size_t nops; 1328 size_t offset = 0; 1329 Dwarf_Attribute attr; 1330 bool first = true; 1331 const char *name; 1332 1333 ret = die_entrypc(sp_die, &entry); 1334 if (ret) 1335 return ret; 1336 1337 name = dwarf_diename(sp_die); 1338 if (!name) 1339 return -ENOENT; 1340 1341 if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL) 1342 return -EINVAL; 1343 1344 while ((offset = dwarf_getlocations(&attr, offset, &base, 1345 &start, &end, &op, &nops)) > 0) { 1346 if (start == 0) { 1347 /* Single Location Descriptions */ 1348 ret = die_get_var_innermost_scope(sp_die, vr_die, buf); 1349 goto out; 1350 } 1351 1352 /* Location Lists */ 1353 start -= entry; 1354 end -= entry; 1355 if (first) { 1356 ret = strbuf_addf(buf, "@<%s+[%" PRIu64 "-%" PRIu64, 1357 name, start, end); 1358 first = false; 1359 } else { 1360 ret = strbuf_addf(buf, ",%" PRIu64 "-%" PRIu64, 1361 start, end); 1362 } 1363 if (ret < 0) 1364 goto out; 1365 } 1366 1367 if (!first) 1368 ret = strbuf_add(buf, "]>", 2); 1369 out: 1370 return ret; 1371 } 1372 1373 /* Interval parameters for __die_find_var_reg_cb() */ 1374 struct find_var_data { 1375 /* Target instruction address */ 1376 Dwarf_Addr pc; 1377 /* Target memory address (for global data) */ 1378 Dwarf_Addr addr; 1379 /* Target register */ 1380 unsigned reg; 1381 /* Access offset, set for global data */ 1382 int offset; 1383 /* True if the current register is the frame base */ 1384 bool is_fbreg; 1385 }; 1386 1387 /* Max number of registers DW_OP_regN supports */ 1388 #define DWARF_OP_DIRECT_REGS 32 1389 1390 static bool match_var_offset(Dwarf_Die *die_mem, struct find_var_data *data, 1391 s64 addr_offset, s64 addr_type, bool is_pointer) 1392 { 1393 Dwarf_Die type_die; 1394 Dwarf_Word size; 1395 s64 offset = addr_offset - addr_type; 1396 1397 if (offset == 0) { 1398 /* Update offset relative to the start of the variable */ 1399 data->offset = 0; 1400 return true; 1401 } 1402 1403 if (offset < 0) 1404 return false; 1405 1406 if (die_get_real_type(die_mem, &type_die) == NULL) 1407 return false; 1408 1409 if (is_pointer && dwarf_tag(&type_die) == DW_TAG_pointer_type) { 1410 /* Get the target type of the pointer */ 1411 if (die_get_real_type(&type_die, &type_die) == NULL) 1412 return false; 1413 } 1414 1415 if (dwarf_aggregate_size(&type_die, &size) < 0) 1416 return false; 1417 1418 if ((u64)offset >= size) 1419 return false; 1420 1421 /* Update offset relative to the start of the variable */ 1422 data->offset = offset; 1423 return true; 1424 } 1425 1426 /** 1427 * is_breg_access_indirect - Check if breg based access implies type 1428 * dereference 1429 * @ops: DWARF operations array 1430 * @nops: Number of operations in @ops 1431 * 1432 * Returns true if the DWARF expression evaluates to the variable's 1433 * value, so the memory access on that register needs type dereference. 1434 * Returns false if the expression evaluates to the variable's address. 1435 * This is called after check_allowed_ops. 1436 */ 1437 static bool is_breg_access_indirect(Dwarf_Op *ops, size_t nops) 1438 { 1439 /* only the base register */ 1440 if (nops == 1) 1441 return false; 1442 1443 if (nops == 2 && ops[1].atom == DW_OP_stack_value) 1444 return true; 1445 1446 if (nops == 3 && (ops[1].atom == DW_OP_deref || 1447 ops[1].atom == DW_OP_deref_size) && 1448 ops[2].atom == DW_OP_stack_value) 1449 return false; 1450 /* unreachable, OP not supported */ 1451 return false; 1452 } 1453 1454 /* Only checks direct child DIEs in the given scope. */ 1455 static int __die_find_var_reg_cb(Dwarf_Die *die_mem, void *arg) 1456 { 1457 struct find_var_data *data = arg; 1458 int tag = dwarf_tag(die_mem); 1459 ptrdiff_t off = 0; 1460 Dwarf_Attribute attr; 1461 Dwarf_Addr base, start, end; 1462 Dwarf_Op *ops; 1463 size_t nops; 1464 1465 if (tag != DW_TAG_variable && tag != DW_TAG_formal_parameter) 1466 return DIE_FIND_CB_SIBLING; 1467 1468 if (dwarf_attr(die_mem, DW_AT_location, &attr) == NULL) 1469 return DIE_FIND_CB_SIBLING; 1470 1471 while ((off = dwarf_getlocations(&attr, off, &base, &start, &end, &ops, &nops)) > 0) { 1472 /* Assuming the location list is sorted by address */ 1473 if (end <= data->pc) 1474 continue; 1475 if (start > data->pc) 1476 break; 1477 1478 /* Local variables accessed using frame base register */ 1479 if (data->is_fbreg && ops->atom == DW_OP_fbreg && 1480 check_allowed_ops(ops, nops) && 1481 match_var_offset(die_mem, data, data->offset, ops->number, 1482 is_breg_access_indirect(ops, nops))) 1483 return DIE_FIND_CB_END; 1484 1485 /* Only match with a simple case */ 1486 if (data->reg < DWARF_OP_DIRECT_REGS) { 1487 /* pointer variables saved in a register 0 to 31 */ 1488 if (ops->atom == (DW_OP_reg0 + data->reg) && 1489 check_allowed_ops(ops, nops) && 1490 match_var_offset(die_mem, data, data->offset, 0, 1491 /*is_pointer=*/true)) 1492 return DIE_FIND_CB_END; 1493 1494 /* variables accessed by a register + offset */ 1495 if (ops->atom == (DW_OP_breg0 + data->reg) && 1496 check_allowed_ops(ops, nops) && 1497 match_var_offset(die_mem, data, data->offset, ops->number, 1498 is_breg_access_indirect(ops, nops))) 1499 return DIE_FIND_CB_END; 1500 } else { 1501 /* pointer variables saved in a register 32 or above */ 1502 if (ops->atom == DW_OP_regx && ops->number == data->reg && 1503 check_allowed_ops(ops, nops) && 1504 match_var_offset(die_mem, data, data->offset, 0, 1505 /*is_pointer=*/true)) 1506 return DIE_FIND_CB_END; 1507 1508 /* variables accessed by a register + offset */ 1509 if (ops->atom == DW_OP_bregx && data->reg == ops->number && 1510 check_allowed_ops(ops, nops) && 1511 match_var_offset(die_mem, data, data->offset, ops->number2, 1512 is_breg_access_indirect(ops, nops))) 1513 return DIE_FIND_CB_END; 1514 } 1515 } 1516 return DIE_FIND_CB_SIBLING; 1517 } 1518 1519 /** 1520 * die_find_variable_by_reg - Find a variable saved in a register 1521 * @sc_die: a scope DIE 1522 * @pc: the program address to find 1523 * @reg: the register number to find 1524 * @poffset: pointer to offset, will be updated for fbreg case 1525 * @is_fbreg: boolean value if the current register is the frame base 1526 * @die_mem: a buffer to save the resulting DIE 1527 * 1528 * Find the variable DIE accessed by the given register. It'll update the @offset 1529 * when the variable is in the stack. 1530 */ 1531 Dwarf_Die *die_find_variable_by_reg(Dwarf_Die *sc_die, Dwarf_Addr pc, int reg, 1532 int *poffset, bool is_fbreg, 1533 Dwarf_Die *die_mem) 1534 { 1535 struct find_var_data data = { 1536 .pc = pc, 1537 .reg = reg, 1538 .offset = *poffset, 1539 .is_fbreg = is_fbreg, 1540 }; 1541 Dwarf_Die *result; 1542 1543 result = die_find_child(sc_die, __die_find_var_reg_cb, &data, die_mem); 1544 if (result) 1545 *poffset = data.offset; 1546 return result; 1547 } 1548 1549 /* Only checks direct child DIEs in the given scope */ 1550 static int __die_find_var_addr_cb(Dwarf_Die *die_mem, void *arg) 1551 { 1552 struct find_var_data *data = arg; 1553 int tag = dwarf_tag(die_mem); 1554 ptrdiff_t off = 0; 1555 Dwarf_Attribute attr; 1556 Dwarf_Addr base, start, end; 1557 Dwarf_Op *ops; 1558 size_t nops; 1559 1560 if (tag != DW_TAG_variable) 1561 return DIE_FIND_CB_SIBLING; 1562 1563 if (dwarf_attr(die_mem, DW_AT_location, &attr) == NULL) 1564 return DIE_FIND_CB_SIBLING; 1565 1566 while ((off = dwarf_getlocations(&attr, off, &base, &start, &end, &ops, &nops)) > 0) { 1567 if (ops->atom != DW_OP_addr) 1568 continue; 1569 1570 if (check_allowed_ops(ops, nops) && 1571 match_var_offset(die_mem, data, data->addr, ops->number, 1572 /*is_pointer=*/false)) 1573 return DIE_FIND_CB_END; 1574 } 1575 return DIE_FIND_CB_SIBLING; 1576 } 1577 1578 /** 1579 * die_find_variable_by_addr - Find variable located at given address 1580 * @sc_die: a scope DIE 1581 * @addr: the data address to find 1582 * @die_mem: a buffer to save the resulting DIE 1583 * @offset: the offset in the resulting type 1584 * 1585 * Find the variable DIE located at the given address (in PC-relative mode). 1586 * This is usually for global variables. 1587 */ 1588 Dwarf_Die *die_find_variable_by_addr(Dwarf_Die *sc_die, Dwarf_Addr addr, 1589 Dwarf_Die *die_mem, int *offset) 1590 { 1591 struct find_var_data data = { 1592 .addr = addr, 1593 }; 1594 Dwarf_Die *result; 1595 1596 result = die_find_child(sc_die, __die_find_var_addr_cb, &data, die_mem); 1597 if (result) 1598 *offset = data.offset; 1599 return result; 1600 } 1601 1602 static int __die_collect_vars_cb(Dwarf_Die *die_mem, void *arg) 1603 { 1604 struct die_var_type **var_types = arg; 1605 Dwarf_Die type_die; 1606 int tag = dwarf_tag(die_mem); 1607 Dwarf_Attribute attr; 1608 Dwarf_Addr base, start, end; 1609 Dwarf_Op *ops; 1610 size_t nops; 1611 struct die_var_type *vt; 1612 1613 if (tag != DW_TAG_variable && tag != DW_TAG_formal_parameter) 1614 return DIE_FIND_CB_SIBLING; 1615 1616 if (dwarf_attr(die_mem, DW_AT_location, &attr) == NULL) 1617 return DIE_FIND_CB_SIBLING; 1618 1619 /* 1620 * Only collect the first location as it can reconstruct the 1621 * remaining state by following the instructions. 1622 * start = 0 means it covers the whole range. 1623 */ 1624 if (dwarf_getlocations(&attr, 0, &base, &start, &end, &ops, &nops) <= 0) 1625 return DIE_FIND_CB_SIBLING; 1626 1627 if (!check_allowed_ops(ops, nops)) 1628 return DIE_FIND_CB_SIBLING; 1629 1630 if (__die_get_real_type(die_mem, &type_die) == NULL) 1631 return DIE_FIND_CB_SIBLING; 1632 1633 vt = malloc(sizeof(*vt)); 1634 if (vt == NULL) 1635 return DIE_FIND_CB_END; 1636 1637 /* Usually a register holds the value of a variable */ 1638 vt->is_reg_var_addr = false; 1639 1640 if (((ops->atom >= DW_OP_breg0 && ops->atom <= DW_OP_breg31) || 1641 ops->atom == DW_OP_bregx || ops->atom == DW_OP_fbreg) && 1642 !is_breg_access_indirect(ops, nops)) 1643 /* The register contains an address of the variable. */ 1644 vt->is_reg_var_addr = true; 1645 1646 vt->die_off = dwarf_dieoffset(&type_die); 1647 vt->addr = start; 1648 vt->reg = reg_from_dwarf_op(ops); 1649 vt->offset = offset_from_dwarf_op(ops); 1650 vt->next = *var_types; 1651 *var_types = vt; 1652 1653 return DIE_FIND_CB_SIBLING; 1654 } 1655 1656 /** 1657 * die_collect_vars - Save all variables and parameters 1658 * @sc_die: a scope DIE 1659 * @var_types: a pointer to save the resulting list 1660 * 1661 * Save all variables and parameters in the @sc_die and save them to @var_types. 1662 * The @var_types is a singly-linked list containing type and location info. 1663 * Actual type can be retrieved using dwarf_offdie() with 'die_off' later. 1664 * 1665 * Callers should free @var_types. 1666 */ 1667 void die_collect_vars(Dwarf_Die *sc_die, struct die_var_type **var_types) 1668 { 1669 Dwarf_Die die_mem; 1670 1671 die_find_child(sc_die, __die_collect_vars_cb, (void *)var_types, &die_mem); 1672 } 1673 1674 static int __die_collect_global_vars_cb(Dwarf_Die *die_mem, void *arg) 1675 { 1676 struct die_var_type **var_types = arg; 1677 Dwarf_Die type_die; 1678 int tag = dwarf_tag(die_mem); 1679 Dwarf_Attribute attr; 1680 Dwarf_Addr base, start, end; 1681 Dwarf_Op *ops; 1682 size_t nops; 1683 struct die_var_type *vt; 1684 1685 if (tag != DW_TAG_variable) 1686 return DIE_FIND_CB_SIBLING; 1687 1688 if (dwarf_attr(die_mem, DW_AT_location, &attr) == NULL) 1689 return DIE_FIND_CB_SIBLING; 1690 1691 /* Only collect the location with an absolute address. */ 1692 if (dwarf_getlocations(&attr, 0, &base, &start, &end, &ops, &nops) <= 0) 1693 return DIE_FIND_CB_SIBLING; 1694 1695 if (ops->atom != DW_OP_addr) 1696 return DIE_FIND_CB_SIBLING; 1697 1698 if (!check_allowed_ops(ops, nops)) 1699 return DIE_FIND_CB_SIBLING; 1700 1701 if (die_get_real_type(die_mem, &type_die) == NULL) 1702 return DIE_FIND_CB_SIBLING; 1703 1704 vt = malloc(sizeof(*vt)); 1705 if (vt == NULL) 1706 return DIE_FIND_CB_END; 1707 1708 vt->die_off = dwarf_dieoffset(&type_die); 1709 vt->addr = ops->number; 1710 vt->reg = -1; 1711 vt->offset = 0; 1712 vt->next = *var_types; 1713 *var_types = vt; 1714 1715 return DIE_FIND_CB_SIBLING; 1716 } 1717 1718 /** 1719 * die_collect_global_vars - Save all global variables 1720 * @cu_die: a CU DIE 1721 * @var_types: a pointer to save the resulting list 1722 * 1723 * Save all global variables in the @cu_die and save them to @var_types. 1724 * The @var_types is a singly-linked list containing type and location info. 1725 * Actual type can be retrieved using dwarf_offdie() with 'die_off' later. 1726 * 1727 * Callers should free @var_types. 1728 */ 1729 void die_collect_global_vars(Dwarf_Die *cu_die, struct die_var_type **var_types) 1730 { 1731 Dwarf_Die die_mem; 1732 1733 die_find_child(cu_die, __die_collect_global_vars_cb, (void *)var_types, &die_mem); 1734 } 1735 1736 /** 1737 * die_get_cfa - Get frame base information 1738 * @dwarf: a Dwarf info 1739 * @pc: program address 1740 * @preg: pointer for saved register 1741 * @poffset: pointer for saved offset 1742 * 1743 * This function gets register and offset for CFA (Canonical Frame Address) 1744 * by searching the CIE/FDE info. The CFA usually points to the start address 1745 * of the current stack frame and local variables can be located using an offset 1746 * from the CFA. The @preg and @poffset will be updated if it returns 0. 1747 */ 1748 int die_get_cfa(Dwarf *dwarf, u64 pc, int *preg, int *poffset) 1749 { 1750 Dwarf_CFI *cfi; 1751 Dwarf_Frame *frame = NULL; 1752 Dwarf_Op *ops = NULL; 1753 size_t nops; 1754 1755 cfi = dwarf_getcfi(dwarf); 1756 if (cfi == NULL) 1757 return -1; 1758 1759 if (!dwarf_cfi_addrframe(cfi, pc, &frame) && 1760 !dwarf_frame_cfa(frame, &ops, &nops) && 1761 check_allowed_ops(ops, nops)) { 1762 *preg = reg_from_dwarf_op(ops); 1763 *poffset = offset_from_dwarf_op(ops); 1764 return 0; 1765 } 1766 return -1; 1767 } 1768 1769 /* 1770 * die_has_loclist - Check if DW_AT_location of @vr_die is a location list 1771 * @vr_die: a variable DIE 1772 */ 1773 static bool die_has_loclist(Dwarf_Die *vr_die) 1774 { 1775 Dwarf_Attribute loc; 1776 int tag = dwarf_tag(vr_die); 1777 1778 if (tag != DW_TAG_formal_parameter && 1779 tag != DW_TAG_variable) 1780 return false; 1781 1782 return (dwarf_attr_integrate(vr_die, DW_AT_location, &loc) && 1783 dwarf_whatform(&loc) == DW_FORM_sec_offset); 1784 } 1785 1786 /* 1787 * die_is_optimized_target - Check if target program is compiled with 1788 * optimization 1789 * @cu_die: a CU DIE 1790 * 1791 * For any object in given CU whose DW_AT_location is a location list, 1792 * target program is compiled with optimization. This is applicable to 1793 * clang as well. 1794 */ 1795 bool die_is_optimized_target(Dwarf_Die *cu_die) 1796 { 1797 Dwarf_Die tmp_die; 1798 1799 if (die_has_loclist(cu_die)) 1800 return true; 1801 1802 if (!dwarf_child(cu_die, &tmp_die) && 1803 die_is_optimized_target(&tmp_die)) 1804 return true; 1805 1806 if (!dwarf_siblingof(cu_die, &tmp_die) && 1807 die_is_optimized_target(&tmp_die)) 1808 return true; 1809 1810 return false; 1811 } 1812 1813 /* 1814 * die_search_idx - Search index of given line address 1815 * @lines: Line records of single CU 1816 * @nr_lines: Number of @lines 1817 * @addr: address we are looking for 1818 * @idx: index to be set by this function (return value) 1819 * 1820 * Search for @addr by looping over every lines of CU. If address 1821 * matches, set index of that line in @idx. Note that single source 1822 * line can have multiple line records. i.e. single source line can 1823 * have multiple index. 1824 */ 1825 static bool die_search_idx(Dwarf_Lines *lines, unsigned long nr_lines, 1826 Dwarf_Addr addr, unsigned long *idx) 1827 { 1828 unsigned long i; 1829 Dwarf_Addr tmp; 1830 1831 for (i = 0; i < nr_lines; i++) { 1832 if (dwarf_lineaddr(dwarf_onesrcline(lines, i), &tmp)) 1833 return false; 1834 1835 if (tmp == addr) { 1836 *idx = i; 1837 return true; 1838 } 1839 } 1840 return false; 1841 } 1842 1843 /* 1844 * die_get_postprologue_addr - Search next address after function prologue 1845 * @entrypc_idx: entrypc index 1846 * @lines: Line records of single CU 1847 * @nr_lines: Number of @lines 1848 * @hignpc: high PC address of function 1849 * @postprologue_addr: Next address after function prologue (return value) 1850 * 1851 * Look for prologue-end marker. If there is no explicit marker, return 1852 * address of next line record or next source line. 1853 */ 1854 static bool die_get_postprologue_addr(unsigned long entrypc_idx, 1855 Dwarf_Lines *lines, 1856 unsigned long nr_lines, 1857 Dwarf_Addr highpc, 1858 Dwarf_Addr *postprologue_addr) 1859 { 1860 unsigned long i; 1861 int entrypc_lno, lno; 1862 Dwarf_Line *line; 1863 Dwarf_Addr addr; 1864 bool p_end; 1865 1866 /* entrypc_lno is actual source line number */ 1867 line = dwarf_onesrcline(lines, entrypc_idx); 1868 if (dwarf_lineno(line, &entrypc_lno)) 1869 return false; 1870 1871 for (i = entrypc_idx; i < nr_lines; i++) { 1872 line = dwarf_onesrcline(lines, i); 1873 1874 if (dwarf_lineaddr(line, &addr) || 1875 dwarf_lineno(line, &lno) || 1876 dwarf_lineprologueend(line, &p_end)) 1877 return false; 1878 1879 /* highpc is exclusive. [entrypc,highpc) */ 1880 if (addr >= highpc) 1881 break; 1882 1883 /* clang supports prologue-end marker */ 1884 if (p_end) 1885 break; 1886 1887 /* Actual next line in source */ 1888 if (lno != entrypc_lno) 1889 break; 1890 1891 /* 1892 * Single source line can have multiple line records. 1893 * For Example, 1894 * void foo() { printf("hello\n"); } 1895 * contains two line records. One points to declaration and 1896 * other points to printf() line. Variable 'lno' won't get 1897 * incremented in this case but 'i' will. 1898 */ 1899 if (i != entrypc_idx) 1900 break; 1901 } 1902 1903 dwarf_lineaddr(line, postprologue_addr); 1904 if (*postprologue_addr >= highpc) 1905 dwarf_lineaddr(dwarf_onesrcline(lines, i - 1), 1906 postprologue_addr); 1907 1908 return true; 1909 } 1910 1911 /* 1912 * die_skip_prologue - Use next address after prologue as probe location 1913 * @sp_die: a subprogram DIE 1914 * @cu_die: a CU DIE 1915 * @entrypc: entrypc of the function 1916 * 1917 * Function prologue prepares stack and registers before executing function 1918 * logic. When target program is compiled without optimization, function 1919 * parameter information is only valid after prologue. When we probe entrypc 1920 * of the function, and try to record function parameter, it contains 1921 * garbage value. 1922 */ 1923 void die_skip_prologue(Dwarf_Die *sp_die, Dwarf_Die *cu_die, 1924 Dwarf_Addr *entrypc) 1925 { 1926 size_t nr_lines = 0; 1927 unsigned long entrypc_idx = 0; 1928 Dwarf_Lines *lines = NULL; 1929 Dwarf_Addr postprologue_addr; 1930 Dwarf_Addr highpc; 1931 1932 if (dwarf_highpc(sp_die, &highpc)) 1933 return; 1934 1935 if (dwarf_getsrclines(cu_die, &lines, &nr_lines)) 1936 return; 1937 1938 if (!die_search_idx(lines, nr_lines, *entrypc, &entrypc_idx)) 1939 return; 1940 1941 if (!die_get_postprologue_addr(entrypc_idx, lines, nr_lines, 1942 highpc, &postprologue_addr)) 1943 return; 1944 1945 *entrypc = postprologue_addr; 1946 } 1947 1948 /* Internal parameters for __die_find_scope_cb() */ 1949 struct find_scope_data { 1950 /* Target instruction address */ 1951 Dwarf_Addr pc; 1952 /* Number of scopes found [output] */ 1953 int nr; 1954 /* Array of scopes found, 0 for the outermost one. [output] */ 1955 Dwarf_Die *scopes; 1956 }; 1957 1958 static int __die_find_scope_cb(Dwarf_Die *die_mem, void *arg) 1959 { 1960 struct find_scope_data *data = arg; 1961 int tag = dwarf_tag(die_mem); 1962 1963 if (dwarf_haspc(die_mem, data->pc)) { 1964 Dwarf_Die *tmp; 1965 1966 tmp = realloc(data->scopes, (data->nr + 1) * sizeof(*tmp)); 1967 if (tmp == NULL) 1968 return DIE_FIND_CB_END; 1969 1970 memcpy(tmp + data->nr, die_mem, sizeof(*die_mem)); 1971 data->scopes = tmp; 1972 data->nr++; 1973 return DIE_FIND_CB_CHILD; 1974 } 1975 1976 /* 1977 * If the DIE doesn't have the PC, we still need to check its children 1978 * and siblings if it's a container like a namespace. 1979 */ 1980 if (tag == DW_TAG_namespace) 1981 return DIE_FIND_CB_CONTINUE; 1982 1983 return DIE_FIND_CB_SIBLING; 1984 } 1985 1986 /** 1987 * die_get_scopes - Return a list of scopes including the address 1988 * @cu_die: a compile unit DIE 1989 * @pc: the address to find 1990 * @scopes: the array of DIEs for scopes (result) 1991 * 1992 * This function does the same as the dwarf_getscopes() but doesn't follow 1993 * the origins of inlined functions. It returns the number of scopes saved 1994 * in the @scopes argument. The outer scope will be saved first (index 0) and 1995 * the last one is the innermost scope at the @pc. 1996 */ 1997 int die_get_scopes(Dwarf_Die *cu_die, Dwarf_Addr pc, Dwarf_Die **scopes) 1998 { 1999 struct find_scope_data data = { 2000 .pc = pc, 2001 }; 2002 Dwarf_Die die_mem; 2003 2004 die_find_child(cu_die, __die_find_scope_cb, &data, &die_mem); 2005 2006 *scopes = data.scopes; 2007 return data.nr; 2008 } 2009 2010 static int __die_find_member_offset_cb(Dwarf_Die *die_mem, void *arg) 2011 { 2012 Dwarf_Die type_die; 2013 Dwarf_Word size, loc; 2014 Dwarf_Word offset = (long)arg; 2015 int tag = dwarf_tag(die_mem); 2016 2017 if (tag != DW_TAG_member) 2018 return DIE_FIND_CB_SIBLING; 2019 2020 /* Unions might not have location */ 2021 if (die_get_data_member_location(die_mem, &loc) < 0) { 2022 Dwarf_Attribute attr; 2023 2024 if (dwarf_attr_integrate(die_mem, DW_AT_data_bit_offset, &attr) && 2025 dwarf_formudata(&attr, &loc) == 0) 2026 loc /= 8; 2027 else 2028 loc = 0; 2029 } 2030 2031 if (offset == loc) 2032 return DIE_FIND_CB_END; 2033 2034 if (die_get_real_type(die_mem, &type_die) == NULL) { 2035 // TODO: add a pr_debug_dtp() later for this unlikely failure 2036 return DIE_FIND_CB_SIBLING; 2037 } 2038 2039 if (dwarf_aggregate_size(&type_die, &size) < 0) 2040 size = 0; 2041 2042 if (loc < offset && offset < (loc + size)) 2043 return DIE_FIND_CB_END; 2044 2045 return DIE_FIND_CB_SIBLING; 2046 } 2047 2048 /** 2049 * die_get_member_type - Return type info of struct member 2050 * @type_die: a type DIE 2051 * @offset: offset in the type 2052 * @die_mem: a buffer to save the resulting DIE 2053 * 2054 * This function returns a type of a member in @type_die where it's located at 2055 * @offset if it's a struct. For now, it just returns the first matching 2056 * member in a union. For other types, it'd return the given type directly 2057 * if it's within the size of the type or NULL otherwise. 2058 */ 2059 Dwarf_Die *die_get_member_type(Dwarf_Die *type_die, int offset, 2060 Dwarf_Die *die_mem) 2061 { 2062 Dwarf_Die *member; 2063 Dwarf_Die mb_type; 2064 int tag; 2065 2066 tag = dwarf_tag(type_die); 2067 /* If it's not a compound type, return the type directly */ 2068 if (tag != DW_TAG_structure_type && tag != DW_TAG_union_type) { 2069 Dwarf_Word size; 2070 2071 if (dwarf_aggregate_size(type_die, &size) < 0) 2072 size = 0; 2073 2074 if ((unsigned)offset >= size) 2075 return NULL; 2076 2077 *die_mem = *type_die; 2078 return die_mem; 2079 } 2080 2081 mb_type = *type_die; 2082 /* TODO: Handle union types better? */ 2083 while (tag == DW_TAG_structure_type || tag == DW_TAG_union_type) { 2084 member = die_find_child(&mb_type, __die_find_member_offset_cb, 2085 (void *)(long)offset, die_mem); 2086 if (member == NULL) 2087 return NULL; 2088 2089 if (die_get_real_type(member, &mb_type) == NULL) 2090 return NULL; 2091 2092 tag = dwarf_tag(&mb_type); 2093 2094 if (tag == DW_TAG_structure_type || tag == DW_TAG_union_type) { 2095 Dwarf_Word loc; 2096 2097 /* Update offset for the start of the member struct */ 2098 if (die_get_data_member_location(member, &loc) == 0) 2099 offset -= loc; 2100 } 2101 } 2102 *die_mem = mb_type; 2103 return die_mem; 2104 } 2105 2106 /** 2107 * die_deref_ptr_type - Return type info for pointer access 2108 * @ptr_die: a pointer type DIE 2109 * @offset: access offset for the pointer 2110 * @die_mem: a buffer to save the resulting DIE 2111 * 2112 * This function follows the pointer in @ptr_die with given @offset 2113 * and saves the resulting type in @die_mem. If the pointer points 2114 * a struct type, actual member at the offset would be returned. 2115 */ 2116 Dwarf_Die *die_deref_ptr_type(Dwarf_Die *ptr_die, int offset, 2117 Dwarf_Die *die_mem) 2118 { 2119 Dwarf_Die type_die; 2120 2121 if (dwarf_tag(ptr_die) != DW_TAG_pointer_type) 2122 return NULL; 2123 2124 if (die_get_real_type(ptr_die, &type_die) == NULL) 2125 return NULL; 2126 2127 return die_get_member_type(&type_die, offset, die_mem); 2128 } 2129