Пример #1
0
/*  The string is freed, contents of *data set to zeroes. */
void esb_destructor(struct esb_s *data)
{
	if (data->esb_string) {
		free(data->esb_string);
	}
	esb_constructor(data);
}
Пример #2
0
static void
mytest(char *in,char *expected,int testnum)
{
    struct esb_s out;
    esb_constructor(&out);
    translate_to_uri(in, &out);
    if (strcmp(expected, esb_get_string(&out))) {
        printf(" Fail test %d expected %s got %s\n",testnum,expected,esb_get_string(&out));
        ++errcnt;
    }
    esb_destructor(&out);
}
Пример #3
0
static void
mytestfrom(const char * in,const char *expected,int testnum)
{
    struct esb_s out;
    esb_constructor(&out);
    translate_from_uri(in, &out);
    if (strcmp(expected, esb_get_string(&out))) {
        printf(" Fail test %d expected \"%s\" got \"%s\"\n",
            testnum,expected,esb_get_string(&out));
        ++errcnt;
    }
    esb_destructor(&out);
}
Пример #4
0
int
main(void)
{
    struct esb_s data;


    esb_alloc_size(2);          /* small to get all code paths tested. */
    esb_constructor(&data);

    esb_append(&data, "a");
    esb_appendn(&data, "bc", 1);
    esb_append(&data, "d");
    esb_append(&data, "e");
    check("test 1", &data, "abde");

    esb_destructor(&data);
    esb_constructor(&data);

    esb_append(&data, "abcdefghij" "0123456789");
    check("test 2", &data, "abcdefghij" "0123456789");

    esb_destructor(&data);
    esb_constructor(&data);
    esb_append(&data, "abcdefghij" "0123456789");

    esb_append(&data, "abcdefghij" "0123456789");

    esb_append(&data, "abcdefghij" "0123456789");

    esb_append(&data, "abcdefghij" "0123456789");
    check("test 3", &data, "abcdefghij"
        "0123456789"
        "abcdefghij"
        "0123456789"
        "abcdefghij" "0123456789" "abcdefghij" "0123456789");
    esb_destructor(&data);
    return 0;
}
Пример #5
0
/* Unified pubnames style output.
   The error checking here against maxoff may be useless
   (in that libdwarf may return an error if the offset is bad
   and we will not get called here).
   But we leave it in nonetheless as it looks sensible.
   In at least one gigantic executable such offsets turned out wrong.
*/
void
print_pubname_style_entry(Dwarf_Debug dbg,
   char *line_title,
   char *name,
   Dwarf_Unsigned die_off,
   Dwarf_Unsigned cu_off,
   Dwarf_Unsigned global_cu_offset,
   Dwarf_Unsigned maxoff)
{
    Dwarf_Die die = NULL;
    Dwarf_Off die_CU_off = 0;
    int dres = 0;
    int ddres = 0;
    int cudres = 0;
    char tmp_buf[100];

    /* get die at die_off */
    dres = dwarf_offdie(dbg, die_off, &die, &err);
    if (dres != DW_DLV_OK) {
        struct esb_s details;
        esb_constructor(&details);
        esb_append(&details,line_title);
        esb_append(&details," dwarf_offdie : "
            "die offset does not reference valid DIE.  ");
        snprintf(tmp_buf,sizeof(tmp_buf),"0x%"  DW_PR_DUx, die_off);
        esb_append(&details,tmp_buf);
        esb_append(&details,".");
        print_error(dbg, esb_get_string(&details), dres, err);
        esb_destructor(&details);
    }

    /* get offset of die from its cu-header */
    ddres = dwarf_die_CU_offset(die, &die_CU_off, &err);
    if (ddres != DW_DLV_OK) {
        struct esb_s details;
        esb_constructor(&details);
        esb_append(&details,line_title);
        esb_append(&details," cannot get CU die offset");
        print_error(dbg, esb_get_string(&details), dres, err);
        esb_destructor(&details);
        die_CU_off = 0;
    }

    /* Get die at offset cu_off to check its existence. */
    {
        Dwarf_Die cu_die = NULL;
        cudres = dwarf_offdie(dbg, cu_off, &cu_die, &err);
        if (cudres != DW_DLV_OK) {
            struct esb_s details;
            esb_constructor(&details);
            esb_append(&details,line_title);
            esb_append(&details," dwarf_offdie: "
                "cu die offset  does not reference valid CU DIE.  ");
            snprintf(tmp_buf,sizeof(tmp_buf),"0x%"  DW_PR_DUx, cu_off);
            esb_append(&details,tmp_buf);
            esb_append(&details,".");
            print_error(dbg, esb_get_string(&details), dres, err);
            esb_destructor(&details);
        } else {
            /* It exists, all is well. */
            dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
        }
    }
    /* Display offsets */
    if (display_offsets) {
        /* Print 'name'at the end for better layout */
        printf("%s die-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx
            ", cu-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx ","
            " die-in-cu 0x%" DW_PR_XZEROS DW_PR_DUx
            ", cu-header-in-sect 0x%" DW_PR_XZEROS DW_PR_DUx ,
            line_title,
            die_off, cu_off,
            (Dwarf_Unsigned) die_CU_off,
            /*  Following is absolute offset of the ** beginning of the
                cu */
            (Dwarf_Signed) (die_off - die_CU_off));
    }

    if ((die_off - die_CU_off) != global_cu_offset) {
        printf(" error: real cuhdr 0x%" DW_PR_XZEROS DW_PR_DUx,
            global_cu_offset);
        exit(1);
    }

    /* Display offsets */
    if (display_offsets && verbose) {
        printf(" cuhdr 0x%" DW_PR_XZEROS DW_PR_DUx , global_cu_offset);
    }

    /* Print 'name'at the end for better layout */
    printf(" '%s'\n",name);

    dwarf_dealloc(dbg, die, DW_DLA_DIE);

    check_info_offset_sanity(line_title,
        "die offset", name, die_off, maxoff);
    check_info_offset_sanity(line_title,
        "die cu offset", name, die_CU_off, maxoff);
    check_info_offset_sanity(line_title,
        "cu offset", name,
        (die_off - die_CU_off), maxoff);

}
Пример #6
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() */
Пример #7
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);
}
Пример #8
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);
    }
}
Пример #9
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);
    }
}
Пример #10
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);
}
Пример #11
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);
    }
}
Пример #12
0
 /*ARGSUSED*/ void
