Blame libdwarf/dwarf_dnames.c

Packit cdaae3
/*
Packit cdaae3
  Portions Copyright (C) 2017-2017 David Anderson. All Rights Reserved.
Packit cdaae3
Packit cdaae3
  This program is free software; you can redistribute it and/or modify it
Packit cdaae3
  under the terms of version 2.1 of the GNU Lesser General Public License
Packit cdaae3
  as published by the Free Software Foundation.
Packit cdaae3
Packit cdaae3
  This program is distributed in the hope that it would be useful, but
Packit cdaae3
  WITHOUT ANY WARRANTY; without even the implied warranty of
Packit cdaae3
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Packit cdaae3
Packit cdaae3
  Further, this software is distributed without any warranty that it is
Packit cdaae3
  free of the rightful claim of any third person regarding infringement
Packit cdaae3
  or the like.  Any license provided herein, whether implied or
Packit cdaae3
  otherwise, applies only to this software file.  Patent licenses, if
Packit cdaae3
  any, provided herein do not apply to combinations of this program with
Packit cdaae3
  other software, or any other product whatsoever.
Packit cdaae3
Packit cdaae3
  You should have received a copy of the GNU Lesser General Public
Packit cdaae3
  License along with this program; if not, write the Free Software
Packit cdaae3
  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
Packit cdaae3
  USA.
Packit cdaae3
Packit cdaae3
*/
Packit cdaae3
Packit cdaae3
/*  This provides access to the DWARF5 .debug_names section. */
Packit cdaae3
Packit cdaae3
#include "config.h"
Packit cdaae3
#include "dwarf_incl.h"
Packit cdaae3
#include <stdio.h>
Packit cdaae3
#include <stdlib.h>
Packit cdaae3
#include "dwarf_global.h"
Packit cdaae3
#include "dwarf_dnames.h"
Packit cdaae3
Packit cdaae3
#define FALSE 0
Packit cdaae3
#define TRUE  1
Packit cdaae3
Packit cdaae3
/*  freedabs attempts to do some cleanup in the face
Packit cdaae3
    of an error. */
