Пример #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
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);
}
Пример #3
0
/* Here we test the interfaces into Dwarf_Line_Context. */
static void
print_line_context_record(Dwarf_Debug dbg,
    Dwarf_Line_Context line_context)
{
    int vres = 0;
    Dwarf_Unsigned lsecoff = 0;
    Dwarf_Unsigned version = 0;
    Dwarf_Signed count = 0;
    Dwarf_Signed i = 0;
    const char *name = 0;
    struct esb_s bufr;
    Dwarf_Small table_count = 0;

    esb_constructor(&bufr);
    printf("Line Context data\n");
    vres = dwarf_srclines_table_offset(line_context,&lsecoff,&err);
    if (vres != DW_DLV_OK) {
        print_error(dbg,"Error accessing line context"
            "Something broken.",
            vres,err);
        return;
    }
    printf(" Line Section Offset 0x%"
        DW_PR_XZEROS DW_PR_DUx "\n", lsecoff);
    vres = dwarf_srclines_version(line_context,&version,
        &table_count, &err);
    if (vres != DW_DLV_OK) {
        print_error(dbg,"Error accessing line context"
            "Something broken.",
            vres,err);
        return;
    }
    printf(" version number      0x%" DW_PR_DUx " %" DW_PR_DUu "\n",
        version,version);
    printf(" number of line tables  %d.\n", table_count);


    vres = dwarf_srclines_comp_dir(line_context,&name,&err);
    if (vres != DW_DLV_OK) {
        print_error(dbg,"Error accessing line context"
            "Something broken.",
            vres,err);
        return;
    }
    if (name) {
        printf(" Compilation directory: %s\n",name);
    } else {
        printf(" Compilation directory: <unknown no DW_AT_comp_dir>\n");
    }

    vres = dwarf_srclines_include_dir_count(line_context,&count,&err);
    if (vres != DW_DLV_OK) {
        print_error(dbg,"Error accessing line context"
            "Something broken.",
            vres,err);
        return;
    }
    printf(" include directory count 0x%"
        DW_PR_DUx " %" DW_PR_DSd "\n",
        (Dwarf_Unsigned)count,count);
    for(i = 1; i <= count; ++i) {
        vres = dwarf_srclines_include_dir_data(line_context,i,
            &name,&err);
        if (vres != DW_DLV_OK) {
            print_error(dbg,"Error accessing line context"
                "Something broken.",
                vres,err);
            return;
        }
        printf("  [%2" DW_PR_DSd "]  \"%s\"\n",i,name);
    }

    vres = dwarf_srclines_files_count(line_context,&count,&err);
    if (vres != DW_DLV_OK) {
        print_error(dbg,"Error accessing line context"
            "Something broken.",
            vres,err);
        return;
    }
    printf( " files count 0x%"
        DW_PR_DUx " %" DW_PR_DUu "\n",
        count,count);
    for(i = 1; i <= count; ++i) {
        Dwarf_Unsigned dirindex = 0;
        Dwarf_Unsigned modtime = 0;
        Dwarf_Unsigned flength = 0;

        vres = dwarf_srclines_files_data(line_context,i,
            &name,&dirindex, &modtime,&flength,&err);
        if (vres != DW_DLV_OK) {
            print_error(dbg,"Error accessing line context"
                "Something broken.",
                vres,err);
            return;
        }
        esb_empty_string(&bufr);
        if (name) {
            esb_empty_string(&bufr);
            esb_append(&bufr,"\"");
            esb_append(&bufr,name);
            esb_append(&bufr,"\"");
        } else {
            esb_append(&bufr,"<ERROR:NULL name in files list>");
        }
        printf("  [%2" DW_PR_DSd "]  %-24s ,",
            i,esb_get_string(&bufr));
        printf(" directory index  %2" DW_PR_DUu ,modtime);
        printf(",  file length %2" DW_PR_DUu ,flength);
        if (modtime) {
            time_t tt3 = (time_t)modtime;

            /* ctime supplies newline */
            printf(
                "file mod time 0x%x %s", (unsigned)tt3, ctime(&tt3));
        } else {
            printf("  file mod time 0\n");
        }
    }
    esb_destructor(&bufr);

    vres = dwarf_srclines_subprog_count(line_context,&count,&err);
    if (vres != DW_DLV_OK) {
        print_error(dbg,"Error accessing line context"
            "Something broken.",
            vres,err);
        return;
    }
    if (count == 0) {
        return;
    }
    printf(" subprograms count (experimental) 0x%"
        DW_PR_DUx " %" DW_PR_DUu "\n",
        count,count);
    for(i = 1; i <= count; ++i) {
        Dwarf_Unsigned decl_file = 0;
        Dwarf_Unsigned decl_line = 0;
        vres = dwarf_srclines_subprog_data(line_context,i,
            &name,&decl_file, &decl_line,&err);
        if (vres != DW_DLV_OK) {
            print_error(dbg,"Error accessing line context"
                "Something broken.",
                vres,err);
            return;
        }
        printf("  [%2" DW_PR_DSd "]  \"%s\""
            ", fileindex %2" DW_PR_DUu
            ", lineindex  %2" DW_PR_DUu
            "\n",
            i,name,decl_file,decl_line);
    }
}
Пример #4
0
int main()
{
    {
        struct esb_s d;
        esb_constructor(&d);
        esb_append(&d,"a");
        validate_esb(1,&d,1,2,"a");
        esb_append(&d,"b");
        validate_esb(2,&d,2,3,"ab");
        esb_append(&d,"c");
        validate_esb(3,&d,3,4,"abc");
        esb_empty_string(&d);
        validate_esb(4,&d,0,4,"");
        esb_destructor(&d);
    }
    {
        struct esb_s d;
        esb_constructor(&d);
        esb_append(&d,"aa");
        validate_esb(6,&d,2,3,"aa");
        esb_append(&d,"bbb");
        validate_esb(7,&d,5,6,"aabbb");
        esb_append(&d,"c");
        validate_esb(8,&d,6,7,"aabbbc");
        esb_empty_string(&d);
        validate_esb(9,&d,0,7,"");
        esb_destructor(&d);
    }
    {
        struct esb_s d;
        static char oddarray[7] = {'a','b',0,'c','c','d',0};
        esb_constructor(&d);
        /* This provokes a msg on stderr. Bad input. */
        esb_appendn(&d,oddarray,6);
        validate_esb(10,&d,2,3,"ab");
        esb_appendn(&d,"cc",1);
        validate_esb(11,&d,3,4,"abc");
        esb_empty_string(&d);
        validate_esb(12,&d,0,4,"");
        esb_destructor(&d);
    }
    {
        struct esb_s d;
        esb_constructor(&d);

        esb_force_allocation(&d,7);
        trialprint(&d);
        validate_esb(13,&d,6,7,"aaaa i");
    }
    {
        struct esb_s d;
        esb_constructor(&d);

        esb_force_allocation(&d,50);
        trialprint(&d);
        validate_esb(14,&d,19,50,"aaaa insert me bbbb");
    }
    if (failcount) {
        printf("FAIL esb test\n");
        exit(1);
    }
    printf("PASS esb test\n");
    exit(0);
}
Пример #5
0
/* print data in .debug_loc 
   There is no guarantee this will work because we are assuming
   that all bytes are valid loclist data, that there are no
   odd padding or garbage bytes.  In normal use one gets
   into here via an offset from .debug_info, so it could be
   that bytes not referenced from .debug_info are garbage
   or even zero padding.  So this can fail (error off) as such bytes
   can lead dwarf_get_loclist_entry() astray.

   It's also wrong because we don't know what CU or frame each
   loclist is from, so we don't know the address_size for sure.
*/
extern void
print_locs(Dwarf_Debug dbg)
{
    Dwarf_Unsigned offset = 0;
    Dwarf_Addr hipc_offset = 0;
    Dwarf_Addr lopc_offset = 0;
    Dwarf_Ptr data = 0;
    Dwarf_Unsigned entry_len = 0;
    Dwarf_Unsigned next_entry = 0;
    struct esb_s  exprstring;
    int index = 0; 
    int lres = 0;
    int fres = 0;

    /* This is sometimes wrong, we need a frame-specific size. */
    Dwarf_Half address_size = 0;

    current_section_id = DEBUG_LOC;

    /* Do nothing if not printing. */
    if (!do_print_dwarf) {
        return;
    }

    fres = dwarf_get_address_size(dbg, &address_size, &err);
    if (fres != DW_DLV_OK) {
        print_error(dbg, "dwarf_get_address_size", fres, err);
    }

    printf("\n.debug_loc");
  
    printf("\nFormat <i o b e l>: "
        "index section-offset begin-addr end-addr length-of-block-entry\n");
    esb_constructor(&exprstring);
    while ((lres = dwarf_get_loclist_entry(dbg, offset,
        &hipc_offset, &lopc_offset,
        &data, &entry_len,
        &next_entry,
        &err)) == DW_DLV_OK) {
        get_string_from_locs(dbg,data,entry_len,address_size,
            &exprstring);
        /* Display offsets */
        if (display_offsets) {
            ++index;
            printf(" <iobel> [%8d] 0x%" DW_PR_XZEROS DW_PR_DUx,
                index, offset);
            if(verbose) {
                printf(" <expr-off 0x%"  DW_PR_XZEROS  DW_PR_DUx ">",
                    next_entry - entry_len);
            }
        }
        printf(" 0x%"  DW_PR_XZEROS  DW_PR_DUx 
            " 0x%" DW_PR_XZEROS DW_PR_DUx  
            " %8" DW_PR_DUu " %s\n",
            (Dwarf_Unsigned) lopc_offset,
            (Dwarf_Unsigned) hipc_offset,  entry_len,
            esb_get_string(&exprstring));
        esb_empty_string(&exprstring);
        offset = next_entry;
    }
    esb_destructor(&exprstring);
    if (lres == DW_DLV_ERROR) {
        print_error(dbg, "dwarf_get_loclist_entry", lres, err);
    }
}
Пример #6
0
/* print data in .debug_loc
   There is no guarantee this will work because we are assuming
   that all bytes are valid loclist data, that there are no
   odd padding or garbage bytes.  In normal use one gets
   into here via an offset from .debug_info, so it could be
   that bytes not referenced from .debug_info are garbage
   or even zero padding.  So this can fail (error off) as such bytes
   can lead dwarf_get_loclist_entry() astray.

   It's also wrong because we don't know what CU or frame each
   loclist is from, so we don't know the address_size for sure.
*/
extern void
print_locs(Dwarf_Debug dbg)
{
    Dwarf_Unsigned offset = 0;
    Dwarf_Addr hipc_offset = 0;
    Dwarf_Addr lopc_offset = 0;
    Dwarf_Ptr data = 0;
    Dwarf_Unsigned entry_len = 0;
    Dwarf_Unsigned next_entry = 0;
    int index = 0;
    int lres = 0;
    int fres = 0;
    Dwarf_Half address_size = 0;
    Dwarf_Half offset_size = 0;
    Dwarf_Half version = 2; /* FAKE */
    Dwarf_Error err = 0;
    struct esb_s  exprstring;
    unsigned loopct = 0;

    esb_constructor(&exprstring);
    glflags.current_section_id = DEBUG_LOC;

    /* Do nothing if not printing. */
    if (!glflags.gf_do_print_dwarf) {
        return;
    }
    if(!glflags.gf_use_old_dwarf_loclist) {
        printf("\n");
        printf("Printing location lists with -c is no longer supported\n");
        return;
    }

    fres = dwarf_get_address_size(dbg, &address_size, &err);
    if (fres != DW_DLV_OK) {
        print_error(dbg, "dwarf_get_address_size", fres, err);
    }
    fres = dwarf_get_offset_size(dbg, &offset_size, &err);
    if (fres != DW_DLV_OK) {
        print_error(dbg, "dwarf_get_address_size", fres, err);
    }
#if 0
    /*  This print code not needed as cannot be safely used
        and uses old interface. */
    {
        struct esb_s truename;
        char buf[DWARF_SECNAME_BUFFER_SIZE];

        esb_constructor_fixed(&truename,buf,sizeof(buf));
        get_true_section_name(dbg,".debug_loc",
            &truename,TRUE);
        printf("\n%s\n",sanitized(esb_get_string(&truename)));
        esb_destructor(&truename);
    }
#endif

    printf("Format <i o b e l>: "
        "index section-offset begin-addr end-addr length-of-block-entry\n");
    /*  Pre=October 2015 version. */
    for (loopct = 0;
        (lres = dwarf_get_loclist_entry(dbg, offset,
        &hipc_offset, &lopc_offset,
        &data, &entry_len,
        &next_entry,
        &err)) == DW_DLV_OK;
        ++loopct) {
        get_string_from_locs(dbg,data,entry_len,address_size,
            offset_size,
            version,
            &exprstring);
        /* Display offsets */
        if (!loopct) {
            /*  This print code not needed as cannot be safely used
                and uses old interface. */
            print_secname(dbg,".debug_loc");
        }
        if (glflags.gf_display_offsets) {
            ++index;
            printf("  <iobel> [%8d] 0x%" DW_PR_XZEROS DW_PR_DUx,
                index, offset);
            if (glflags.verbose) {
                printf(" <expr-off 0x%"  DW_PR_XZEROS  DW_PR_DUx ">",
                    next_entry - entry_len);
            }
        }
        printf(" 0x%"  DW_PR_XZEROS  DW_PR_DUx
            " 0x%" DW_PR_XZEROS DW_PR_DUx
            " %8" DW_PR_DUu " %s\n",
            (Dwarf_Unsigned) lopc_offset,
            (Dwarf_Unsigned) hipc_offset,  entry_len,
            esb_get_string(&exprstring));
        esb_empty_string(&exprstring);
        offset = next_entry;
    }
    if (!loopct) {
        /*  This print code not needed as cannot be safely used
            and uses old interface. */
        print_secname(dbg,".debug_loc");
    }
    esb_destructor(&exprstring);
    if (lres == DW_DLV_ERROR) {
        print_error(dbg, "dwarf_get_loclist_entry", lres, err);
    }
}
Пример #7
0
int main()
{
#ifdef _WIN32
    /* Open the null device used during formatting printing */
    if (!esb_open_null_device())
    {
        fprintf(stderr, "esb: Unable to open null device.\n");
        exit(1);
    }
#endif /* _WIN32 */
    {   /*  First lets establish standard sprintf on
        cases of interest. */
        struct esb_s d5;
        char bufs[4];
        char bufl[60];
        esb_int i = -33;
        esb_unsigned u = 0;

        /* After static alloc we add len, ie, 11 */
        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf(&d5,"aaa %d bbb",(int)i);
        validate_esb(201,&d5,11,15,"aaa -33 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf(&d5,"aaa %6d bbb",(int)i);
        validate_esb(202,&d5,14,18,"aaa    -33 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf(&d5,"aaa %6d bbb",6);
        validate_esb(203,&d5,14,18,"aaa      6 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf(&d5,"aaa %06d bbb",6);
        validate_esb(204,&d5,14,18,"aaa 000006 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf(&d5,"aaa %06u bbb",6);
        validate_esb(205,&d5,14,18,"aaa 000006 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf(&d5,"aaa %6u bbb",6);
        validate_esb(206,&d5,14,18,"aaa      6 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf(&d5,"aaa %u bbb",12);
        validate_esb(207,&d5,10,14,"aaa 12 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf(&d5,"aaa %06x bbb",12);
        validate_esb(208,&d5,14,18,"aaa 00000c bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf(&d5,"aaa %6x bbb",12);
        validate_esb(209,&d5,14,18,"aaa      c bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf(&d5,"aaa %+d bbb",12);
        validate_esb(210,&d5,11,15,"aaa +12 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf(&d5,"aaa %+6d bbb",12);
        validate_esb(211,&d5,14,18,"aaa    +12 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf(&d5,"aaa %6d bbb",(int)i);
        validate_esb(212,&d5,14,18,"aaa    -33 bbb",__LINE__);
        esb_destructor(&d5);



    }


   {
        struct esb_s d;
        esb_constructor(&d);
        esb_append(&d,"a");
        validate_esb(1,&d,1,2,"a",__LINE__);
        esb_append(&d,"b");
        validate_esb(2,&d,2,3,"ab",__LINE__);
        esb_append(&d,"c");
        validate_esb(3,&d,3,4,"abc",__LINE__);
        esb_empty_string(&d);
        validate_esb(4,&d,0,4,"",__LINE__);
        esb_destructor(&d);
    }
    {
        struct esb_s d;

        esb_constructor(&d);
        esb_append(&d,"aa");
        validate_esb(6,&d,2,3,"aa",__LINE__);
        esb_append(&d,"bbb");
        validate_esb(7,&d,5,6,"aabbb",__LINE__);
        esb_append(&d,"c");
        validate_esb(8,&d,6,7,"aabbbc",__LINE__);
        esb_empty_string(&d);
        validate_esb(9,&d,0,7,"",__LINE__);
        esb_destructor(&d);
    }
    {
        struct esb_s d;
        static char oddarray[7] = {'a','b',0,'c','c','d',0};

        esb_constructor(&d);
        /*  This used to provoke a msg on stderr. Bad input.
            Now inserts particular string instead. */
        esb_appendn(&d,oddarray,6);
        validate_esb(10,&d,23,24,"ESBERR_appendn bad call",__LINE__);
        /*  The next one just keeps the previous ESBERR* and adds a 'c' */
        esb_appendn(&d,"cc",1);
        validate_esb(11,&d,24,25,"ESBERR_appendn bad callc",__LINE__);
        esb_empty_string(&d);
        validate_esb(12,&d,0,25,"",__LINE__);
        esb_destructor(&d);
    }
    {
        struct esb_s d;

        esb_constructor(&d);
        esb_force_allocation(&d,7);
        esb_append(&d,"aaaa i");
        validate_esb(13,&d,6,7,"aaaa i",__LINE__);
        esb_destructor(&d);
    }
    {
        struct esb_s d5;
        const char * s = "insert me %d";

        esb_constructor(&d5);
        esb_force_allocation(&d5,50);
        esb_append(&d5,"aaa ");
        esb_append_printf(&d5,s,1);
        esb_append(&d5,"zzz");
        validate_esb(14,&d5,18,50,"aaa insert me 1zzz",__LINE__);
        esb_destructor(&d5);
    }
    {
        struct esb_s d;
        struct esb_s e;
        esb_constructor(&d);
        esb_constructor(&e);

        char* result = NULL;
        esb_append(&d,"abcde fghij klmno pqrst");
        validate_esb(15,&d,23,24,"abcde fghij klmno pqrst",__LINE__);

        result = esb_get_copy(&d);
        esb_append(&e,result);
        validate_esb(16,&e,23,24,"abcde fghij klmno pqrst",__LINE__);
        esb_destructor(&d);
        esb_destructor(&e);
    }
    {
        struct esb_s d5;
        char bufs[4];
        char bufl[60];
        const char * s = "insert me %d";

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append(&d5,"aaa ");
        esb_append_printf(&d5,s,1);
        esb_append(&d5,"zzz");
        validate_esb(17,&d5,18,19,"aaa insert me 1zzz",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufl,sizeof(bufl));
        esb_append(&d5,"aaa ");
        esb_append_printf(&d5,s,1);
        esb_append(&d5,"zzz");
        validate_esb(18,&d5,18,60,"aaa insert me 1zzz",__LINE__);
        esb_destructor(&d5);

    }

    {
        struct esb_s d5;
        char bufs[4];
        char bufl[60];
        const char * s = "insert me";

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_s(&d5,"aaa %s bbb",s);
        validate_esb(19,&d5,17,18,"aaa insert me bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_s(&d5,"aaa %12s bbb",s);
        validate_esb(20,&d5,20,21,"aaa    insert me bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_s(&d5,"aaa %-12s bbb",s);
        validate_esb(21,&d5,20,21,"aaa insert me    bbb",__LINE__);
        esb_destructor(&d5);

    }

    {
        struct esb_s d5;
        char bufs[4];
        char bufl[60];
        esb_int i = -33;
        esb_unsigned u = 0;

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_i(&d5,"aaa %d bbb",i);
        validate_esb(18,&d5,11,12,"aaa -33 bbb",__LINE__);
        esb_destructor(&d5);

        i = -2;
        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_i(&d5,"aaa %4d bbb",i);
        validate_esb(19,&d5,12,13,"aaa   -2 bbb",__LINE__);
        esb_destructor(&d5);

        i = -2;
        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_i(&d5,"aaa %4d bbb",i);
        validate_esb(20,&d5,12,13,"aaa   -2 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_i(&d5,"aaa %6d bbb",i);
        validate_esb(21,&d5,14,15,"aaa     -2 bbb",__LINE__);
        esb_destructor(&d5);

        i = -2;
        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_i(&d5,"aaa %04d bbb",i);
        validate_esb(22,&d5,12,13,"aaa -002 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_i(&d5,"aaa %06d bbb",i);
        validate_esb(23,&d5,14,15,"aaa -00002 bbb",__LINE__);
        esb_destructor(&d5);

        i = -200011;
        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_i(&d5,"aaa %04d bbb",i);
        validate_esb(24,&d5,15,16,"aaa -200011 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_i(&d5,"aaa %06d bbb",i);
        validate_esb(25,&d5,15,16,"aaa -200011 bbb",__LINE__);
        esb_destructor(&d5);




        u = 0x80000000;
        u = 0x8000000000000000;
        i = u;
        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_i(&d5,"aaa %4d bbb",i);
        validate_esb(26,&d5,28,29,"aaa -9223372036854775808 bbb",__LINE__);
        esb_destructor(&d5);

        i = 987665432;
        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_i(&d5,"aaa %4d bbb",i);
        validate_esb(27,&d5,17,18,"aaa 987665432 bbb",__LINE__);
        esb_destructor(&d5);

    }
    {
        struct esb_s d5;
        char bufs[4];
        char bufl[60];
        esb_unsigned u = 0;

        u = 37;
        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_u(&d5,"aaa %u bbb",u);
        validate_esb(28,&d5,10,11,"aaa 37 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_u(&d5,"aaa %4u bbb",u);
        validate_esb(29,&d5,12,13,"aaa   37 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_u(&d5,"aaa %4u bbb",u);
        validate_esb(30,&d5,12,13,"aaa   37 bbb",__LINE__);
        esb_destructor(&d5);

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_u(&d5,"aaa %6u bbb",u);
        validate_esb(31,&d5,14,15,"aaa     37 bbb",__LINE__);
        esb_destructor(&d5);

    }
    {
        struct esb_s d5;
        char bufs[4];
        char bufl[60];
        esb_int i = -33;
        esb_unsigned u = 0;

        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_i(&d5,"aaa %+d bbb",i);
        validate_esb(18,&d5,11,12,"aaa -33 bbb",__LINE__);
        esb_destructor(&d5);

        i = 33;
        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_i(&d5,"aaa %+d bbb",i);
        validate_esb(18,&d5,11,12,"aaa +33 bbb",__LINE__);
        esb_destructor(&d5);

        i = -2;
        esb_constructor_fixed(&d5,bufs,sizeof(bufs));
        esb_append_printf_i(&d5,"aaa %+4d bbb",i);
        validate_esb(19,&d5,12,13,"aaa   -2 bbb",__LINE__);
        esb_destructor(&d5);

    }



#ifdef _WIN32
    /* Close the null device used during formatting printing */
    esb_close_null_device();
#endif /* _WIN32 */
    if (failcount) {
        printf("FAIL esb test\n");
        exit(1);
    }
    printf("PASS esb test\n");
    exit(0);
}