diff options
Diffstat (limited to 'usr/src/tools/ctf/dwarf/common/dwarf_util.c')
| -rw-r--r-- | usr/src/tools/ctf/dwarf/common/dwarf_util.c | 547 | 
1 files changed, 0 insertions, 547 deletions
| diff --git a/usr/src/tools/ctf/dwarf/common/dwarf_util.c b/usr/src/tools/ctf/dwarf/common/dwarf_util.c deleted file mode 100644 index 01e0dd755d..0000000000 --- a/usr/src/tools/ctf/dwarf/common/dwarf_util.c +++ /dev/null @@ -1,547 +0,0 @@ -/* -  Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved. -  Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved. - -  This program is free software; you can redistribute it and/or modify it -  under the terms of version 2.1 of the GNU Lesser General Public License  -  as published by the Free Software Foundation. - -  This program is distributed in the hope that it would be useful, but -  WITHOUT ANY WARRANTY; without even the implied warranty of -  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.   - -  Further, this software is distributed without any warranty that it is -  free of the rightful claim of any third person regarding infringement  -  or the like.  Any license provided herein, whether implied or  -  otherwise, applies only to this software file.  Patent licenses, if -  any, provided herein do not apply to combinations of this program with  -  other software, or any other product whatsoever.   - -  You should have received a copy of the GNU Lesser General Public  -  License along with this program; if not, write the Free Software  -  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, -  USA. - -  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane, -  Mountain View, CA 94043, or: - -  http://www.sgi.com - -  For further information regarding this notice, see: - -  http://oss.sgi.com/projects/GenInfo/NoticeExplan - -*/ -/* The address of the Free Software Foundation is -   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,  -   Boston, MA 02110-1301, USA. -   SGI has moved from the Crittenden Lane address. -*/ - - - - - -#include "config.h" -#include "dwarf_incl.h" -#include <stdio.h> -#include "dwarf_die_deliv.h" - - - -/* -    Given a form, and a pointer to the bytes encoding  -    a value of that form, val_ptr, this function returns -    the length, in bytes, of a value of that form. -    When using this function, check for a return of 0 -    a recursive DW_FORM_INDIRECT value. -*/ -Dwarf_Unsigned -_dwarf_get_size_of_val(Dwarf_Debug dbg, -    Dwarf_Unsigned form, -    Dwarf_Half address_size, -    Dwarf_Small * val_ptr, int v_length_size) -{ -    Dwarf_Unsigned length = 0; -    Dwarf_Word leb128_length = 0; -    Dwarf_Unsigned form_indirect = 0; -    Dwarf_Unsigned ret_value = 0; - -    switch (form) { - -    default:                    /* Handles form = 0. */ -        return (form); - -    case DW_FORM_addr: -        if(address_size) { -            return address_size; -        } -        /* This should never happen, address_size should be set. */ -        return (dbg->de_pointer_size); - -    /* DWARF2 was wrong on the size of the attribute for -       DW_FORM_ref_addr.  We assume compilers are using the  -       corrected DWARF3 text (for 32bit pointer target objects pointer and -       offsets are the same size anyway). */ -    case DW_FORM_ref_addr: -        return (v_length_size); - -    case DW_FORM_block1: -        return (*(Dwarf_Small *) val_ptr + 1); - -    case DW_FORM_block2: -        READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, -                       val_ptr, sizeof(Dwarf_Half)); -        return (ret_value + sizeof(Dwarf_Half)); - -    case DW_FORM_block4: -        READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, -                       val_ptr, sizeof(Dwarf_ufixed)); -        return (ret_value + sizeof(Dwarf_ufixed)); - - -    case DW_FORM_data1: -        return (1); - -    case DW_FORM_data2: -        return (2); - -    case DW_FORM_data4: -        return (4); - -    case DW_FORM_data8: -        return (8); - -    case DW_FORM_string: -        return (strlen((char *) val_ptr) + 1); - -    case DW_FORM_block: -    case DW_FORM_exprloc: -        length = _dwarf_decode_u_leb128(val_ptr, &leb128_length); -        return (length + leb128_length); - -    case DW_FORM_flag_present: -        return (0); -    case DW_FORM_flag: -        return (1); - -    case DW_FORM_sec_offset: -        /* If 32bit dwarf, is 4. Else is 64bit dwarf and is 8. */ -        return (v_length_size); - -    case DW_FORM_ref_udata: -        length = _dwarf_decode_u_leb128(val_ptr, &leb128_length); -        return (leb128_length); - -    case DW_FORM_indirect: -        { -            Dwarf_Word indir_len = 0; - -            form_indirect = _dwarf_decode_u_leb128(val_ptr, &indir_len); -            if (form_indirect == DW_FORM_indirect) { -                return (0);     /* We are in big trouble: The true form  -                                   of DW_FORM_indirect is -                                   DW_FORM_indirect? Nonsense. Should -                                   never happen. */ -            } -            return (indir_len + _dwarf_get_size_of_val(dbg, -                   form_indirect, -                   address_size, -                   val_ptr + indir_len, -                   v_length_size)); -        } - -    case DW_FORM_ref1: -        return (1); - -    case DW_FORM_ref2: -        return (2); - -    case DW_FORM_ref4: -        return (4); - -    case DW_FORM_ref8: -        return (8); - -    case DW_FORM_sdata: -        _dwarf_decode_s_leb128(val_ptr, &leb128_length); -        return (leb128_length); - -    case DW_FORM_strp: -        return (v_length_size); - -    case DW_FORM_udata: -        _dwarf_decode_u_leb128(val_ptr, &leb128_length); -        return (leb128_length); -    } -} - -/* We allow an arbitrary number of HT_MULTIPLE entries -   before resizing.  It seems up to 20 or 30 -   would work nearly as well. -   We could have a different resize multiple than 'resize now' -   test multiple, but for now we don't do that. -*/ -#define HT_MULTIPLE 8 - -/* Copy the old entries, updating each to be in -   a new list.  Don't delete anything. Leave the -   htin with stale data. */ -static void -copy_abbrev_table_to_new_table(Dwarf_Hash_Table htin,  -  Dwarf_Hash_Table htout) -{ -    Dwarf_Hash_Table_Entry entry_in = htin->tb_entries; -    unsigned entry_in_count = htin->tb_table_entry_count; -    Dwarf_Hash_Table_Entry entry_out = htout->tb_entries; -    unsigned entry_out_count = htout->tb_table_entry_count; -    unsigned k = 0; -    for ( ;  k < entry_in_count; ++k,++entry_in) { -        Dwarf_Abbrev_List listent = entry_in->at_head; -        Dwarf_Abbrev_List nextlistent = 0; - -        for (  ; listent ; listent = nextlistent) { -             unsigned newtmp = listent->ab_code; -             unsigned newhash = newtmp%entry_out_count; -             Dwarf_Hash_Table_Entry e; -             nextlistent = listent->ab_next; -             e = entry_out+newhash;  -             /* Move_entry_to_new_hash. This reverses the -                order of the entries, effectively, but -                that does not seem significant. */ -             listent->ab_next = e->at_head; -             e->at_head = listent; - -             htout->tb_total_abbrev_count++; -        }  -    } -} - -/* -    This function returns a pointer to a Dwarf_Abbrev_List_s -    struct for the abbrev with the given code.  It puts the -    struct on the appropriate hash table.  It also adds all -    the abbrev between the last abbrev added and this one to -    the hash table.  In other words, the .debug_abbrev section -    is scanned sequentially from the top for an abbrev with -    the given code.  All intervening abbrevs are also put  -    into the hash table. - -    This function hashes the given code, and checks the chain -    at that hash table entry to see if a Dwarf_Abbrev_List_s -    with the given code exists.  If yes, it returns a pointer -    to that struct.  Otherwise, it scans the .debug_abbrev -    section from the last byte scanned for that CU till either -    an abbrev with the given code is found, or an abbrev code -    of 0 is read.  It puts Dwarf_Abbrev_List_s entries for all -    abbrev's read till that point into the hash table.  The -    hash table contains both a head pointer and a tail pointer -    for each entry. - -    While the lists can move and entries can be moved between -    lists on reallocation, any given Dwarf_Abbrev_list entry -    never moves once allocated, so the pointer is safe to return. - -    Returns NULL on error. -*/ -Dwarf_Abbrev_List -_dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code) -{ -    Dwarf_Debug dbg = cu_context->cc_dbg; -    Dwarf_Hash_Table hash_table_base = cu_context->cc_abbrev_hash_table; -    Dwarf_Hash_Table_Entry entry_base = 0;  -    Dwarf_Hash_Table_Entry entry_cur = 0;  -    Dwarf_Word hash_num = 0; -    Dwarf_Unsigned abbrev_code = 0;  -    Dwarf_Unsigned abbrev_tag  = 0; -    Dwarf_Unsigned attr_name = 0; -    Dwarf_Unsigned attr_form = 0; - -    Dwarf_Abbrev_List hash_abbrev_entry = 0; - -    Dwarf_Abbrev_List inner_list_entry = 0;  -    Dwarf_Hash_Table_Entry inner_hash_entry = 0;  - -    Dwarf_Byte_Ptr abbrev_ptr = 0; -    unsigned hashable_val; - -    if ( !hash_table_base->tb_entries ) { -         hash_table_base->tb_table_entry_count =  HT_MULTIPLE; -         hash_table_base->tb_total_abbrev_count= 0; -         hash_table_base->tb_entries =  _dwarf_get_alloc(dbg, -            DW_DLA_HASH_TABLE_ENTRY,  -            hash_table_base->tb_table_entry_count); -         if(! hash_table_base->tb_entries) { -             return NULL; -         } - -    } else if (hash_table_base->tb_total_abbrev_count > -          ( hash_table_base->tb_table_entry_count * HT_MULTIPLE) ) { -        struct Dwarf_Hash_Table_s newht; -        /* Effectively multiplies by >= HT_MULTIPLE */ -        newht.tb_table_entry_count =  hash_table_base->tb_total_abbrev_count; -        newht.tb_total_abbrev_count = 0; -        newht.tb_entries =  _dwarf_get_alloc(dbg, -            DW_DLA_HASH_TABLE_ENTRY,  -            newht.tb_table_entry_count); - -        if(! newht.tb_entries) { -             return NULL; -        } -        /* Copy the existing entries to the new table, -           rehashing each.  -        */ -        copy_abbrev_table_to_new_table(hash_table_base, &newht); -        /* Dealloc only the entries hash table array, not the lists -           of things pointed to by a hash table entry array. */ -        dwarf_dealloc(dbg, hash_table_base->tb_entries,DW_DLA_HASH_TABLE_ENTRY); -        hash_table_base->tb_entries = 0; -        /* Now overwrite the existing table descriptor with -           the new, newly valid, contents. */ -        *hash_table_base = newht; -    } /* Else is ok as is, add entry */  - -     -    hashable_val = code; -    hash_num = hashable_val %  -        hash_table_base->tb_table_entry_count; -    entry_base = hash_table_base->tb_entries; -    entry_cur  = entry_base + hash_num; -    -    /* Determine if the 'code' is the list of synonyms already. */ -    for (hash_abbrev_entry = entry_cur->at_head; -         hash_abbrev_entry != NULL && hash_abbrev_entry->ab_code != code; -         hash_abbrev_entry = hash_abbrev_entry->ab_next); -    if (hash_abbrev_entry != NULL) { -        /* This returns a pointer to an abbrev list entry, not  -           the list itself. */ -        return (hash_abbrev_entry); -    } - -    abbrev_ptr = cu_context->cc_last_abbrev_ptr != NULL ? -        cu_context->cc_last_abbrev_ptr : -        dbg->de_debug_abbrev.dss_data + cu_context->cc_abbrev_offset; - -    /* End of abbrev's for this cu, since abbrev code is 0. */ -    if (*abbrev_ptr == 0) { -        return (NULL); -    } - -    do { -        unsigned new_hashable_val; -        DECODE_LEB128_UWORD(abbrev_ptr, abbrev_code); -        DECODE_LEB128_UWORD(abbrev_ptr, abbrev_tag); - -        inner_list_entry = (Dwarf_Abbrev_List) -            _dwarf_get_alloc(cu_context->cc_dbg, DW_DLA_ABBREV_LIST, 1); -        if (inner_list_entry == NULL) -            return (NULL); - -        new_hashable_val = abbrev_code; -        hash_num = new_hashable_val %  -            hash_table_base->tb_table_entry_count; -        inner_hash_entry = entry_base + hash_num; -        /* Move_entry_to_new_hash */ -        inner_list_entry->ab_next = inner_hash_entry->at_head; -        inner_hash_entry->at_head = inner_list_entry; - -        hash_table_base->tb_total_abbrev_count++; - -        inner_list_entry->ab_code = abbrev_code; -        inner_list_entry->ab_tag = abbrev_tag; -        inner_list_entry->ab_has_child = *(abbrev_ptr++); -        inner_list_entry->ab_abbrev_ptr = abbrev_ptr; - -        /* Cycle thru the abbrev content, ignoring the content except -           to find the end of the content. */ -        do { -            DECODE_LEB128_UWORD(abbrev_ptr, attr_name); -            DECODE_LEB128_UWORD(abbrev_ptr, attr_form); -        } while (attr_name != 0 && attr_form != 0); - -    } while (*abbrev_ptr != 0 && abbrev_code != code); - -    cu_context->cc_last_abbrev_ptr = abbrev_ptr; -    return (abbrev_code == code ? inner_list_entry : NULL); -} - - -/* return 1 if string ends before 'endptr' else -** return 0 meaning string is not properly terminated. -** Presumption is the 'endptr' pts to end of some dwarf section data. -*/ -int -_dwarf_string_valid(void *startptr, void *endptr) -{ - -    char *start = startptr; -    char *end = endptr; - -    while (start < end) { -        if (*start == 0) { -            return 1;           /* OK! */ -        } -        ++start; -        ++end; -    } -    return 0;                   /* FAIL! bad string! */ -} - -/* -  A byte-swapping version of memcpy -  for cross-endian use. -  Only 2,4,8 should be lengths passed in. -*/ -void * -_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len) -{ -    void *orig_s1 = s1; -    unsigned char *targ = (unsigned char *) s1; -    unsigned char *src = (unsigned char *) s2; - -    if (len == 4) { -        targ[3] = src[0]; -        targ[2] = src[1]; -        targ[1] = src[2]; -        targ[0] = src[3]; -    } else if (len == 8) { -        targ[7] = src[0]; -        targ[6] = src[1]; -        targ[5] = src[2]; -        targ[4] = src[3]; -        targ[3] = src[4]; -        targ[2] = src[5]; -        targ[1] = src[6]; -        targ[0] = src[7]; -    } else if (len == 2) { -        targ[1] = src[0]; -        targ[0] = src[1]; -    } -/* should NOT get below here: is not the intended use */ -    else if (len == 1) { -        targ[0] = src[0]; -    } else { -        memcpy(s1, s2, len); -    } - -    return orig_s1; -} - - -/* -  This calculation used to be sprinkled all over. -  Now brought to one place. - -  We try to accurately compute the size of a cu header -  given a known cu header location ( an offset in .debug_info). - -*/ -/* ARGSUSED */ -Dwarf_Unsigned -_dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset) -{ -    int local_length_size = 0; -    int local_extension_size = 0; -    Dwarf_Unsigned length = 0; -    Dwarf_Small *cuptr = dbg->de_debug_info.dss_data + offset; - -    READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, -                     cuptr, local_length_size, local_extension_size); - -    return local_extension_size +       /* initial extesion, if present  -                                         */ -        local_length_size +     /* Size of cu length field. */ -        sizeof(Dwarf_Half) +    /* Size of version stamp field. */ -        local_length_size +     /* Size of abbrev offset field. */ -        sizeof(Dwarf_Small);    /* Size of address size field. */ - -} - -/* -        Pretend we know nothing about the CU -        and just roughly compute the result.  -*/ -Dwarf_Unsigned -_dwarf_length_of_cu_header_simple(Dwarf_Debug dbg) -{ -    return dbg->de_length_size +        /* Size of cu length field. */ -        sizeof(Dwarf_Half) +    /* Size of version stamp field. */ -        dbg->de_length_size +   /* Size of abbrev offset field. */ -        sizeof(Dwarf_Small);    /* Size of address size field. */ -} - -/* Now that we delay loading .debug_info, we need to do the -   load in more places. So putting the load -   code in one place now instead of replicating it in multiple -   places. - -*/ -int -_dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error * error) -{ -    int res = DW_DLV_ERROR; - -    /* Testing de_debug_info.dss_data allows us to avoid testing -       de_debug_abbrev.dss_data.  -       One test instead of 2. .debug_info is useless -       without .debug_abbrev. */ -    if (dbg->de_debug_info.dss_data) { -        return DW_DLV_OK; -    } - -    res = _dwarf_load_section(dbg, &dbg->de_debug_abbrev,error); -    if (res != DW_DLV_OK) { -        return res; -    } -    res = _dwarf_load_section(dbg, &dbg->de_debug_info, error); -    return res; - -} -void -_dwarf_free_abbrev_hash_table_contents(Dwarf_Debug dbg,Dwarf_Hash_Table hash_table) -{ -    /* A Hash Table is an array with tb_table_entry_count struct -       Dwarf_Hash_Table_s entries in the array. */ -    int hashnum = 0; -    for (; hashnum < hash_table->tb_table_entry_count; ++hashnum) { -        struct Dwarf_Abbrev_List_s *abbrev = 0; -        struct Dwarf_Abbrev_List_s *nextabbrev = 0; -        struct  Dwarf_Hash_Table_Entry_s *tb =  &hash_table->tb_entries[hashnum]; - -        abbrev = tb->at_head; -        for (; abbrev; abbrev = nextabbrev) { -            nextabbrev = abbrev->ab_next; -            dwarf_dealloc(dbg, abbrev, DW_DLA_ABBREV_LIST); -        } -    } -    /* Frees all the entries at once: an array. */ -    dwarf_dealloc(dbg,hash_table->tb_entries,DW_DLA_HASH_TABLE_ENTRY); -} - -/*  -    If no die provided the size value returned might be wrong. -    If different compilation units have different address sizes  -    this may not give the correct value in all contexts if the die -    pointer is NULL.  -    If the Elf offset size != address_size  -    (for example if address_size = 4 but recorded in elf64 object) -    this may not give the correct value in all contexts if the die -    pointer is NULL.  -    If the die pointer is non-NULL (in which case it must point to -    a valid DIE) this will return the correct size. -*/ -int  -_dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Die die) -{ -    Dwarf_CU_Context context = 0; -    Dwarf_Half addrsize = 0; -    if(!die) { -        return dbg->de_pointer_size; -    } -    context = die->di_cu_context; -    addrsize = context->cc_address_size; -    return addrsize; -} - - - | 
