xref: /titanic_52/usr/src/lib/libdwarf/common/dwarf_util.c (revision 7fd791373689a6af05e27efec3b1ab556e02aa23)
1*7fd79137SRobert Mustacchi /*
2*7fd79137SRobert Mustacchi   Copyright (C) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
3*7fd79137SRobert Mustacchi   Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
4*7fd79137SRobert Mustacchi 
5*7fd79137SRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
6*7fd79137SRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
7*7fd79137SRobert Mustacchi   as published by the Free Software Foundation.
8*7fd79137SRobert Mustacchi 
9*7fd79137SRobert Mustacchi   This program is distributed in the hope that it would be useful, but
10*7fd79137SRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
11*7fd79137SRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12*7fd79137SRobert Mustacchi 
13*7fd79137SRobert Mustacchi   Further, this software is distributed without any warranty that it is
14*7fd79137SRobert Mustacchi   free of the rightful claim of any third person regarding infringement
15*7fd79137SRobert Mustacchi   or the like.  Any license provided herein, whether implied or
16*7fd79137SRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
17*7fd79137SRobert Mustacchi   any, provided herein do not apply to combinations of this program with
18*7fd79137SRobert Mustacchi   other software, or any other product whatsoever.
19*7fd79137SRobert Mustacchi 
20*7fd79137SRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
21*7fd79137SRobert Mustacchi   License along with this program; if not, write the Free Software
22*7fd79137SRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
23*7fd79137SRobert Mustacchi   USA.
24*7fd79137SRobert Mustacchi 
25*7fd79137SRobert Mustacchi   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
26*7fd79137SRobert Mustacchi   Mountain View, CA 94043, or:
27*7fd79137SRobert Mustacchi 
28*7fd79137SRobert Mustacchi   http://www.sgi.com
29*7fd79137SRobert Mustacchi 
30*7fd79137SRobert Mustacchi   For further information regarding this notice, see:
31*7fd79137SRobert Mustacchi 
32*7fd79137SRobert Mustacchi   http://oss.sgi.com/projects/GenInfo/NoticeExplan
33*7fd79137SRobert Mustacchi 
34*7fd79137SRobert Mustacchi */
35*7fd79137SRobert Mustacchi /* The address of the Free Software Foundation is
36*7fd79137SRobert Mustacchi    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
37*7fd79137SRobert Mustacchi    Boston, MA 02110-1301, USA.
38*7fd79137SRobert Mustacchi    SGI has moved from the Crittenden Lane address.
39*7fd79137SRobert Mustacchi */
40*7fd79137SRobert Mustacchi 
41*7fd79137SRobert Mustacchi 
42*7fd79137SRobert Mustacchi 
43*7fd79137SRobert Mustacchi 
44*7fd79137SRobert Mustacchi 
45*7fd79137SRobert Mustacchi #include "config.h"
46*7fd79137SRobert Mustacchi #include "dwarf_incl.h"
47*7fd79137SRobert Mustacchi #include <stdio.h>
48*7fd79137SRobert Mustacchi #include "dwarf_die_deliv.h"
49*7fd79137SRobert Mustacchi 
50*7fd79137SRobert Mustacchi 
51*7fd79137SRobert Mustacchi 
52*7fd79137SRobert Mustacchi /*
53*7fd79137SRobert Mustacchi     Given a form, and a pointer to the bytes encoding
54*7fd79137SRobert Mustacchi     a value of that form, val_ptr, this function returns
55*7fd79137SRobert Mustacchi     the length, in bytes, of a value of that form.
56*7fd79137SRobert Mustacchi     When using this function, check for a return of 0
57*7fd79137SRobert Mustacchi     a recursive DW_FORM_INDIRECT value.
58*7fd79137SRobert Mustacchi */
59*7fd79137SRobert Mustacchi Dwarf_Unsigned
60*7fd79137SRobert Mustacchi _dwarf_get_size_of_val(Dwarf_Debug dbg,
61*7fd79137SRobert Mustacchi     Dwarf_Unsigned form,
62*7fd79137SRobert Mustacchi     Dwarf_Half address_size,
63*7fd79137SRobert Mustacchi     Dwarf_Small * val_ptr, int v_length_size)
64*7fd79137SRobert Mustacchi {
65*7fd79137SRobert Mustacchi     Dwarf_Unsigned length = 0;
66*7fd79137SRobert Mustacchi     Dwarf_Word leb128_length = 0;
67*7fd79137SRobert Mustacchi     Dwarf_Unsigned form_indirect = 0;
68*7fd79137SRobert Mustacchi     Dwarf_Unsigned ret_value = 0;
69*7fd79137SRobert Mustacchi 
70*7fd79137SRobert Mustacchi     switch (form) {
71*7fd79137SRobert Mustacchi 
72*7fd79137SRobert Mustacchi     default:                    /* Handles form = 0. */
73*7fd79137SRobert Mustacchi         return (form);
74*7fd79137SRobert Mustacchi 
75*7fd79137SRobert Mustacchi     case DW_FORM_addr:
76*7fd79137SRobert Mustacchi         if(address_size) {
77*7fd79137SRobert Mustacchi             return address_size;
78*7fd79137SRobert Mustacchi         }
79*7fd79137SRobert Mustacchi         /* This should never happen, address_size should be set. */
80*7fd79137SRobert Mustacchi         return (dbg->de_pointer_size);
81*7fd79137SRobert Mustacchi 
82*7fd79137SRobert Mustacchi     /* DWARF2 was wrong on the size of the attribute for
83*7fd79137SRobert Mustacchi        DW_FORM_ref_addr.  We assume compilers are using the
84*7fd79137SRobert Mustacchi        corrected DWARF3 text (for 32bit pointer target objects pointer and
85*7fd79137SRobert Mustacchi        offsets are the same size anyway). */
86*7fd79137SRobert Mustacchi     case DW_FORM_ref_addr:
87*7fd79137SRobert Mustacchi         return (v_length_size);
88*7fd79137SRobert Mustacchi 
89*7fd79137SRobert Mustacchi     case DW_FORM_block1:
90*7fd79137SRobert Mustacchi         return (*(Dwarf_Small *) val_ptr + 1);
91*7fd79137SRobert Mustacchi 
92*7fd79137SRobert Mustacchi     case DW_FORM_block2:
93*7fd79137SRobert Mustacchi         READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
94*7fd79137SRobert Mustacchi                        val_ptr, sizeof(Dwarf_Half));
95*7fd79137SRobert Mustacchi         return (ret_value + sizeof(Dwarf_Half));
96*7fd79137SRobert Mustacchi 
97*7fd79137SRobert Mustacchi     case DW_FORM_block4:
98*7fd79137SRobert Mustacchi         READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
99*7fd79137SRobert Mustacchi                        val_ptr, sizeof(Dwarf_ufixed));
100*7fd79137SRobert Mustacchi         return (ret_value + sizeof(Dwarf_ufixed));
101*7fd79137SRobert Mustacchi 
102*7fd79137SRobert Mustacchi 
103*7fd79137SRobert Mustacchi     case DW_FORM_data1:
104*7fd79137SRobert Mustacchi         return (1);
105*7fd79137SRobert Mustacchi 
106*7fd79137SRobert Mustacchi     case DW_FORM_data2:
107*7fd79137SRobert Mustacchi         return (2);
108*7fd79137SRobert Mustacchi 
109*7fd79137SRobert Mustacchi     case DW_FORM_data4:
110*7fd79137SRobert Mustacchi         return (4);
111*7fd79137SRobert Mustacchi 
112*7fd79137SRobert Mustacchi     case DW_FORM_data8:
113*7fd79137SRobert Mustacchi         return (8);
114*7fd79137SRobert Mustacchi 
115*7fd79137SRobert Mustacchi     case DW_FORM_string:
116*7fd79137SRobert Mustacchi         return (strlen((char *) val_ptr) + 1);
117*7fd79137SRobert Mustacchi 
118*7fd79137SRobert Mustacchi     case DW_FORM_block:
119*7fd79137SRobert Mustacchi     case DW_FORM_exprloc:
120*7fd79137SRobert Mustacchi         length = _dwarf_decode_u_leb128(val_ptr, &leb128_length);
121*7fd79137SRobert Mustacchi         return (length + leb128_length);
122*7fd79137SRobert Mustacchi 
123*7fd79137SRobert Mustacchi     case DW_FORM_flag_present:
124*7fd79137SRobert Mustacchi         return (0);
125*7fd79137SRobert Mustacchi     case DW_FORM_flag:
126*7fd79137SRobert Mustacchi         return (1);
127*7fd79137SRobert Mustacchi 
128*7fd79137SRobert Mustacchi     case DW_FORM_sec_offset:
129*7fd79137SRobert Mustacchi         /* If 32bit dwarf, is 4. Else is 64bit dwarf and is 8. */
130*7fd79137SRobert Mustacchi         return (v_length_size);
131*7fd79137SRobert Mustacchi 
132*7fd79137SRobert Mustacchi     case DW_FORM_ref_udata:
133*7fd79137SRobert Mustacchi         length = _dwarf_decode_u_leb128(val_ptr, &leb128_length);
134*7fd79137SRobert Mustacchi         return (leb128_length);
135*7fd79137SRobert Mustacchi 
136*7fd79137SRobert Mustacchi     case DW_FORM_indirect:
137*7fd79137SRobert Mustacchi         {
138*7fd79137SRobert Mustacchi             Dwarf_Word indir_len = 0;
139*7fd79137SRobert Mustacchi 
140*7fd79137SRobert Mustacchi             form_indirect = _dwarf_decode_u_leb128(val_ptr, &indir_len);
141*7fd79137SRobert Mustacchi             if (form_indirect == DW_FORM_indirect) {
142*7fd79137SRobert Mustacchi                 return (0);     /* We are in big trouble: The true form
143*7fd79137SRobert Mustacchi                                    of DW_FORM_indirect is
144*7fd79137SRobert Mustacchi                                    DW_FORM_indirect? Nonsense. Should
145*7fd79137SRobert Mustacchi                                    never happen. */
146*7fd79137SRobert Mustacchi             }
147*7fd79137SRobert Mustacchi             return (indir_len + _dwarf_get_size_of_val(dbg,
148*7fd79137SRobert Mustacchi                    form_indirect,
149*7fd79137SRobert Mustacchi                    address_size,
150*7fd79137SRobert Mustacchi                    val_ptr + indir_len,
151*7fd79137SRobert Mustacchi                    v_length_size));
152*7fd79137SRobert Mustacchi         }
153*7fd79137SRobert Mustacchi 
154*7fd79137SRobert Mustacchi     case DW_FORM_ref1:
155*7fd79137SRobert Mustacchi         return (1);
156*7fd79137SRobert Mustacchi 
157*7fd79137SRobert Mustacchi     case DW_FORM_ref2:
158*7fd79137SRobert Mustacchi         return (2);
159*7fd79137SRobert Mustacchi 
160*7fd79137SRobert Mustacchi     case DW_FORM_ref4:
161*7fd79137SRobert Mustacchi         return (4);
162*7fd79137SRobert Mustacchi 
163*7fd79137SRobert Mustacchi     case DW_FORM_ref8:
164*7fd79137SRobert Mustacchi         return (8);
165*7fd79137SRobert Mustacchi 
166*7fd79137SRobert Mustacchi     case DW_FORM_sdata:
167*7fd79137SRobert Mustacchi         _dwarf_decode_s_leb128(val_ptr, &leb128_length);
168*7fd79137SRobert Mustacchi         return (leb128_length);
169*7fd79137SRobert Mustacchi 
170*7fd79137SRobert Mustacchi     case DW_FORM_strp:
171*7fd79137SRobert Mustacchi         return (v_length_size);
172*7fd79137SRobert Mustacchi 
173*7fd79137SRobert Mustacchi     case DW_FORM_udata:
174*7fd79137SRobert Mustacchi         _dwarf_decode_u_leb128(val_ptr, &leb128_length);
175*7fd79137SRobert Mustacchi         return (leb128_length);
176*7fd79137SRobert Mustacchi     }
177*7fd79137SRobert Mustacchi }
178*7fd79137SRobert Mustacchi 
179*7fd79137SRobert Mustacchi /* We allow an arbitrary number of HT_MULTIPLE entries
180*7fd79137SRobert Mustacchi    before resizing.  It seems up to 20 or 30
181*7fd79137SRobert Mustacchi    would work nearly as well.
182*7fd79137SRobert Mustacchi    We could have a different resize multiple than 'resize now'
183*7fd79137SRobert Mustacchi    test multiple, but for now we don't do that.
184*7fd79137SRobert Mustacchi */
185*7fd79137SRobert Mustacchi #define HT_MULTIPLE 8
186*7fd79137SRobert Mustacchi 
187*7fd79137SRobert Mustacchi /* Copy the old entries, updating each to be in
188*7fd79137SRobert Mustacchi    a new list.  Don't delete anything. Leave the
189*7fd79137SRobert Mustacchi    htin with stale data. */
190*7fd79137SRobert Mustacchi static void
191*7fd79137SRobert Mustacchi copy_abbrev_table_to_new_table(Dwarf_Hash_Table htin,
192*7fd79137SRobert Mustacchi   Dwarf_Hash_Table htout)
193*7fd79137SRobert Mustacchi {
194*7fd79137SRobert Mustacchi     Dwarf_Hash_Table_Entry entry_in = htin->tb_entries;
195*7fd79137SRobert Mustacchi     unsigned entry_in_count = htin->tb_table_entry_count;
196*7fd79137SRobert Mustacchi     Dwarf_Hash_Table_Entry entry_out = htout->tb_entries;
197*7fd79137SRobert Mustacchi     unsigned entry_out_count = htout->tb_table_entry_count;
198*7fd79137SRobert Mustacchi     unsigned k = 0;
199*7fd79137SRobert Mustacchi     for ( ;  k < entry_in_count; ++k,++entry_in) {
200*7fd79137SRobert Mustacchi         Dwarf_Abbrev_List listent = entry_in->at_head;
201*7fd79137SRobert Mustacchi         Dwarf_Abbrev_List nextlistent = 0;
202*7fd79137SRobert Mustacchi 
203*7fd79137SRobert Mustacchi         for (  ; listent ; listent = nextlistent) {
204*7fd79137SRobert Mustacchi              unsigned newtmp = listent->ab_code;
205*7fd79137SRobert Mustacchi              unsigned newhash = newtmp%entry_out_count;
206*7fd79137SRobert Mustacchi              Dwarf_Hash_Table_Entry e;
207*7fd79137SRobert Mustacchi              nextlistent = listent->ab_next;
208*7fd79137SRobert Mustacchi              e = entry_out+newhash;
209*7fd79137SRobert Mustacchi              /* Move_entry_to_new_hash. This reverses the
210*7fd79137SRobert Mustacchi                 order of the entries, effectively, but
211*7fd79137SRobert Mustacchi                 that does not seem significant. */
212*7fd79137SRobert Mustacchi              listent->ab_next = e->at_head;
213*7fd79137SRobert Mustacchi              e->at_head = listent;
214*7fd79137SRobert Mustacchi 
215*7fd79137SRobert Mustacchi              htout->tb_total_abbrev_count++;
216*7fd79137SRobert Mustacchi         }
217*7fd79137SRobert Mustacchi     }
218*7fd79137SRobert Mustacchi }
219*7fd79137SRobert Mustacchi 
220*7fd79137SRobert Mustacchi /*
221*7fd79137SRobert Mustacchi     This function returns a pointer to a Dwarf_Abbrev_List_s
222*7fd79137SRobert Mustacchi     struct for the abbrev with the given code.  It puts the
223*7fd79137SRobert Mustacchi     struct on the appropriate hash table.  It also adds all
224*7fd79137SRobert Mustacchi     the abbrev between the last abbrev added and this one to
225*7fd79137SRobert Mustacchi     the hash table.  In other words, the .debug_abbrev section
226*7fd79137SRobert Mustacchi     is scanned sequentially from the top for an abbrev with
227*7fd79137SRobert Mustacchi     the given code.  All intervening abbrevs are also put
228*7fd79137SRobert Mustacchi     into the hash table.
229*7fd79137SRobert Mustacchi 
230*7fd79137SRobert Mustacchi     This function hashes the given code, and checks the chain
231*7fd79137SRobert Mustacchi     at that hash table entry to see if a Dwarf_Abbrev_List_s
232*7fd79137SRobert Mustacchi     with the given code exists.  If yes, it returns a pointer
233*7fd79137SRobert Mustacchi     to that struct.  Otherwise, it scans the .debug_abbrev
234*7fd79137SRobert Mustacchi     section from the last byte scanned for that CU till either
235*7fd79137SRobert Mustacchi     an abbrev with the given code is found, or an abbrev code
236*7fd79137SRobert Mustacchi     of 0 is read.  It puts Dwarf_Abbrev_List_s entries for all
237*7fd79137SRobert Mustacchi     abbrev's read till that point into the hash table.  The
238*7fd79137SRobert Mustacchi     hash table contains both a head pointer and a tail pointer
239*7fd79137SRobert Mustacchi     for each entry.
240*7fd79137SRobert Mustacchi 
241*7fd79137SRobert Mustacchi     While the lists can move and entries can be moved between
242*7fd79137SRobert Mustacchi     lists on reallocation, any given Dwarf_Abbrev_list entry
243*7fd79137SRobert Mustacchi     never moves once allocated, so the pointer is safe to return.
244*7fd79137SRobert Mustacchi 
245*7fd79137SRobert Mustacchi     Returns NULL on error.
246*7fd79137SRobert Mustacchi */
247*7fd79137SRobert Mustacchi Dwarf_Abbrev_List
248*7fd79137SRobert Mustacchi _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Unsigned code)
249*7fd79137SRobert Mustacchi {
250*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = cu_context->cc_dbg;
251*7fd79137SRobert Mustacchi     Dwarf_Hash_Table hash_table_base = cu_context->cc_abbrev_hash_table;
252*7fd79137SRobert Mustacchi     Dwarf_Hash_Table_Entry entry_base = 0;
253*7fd79137SRobert Mustacchi     Dwarf_Hash_Table_Entry entry_cur = 0;
254*7fd79137SRobert Mustacchi     Dwarf_Word hash_num = 0;
255*7fd79137SRobert Mustacchi     Dwarf_Unsigned abbrev_code = 0;
256*7fd79137SRobert Mustacchi     Dwarf_Unsigned abbrev_tag  = 0;
257*7fd79137SRobert Mustacchi     Dwarf_Unsigned attr_name = 0;
258*7fd79137SRobert Mustacchi     Dwarf_Unsigned attr_form = 0;
259*7fd79137SRobert Mustacchi 
260*7fd79137SRobert Mustacchi     Dwarf_Abbrev_List hash_abbrev_entry = 0;
261*7fd79137SRobert Mustacchi 
262*7fd79137SRobert Mustacchi     Dwarf_Abbrev_List inner_list_entry = 0;
263*7fd79137SRobert Mustacchi     Dwarf_Hash_Table_Entry inner_hash_entry = 0;
264*7fd79137SRobert Mustacchi 
265*7fd79137SRobert Mustacchi     Dwarf_Byte_Ptr abbrev_ptr = 0;
266*7fd79137SRobert Mustacchi     unsigned hashable_val;
267*7fd79137SRobert Mustacchi 
268*7fd79137SRobert Mustacchi     if ( !hash_table_base->tb_entries ) {
269*7fd79137SRobert Mustacchi          hash_table_base->tb_table_entry_count =  HT_MULTIPLE;
270*7fd79137SRobert Mustacchi          hash_table_base->tb_total_abbrev_count= 0;
271*7fd79137SRobert Mustacchi          hash_table_base->tb_entries =  _dwarf_get_alloc(dbg,
272*7fd79137SRobert Mustacchi             DW_DLA_HASH_TABLE_ENTRY,
273*7fd79137SRobert Mustacchi             hash_table_base->tb_table_entry_count);
274*7fd79137SRobert Mustacchi          if(! hash_table_base->tb_entries) {
275*7fd79137SRobert Mustacchi              return NULL;
276*7fd79137SRobert Mustacchi          }
277*7fd79137SRobert Mustacchi 
278*7fd79137SRobert Mustacchi     } else if (hash_table_base->tb_total_abbrev_count >
279*7fd79137SRobert Mustacchi           ( hash_table_base->tb_table_entry_count * HT_MULTIPLE) ) {
280*7fd79137SRobert Mustacchi         struct Dwarf_Hash_Table_s newht;
281*7fd79137SRobert Mustacchi         /* Effectively multiplies by >= HT_MULTIPLE */
282*7fd79137SRobert Mustacchi         newht.tb_table_entry_count =  hash_table_base->tb_total_abbrev_count;
283*7fd79137SRobert Mustacchi         newht.tb_total_abbrev_count = 0;
284*7fd79137SRobert Mustacchi         newht.tb_entries =  _dwarf_get_alloc(dbg,
285*7fd79137SRobert Mustacchi             DW_DLA_HASH_TABLE_ENTRY,
286*7fd79137SRobert Mustacchi             newht.tb_table_entry_count);
287*7fd79137SRobert Mustacchi 
288*7fd79137SRobert Mustacchi         if(! newht.tb_entries) {
289*7fd79137SRobert Mustacchi              return NULL;
290*7fd79137SRobert Mustacchi         }
291*7fd79137SRobert Mustacchi         /* Copy the existing entries to the new table,
292*7fd79137SRobert Mustacchi            rehashing each.
293*7fd79137SRobert Mustacchi         */
294*7fd79137SRobert Mustacchi         copy_abbrev_table_to_new_table(hash_table_base, &newht);
295*7fd79137SRobert Mustacchi         /* Dealloc only the entries hash table array, not the lists
296*7fd79137SRobert Mustacchi            of things pointed to by a hash table entry array. */
297*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, hash_table_base->tb_entries,DW_DLA_HASH_TABLE_ENTRY);
298*7fd79137SRobert Mustacchi         hash_table_base->tb_entries = 0;
299*7fd79137SRobert Mustacchi         /* Now overwrite the existing table descriptor with
300*7fd79137SRobert Mustacchi            the new, newly valid, contents. */
301*7fd79137SRobert Mustacchi         *hash_table_base = newht;
302*7fd79137SRobert Mustacchi     } /* Else is ok as is, add entry */
303*7fd79137SRobert Mustacchi 
304*7fd79137SRobert Mustacchi 
305*7fd79137SRobert Mustacchi     hashable_val = code;
306*7fd79137SRobert Mustacchi     hash_num = hashable_val %
307*7fd79137SRobert Mustacchi         hash_table_base->tb_table_entry_count;
308*7fd79137SRobert Mustacchi     entry_base = hash_table_base->tb_entries;
309*7fd79137SRobert Mustacchi     entry_cur  = entry_base + hash_num;
310*7fd79137SRobert Mustacchi 
311*7fd79137SRobert Mustacchi     /* Determine if the 'code' is the list of synonyms already. */
312*7fd79137SRobert Mustacchi     for (hash_abbrev_entry = entry_cur->at_head;
313*7fd79137SRobert Mustacchi          hash_abbrev_entry != NULL && hash_abbrev_entry->ab_code != code;
314*7fd79137SRobert Mustacchi          hash_abbrev_entry = hash_abbrev_entry->ab_next);
315*7fd79137SRobert Mustacchi     if (hash_abbrev_entry != NULL) {
316*7fd79137SRobert Mustacchi         /* This returns a pointer to an abbrev list entry, not
317*7fd79137SRobert Mustacchi            the list itself. */
318*7fd79137SRobert Mustacchi         return (hash_abbrev_entry);
319*7fd79137SRobert Mustacchi     }
320*7fd79137SRobert Mustacchi 
321*7fd79137SRobert Mustacchi     abbrev_ptr = cu_context->cc_last_abbrev_ptr != NULL ?
322*7fd79137SRobert Mustacchi         cu_context->cc_last_abbrev_ptr :
323*7fd79137SRobert Mustacchi         dbg->de_debug_abbrev.dss_data + cu_context->cc_abbrev_offset;
324*7fd79137SRobert Mustacchi 
325*7fd79137SRobert Mustacchi     /* End of abbrev's for this cu, since abbrev code is 0. */
326*7fd79137SRobert Mustacchi     if (*abbrev_ptr == 0) {
327*7fd79137SRobert Mustacchi         return (NULL);
328*7fd79137SRobert Mustacchi     }
329*7fd79137SRobert Mustacchi 
330*7fd79137SRobert Mustacchi     do {
331*7fd79137SRobert Mustacchi         unsigned new_hashable_val;
332*7fd79137SRobert Mustacchi         DECODE_LEB128_UWORD(abbrev_ptr, abbrev_code);
333*7fd79137SRobert Mustacchi         DECODE_LEB128_UWORD(abbrev_ptr, abbrev_tag);
334*7fd79137SRobert Mustacchi 
335*7fd79137SRobert Mustacchi         inner_list_entry = (Dwarf_Abbrev_List)
336*7fd79137SRobert Mustacchi             _dwarf_get_alloc(cu_context->cc_dbg, DW_DLA_ABBREV_LIST, 1);
337*7fd79137SRobert Mustacchi         if (inner_list_entry == NULL)
338*7fd79137SRobert Mustacchi             return (NULL);
339*7fd79137SRobert Mustacchi 
340*7fd79137SRobert Mustacchi         new_hashable_val = abbrev_code;
341*7fd79137SRobert Mustacchi         hash_num = new_hashable_val %
342*7fd79137SRobert Mustacchi             hash_table_base->tb_table_entry_count;
343*7fd79137SRobert Mustacchi         inner_hash_entry = entry_base + hash_num;
344*7fd79137SRobert Mustacchi         /* Move_entry_to_new_hash */
345*7fd79137SRobert Mustacchi         inner_list_entry->ab_next = inner_hash_entry->at_head;
346*7fd79137SRobert Mustacchi         inner_hash_entry->at_head = inner_list_entry;
347*7fd79137SRobert Mustacchi 
348*7fd79137SRobert Mustacchi         hash_table_base->tb_total_abbrev_count++;
349*7fd79137SRobert Mustacchi 
350*7fd79137SRobert Mustacchi         inner_list_entry->ab_code = abbrev_code;
351*7fd79137SRobert Mustacchi         inner_list_entry->ab_tag = abbrev_tag;
352*7fd79137SRobert Mustacchi         inner_list_entry->ab_has_child = *(abbrev_ptr++);
353*7fd79137SRobert Mustacchi         inner_list_entry->ab_abbrev_ptr = abbrev_ptr;
354*7fd79137SRobert Mustacchi 
355*7fd79137SRobert Mustacchi         /* Cycle thru the abbrev content, ignoring the content except
356*7fd79137SRobert Mustacchi            to find the end of the content. */
357*7fd79137SRobert Mustacchi         do {
358*7fd79137SRobert Mustacchi             DECODE_LEB128_UWORD(abbrev_ptr, attr_name);
359*7fd79137SRobert Mustacchi             DECODE_LEB128_UWORD(abbrev_ptr, attr_form);
360*7fd79137SRobert Mustacchi         } while (attr_name != 0 && attr_form != 0);
361*7fd79137SRobert Mustacchi 
362*7fd79137SRobert Mustacchi     } while (*abbrev_ptr != 0 && abbrev_code != code);
363*7fd79137SRobert Mustacchi 
364*7fd79137SRobert Mustacchi     cu_context->cc_last_abbrev_ptr = abbrev_ptr;
365*7fd79137SRobert Mustacchi     return (abbrev_code == code ? inner_list_entry : NULL);
366*7fd79137SRobert Mustacchi }
367*7fd79137SRobert Mustacchi 
368*7fd79137SRobert Mustacchi 
369*7fd79137SRobert Mustacchi /* return 1 if string ends before 'endptr' else
370*7fd79137SRobert Mustacchi ** return 0 meaning string is not properly terminated.
371*7fd79137SRobert Mustacchi ** Presumption is the 'endptr' pts to end of some dwarf section data.
372*7fd79137SRobert Mustacchi */
373*7fd79137SRobert Mustacchi int
374*7fd79137SRobert Mustacchi _dwarf_string_valid(void *startptr, void *endptr)
375*7fd79137SRobert Mustacchi {
376*7fd79137SRobert Mustacchi 
377*7fd79137SRobert Mustacchi     char *start = startptr;
378*7fd79137SRobert Mustacchi     char *end = endptr;
379*7fd79137SRobert Mustacchi 
380*7fd79137SRobert Mustacchi     while (start < end) {
381*7fd79137SRobert Mustacchi         if (*start == 0) {
382*7fd79137SRobert Mustacchi             return 1;           /* OK! */
383*7fd79137SRobert Mustacchi         }
384*7fd79137SRobert Mustacchi         ++start;
385*7fd79137SRobert Mustacchi         ++end;
386*7fd79137SRobert Mustacchi     }
387*7fd79137SRobert Mustacchi     return 0;                   /* FAIL! bad string! */
388*7fd79137SRobert Mustacchi }
389*7fd79137SRobert Mustacchi 
390*7fd79137SRobert Mustacchi /*
391*7fd79137SRobert Mustacchi   A byte-swapping version of memcpy
392*7fd79137SRobert Mustacchi   for cross-endian use.
393*7fd79137SRobert Mustacchi   Only 2,4,8 should be lengths passed in.
394*7fd79137SRobert Mustacchi */
395*7fd79137SRobert Mustacchi void *
396*7fd79137SRobert Mustacchi _dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len)
397*7fd79137SRobert Mustacchi {
398*7fd79137SRobert Mustacchi     void *orig_s1 = s1;
399*7fd79137SRobert Mustacchi     unsigned char *targ = (unsigned char *) s1;
400*7fd79137SRobert Mustacchi     unsigned char *src = (unsigned char *) s2;
401*7fd79137SRobert Mustacchi 
402*7fd79137SRobert Mustacchi     if (len == 4) {
403*7fd79137SRobert Mustacchi         targ[3] = src[0];
404*7fd79137SRobert Mustacchi         targ[2] = src[1];
405*7fd79137SRobert Mustacchi         targ[1] = src[2];
406*7fd79137SRobert Mustacchi         targ[0] = src[3];
407*7fd79137SRobert Mustacchi     } else if (len == 8) {
408*7fd79137SRobert Mustacchi         targ[7] = src[0];
409*7fd79137SRobert Mustacchi         targ[6] = src[1];
410*7fd79137SRobert Mustacchi         targ[5] = src[2];
411*7fd79137SRobert Mustacchi         targ[4] = src[3];
412*7fd79137SRobert Mustacchi         targ[3] = src[4];
413*7fd79137SRobert Mustacchi         targ[2] = src[5];
414*7fd79137SRobert Mustacchi         targ[1] = src[6];
415*7fd79137SRobert Mustacchi         targ[0] = src[7];
416*7fd79137SRobert Mustacchi     } else if (len == 2) {
417*7fd79137SRobert Mustacchi         targ[1] = src[0];
418*7fd79137SRobert Mustacchi         targ[0] = src[1];
419*7fd79137SRobert Mustacchi     }
420*7fd79137SRobert Mustacchi /* should NOT get below here: is not the intended use */
421*7fd79137SRobert Mustacchi     else if (len == 1) {
422*7fd79137SRobert Mustacchi         targ[0] = src[0];
423*7fd79137SRobert Mustacchi     } else {
424*7fd79137SRobert Mustacchi         memcpy(s1, s2, len);
425*7fd79137SRobert Mustacchi     }
426*7fd79137SRobert Mustacchi 
427*7fd79137SRobert Mustacchi     return orig_s1;
428*7fd79137SRobert Mustacchi }
429*7fd79137SRobert Mustacchi 
430*7fd79137SRobert Mustacchi 
431*7fd79137SRobert Mustacchi /*
432*7fd79137SRobert Mustacchi   This calculation used to be sprinkled all over.
433*7fd79137SRobert Mustacchi   Now brought to one place.
434*7fd79137SRobert Mustacchi 
435*7fd79137SRobert Mustacchi   We try to accurately compute the size of a cu header
436*7fd79137SRobert Mustacchi   given a known cu header location ( an offset in .debug_info).
437*7fd79137SRobert Mustacchi 
438*7fd79137SRobert Mustacchi */
439*7fd79137SRobert Mustacchi /* ARGSUSED */
440*7fd79137SRobert Mustacchi Dwarf_Unsigned
441*7fd79137SRobert Mustacchi _dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset)
442*7fd79137SRobert Mustacchi {
443*7fd79137SRobert Mustacchi     int local_length_size = 0;
444*7fd79137SRobert Mustacchi     int local_extension_size = 0;
445*7fd79137SRobert Mustacchi     Dwarf_Unsigned length = 0;
446*7fd79137SRobert Mustacchi     Dwarf_Small *cuptr = dbg->de_debug_info.dss_data + offset;
447*7fd79137SRobert Mustacchi 
448*7fd79137SRobert Mustacchi     READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
449*7fd79137SRobert Mustacchi                      cuptr, local_length_size, local_extension_size);
450*7fd79137SRobert Mustacchi 
451*7fd79137SRobert Mustacchi     return local_extension_size +       /* initial extesion, if present
452*7fd79137SRobert Mustacchi                                          */
453*7fd79137SRobert Mustacchi         local_length_size +     /* Size of cu length field. */
454*7fd79137SRobert Mustacchi         sizeof(Dwarf_Half) +    /* Size of version stamp field. */
455*7fd79137SRobert Mustacchi         local_length_size +     /* Size of abbrev offset field. */
456*7fd79137SRobert Mustacchi         sizeof(Dwarf_Small);    /* Size of address size field. */
457*7fd79137SRobert Mustacchi 
458*7fd79137SRobert Mustacchi }
459*7fd79137SRobert Mustacchi 
460*7fd79137SRobert Mustacchi /*
461*7fd79137SRobert Mustacchi         Pretend we know nothing about the CU
462*7fd79137SRobert Mustacchi         and just roughly compute the result.
463*7fd79137SRobert Mustacchi */
464*7fd79137SRobert Mustacchi Dwarf_Unsigned
465*7fd79137SRobert Mustacchi _dwarf_length_of_cu_header_simple(Dwarf_Debug dbg)
466*7fd79137SRobert Mustacchi {
467*7fd79137SRobert Mustacchi     return dbg->de_length_size +        /* Size of cu length field. */
468*7fd79137SRobert Mustacchi         sizeof(Dwarf_Half) +    /* Size of version stamp field. */
469*7fd79137SRobert Mustacchi         dbg->de_length_size +   /* Size of abbrev offset field. */
470*7fd79137SRobert Mustacchi         sizeof(Dwarf_Small);    /* Size of address size field. */
471*7fd79137SRobert Mustacchi }
472*7fd79137SRobert Mustacchi 
473*7fd79137SRobert Mustacchi /* Now that we delay loading .debug_info, we need to do the
474*7fd79137SRobert Mustacchi    load in more places. So putting the load
475*7fd79137SRobert Mustacchi    code in one place now instead of replicating it in multiple
476*7fd79137SRobert Mustacchi    places.
477*7fd79137SRobert Mustacchi 
478*7fd79137SRobert Mustacchi */
479*7fd79137SRobert Mustacchi int
480*7fd79137SRobert Mustacchi _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error * error)
481*7fd79137SRobert Mustacchi {
482*7fd79137SRobert Mustacchi     int res = DW_DLV_ERROR;
483*7fd79137SRobert Mustacchi 
484*7fd79137SRobert Mustacchi     /* Testing de_debug_info.dss_data allows us to avoid testing
485*7fd79137SRobert Mustacchi        de_debug_abbrev.dss_data.
486*7fd79137SRobert Mustacchi        One test instead of 2. .debug_info is useless
487*7fd79137SRobert Mustacchi        without .debug_abbrev. */
488*7fd79137SRobert Mustacchi     if (dbg->de_debug_info.dss_data) {
489*7fd79137SRobert Mustacchi         return DW_DLV_OK;
490*7fd79137SRobert Mustacchi     }
491*7fd79137SRobert Mustacchi 
492*7fd79137SRobert Mustacchi     res = _dwarf_load_section(dbg, &dbg->de_debug_abbrev,error);
493*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
494*7fd79137SRobert Mustacchi         return res;
495*7fd79137SRobert Mustacchi     }
496*7fd79137SRobert Mustacchi     res = _dwarf_load_section(dbg, &dbg->de_debug_info, error);
497*7fd79137SRobert Mustacchi     return res;
498*7fd79137SRobert Mustacchi 
499*7fd79137SRobert Mustacchi }
500*7fd79137SRobert Mustacchi void
501*7fd79137SRobert Mustacchi _dwarf_free_abbrev_hash_table_contents(Dwarf_Debug dbg,Dwarf_Hash_Table hash_table)
502*7fd79137SRobert Mustacchi {
503*7fd79137SRobert Mustacchi     /* A Hash Table is an array with tb_table_entry_count struct
504*7fd79137SRobert Mustacchi        Dwarf_Hash_Table_s entries in the array. */
505*7fd79137SRobert Mustacchi     int hashnum = 0;
506*7fd79137SRobert Mustacchi     for (; hashnum < hash_table->tb_table_entry_count; ++hashnum) {
507*7fd79137SRobert Mustacchi         struct Dwarf_Abbrev_List_s *abbrev = 0;
508*7fd79137SRobert Mustacchi         struct Dwarf_Abbrev_List_s *nextabbrev = 0;
509*7fd79137SRobert Mustacchi         struct  Dwarf_Hash_Table_Entry_s *tb =  &hash_table->tb_entries[hashnum];
510*7fd79137SRobert Mustacchi 
511*7fd79137SRobert Mustacchi         abbrev = tb->at_head;
512*7fd79137SRobert Mustacchi         for (; abbrev; abbrev = nextabbrev) {
513*7fd79137SRobert Mustacchi             nextabbrev = abbrev->ab_next;
514*7fd79137SRobert Mustacchi             dwarf_dealloc(dbg, abbrev, DW_DLA_ABBREV_LIST);
515*7fd79137SRobert Mustacchi         }
516*7fd79137SRobert Mustacchi     }
517*7fd79137SRobert Mustacchi     /* Frees all the entries at once: an array. */
518*7fd79137SRobert Mustacchi     dwarf_dealloc(dbg,hash_table->tb_entries,DW_DLA_HASH_TABLE_ENTRY);
519*7fd79137SRobert Mustacchi }
520*7fd79137SRobert Mustacchi 
521*7fd79137SRobert Mustacchi /*
522*7fd79137SRobert Mustacchi     If no die provided the size value returned might be wrong.
523*7fd79137SRobert Mustacchi     If different compilation units have different address sizes
524*7fd79137SRobert Mustacchi     this may not give the correct value in all contexts if the die
525*7fd79137SRobert Mustacchi     pointer is NULL.
526*7fd79137SRobert Mustacchi     If the Elf offset size != address_size
527*7fd79137SRobert Mustacchi     (for example if address_size = 4 but recorded in elf64 object)
528*7fd79137SRobert Mustacchi     this may not give the correct value in all contexts if the die
529*7fd79137SRobert Mustacchi     pointer is NULL.
530*7fd79137SRobert Mustacchi     If the die pointer is non-NULL (in which case it must point to
531*7fd79137SRobert Mustacchi     a valid DIE) this will return the correct size.
532*7fd79137SRobert Mustacchi */
533*7fd79137SRobert Mustacchi int
534*7fd79137SRobert Mustacchi _dwarf_get_address_size(Dwarf_Debug dbg, Dwarf_Die die)
535*7fd79137SRobert Mustacchi {
536*7fd79137SRobert Mustacchi     Dwarf_CU_Context context = 0;
537*7fd79137SRobert Mustacchi     Dwarf_Half addrsize = 0;
538*7fd79137SRobert Mustacchi     if(!die) {
539*7fd79137SRobert Mustacchi         return dbg->de_pointer_size;
540*7fd79137SRobert Mustacchi     }
541*7fd79137SRobert Mustacchi     context = die->di_cu_context;
542*7fd79137SRobert Mustacchi     addrsize = context->cc_address_size;
543*7fd79137SRobert Mustacchi     return addrsize;
544*7fd79137SRobert Mustacchi }
545*7fd79137SRobert Mustacchi 
546*7fd79137SRobert Mustacchi 
547*7fd79137SRobert Mustacchi 
548