print_frame_inst_bytes(Dwarf_Debug dbg,
		       Dwarf_Ptr cie_init_inst, Dwarf_Signed len,
		       Dwarf_Signed data_alignment_factor,
		       int code_alignment_factor, Dwarf_Half addr_size,
		       struct dwconf_s *config_data)
{
    unsigned char *instp = (unsigned char *) cie_init_inst;
    Dwarf_Unsigned uval;
    Dwarf_Unsigned uval2;
    unsigned int uleblen;
    unsigned int off = 0;
    unsigned int loff = 0;
    unsigned short u16;
    unsigned int u32;
    unsigned long long u64;

    for (; len > 0;) {
	unsigned char ibyte = *instp;
	int top = ibyte & 0xc0;
	int bottom = ibyte & 0x3f;
	int delta;
	int reg;

	switch (top) {
	case DW_CFA_advance_loc:
	    delta = ibyte & 0x3f;
	    printf("\t%2u DW_CFA_advance_loc %d", off,
		   (int) (delta * code_alignment_factor));
	    if (verbose) {
		printf("  (%d * %d)", (int) delta,
		       (int) code_alignment_factor);
	    }
	    printf("\n");
	    break;
	case DW_CFA_offset:
	    loff = off;
	    reg = ibyte & 0x3f;
	    uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
	    instp += uleblen;
	    len -= uleblen;
	    off += uleblen;
	    printf("\t%2u DW_CFA_offset ", loff);
	    printreg((Dwarf_Signed) reg, config_data);
	    printf(" %lld", (signed long long)
		   (((Dwarf_Signed) uval) * data_alignment_factor));
	    if (verbose) {
		printf("  (%llu * %d)", (unsigned long long) uval,
		       (int) data_alignment_factor);
	    }
	    printf("\n");
	    break;

	case DW_CFA_restore:
	    reg = ibyte & 0x3f;
	    printf("\t%2u DW_CFA_restore \n", off);
	    printreg((Dwarf_Signed) reg, config_data);
	    printf("\n");
	    break;

	default:
	    loff = off;
	    switch (bottom) {
	    case DW_CFA_set_loc:
		/* operand is address, so need address size */
		/* which will be 4 or 8. */
		switch (addr_size) {
		case 4:
		    {
			__uint32_t v32;

			memcpy(&v32, instp + 1, addr_size);
			uval = v32;
		    }
		    break;
		case 8:
		    {
			__uint64_t v64;

			memcpy(&v64, instp + 1, addr_size);
			uval = v64;
		    }
		    break;
		default:
		    printf
			("Error: Unexpected address size %d in DW_CFA_set_loc!\n",
			 addr_size);
		    uval = 0;
		}

		instp += addr_size;
		len -= (Dwarf_Signed) addr_size;
		off += addr_size;
		printf("\t%2u DW_CFA_set_loc %llu\n",
		       loff, (unsigned long long) uval);
		break;
	    case DW_CFA_advance_loc1:
		delta = (unsigned char) *(instp + 1);
		uval2 = delta;
		instp += 1;
		len -= 1;
		off += 1;
		printf("\t%2u DW_CFA_advance_loc1 %llu\n",
		       loff, (unsigned long long) uval2);
		break;
	    case DW_CFA_advance_loc2:
		memcpy(&u16, instp + 1, 2);
		uval2 = u16;
		instp += 2;
		len -= 2;
		off += 2;
		printf("\t%2u DW_CFA_advance_loc2 %llu\n",
		       loff, (unsigned long long) uval2);
		break;
	    case DW_CFA_advance_loc4:
		memcpy(&u32, instp + 1, 4);
		uval2 = u32;
		instp += 4;
		len -= 4;
		off += 4;
		printf("\t%2u DW_CFA_advance_loc4 %llu\n",
		       loff, (unsigned long long) uval2);
		break;
	    case DW_CFA_MIPS_advance_loc8:
		memcpy(&u64, instp + 1, 8);
		uval2 = u64;
		instp += 8;
		len -= 8;
		off += 8;
		printf("\t%2u DW_CFA_MIPS_advance_loc8 %llu\n",
		       loff, (unsigned long long) uval2);
		break;
	    case DW_CFA_offset_extended:
		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		uval2 =
		    local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		printf("\t%2u DW_CFA_offset_extended ", loff);
		printreg((Dwarf_Signed) uval, config_data);
		printf(" %lld", (signed long long)
		       (((Dwarf_Signed) uval2) *
			data_alignment_factor));
		if (verbose) {
		    printf("  (%llu * %d)", (unsigned long long) uval2,
			   (int) data_alignment_factor);
		}
		printf("\n");
		break;

	    case DW_CFA_restore_extended:
		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		printf("\t%2u DW_CFA_restore_extended ", loff);
		printreg((Dwarf_Signed) uval, config_data);
		printf("\n");
		break;
	    case DW_CFA_undefined:
		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		printf("\t%2u DW_CFA_undefined ", loff);
		printreg((Dwarf_Signed) uval, config_data);
		printf("\n");
		break;
	    case DW_CFA_same_value:
		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		printf("\t%2u DW_CFA_same_value ", loff);
		printreg((Dwarf_Signed) uval, config_data);
		printf("\n");
		break;
	    case DW_CFA_register:
		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		uval2 =
		    local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		printf("\t%2u DW_CFA_register ", loff);
		printreg((Dwarf_Signed) uval, config_data);
		printf(" = ");
		printreg((Dwarf_Signed) uval2, config_data);
		printf("\n");
		break;
	    case DW_CFA_remember_state:
		printf("\t%2u DW_CFA_remember_state\n", loff);
		break;
	    case DW_CFA_restore_state:
		printf("\t%2u DW_CFA_restore_state\n", loff);
		break;
	    case DW_CFA_def_cfa:
		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		uval2 =
		    local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		printf("\t%2u DW_CFA_def_cfa ", loff);
		printreg((Dwarf_Signed) uval, config_data);
		printf(" %llu", (unsigned long long) uval2);
		printf("\n");
		break;
	    case DW_CFA_def_cfa_register:
		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		printf("\t%2u DW_CFA_def_cfa_register ", loff);
		printreg((Dwarf_Signed) uval, config_data);
		printf("\n");
		break;
	    case DW_CFA_def_cfa_offset:
		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		printf("\t%2u DW_CFA_def_cfa_offset %llu\n",
		       loff, (unsigned long long) uval);
		break;

	    case DW_CFA_nop:
		printf("\t%2u DW_CFA_nop\n", loff);
		break;

	    case DW_CFA_def_cfa_expression:	/* DWARF3 */
		{
		    Dwarf_Unsigned block_len =
			local_dwarf_decode_u_leb128(instp + 1,
						    &uleblen);

		    instp += uleblen;
		    len -= uleblen;
		    off += uleblen;
		    printf
			("\t%2u DW_CFA_def_cfa_expression expr block len %lld\n",
			 loff, (unsigned long long)
			 block_len);
		    dump_block("\t\t", (char *) instp+1,
			       (Dwarf_Signed) block_len);
                    printf("\n");
                    if(verbose) {
                      struct esb_s exprstring;
                      esb_constructor(&exprstring);
                      get_string_from_locs(dbg,
			    instp+1,block_len,&exprstring);
                      printf("\t\t%s\n",esb_get_string(&exprstring));
                      esb_destructor(&exprstring);
                    }
		    instp += block_len;
		    len -= block_len;
		    off += block_len;
		}
		break;
	    case DW_CFA_expression:	/* DWARF3 */
		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		{
                    /* instp is always 1 byte back, so we need +1
			when we use it. See the final increment
                        of this for loop. */
		    Dwarf_Unsigned block_len =
			local_dwarf_decode_u_leb128(instp + 1,
						    &uleblen);

		    instp += uleblen;
		    len -= uleblen;
		    off += uleblen;
		    printf
			("\t%2u DW_CFA_expression %llu expr block len %lld\n",
			 loff, (unsigned long long) uval,
			 (unsigned long long)
			 block_len);
		    dump_block("\t\t", (char *) instp+1,
			       (Dwarf_Signed) block_len);
                    printf("\n");
                    if(verbose) {
                      struct esb_s exprstring;
                      esb_constructor(&exprstring);
                      get_string_from_locs(dbg,
			    instp+1,block_len,&exprstring);
                      printf("\t\t%s\n",esb_get_string(&exprstring));
                      esb_destructor(&exprstring);
                    }
		    instp += block_len;
		    len -= block_len;
		    off += block_len;
		}

		break;
	    case DW_CFA_cfa_offset_extended_sf:	/* DWARF3 */
		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		{
                    /* instp is always 1 byte back, so we need +1
			when we use it. See the final increment
                        of this for loop. */
		    Dwarf_Signed sval2 =
			local_dwarf_decode_s_leb128(instp + 1,
						    &uleblen);

		    instp += uleblen;
		    len -= uleblen;
		    off += uleblen;
		    printf("\t%2u DW_CFA_offset_extended_sf ", loff);
		    printreg((Dwarf_Signed) uval, config_data);
		    printf(" %lld", (signed long long)
			   ((sval2) * data_alignment_factor));
		    if (verbose) {
			printf("  (%lld * %d)", (long long) sval2,
			       (int) data_alignment_factor);
		    }
		}
		printf("\n");
		break;
	    case DW_CFA_def_cfa_sf:	/* DWARF3 */
                    /* instp is always 1 byte back, so we need +1
			when we use it. See the final increment
                        of this for loop. */
		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		{
		    Dwarf_Signed sval2 =
			local_dwarf_decode_s_leb128(instp + 1,
						    &uleblen);

		    instp += uleblen;
		    len -= uleblen;
		    off += uleblen;
		    printf("\t%2u DW_CFA_def_cfa_sf ", loff);
		    printreg((Dwarf_Signed) uval, config_data);
		    printf(" %lld", (long long) sval2); 
                    printf(" (*data alignment factor=>%lld)",
                     (long long)(sval2*data_alignment_factor));
		}
		printf("\n");
		break;
	    case DW_CFA_def_cfa_offset_sf:	/* DWARF3 */
		{
                    /* instp is always 1 byte back, so we need +1
			when we use it. See the final increment
                        of this for loop. */
		    Dwarf_Signed sval =
			local_dwarf_decode_s_leb128(instp + 1,
						    &uleblen);

		    instp += uleblen;
		    len -= uleblen;
		    off += uleblen;
		    printf("\t%2u DW_CFA_def_cfa_offset_sf %lld (*data alignment factor=> %lld)\n",
			   loff, (long long) sval,
                           (long long)(data_alignment_factor*sval));

		}
		break;
	    case DW_CFA_val_offset:	/* DWARF3 */
                    /* instp is always 1 byte back, so we need +1
			when we use it. See the final increment
                        of this for loop. */
		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		{
		    uval2 =
			local_dwarf_decode_s_leb128(instp + 1,
						    &uleblen);
		    instp += uleblen;
		    len -= uleblen;
		    off += uleblen;
		    printf("\t%2u DW_CFA_val_offset ", loff);
		    printreg((Dwarf_Signed) uval, config_data);
		    printf(" %lld", (unsigned long long)
			   (((Dwarf_Signed) uval2) *
			    data_alignment_factor));
		    if (verbose) {
			printf("  (%lld * %d)", (long long) uval2,
			       (int) data_alignment_factor);
		    }
		}
		printf("\n");

		break;
	    case DW_CFA_val_offset_sf:	/* DWARF3 */
                    /* instp is always 1 byte back, so we need +1
			when we use it. See the final increment
                        of this for loop. */
		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		{
		    Dwarf_Signed sval2 =
			local_dwarf_decode_s_leb128(instp + 1,
						    &uleblen);

		    instp += uleblen;
		    len -= uleblen;
		    off += uleblen;
		    printf("\t%2u DW_CFA_val_offset_sf ", loff);
		    printreg((Dwarf_Signed) uval, config_data);
		    printf(" %lld", (signed long long)
			   ((sval2) * data_alignment_factor));
		    if (verbose) {
			printf("  (%lld * %d)", (long long) sval2,
			       (int) data_alignment_factor);
		    }
		}
		printf("\n");

		break;
	    case DW_CFA_val_expression:	/* DWARF3 */
                    /* instp is always 1 byte back, so we need +1
			when we use it. See the final increment
                        of this for loop. */
		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
		instp += uleblen;
		len -= uleblen;
		off += uleblen;
		{
		    Dwarf_Unsigned block_len =
			local_dwarf_decode_u_leb128(instp + 1,
						    &uleblen);

		    instp += uleblen;
		    len -= uleblen;
		    off += uleblen;
		    printf
			("\t%2u DW_CFA_val_expression %llu expr block len %lld\n",
			 loff, (unsigned long long) uval,
			 (unsigned long long)
			 block_len);
		    dump_block("\t\t", (char *) instp+1,
			       (Dwarf_Signed) block_len);
                    printf("\n");
                    if(verbose) {
                      struct esb_s exprstring;
                      esb_constructor(&exprstring);
                      get_string_from_locs(dbg,
			    instp+1,block_len,&exprstring);
                      printf("\t\t%s\n",esb_get_string(&exprstring));
                      esb_destructor(&exprstring);
                    }
		    instp += block_len;
		    len -= block_len;
		    off += block_len;
		}


		break;


#ifdef DW_CFA_GNU_window_save
	    case DW_CFA_GNU_window_save:{
		    /* no information: this just tells unwinder to
		       restore the window registers from the previous
		       frame's window save area */
		    printf("\t%2u DW_CFA_GNU_window_save \n", loff);
		    break;
		}
#endif
#ifdef DW_CFA_GNU_negative_offset_extended
	    case DW_CFA_GNU_negative_offset_extended:{
		    printf
			("\t%2u DW_CFA_GNU_negative_offset_extended \n",
			 loff);
		}
#endif
#ifdef  DW_CFA_GNU_args_size
		/* single uleb128 is the current arg area size in
		   bytes. no register exists yet to save this in */
	    case DW_CFA_GNU_args_size:{
		    Dwarf_Unsigned lreg;

                    /* instp is always 1 byte back, so we need +1
			when we use it. See the final increment
                        of this for loop. */
		    lreg =
			local_dwarf_decode_u_leb128(instp + 1,
						    &uleblen);
		    printf
			("\t%2u DW_CFA_GNU_args_size arg size: %llu\n",
			 loff, (unsigned long long) lreg);
		    instp += uleblen;
		    len -= uleblen;
		    off += uleblen;

		    break;
		}
#endif

	    default:
		printf("\t%u Unexpected op 0x%x: \n",
		       loff, (unsigned int) bottom);
		len = 0;
		break;
	    }
	}
	instp++;
	len--;
	off++;
    }
}
Пример #13
0
static void
print_one_frame_reg_col(Dwarf_Debug dbg,
                        Dwarf_Unsigned rule_id,
                        Dwarf_Small value_type,
                        Dwarf_Unsigned reg_used,
                        struct dwconf_s *config_data,
                        Dwarf_Signed offset_relevant,
                        Dwarf_Signed offset, 
                        Dwarf_Ptr block_ptr)
{
    char *type_title = "";
    int print_type_title = 1;

    if (config_data->cf_interface_number == 2)
	print_type_title = 0;

    switch (value_type) {
    case DW_EXPR_OFFSET:
	type_title = "off";
	goto preg2;
    case DW_EXPR_VAL_OFFSET:
	type_title = "valoff";
      preg2:
	if (reg_used == config_data->cf_initial_rule_value) {
	    break;
	}
	if (print_type_title)
	    printf("<%s ", type_title);
	printreg((Dwarf_Signed) rule_id, config_data);
	printf("=");
	if (offset_relevant == 0) {
	    printreg((Dwarf_Signed) reg_used, config_data);
	    printf(" ");
	} else {
	    printf("%02lld", offset);
	    printf("(");
	    printreg((Dwarf_Signed) reg_used, config_data);
	    printf(") ");
	}
	if (print_type_title)
	    printf("%s", "> ");
	break;
    case DW_EXPR_EXPRESSION:
	type_title = "expr";
	goto pexp2;
    case DW_EXPR_VAL_EXPRESSION:
	type_title = "valexpr";
      pexp2:
	if (print_type_title)
	    printf("<%s ", type_title);
	printreg((Dwarf_Signed) rule_id, config_data);
	printf("=");
	printf("expr-block-len=%lld", (long long) offset);
	if (print_type_title)
	    printf("%s", "> ");
	if (verbose) {
	    char pref[40];

	    strcpy(pref, "<");
	    strcat(pref, type_title);
	    strcat(pref, "bytes:");
	    dump_block(pref, block_ptr, offset);
	    printf("%s", "> ");
            if(verbose) {
                      struct esb_s exprstring;
                      esb_constructor(&exprstring);
                      get_string_from_locs(dbg,
			    block_ptr,offset,&exprstring);
                      printf("<expr:%s>",esb_get_string(&exprstring));
                      esb_destructor(&exprstring);
            }
	}
	break;
    default:
	printf("Internal error in libdwarf, value type %d\n",
	       value_type);
	exit(1);
    }
    return;
}
Пример #14
0
void
init_global_flags(void)
{
    glflags.gf_debug_names_flag = FALSE;
    glflags.gf_info_flag = FALSE;
    glflags.gf_use_old_dwarf_loclist = FALSE;  /* This so both
        dwarf_loclist_n()  and dwarf_get_loclist_c()
        and the dwarf_loclist_from_expr
        variations can be
        tested. Defaults to new
        dwarf_get_loclist_c(). See -g option.
        The original IRIX dwarf_loclist() no longer tested
        as of October 2015. */

    glflags.gf_line_flag_selection = s2l;
    glflags.gf_line_flag = FALSE;

    /*  Setting this FALSE tells dwarfdump to use the old
        line-table interfaces.  using:
            -x line5=no
        The new interfaces allow for both two-level line tables
        and access to line table headers in case
        we have a DWARF5 skeleton line table (a line table
        header with no lines).
        */
    glflags.gf_line_skeleton_flag = TRUE;
    glflags.gf_line_print_pc = TRUE;    /* Print <pc> addresses. */
    glflags.gf_abbrev_flag = FALSE;
    glflags.gf_frame_flag = FALSE;      /* .debug_frame section. */
    glflags.gf_eh_frame_flag = FALSE;   /* GNU .eh_frame section. */
    glflags.gf_pubnames_flag = FALSE;
    glflags.gf_macinfo_flag = FALSE; /* DWARF2,3,4. Old macro section*/
    glflags.gf_macro_flag = FALSE; /* DWARF5(and DWARF4 extension) new macro section */
    glflags.gf_loc_flag = FALSE;
    glflags.gf_aranges_flag = FALSE; /* .debug_aranges section. */
    glflags.gf_ranges_flag = FALSE; /* .debug_ranges section. */
    glflags.gf_string_flag = FALSE;
    glflags.gf_reloc_flag = FALSE;
    glflags.gf_static_func_flag = FALSE;
    glflags.gf_static_var_flag = FALSE;
    glflags.gf_types_flag = FALSE;
    glflags.gf_weakname_flag = FALSE;
    glflags.gf_header_flag = FALSE; /* Control printing of Elf header. */
    glflags.gf_gdbindex_flag = FALSE;
    glflags.gf_producer_children_flag = FALSE;   /* List of CUs per compiler */
    glflags.gf_check_abbrev_code = FALSE;
    glflags.gf_check_pubname_attr = FALSE;
    glflags.gf_check_reloc_offset = FALSE;
    glflags.gf_check_attr_tag = FALSE;
    glflags.gf_check_tag_tree = FALSE;
    glflags.gf_check_type_offset = FALSE;
    glflags.gf_check_decl_file = FALSE;
    glflags.gf_check_macros = FALSE;
    glflags.gf_check_lines = FALSE;
    glflags.gf_check_fdes = FALSE;
    glflags.gf_check_ranges = FALSE;
    glflags.gf_check_aranges = FALSE;
    glflags.gf_check_harmless = FALSE;
    glflags.gf_check_abbreviations = FALSE;
    glflags.gf_check_dwarf_constants = FALSE;
    glflags.gf_check_di_gaps = FALSE;
    glflags.gf_check_forward_decl = FALSE;
    glflags.gf_check_self_references = FALSE;
    glflags.gf_check_attr_encoding = FALSE;   /* Attributes encoding */
    glflags.gf_generic_1200_regs = FALSE;
    glflags.gf_suppress_check_extensions_tables = FALSE;
    glflags.gf_check_duplicated_attributes = FALSE;

    /* lots of checks make no sense on a dwp debugfission object. */
    glflags.gf_suppress_checking_on_dwp = FALSE;

    /*  suppress_nested_name_search is a band-aid.
        A workaround. A real fix for N**2 behavior is needed.  */
    glflags.gf_suppress_nested_name_search = FALSE;
    glflags.gf_uri_options_translation = TRUE;
    glflags.gf_do_print_uri_in_input = TRUE;

    glflags.gf_print_unique_errors = FALSE;
    glflags.gf_found_error_message = FALSE;

    glflags.gf_check_names = FALSE;

    /* During '-k' mode, display errors */
    glflags.gf_check_verbose_mode = TRUE;

    glflags.gf_check_frames = FALSE;

    /* Extensive frames check */
    glflags.gf_check_frames_extended = FALSE;

    glflags.gf_check_locations      = FALSE;
    glflags.gf_print_usage_tag_attr = FALSE;
    glflags.gf_print_usage_tag_attr_full = FALSE;
    glflags.gf_check_all_compilers  = TRUE;
    glflags.gf_check_snc_compiler   = FALSE;
    glflags.gf_check_gcc_compiler   = FALSE;
    glflags.gf_print_summary_all    = FALSE;

    /*  The check and print flags here make it easy to
        allow check-only or print-only.  We no longer support
        check-and-print in a single run.  */
    glflags.gf_do_check_dwarf       = FALSE;
    glflags.gf_do_print_dwarf       = FALSE;
    glflags.gf_check_show_results   = FALSE;
    glflags.gf_record_dwarf_error   = FALSE;  /* A test has failed, this
        is normally set FALSE shortly after being set TRUE, it is
        a short-range hint we should print something we might not
        otherwise print (under the circumstances). */

    glflags.gf_check_debug_names    = FALSE;

    /* Display parent/children when in wide format? */
    glflags.gf_display_parent_tree  = FALSE;
    glflags.gf_display_children_tree = FALSE;
    glflags.gf_stop_indent_level    = 0;

    /* Print search results in wide format? */
    glflags.gf_search_wide_format   = FALSE;
    /* -S option: strings for 'any' and 'match' */
    glflags.gf_search_is_on         = FALSE;
    glflags.gf_search_print_results = FALSE;
    glflags.gf_cu_name_flag         = FALSE;
    glflags.gf_show_global_offsets  = FALSE;
    glflags.gf_display_offsets      = TRUE;

    /*  Base address has a special meaning in DWARF4 relative to address ranges. */
    glflags.seen_PU = FALSE;              /* Detected a PU */
    glflags.seen_CU = FALSE;              /* Detected a CU */
    glflags.need_CU_name = TRUE;          /* Need CU name */
    glflags.need_CU_base_address = TRUE;  /* Need CU Base address */
    glflags.need_CU_high_address = TRUE;  /* Need CU High address */
    glflags.need_PU_valid_code = TRUE;    /* Need PU valid code */

    glflags.seen_PU_base_address = FALSE; /* Detected a Base address for PU */
    glflags.seen_PU_high_address = FALSE; /* Detected a High address for PU */
    glflags.PU_base_address = 0;       /* PU Base address */
    glflags.PU_high_address = 0;       /* PU High address */

    glflags.DIE_offset = 0;            /* DIE offset in compile unit */
    glflags.DIE_overall_offset = 0;    /* DIE offset in .debug_info */

    /*  These globals  enable better error reporting. */
    glflags.DIE_CU_offset = 0;         /* CU DIE offset in compile unit */
    glflags.DIE_CU_overall_offset = 0; /* CU DIE offset in .debug_info */
    glflags.current_section_id = 0;           /* Section being process */

    /*  Base Address is needed for range lists and must come from a CU.
        Low address is for information and can come from a function
        or something in the CU. */
    glflags.CU_base_address = 0;       /* CU Base address */
    glflags.CU_low_address = 0;        /* CU low address */
    glflags.CU_high_address = 0;       /* CU High address */

    glflags.fde_offset_for_cu_low = DW_DLV_BADOFFSET;
    glflags.fde_offset_for_cu_high = DW_DLV_BADOFFSET;

    glflags.program_name = NULL;

    /* Able to generate report on search */
    glflags.search_any_text = 0;
    glflags.search_match_text = 0;
    glflags.search_regex_text = 0;
    glflags.search_occurrences = 0;

#ifdef HAVE_REGEX
    glflags.search_re = &_search_re;
#endif

    /*  Start verbose at zero. verbose can
        be incremented with -v but not decremented. */
    glflags.verbose = 0;

    glflags.dense = FALSE;
    glflags.ellipsis = FALSE;
    glflags.show_form_used = FALSE;

    /*  break_after_n_units is mainly for testing.
        It enables easy limiting of output size/running time
        when one wants the output limited.
        For example,
            -H 2
        limits the -i output to 2 compilation units and
        the -f or -F output to 2 FDEs and 2 CIEs.
    */
    glflags.break_after_n_units = INT_MAX;

    glflags.section_high_offsets_global = &_section_high_offsets_global;

    glflags.pRangesInfo = NULL;
    glflags.pLinkonceInfo = NULL;
    glflags.pVisitedInfo = NULL;

    /*  These names make diagnostic messages more complete, the
        fixed length is safe, though ultra long names will get
        truncated. */
    glflags.PU_name[0] = 0;
    glflags.CU_name[0] = 0;
    glflags.CU_producer[0] = 0;

    /*  Options to enable debug tracing. */
    {
        int i = 0;
        for ( ; i <= MAX_TRACE_LEVEL; ++i) {
            glflags.nTrace[i] = 0;
        }
    }

    /*  Output filename */
    glflags.output_file = 0;
    glflags.group_number = 0;

    /*  Global esb-buffers. */
    glflags.newprogname = &_newprogname;
    esb_constructor(glflags.newprogname);

    glflags.cu_name = &_cu_name;
    esb_constructor(glflags.cu_name);

    glflags.config_file_path = &_config_file_path;
    esb_constructor(glflags.config_file_path);

    glflags.config_file_tiedpath = &_config_file_tiedpath;
    esb_constructor(glflags.config_file_tiedpath);

    glflags.config_file_data = &_config_file_data;

    /*  Check errors. */
    glflags.check_error = 0;
}
Пример #15
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);
    }
}
Пример #16
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);
}
Пример #17
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;
    }
}