Packit cdaae3
static void
Packit cdaae3
freedabs(struct Dwarf_D_Abbrev_s *dab)
Packit cdaae3
{
Packit cdaae3
    struct Dwarf_D_Abbrev_s *tmp = 0;
Packit cdaae3
    for(; dab; dab = tmp) {
Packit cdaae3
        tmp = dab->da_next;
Packit cdaae3
        free(tmp);
Packit cdaae3
    }
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
static int
Packit cdaae3
fill_in_abbrevs_table(struct Dwarf_Dnames_index_header_s * dn,
Packit cdaae3
    Dwarf_Error * error)
Packit cdaae3
{
Packit cdaae3
    Dwarf_Small *abdata = dn->din_abbreviations;
Packit cdaae3
    Dwarf_Unsigned ablen =  dn->din_abbrev_table_size;
Packit cdaae3
    Dwarf_Small *tabend = abdata+ablen;
Packit cdaae3
    Dwarf_Small *abcur = 0;
Packit cdaae3
    Dwarf_Unsigned code = 0;
Packit cdaae3
    Dwarf_Unsigned tag = 0;
Packit cdaae3
    int foundabend = FALSE;
Packit cdaae3
    unsigned abcount = 0;
Packit cdaae3
    struct Dwarf_D_Abbrev_s *firstdab = 0;
Packit cdaae3
    struct Dwarf_D_Abbrev_s *lastdab = 0;
Packit cdaae3
    struct Dwarf_D_Abbrev_s *curdab = 0;
Packit cdaae3
    Dwarf_Debug dbg = dn->din_dbg;
Packit cdaae3
Packit cdaae3
    for (abcur = abdata; abcur < tabend; ) {
Packit cdaae3
        Dwarf_Unsigned idx = 0;
Packit cdaae3
        Dwarf_Unsigned form = 0;
Packit cdaae3
        Dwarf_Small *inner = 0;
Packit cdaae3
        unsigned idxcount = 0;
Packit cdaae3
Packit cdaae3
        DECODE_LEB128_UWORD_CK(abcur,
Packit cdaae3
            code,dbg,error,
Packit cdaae3
            tabend);
Packit cdaae3
        if (code == 0) {
Packit cdaae3
            foundabend = TRUE;
Packit cdaae3
            break;
Packit cdaae3
        }
Packit cdaae3
        /*  abcur updated by macro */
Packit cdaae3
        DECODE_LEB128_UWORD_CK(abcur,
Packit cdaae3
            tag,dbg,error,
Packit cdaae3
            tabend);
Packit cdaae3
        inner = abcur;
Packit cdaae3
        curdab = (struct Dwarf_D_Abbrev_s *)calloc(1,
Packit cdaae3
            sizeof(struct Dwarf_D_Abbrev_s));
Packit cdaae3
        if(!curdab) {
Packit cdaae3
            freedabs(firstdab);
Packit cdaae3
            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
Packit cdaae3
            return DW_DLV_OK;
Packit cdaae3
        }
Packit cdaae3
        curdab->da_tag = tag;
Packit cdaae3
        curdab->da_abbrev_code = code;
Packit cdaae3
        abcount++;
Packit cdaae3
        for(;;) {
Packit cdaae3
            DECODE_LEB128_UWORD_CK(inner,
Packit cdaae3
                idx,dbg,error,
Packit cdaae3
                tabend);
Packit cdaae3
Packit cdaae3
            /*  inner updated by macro */
Packit cdaae3
            DECODE_LEB128_UWORD_CK(inner,
Packit cdaae3
                form,dbg,error,
Packit cdaae3
                tabend);
Packit cdaae3
Packit cdaae3
            if (!idx && !form) {
Packit cdaae3
                break;
Packit cdaae3
            }
Packit cdaae3
            if (idxcount >= ABB_PAIRS_MAX) {
Packit cdaae3
                freedabs(firstdab);
Packit cdaae3
                _dwarf_error(dbg, error,
Packit cdaae3
                    DW_DLE_DEBUG_NAMES_ABBREV_OVERFLOW);
Packit cdaae3
                return DW_DLV_OK;
Packit cdaae3
            }
Packit cdaae3
            curdab->da_pairs[idxcount].ap_index = idx;
Packit cdaae3
            curdab->da_pairs[idxcount].ap_form = form;
Packit cdaae3
            idxcount++;
Packit cdaae3
        }
Packit cdaae3
        curdab->da_pairs_count = idxcount;
Packit cdaae3
        abcur = inner +1;
Packit cdaae3
        if (firstdab) {
Packit cdaae3
            firstdab  = curdab;
Packit cdaae3
            lastdab  = curdab;
Packit cdaae3
        } else {
Packit cdaae3
            firstdab  = curdab;
Packit cdaae3
            lastdab->da_next = curdab;
Packit cdaae3
        }
Packit cdaae3
    }
Packit cdaae3
    if (!foundabend) {
Packit cdaae3
        _dwarf_error(dbg, error,
Packit cdaae3
            DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION);
Packit cdaae3
        return DW_DLV_OK;
Packit cdaae3
    }
Packit cdaae3
    {
Packit cdaae3
        unsigned ct = 0;
Packit cdaae3
        struct Dwarf_D_Abbrev_s *tmpa = 0;
Packit cdaae3
Packit cdaae3
        dn->din_abbrev_list = (struct Dwarf_D_Abbrev_s *)calloc(
Packit cdaae3
            abcount,sizeof(struct Dwarf_D_Abbrev_s));
Packit cdaae3
        if(!dn->din_abbrev_list) {
Packit cdaae3
            freedabs(firstdab);
Packit cdaae3
            _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
Packit cdaae3
            return DW_DLV_ERROR;
Packit cdaae3
        }
Packit cdaae3
        dn->din_abbrev_list_count = abcount;
Packit cdaae3
        tmpa = firstdab;
Packit cdaae3
        for(ct = 0; ct < abcount; ++ct) {
Packit cdaae3
            struct Dwarf_D_Abbrev_s *tmpb =tmpa->da_next;
Packit cdaae3
            /*  da_next no longer means anything */
Packit cdaae3
            tmpa->da_next = 0;
Packit cdaae3
            dn->din_abbrev_list[ct] = *tmpa;
Packit cdaae3
            free(tmpa);
Packit cdaae3
            tmpa = tmpb;
Packit cdaae3
        }
Packit cdaae3
        /*  Now the list has turned into an array. We can ignore
Packit cdaae3
            the list aspect. */
Packit cdaae3
    }
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
static int
Packit cdaae3
get_inhdr_cur(Dwarf_Dnames_Head dn,
Packit cdaae3
    Dwarf_Unsigned index_number,
Packit cdaae3
    struct Dwarf_Dnames_index_header_s **cur,
Packit cdaae3
    Dwarf_Error *error)
Packit cdaae3
{
Packit cdaae3
    Dwarf_Debug dbg = 0;
Packit cdaae3
Packit cdaae3
    if (!dn) {
Packit cdaae3
        _dwarf_error(NULL, error,DW_DLE_DEBUG_NAMES_NULL_POINTER);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    dbg = dn->dn_dbg;
Packit cdaae3
    if (index_number >= dn->dn_inhdr_count) {
Packit cdaae3
        _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    *cur = dn->dn_inhdr_first + index_number;
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
Packit cdaae3
static int
Packit cdaae3
read_uword_val(Dwarf_Debug dbg,
Packit cdaae3
    Dwarf_Small **ptr_in,
Packit cdaae3
    Dwarf_Small *endptr,
Packit cdaae3
    int   errcode,
Packit cdaae3
    Dwarf_ufixed *val_out,
Packit cdaae3
    Dwarf_Unsigned area_length,
Packit cdaae3
    Dwarf_Error *error)
Packit cdaae3
{
Packit cdaae3
    Dwarf_ufixed val = 0;
Packit cdaae3
    Dwarf_Small *ptr = *ptr_in;
Packit cdaae3
Packit cdaae3
    READ_UNALIGNED_CK(dbg, val, Dwarf_ufixed,
Packit cdaae3
        ptr, sizeof(Dwarf_ufixed),
Packit cdaae3
        error,endptr);
Packit cdaae3
    ptr += sizeof(Dwarf_ufixed);
Packit cdaae3
    if (ptr >= endptr) {
Packit cdaae3
        _dwarf_error(dbg, error,errcode);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    /*  Some of the fields are not length fields, but
Packit cdaae3
        if non-zero the size will be longer than
Packit cdaae3
        the value, so we do the following
Packit cdaae3
        overall sanity check to avoid overflows. */
Packit cdaae3
    if (val > area_length) {
Packit cdaae3
        _dwarf_error(dbg, error,errcode);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    *val_out = val;
Packit cdaae3
    *ptr_in = ptr;
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
/*  We do not alter the dn data here. */
Packit cdaae3
static int
Packit cdaae3
read_a_name_index(Dwarf_Dnames_Head dn,
Packit cdaae3
    Dwarf_Unsigned section_offset,
Packit cdaae3
    Dwarf_Small **curptr_in,
Packit cdaae3
    Dwarf_Small *end_section,
Packit cdaae3
    Dwarf_Unsigned remaining_section_size,
Packit cdaae3
    struct Dwarf_Dnames_index_header_s ** index_header_out,
Packit cdaae3
    Dwarf_Error *error)
Packit cdaae3
{
Packit cdaae3
    Dwarf_Unsigned area_length = 0;
Packit cdaae3
    int local_length_size;
Packit cdaae3
    int local_extension_size = 0;
Packit cdaae3
    Dwarf_Small *past_length = 0;
Packit cdaae3
    Dwarf_Small *end_dnames = 0;
Packit cdaae3
    Dwarf_Half version = 0;
Packit cdaae3
    Dwarf_Half padding = 0;
Packit cdaae3
    Dwarf_ufixed comp_unit_count = 0;
Packit cdaae3
    Dwarf_ufixed local_type_unit_count = 0;
Packit cdaae3
    Dwarf_ufixed foreign_type_unit_count = 0;
Packit cdaae3
    Dwarf_ufixed bucket_count = 0;
Packit cdaae3
    Dwarf_ufixed name_count = 0;
Packit cdaae3
    Dwarf_ufixed abbrev_table_size = 0; /* bytes */
Packit cdaae3
    Dwarf_ufixed augmentation_string_size = 0; /* bytes */
Packit cdaae3
    int res = 0;
Packit cdaae3
    const char *str_utf8 = 0;
Packit cdaae3
    Dwarf_Small *curptr = *curptr_in;
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *di_header = 0;
Packit cdaae3
    Dwarf_Debug dbg = dn->dn_dbg;
Packit cdaae3
Packit cdaae3
    READ_AREA_LENGTH_CK(dbg, area_length, Dwarf_Unsigned,
Packit cdaae3
        curptr, local_length_size,
Packit cdaae3
        local_extension_size,error,
Packit cdaae3
        remaining_section_size,end_section);
Packit cdaae3
Packit cdaae3
    /* curptr now points past the length field */
Packit cdaae3
    past_length = curptr;
Packit cdaae3
Packit cdaae3
    /* Two stage length test so overflow is caught. */
Packit cdaae3
    if (area_length > remaining_section_size) {
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    if ((area_length + local_length_size + local_extension_size) >
Packit cdaae3
        remaining_section_size) {
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    end_dnames = curptr + area_length;
Packit cdaae3
Packit cdaae3
    READ_UNALIGNED_CK(dbg, version, Dwarf_Half,
Packit cdaae3
        curptr, sizeof(Dwarf_Half),
Packit cdaae3
        error,end_dnames);
Packit cdaae3
    curptr += sizeof(Dwarf_Half);
Packit cdaae3
    if (curptr >= end_dnames) {
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    if (version != DWARF_DNAMES_VERSION5) {
Packit cdaae3
        _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
Packit cdaae3
        return (DW_DLV_ERROR);
Packit cdaae3
    }
Packit cdaae3
    READ_UNALIGNED_CK(dbg, padding, Dwarf_Half,
Packit cdaae3
        curptr, sizeof(Dwarf_Half),
Packit cdaae3
        error,end_dnames);
Packit cdaae3
    curptr += sizeof(Dwarf_Half);
Packit cdaae3
    if (curptr >= end_dnames) {
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    if (padding) {
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
Packit cdaae3
        return (DW_DLV_ERROR);
Packit cdaae3
    }
Packit cdaae3
    res = read_uword_val(dbg, &curptr,
Packit cdaae3
        end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR,
Packit cdaae3
        &comp_unit_count,area_length,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    res = read_uword_val(dbg, &curptr,
Packit cdaae3
        end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR,
Packit cdaae3
        &local_type_unit_count,area_length,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    res = read_uword_val(dbg, &curptr,
Packit cdaae3
        end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR,
Packit cdaae3
        &foreign_type_unit_count,area_length,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    res = read_uword_val(dbg, &curptr,
Packit cdaae3
        end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR,
Packit cdaae3
        &bucket_count,area_length,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    res = read_uword_val(dbg, &curptr,
Packit cdaae3
        end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR,
Packit cdaae3
        &name_count,area_length,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    res = read_uword_val(dbg, &curptr,
Packit cdaae3
        end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR,
Packit cdaae3
        &abbrev_table_size,area_length,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    res = read_uword_val(dbg, &curptr,
Packit cdaae3
        end_dnames, DW_DLE_DEBUG_NAMES_HEADER_ERROR,
Packit cdaae3
        &augmentation_string_size,area_length,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    str_utf8 = (const char *) curptr;
Packit cdaae3
Packit cdaae3
    curptr+= augmentation_string_size;
Packit cdaae3
    if (curptr >= end_dnames) {
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    di_header = (struct Dwarf_Dnames_index_header_s *)
Packit cdaae3
        calloc(1,sizeof(*di_header));
Packit cdaae3
    if(!di_header) {
Packit cdaae3
        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
Packit cdaae3
        return (DW_DLV_ERROR);
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    di_header->din_dbg = dbg;
Packit cdaae3
    di_header->din_section_offset = section_offset;
Packit cdaae3
    di_header->din_indextable_data = past_length;
Packit cdaae3
    di_header->din_indextable_length = area_length;
Packit cdaae3
    di_header->din_version = version;
Packit cdaae3
    di_header->din_comp_unit_count = comp_unit_count;
Packit cdaae3
    di_header->din_local_type_unit_count = local_type_unit_count ;
Packit cdaae3
    di_header->din_foreign_type_unit_count = foreign_type_unit_count ;
Packit cdaae3
    di_header->din_bucket_count = bucket_count ;
Packit cdaae3
    di_header->din_name_count = name_count ;
Packit cdaae3
    di_header->din_abbrev_table_size = abbrev_table_size;
Packit cdaae3
    di_header->din_augmentation_string_size = augmentation_string_size;
Packit cdaae3
    di_header->din_augmentation_string = calloc(1,
Packit cdaae3
        augmentation_string_size +1);
Packit cdaae3
    strncpy(di_header->din_augmentation_string,str_utf8,
Packit cdaae3
        augmentation_string_size);
Packit cdaae3
Packit cdaae3
    {
Packit cdaae3
        /* This deals with a zero length string too. */
Packit cdaae3
        Dwarf_Unsigned len = augmentation_string_size;
Packit cdaae3
        char *cp = 0;
Packit cdaae3
        char *cpend = 0;
Packit cdaae3
        Dwarf_Bool foundnull = FALSE;
Packit cdaae3
Packit cdaae3
        cp = di_header->din_augmentation_string;
Packit cdaae3
        cpend = cp + len;
Packit cdaae3
        for( ; cp
Packit cdaae3
            if (!*cp) {
Packit cdaae3
                foundnull = TRUE;
Packit cdaae3
                break;
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
        if (!foundnull) {
Packit cdaae3
            /*  Force a NUL terminator in the extra byte
Packit cdaae3
                we calloc-d. */
Packit cdaae3
            cp[len] = 0;
Packit cdaae3
        } else {
Packit cdaae3
            /*  Ensure that there is no corruption in
Packit cdaae3
                the padding. */
Packit cdaae3
            for( ; cp < cpend; ++cp) {
Packit cdaae3
                if(*cp) {
Packit cdaae3
                    _dwarf_error(dbg, error,
Packit cdaae3
                        DW_DLE_DEBUG_NAMES_PAD_NON_ZERO);
Packit cdaae3
                    return DW_DLV_ERROR;
Packit cdaae3
                }
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
    }
Packit cdaae3
    di_header->din_cu_list = curptr;
Packit cdaae3
    curptr +=  dbg->de_length_size * comp_unit_count;
Packit cdaae3
    if(curptr > end_dnames) {
Packit cdaae3
        free(di_header->din_augmentation_string);
Packit cdaae3
        free(di_header);
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    di_header->din_local_tu_list = curptr;
Packit cdaae3
Packit cdaae3
    curptr +=  dbg->de_length_size * local_type_unit_count;
Packit cdaae3
    if(curptr > end_dnames) {
Packit cdaae3
        free(di_header->din_augmentation_string);
Packit cdaae3
        free(di_header);
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    di_header->din_foreign_tu_list = curptr;
Packit cdaae3
    curptr +=  sizeof(Dwarf_Sig8) * foreign_type_unit_count;
Packit cdaae3
    if(curptr > end_dnames) {
Packit cdaae3
        free(di_header->din_augmentation_string);
Packit cdaae3
        free(di_header);
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    di_header->din_buckets = curptr;
Packit cdaae3
    curptr +=  sizeof(Dwarf_ufixed) * bucket_count;
Packit cdaae3
    if(curptr > end_dnames) {
Packit cdaae3
        free(di_header->din_augmentation_string);
Packit cdaae3
        free(di_header);
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    di_header->din_hash_table = curptr;
Packit cdaae3
    curptr +=  sizeof(Dwarf_Sig8) * name_count;
Packit cdaae3
    if(curptr > end_dnames) {
Packit cdaae3
        free(di_header->din_augmentation_string);
Packit cdaae3
        free(di_header);
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    di_header->din_string_offsets = curptr;
Packit cdaae3
    curptr +=  sizeof(Dwarf_ufixed) * name_count;
Packit cdaae3
    if(curptr > end_dnames) {
Packit cdaae3
        free(di_header->din_augmentation_string);
Packit cdaae3
        free(di_header);
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    di_header->din_entry_offsets = curptr;
Packit cdaae3
    curptr +=  sizeof(Dwarf_ufixed) * name_count;
Packit cdaae3
    if(curptr > end_dnames) {
Packit cdaae3
        free(di_header->din_augmentation_string);
Packit cdaae3
        free(di_header);
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    di_header->din_abbreviations = curptr;
Packit cdaae3
    curptr +=   abbrev_table_size;
Packit cdaae3
    if(curptr > end_dnames) {
Packit cdaae3
        free(di_header->din_augmentation_string);
Packit cdaae3
        free(di_header);
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_HEADER_ERROR);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    di_header->din_entry_pool = curptr;
Packit cdaae3
    di_header->din_offset_size = local_length_size;
Packit cdaae3
Packit cdaae3
    di_header->din_entry_pool_size = end_dnames - curptr;
Packit cdaae3
Packit cdaae3
    *curptr_in = curptr;
Packit cdaae3
    *index_header_out = di_header;
Packit cdaae3
    res = fill_in_abbrevs_table(di_header,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        free(di_header->din_augmentation_string);
Packit cdaae3
        free(di_header);
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
#define FAKE_LAST_USED 0xffffffff
Packit cdaae3
Packit cdaae3
static void
Packit cdaae3
free_inhdr_content(struct Dwarf_Dnames_index_header_s *f)
Packit cdaae3
{
Packit cdaae3
    free(f->din_augmentation_string);
Packit cdaae3
    free(f->din_abbrev_list);
Packit cdaae3
}
Packit cdaae3
static void
Packit cdaae3
free_inhdr_list(struct Dwarf_Dnames_index_header_s *f)
Packit cdaae3
{
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *tmp = 0;
Packit cdaae3
Packit cdaae3
    for( ; f ; f = tmp) {
Packit cdaae3
        tmp = f->din_next;
Packit cdaae3
        free_inhdr_content(f);
Packit cdaae3
        free(f);
Packit cdaae3
    }
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
/*  There may be one debug index for an entire object file,
Packit cdaae3
    for multiple CUs or there can be individual indexes
Packit cdaae3
    for some CUs.
Packit cdaae3
    see DWARF5 6.1.1.3 Per_CU versus Per-Module Indexes. */
Packit cdaae3
int
Packit cdaae3
dwarf_debugnames_header(Dwarf_Debug dbg,
Packit cdaae3
    Dwarf_Dnames_Head * dn_out,
Packit cdaae3
    Dwarf_Unsigned    * dn_count_out,
Packit cdaae3
    Dwarf_Error *error)
Packit cdaae3
{
Packit cdaae3
    Dwarf_Unsigned remaining = 0;
Packit cdaae3
    Dwarf_Dnames_Head dn_header = 0;
Packit cdaae3
    Dwarf_Unsigned section_size;
Packit cdaae3
    Dwarf_Small *start_section = 0;
Packit cdaae3
    Dwarf_Small *end_section = 0;
Packit cdaae3
    Dwarf_Small *curptr = 0;
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *inhdr_last = 0;
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *inhdr_first = 0;
Packit cdaae3
    unsigned inhdr_count = 0;
Packit cdaae3
    int res = 0;
Packit cdaae3
Packit cdaae3
    if(!dbg) {
Packit cdaae3
        _dwarf_error(dbg, error,DW_DLE_DBG_NULL);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    res = _dwarf_load_section(dbg, &dbg->de_debug_names, error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    section_size = dbg->de_debug_names.dss_size;
Packit cdaae3
    if(!section_size){
Packit cdaae3
        return DW_DLV_NO_ENTRY;
Packit cdaae3
    }
Packit cdaae3
    start_section = dbg->de_debug_names.dss_data;
Packit cdaae3
    curptr = start_section;
Packit cdaae3
    end_section = start_section + section_size;
Packit cdaae3
    remaining = section_size;
Packit cdaae3
    dn_header =  (Dwarf_Dnames_Head)_dwarf_get_alloc(dbg,
Packit cdaae3
        DW_DLA_DNAMES_HEAD, 1);
Packit cdaae3
    if(!dn_header) {
Packit cdaae3
        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
Packit cdaae3
        return (DW_DLV_ERROR);
Packit cdaae3
    }
Packit cdaae3
    dn_header->dn_section_data = start_section;
Packit cdaae3
    dn_header->dn_section_size = section_size;
Packit cdaae3
    dn_header->dn_section_end = start_section + section_size;
Packit cdaae3
    dn_header->dn_dbg = dbg;
Packit cdaae3
    for( ; curptr < end_section; ) {
Packit cdaae3
        struct Dwarf_Dnames_index_header_s * index_header = 0;
Packit cdaae3
        Dwarf_Small *curptr_start = curptr;
Packit cdaae3
        Dwarf_Unsigned usedspace = 0;
Packit cdaae3
        Dwarf_Unsigned section_offset = curptr - start_section;
Packit cdaae3
Packit cdaae3
        res = read_a_name_index(dn_header,
Packit cdaae3
            section_offset,
Packit cdaae3
            &curptr,
Packit cdaae3
            end_section,
Packit cdaae3
            remaining,
Packit cdaae3
            &index_header,
Packit cdaae3
            error);
Packit cdaae3
        if (res == DW_DLV_ERROR) {
Packit cdaae3
            free_inhdr_list(inhdr_first);
Packit cdaae3
            dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD);
Packit cdaae3
            return res;
Packit cdaae3
        }
Packit cdaae3
        if (res == DW_DLV_NO_ENTRY) {
Packit cdaae3
            /*  Impossible. A bug. Or possibly
Packit cdaae3
                a bunch of zero pad? */
Packit cdaae3
            free_inhdr_list(inhdr_first);
Packit cdaae3
            dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD);
Packit cdaae3
            break;
Packit cdaae3
        }
Packit cdaae3
        /* Add the new one to the list. */
Packit cdaae3
        if(!inhdr_first) {
Packit cdaae3
            inhdr_count = 1;
Packit cdaae3
            inhdr_first = index_header;
Packit cdaae3
            inhdr_last = index_header;
Packit cdaae3
        } else {
Packit cdaae3
            struct Dwarf_Dnames_index_header_s *tmp = inhdr_last;
Packit cdaae3
            inhdr_last = index_header;
Packit cdaae3
            tmp->din_next = index_header;
Packit cdaae3
            inhdr_count++;
Packit cdaae3
        }
Packit cdaae3
        usedspace = curptr - curptr_start;
Packit cdaae3
        remaining -= - usedspace;
Packit cdaae3
        if (remaining < 5) {
Packit cdaae3
            /*  No more in here, just padding. Check for zero
Packit cdaae3
                in padding. */
Packit cdaae3
            if ((curptr +remaining) < end_section) {
Packit cdaae3
                free_inhdr_list(inhdr_first);
Packit cdaae3
                dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD);
Packit cdaae3
                _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_OFF_END);
Packit cdaae3
                return DW_DLV_ERROR;
Packit cdaae3
            }
Packit cdaae3
            for ( ; curptr < end_section; ++curptr) {
Packit cdaae3
                if(*curptr) {
Packit cdaae3
                    /*  One could argue this is a harmless error,
Packit cdaae3
                        but for now assume it is real corruption. */
Packit cdaae3
                    free_inhdr_list(inhdr_first);
Packit cdaae3
                    dwarf_dealloc(dbg,dn_header,DW_DLA_DNAMES_HEAD);
Packit cdaae3
                    _dwarf_error(dbg, error,DW_DLE_DEBUG_NAMES_PAD_NON_ZERO);
Packit cdaae3
                    return DW_DLV_ERROR;
Packit cdaae3
                }
Packit cdaae3
            }
Packit cdaae3
        }
Packit cdaae3
    }
Packit cdaae3
    {
Packit cdaae3
        struct Dwarf_Dnames_index_header_s *cur = 0;
Packit cdaae3
        int n = 0;
Packit cdaae3
Packit cdaae3
        dn_header->dn_inhdr_first =
Packit cdaae3
            (struct Dwarf_Dnames_index_header_s *)
Packit cdaae3
            calloc(inhdr_count,sizeof(struct Dwarf_Dnames_index_header_s));
Packit cdaae3
        for(n = 0,cur = inhdr_first; cur; ++n ) {
Packit cdaae3
            /*  We are copying these structs so do not
Packit cdaae3
                free them at this time. */
Packit cdaae3
            struct Dwarf_Dnames_index_header_s *tmp = cur->din_next;
Packit cdaae3
            dn_header->dn_inhdr_first[n] = *cur;
Packit cdaae3
            cur = tmp;
Packit cdaae3
        }
Packit cdaae3
    }
Packit cdaae3
    *dn_out = dn_header;
Packit cdaae3
    *dn_count_out = inhdr_count;
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
Packit cdaae3
int dwarf_debugnames_sizes(Dwarf_Dnames_Head dn,
Packit cdaae3
    Dwarf_Unsigned   index_number,
Packit cdaae3
Packit cdaae3
    Dwarf_Unsigned * section_offset,
Packit cdaae3
    Dwarf_Unsigned * version,     /* 5 */
Packit cdaae3
    Dwarf_Unsigned * offset_size, /* 4 or 8 */
Packit cdaae3
Packit cdaae3
    /* The counts are entry counts, not bye sizes. */
Packit cdaae3
    Dwarf_Unsigned * comp_unit_count,
Packit cdaae3
    Dwarf_Unsigned * local_type_unit_count,
Packit cdaae3
    Dwarf_Unsigned * foreign_type_unit_count,
Packit cdaae3
    Dwarf_Unsigned * bucket_count,
Packit cdaae3
    Dwarf_Unsigned * name_count,
Packit cdaae3
Packit cdaae3
    /* The following are counted in bytes */
Packit cdaae3
    Dwarf_Unsigned * indextable_overall_length,
Packit cdaae3
    Dwarf_Unsigned * abbrev_table_size,
Packit cdaae3
    Dwarf_Unsigned * entry_pool_size,
Packit cdaae3
    Dwarf_Unsigned * augmentation_string_size,
Packit cdaae3
Packit cdaae3
    Dwarf_Error *    error)
Packit cdaae3
{
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *cur = 0;
Packit cdaae3
    int res = 0;
Packit cdaae3
Packit cdaae3
    res = get_inhdr_cur(dn,index_number,&cur,error);
Packit cdaae3
    if(res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (section_offset) {
Packit cdaae3
        *section_offset = cur->din_section_offset;
Packit cdaae3
    }
Packit cdaae3
    if (version) {
Packit cdaae3
        *version = cur->din_version;
Packit cdaae3
    }
Packit cdaae3
    if (offset_size) {
Packit cdaae3
        *offset_size = cur->din_offset_size;
Packit cdaae3
    }
Packit cdaae3
    if (comp_unit_count) {
Packit cdaae3
        *comp_unit_count = cur->din_comp_unit_count;
Packit cdaae3
    }
Packit cdaae3
    if (local_type_unit_count) {
Packit cdaae3
        *local_type_unit_count = cur->din_local_type_unit_count;
Packit cdaae3
    }
Packit cdaae3
    if (foreign_type_unit_count) {
Packit cdaae3
        *foreign_type_unit_count = cur->din_foreign_type_unit_count;
Packit cdaae3
    }
Packit cdaae3
    if (bucket_count) {
Packit cdaae3
        *bucket_count = cur->din_bucket_count;
Packit cdaae3
    }
Packit cdaae3
    if (name_count) {
Packit cdaae3
        *name_count = cur->din_name_count;
Packit cdaae3
    }
Packit cdaae3
    if (abbrev_table_size) {
Packit cdaae3
        *abbrev_table_size = cur->din_abbrev_table_size;
Packit cdaae3
    }
Packit cdaae3
    if (entry_pool_size) {
Packit cdaae3
        *entry_pool_size = cur->din_entry_pool_size;
Packit cdaae3
    }
Packit cdaae3
    if (augmentation_string_size) {
Packit cdaae3
        *augmentation_string_size = cur->din_augmentation_string_size;
Packit cdaae3
    }
Packit cdaae3
    if (indextable_overall_length) {
Packit cdaae3
        *indextable_overall_length =  cur->din_indextable_length;
Packit cdaae3
    }
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
int
Packit cdaae3
dwarf_debugnames_cu_entry(Dwarf_Dnames_Head dn,
Packit cdaae3
    Dwarf_Unsigned      index_number,
Packit cdaae3
    Dwarf_Unsigned      offset_number,
Packit cdaae3
    Dwarf_Unsigned    * offset_count,
Packit cdaae3
    Dwarf_Unsigned    * offset,
Packit cdaae3
    Dwarf_Error *       error)
Packit cdaae3
{
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *cur = 0;
Packit cdaae3
    Dwarf_Debug dbg = 0;
Packit cdaae3
    int res;
Packit cdaae3
Packit cdaae3
    res = get_inhdr_cur(dn,index_number,&cur,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    dbg = dn->dn_dbg;
Packit cdaae3
Packit cdaae3
    if (offset_number >= cur->din_comp_unit_count) {
Packit cdaae3
        if (offset_count) {
Packit cdaae3
            *offset_count = cur->din_comp_unit_count;
Packit cdaae3
        }
Packit cdaae3
        return DW_DLV_NO_ENTRY;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
Packit cdaae3
    if (offset) {
Packit cdaae3
        Dwarf_Unsigned offsetval = 0;
Packit cdaae3
        Dwarf_Small *ptr = cur->din_cu_list +
Packit cdaae3
            offset_number *cur->din_offset_size;
Packit cdaae3
        Dwarf_Small *endptr = cur->din_local_tu_list;
Packit cdaae3
Packit cdaae3
        READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned,
Packit cdaae3
            ptr, cur->din_offset_size,
Packit cdaae3
            error,endptr);
Packit cdaae3
        *offset = offsetval;
Packit cdaae3
    }
Packit cdaae3
    if (offset_count) {
Packit cdaae3
        *offset_count = cur->din_comp_unit_count;
Packit cdaae3
    }
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
int
Packit cdaae3
dwarf_debugnames_local_tu_entry(Dwarf_Dnames_Head dn,
Packit cdaae3
    Dwarf_Unsigned      index_number,
Packit cdaae3
    Dwarf_Unsigned      offset_number,
Packit cdaae3
    Dwarf_Unsigned    * offset_count,
Packit cdaae3
    Dwarf_Unsigned    * offset,
Packit cdaae3
    Dwarf_Error *       error)
Packit cdaae3
{
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *cur = 0;
Packit cdaae3
    Dwarf_Debug dbg = 0;
Packit cdaae3
    int res;
Packit cdaae3
Packit cdaae3
    res = get_inhdr_cur(dn,index_number,&cur,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    dbg = dn->dn_dbg;
Packit cdaae3
Packit cdaae3
    if (offset_number >= cur->din_local_type_unit_count) {
Packit cdaae3
        if (offset_count) {
Packit cdaae3
            *offset_count = cur->din_local_type_unit_count;
Packit cdaae3
        }
Packit cdaae3
        return DW_DLV_NO_ENTRY;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
Packit cdaae3
    if (offset) {
Packit cdaae3
        Dwarf_Unsigned offsetval = 0;
Packit cdaae3
        Dwarf_Small *ptr = cur->din_local_tu_list +
Packit cdaae3
            offset_number *cur->din_offset_size;
Packit cdaae3
        Dwarf_Small *endptr = cur->din_foreign_tu_list;
Packit cdaae3
Packit cdaae3
        READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned,
Packit cdaae3
            ptr, cur->din_offset_size,
Packit cdaae3
            error,endptr);
Packit cdaae3
        *offset = offsetval;
Packit cdaae3
    }
Packit cdaae3
    if (offset_count) {
Packit cdaae3
        *offset_count = cur->din_local_type_unit_count;
Packit cdaae3
    }
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
Packit cdaae3
Packit cdaae3
/*  Here the sig_number ranges from
Packit cdaae3
    local_type_unit_count to
Packit cdaae3
    local_type_unit_count+foreign_type_unit_count-1
Packit cdaae3
    because the foreign indices are a continuation
Packit cdaae3
    of the local tu indices.
Packit cdaae3
*/
Packit cdaae3
int
Packit cdaae3
dwarf_debugnames_foreign_tu_entry(Dwarf_Dnames_Head dn,
Packit cdaae3
    Dwarf_Unsigned      index_number,
Packit cdaae3
    Dwarf_Unsigned      sig_number,
Packit cdaae3
Packit cdaae3
    /* these index starting at local_type_unit_count */
Packit cdaae3
    Dwarf_Unsigned    * sig_minimum,
Packit cdaae3
    Dwarf_Unsigned    * sig_count,
Packit cdaae3
    Dwarf_Sig8 *        signature,
Packit cdaae3
    Dwarf_Error *       error)
Packit cdaae3
{
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *cur = 0;
Packit cdaae3
    Dwarf_Debug dbg = 0;
Packit cdaae3
    int res;
Packit cdaae3
    unsigned legal_low = 0;
Packit cdaae3
    unsigned legal_high = 0;
Packit cdaae3
Packit cdaae3
    res = get_inhdr_cur(dn,index_number,&cur,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    dbg = dn->dn_dbg;
Packit cdaae3
    legal_low = cur->din_local_type_unit_count;
Packit cdaae3
    legal_high = legal_low + cur->din_foreign_type_unit_count;
Packit cdaae3
    if (sig_number < legal_low) {
Packit cdaae3
        _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    if (sig_number >= legal_high) {
Packit cdaae3
        if (sig_minimum) {
Packit cdaae3
            *sig_minimum = legal_low;
Packit cdaae3
        }
Packit cdaae3
        if (sig_count) {
Packit cdaae3
            *sig_count = cur->din_foreign_type_unit_count;
Packit cdaae3
        }
Packit cdaae3
        return DW_DLV_NO_ENTRY;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (signature) {
Packit cdaae3
        Dwarf_Small *ptr = cur->din_foreign_tu_list +
Packit cdaae3
            sig_number *cur->din_offset_size;
Packit cdaae3
        Dwarf_Small *endptr = cur->din_hash_table;
Packit cdaae3
        if((ptr +sizeof(Dwarf_Sig8)) > endptr) {
Packit cdaae3
            _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG);
Packit cdaae3
            return DW_DLV_ERROR;
Packit cdaae3
        }
Packit cdaae3
        memcpy(signature,ptr,sizeof(Dwarf_Sig8));
Packit cdaae3
    }
Packit cdaae3
    if (sig_minimum) {
Packit cdaae3
        *sig_minimum = legal_low;
Packit cdaae3
    }
Packit cdaae3
    if (sig_count) {
Packit cdaae3
        *sig_count = cur->din_foreign_type_unit_count;
Packit cdaae3
    }
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
/*  The hash table is composed of the buckets table
Packit cdaae3
    and the hashes table.
Packit cdaae3
    If there is no buckets table (bucket_count == 0)
Packit cdaae3
    the hashes part still exists. */
Packit cdaae3
int dwarf_debugnames_bucket(Dwarf_Dnames_Head dn,
Packit cdaae3
    Dwarf_Unsigned      index_number,
Packit cdaae3
    Dwarf_Unsigned      bucket_number,
Packit cdaae3
    Dwarf_Unsigned    * bucket_count,
Packit cdaae3
    Dwarf_Unsigned    * index_of_name_entry,
Packit cdaae3
    Dwarf_Error *       error)
Packit cdaae3
{
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *cur = 0;
Packit cdaae3
    Dwarf_Debug dbg = 0;
Packit cdaae3
    int res;
Packit cdaae3
Packit cdaae3
    res = get_inhdr_cur(dn,index_number,&cur,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    dbg = dn->dn_dbg;
Packit cdaae3
Packit cdaae3
    if (bucket_number >= cur->din_bucket_count) {
Packit cdaae3
        if (bucket_count) {
Packit cdaae3
            *bucket_count = cur->din_bucket_count;
Packit cdaae3
        }
Packit cdaae3
        return DW_DLV_NO_ENTRY;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (index_of_name_entry) {
Packit cdaae3
        Dwarf_Unsigned offsetval = 0;
Packit cdaae3
        Dwarf_Small *ptr = cur->din_buckets +
Packit cdaae3
            bucket_number * sizeof(Dwarf_ufixed);
Packit cdaae3
        Dwarf_Small *endptr = cur->din_hash_table;
Packit cdaae3
Packit cdaae3
        READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned,
Packit cdaae3
            ptr, sizeof(Dwarf_ufixed),
Packit cdaae3
            error,endptr);
Packit cdaae3
        *index_of_name_entry = offsetval;
Packit cdaae3
    }
Packit cdaae3
    if (bucket_count) {
Packit cdaae3
        *bucket_count = cur->din_bucket_count;
Packit cdaae3
    }
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
/*  Access to the .debug_names name table. */
Packit cdaae3
int
Packit cdaae3
dwarf_debugnames_name(Dwarf_Dnames_Head dn,
Packit cdaae3
    Dwarf_Unsigned      index_number,
Packit cdaae3
    Dwarf_Unsigned      name_entry,
Packit cdaae3
    Dwarf_Unsigned    * names_count,
Packit cdaae3
    Dwarf_Sig8        * signature,
Packit cdaae3
    Dwarf_Unsigned    * offset_to_debug_str,
Packit cdaae3
    Dwarf_Unsigned    * offset_in_entrypool,
Packit cdaae3
    Dwarf_Error *       error)
Packit cdaae3
Packit cdaae3
{
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *cur = 0;
Packit cdaae3
    Dwarf_Debug dbg = 0;
Packit cdaae3
    int res;
Packit cdaae3
Packit cdaae3
    res = get_inhdr_cur(dn,index_number,&cur,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    dbg = dn->dn_dbg;
Packit cdaae3
Packit cdaae3
    if (name_entry >= cur->din_name_count) {
Packit cdaae3
        if (names_count) {
Packit cdaae3
            *names_count = cur->din_bucket_count;
Packit cdaae3
        }
Packit cdaae3
        return DW_DLV_NO_ENTRY;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (signature) {
Packit cdaae3
        Dwarf_Small *ptr = cur->din_hash_table +
Packit cdaae3
            name_entry *sizeof(Dwarf_Sig8);
Packit cdaae3
        Dwarf_Small *endptr = cur->din_string_offsets;
Packit cdaae3
        if ((ptr + sizeof(Dwarf_Sig8)) > endptr) {
Packit cdaae3
            _dwarf_error(dbg, error, DW_DLE_DEBUG_NAMES_BAD_INDEX_ARG);
Packit cdaae3
            return DW_DLV_ERROR;
Packit cdaae3
        }
Packit cdaae3
        memcpy(signature,ptr,sizeof(Dwarf_Sig8));
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (offset_to_debug_str) {
Packit cdaae3
        Dwarf_Unsigned offsetval = 0;
Packit cdaae3
        Dwarf_Small *ptr = cur->din_string_offsets +
Packit cdaae3
            name_entry * sizeof(Dwarf_ufixed);
Packit cdaae3
        Dwarf_Small *endptr = cur->din_abbreviations;
Packit cdaae3
Packit cdaae3
        READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned,
Packit cdaae3
            ptr, sizeof(Dwarf_ufixed),
Packit cdaae3
            error,endptr);
Packit cdaae3
        *offset_to_debug_str = offsetval;
Packit cdaae3
    }
Packit cdaae3
    if (offset_in_entrypool) {
Packit cdaae3
        Dwarf_Unsigned offsetval = 0;
Packit cdaae3
        Dwarf_Small *ptr = cur->din_entry_offsets +
Packit cdaae3
            name_entry * sizeof(Dwarf_ufixed);
Packit cdaae3
        Dwarf_Small *endptr = cur->din_abbreviations;
Packit cdaae3
Packit cdaae3
        READ_UNALIGNED_CK(dbg, offsetval, Dwarf_Unsigned,
Packit cdaae3
            ptr, sizeof(Dwarf_ufixed),
Packit cdaae3
            error,endptr);
Packit cdaae3
        *offset_in_entrypool = offsetval;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (names_count) {
Packit cdaae3
        *names_count = cur->din_name_count;
Packit cdaae3
    }
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
Packit cdaae3
Packit cdaae3
Packit cdaae3
Packit cdaae3
Packit cdaae3
/*  If abbrev_code returned is zero there is no tag returned
Packit cdaae3
    and we are at the end of the entry pool set for this name
Packit cdaae3
    entry.
Packit cdaae3
        abbrev code, tag
Packit cdaae3
        nameindexattr,form
Packit cdaae3
        ...
Packit cdaae3
        0,0
Packit cdaae3
        ... repeat like the above
Packit cdaae3
        0
Packit cdaae3
*/
Packit cdaae3
Packit cdaae3
/*  This provides a way to print the abbrev table by
Packit cdaae3
    indexing from 0.  */
Packit cdaae3
int
Packit cdaae3
dwarf_debugnames_abbrev_by_index(Dwarf_Dnames_Head dn,
Packit cdaae3
    Dwarf_Unsigned   index_number,
Packit cdaae3
    Dwarf_Unsigned   abbrev_entry,
Packit cdaae3
    Dwarf_Unsigned * abbrev_code,
Packit cdaae3
    Dwarf_Unsigned * tag,
Packit cdaae3
Packit cdaae3
    /*  The number of valid abbrev_entry values: 0 to number_of_abbrev-1
Packit cdaae3
        */
Packit cdaae3
    Dwarf_Unsigned *  number_of_abbrev,
Packit cdaae3
Packit cdaae3
    /*  The number of attr/form pairs, not counting the trailing
Packit cdaae3
        0,0 pair. */
Packit cdaae3
    Dwarf_Unsigned *  number_of_attr_form_entries,
Packit cdaae3
    Dwarf_Error *error)
Packit cdaae3
{
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *cur = 0;
Packit cdaae3
    struct Dwarf_D_Abbrev_s * abbrev = 0;
Packit cdaae3
    int res = 0;
Packit cdaae3
Packit cdaae3
    res = get_inhdr_cur(dn,index_number,&cur,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (abbrev_entry >= cur->din_abbrev_list_count) {
Packit cdaae3
        if (number_of_abbrev) {
Packit cdaae3
            *number_of_abbrev = cur->din_abbrev_list_count;
Packit cdaae3
        }
Packit cdaae3
        return DW_DLV_NO_ENTRY;
Packit cdaae3
    }
Packit cdaae3
    abbrev = cur->din_abbrev_list + abbrev_entry;
Packit cdaae3
    if(abbrev_code) {
Packit cdaae3
        *abbrev_code = abbrev->da_abbrev_code;
Packit cdaae3
    }
Packit cdaae3
    if(tag) {
Packit cdaae3
        *tag = abbrev->da_tag;
Packit cdaae3
    }
Packit cdaae3
    if(number_of_abbrev) {
Packit cdaae3
        *number_of_abbrev = cur->din_abbrev_list_count;
Packit cdaae3
    }
Packit cdaae3
    if(number_of_attr_form_entries) {
Packit cdaae3
        *number_of_attr_form_entries = abbrev->da_pairs_count;
Packit cdaae3
    }
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
static int
Packit cdaae3
_dwarf_internal_abbrev_by_code(struct Dwarf_Dnames_index_header_s *cur,
Packit cdaae3
    Dwarf_Unsigned abbrev_code,
Packit cdaae3
    Dwarf_Unsigned *  tag,
Packit cdaae3
    Dwarf_Unsigned *  index_of_abbrev,
Packit cdaae3
    Dwarf_Unsigned *  number_of_attr_form_entries)
Packit cdaae3
{
Packit cdaae3
    unsigned n = 0;
Packit cdaae3
    struct Dwarf_D_Abbrev_s * abbrev = 0;
Packit cdaae3
Packit cdaae3
    abbrev = cur->din_abbrev_list;
Packit cdaae3
    for(n = 0; n < cur->din_abbrev_list_count; ++n,++abbrev) {
Packit cdaae3
        if (abbrev_code == abbrev->da_abbrev_code) {
Packit cdaae3
            if (tag) {
Packit cdaae3
                *tag = abbrev->da_tag;
Packit cdaae3
            }
Packit cdaae3
            if (index_of_abbrev) {
Packit cdaae3
                *index_of_abbrev = n;
Packit cdaae3
            }
Packit cdaae3
            if (number_of_attr_form_entries) {
Packit cdaae3
                *number_of_attr_form_entries = abbrev->da_pairs_count;
Packit cdaae3
            }
Packit cdaae3
            return DW_DLV_OK;
Packit cdaae3
        }
Packit cdaae3
    }
Packit cdaae3
    /*  Something is wrong, not found! */
Packit cdaae3
    return DW_DLV_NO_ENTRY;
Packit cdaae3
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
/* Access the abbrev by abbrev code (instead of index). */
Packit cdaae3
int
Packit cdaae3
dwarf_debugnames_abbrev_by_code(Dwarf_Dnames_Head dn,
Packit cdaae3
    Dwarf_Unsigned    index_number,
Packit cdaae3
    Dwarf_Unsigned    abbrev_code,
Packit cdaae3
    Dwarf_Unsigned *  tag,
Packit cdaae3
Packit cdaae3
    /*  The number of this code/tag as an array index. */
Packit cdaae3
    Dwarf_Unsigned *  index_of_abbrev,
Packit cdaae3
Packit cdaae3
    /*  The number of attr/form pairs, not counting the trailing
Packit cdaae3
        0,0 pair. */
Packit cdaae3
    Dwarf_Unsigned * number_of_attr_form_entries,
Packit cdaae3
    Dwarf_Error *    error)
Packit cdaae3
{
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *cur = 0;
Packit cdaae3
    int res;
Packit cdaae3
Packit cdaae3
    res = get_inhdr_cur(dn,index_number,&cur,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    res = _dwarf_internal_abbrev_by_code(cur,
Packit cdaae3
        abbrev_code,
Packit cdaae3
        tag, index_of_abbrev,
Packit cdaae3
        number_of_attr_form_entries);
Packit cdaae3
    return res;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
Packit cdaae3
int
Packit cdaae3
dwarf_debugnames_abbrev_form_by_index(Dwarf_Dnames_Head dn,
Packit cdaae3
    Dwarf_Unsigned    index_number,
Packit cdaae3
    Dwarf_Unsigned    abbrev_entry_index,
Packit cdaae3
    Dwarf_Unsigned    abbrev_form_index,
Packit cdaae3
    Dwarf_Unsigned  * name_index_attr,
Packit cdaae3
    Dwarf_Unsigned  * form,
Packit cdaae3
    Dwarf_Unsigned *  number_of_attr_form_entries,
Packit cdaae3
    Dwarf_Error    *  error)
Packit cdaae3
{
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *cur = 0;
Packit cdaae3
    struct Dwarf_D_Abbrev_s * abbrev = 0;
Packit cdaae3
    struct abbrev_pair_s *ap = 0;
Packit cdaae3
    int res;
Packit cdaae3
Packit cdaae3
    res = get_inhdr_cur(dn,index_number,&cur,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
Packit cdaae3
    if (abbrev_entry_index >= cur->din_abbrev_list_count) {
Packit cdaae3
        if (number_of_attr_form_entries) {
Packit cdaae3
            *number_of_attr_form_entries = cur->din_bucket_count;
Packit cdaae3
        }
Packit cdaae3
        return DW_DLV_NO_ENTRY;
Packit cdaae3
    }
Packit cdaae3
    abbrev = cur->din_abbrev_list + abbrev_entry_index;
Packit cdaae3
    if (abbrev_form_index >= abbrev->da_pairs_count) {
Packit cdaae3
        return DW_DLV_NO_ENTRY;
Packit cdaae3
    }
Packit cdaae3
    ap = abbrev->da_pairs + abbrev_entry_index;
Packit cdaae3
    if(name_index_attr) {
Packit cdaae3
        *name_index_attr = ap->ap_index;
Packit cdaae3
    }
Packit cdaae3
    if(form) {
Packit cdaae3
        *form = ap->ap_form;
Packit cdaae3
    }
Packit cdaae3
    if(number_of_attr_form_entries) {
Packit cdaae3
        *number_of_attr_form_entries = abbrev->da_pairs_count;
Packit cdaae3
    }
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
/*  This, combined with dwarf_debugnames_entrypool_values(),
Packit cdaae3
    lets one examine as much or as little of an entrypool
Packit cdaae3
    as one wants to by alternately calling these two
Packit cdaae3
    functions. */
Packit cdaae3
Packit cdaae3
int dwarf_debugnames_entrypool(Dwarf_Dnames_Head dn,
Packit cdaae3
    Dwarf_Unsigned      index_number,
Packit cdaae3
    Dwarf_Unsigned      offset_in_entrypool,
Packit cdaae3
    Dwarf_Unsigned       *    abbrev_code,
Packit cdaae3
    Dwarf_Unsigned       *    tag,
Packit cdaae3
    Dwarf_Unsigned       *    value_count,
Packit cdaae3
    Dwarf_Unsigned       *    index_of_abbrev,
Packit cdaae3
    Dwarf_Unsigned *    offset_of_initial_value,
Packit cdaae3
    Dwarf_Error *       error)
Packit cdaae3
{
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *cur = 0;
Packit cdaae3
    Dwarf_Debug dbg = 0;
Packit cdaae3
    int res = 0;
Packit cdaae3
    Dwarf_Small *entrypool = 0;
Packit cdaae3
    Dwarf_Small *endentrypool = 0;
Packit cdaae3
    Dwarf_Unsigned abcode = 0;
Packit cdaae3
    Dwarf_Unsigned leblen = 0;
Packit cdaae3
Packit cdaae3
    res = get_inhdr_cur(dn,index_number,&cur,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    dbg = dn->dn_dbg;
Packit cdaae3
Packit cdaae3
    if (offset_in_entrypool >= cur->din_entry_pool_size) {
Packit cdaae3
        _dwarf_error(NULL, error,DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    endentrypool = cur->din_entry_pool +cur->din_entry_pool_size;
Packit cdaae3
    entrypool = cur->din_entry_pool + offset_in_entrypool;
Packit cdaae3
Packit cdaae3
    DECODE_LEB128_UWORD_LEN_CK(entrypool,abcode,leblen,
Packit cdaae3
        dbg,error,endentrypool);
Packit cdaae3
Packit cdaae3
    res = _dwarf_internal_abbrev_by_code(cur,
Packit cdaae3
        abcode,
Packit cdaae3
        tag, index_of_abbrev,
Packit cdaae3
        value_count);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        /* Never DW_DLV_ERROR (so far) */
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    *offset_of_initial_value = offset_in_entrypool + leblen;
Packit cdaae3
    *abbrev_code = abcode;
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
Packit cdaae3
/*  Caller, knowing array size needed, passes in arrays
Packit cdaae3
    it allocates of for idx, form, offset-size-values,
Packit cdaae3
    and signature values.  Caller must examine idx-number
Packit cdaae3
    and form to decide, for each array element, whether
Packit cdaae3
    the offset or the signature contains the value.
Packit cdaae3
    So this returns all the values for the abbrev code.
Packit cdaae3
    And points via offset_of_next to the next abbrev code.
Packit cdaae3
Packit cdaae3
    While an array of structs would be easier for the caller
Packit cdaae3
    to allocate than parallel arrays, public structs have
Packit cdaae3
    turned out to be difficult to work with as interfaces
Packit cdaae3
    (as formats change over time).
Packit cdaae3
    */
Packit cdaae3
int dwarf_debugnames_entrypool_values(Dwarf_Dnames_Head dn,
Packit cdaae3
    Dwarf_Unsigned      index_number,
Packit cdaae3
    Dwarf_Unsigned      index_of_abbrev,
Packit cdaae3
    Dwarf_Unsigned      offset_in_entrypool_of_values,
Packit cdaae3
    Dwarf_Unsigned *    array_dw_idx_number,
Packit cdaae3
    Dwarf_Unsigned *    array_form,
Packit cdaae3
    Dwarf_Unsigned *    array_of_offsets,
Packit cdaae3
    Dwarf_Sig8     *    array_of_signatures,
Packit cdaae3
Packit cdaae3
    /*  offset of the next entrypool entry. */
Packit cdaae3
    Dwarf_Unsigned *    offset_of_next_entrypool,
Packit cdaae3
    Dwarf_Error *       error)
Packit cdaae3
{
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *cur = 0;
Packit cdaae3
    struct Dwarf_D_Abbrev_s * abbrev = 0;
Packit cdaae3
    Dwarf_Debug dbg = 0;
Packit cdaae3
    unsigned n = 0;
Packit cdaae3
    int res = 0;
Packit cdaae3
    Dwarf_Unsigned abcount = 0;
Packit cdaae3
    Dwarf_Unsigned pooloffset = offset_in_entrypool_of_values;
Packit cdaae3
    Dwarf_Small * endpool = 0;
Packit cdaae3
    Dwarf_Small * poolptr = 0;
Packit cdaae3
Packit cdaae3
    res = get_inhdr_cur(dn,index_number,&cur,error);
Packit cdaae3
    if (res != DW_DLV_OK) {
Packit cdaae3
        return res;
Packit cdaae3
    }
Packit cdaae3
    dbg = dn->dn_dbg;
Packit cdaae3
    endpool = cur->din_entry_pool + cur->din_entry_pool_size;
Packit cdaae3
Packit cdaae3
    if (index_of_abbrev >= cur->din_abbrev_list_count) {
Packit cdaae3
        _dwarf_error(dbg,error,DW_DLE_DEBUG_NAMES_ABBREV_CORRUPTION);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    poolptr = cur->din_entry_pool + offset_in_entrypool_of_values;
Packit cdaae3
    abbrev = cur->din_abbrev_list + index_of_abbrev;
Packit cdaae3
    abcount = cur->din_abbrev_list_count;
Packit cdaae3
    for(n = 0; n < abcount ; ++n) {
Packit cdaae3
        struct abbrev_pair_s *abp = abbrev->da_pairs +n;
Packit cdaae3
        unsigned idxtype = abp->ap_index;
Packit cdaae3
        unsigned form = abp->ap_form;
Packit cdaae3
        array_dw_idx_number[n] = idxtype;
Packit cdaae3
        array_form[n] = form;
Packit cdaae3
Packit cdaae3
        if(form == DW_FORM_data8 && idxtype == DW_IDX_type_hash) {
Packit cdaae3
            if ((poolptr + sizeof(Dwarf_Sig8)) > endpool){
Packit cdaae3
                _dwarf_error(dbg,error,
Packit cdaae3
                    DW_DLE_DEBUG_NAMES_ENTRYPOOL_OFFSET);
Packit cdaae3
                return DW_DLV_ERROR;
Packit cdaae3
            }
Packit cdaae3
            memcpy(array_of_signatures+n,
Packit cdaae3
                poolptr,sizeof(Dwarf_Sig8));
Packit cdaae3
            poolptr += sizeof(Dwarf_Sig8);
Packit cdaae3
            pooloffset += sizeof(Dwarf_Sig8);
Packit cdaae3
            continue;
Packit cdaae3
        } else if (_dwarf_allow_formudata(form)) {
Packit cdaae3
            Dwarf_Unsigned val = 0;
Packit cdaae3
            Dwarf_Unsigned bytesread = 0;
Packit cdaae3
            res = _dwarf_formudata_internal(dbg,form,poolptr,
Packit cdaae3
                endpool,&val,&bytesread,error);
Packit cdaae3
            poolptr += bytesread;
Packit cdaae3
            pooloffset += bytesread;
Packit cdaae3
            array_of_offsets[n] = val;
Packit cdaae3
            continue;
Packit cdaae3
        }
Packit cdaae3
        /*  There is some mistake/omission in our code here or in
Packit cdaae3
            the data. */
Packit cdaae3
        _dwarf_error(dbg,error,DW_DLE_DEBUG_NAMES_UNHANDLED_FORM);
Packit cdaae3
        return DW_DLV_ERROR;
Packit cdaae3
    }
Packit cdaae3
    *offset_of_next_entrypool = pooloffset;
Packit cdaae3
    return DW_DLV_OK;
Packit cdaae3
}
Packit cdaae3
Packit cdaae3
Packit cdaae3
Packit cdaae3
Packit cdaae3
/*  Frees any Dwarf_Dnames_Head_s data that is directly
Packit cdaae3
    mallocd. */
Packit cdaae3
void
Packit cdaae3
_dwarf_debugnames_destructor(void *m)
Packit cdaae3
{
Packit cdaae3
    struct Dwarf_Dnames_Head_s *h = (struct Dwarf_Dnames_Head_s *)m;
Packit cdaae3
Packit cdaae3
    struct Dwarf_Dnames_index_header_s *cur = 0;
Packit cdaae3
    unsigned n = 0;
Packit cdaae3
Packit cdaae3
    cur = h->dn_inhdr_first;
Packit cdaae3
    for( ;n < h->dn_inhdr_count ; ++n,++cur) {
Packit cdaae3
        free_inhdr_content(cur);
Packit cdaae3
    }
Packit cdaae3
    free(h->dn_inhdr_first);
Packit cdaae3
    h->dn_inhdr_first = 0;
Packit cdaae3
    h->dn_inhdr_count = 0;
Packit cdaae3
}