extern void print_line_numbers_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die) { Dwarf_Unsigned lineversion = 0; Dwarf_Signed linecount = 0; Dwarf_Line *linebuf = NULL; Dwarf_Signed linecount_actuals = 0; Dwarf_Line *linebuf_actuals = NULL; Dwarf_Small table_count = 0; int lres = 0; int line_errs = 0; Dwarf_Line_Context line_context = 0; const char *sec_name = 0; current_section_id = DEBUG_LINE; /* line_flag is TRUE */ lres = dwarf_get_line_section_name_from_die(cu_die, &sec_name,&err); if (lres != DW_DLV_OK || !sec_name || !strlen(sec_name)) { sec_name = ".debug_line"; } if (do_print_dwarf) { printf("\n%s: line number info for a single cu\n", sec_name); } else { /* We are checking, not printing. */ Dwarf_Half tag = 0; int tres = dwarf_tag(cu_die, &tag, &err); if (tres != DW_DLV_OK) { /* Something broken here. */ print_error(dbg,"Unable to see CU DIE tag " "though we could see it earlier. Something broken.", tres,err); return; } else if (tag == DW_TAG_type_unit) { /* Not checking since type units missing address or range in CU header. */ return; } } if (verbose > 1) { int errcount = 0; print_source_intro(cu_die); print_one_die(dbg, cu_die, /* print_information= */ 1, /* indent level */0, /* srcfiles= */ 0, /* cnt= */ 0, /* ignore_die_stack= */TRUE); DWARF_CHECK_COUNT(lines_result,1); lres = dwarf_print_lines(cu_die, &err,&errcount); if (errcount > 0) { DWARF_ERROR_COUNT(lines_result,errcount); DWARF_CHECK_COUNT(lines_result,(errcount-1)); } if (lres == DW_DLV_ERROR) { print_error(dbg, "dwarf_srclines details", lres, err); } return; } if (check_lines && checking_this_compiler()) { DWARF_CHECK_COUNT(lines_result,1); dwarf_check_lineheader(cu_die,&line_errs); if (line_errs > 0) { DWARF_CHECK_ERROR_PRINT_CU(); DWARF_ERROR_COUNT(lines_result,line_errs); DWARF_CHECK_COUNT(lines_result,(line_errs-1)); } } /* The following is complicated by a desire to test various line table interface functions. Hence we test line_flag_selection. Normal code should pick an interface (for most the best choice is what we here call line_flag_selection == std) and use just that interface set. Sorry about the length of the code that results from having so many interfaces. */ if (line_flag_selection == std) { lres = dwarf_srclines_b(cu_die,&lineversion, &table_count,&line_context, &err); if(lres == DW_DLV_OK) { lres = dwarf_srclines_from_linecontext(line_context, &linebuf, &linecount,&err); } } else if (line_flag_selection == orig) { /* DWARF2,3,4, ok for 5. */ /* Useless for experimental line tables */ lres = dwarf_srclines(cu_die, &linebuf, &linecount, &err); if(lres == DW_DLV_OK && linecount ){ table_count++; } } else if (line_flag_selection == orig2l) { lres = dwarf_srclines_two_level(cu_die, &lineversion, &linebuf, &linecount, &linebuf_actuals, &linecount_actuals, &err); if(lres == DW_DLV_OK && linecount){ table_count++; } if(lres == DW_DLV_OK && linecount_actuals){ table_count++; } } else if (line_flag_selection == s2l) { lres = dwarf_srclines_b(cu_die,&lineversion, &table_count,&line_context, &err); if(lres == DW_DLV_OK) { lres = dwarf_srclines_two_level_from_linecontext(line_context, &linebuf, &linecount, &linebuf_actuals, &linecount_actuals, &err); } } if (lres == DW_DLV_ERROR) { /* Do not terminate processing */ if (check_decl_file) { DWARF_CHECK_COUNT(decl_file_result,1); DWARF_CHECK_ERROR2(decl_file_result,"dwarf_srclines", dwarf_errmsg(err)); record_dwarf_error = FALSE; /* Clear error condition */ } else { print_error(dbg, "dwarf_srclines", lres, err); } } else if (lres == DW_DLV_NO_ENTRY) { /* no line information is included */ } else if (table_count > 0) { /* DW_DLV_OK */ if(line_context && verbose) { print_line_context_record(dbg,line_context); } if (do_print_dwarf) { print_source_intro(cu_die); if (verbose) { print_one_die(dbg, cu_die, /* print_information= */ TRUE, /* indent_level= */ 0, /* srcfiles= */ 0, /* cnt= */ 0, /* ignore_die_stack= */TRUE); } } if(line_flag_selection == std || line_flag_selection == s2l) { if (table_count == 0 || table_count == 1) { /* ASSERT: is_single_table == true */ Dwarf_Bool is_logicals = FALSE; Dwarf_Bool is_actuals = FALSE; process_line_table(dbg,sec_name, linebuf, linecount, is_logicals,is_actuals); } else { Dwarf_Bool is_logicals = TRUE; Dwarf_Bool is_actuals = FALSE; process_line_table(dbg,sec_name, linebuf, linecount, is_logicals, is_actuals); process_line_table(dbg,sec_name, linebuf_actuals, linecount_actuals, !is_logicals, !is_actuals); } dwarf_srclines_dealloc_b(line_context); } else if (line_flag_selection == orig) { Dwarf_Bool is_logicals = FALSE; Dwarf_Bool is_actuals = FALSE; process_line_table(dbg,sec_name, linebuf, linecount, is_logicals, is_actuals); dwarf_srclines_dealloc(dbg,linebuf,linecount); } else if (line_flag_selection == orig2l) { if (table_count == 1 || table_count == 0) { Dwarf_Bool is_logicals = FALSE; Dwarf_Bool is_actuals = FALSE; process_line_table(dbg,sec_name, linebuf, linecount, is_logicals, is_actuals); } else { Dwarf_Bool is_logicals = TRUE; Dwarf_Bool is_actuals = FALSE; process_line_table(dbg,sec_name, linebuf, linecount, is_logicals, is_actuals); process_line_table(dbg,sec_name, linebuf_actuals, linecount_actuals, !is_logicals, !is_actuals); } dwarf_srclines_dealloc(dbg,linebuf,linecount); } /* end, table_count > 0 */ } else { /* DW_DLV_OK */ /* table_count == 0. no lines in table. Just a line table header. */ if (do_print_dwarf) { int ores = 0; Dwarf_Unsigned off = 0; print_source_intro(cu_die); if (verbose) { print_one_die(dbg, cu_die, /* print_information= */ TRUE, /* indent_level= */ 0, /* srcfiles= */ 0, /* cnt= */ 0, /* ignore_die_stack= */TRUE); } if(line_context) { if (verbose > 2) { print_line_context_record(dbg,line_context); } ores = dwarf_srclines_table_offset(line_context, &off,&err); if (ores != DW_DLV_OK) { print_error(dbg,"dwarf_srclines_table_offset fail",ores,err); } else { printf(" Line table is present (offset 0x%" DW_PR_XZEROS DW_PR_DUx ") but no lines present\n", off); } } else { printf(" Line table is present but no lines present\n"); } } if(line_flag_selection == std || line_flag_selection == s2l) { dwarf_srclines_dealloc_b(line_context); } else { /* Original allocation. */ dwarf_srclines_dealloc(dbg,linebuf,linecount); } /* end, linecounttotal == 0 */ } }
/* 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); } }