示例#1
0
/* Because we do not know what DIE is involved, if the
   object being printed has different address sizes 
   in different compilation units this will not work
   properly: anything could happen. */
extern void
print_ranges(Dwarf_Debug dbg)
{
    Dwarf_Unsigned off = 0;
    int group_number = 0;
    int wasdense = 0;

    current_section_id = DEBUG_RANGES;
    if (!do_print_dwarf) {
        return;
    }
    printf("\n.debug_ranges\n");

    /*  Turn off dense, we do not want  print_ranges_list_to_extra
        to use dense form here. */
    wasdense = dense;
    dense = 0;
    for(;;) {
        Dwarf_Ranges *rangeset = 0;
        Dwarf_Signed rangecount = 0;
        Dwarf_Unsigned bytecount = 0;

        /*  We do not know what DIE is involved, we use
            the older call here. */
        int rres = dwarf_get_ranges(dbg,off,&rangeset,
            &rangecount,&bytecount,&err);
        if(rres == DW_DLV_OK) {
            char *val = 0;
            printf(" Ranges group %d:\n",group_number);
            esb_empty_string(&esb_string);
            print_ranges_list_to_extra(dbg,off,
                rangeset,rangecount,bytecount,
                &esb_string);
            dwarf_ranges_dealloc(dbg,rangeset,rangecount);
            val = esb_get_string(&esb_string);
            printf("%s",val);
            ++group_number;
        } else if (rres == DW_DLV_NO_ENTRY) {
            printf("End of .debug_ranges.\n");
            break;
        } else { 
            /*  ERROR, which does not quite mean a real error,
                as we might just be misaligned reading things without
                a DW_AT_ranges offset.*/
            printf("End of .debug_ranges..\n");
            break;
        }
        off += bytecount;
    }
    dense = wasdense;
}
示例#2
0
/*  Extracted this from print_range_attribute() to isolate the check of
    the range list.
*/
static void
check_ranges_list(Dwarf_Debug dbg,
    Dwarf_Off die_off,
    Dwarf_Die cu_die,
    Dwarf_Unsigned original_off,
    Dwarf_Ranges *rangeset,
    Dwarf_Signed rangecount,
    Dwarf_Unsigned bytecount)
{
    Dwarf_Unsigned off = original_off;

    Dwarf_Signed index = 0;
    Dwarf_Addr base_address = CU_base_address;
    Dwarf_Addr lopc = 0;
    Dwarf_Addr hipc = 0;
    Dwarf_Bool bError = FALSE;

    static boolean do_print = TRUE;
#if 0
{
/* START -> Just for debugging */
struct esb_s rangesstr;
esb_constructor(&rangesstr);
printf("\n**** START ****\n");
printf("\tGLB_OFF: (0x%" DW_PR_XZEROS DW_PR_DUx ") ",die_off);
printf("\tRGN_OFF: (0x%" DW_PR_XZEROS DW_PR_DUx ")\n",original_off);
print_ranges_list_to_extra(dbg,original_off,
    rangeset,rangecount,bytecount,
    &rangesstr);
printf("%s\n", esb_get_string(&rangesstr));
printf("**** END ****\n");
/* END <- Just for debugging */
}
#endif /* 0 */

    /* Ignore last entry, is the end-of-list */
    for (index = 0; index < rangecount - 1; index++) {
        Dwarf_Ranges *r = rangeset + index;

        if (r->dwr_addr1 == elf_max_address) {
            /* (0xffffffff,addr), use specific address (current PU address) */
            base_address = r->dwr_addr2;
        } else {
            /* (offset,offset), update using CU address */
            lopc = r->dwr_addr1 + base_address;
            hipc = r->dwr_addr2 + base_address;
            DWARF_CHECK_COUNT(ranges_result,1);

            /*  Check the low_pc and high_pc
                are within a valid range in
                the .text section */
            if (IsValidInBucketGroup(pRangesInfo,lopc) &&
                IsValidInBucketGroup(pRangesInfo,hipc)) {
                /* Valid values; do nothing */
            } else {
                /*  At this point may be we
                    are dealing with a
                    linkonce symbol */
                if (IsValidInLinkonce(pLinkonceInfo,
                    PU_name,lopc,hipc)) {
                    /* Valid values; do nothing */
                } else {
                    bError = TRUE;
                    DWARF_CHECK_ERROR(ranges_result,
                        ".debug_ranges: Address outside a "
                        "valid .text range");
                    if (check_verbose_mode && do_print) {
                        /*  Update DIEs offset just for printing */
                        int res = dwarf_die_offsets(cu_die,
                            &DIE_overall_offset,&DIE_offset,&err);
                        if (res != DW_DLV_OK) {
                            print_error(dbg, "dwarf_die_offsets",res,err);
                        }
                        printf(
                            "Offset = 0x%" DW_PR_XZEROS DW_PR_DUx
                            ", Base = 0x%" DW_PR_XZEROS DW_PR_DUx
                            ", "
                            "Low = 0x%" DW_PR_XZEROS DW_PR_DUx
                            " (0x%" DW_PR_XZEROS  DW_PR_DUx
                            "), High = 0x%"
                            DW_PR_XZEROS  DW_PR_DUx
                            " (0x%" DW_PR_XZEROS DW_PR_DUx
                            ")\n",
                            off,base_address,lopc,
                            r->dwr_addr1,hipc,
                            r->dwr_addr2);
                    }
                }
            }
        }
        /*  Each entry holds 2 addresses (offsets) */
        off += elf_address_size * 2;
    }

    /*  In the case of errors, we have to print the range records that
        caused the error. */
    if (bError && check_verbose_mode && do_print) {
        struct esb_s rangesstr;
        esb_constructor(&rangesstr);

        printf("\n");
        print_ranges_list_to_extra(dbg,original_off,
            rangeset,rangecount,bytecount,
            &rangesstr);
        printf("%s\n", esb_get_string(&rangesstr));
    }

    /*  In the case of printing unique errors, stop the printing of any
        subsequent errors, which have the same text. */
    if (bError && check_verbose_mode && print_unique_errors) {
        do_print = FALSE;
    }
}