示例#1
0
/* 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() */
示例#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);
    }
}