/* Print data in .debug_abbrev This is inherently unsafe as it assumes there are no byte sequences in .debug_abbrev other than legal abbrev sequences. But the Dwarf spec does not promise that. The spec only promises that any bytes at an offset referred to from .debug_info are legal sequences. */ extern void print_abbrevs(Dwarf_Debug dbg) { Dwarf_Abbrev ab; Dwarf_Unsigned offset = 0; Dwarf_Unsigned length = 0; Dwarf_Unsigned abbrev_entry_count = 0; /* Maximum defined tag is 0xffff, DW_TAG_hi_user. */ Dwarf_Half tag = 0; Dwarf_Half attr = 0; Dwarf_Signed form = 0; Dwarf_Off off = 0; Dwarf_Unsigned i = 0; const char * child_name = 0; Dwarf_Unsigned abbrev_num = 1; Dwarf_Signed child_flag = 0; int abres = 0; int tres = 0; int acres = 0; Dwarf_Unsigned abbrev_code = 0; current_section_id = DEBUG_ABBREV; if (do_print_dwarf) { printf("\n.debug_abbrev\n"); } while ((abres = dwarf_get_abbrev(dbg, offset, &ab, &length, &abbrev_entry_count, &err)) == DW_DLV_OK) { if (abbrev_entry_count == 0) { /* Simple innocuous zero : null abbrev entry */ if (dense) { printf("<%" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx "><%" DW_PR_DSd "><%s>\n", abbrev_num, offset, (Dwarf_Signed) /* abbrev_code */ 0, "null .debug_abbrev entry"); } else { printf("<%5" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx "><code: %3" DW_PR_DSd "> %-20s\n", abbrev_num, offset, (Dwarf_Signed) /* abbrev_code */ 0, "null .debug_abbrev entry"); } offset += length; ++abbrev_num; dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); continue; } tres = dwarf_get_abbrev_tag(ab, &tag, &err); if (tres != DW_DLV_OK) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); print_error(dbg, "dwarf_get_abbrev_tag", tres, err); } tres = dwarf_get_abbrev_code(ab, &abbrev_code, &err); if (tres != DW_DLV_OK) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); print_error(dbg, "dwarf_get_abbrev_code", tres, err); } if (dense) { printf("<%" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx "><%" DW_PR_DSd "><%s>", abbrev_num, offset, abbrev_code, get_TAG_name(tag,dwarf_names_print_on_error)); } else { printf("<%5" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx "><code: %3" DW_PR_DSd "> %-20s", abbrev_num, offset, abbrev_code, get_TAG_name(tag,dwarf_names_print_on_error)); } /* Process specific TAGs specially. */ tag_specific_checks_setup(tag,0); ++abbrev_num; acres = dwarf_get_abbrev_children_flag(ab, &child_flag, &err); if (acres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); print_error(dbg, "dwarf_get_abbrev_children_flag", acres, err); } if (acres == DW_DLV_NO_ENTRY) { child_flag = 0; } child_name = get_children_name(child_flag, dwarf_names_print_on_error); if (dense) printf(" %s", child_name); else printf(" %s\n", child_name); /* Abbrev just contains the format of a die, which debug_info then points to with the real data. So here we just print the given format. */ for (i = 0; i < abbrev_entry_count; i++) { int aeres = 0; aeres = dwarf_get_abbrev_entry(ab, i, &attr, &form, &off, &err); if (aeres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); print_error(dbg, "dwarf_get_abbrev_entry", aeres, err); } if (aeres == DW_DLV_NO_ENTRY) { attr = -1LL; form = -1LL; } if (dense) { printf(" <%ld>%s<%s>", (unsigned long) off, get_AT_name(attr,dwarf_names_print_on_error), get_FORM_name((Dwarf_Half) form, dwarf_names_print_on_error)); } else { printf(" <0x%08lx> %-28s%s\n", (unsigned long) off, get_AT_name(attr, dwarf_names_print_on_error), get_FORM_name((Dwarf_Half) form, dwarf_names_print_on_error)); } } dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); offset += length; if (dense) { printf("\n"); } } if (abres == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_abbrev", abres, err); } }
/* Print data in .debug_abbrev This is inherently unsafe as it assumes there are no byte sequences in .debug_abbrev other than legal abbrev sequences. But the Dwarf spec does not promise that. The spec only promises that any bytes at an offset referred to from .debug_info are legal sequences. */ extern void print_abbrevs(Dwarf_Debug dbg) { Dwarf_Abbrev ab; Dwarf_Unsigned offset = 0; Dwarf_Unsigned length = 0; Dwarf_Unsigned abbrev_entry_count = 0; /* Maximum defined tag is 0xffff, DW_TAG_hi_user. */ Dwarf_Half tag = 0; Dwarf_Half attr = 0; Dwarf_Signed form = 0; Dwarf_Off off = 0; Dwarf_Unsigned i = 0; Dwarf_Unsigned abbrev_num = 1; Dwarf_Signed child_flag = 0; int abres = 0; int tres = 0; int acres = 0; Dwarf_Unsigned abbrev_code = 0; Dwarf_Error paerr = 0; current_section_id = DEBUG_ABBREV; if (do_print_dwarf) { printf("\n.debug_abbrev\n"); } while ((abres = dwarf_get_abbrev(dbg, offset, &ab, &length, &abbrev_entry_count, &paerr)) == DW_DLV_OK) { const char *tagname = ""; /* Here offset is the global offset in .debug_abbrev. The abbrev_num is a relatively worthless counter of all abbreviations. */ tres = dwarf_get_abbrev_tag(ab, &tag, &paerr); if (tres != DW_DLV_OK) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); print_error(dbg, "dwarf_get_abbrev_tag", tres, paerr); } tres = dwarf_get_abbrev_code(ab, &abbrev_code, &paerr); if (tres != DW_DLV_OK) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); print_error(dbg, "dwarf_get_abbrev_code", tres, paerr); } tagname = get_TAG_name(tag,dwarf_names_print_on_error); if (!tag) { tagname = "Abbrev 0: null abbrev entry"; } if (dense) { printf("<%" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx "><code: %" DW_PR_DUu ">", abbrev_num, offset,abbrev_code); if (verbose) { printf("<length: 0x%" DW_PR_XZEROS DW_PR_DUx ">", length); } printf(" %s", tagname); } else { printf("<%5" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx "><code: %3" DW_PR_DUu ">", abbrev_num, offset, abbrev_code); if (verbose) { printf("<length: 0x%" DW_PR_XZEROS DW_PR_DUx ">", length); } printf(" %-27s", tagname); } /* Process specific TAGs specially. */ tag_specific_checks_setup(tag,0); ++abbrev_num; acres = dwarf_get_abbrev_children_flag(ab, &child_flag, &paerr); if (acres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); print_error(dbg, "dwarf_get_abbrev_children_flag", acres, paerr); } if (acres == DW_DLV_NO_ENTRY) { child_flag = 0; } /* If tag is zero, it is a null byte, not a real abbreviation, so there is no 'children' flag to print. */ if (tag) { const char * child_name = 0; child_name = get_children_name(child_flag, dwarf_names_print_on_error); printf(" %s", child_name); } if(!dense) { printf("\n"); } /* Abbrev just contains the format of a die, which debug_info then points to with the real data. So here we just print the given format. */ for (i = 0; i < abbrev_entry_count; i++) { int aeres = 0; aeres = dwarf_get_abbrev_entry(ab, i, &attr, &form, &off, &paerr); if (aeres == DW_DLV_ERROR) { dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); print_error(dbg, "dwarf_get_abbrev_entry", aeres, paerr); } if (aeres == DW_DLV_NO_ENTRY) { attr = -1LL; form = -1LL; } if (dense) { printf(" <%ld>%s<%s>", (unsigned long) off, get_AT_name(attr,dwarf_names_print_on_error), get_FORM_name((Dwarf_Half) form, dwarf_names_print_on_error)); } else { printf(" <0x%08lx> %-28s%s\n", (unsigned long) off, get_AT_name(attr, dwarf_names_print_on_error), get_FORM_name((Dwarf_Half) form, dwarf_names_print_on_error)); } } dwarf_dealloc(dbg, ab, DW_DLA_ABBREV); offset += length; if (dense) { printf("\n"); } } if (abres == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_abbrev", abres, paerr); } }