/* Get all the data in .debug_pubnames */ void print_pubnames(Dwarf_Debug dbg) { Dwarf_Global *globbuf = NULL; Dwarf_Signed count = 0; Dwarf_Signed i = 0; Dwarf_Off die_off = 0; Dwarf_Off cu_off = 0; /* Offset to previous CU */ Dwarf_Off prev_cu_off = elf_max_address; char *name = 0; int res = 0; current_section_id = DEBUG_PUBNAMES; if (do_print_dwarf) { printf("\n.debug_pubnames\n"); } res = dwarf_get_globals(dbg, &globbuf, &count, &err); if (res == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_globals", res, err); } else if (res == DW_DLV_NO_ENTRY) { /* (err == 0 && count == DW_DLV_NOCOUNT) means there are no pubnames. */ } else { Dwarf_Unsigned maxoff = get_info_max_offset(dbg); for (i = 0; i < count; i++) { int nres = 0; int cures3 = 0; Dwarf_Off global_cu_off = 0; nres = dwarf_global_name_offsets(globbuf[i], &name, &die_off, &cu_off, &err); deal_with_name_offset_err(dbg, "dwarf_global_name_offsets", name, die_off, nres, err); cures3 = dwarf_global_cu_offset(globbuf[i], &global_cu_off, &err); if (cures3 != DW_DLV_OK) { print_error(dbg, "dwarf_global_cu_offset", cures3, err); } if (check_pubname_attr) { Dwarf_Bool has_attr; int ares; int dres; Dwarf_Die die; /* We are processing a new set of pubnames for a different CU; get the producer ID, at 'cu_off' to see if we need to skip these pubnames */ if (cu_off != prev_cu_off) { /* Record offset for previous CU */ prev_cu_off = cu_off; dres = dwarf_offdie(dbg, cu_off, &die, &err); if (dres != DW_DLV_OK) { print_error(dbg, "print pubnames: dwarf_offdie a", dres,err); } { /* Get producer name for this CU and update compiler list */ struct esb_s producername; esb_constructor(&producername); get_producer_name(dbg,die,err,&producername); update_compiler_target(esb_get_string(&producername)); esb_destructor(&producername); } dwarf_dealloc(dbg, die, DW_DLA_DIE); } /* get die at die_off */ dres = dwarf_offdie(dbg, die_off, &die, &err); if (dres != DW_DLV_OK) { print_error(dbg, "print pubnames: dwarf_offdie b", dres, err); } ares = dwarf_hasattr(die, DW_AT_external, &has_attr, &err); if (ares == DW_DLV_ERROR) { print_error(dbg, "hassattr on DW_AT_external", ares, err); } /* Check for specific compiler */ if (checking_this_compiler()) { DWARF_CHECK_COUNT(pubname_attr_result,1); if (ares == DW_DLV_OK && has_attr) { /* Should the value of flag be examined? */ } else { DWARF_CHECK_ERROR2(pubname_attr_result,name, "pubname does not have DW_AT_external"); } } dwarf_dealloc(dbg, die, DW_DLA_DIE); } /* Now print pubname, after the test */ if (do_print_dwarf || (record_dwarf_error && check_verbose_mode)) { print_pubname_style_entry(dbg, "global", name, die_off, cu_off, global_cu_off, maxoff); record_dwarf_error = FALSE; /* Clear error condition */ } } dwarf_globals_dealloc(dbg, globbuf, count); } } /* print_pubnames() */
/* get all the data in .debug_aranges */ extern void print_aranges(Dwarf_Debug dbg) { Dwarf_Signed count = 0; Dwarf_Signed i = 0; Dwarf_Arange *arange_buf = NULL; int ares = 0; int aires = 0; Dwarf_Off prev_off = 0; /* Holds previous CU offset */ Dwarf_Bool first_cu = TRUE; Dwarf_Off cu_die_offset_prev = 0; /* Reset the global state, so we can traverse the debug_info */ seen_CU = FALSE; need_CU_name = TRUE; need_CU_base_address = TRUE; need_CU_high_address = TRUE; current_section_id = DEBUG_ARANGES; if (do_print_dwarf) { printf("\n.debug_aranges\n"); } ares = dwarf_get_aranges(dbg, &arange_buf, &count, &err); if (ares == DW_DLV_ERROR) { print_error(dbg, "dwarf_get_aranges", ares, err); } else if (ares == DW_DLV_NO_ENTRY) { /* no arange is included */ } else { for (i = 0; i < count; i++) { Dwarf_Unsigned segment = 0; Dwarf_Unsigned segment_entry_size = 0; Dwarf_Addr start = 0; Dwarf_Unsigned length = 0; Dwarf_Off cu_die_offset = 0; Dwarf_Die cu_die = NULL; aires = dwarf_get_arange_info_b(arange_buf[i], &segment, &segment_entry_size, &start, &length, &cu_die_offset, &err); if (aires != DW_DLV_OK) { print_error(dbg, "dwarf_get_arange_info", aires, err); } else { int dres; struct esb_s producer_name; esb_constructor(&producer_name); /* Get basic locations for error reporting */ dres = dwarf_offdie(dbg, cu_die_offset, &cu_die, &err); if (dres != DW_DLV_OK) { print_error(dbg, "dwarf_offdie", dres, err); } if (cu_name_flag) { if (should_skip_this_cu(dbg,cu_die,err)) { continue; } } /* Get producer name for this CU and update compiler list */ get_producer_name(dbg,cu_die,err,&producer_name); update_compiler_target(esb_get_string(&producer_name)); esb_destructor(&producer_name); if (!checking_this_compiler()) { continue; } if (check_aranges) { do_checking(dbg,arange_buf,i,cu_die_offset,first_cu, cu_die_offset_prev,cu_die); } /* Get the offset of the cu header itself in the section, but not for end-entries. */ if (start || length) { Dwarf_Off off = 0; int cures3 = dwarf_get_arange_cu_header_offset( arange_buf[i], &off, &err); if (cures3 != DW_DLV_OK) { print_error(dbg, "dwarf_get_cu_hdr_offset", cures3, err); } /* Print the CU information if different. */ if (prev_off != off || first_cu) { first_cu = FALSE; prev_off = off; /* We are faking the indent level. We do not know what level it is, really. If do_check_dwarf we do not want to do the die print call as it will do check/print we may not have asked for. And if we did ask for debug_info checks this will do the checks a second time! So only call print_one_die if printing. */ if (do_print_dwarf){ /* There is no die if its a set-end entry */ print_one_die(dbg, cu_die, /* print_information= */ (boolean2) TRUE, /* indent_level = */0, /* srcfiles= */ 0, /* cnt= */ 0, /* ignore_die_stack= */TRUE); } /* Reset the state, so we can traverse the debug_info */ seen_CU = FALSE; need_CU_name = TRUE; if (do_print_dwarf) { printf("\n"); } } if (do_print_dwarf) { /* Print current aranges record */ if (segment_entry_size) { printf( "\narange starts at seg,off 0x%" DW_PR_XZEROS DW_PR_DUx ",0x%" DW_PR_XZEROS DW_PR_DUx ", ", segment, (Dwarf_Unsigned)start); } else { printf("\narange starts at 0x%" DW_PR_XZEROS DW_PR_DUx ", ", (Dwarf_Unsigned)start); } printf("length of 0x%" DW_PR_XZEROS DW_PR_DUx ", cu_die_offset = 0x%" DW_PR_XZEROS DW_PR_DUx, length, (Dwarf_Unsigned)cu_die_offset); } if (verbose && do_print_dwarf) { printf(" cuhdr 0x%" DW_PR_XZEROS DW_PR_DUx "\n", (Dwarf_Unsigned)off); } dwarf_dealloc(dbg, cu_die, DW_DLA_DIE); cu_die = 0; } else { /* Must be a range end. We really do want to print this as there is a real record here, an 'arange end' record. */ if (do_print_dwarf) { printf("\narange end"); } }/* end start||length test */ } /* end aires DW_DLV_OK test */ /* print associated die too? */ dwarf_dealloc(dbg, arange_buf[i], DW_DLA_ARANGE); } dwarf_dealloc(dbg, arange_buf, DW_DLA_LIST); } }