xref: /titanic_41/usr/src/tools/ctf/dwarf/common/dwarf_util.c (revision 5aeb94743e3be0c51e86f73096334611ae3a058e)
1 /*
2 
3   Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
4 
5   This program is free software; you can redistribute it and/or modify it
6   under the terms of version 2.1 of the GNU Lesser General Public License
7   as published by the Free Software Foundation.
8 
9   This program is distributed in the hope that it would be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13   Further, this software is distributed without any warranty that it is
14   free of the rightful claim of any third person regarding infringement
15   or the like.  Any license provided herein, whether implied or
16   otherwise, applies only to this software file.  Patent licenses, if
17   any, provided herein do not apply to combinations of this program with
18   other software, or any other product whatsoever.
19 
20   You should have received a copy of the GNU Lesser General Public
21   License along with this program; if not, write the Free Software
22   Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
23   USA.
24 
25   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
26   Mountain View, CA 94043, or:
27 
28   http://www.sgi.com
29 
30   For further information regarding this notice, see:
31 
32   http://oss.sgi.com/projects/GenInfo/NoticeExplan
33 
34 */
35 
36 
37 
38 #include "config.h"
39 #include "dwarf_incl.h"
40 #include <stdio.h>
41 #include "dwarf_die_deliv.h"
42 
43 
44 
45 /*
46     Given a form, and a pointer to the bytes encoding
47     a value of that form, val_ptr, this function returns
48     the length, in bytes, of a value of that form.
49     When using this function, check for a return of 0
50     a recursive DW_FORM_INDIRECT value.
51 */
52 Dwarf_Unsigned
53 _dwarf_get_size_of_val(Dwarf_Debug dbg,
54 		       Dwarf_Unsigned form,
55 		       Dwarf_Small * val_ptr, int v_length_size)
56 {
57     Dwarf_Unsigned length = 0;
58     Dwarf_Word leb128_length = 0;
59     Dwarf_Unsigned form_indirect = 0;
60     Dwarf_Unsigned ret_value = 0;
61 
62     switch (form) {
63 
64     default:			/* Handles form = 0. */
65 	return (form);
66 
67     case DW_FORM_addr:
68 	return (dbg->de_pointer_size);
69 
70     case DW_FORM_ref_addr:
71 	return (v_length_size);
72 
73     case DW_FORM_block1:
74 	return (*(Dwarf_Small *) val_ptr + 1);
75 
76     case DW_FORM_block2:
77 	READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
78 		       val_ptr, sizeof(Dwarf_Half));
79 	return (ret_value + sizeof(Dwarf_Half));
80 
81     case DW_FORM_block4:
82 	READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
83 		       val_ptr, sizeof(Dwarf_ufixed));
84 	return (ret_value + sizeof(Dwarf_ufixed));
85 
86 
87     case DW_FORM_data1:
88 	return (1);
89 
90     case DW_FORM_data2:
91 	return (2);
92 
93     case DW_FORM_data4:
94 	return (4);
95 
96     case DW_FORM_data8:
97 	return (8);
98 
99     case DW_FORM_string:
100 	return (strlen((char *) val_ptr) + 1);
101 
102     case DW_FORM_block:
103 	length = _dwarf_decode_u_leb128(val_ptr, &leb128_length);
104 	return (length + leb128_length);
105 
106     case DW_FORM_flag:
107 	return (1);
108 
109     case DW_FORM_ref_udata:
110 	_dwarf_decode_u_leb128(val_ptr, &leb128_length);
111 	return (leb128_length);
112 
113     case DW_FORM_indirect:
114 	{
115 	    Dwarf_Word indir_len = 0;
116 
117 	    form_indirect = _dwarf_decode_u_leb128(val_ptr, &indir_len);
118 	    if (form_indirect == DW_FORM_indirect) {
119 		return (0);	/* We are in big trouble: The true form
120 				   of DW_FORM_indirect is
121 				   DW_FORM_indirect? Nonsense. Should
122 				   never happen. */
123 	    }
124 	    return (indir_len + _dwarf_get_size_of_val(dbg,
125 						       form_indirect,
126 						       val_ptr +
127 						       indir_len,
128 						       v_length_size));
129 	}
130 
131     case DW_FORM_ref1:
132 	return (1);
133 
134     case DW_FORM_ref2:
135 	return (2);
136 
137     case DW_FORM_ref4:
138 	return (4);
139 
140     case DW_FORM_ref8:
141 	return (8);
142 
143     case DW_FORM_sdata:
144 	_dwarf_decode_s_leb128(val_ptr, &leb128_length);
145 	return (leb128_length);
146 
147     case DW_FORM_strp:
148 	return (v_length_size);
149 
150     case DW_FORM_udata:
151 	_dwarf_decode_u_leb128(val_ptr, &leb128_length);
152 	return (leb128_length);
153     }
154 }
155 
156 
157 /*
158     This function returns a pointer to a Dwarf_Abbrev_List_s
159     struct for the abbrev with the given code.  It puts the
160     struct on the appropriate hash table.  It also adds all
161     the abbrev between the last abbrev added and this one to
162     the hash table.  In other words, the .debug_abbrev section
163     is scanned sequentially from the top for an abbrev with
164     the given code.  All intervening abbrevs are also put
165     into the hash table.
166 
167     This function hashes the given code, and checks the chain
168     at that hash table entry to see if a Dwarf_Abbrev_List_s
169     with the given code exists.  If yes, it returns a pointer
170     to that struct.  Otherwise, it scans the .debug_abbrev
171     section from the last byte scanned for that CU till either
172     an abbrev with the given code is found, or an abbrev code
173     of 0 is read.  It puts Dwarf_Abbrev_List_s entries for all
174     abbrev's read till that point into the hash table.  The
175     hash table contains both a head pointer and a tail pointer
176     for each entry.
177 
178     Returns NULL on error.
179 */
180 Dwarf_Abbrev_List
181 _dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Word code)
182 {
183     Dwarf_Debug dbg = cu_context->cc_dbg;
184     Dwarf_Hash_Table hash_table = cu_context->cc_abbrev_hash_table;
185     Dwarf_Word hash_num;
186     Dwarf_Abbrev_List hash_abbrev_list;
187     Dwarf_Abbrev_List abbrev_list;
188     Dwarf_Byte_Ptr abbrev_ptr;
189     Dwarf_Half abbrev_code, abbrev_tag;
190     Dwarf_Half attr_name, attr_form;
191 
192     hash_num = code % ABBREV_HASH_TABLE_SIZE;
193     for (hash_abbrev_list = hash_table[hash_num].at_head;
194 	 hash_abbrev_list != NULL && hash_abbrev_list->ab_code != code;
195 	 hash_abbrev_list = hash_abbrev_list->ab_next);
196     if (hash_abbrev_list != NULL)
197 	return (hash_abbrev_list);
198 
199     abbrev_ptr = cu_context->cc_last_abbrev_ptr != NULL ?
200 	cu_context->cc_last_abbrev_ptr :
201 	dbg->de_debug_abbrev + cu_context->cc_abbrev_offset;
202 
203     /* End of abbrev's for this cu, since abbrev code is 0. */
204     if (*abbrev_ptr == 0) {
205 	return (NULL);
206     }
207 
208     do {
209 	Dwarf_Unsigned utmp;
210 
211 	DECODE_LEB128_UWORD(abbrev_ptr, utmp)
212 	    abbrev_code = (Dwarf_Half) utmp;
213 	DECODE_LEB128_UWORD(abbrev_ptr, utmp)
214 	    abbrev_tag = (Dwarf_Half) utmp;
215 
216 	abbrev_list = (Dwarf_Abbrev_List)
217 	    _dwarf_get_alloc(cu_context->cc_dbg, DW_DLA_ABBREV_LIST, 1);
218 	if (abbrev_list == NULL)
219 	    return (NULL);
220 
221 	hash_num = abbrev_code % ABBREV_HASH_TABLE_SIZE;
222 	if (hash_table[hash_num].at_head == NULL) {
223 	    hash_table[hash_num].at_head =
224 		hash_table[hash_num].at_tail = abbrev_list;
225 	} else {
226 	    hash_table[hash_num].at_tail->ab_next = abbrev_list;
227 	    hash_table[hash_num].at_tail = abbrev_list;
228 	}
229 
230 	abbrev_list->ab_code = abbrev_code;
231 	abbrev_list->ab_tag = abbrev_tag;
232 
233 	abbrev_list->ab_has_child = *(abbrev_ptr++);
234 	abbrev_list->ab_abbrev_ptr = abbrev_ptr;
235 
236 	do {
237 	    Dwarf_Unsigned utmp3;
238 
239 	    DECODE_LEB128_UWORD(abbrev_ptr, utmp3)
240 		attr_name = (Dwarf_Half) utmp3;
241 	    DECODE_LEB128_UWORD(abbrev_ptr, utmp3)
242 		attr_form = (Dwarf_Half) utmp3;
243 	} while (attr_name != 0 && attr_form != 0);
244 
245     } while (*abbrev_ptr != 0 && abbrev_code != code);
246 
247     cu_context->cc_last_abbrev_ptr = abbrev_ptr;
248     return (abbrev_code == code ? abbrev_list : NULL);
249 }
250 
251 
252 /* return 1 if string ends before 'endptr' else
253 ** return 0 meaning string is not properly terminated.
254 ** Presumption is the 'endptr' pts to end of some dwarf section data.
255 */
256 int
257 _dwarf_string_valid(void *startptr, void *endptr)
258 {
259 
260     char *start = startptr;
261     char *end = endptr;
262 
263     while (start < end) {
264 	if (*start == 0) {
265 	    return 1;		/* OK! */
266 	}
267 	++start;
268 	++end;
269     }
270     return 0;			/* FAIL! bad string! */
271 }
272 
273 /*
274   A byte-swapping version of memcpy
275   for cross-endian use.
276   Only 2,4,8 should be lengths passed in.
277 */
278 void *
279 _dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len)
280 {
281     void *orig_s1 = s1;
282     unsigned char *targ = (unsigned char *) s1;
283     unsigned char *src = (unsigned char *) s2;
284 
285     if (len == 4) {
286 	targ[3] = src[0];
287 	targ[2] = src[1];
288 	targ[1] = src[2];
289 	targ[0] = src[3];
290     } else if (len == 8) {
291 	targ[7] = src[0];
292 	targ[6] = src[1];
293 	targ[5] = src[2];
294 	targ[4] = src[3];
295 	targ[3] = src[4];
296 	targ[2] = src[5];
297 	targ[1] = src[6];
298 	targ[0] = src[7];
299     } else if (len == 2) {
300 	targ[1] = src[0];
301 	targ[0] = src[1];
302     }
303 /* should NOT get below here: is not the intended use */
304     else if (len == 1) {
305 	targ[0] = src[0];
306     } else {
307 	memcpy(s1, s2, len);
308     }
309 
310     return orig_s1;
311 }
312 
313 
314 /*
315   This calculation used to be sprinkled all over.
316   Now brought to one place.
317 
318   We try to accurately compute the size of a cu header
319   given a known cu header location ( an offset in .debug_info).
320 
321 */
322 /* ARGSUSED */
323 Dwarf_Unsigned
324 _dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset)
325 {
326     int local_length_size = 0;
327     int local_extension_size = 0;
328     Dwarf_Unsigned length = 0;
329     Dwarf_Small *cuptr = dbg->de_debug_info + offset;
330 
331     READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
332 		     cuptr, local_length_size, local_extension_size);
333 
334     return local_extension_size +	/* initial extesion, if present
335 					 */
336 	local_length_size +	/* Size of cu length field. */
337 	sizeof(Dwarf_Half) +	/* Size of version stamp field. */
338 	local_length_size +	/* Size of abbrev offset field. */
339 	sizeof(Dwarf_Small);	/* Size of address size field. */
340 
341 }
342 
343 /*
344 	Pretend we know nothing about the CU
345 	and just roughly compute the result.
346 */
347 Dwarf_Unsigned
348 _dwarf_length_of_cu_header_simple(Dwarf_Debug dbg)
349 {
350     return dbg->de_length_size +	/* Size of cu length field. */
351 	sizeof(Dwarf_Half) +	/* Size of version stamp field. */
352 	dbg->de_length_size +	/* Size of abbrev offset field. */
353 	sizeof(Dwarf_Small);	/* Size of address size field. */
354 }
355 
356 /* Now that we delay loading .debug_info, we need to do the
357    load in more places. So putting the load
358    code in one place now instead of replicating it in multiple
359    places.
360 
361 */
362 int
363 _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error * error)
364 {
365     int res;
366 
367     /* Testing de_debug_info allows us to avoid testing
368        de_debug_abbrev. One test instead of 2. .debug_info is useless
369        without .debug_abbrev. */
370     if (dbg->de_debug_info) {
371 	return DW_DLV_OK;
372     }
373 
374     res = _dwarf_load_section(dbg, dbg->de_debug_abbrev_index,
375 			      &dbg->de_debug_abbrev, error);
376     if (res != DW_DLV_OK) {
377 	return res;
378     }
379     res = _dwarf_load_section(dbg, dbg->de_debug_info_index,
380 			      &dbg->de_debug_info, error);
381     return res;
382 
383 }
384