xref: /titanic_50/usr/src/lib/libdwarf/common/dwarf_form.c (revision f3e7f55e73a39377d55a030f124cc86b3b66a9cc)
1 /*
2 
3   Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved.
4   Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved.
5   Portions Copyright 2008-2010 David Anderson. All rights reserved.
6 
7   This program is free software; you can redistribute it and/or modify it
8   under the terms of version 2.1 of the GNU Lesser General Public License
9   as published by the Free Software Foundation.
10 
11   This program is distributed in the hope that it would be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 
15   Further, this software is distributed without any warranty that it is
16   free of the rightful claim of any third person regarding infringement
17   or the like.  Any license provided herein, whether implied or
18   otherwise, applies only to this software file.  Patent licenses, if
19   any, provided herein do not apply to combinations of this program with
20   other software, or any other product whatsoever.
21 
22   You should have received a copy of the GNU Lesser General Public
23   License along with this program; if not, write the Free Software
24   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
25   USA.
26 
27   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
28   Mountain View, CA 94043, or:
29 
30   http://www.sgi.com
31 
32   For further information regarding this notice, see:
33 
34   http://oss.sgi.com/projects/GenInfo/NoticeExplan
35 
36 */
37 
38 
39 
40 #include "config.h"
41 #include "dwarf_incl.h"
42 #include "dwarf_die_deliv.h"
43 
44 int
dwarf_hasform(Dwarf_Attribute attr,Dwarf_Half form,Dwarf_Bool * return_bool,Dwarf_Error * error)45 dwarf_hasform(Dwarf_Attribute attr,
46               Dwarf_Half form,
47               Dwarf_Bool * return_bool, Dwarf_Error * error)
48 {
49     Dwarf_CU_Context cu_context = 0;
50 
51     if (attr == NULL) {
52         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
53         return (DW_DLV_ERROR);
54     }
55 
56     cu_context = attr->ar_cu_context;
57     if (cu_context == NULL) {
58         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
59         return (DW_DLV_ERROR);
60     }
61 
62     if (cu_context->cc_dbg == NULL) {
63         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
64         return (DW_DLV_ERROR);
65     }
66 
67     *return_bool = (attr->ar_attribute_form == form);
68     return DW_DLV_OK;
69 }
70 
71 /* Not often called, we do not worry about efficiency here.
72    The dwarf_whatform() call does the sanity checks for us.
73 */
74 int
dwarf_whatform_direct(Dwarf_Attribute attr,Dwarf_Half * return_form,Dwarf_Error * error)75 dwarf_whatform_direct(Dwarf_Attribute attr,
76                       Dwarf_Half * return_form, Dwarf_Error * error)
77 {
78     int res = dwarf_whatform(attr, return_form, error);
79 
80     if (res != DW_DLV_OK) {
81         return res;
82     }
83 
84     *return_form = attr->ar_attribute_form_direct;
85     return (DW_DLV_OK);
86 }
87 void *
dwarf_uncompress_integer_block(Dwarf_Debug dbg,Dwarf_Bool unit_is_signed,Dwarf_Small unit_length_in_bits,void * input_block,Dwarf_Unsigned input_length_in_bytes,Dwarf_Unsigned * output_length_in_units_ptr,Dwarf_Error * error)88 dwarf_uncompress_integer_block(
89     Dwarf_Debug      dbg,
90     Dwarf_Bool       unit_is_signed,
91     Dwarf_Small      unit_length_in_bits,
92     void*            input_block,
93     Dwarf_Unsigned   input_length_in_bytes,
94     Dwarf_Unsigned*  output_length_in_units_ptr,
95     Dwarf_Error*     error
96 )
97 {
98     Dwarf_Unsigned output_length_in_units = 0;
99     void * output_block = 0;
100     int i = 0;
101     char * ptr = 0;
102     int remain = 0;
103     Dwarf_sfixed * array = 0;
104 
105     if (dbg == NULL) {
106         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
107         return((void *)DW_DLV_BADADDR);
108     }
109 
110     if (unit_is_signed == false ||
111         unit_length_in_bits != 32 ||
112         input_block == NULL ||
113         input_length_in_bytes == 0 ||
114         output_length_in_units_ptr == NULL) {
115 
116         _dwarf_error(NULL, error, DW_DLE_BADBITC);
117         return ((void *) DW_DLV_BADADDR);
118     }
119 
120     /* At this point we assume the format is: signed 32 bit */
121 
122     /* first uncompress everything to find the total size. */
123 
124     output_length_in_units = 0;
125     remain = input_length_in_bytes;
126     ptr = input_block;
127     while (remain > 0) {
128         Dwarf_Signed num;
129         Dwarf_Word len;
130         num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len);
131         ptr += len;
132         remain -= len;
133         output_length_in_units++;
134     }
135 
136     if (remain != 0) {
137         _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
138         return((void *)DW_DLV_BADADDR);
139     }
140 
141     /* then alloc */
142 
143     output_block = (void *)
144         _dwarf_get_alloc(dbg,
145                          DW_DLA_STRING,
146                          output_length_in_units * (unit_length_in_bits / 8));
147     if (output_block == NULL) {
148         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
149         return((void*)DW_DLV_BADADDR);
150     }
151 
152     /* then uncompress again and copy into new buffer */
153 
154     array = (Dwarf_sfixed *) output_block;
155     remain = input_length_in_bytes;
156     ptr = input_block;
157     for (i=0; i<output_length_in_units && remain>0; i++) {
158         Dwarf_Signed num;
159         Dwarf_Word len;
160         num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len);
161         ptr += len;
162         remain -= len;
163         array[i] = num;
164     }
165 
166     if (remain != 0) {
167         dwarf_dealloc(dbg, (unsigned char *)output_block, DW_DLA_STRING);
168         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
169         return((Dwarf_P_Attribute)DW_DLV_BADADDR);
170     }
171 
172     *output_length_in_units_ptr = output_length_in_units;
173     return output_block;
174 }
175 
176 void
dwarf_dealloc_uncompressed_block(Dwarf_Debug dbg,void * space)177 dwarf_dealloc_uncompressed_block(Dwarf_Debug dbg, void * space)
178 {
179     dwarf_dealloc(dbg, space, DW_DLA_STRING);
180 }
181 
182 
183 int
dwarf_whatform(Dwarf_Attribute attr,Dwarf_Half * return_form,Dwarf_Error * error)184 dwarf_whatform(Dwarf_Attribute attr,
185                Dwarf_Half * return_form, Dwarf_Error * error)
186 {
187     Dwarf_CU_Context cu_context = 0;
188 
189     if (attr == NULL) {
190         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
191         return (DW_DLV_ERROR);
192     }
193 
194     cu_context = attr->ar_cu_context;
195     if (cu_context == NULL) {
196         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
197         return (DW_DLV_ERROR);
198     }
199 
200     if (cu_context->cc_dbg == NULL) {
201         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
202         return (DW_DLV_ERROR);
203     }
204 
205     *return_form = attr->ar_attribute_form;
206     return (DW_DLV_OK);
207 }
208 
209 
210 /*
211     This function is analogous to dwarf_whatform.
212     It returns the attribute in attr instead of
213     the form.
214 */
215 int
dwarf_whatattr(Dwarf_Attribute attr,Dwarf_Half * return_attr,Dwarf_Error * error)216 dwarf_whatattr(Dwarf_Attribute attr,
217                Dwarf_Half * return_attr, Dwarf_Error * error)
218 {
219     Dwarf_CU_Context cu_context = 0;
220 
221     if (attr == NULL) {
222         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
223         return (DW_DLV_ERROR);
224     }
225 
226     cu_context = attr->ar_cu_context;
227     if (cu_context == NULL) {
228         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
229         return (DW_DLV_ERROR);
230     }
231 
232     if (cu_context->cc_dbg == NULL) {
233         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
234         return (DW_DLV_ERROR);
235     }
236 
237     *return_attr = (attr->ar_attribute);
238     return DW_DLV_OK;
239 }
240 
241 
242 /*
243     A global offset cannot be returned by this interface:
244     see dwarf_global_formref().
245 
246     DW_FORM_ref_addr is considered an incorrect form
247     for this call because DW_FORM_ref_addr is a global-offset into
248     the debug_info section.
249 
250     For the same reason DW_FORM_data4/data8 are not returned
251     from this function.
252 
253     For the same reason DW_FORM_sec_offset is not returned
254     from this function, DW_FORM_sec_offset is a global offset
255     (to various sections, not a CU relative offset.
256 
257     DW_FORM_ref_addr has a value which was documented in
258     DWARF2 as address-size but which was always an offset
259     so should have always been offset size (wording
260     corrected in DWARF3).
261 
262 
263 */
264 int
dwarf_formref(Dwarf_Attribute attr,Dwarf_Off * ret_offset,Dwarf_Error * error)265 dwarf_formref(Dwarf_Attribute attr,
266               Dwarf_Off * ret_offset, Dwarf_Error * error)
267 {
268     Dwarf_Debug dbg = 0;
269     Dwarf_Unsigned offset = 0;
270     Dwarf_CU_Context cu_context = 0;
271 
272 
273     if (attr == NULL) {
274         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
275         return (DW_DLV_ERROR);
276     }
277 
278     cu_context = attr->ar_cu_context;
279     if (cu_context == NULL) {
280         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
281         return (DW_DLV_ERROR);
282     }
283 
284     if (cu_context->cc_dbg == NULL) {
285         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
286         return (DW_DLV_ERROR);
287     }
288     dbg = cu_context->cc_dbg;
289 
290     switch (attr->ar_attribute_form) {
291 
292     case DW_FORM_ref1:
293         offset = *(Dwarf_Small *) attr->ar_debug_info_ptr;
294         break;
295 
296     case DW_FORM_ref2:
297         READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
298                        attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
299         break;
300 
301     case DW_FORM_ref4:
302         READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
303                        attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
304         break;
305 
306     case DW_FORM_ref8:
307         READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
308                        attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
309         break;
310 
311     case DW_FORM_ref_udata:
312         offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL);
313         break;
314 
315     default:
316         _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM);
317         return (DW_DLV_ERROR);
318     }
319 
320     /* Check that offset is within current cu portion of .debug_info. */
321     if (offset >= cu_context->cc_length +
322         cu_context->cc_length_size + cu_context->cc_extension_size) {
323         _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
324         return (DW_DLV_ERROR);
325     }
326 
327     *ret_offset = (offset);
328     return DW_DLV_OK;
329 }
330 
331 /*  dwarf_formsig8 returns in the caller-provided 8 byte area
332     the 8 bytes of a DW_FORM_ref_sig8 (copying the bytes
333     directly to the caller).  Not a string, an 8 byte
334     MD5 hash.  This function is new in DWARF4 libdwarf.
335 */
dwarf_formsig8(Dwarf_Attribute attr,Dwarf_Sig8 * returned_sig_bytes,Dwarf_Error * error)336 int dwarf_formsig8(Dwarf_Attribute attr,
337     Dwarf_Sig8 * returned_sig_bytes,
338     Dwarf_Error*     error)
339 {
340     Dwarf_Debug dbg = 0;
341     Dwarf_Unsigned field_end_offset = 0;
342     Dwarf_CU_Context cu_context = 0;
343 
344 
345     if (attr == NULL) {
346         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
347         return (DW_DLV_ERROR);
348     }
349 
350     cu_context = attr->ar_cu_context;
351     if (cu_context == NULL) {
352         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
353         return (DW_DLV_ERROR);
354     }
355 
356     if (cu_context->cc_dbg == NULL) {
357         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
358         return (DW_DLV_ERROR);
359     }
360     dbg = cu_context->cc_dbg;
361 
362     if(attr->ar_attribute_form != DW_FORM_ref_sig8 ) {
363         _dwarf_error(dbg, error, DW_DLE_BAD_REF_SIG8_FORM);
364         return (DW_DLV_ERROR);
365     }
366 
367     field_end_offset = attr->ar_debug_info_ptr + sizeof(Dwarf_Sig8) -
368         (dbg->de_debug_info.dss_data + cu_context->cc_debug_info_offset);
369     /* Check that offset is within current cu portion of .debug_info. */
370     if (field_end_offset > cu_context->cc_length +
371         cu_context->cc_length_size + cu_context->cc_extension_size) {
372         _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
373         return (DW_DLV_ERROR);
374     }
375 
376     memcpy(returned_sig_bytes, attr->ar_debug_info_ptr,
377         sizeof(Dwarf_Sig8));
378     return DW_DLV_OK;
379 }
380 
381 
382 /*
383     Since this returns section-relative debug_info offsets,
384     this can represent all REFERENCE forms correctly
385     and allows all applicable forms.
386 
387     DW_FORM_ref_addr has a value which was documented in
388     DWARF2 as address-size but which was always an offset
389     so should have always been offset size (wording
390     corrected in DWARF3).
391 
392     See the DWARF4 document for the 3 cases fitting
393     reference forms.  The caller must determine which section the
394     reference 'points' to.  The function added in November 2009,
395     dwarf_get_form_class(), helps in this regard.
396 
397 */
398 int
dwarf_global_formref(Dwarf_Attribute attr,Dwarf_Off * ret_offset,Dwarf_Error * error)399 dwarf_global_formref(Dwarf_Attribute attr,
400                      Dwarf_Off * ret_offset, Dwarf_Error * error)
401 {
402     Dwarf_Debug dbg = 0;
403     Dwarf_Unsigned offset = 0;
404     Dwarf_Addr ref_addr = 0;
405     Dwarf_CU_Context cu_context = 0;
406     Dwarf_Half context_version = 0;
407 
408     if (attr == NULL) {
409         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
410         return (DW_DLV_ERROR);
411     }
412 
413     cu_context = attr->ar_cu_context;
414     if (cu_context == NULL) {
415         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
416         return (DW_DLV_ERROR);
417     }
418     context_version = cu_context->cc_version_stamp;
419 
420     if (cu_context->cc_dbg == NULL) {
421         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
422         return (DW_DLV_ERROR);
423     }
424     dbg = cu_context->cc_dbg;
425 
426     switch (attr->ar_attribute_form) {
427 
428     case DW_FORM_ref1:
429         offset = *(Dwarf_Small *) attr->ar_debug_info_ptr;
430         goto fixoffset;
431 
432     case DW_FORM_ref2:
433         READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
434                        attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
435         goto fixoffset;
436 
437     case DW_FORM_ref4:
438         READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
439                        attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
440         goto fixoffset;
441 
442     case DW_FORM_ref8:
443         READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
444                        attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
445         goto fixoffset;
446 
447     case DW_FORM_ref_udata:
448         offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL);
449 
450       fixoffset:                /* we have a local offset, make it
451                                    global */
452 
453         /* check legality of offset */
454         if (offset >= cu_context->cc_length +
455             cu_context->cc_length_size +
456             cu_context->cc_extension_size) {
457             _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
458             return (DW_DLV_ERROR);
459         }
460 
461         /* globalize the offset */
462         offset += cu_context->cc_debug_info_offset;
463         break;
464     /* The DWARF2 document did not make clear that
465        DW_FORM_data4( and 8) were references with
466        global offsets to some section.
467        That was first clearly documented in DWARF3.
468        In DWARF4 these two forms are no longer references. */
469     case DW_FORM_data4:
470         if(context_version == DW_CU_VERSION4) {
471             _dwarf_error(dbg, error, DW_DLE_NOT_REF_FORM);
472             return (DW_DLV_ERROR);
473         }
474         READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
475                        attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
476         /* The offset is global. */
477         break;
478     case DW_FORM_data8:
479         if(context_version == DW_CU_VERSION4) {
480             _dwarf_error(dbg, error, DW_DLE_NOT_REF_FORM);
481             return (DW_DLV_ERROR);
482         }
483         READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
484                        attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
485         /* The offset is global. */
486         break;
487     case DW_FORM_ref_addr:
488     case DW_FORM_sec_offset:
489         {
490             /* DW_FORM_sec_offset first exists in DWARF4.*/
491             /* It is up to the caller to know what the offset
492                of DW_FORM_sec_offset refers to,
493                the offset is not going to refer to .debug_info! */
494             unsigned length_size = cu_context->cc_length_size;
495             if(length_size == 4) {
496                 READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
497                        attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
498             } else if (length_size == 8) {
499                 READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
500                        attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
501             } else {
502                 _dwarf_error(dbg, error, DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD);
503                 return (DW_DLV_ERROR);
504             }
505         }
506         break;
507 
508     default:
509         _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM);
510         return (DW_DLV_ERROR);
511     }
512 
513     /* We do not know what section the offset refers to, so
514        we have no way to check it for correctness. */
515     *ret_offset = offset;
516     return DW_DLV_OK;
517 }
518 
519 
520 int
dwarf_formaddr(Dwarf_Attribute attr,Dwarf_Addr * return_addr,Dwarf_Error * error)521 dwarf_formaddr(Dwarf_Attribute attr,
522                Dwarf_Addr * return_addr, Dwarf_Error * error)
523 {
524     Dwarf_Debug dbg = 0;
525     Dwarf_Addr ret_addr = 0;
526     Dwarf_CU_Context cu_context = 0;
527 
528     if (attr == NULL) {
529         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
530         return (DW_DLV_ERROR);
531     }
532 
533     cu_context = attr->ar_cu_context;
534     if (cu_context == NULL) {
535         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
536         return (DW_DLV_ERROR);
537     }
538 
539     if (cu_context->cc_dbg == NULL) {
540         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
541         return (DW_DLV_ERROR);
542     }
543     dbg = cu_context->cc_dbg;
544 
545     if (attr->ar_attribute_form == DW_FORM_addr
546         /* || attr->ar_attribute_form == DW_FORM_ref_addr Allowance of
547            DW_FORM_ref_addr was a mistake. The value returned in that
548            case is NOT an address it is a global debug_info offset (ie,
549            not CU-relative offset within the CU in debug_info). The
550            Dwarf document refers to it as an address (misleadingly) in
551            sec 6.5.4 where it describes the reference form. It is
552            address-sized so that the linker can easily update it, but
553            it is a reference inside the debug_info section. No longer
554            allowed. */
555         ) {
556 
557         READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
558                        attr->ar_debug_info_ptr,
559                        cu_context->cc_address_size);
560         *return_addr = ret_addr;
561         return (DW_DLV_OK);
562     }
563 
564     _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
565     return (DW_DLV_ERROR);
566 }
567 
568 
569 int
dwarf_formflag(Dwarf_Attribute attr,Dwarf_Bool * ret_bool,Dwarf_Error * error)570 dwarf_formflag(Dwarf_Attribute attr,
571                Dwarf_Bool * ret_bool, Dwarf_Error * error)
572 {
573     Dwarf_CU_Context cu_context = 0;
574 
575     if (attr == NULL) {
576         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
577         return (DW_DLV_ERROR);
578     }
579 
580     cu_context = attr->ar_cu_context;
581     if (cu_context == NULL) {
582         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
583         return (DW_DLV_ERROR);
584     }
585 
586     if (cu_context->cc_dbg == NULL) {
587         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
588         return (DW_DLV_ERROR);
589     }
590     if (attr->ar_attribute_form == DW_FORM_flag_present) {
591         /* Implicit means we don't read any data at all. Just
592            the existence of the Form does it. DWARF4. */
593         *ret_bool = 1;
594         return (DW_DLV_OK);
595     }
596 
597     if (attr->ar_attribute_form == DW_FORM_flag) {
598         *ret_bool = (*(Dwarf_Small *) attr->ar_debug_info_ptr != 0);
599         return (DW_DLV_OK);
600     }
601     _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD);
602     return (DW_DLV_ERROR);
603 }
604 
605 
606 int
dwarf_formudata(Dwarf_Attribute attr,Dwarf_Unsigned * return_uval,Dwarf_Error * error)607 dwarf_formudata(Dwarf_Attribute attr,
608                 Dwarf_Unsigned * return_uval, Dwarf_Error * error)
609 {
610     Dwarf_Unsigned ret_value = 0;
611     Dwarf_Debug dbg = 0;
612     Dwarf_CU_Context cu_context = 0;
613 
614     if (attr == NULL) {
615         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
616         return (DW_DLV_ERROR);
617     }
618 
619 
620     cu_context = attr->ar_cu_context;
621     if (cu_context == NULL) {
622         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
623         return (DW_DLV_ERROR);
624     }
625 
626     dbg = cu_context->cc_dbg;
627     if (dbg == NULL) {
628         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
629         return (DW_DLV_ERROR);
630     }
631 
632     switch (attr->ar_attribute_form) {
633 
634     case DW_FORM_data1:
635         READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
636                        attr->ar_debug_info_ptr, sizeof(Dwarf_Small));
637         *return_uval = ret_value;
638         return DW_DLV_OK;
639 
640     /* READ_UNALIGNED does the right thing as it reads
641        the right number bits and generates host order.
642        So we can just assign to *return_uval. */
643     case DW_FORM_data2:{
644             READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
645                            attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
646             *return_uval = ret_value;
647             return DW_DLV_OK;
648         }
649 
650     case DW_FORM_data4:{
651             READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
652                            attr->ar_debug_info_ptr,
653                            sizeof(Dwarf_ufixed));
654             *return_uval = ret_value;
655             return DW_DLV_OK;
656         }
657 
658     case DW_FORM_data8:{
659             READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
660                            attr->ar_debug_info_ptr,
661                            sizeof(Dwarf_Unsigned));
662             *return_uval = ret_value;
663             return DW_DLV_OK;
664         }
665         break;
666     case DW_FORM_udata:
667         ret_value =
668             (_dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL));
669         *return_uval = ret_value;
670         return DW_DLV_OK;
671 
672 
673         /* see bug 583450. We do not allow reading sdata from a udata
674            value. Caller can retry, calling sdata */
675 
676 
677     default:
678         break;
679     }
680     _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
681     return (DW_DLV_ERROR);
682 }
683 
684 
685 int
dwarf_formsdata(Dwarf_Attribute attr,Dwarf_Signed * return_sval,Dwarf_Error * error)686 dwarf_formsdata(Dwarf_Attribute attr,
687                 Dwarf_Signed * return_sval, Dwarf_Error * error)
688 {
689     Dwarf_Signed ret_value = 0;
690     Dwarf_Debug dbg = 0;
691     Dwarf_CU_Context cu_context = 0;
692 
693     if (attr == NULL) {
694         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
695         return (DW_DLV_ERROR);
696     }
697 
698     cu_context = attr->ar_cu_context;
699     if (cu_context == NULL) {
700         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
701         return (DW_DLV_ERROR);
702     }
703 
704     dbg = cu_context->cc_dbg;
705     if (dbg == NULL) {
706         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
707         return (DW_DLV_ERROR);
708     }
709 
710     switch (attr->ar_attribute_form) {
711 
712     case DW_FORM_data1:
713         *return_sval = (*(Dwarf_Sbyte *) attr->ar_debug_info_ptr);
714         return DW_DLV_OK;
715 
716     /* READ_UNALIGNED does not sign extend.
717        So we have to use a cast to get the
718        value sign extended in the right way for each case. */
719     case DW_FORM_data2:{
720             READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
721                            attr->ar_debug_info_ptr,
722                            sizeof(Dwarf_Shalf));
723             *return_sval = (Dwarf_Shalf) ret_value;
724             return DW_DLV_OK;
725 
726         }
727 
728     case DW_FORM_data4:{
729             READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
730                            attr->ar_debug_info_ptr,
731                            sizeof(Dwarf_sfixed));
732             *return_sval = (Dwarf_sfixed) ret_value;
733             return DW_DLV_OK;
734         }
735 
736     case DW_FORM_data8:{
737             READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
738                            attr->ar_debug_info_ptr,
739                            sizeof(Dwarf_Signed));
740             *return_sval = (Dwarf_Signed) ret_value;
741             return DW_DLV_OK;
742         }
743 
744     case DW_FORM_sdata:
745         ret_value =
746             (_dwarf_decode_s_leb128(attr->ar_debug_info_ptr, NULL));
747         *return_sval = ret_value;
748         return DW_DLV_OK;
749 
750 
751         /* see bug 583450. We do not allow reading sdata from a udata
752            value. Caller can retry, calling sdata */
753 
754 
755     default:
756         break;
757     }
758     _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
759     return (DW_DLV_ERROR);
760 }
761 
762 
763 int
dwarf_formblock(Dwarf_Attribute attr,Dwarf_Block ** return_block,Dwarf_Error * error)764 dwarf_formblock(Dwarf_Attribute attr,
765                 Dwarf_Block ** return_block, Dwarf_Error * error)
766 {
767     Dwarf_CU_Context cu_context = 0;
768     Dwarf_Debug dbg = 0;
769     Dwarf_Unsigned length = 0;
770     Dwarf_Small *data = 0;
771     Dwarf_Word leb128_length = 0;
772     Dwarf_Block *ret_block = 0;
773 
774     if (attr == NULL) {
775         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
776         return (DW_DLV_ERROR);
777     }
778 
779     cu_context = attr->ar_cu_context;
780     if (cu_context == NULL) {
781         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
782         return (DW_DLV_ERROR);
783     }
784 
785     if (cu_context->cc_dbg == NULL) {
786         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
787         return (DW_DLV_ERROR);
788     }
789     dbg = cu_context->cc_dbg;
790 
791     switch (attr->ar_attribute_form) {
792 
793     case DW_FORM_block1:
794         length = *(Dwarf_Small *) attr->ar_debug_info_ptr;
795         data = attr->ar_debug_info_ptr + sizeof(Dwarf_Small);
796         break;
797 
798     case DW_FORM_block2:
799         READ_UNALIGNED(dbg, length, Dwarf_Unsigned,
800                        attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
801         data = attr->ar_debug_info_ptr + sizeof(Dwarf_Half);
802         break;
803 
804     case DW_FORM_block4:
805         READ_UNALIGNED(dbg, length, Dwarf_Unsigned,
806                        attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
807         data = attr->ar_debug_info_ptr + sizeof(Dwarf_ufixed);
808         break;
809 
810     case DW_FORM_block:
811         length = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr,
812                                         &leb128_length);
813         data = attr->ar_debug_info_ptr + leb128_length;
814         break;
815 
816     default:
817         _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD);
818         return (DW_DLV_ERROR);
819     }
820 
821     /* Check that block lies within current cu in .debug_info. */
822     if (attr->ar_debug_info_ptr + length >=
823         dbg->de_debug_info.dss_data + cu_context->cc_debug_info_offset +
824         cu_context->cc_length + cu_context->cc_length_size +
825         cu_context->cc_extension_size) {
826         _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
827         return (DW_DLV_ERROR);
828     }
829 
830     ret_block = (Dwarf_Block *) _dwarf_get_alloc(dbg, DW_DLA_BLOCK, 1);
831     if (ret_block == NULL) {
832         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
833         return (DW_DLV_ERROR);
834     }
835 
836     ret_block->bl_len = length;
837     ret_block->bl_data = (Dwarf_Ptr) data;
838     ret_block->bl_from_loclist = 0;
839     ret_block->bl_section_offset = data - dbg->de_debug_info.dss_data;
840 
841 
842     *return_block = ret_block;
843     return (DW_DLV_OK);
844 }
845 
846 
847 /* Contrary to long standing documentation,
848    The string pointer returned thru return_str must
849    never have dwarf_dealloc() applied to it.
850    Documentation fixed July 2005.
851 */
852 int
dwarf_formstring(Dwarf_Attribute attr,char ** return_str,Dwarf_Error * error)853 dwarf_formstring(Dwarf_Attribute attr,
854                  char **return_str, Dwarf_Error * error)
855 {
856     Dwarf_CU_Context cu_context = 0;
857     Dwarf_Debug dbg = 0;
858     Dwarf_Unsigned offset = 0;
859     int res = DW_DLV_ERROR;
860 
861     if (attr == NULL) {
862         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
863         return (DW_DLV_ERROR);
864     }
865 
866     cu_context = attr->ar_cu_context;
867     if (cu_context == NULL) {
868         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
869         return (DW_DLV_ERROR);
870     }
871 
872     if (cu_context->cc_dbg == NULL) {
873         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
874         return (DW_DLV_ERROR);
875     }
876     dbg = cu_context->cc_dbg;
877 
878     if (attr->ar_attribute_form == DW_FORM_string) {
879 
880         void *begin = attr->ar_debug_info_ptr;
881 
882         if (0 == dbg->de_assume_string_in_bounds) {
883             /* Check that string lies within current cu in .debug_info.
884              */
885             void *end = dbg->de_debug_info.dss_data +
886                 cu_context->cc_debug_info_offset +
887                 cu_context->cc_length + cu_context->cc_length_size +
888                 cu_context->cc_extension_size;
889             if (0 == _dwarf_string_valid(begin, end)) {
890                 _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
891                 return (DW_DLV_ERROR);
892             }
893         }
894         *return_str = (char *) (begin);
895         return DW_DLV_OK;
896     }
897 
898     if (attr->ar_attribute_form == DW_FORM_strp) {
899         READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
900                        attr->ar_debug_info_ptr,
901                        cu_context->cc_length_size);
902 
903         res = _dwarf_load_section(dbg, &dbg->de_debug_str,error);
904         if (res != DW_DLV_OK) {
905             return res;
906         }
907         if (0 == dbg->de_assume_string_in_bounds) {
908             /* Check that string lies within current cu in .debug_info.
909              */
910             void *end = dbg->de_debug_str.dss_data +
911                 dbg->de_debug_str.dss_size;
912             void*begin = dbg->de_debug_str.dss_data + offset;
913             if (0 == _dwarf_string_valid(begin, end)) {
914                 _dwarf_error(dbg, error, DW_DLE_STRP_OFFSET_BAD);
915                 return (DW_DLV_ERROR);
916             }
917         }
918         *return_str = (char *) (dbg->de_debug_str.dss_data + offset);
919         return DW_DLV_OK;
920     }
921 
922     _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
923     return (DW_DLV_ERROR);
924 }
925 
926 int
dwarf_formexprloc(Dwarf_Attribute attr,Dwarf_Unsigned * return_exprlen,Dwarf_Ptr * block_ptr,Dwarf_Error * error)927 dwarf_formexprloc(Dwarf_Attribute attr,
928     Dwarf_Unsigned * return_exprlen,
929     Dwarf_Ptr  * block_ptr,
930     Dwarf_Error * error)
931 {
932     Dwarf_Debug dbg = 0;
933     Dwarf_CU_Context cu_context = 0;
934 
935     if (attr == NULL) {
936         _dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
937         return (DW_DLV_ERROR);
938     }
939 
940     cu_context = attr->ar_cu_context;
941     if (cu_context == NULL) {
942         _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
943         return (DW_DLV_ERROR);
944     }
945 
946     dbg = cu_context->cc_dbg;
947     if (dbg == NULL) {
948         _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
949         return (DW_DLV_ERROR);
950     }
951 
952     if (attr->ar_attribute_form == DW_FORM_exprloc ) {
953         Dwarf_Unsigned exprlen =
954             (_dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL));
955         Dwarf_Small * addr = attr->ar_debug_info_ptr;
956         *return_exprlen = exprlen;
957         *block_ptr = addr + exprlen;
958         return DW_DLV_OK;
959 
960     }
961     _dwarf_error(dbg, error, DW_DLE_ATTR_EXPRLOC_FORM_BAD);
962     return (DW_DLV_ERROR);
963 }
964