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; }
static void do_checking(Dwarf_Debug dbg, Dwarf_Arange *arange_buf,Dwarf_Signed i, Dwarf_Off cu_die_offset,Dwarf_Bool first_cu, Dwarf_Off cu_die_offset_prev, Dwarf_Die cu_die ) { int dres = 0; Dwarf_Off cuhdroff = 0; Dwarf_Off cudieoff3 = 0; dres = dwarf_get_arange_cu_header_offset( arange_buf[i],&cuhdroff,&err); if (dres == DW_DLV_OK) { Dwarf_Off cudieoff2 = 0; /* Get the CU offset for easy error reporting */ if (first_cu || cu_die_offset != cu_die_offset_prev) { cu_die_offset_prev = cu_die_offset; dres = dwarf_die_offsets(cu_die,&DIE_overall_offset,&DIE_offset,&err); if (dres != DW_DLV_OK) { print_error(dbg, "dwarf_die_offsets", dres, err); } } dres = dwarf_get_cu_die_offset_given_cu_header_offset( dbg,cuhdroff,&cudieoff2,&err); if (dres == DW_DLV_OK) { /* Get the CU offset for easy error reporting */ dwarf_die_offsets(cu_die,&DIE_overall_offset,&DIE_offset,&err); DWARF_CHECK_COUNT(aranges_result,1); if (cudieoff2 != cu_die_offset) { printf("Error, cu_die offsets mismatch, 0x%" DW_PR_DUx " != 0x%" DW_PR_DUx " from arange data", cu_die_offset,cudieoff2); DWARF_CHECK_ERROR(aranges_result, " dwarf_get_cu_die_offset_given_cu..." " gets wrong offset"); } } else { print_error(dbg, "dwarf_get_cu_die_offset_given...", dres, err); } } else { print_error(dbg, "dwarf_get_arange_cu_header_offset", dres, err); } dres = dwarf_get_cu_die_offset(arange_buf[i],&cudieoff3, &err); if (dres == DW_DLV_OK) { DWARF_CHECK_COUNT(aranges_result,1); if (cudieoff3 != cu_die_offset) { printf( "Error, cu_die offsets (b) mismatch , 0x%" DW_PR_DUx " != 0x%" DW_PR_DUx " from arange data", cu_die_offset,cudieoff3); DWARF_CHECK_ERROR(aranges_result, " dwarf_get_cu_die_offset " " gets wrong offset"); } } else { print_error(dbg, "dwarf_get_cu_die_offset failed ", dres,err); } }
static void tp_dwarf_arange(void) { Dwarf_Debug dbg; Dwarf_Arange *aranges; Dwarf_Arange arange; Dwarf_Signed arange_cnt; Dwarf_Off cu_die_offset, cu_die_offset2, cu_header_offset; Dwarf_Addr start; Dwarf_Unsigned length; Dwarf_Error de; int fd, i, r_aranges, r_arange; result = TET_UNRESOLVED; TS_DWARF_INIT(dbg, fd, de); r_aranges = dwarf_get_aranges(dbg, &aranges, &arange_cnt, &de); TS_CHECK_INT(r_aranges); if (r_aranges == DW_DLV_ERROR) { tet_printf("dwarf_get_aranges failed: %s\n", dwarf_errmsg(de)); result = TET_FAIL; goto done; } if (r_aranges == DW_DLV_OK) { for (i = 0; i < arange_cnt; i++) { if (dwarf_get_cu_die_offset(aranges[i], &cu_die_offset, &de) != DW_DLV_OK) { tet_printf("dwarf_get_cu_die_offset failed:" " %s\n", dwarf_errmsg(de)); result = TET_FAIL; continue; } TS_CHECK_INT(cu_die_offset); if (dwarf_get_arange_cu_header_offset(aranges[i], &cu_header_offset, &de) != DW_DLV_OK) { tet_printf("dwarf_get_arange_cu_header_offset" "failed: %s\n", dwarf_errmsg(de)); result = TET_FAIL; continue; } TS_CHECK_INT(cu_header_offset); if (dwarf_get_arange_info(aranges[i], &start, &length, &cu_die_offset2, &de) != DW_DLV_OK) { tet_printf("dwarf_get_arange_info failed:%s\n", dwarf_errmsg(de)); result = TET_FAIL; continue; } TS_CHECK_UINT(start); TS_CHECK_UINT(length); TS_CHECK_UINT(cu_die_offset2); r_arange = dwarf_get_arange(aranges, arange_cnt, start, &arange, &de); TS_CHECK_INT(r_arange); r_arange = dwarf_get_arange(aranges, arange_cnt, start + 1, &arange, &de); TS_CHECK_INT(r_arange); r_arange = dwarf_get_arange(aranges, arange_cnt, start + length, &arange, &de); TS_CHECK_INT(r_arange); r_arange = dwarf_get_arange(aranges, arange_cnt, start + length + 1, &arange, &de); TS_CHECK_INT(r_arange); r_arange = dwarf_get_arange(aranges, arange_cnt, start + length - 1, &arange, &de); TS_CHECK_INT(r_arange); } } if (result == TET_UNRESOLVED) result = TET_PASS; done: TS_DWARF_FINISH(dbg, de); TS_RESULT(result); }