Beispiel #1
0
/* Calculate the number of abbreviations for the
   current CU and set up a basic abbreviations array info,
   storing the number of attributes per abbreviation.
*/
void
get_abbrev_array_info(Dwarf_Debug dbg, Dwarf_Unsigned offset_in)
{
    Dwarf_Unsigned offset = offset_in;
    if (check_abbreviations) {
        Dwarf_Abbrev ab;
        Dwarf_Unsigned length = 0;
        Dwarf_Unsigned abbrev_entry_count = 0;
        Dwarf_Unsigned abbrev_code;
        int abres = DW_DLV_OK;
        Dwarf_Error err;

        Dwarf_Bool bMore = TRUE;
        CU_abbrev_count = 0;

        if (abbrev_array == NULL) {
            /* Allocate initial abbreviation array info */
            abbrev_array = (Dwarf_Signed *)
                calloc(ABBREV_ARRAY_INITIAL_SIZE+1,sizeof(Dwarf_Signed));
            abbrev_array_size = ABBREV_ARRAY_INITIAL_SIZE;
        } else {
            /* Clear out values from previous CU */
            memset((void *)abbrev_array,0,
                (abbrev_array_size+1) * sizeof(Dwarf_Signed));
        }

        while (bMore && (abres = dwarf_get_abbrev(dbg, offset, &ab,
            &length, &abbrev_entry_count,
            &err)) == DW_DLV_OK) {
            dwarf_get_abbrev_code(ab,&abbrev_code,&err);
            if (abbrev_code == 0) {
                /* End of abbreviation table for this CU */
                ++offset; /* Skip abbreviation code */
                bMore = FALSE;
            } else {
                /* Valid abbreviation code */
                if (abbrev_code > 0) {
                    if (abbrev_code > abbrev_array_size) {
                        /* Resize abbreviation array */
                        abbrev_array_size *= 2;
                        abbrev_array = (Dwarf_Signed *)
                            realloc(abbrev_array,
                            (abbrev_array_size+1) * sizeof(Dwarf_Signed));
                    }
                    abbrev_array[abbrev_code] = abbrev_entry_count;
                    ++CU_abbrev_count;
                    offset += length;
                } else {
                    /* Invalid abbreviation code */
                    print_error(dbg, "get_abbrev_array_info", abres, err);
                }
            }
            dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
        }
    }
}
Beispiel #2
0
/*  This function is not entirely safe to call.
    The problem is that the DWARF[234] specification does not insist
    that bytes in .debug_abbrev that are not referenced by .debug_info
    or .debug_types need to be initialized to anything specific.
    Any garbage bytes may cause trouble.  Not all compilers/linkers
    leave unreferenced garbage bytes in .debug_abbrev, so this may
    work for most objects. */
