bool drsym_obj_dwarf_init(void *mod_in, Dwarf_Debug *dbg) { elf_info_t *mod = (elf_info_t *) mod_in; Dwarf_Error de = {0}; if (mod == NULL) return false; if (dwarf_elf_init(mod->elf, DW_DLC_READ, NULL, NULL, dbg, &de) != DW_DLV_OK) { NOTIFY_DWARF(de); return false; } return true; }
bool drsym_obj_dwarf_init(void *mod_in, Dwarf_Debug *dbg) { pecoff_data_t *mod = (pecoff_data_t *) mod_in; Dwarf_Error de; /* expensive to init (DrM#1770) */ if (mod == NULL) return false; if (dwarf_pecoff_init(mod->map_base, DW_DLC_READ, NULL, NULL, dbg, &de) != DW_DLV_OK) { NOTIFY_DWARF(de); return false; } return true; }
/* Find the next DIE matching this tag. Uses the internal state of dbg to * determine where to start searching. */ static Dwarf_Die next_die_matching_tag(Dwarf_Debug dbg, Dwarf_Tag search_tag) { Dwarf_Half tag = 0; Dwarf_Die die = NULL; Dwarf_Error de = {0}; while (dwarf_siblingof(dbg, die, &die, &de) == DW_DLV_OK) { if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { NOTIFY_DWARF(de); die = NULL; break; } if (tag == search_tag) break; } return die; }
static Dwarf_Die find_cu_die(Dwarf_Debug dbg, Dwarf_Addr pc) { Dwarf_Error de = {0}; Dwarf_Die cu_die = NULL; Dwarf_Arange *arlist; Dwarf_Signed arcnt; Dwarf_Arange ar; Dwarf_Off die_offs; if (dwarf_get_aranges(dbg, &arlist, &arcnt, &de) != DW_DLV_OK || dwarf_get_arange(arlist, arcnt, pc, &ar, &de) != DW_DLV_OK || dwarf_get_cu_die_offset(ar, &die_offs, &de) != DW_DLV_OK || dwarf_offdie(dbg, die_offs, &cu_die, &de) != DW_DLV_OK) { NOTIFY_DWARF(de); /* Try to find it by walking all CU's and looking at their lowpc+highpc * entries, which should work if each has a single contiguous * range. Note that Cygwin and MinGW gcc don't seen to include * lowpc+highpc in their CU's. */ cu_die = find_cu_die_via_iter(dbg, pc); } return cu_die; }
/* Iterate over all the CUs in the module to find the CU containing the given * PC. */ static Dwarf_Die find_cu_die_via_iter(Dwarf_Debug dbg, Dwarf_Addr pc) { Dwarf_Die die = NULL; Dwarf_Unsigned cu_offset = 0; Dwarf_Error de = {0}; Dwarf_Die cu_die = NULL; while (dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, &cu_offset, &de) == DW_DLV_OK) { /* Scan forward in the tag soup for a CU DIE. */ die = next_die_matching_tag(dbg, DW_TAG_compile_unit); /* We found a CU die, now check if it's the one we wanted. */ if (die != NULL) { Dwarf_Addr lo_pc, hi_pc; if (dwarf_lowpc(die, &lo_pc, &de) != DW_DLV_OK || dwarf_highpc(die, &hi_pc, &de) != DW_DLV_OK) { NOTIFY_DWARF(de); break; } if (lo_pc <= pc && pc < hi_pc) { cu_die = die; break; } } } while (dwarf_next_cu_header(dbg, NULL, NULL, NULL, NULL, &cu_offset, &de) == DW_DLV_OK) { /* Reset the internal CU header state. */ } return cu_die; }