static void _dwarf_srcfiles(Dwarf_Die die) { Dwarf_Half tag; Dwarf_Error de; Dwarf_Signed srccount; char **srcfiles; int r_srcfiles, i; if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { tet_printf("dwarf_tag failed: %s\n", dwarf_errmsg(de)); result = TET_FAIL; return; } r_srcfiles = dwarf_srcfiles(die, &srcfiles, &srccount, &de); TS_CHECK_INT(r_srcfiles); if (r_srcfiles == DW_DLV_ERROR) { tet_printf("dwarf_srcfiles should not fail but still failed:", " %s", dwarf_errmsg(de)); return; } if (r_srcfiles != DW_DLV_OK) return; if (dwarf_srcfiles(die, &srcfiles, &srccount, &de) != DW_DLV_OK) { tet_printf("dwarf_srcfiles failed: %s\n", dwarf_errmsg(de)); result = TET_FAIL; return; } TS_CHECK_INT(srccount); for (i = 0; i < srccount; i++) { if (srcfiles[i] == NULL) { tet_printf("dwarf_srcfiles returned NULL pointer" " srcfiles[%d]\n", i); result = TET_FAIL; } else TS_CHECK_STRING(srcfiles[i]); } }
static void _dwarf_lineno(Dwarf_Die die) { Dwarf_Line *linebuf, ln; Dwarf_Signed linecount, lineoff; Dwarf_Unsigned lineno, srcfileno; Dwarf_Addr lineaddr; Dwarf_Half tag; Dwarf_Error de; Dwarf_Bool linebeginstatement, lineendsequence, lineblock; char *linesrc; int r_srclines; int i; if (dwarf_tag(die, &tag, &de) != DW_DLV_OK) { tet_printf("dwarf_tag failed: %s\n", dwarf_errmsg(de)); result = TET_FAIL; return; } r_srclines = dwarf_srclines(die, &linebuf, &linecount, &de); TS_CHECK_INT(r_srclines); if (r_srclines == DW_DLV_ERROR) { tet_printf("dwarf_srclines should not fail but still failed:", " %s", dwarf_errmsg(de)); return; } if (r_srclines != DW_DLV_OK) return; for (i = 0; i < linecount; i++) { ln = linebuf[i]; if (dwarf_linebeginstatement(ln, &linebeginstatement, &de) != DW_DLV_OK) { tet_printf("dwarf_linebeginstatement failed: %s", dwarf_errmsg(de)); result = TET_FAIL; } TS_CHECK_INT(linebeginstatement); if (dwarf_linebeginstatement(ln, &linebeginstatement, &de) != DW_DLV_OK) { tet_printf("dwarf_linebeginstatement failed: %s", dwarf_errmsg(de)); result = TET_FAIL; } TS_CHECK_INT(linebeginstatement); if (dwarf_lineendsequence(ln, &lineendsequence, &de) != DW_DLV_OK) { tet_printf("dwarf_lineendsequence failed: %s", dwarf_errmsg(de)); result = TET_FAIL; } TS_CHECK_INT(lineendsequence); if (dwarf_lineno(ln, &lineno, &de) != DW_DLV_OK) { tet_printf("dwarf_lineno failed: %s", dwarf_errmsg(de)); result = TET_FAIL; } TS_CHECK_UINT(lineno); if (dwarf_line_srcfileno(ln, &srcfileno, &de) != DW_DLV_OK) { tet_printf("dwarf_line_srcfileno failed: %s", dwarf_errmsg(de)); result = TET_FAIL; } TS_CHECK_UINT(srcfileno); if (dwarf_lineaddr(ln, &lineaddr, &de) != DW_DLV_OK) { tet_printf("dwarf_lineaddr failed: %s", dwarf_errmsg(de)); result = TET_FAIL; } TS_CHECK_UINT(lineaddr); if (dwarf_lineoff(ln, &lineoff, &de) != DW_DLV_OK) { tet_printf("dwarf_lineoff failed: %s", dwarf_errmsg(de)); result = TET_FAIL; } TS_CHECK_INT(lineoff); if (dwarf_linesrc(ln, &linesrc, &de) != DW_DLV_OK) { tet_printf("dwarf_linesrc failed: %s", dwarf_errmsg(de)); result = TET_FAIL; } TS_CHECK_STRING(linesrc); if (dwarf_lineblock(ln, &lineblock, &de) != DW_DLV_OK) { tet_printf("dwarf_lineblock failed: %s", dwarf_errmsg(de)); result = TET_FAIL; } TS_CHECK_INT(lineblock); } }
static void _dwarf_attr(Dwarf_Die die) { Dwarf_Attribute at; Dwarf_Bool has_attr; Dwarf_Half attr; Dwarf_Error de; const char *attr_name; int i, r; for (i = 0; i < attr_array_size; i++) { if (dwarf_hasattr(die, attr_array[i], &has_attr, &de) != DW_DLV_OK) { tet_printf("dwarf_hasattr failed: %s\n", dwarf_errmsg(de)); result = TET_FAIL; } TS_CHECK_INT(has_attr); if (has_attr) { if (dwarf_get_AT_name(attr_array[i], &attr_name) != DW_DLV_OK) { tet_printf("dwarf_get_AT_name failed: %s\n", dwarf_errmsg(de)); result = TET_FAIL; continue; } if (attr_name == NULL) { tet_infoline("dwarf_get_AT_name returned " "DW_DLV_OK but didn't return string"); result = TET_FAIL; continue; } TS_CHECK_STRING(attr_name); tet_printf("DIE #%d has attribute '%s'\n", die_cnt, attr_name); r = dwarf_attr(die, attr_array[i], &at, &de); if (r == DW_DLV_ERROR) { tet_printf("dwarf_attr failed: %s", dwarf_errmsg(de)); result = TET_FAIL; continue; } else if (r == DW_DLV_NO_ENTRY) { tet_infoline("dwarf_hasattr returned true for " "attribute '%s', while dwarf_attr returned" " DW_DLV_NO_ENTRY for the same attr"); result = TET_FAIL; continue; } if (dwarf_whatattr(at, &attr, &de) != DW_DLV_OK) { tet_printf("dwarf_whatattr failed: %s", dwarf_errmsg(de)); result = TET_FAIL; continue; } if (attr != attr_array[i]) { tet_infoline("attr returned by dwarf_whatattr" " != attr_array[i]"); result = TET_FAIL; continue; } } } }
static void _dwarf_cie_fde_test(Dwarf_Debug dbg, int eh, void (*_frame_test)(Dwarf_Debug, Dwarf_Fde, Dwarf_Addr, Dwarf_Unsigned, Dwarf_Unsigned)) { Dwarf_Cie *cielist, cie; Dwarf_Fde *fdelist, fde; Dwarf_Frame_Op *oplist; Dwarf_Signed ciecnt, fdecnt; Dwarf_Addr low_pc, high_pc; Dwarf_Unsigned func_len, fde_byte_len, fde_inst_len, bytes_in_cie; Dwarf_Unsigned cie_caf, cie_daf, cie_inst_len; Dwarf_Signed cie_index, opcnt; Dwarf_Off cie_offset, fde_offset; Dwarf_Ptr fde_bytes, fde_inst, cie_initinst; Dwarf_Half cie_ra; Dwarf_Small cie_version; Dwarf_Error de; const char *cfa_str; char *cie_augmenter; int i, j, r_fde_at_pc; if (eh) { if (dwarf_get_fde_list_eh(dbg, &cielist, &ciecnt, &fdelist, &fdecnt, &de) != DW_DLV_OK) { tet_printf("dwarf_get_fde_list_eh failed: %s\n", dwarf_errmsg(de)); result = TET_FAIL; goto done; } } else { if (dwarf_get_fde_list(dbg, &cielist, &ciecnt, &fdelist, &fdecnt, &de) != DW_DLV_OK) { tet_printf("dwarf_get_fde_list failed: %s\n", dwarf_errmsg(de)); result = TET_FAIL; goto done; } } TS_CHECK_INT(ciecnt); TS_CHECK_INT(fdecnt); /* * Test dwarf_get_fde_at_pc using hard-coded PC values. */ tet_infoline("attempt to get fde at 0x08082a30"); r_fde_at_pc = dwarf_get_fde_at_pc(fdelist, 0x08082a30, &fde, &low_pc, &high_pc, &de); TS_CHECK_INT(r_fde_at_pc); if (r_fde_at_pc == DW_DLV_OK) { TS_CHECK_UINT(low_pc); TS_CHECK_UINT(high_pc); } tet_infoline("attempt to get fde at 0x08083087"); r_fde_at_pc = dwarf_get_fde_at_pc(fdelist, 0x08083087, &fde, &low_pc, &high_pc, &de); TS_CHECK_INT(r_fde_at_pc); if (r_fde_at_pc == DW_DLV_OK) { TS_CHECK_UINT(low_pc); TS_CHECK_UINT(high_pc); } tet_infoline("attempt to get fde at 0x080481f0"); r_fde_at_pc = dwarf_get_fde_at_pc(fdelist, 0x080481f0, &fde, &low_pc, &high_pc, &de); TS_CHECK_INT(r_fde_at_pc); if (r_fde_at_pc == DW_DLV_OK) { TS_CHECK_UINT(low_pc); TS_CHECK_UINT(high_pc); } tet_infoline("attempt to get fde at 0x08048564"); r_fde_at_pc = dwarf_get_fde_at_pc(fdelist, 0x08048564, &fde, &low_pc, &high_pc, &de); TS_CHECK_INT(r_fde_at_pc); if (r_fde_at_pc == DW_DLV_OK) { TS_CHECK_UINT(low_pc); TS_CHECK_UINT(high_pc); } tet_infoline("attempt to get fde at 0x00401280"); r_fde_at_pc = dwarf_get_fde_at_pc(fdelist, 0x00401280, &fde, &low_pc, &high_pc, &de); TS_CHECK_INT(r_fde_at_pc); if (r_fde_at_pc == DW_DLV_OK) { TS_CHECK_UINT(low_pc); TS_CHECK_UINT(high_pc); } tet_infoline("attempt to get fde at 0x004012b1"); r_fde_at_pc = dwarf_get_fde_at_pc(fdelist, 0x004012b1, &fde, &low_pc, &high_pc, &de); TS_CHECK_INT(r_fde_at_pc); if (r_fde_at_pc == DW_DLV_OK) { TS_CHECK_UINT(low_pc); TS_CHECK_UINT(high_pc); } /* * Test each FDE contained in the FDE list. */ for (i = 0; i < fdecnt; i++) { if (dwarf_get_fde_n(fdelist, i, &fde, &de) != DW_DLV_OK) { tet_printf("dwarf_get_fde_n(%d) failed: %s\n", i, dwarf_errmsg(de)); result = TET_FAIL; continue; } if (dwarf_get_fde_range(fde, &low_pc, &func_len, &fde_bytes, &fde_byte_len, &cie_offset, &cie_index, &fde_offset, &de) == DW_DLV_ERROR) { tet_printf("dwarf_get_fde_range(%d) failed: %s\n", i, dwarf_errmsg(de)); result = TET_FAIL; continue; } TS_CHECK_UINT(low_pc); TS_CHECK_UINT(func_len); TS_CHECK_UINT(fde_byte_len); if (fde_byte_len > 0) TS_CHECK_BLOCK(fde_bytes, fde_byte_len); TS_CHECK_INT(cie_offset); TS_CHECK_INT(cie_index); TS_CHECK_INT(fde_offset); if (dwarf_get_cie_of_fde(fde, &cie, &de) != DW_DLV_OK) { tet_printf("dwarf_get_cie_of_fde(%d) failed: %s\n", i, dwarf_errmsg(de)); result = TET_FAIL; continue; } if (dwarf_get_cie_index(cie, &cie_index, &de) != DW_DLV_OK) { tet_printf("dwarf_get_cie_index(%d) failed: %s\n", i, dwarf_errmsg(de)); result = TET_FAIL; continue; } TS_CHECK_INT(cie_index); if (dwarf_get_cie_info(cie, &bytes_in_cie, &cie_version, &cie_augmenter, &cie_caf, &cie_daf, &cie_ra, &cie_initinst, &cie_inst_len, &de) != DW_DLV_OK) { tet_printf("dwarf_get_cie_info(%d) failed: %s\n", i, dwarf_errmsg(de)); result = TET_FAIL; continue; } TS_CHECK_UINT(bytes_in_cie); TS_CHECK_UINT(cie_version); TS_CHECK_STRING(cie_augmenter); TS_CHECK_UINT(cie_caf); TS_CHECK_UINT(cie_daf); TS_CHECK_UINT(cie_ra); TS_CHECK_UINT(cie_inst_len); if (cie_inst_len > 0) TS_CHECK_BLOCK(cie_initinst, cie_inst_len); if (dwarf_get_fde_instr_bytes(fde, &fde_inst, &fde_inst_len, &de) != DW_DLV_OK) { tet_printf("dwarf_get_fde_instr_bytes(%d) failed: %s\n", i, dwarf_errmsg(de)); result = TET_FAIL; continue; } TS_CHECK_UINT(fde_inst_len); if (fde_inst_len > 0) { TS_CHECK_BLOCK(fde_inst, fde_inst_len); if (dwarf_expand_frame_instructions(cie, fde_inst, fde_inst_len, &oplist, &opcnt, &de) != DW_DLV_OK) { tet_printf("dwarf_expand_frame_instructions(%d)" " failed: %s\n", i, dwarf_errmsg(de)); result = TET_FAIL; continue; } TS_CHECK_INT(opcnt); for (j = 0; j < opcnt; j++) { TS_CHECK_UINT(oplist[j].fp_base_op); if (oplist[j].fp_base_op != 0) { if (dwarf_get_CFA_name( oplist[j].fp_base_op << 6, &cfa_str) != DW_DLV_OK) { tet_printf("dwarf_get_CFA_name" " failed\n"); continue; } TS_CHECK_STRING(cfa_str); } TS_CHECK_UINT(oplist[j].fp_extended_op); if (oplist[j].fp_extended_op != 0) { if (dwarf_get_CFA_name( oplist[j].fp_extended_op, &cfa_str) != DW_DLV_OK) { tet_printf("dwarf_get_CFA_name" " failed\n"); continue; } TS_CHECK_STRING(cfa_str); } TS_CHECK_UINT(oplist[j].fp_register); TS_CHECK_INT(oplist[j].fp_offset); TS_CHECK_INT(oplist[j].fp_instr_offset); } } _frame_test(dbg, fde, low_pc, func_len, cie_caf); } done: return; }