Exemple #1
0
static const char *
ellipname(int res, int val_in, const char *v,const char *ty,int printonerr)
{
#ifndef TRIVIAL_NAMING
    if (glflags.gf_check_dwarf_constants && checking_this_compiler()) {
        DWARF_CHECK_COUNT(dwarf_constants_result,1);
    }
#endif
    if (res != DW_DLV_OK) {
        char buf[100];
        char *n;
#ifdef ORIGINAL_SPRINTF
        snprintf(buf,sizeof(buf),"<Unknown %s value 0x%x>",ty,val_in);
#else
        struct esb_s eb;

        esb_constructor_fixed(&eb,buf,sizeof(buf));
        esb_append_printf_s(&eb,
            "<Unknown %s",ty);
        esb_append_printf_u(&eb,
            " value 0x%x>",val_in);
#endif
        /* Capture any name error in DWARF constants */
#ifndef TRIVIAL_NAMING
        if (printonerr && glflags.gf_check_dwarf_constants &&
            checking_this_compiler()) {
            if (glflags.gf_check_verbose_mode) {
                fprintf(stderr,"%s of %d (0x%x) is unknown to dwarfdump. "
                    "Continuing. \n",ty,val_in,val_in );
            }
            DWARF_ERROR_COUNT(dwarf_constants_result,1);
            DWARF_CHECK_ERROR_PRINT_CU();
        }
#else
        /* This is for the tree-generation, not dwarfdump itself. */
        if (printonerr) {
            fprintf(stderr,"%s of %d (0x%x) is unknown to dwarfdump. "
                "Continuing. \n",ty,val_in,val_in );
        }
#endif

#ifdef ORIGINAL_SPRINTF
        n = makename(buf);
#else
        n = makename(esb_get_string(&eb));
        esb_destructor(&eb);
#endif
        return n;
    }
#ifndef TRIVIAL_NAMING
    if (glflags.ellipsis) {
        return skipunder(v);
    }
#endif
    return v;
}
Exemple #2
0
static void
record_line_error(const char *where, Dwarf_Error err)
{
    char tmp_buff[500];
    if (check_lines && checking_this_compiler()) {
        snprintf(tmp_buff, sizeof(tmp_buff),
            "Error getting line details calling %s dwarf error is %s",
            where,dwarf_errmsg(err));
        DWARF_CHECK_ERROR(lines_result,tmp_buff);
    }
}
Exemple #3
0
static const char *
ellipname(int res, int val_in, const char *v,const char *ty,int printonerr)
{
#ifndef TRIVIAL_NAMING
    if (check_dwarf_constants && checking_this_compiler()) {
        DWARF_CHECK_COUNT(dwarf_constants_result,1);
    }
#endif
    if(res != DW_DLV_OK) {
        char buf[100];
        char *n;
        snprintf(buf,sizeof(buf),"<Unknown %s value 0x%x>",ty,val_in);
        /* Capture any name error in DWARF constants */
#ifndef TRIVIAL_NAMING
        if(printonerr && check_dwarf_constants && checking_this_compiler()) {
            if (check_verbose_mode) {
                fprintf(stderr,"%s of %d (0x%x) is unknown to dwarfdump. "
                    "Continuing. \n",ty,val_in,val_in );
            }
            DWARF_ERROR_COUNT(dwarf_constants_result,1);
            DWARF_CHECK_ERROR_PRINT_CU();
        }
#else
        /* This is for the tree-generation, not dwarfdump itself. */
        if(printonerr) {
            fprintf(stderr,"%s of %d (0x%x) is unknown to dwarfdump. "
                "Continuing. \n",ty,val_in,val_in );
        }
#endif
        n = makename(buf);
        return n;
    }
    if(ellipsis) {
        return skipunder(v);
    }
    return v;
}
Exemple #4
0
static void
process_line_table(Dwarf_Debug dbg,
    const char *sec_name,
    Dwarf_Line *linebuf, Dwarf_Signed linecount,
    Dwarf_Bool is_logicals_table, Dwarf_Bool is_actuals_table)
{
    char *padding = 0;
    Dwarf_Signed i = 0;
    Dwarf_Addr pc = 0;
    Dwarf_Unsigned lineno = 0;
    Dwarf_Unsigned logicalno = 0;
    Dwarf_Unsigned column = 0;
    Dwarf_Unsigned call_context = 0;
    string subprog_name = 0;
    string subprog_filename = 0;
    Dwarf_Unsigned subprog_line = 0;

    Dwarf_Error err = 0;

    Dwarf_Bool newstatement = 0;
    Dwarf_Bool lineendsequence = 0;
    Dwarf_Bool new_basic_block = 0;
    int sres = 0;
    int ares = 0;
    int lires = 0;
    int cores = 0;
    Dwarf_Addr elf_max_address = 0;

    Dwarf_Bool SkipRecord = FALSE;

    current_section_id = DEBUG_LINE;
    struct esb_s lastsrc;

    /* line_flag is TRUE */
    esb_constructor(&lastsrc);

    get_address_size_and_max(dbg,0,&elf_max_address,&err);
    /* Padding for a nice layout */
    padding = line_print_pc ? "            " : "";
    if (do_print_dwarf) {
        /* Check if print of <pc> address is needed. */
        printf("\n");
        if (is_logicals_table) {
            printf("Logicals Table:\n");
            printf("%sNS new statement, PE prologue end, "
                "EB epilogue begin\n",padding);
            printf("%sDI=val discriminator value\n",
                padding);
            printf("%sCC=val context, SB=val subprogram\n",
                padding);
        } else if (is_actuals_table) {
            printf("Actuals Table:\n");
            printf("%sBB new basic block, ET end of text sequence\n"
                "%sIS=val ISA number\n",padding,padding);

        } else {
            /* Standard DWARF line table. */
            printf("%sNS new statement, BB new basic block, "
                "ET end of text sequence\n",padding);
            printf("%sPE prologue end, EB epilogue begin\n",padding);
            printf("%sIS=val ISA number, DI=val discriminator value\n",
                padding);
        }
        if (is_logicals_table || is_actuals_table) {
            printf("[ row]  ");
        }
        if (line_print_pc) {
            printf("<pc>        ");
        }
        if (is_logicals_table) {
            printf("[lno,col] NS PE EB DI= CC= SB= uri: \"filepath\"\n");
        } else if (is_actuals_table) {
            printf("[logical] BB ET IS=\n");
        } else {
            printf("[row,col] NS BB ET PE EB IS= DI= uri: \"filepath\"\n");
        }
    }
    for (i = 0; i < linecount; i++) {
        Dwarf_Line line = linebuf[i];
        string filename = 0;
        int nsres = 0;
        Dwarf_Bool found_line_error = FALSE;
        Dwarf_Bool has_is_addr_set = FALSE;
        char *where = NULL;

        if (check_decl_file && checking_this_compiler()) {
            /* A line record with addr=0 was detected */
            if (SkipRecord) {
                /* Skip records that do not have ís_addr_set' */
                ares = dwarf_line_is_addr_set(line, &has_is_addr_set, &err);
                if (ares == DW_DLV_OK && has_is_addr_set) {
                    SkipRecord = FALSE;
                }
                else {
                    /*  Keep ignoring records until we have
                        one with 'is_addr_set' */
                    continue;
                }
            }
        }

        if (check_lines && checking_this_compiler()) {
            DWARF_CHECK_COUNT(lines_result,1);
        }

        filename = "<unknown>";
        if (!is_actuals_table) {
            sres = dwarf_linesrc(line, &filename, &err);
            if (sres == DW_DLV_ERROR) {
                /* Do not terminate processing */
                where = "dwarf_linesrc()";
                record_line_error(where,err);
                found_line_error = TRUE;
            }
        }

        pc = 0;
        ares = dwarf_lineaddr(line, &pc, &err);

        if (ares == DW_DLV_ERROR) {
            /* Do not terminate processing */
            where = "dwarf_lineaddr()";
            record_line_error(where,err);
            found_line_error = TRUE;
            pc = 0;
        }
        if (ares == DW_DLV_NO_ENTRY) {
            pc = 0;
        }

        if (is_actuals_table) {
            lires = dwarf_linelogical(line, &logicalno, &err);
            if (lires == DW_DLV_ERROR) {
                /* Do not terminate processing */
                where = "dwarf_linelogical()";
                record_line_error(where,err);
                found_line_error = TRUE;
            }
            if (lires == DW_DLV_NO_ENTRY) {
                logicalno = -1LL;
            }
            column = 0;
        } else {
            lires = dwarf_lineno(line, &lineno, &err);
            if (lires == DW_DLV_ERROR) {
                /* Do not terminate processing */
                where = "dwarf_lineno()";
                record_line_error(where,err);
                found_line_error = TRUE;
            }
            if (lires == DW_DLV_NO_ENTRY) {
                lineno = -1LL;
            }
            cores = dwarf_lineoff_b(line, &column, &err);
            if (cores == DW_DLV_ERROR) {
                /* Do not terminate processing */
                where = "dwarf_lineoff()";
                record_line_error(where,err);
                found_line_error = TRUE;
            }
            if (cores == DW_DLV_NO_ENTRY) {
                /*  Zero was always the correct default, meaning
                    the left edge. DWARF2/3/4 spec sec 6.2.2 */
                column = 0;
            }
        }

        /*  Process any possible error condition, though
            we won't be at the first such error. */
        if (check_decl_file && checking_this_compiler()) {
            DWARF_CHECK_COUNT(decl_file_result,1);
            if (found_line_error) {
                DWARF_CHECK_ERROR2(decl_file_result,where,dwarf_errmsg(err));
            } else if (do_check_dwarf) {
                /*  Check the address lies with a valid [lowPC:highPC]
                    in the .text section*/
                if (IsValidInBucketGroup(pRangesInfo,pc)) {
                    /* Valid values; do nothing */
                } else {
                    /*  At this point may be we are dealing with
                        a linkonce symbol. The problem we have here
                        is we have consumed the deug_info section
                        and we are dealing just with the records
                        from the .debug_line, so no PU_name is
                        available and no high_pc. Traverse the linkonce
                        table if try to match the pc value with
                        one of those ranges.
                    */
                    if (check_lines && checking_this_compiler()) {
                        DWARF_CHECK_COUNT(lines_result,1);
                    }
                    if (FindAddressInBucketGroup(pLinkonceInfo,pc)){
                        /* Valid values; do nothing */
                    } else {
                        /*  The SN Systems Linker generates
                            line records
                            with addr=0, when dealing with linkonce
                            symbols and no stripping */
                        if (pc) {
                            char addr_tmp[100];
                            if (check_lines && checking_this_compiler()) {
                                snprintf(addr_tmp,sizeof(addr_tmp),
                                    "%s: Address"
                                    " 0x%" DW_PR_XZEROS DW_PR_DUx
                                    " outside a valid .text range",
                                    sec_name,pc);
                                DWARF_CHECK_ERROR(lines_result,
                                    addr_tmp);
                            }
                        } else {
                            SkipRecord = TRUE;
                        }
                    }
                }
                /*  Check the last record for the .debug_line,
                    the one created by DW_LNE_end_sequence,
                    is the same as the high_pc
                    address for the last known user program
                    unit (PU) */
                if ((i + 1 == linecount) &&
                    seen_PU_high_address &&
                    !is_logicals_table) {
                    /*  Ignore those PU that have been stripped
                        by the linker; their low_pc values are
                        set to -1 (snc linker only) */
                    /*  It is perfectly sensible for a compiler
                        to leave a few bytes of NOP or other stuff
                        after the last instruction in a subprogram,
                        for cache-alignment or other purposes, so
                        a mismatch here is not necessarily
                        an error.  */

                    if (check_lines && checking_this_compiler()) {
                        DWARF_CHECK_COUNT(lines_result,1);
                        if ((pc != PU_high_address) &&
                            (PU_base_address != elf_max_address)) {
                            char addr_tmp[100];
                            snprintf(addr_tmp,sizeof(addr_tmp),
                                "%s: Address"
                                " 0x%" DW_PR_XZEROS DW_PR_DUx
                                " may be incorrect"
                                " as DW_LNE_end_sequence address",
                                sec_name,pc);
                            DWARF_CHECK_ERROR(lines_result,
                                addr_tmp);
                        }
                    }
                }
            }
        }

        /* Display the error information */
        if (found_line_error || record_dwarf_error) {
            if (check_verbose_mode && PRINTING_UNIQUE) {
                /* Print the record number for better error description */
                printf("Record = %"  DW_PR_DUu
                    " Addr = 0x%" DW_PR_XZEROS DW_PR_DUx
                    " [%4" DW_PR_DUu ",%2" DW_PR_DUu "] '%s'\n",
                    i, pc,lineno,column,filename);
                /* The compilation unit was already printed */
                if (!check_decl_file) {
                    PRINT_CU_INFO();
                }
            }
            record_dwarf_error = FALSE;
            /* Due to a fatal error, skip current record */
            if (found_line_error) {
                continue;
            }
        }
        if (do_print_dwarf) {
            if (is_logicals_table || is_actuals_table) {
                printf("[%4" DW_PR_DUu "]  ", i + 1);
            }
            /* Check if print of <pc> address is needed. */
            if (line_print_pc) {
                printf("0x%" DW_PR_XZEROS DW_PR_DUx "  ", pc);
            }
            if (is_actuals_table) {
                printf("[%7" DW_PR_DUu "]", logicalno);
            } else {
                printf("[%4" DW_PR_DUu ",%2" DW_PR_DUu "]", lineno, column);
            }
        }

        if (!is_actuals_table) {
            nsres = dwarf_linebeginstatement(line, &newstatement, &err);
            if (nsres == DW_DLV_OK) {
                if (newstatement && do_print_dwarf) {
                    printf(" %s","NS");
                }
            } else if (nsres == DW_DLV_ERROR) {
                print_error(dbg, "linebeginstatment failed", nsres, err);
            }
        }

        if (!is_logicals_table) {
            nsres = dwarf_lineblock(line, &new_basic_block, &err);
            if (nsres == DW_DLV_OK) {
                if (new_basic_block && do_print_dwarf) {
                    printf(" %s","BB");
                }
            } else if (nsres == DW_DLV_ERROR) {
                print_error(dbg, "lineblock failed", nsres, err);
            }
            nsres = dwarf_lineendsequence(line, &lineendsequence, &err);
            if (nsres == DW_DLV_OK) {
                if (lineendsequence && do_print_dwarf) {
                    printf(" %s", "ET");
                }
            } else if (nsres == DW_DLV_ERROR) {
                print_error(dbg, "lineendsequence failed", nsres, err);
            }
        }

        if (do_print_dwarf) {
            Dwarf_Bool prologue_end = 0;
            Dwarf_Bool epilogue_begin = 0;
            Dwarf_Unsigned isa = 0;
            Dwarf_Unsigned discriminator = 0;
            int disres = dwarf_prologue_end_etc(line,
                &prologue_end,&epilogue_begin,
                &isa,&discriminator,&err);
            if (disres == DW_DLV_ERROR) {
                print_error(dbg, "dwarf_prologue_end_etc() failed",
                    disres, err);
            }
            if (prologue_end && !is_actuals_table) {
                printf(" PE");
            }
            if (epilogue_begin && !is_actuals_table) {
                printf(" EB");
            }
            if (isa && !is_logicals_table) {
                printf(" IS=0x%" DW_PR_DUx, isa);
            }
            if (discriminator && !is_actuals_table) {
                printf(" DI=0x%" DW_PR_DUx, discriminator);
            }
            if (is_logicals_table) {
                call_context = 0;
                disres = dwarf_linecontext(line, &call_context, &err);
                if (disres == DW_DLV_ERROR) {
                    print_error(dbg, "dwarf_linecontext() failed",
                        disres, err);
                }
                if (call_context) {
                    printf(" CC=%" DW_PR_DUu, call_context);
                }
                subprog_name = 0;
                disres = dwarf_line_subprog(line, &subprog_name,
                    &subprog_filename, &subprog_line, &err);
                if (disres == DW_DLV_ERROR) {
                    print_error(dbg, "dwarf_line_subprog() failed",
                        disres, err);
                }
                if (subprog_name && strlen(subprog_name)) {
                    /*  We do not print an empty name.
                        Clutters things up. */
                    printf(" SB=\"%s\"", subprog_name);
                }
            }
        }

        if (!is_actuals_table) {
            if (i > 0 &&  verbose < 3  &&
                strcmp(filename,esb_get_string(&lastsrc)) == 0) {
                /* Do not print name. */
            } else {
                struct esb_s urs;
                esb_constructor(&urs);
                esb_append(&urs, " uri: \"");
                translate_to_uri(filename,&urs);
                esb_append(&urs,"\"");
                if (do_print_dwarf) {
                    printf("%s",esb_get_string(&urs));
                }
                esb_destructor(&urs);
                esb_empty_string(&lastsrc);
                esb_append(&lastsrc,filename);
            }
            if (sres == DW_DLV_OK) {
                dwarf_dealloc(dbg, filename, DW_DLA_STRING);
            }
        }

        if (do_print_dwarf) {
            printf("\n");
        }
    }
    esb_destructor(&lastsrc);
}
Exemple #5
0
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_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() */
Exemple #7
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);
    }
}