int
dwarf_get_abbrev_count(Dwarf_Debug dbg)
{
    Dwarf_Abbrev ab;
    Dwarf_Unsigned offset = 0;
    Dwarf_Unsigned length = 0;
    Dwarf_Unsigned attr_count = 0;
    Dwarf_Unsigned abbrev_count = 0;
    int abres = DW_DLV_OK;
    Dwarf_Error err;

    while ((abres = dwarf_get_abbrev(dbg, offset, &ab,
        &length, &attr_count,
        &err)) == DW_DLV_OK) {

        ++abbrev_count;
        offset += length;
        dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
    }
    return abbrev_count;
}
Beispiel #3
0
/* Print data in .debug_abbrev
   This is inherently unsafe as it assumes there
   are no byte sequences in .debug_abbrev other than
   legal abbrev sequences.  But the Dwarf spec
   does not promise that. The spec only promises
   that any bytes at an offset referred to from
   .debug_info are legal sequences.
*/
extern void
print_abbrevs(Dwarf_Debug dbg)
{
    Dwarf_Abbrev ab;
    Dwarf_Unsigned offset = 0;
    Dwarf_Unsigned length = 0;
    Dwarf_Unsigned abbrev_entry_count = 0;
    /* Maximum defined tag is 0xffff, DW_TAG_hi_user. */
    Dwarf_Half tag = 0;
    Dwarf_Half attr = 0;
    Dwarf_Signed form = 0;
    Dwarf_Off off = 0;
    Dwarf_Unsigned i = 0;
    const char * child_name = 0;
    Dwarf_Unsigned abbrev_num = 1;
    Dwarf_Signed child_flag = 0;
    int abres = 0;
    int tres = 0;
    int acres = 0;
    Dwarf_Unsigned abbrev_code = 0;

    current_section_id = DEBUG_ABBREV;

    if (do_print_dwarf) {
        printf("\n.debug_abbrev\n");
    }
    while ((abres = dwarf_get_abbrev(dbg, offset, &ab,
        &length, &abbrev_entry_count,
        &err)) == DW_DLV_OK) {

        if (abbrev_entry_count == 0) {
            /* Simple innocuous zero : null abbrev entry */
            if (dense) {
                printf("<%" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx "><%"
                    DW_PR_DSd "><%s>\n",
                    abbrev_num,
                    offset,
                    (Dwarf_Signed) /* abbrev_code */ 0,
                    "null .debug_abbrev entry");
            } else {
                printf("<%5" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx
                    "><code: %3" DW_PR_DSd "> %-20s\n",
                    abbrev_num,
                    offset,
                    (Dwarf_Signed) /* abbrev_code */ 0,
                    "null .debug_abbrev entry");
            }

            offset += length;
            ++abbrev_num;
            dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
            continue;
        }
        tres = dwarf_get_abbrev_tag(ab, &tag, &err);
        if (tres != DW_DLV_OK) {
            dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
            print_error(dbg, "dwarf_get_abbrev_tag", tres, err);
        }
        tres = dwarf_get_abbrev_code(ab, &abbrev_code, &err);
        if (tres != DW_DLV_OK) {
            dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
            print_error(dbg, "dwarf_get_abbrev_code", tres, err);
        }
        if (dense) {
            printf("<%" DW_PR_DUu "><0x%" DW_PR_XZEROS  DW_PR_DUx
                "><%" DW_PR_DSd "><%s>",
                abbrev_num,
                offset, abbrev_code,
                get_TAG_name(tag,dwarf_names_print_on_error));
        }
        else {
            printf("<%5" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx "><code: %3"
                DW_PR_DSd "> %-20s",
                abbrev_num,
                offset, abbrev_code,
                get_TAG_name(tag,dwarf_names_print_on_error));
        }
        /* Process specific TAGs specially. */
        tag_specific_checks_setup(tag,0);
        ++abbrev_num;
        acres = dwarf_get_abbrev_children_flag(ab, &child_flag, &err);
        if (acres == DW_DLV_ERROR) {
            dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
            print_error(dbg, "dwarf_get_abbrev_children_flag", acres,
                err);
        }
        if (acres == DW_DLV_NO_ENTRY) {
            child_flag = 0;
        }
        child_name = get_children_name(child_flag,
            dwarf_names_print_on_error);
        if (dense)
            printf(" %s", child_name);
        else
            printf("        %s\n", child_name);
        /*  Abbrev just contains the format of a die, which debug_info
            then points to with the real data. So here we just print the
            given format. */
        for (i = 0; i < abbrev_entry_count; i++) {
            int aeres = 0;

            aeres =
                dwarf_get_abbrev_entry(ab, i, &attr, &form, &off, &err);
            if (aeres == DW_DLV_ERROR) {
                dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
                print_error(dbg, "dwarf_get_abbrev_entry", aeres, err);
            }
            if (aeres == DW_DLV_NO_ENTRY) {
                attr = -1LL;
                form = -1LL;
            }
            if (dense) {
                printf(" <%ld>%s<%s>", (unsigned long) off,
                    get_AT_name(attr,dwarf_names_print_on_error),
                    get_FORM_name((Dwarf_Half) form,
                        dwarf_names_print_on_error));
            } else {
                printf("       <0x%08lx>              %-28s%s\n",
                    (unsigned long) off,
                    get_AT_name(attr,
                        dwarf_names_print_on_error),
                    get_FORM_name((Dwarf_Half) form,
                        dwarf_names_print_on_error));
            }
        }
        dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
        offset += length;
        if (dense) {
            printf("\n");
        }
    }
    if (abres == DW_DLV_ERROR) {
        print_error(dbg, "dwarf_get_abbrev", abres, err);
    }
}
Beispiel #4
0
/* Print data in .debug_abbrev
   This is inherently unsafe as it assumes there
   are no byte sequences in .debug_abbrev other than
   legal abbrev sequences.  But the Dwarf spec
   does not promise that. The spec only promises
   that any bytes at an offset referred to from
   .debug_info are legal sequences.
*/
extern void
print_abbrevs(Dwarf_Debug dbg)
{
    Dwarf_Abbrev ab;
    Dwarf_Unsigned offset = 0;
    Dwarf_Unsigned length = 0;
    Dwarf_Unsigned abbrev_entry_count = 0;
    /* Maximum defined tag is 0xffff, DW_TAG_hi_user. */
    Dwarf_Half tag = 0;
    Dwarf_Half attr = 0;
    Dwarf_Signed form = 0;
    Dwarf_Off off = 0;
    Dwarf_Unsigned i = 0;
    Dwarf_Unsigned abbrev_num = 1;
    Dwarf_Signed child_flag = 0;
    int abres = 0;
    int tres = 0;
    int acres = 0;
    Dwarf_Unsigned abbrev_code = 0;
    Dwarf_Error paerr = 0;

    current_section_id = DEBUG_ABBREV;

    if (do_print_dwarf) {
        printf("\n.debug_abbrev\n");
    }
    while ((abres = dwarf_get_abbrev(dbg, offset, &ab,
        &length, &abbrev_entry_count, &paerr)) == DW_DLV_OK) {
        const char *tagname = "";

        /*  Here offset is the global offset in .debug_abbrev.
            The abbrev_num is a relatively worthless counter
            of all abbreviations.  */
        tres = dwarf_get_abbrev_tag(ab, &tag, &paerr);
        if (tres != DW_DLV_OK) {
            dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
            print_error(dbg, "dwarf_get_abbrev_tag", tres, paerr);
        }
        tres = dwarf_get_abbrev_code(ab, &abbrev_code, &paerr);
        if (tres != DW_DLV_OK) {
            dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
            print_error(dbg, "dwarf_get_abbrev_code", tres, paerr);
        }
        tagname = get_TAG_name(tag,dwarf_names_print_on_error);
        if (!tag) {
            tagname = "Abbrev 0: null abbrev entry";
        }
        if (dense) {
            printf("<%" DW_PR_DUu "><0x%" DW_PR_XZEROS  DW_PR_DUx
                "><code: %" DW_PR_DUu ">",
                abbrev_num, offset,abbrev_code);
            if (verbose) {
                printf("<length: 0x%" DW_PR_XZEROS  DW_PR_DUx ">",
                    length);
            }
            printf(" %s", tagname);
        }
        else {
            printf("<%5" DW_PR_DUu "><0x%" DW_PR_XZEROS DW_PR_DUx
                "><code: %3" DW_PR_DUu ">",
                abbrev_num, offset, abbrev_code);
            if (verbose) {
                printf("<length: 0x%" DW_PR_XZEROS  DW_PR_DUx ">",
                    length);
            }
            printf(" %-27s", tagname);
        }
        /* Process specific TAGs specially. */
        tag_specific_checks_setup(tag,0);
        ++abbrev_num;
        acres = dwarf_get_abbrev_children_flag(ab, &child_flag, &paerr);
        if (acres == DW_DLV_ERROR) {
            dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
            print_error(dbg, "dwarf_get_abbrev_children_flag", acres,
                paerr);
        }
        if (acres == DW_DLV_NO_ENTRY) {
            child_flag = 0;
        }
        /*  If tag is zero, it is a null byte, not a real abbreviation,
            so there is no 'children' flag to print.  */
        if (tag) {
            const char * child_name = 0;

            child_name = get_children_name(child_flag,
                dwarf_names_print_on_error);
            printf(" %s", child_name);
        }
        if(!dense) {
            printf("\n");
        }
        /*  Abbrev just contains the format of a die, which debug_info
            then points to with the real data. So here we just print the
            given format. */
        for (i = 0; i < abbrev_entry_count; i++) {
            int aeres = 0;

            aeres =
                dwarf_get_abbrev_entry(ab, i, &attr, &form, &off, &paerr);
            if (aeres == DW_DLV_ERROR) {
                dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
                print_error(dbg, "dwarf_get_abbrev_entry", aeres, paerr);
            }
            if (aeres == DW_DLV_NO_ENTRY) {
                attr = -1LL;
                form = -1LL;
            }
            if (dense) {
                printf(" <%ld>%s<%s>", (unsigned long) off,
                    get_AT_name(attr,dwarf_names_print_on_error),
                    get_FORM_name((Dwarf_Half) form,
                        dwarf_names_print_on_error));
            } else {
                printf("       <0x%08lx>              %-28s%s\n",
                    (unsigned long) off,
                    get_AT_name(attr,
                        dwarf_names_print_on_error),
                    get_FORM_name((Dwarf_Half) form,
                        dwarf_names_print_on_error));
            }
        }
        dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
        offset += length;
        if (dense) {
            printf("\n");
        }
    }
    if (abres == DW_DLV_ERROR) {
        print_error(dbg, "dwarf_get_abbrev", abres, paerr);
    }
}
Beispiel #5
0
/* Calculate the number of abbreviations for the
   current CU and set up basic abbreviations array info,
   storing the number of attributes per abbreviation
*/
void
get_abbrev_array_info(Dwarf_Debug dbg, Dwarf_Unsigned offset_in)
{
    Dwarf_Unsigned offset = offset_in;
    if (check_abbreviations) {
        Dwarf_Abbrev ab = 0;
        Dwarf_Unsigned length = 0;
        Dwarf_Unsigned abbrev_entry_count = 0;
        Dwarf_Unsigned abbrev_code;
        int abres = DW_DLV_OK;
        Dwarf_Error aberr = 0;
        Dwarf_Unsigned last_abbrev_code = 0;

        Dwarf_Bool bMore = TRUE;
        Dwarf_Unsigned CU_abbrev_count = 0;

        if (abbrev_array == NULL) {
            /* Allocate initial abbreviation array info */
            abbrev_array_size = ABBREV_ARRAY_INITIAL_SIZE;
            abbrev_array = (Dwarf_Unsigned *)
                calloc(abbrev_array_size,sizeof(Dwarf_Unsigned));
        } else {
            /* Clear out values from previous CU */
            memset((void *)abbrev_array,0,
                (abbrev_array_size) * sizeof(Dwarf_Unsigned));
        }

        while (bMore && (abres = dwarf_get_abbrev(dbg, offset, &ab,
            &length, &abbrev_entry_count,
            &aberr)) == DW_DLV_OK) {
            dwarf_get_abbrev_code(ab,&abbrev_code,&aberr);
            if (abbrev_code == 0) {
                /* End of abbreviation table for this CU */
                ++offset; /* Skip abbreviation code */
                bMore = FALSE;
            } else {
                /* Valid abbreviation code. We hope. */
                if (abbrev_code > 0) {
                    check_abbrev_num_sequence(abbrev_code,last_abbrev_code,
                        abbrev_array_size,abbrev_entry_count,CU_abbrev_count);
                    while (abbrev_code >= abbrev_array_size) {
                        Dwarf_Unsigned old_size = abbrev_array_size;
                        size_t addl_size_bytes = old_size *
                            sizeof(Dwarf_Unsigned);

                        /*  Resize abbreviation array.
                            Only a bogus abbreviation number will iterate
                            more than once, and it will be caught later.
                            Or we will run out of memory! */
                        abbrev_array_size *= 2;
                        abbrev_array = (Dwarf_Unsigned *)
                            realloc(abbrev_array,
                            abbrev_array_size * sizeof(Dwarf_Unsigned));
                        /* Zero out the new bytes. */
                        memset(abbrev_array + old_size,0,addl_size_bytes);
                    }
                    check_reused_code(abbrev_code, abbrev_entry_count);
                    abbrev_array[abbrev_code] = abbrev_entry_count;
                    ++CU_abbrev_count;
                    offset += length;
                } else {
                    /* Invalid abbreviation code */
                    print_error(dbg, "get_abbrev_array_info", abres, aberr);
                }
                last_abbrev_code = abbrev_code;
            }
            dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
        }
    }
}