Example #1
0
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;
}
Example #2
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);
    }
}
Example #3
0
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);
}