| 3394 | } |
| 3395 | |
| 3396 | Dwarf_Die find_die(dwarf_fileobject& fobj, Dwarf_Addr addr) |
| 3397 | { |
| 3398 | // Let's get to work! First see if we have a debug_aranges section so |
| 3399 | // we can speed up the search |
| 3400 | |
| 3401 | Dwarf_Debug dwarf = fobj.dwarf_handle.get(); |
| 3402 | Dwarf_Error error = DW_DLE_NE; |
| 3403 | Dwarf_Arange* aranges; |
| 3404 | Dwarf_Signed arange_count; |
| 3405 | |
| 3406 | Dwarf_Die returnDie; |
| 3407 | bool found = false; |
| 3408 | if (dwarf_get_aranges(dwarf, &aranges, &arange_count, &error) != DW_DLV_OK) { |
| 3409 | aranges = NULL; |
| 3410 | } |
| 3411 | |
| 3412 | if (aranges) { |
| 3413 | // We have aranges. Get the one where our address is. |
| 3414 | Dwarf_Arange arange; |
| 3415 | if (dwarf_get_arange(aranges, arange_count, addr, &arange, &error) == DW_DLV_OK) { |
| 3416 | |
| 3417 | // We found our address. Get the compilation-unit DIE offset |
| 3418 | // represented by the given address range. |
| 3419 | Dwarf_Off cu_die_offset; |
| 3420 | if (dwarf_get_cu_die_offset(arange, &cu_die_offset, &error) == DW_DLV_OK) { |
| 3421 | // Get the DIE at the offset returned by the aranges search. |
| 3422 | // We set is_info to 1 to specify that the offset is from |
| 3423 | // the .debug_info section (and not .debug_types) |
| 3424 | int dwarf_result = dwarf_offdie_b(dwarf, cu_die_offset, 1, &returnDie, &error); |
| 3425 | |
| 3426 | found = dwarf_result == DW_DLV_OK; |
| 3427 | } |
| 3428 | dwarf_dealloc(dwarf, arange, DW_DLA_ARANGE); |
| 3429 | } |
| 3430 | } |
| 3431 | |
| 3432 | if (found) |
| 3433 | return returnDie; // The caller is responsible for freeing the die |
| 3434 | |
| 3435 | // The search for aranges failed. Try to find our address by scanning |
| 3436 | // all compilation units. |
| 3437 | Dwarf_Unsigned next_cu_header; |
| 3438 | Dwarf_Half tag = 0; |
| 3439 | returnDie = 0; |
| 3440 | |
| 3441 | while (!found && |
| 3442 | dwarf_next_cu_header_d(dwarf, 1, 0, 0, 0, 0, 0, 0, 0, 0, &next_cu_header, 0, &error) == DW_DLV_OK) { |
| 3443 | |
| 3444 | if (returnDie) |
| 3445 | dwarf_dealloc(dwarf, returnDie, DW_DLA_DIE); |
| 3446 | |
| 3447 | if (dwarf_siblingof(dwarf, 0, &returnDie, &error) == DW_DLV_OK) { |
| 3448 | if ((dwarf_tag(returnDie, &tag, &error) == DW_DLV_OK) && tag == DW_TAG_compile_unit) { |
| 3449 | if (die_has_pc(fobj, returnDie, addr)) { |
| 3450 | found = true; |
| 3451 | } |
| 3452 | } |
| 3453 | } |
no test coverage detected