3 Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
4 Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of version 2.1 of the GNU Lesser General Public License
8 as published by the Free Software Foundation.
10 This program is distributed in the hope that it would be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 Further, this software is distributed without any warranty that it is
15 free of the rightful claim of any third person regarding infringement
16 or the like. Any license provided herein, whether implied or
17 otherwise, applies only to this software file. Patent licenses, if
18 any, provided herein do not apply to combinations of this program with
19 other software, or any other product whatsoever.
21 You should have received a copy of the GNU Lesser General Public
22 License along with this program; if not, write the Free Software
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
26 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
27 Mountain View, CA 94043, or:
31 For further information regarding this notice, see:
33 http://oss.sgi.com/projects/GenInfo/NoticeExplan
36 /* The address of the Free Software Foundation is
37 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38 Boston, MA 02110-1301, USA.
39 SGI has moved from the Crittenden Lane address.
46 #include "dwarf_incl.h"
51 #include "dwarf_die_deliv.h"
55 For a given Dwarf_Debug dbg, this function checks
56 if a CU that includes the given offset has been read
57 or not. If yes, it returns the Dwarf_CU_Context
58 for the CU. Otherwise it returns NULL. Being an
59 internal routine, it is assumed that a valid dbg
62 **This is a sequential search. May be too slow.
64 If debug_info and debug_abbrev not loaded, this will
65 wind up returning NULL. So no need to load before calling
68 static Dwarf_CU_Context
69 _dwarf_find_CU_Context(Dwarf_Debug dbg
, Dwarf_Off offset
)
71 Dwarf_CU_Context cu_context
= 0;
73 if (offset
>= dbg
->de_info_last_offset
)
76 if (dbg
->de_cu_context
!= NULL
&&
77 dbg
->de_cu_context
->cc_next
!= NULL
&&
78 dbg
->de_cu_context
->cc_next
->cc_debug_info_offset
== offset
) {
80 return (dbg
->de_cu_context
->cc_next
);
83 if (dbg
->de_cu_context
!= NULL
&&
84 dbg
->de_cu_context
->cc_debug_info_offset
<= offset
) {
86 for (cu_context
= dbg
->de_cu_context
;
87 cu_context
!= NULL
; cu_context
= cu_context
->cc_next
) {
89 if (offset
>= cu_context
->cc_debug_info_offset
&&
90 offset
< cu_context
->cc_debug_info_offset
+
91 cu_context
->cc_length
+ cu_context
->cc_length_size
92 + cu_context
->cc_extension_size
) {
99 for (cu_context
= dbg
->de_cu_context_list
;
100 cu_context
!= NULL
; cu_context
= cu_context
->cc_next
) {
102 if (offset
>= cu_context
->cc_debug_info_offset
&&
103 offset
< cu_context
->cc_debug_info_offset
+
104 cu_context
->cc_length
+ cu_context
->cc_length_size
105 + cu_context
->cc_extension_size
) {
116 This routine checks the dwarf_offdie() list of
117 CU contexts for the right CU context.
119 static Dwarf_CU_Context
120 _dwarf_find_offdie_CU_Context(Dwarf_Debug dbg
, Dwarf_Off offset
)
122 Dwarf_CU_Context cu_context
= 0;
124 for (cu_context
= dbg
->de_offdie_cu_context
;
125 cu_context
!= NULL
; cu_context
= cu_context
->cc_next
)
127 if (offset
>= cu_context
->cc_debug_info_offset
&&
128 offset
< cu_context
->cc_debug_info_offset
+
129 cu_context
->cc_length
+ cu_context
->cc_length_size
130 + cu_context
->cc_extension_size
)
139 This function is used to create a CU Context for
140 a compilation-unit that begins at offset in
141 .debug_info. The CU Context is attached to the
142 list of CU Contexts for this dbg. It is assumed
143 that the CU at offset has not been read before,
144 and so do not call this routine before making
145 sure of this with _dwarf_find_CU_Context().
146 Returns NULL on error. As always, being an
147 internal routine, assumes a good dbg.
149 This function must always set a dwarf error code
150 before returning NULL. Always.
152 static Dwarf_CU_Context
153 _dwarf_make_CU_Context(Dwarf_Debug dbg
,
154 Dwarf_Off offset
, Dwarf_Error
* error
)
156 Dwarf_CU_Context cu_context
= 0;
157 Dwarf_Unsigned length
= 0;
158 Dwarf_Signed abbrev_offset
= 0;
159 Dwarf_Byte_Ptr cu_ptr
= 0;
160 int local_extension_size
= 0;
161 int local_length_size
= 0;
164 (Dwarf_CU_Context
) _dwarf_get_alloc(dbg
, DW_DLA_CU_CONTEXT
, 1);
165 if (cu_context
== NULL
) {
166 _dwarf_error(dbg
, error
, DW_DLE_ALLOC_FAIL
);
169 cu_context
->cc_dbg
= dbg
;
171 cu_ptr
= (Dwarf_Byte_Ptr
) (dbg
->de_debug_info
.dss_data
+ offset
);
173 /* READ_AREA_LENGTH updates cu_ptr for consumed bytes */
174 READ_AREA_LENGTH(dbg
, length
, Dwarf_Unsigned
,
175 cu_ptr
, local_length_size
, local_extension_size
);
176 cu_context
->cc_length_size
= local_length_size
;
177 cu_context
->cc_extension_size
= local_extension_size
;
180 cu_context
->cc_length
= (Dwarf_Word
) length
;
182 READ_UNALIGNED(dbg
, cu_context
->cc_version_stamp
, Dwarf_Half
,
183 cu_ptr
, sizeof(Dwarf_Half
));
184 cu_ptr
+= sizeof(Dwarf_Half
);
186 READ_UNALIGNED(dbg
, abbrev_offset
, Dwarf_Signed
,
187 cu_ptr
, local_length_size
);
188 cu_ptr
+= local_length_size
;
189 cu_context
->cc_abbrev_offset
= (Dwarf_Sword
) abbrev_offset
;
191 cu_context
->cc_address_size
= *(Dwarf_Small
*) cu_ptr
;
193 if ((length
< CU_VERSION_STAMP_SIZE
+ local_length_size
+
194 CU_ADDRESS_SIZE_SIZE
) ||
195 (offset
+ length
+ local_length_size
+
196 local_extension_size
> dbg
->de_debug_info
.dss_size
)) {
198 dwarf_dealloc(dbg
, cu_context
, DW_DLA_CU_CONTEXT
);
199 _dwarf_error(dbg
, error
, DW_DLE_CU_LENGTH_ERROR
);
203 if (cu_context
->cc_version_stamp
!= CURRENT_VERSION_STAMP
204 && cu_context
->cc_version_stamp
!= CURRENT_VERSION_STAMP3
205 && cu_context
->cc_version_stamp
!= CURRENT_VERSION_STAMP4
) {
206 dwarf_dealloc(dbg
, cu_context
, DW_DLA_CU_CONTEXT
);
207 _dwarf_error(dbg
, error
, DW_DLE_VERSION_STAMP_ERROR
);
211 if (abbrev_offset
>= dbg
->de_debug_abbrev
.dss_size
) {
212 dwarf_dealloc(dbg
, cu_context
, DW_DLA_CU_CONTEXT
);
213 _dwarf_error(dbg
, error
, DW_DLE_ABBREV_OFFSET_ERROR
);
217 cu_context
->cc_abbrev_hash_table
=
218 (Dwarf_Hash_Table
) _dwarf_get_alloc(dbg
, DW_DLA_HASH_TABLE
, 1);
219 if (cu_context
->cc_abbrev_hash_table
== NULL
) {
220 _dwarf_error(dbg
, error
, DW_DLE_ALLOC_FAIL
);
224 cu_context
->cc_debug_info_offset
= (Dwarf_Word
) offset
;
225 dbg
->de_info_last_offset
=
226 (Dwarf_Word
) (offset
+ length
+
227 local_extension_size
+ local_length_size
);
229 if (dbg
->de_cu_context_list
== NULL
) {
230 dbg
->de_cu_context_list
= cu_context
;
231 dbg
->de_cu_context_list_end
= cu_context
;
233 dbg
->de_cu_context_list_end
->cc_next
= cu_context
;
234 dbg
->de_cu_context_list_end
= cu_context
;
242 Returns offset of next compilation-unit thru next_cu_offset
244 It basically sequentially moves from one
245 cu to the next. The current cu is recorded
246 internally by libdwarf.
248 The _b form is new for DWARF4 adding new returned fields.
251 dwarf_next_cu_header(Dwarf_Debug dbg
,
252 Dwarf_Unsigned
* cu_header_length
,
253 Dwarf_Half
* version_stamp
,
254 Dwarf_Unsigned
* abbrev_offset
,
255 Dwarf_Half
* address_size
,
256 Dwarf_Unsigned
* next_cu_offset
,
259 return dwarf_next_cu_header_b(dbg
,
269 dwarf_next_cu_header_b(Dwarf_Debug dbg
,
270 Dwarf_Unsigned
* cu_header_length
,
271 Dwarf_Half
* version_stamp
,
272 Dwarf_Unsigned
* abbrev_offset
,
273 Dwarf_Half
* address_size
,
274 Dwarf_Half
* offset_size
,
275 Dwarf_Half
* extension_size
,
276 Dwarf_Unsigned
* next_cu_offset
,
279 /* Offset for current and new CU. */
280 Dwarf_Unsigned new_offset
= 0;
282 /* CU Context for current CU. */
283 Dwarf_CU_Context cu_context
= 0;
285 /* ***** BEGIN CODE ***** */
288 _dwarf_error(NULL
, error
, DW_DLE_DBG_NULL
);
289 return (DW_DLV_ERROR
);
292 Get offset into .debug_info of next CU. If dbg has no context,
293 this has to be the first one. */
294 if (dbg
->de_cu_context
== NULL
) {
296 if (!dbg
->de_debug_info
.dss_data
) {
297 int res
= _dwarf_load_debug_info(dbg
, error
);
299 if (res
!= DW_DLV_OK
) {
305 new_offset
= dbg
->de_cu_context
->cc_debug_info_offset
+
306 dbg
->de_cu_context
->cc_length
+
307 dbg
->de_cu_context
->cc_length_size
+
308 dbg
->de_cu_context
->cc_extension_size
;
312 Check that there is room in .debug_info beyond the new offset
313 for at least a new cu header. If not, return 0 to indicate end
314 of debug_info section, and reset de_cu_debug_info_offset to
315 enable looping back through the cu's. */
316 if ((new_offset
+ _dwarf_length_of_cu_header_simple(dbg
)) >=
317 dbg
->de_debug_info
.dss_size
) {
318 dbg
->de_cu_context
= NULL
;
319 return (DW_DLV_NO_ENTRY
);
322 /* Check if this CU has been read before. */
323 cu_context
= _dwarf_find_CU_Context(dbg
, new_offset
);
325 /* If not, make CU Context for it. */
326 if (cu_context
== NULL
) {
327 cu_context
= _dwarf_make_CU_Context(dbg
, new_offset
, error
);
328 if (cu_context
== NULL
) {
329 /* Error if CU Context could not be made. Since
330 _dwarf_make_CU_Context has already registered an error
331 we do not do that here: we let the lower error pass
333 return (DW_DLV_ERROR
);
337 dbg
->de_cu_context
= cu_context
;
339 if (cu_header_length
!= NULL
)
340 *cu_header_length
= cu_context
->cc_length
;
342 if (version_stamp
!= NULL
)
343 *version_stamp
= cu_context
->cc_version_stamp
;
345 if (abbrev_offset
!= NULL
)
346 *abbrev_offset
= cu_context
->cc_abbrev_offset
;
348 if (address_size
!= NULL
)
349 *address_size
= cu_context
->cc_address_size
;
350 if (offset_size
!= NULL
)
351 *offset_size
= cu_context
->cc_length_size
;
352 if (extension_size
!= NULL
)
353 *extension_size
= cu_context
->cc_extension_size
;
355 new_offset
= new_offset
+ cu_context
->cc_length
+
356 cu_context
->cc_length_size
+ cu_context
->cc_extension_size
;
357 *next_cu_offset
= new_offset
;
363 This function does two slightly different things
364 depending on the input flag want_AT_sibling. If
365 this flag is true, it checks if the input die has
366 a DW_AT_sibling attribute. If it does it returns
367 a pointer to the start of the sibling die in the
368 .debug_info section. Otherwise it behaves the
369 same as the want_AT_sibling false case.
371 If the want_AT_sibling flag is false, it returns
372 a pointer to the immediately adjacent die in the
375 Die_info_end points to the end of the .debug_info
376 portion for the cu the die belongs to. It is used
377 to check that the search for the next die does not
378 cross the end of the current cu. Cu_info_start points
379 to the start of the .debug_info portion for the
380 current cu, and is used to add to the offset for
381 DW_AT_sibling attributes. Finally, has_die_child
382 is a pointer to a Dwarf_Bool that is set true if
383 the present die has children, false otherwise.
384 However, in case want_AT_child is true and the die
385 has a DW_AT_sibling attribute *has_die_child is set
386 false to indicate that the children are being skipped.
388 die_info_end points to the last byte+1 of the cu.
391 static Dwarf_Byte_Ptr
392 _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr
,
393 Dwarf_CU_Context cu_context
,
394 Dwarf_Byte_Ptr die_info_end
,
395 Dwarf_Byte_Ptr cu_info_start
,
396 Dwarf_Bool want_AT_sibling
,
397 Dwarf_Bool
* has_die_child
)
399 Dwarf_Byte_Ptr info_ptr
= 0;
400 Dwarf_Byte_Ptr abbrev_ptr
= 0;
401 Dwarf_Word abbrev_code
= 0;
402 Dwarf_Abbrev_List abbrev_list
;
404 Dwarf_Half attr_form
= 0;
405 Dwarf_Unsigned offset
= 0;
406 Dwarf_Word leb128_length
= 0;
407 Dwarf_Unsigned utmp
= 0;
410 info_ptr
= die_info_ptr
;
411 DECODE_LEB128_UWORD(info_ptr
, utmp
);
412 abbrev_code
= (Dwarf_Word
) utmp
;
413 if (abbrev_code
== 0) {
418 abbrev_list
= _dwarf_get_abbrev_for_code(cu_context
, abbrev_code
);
419 if (abbrev_list
== NULL
) {
422 dbg
= cu_context
->cc_dbg
;
424 *has_die_child
= abbrev_list
->ab_has_child
;
426 abbrev_ptr
= abbrev_list
->ab_abbrev_ptr
;
428 Dwarf_Unsigned utmp2
;
430 DECODE_LEB128_UWORD(abbrev_ptr
, utmp2
);
431 attr
= (Dwarf_Half
) utmp2
;
432 DECODE_LEB128_UWORD(abbrev_ptr
, utmp2
);
433 attr_form
= (Dwarf_Half
) utmp2
;
434 if (attr_form
== DW_FORM_indirect
) {
435 Dwarf_Unsigned utmp6
;
437 /* DECODE_LEB128_UWORD updates info_ptr */
438 DECODE_LEB128_UWORD(info_ptr
, utmp6
);
439 attr_form
= (Dwarf_Half
) utmp6
;
443 if (want_AT_sibling
&& attr
== DW_AT_sibling
) {
446 offset
= *(Dwarf_Small
*) info_ptr
;
449 /* READ_UNALIGNED does not update info_ptr */
450 READ_UNALIGNED(dbg
, offset
, Dwarf_Unsigned
,
451 info_ptr
, sizeof(Dwarf_Half
));
454 READ_UNALIGNED(dbg
, offset
, Dwarf_Unsigned
,
455 info_ptr
, sizeof(Dwarf_ufixed
));
458 READ_UNALIGNED(dbg
, offset
, Dwarf_Unsigned
,
459 info_ptr
, sizeof(Dwarf_Unsigned
));
461 case DW_FORM_ref_udata
:
463 _dwarf_decode_u_leb128(info_ptr
, &leb128_length
);
465 case DW_FORM_ref_addr
:
466 /* Very unusual. The FORM is intended to refer to
467 a different CU, but a different CU cannot
468 be a sibling, can it?
469 We could ignore this and treat as if no DW_AT_sibling
470 present. Or derive the offset from it and if
471 it is in the same CU use it directly.
472 The offset here is *supposed* to be a global offset,
473 so adding cu_info_start is wrong to any offset
474 we find here unless cu_info_start
475 is zero! Lets pretend there is no DW_AT_sibling
477 goto no_sibling_attr
;
482 /* Reset *has_die_child to indicate children skipped. */
483 *has_die_child
= false;
485 /* A value beyond die_info_end indicates an error. Exactly
486 at die_info_end means 1-past-cu-end and simply means we
487 are at the end, do not return NULL. Higher level code
488 will detect that we are at the end. */
489 if (cu_info_start
+ offset
> die_info_end
) {
490 /* Error case, bad DWARF. */
493 /* At or before end-of-cu */
494 return (cu_info_start
+ offset
);
498 if (attr_form
!= 0) {
499 info_ptr
+= _dwarf_get_size_of_val(cu_context
->cc_dbg
,
501 cu_context
->cc_address_size
,
503 cu_context
->cc_length_size
);
504 /* It is ok for info_ptr == die_info_end, as we will test
505 later before using a too-large info_ptr */
506 if (info_ptr
> die_info_end
) {
507 /* More than one-past-end indicates a bug somewhere,
508 likely bad dwarf generation. */
512 } while (attr
!= 0 || attr_form
!= 0);
519 Given a Dwarf_Debug dbg, and a Dwarf_Die die, it returns
520 a Dwarf_Die for the sibling of die. In case die is NULL,
521 it returns (thru ptr) a Dwarf_Die for the first die in the current
522 cu in dbg. Returns DW_DLV_ERROR on error.
524 It is assumed that every sibling chain including those with
525 only one element is terminated with a NULL die, except a
526 chain with only a NULL die.
528 The algorithm moves from one die to the adjacent one. It
529 returns when the depth of children it sees equals the number
530 of sibling chain terminations. A single count, child_depth
531 is used to track the depth of children and sibling terminations
532 encountered. Child_depth is incremented when a die has the
533 Has-Child flag set unless the child happens to be a NULL die.
534 Child_depth is decremented when a die has Has-Child false,
535 and the adjacent die is NULL. Algorithm returns when
538 **NOTE: Do not modify input die, since it is used at the end.
541 dwarf_siblingof(Dwarf_Debug dbg
,
543 Dwarf_Die
* caller_ret_die
, Dwarf_Error
* error
)
545 Dwarf_Die ret_die
= 0;
546 Dwarf_Byte_Ptr die_info_ptr
= 0;
547 Dwarf_Byte_Ptr cu_info_start
= 0;
549 /* die_info_end points 1-past end of die (once set) */
550 Dwarf_Byte_Ptr die_info_end
= 0;
551 Dwarf_Word abbrev_code
= 0;
552 Dwarf_Unsigned utmp
= 0;
556 _dwarf_error(NULL
, error
, DW_DLE_DBG_NULL
);
557 return (DW_DLV_ERROR
);
561 /* Find root die of cu */
562 /* die_info_end is untouched here, need not be set in this
566 /* If we've not loaded debug_info, de_cu_context will be NULL,
567 so no need to laod */
569 if (dbg
->de_cu_context
== NULL
) {
570 _dwarf_error(dbg
, error
, DW_DLE_DBG_NO_CU_CONTEXT
);
571 return (DW_DLV_ERROR
);
574 off2
= dbg
->de_cu_context
->cc_debug_info_offset
;
575 die_info_ptr
= dbg
->de_debug_info
.dss_data
+
576 off2
+ _dwarf_length_of_cu_header(dbg
, off2
);
578 /* Find sibling die. */
579 Dwarf_Bool has_child
= false;
580 Dwarf_Sword child_depth
= 0;
582 /* We cannot have a legal die unless debug_info was loaded, so
583 no need to load debug_info here. */
584 CHECK_DIE(die
, DW_DLV_ERROR
);
586 die_info_ptr
= die
->di_debug_info_ptr
;
587 if (*die_info_ptr
== 0) {
588 return (DW_DLV_NO_ENTRY
);
590 cu_info_start
= dbg
->de_debug_info
.dss_data
+
591 die
->di_cu_context
->cc_debug_info_offset
;
592 die_info_end
= cu_info_start
+ die
->di_cu_context
->cc_length
+
593 die
->di_cu_context
->cc_length_size
+
594 die
->di_cu_context
->cc_extension_size
;
596 if ((*die_info_ptr
) == 0) {
597 return (DW_DLV_NO_ENTRY
);
601 die_info_ptr
= _dwarf_next_die_info_ptr(die_info_ptr
,
606 if (die_info_ptr
== NULL
) {
607 _dwarf_error(dbg
, error
, DW_DLE_NEXT_DIE_PTR_NULL
);
608 return (DW_DLV_ERROR
);
611 /* die_info_end is one past end. Do not read it!
612 A test for ``!= die_info_end'' would work as well,
613 but perhaps < reads more like the meaning. */
614 if(die_info_ptr
< die_info_end
) {
615 if ((*die_info_ptr
) == 0 && has_child
) {
621 /* die_info_ptr can be one-past-end. */
622 if ((die_info_ptr
== die_info_end
) ||
623 ((*die_info_ptr
) == 0)) {
624 for (; child_depth
> 0 && *die_info_ptr
== 0;
625 child_depth
--, die_info_ptr
++);
627 child_depth
= has_child
? child_depth
+ 1 : child_depth
;
630 } while (child_depth
!= 0);
633 /* die_info_ptr > die_info_end is really a bug (possibly in dwarf
634 generation)(but we are past end, no more DIEs here), whereas
635 die_info_ptr == die_info_end means 'one past end, no more DIEs
637 if (die
!= NULL
&& die_info_ptr
>= die_info_end
) {
638 return (DW_DLV_NO_ENTRY
);
641 if ((*die_info_ptr
) == 0) {
642 return (DW_DLV_NO_ENTRY
);
645 ret_die
= (Dwarf_Die
) _dwarf_get_alloc(dbg
, DW_DLA_DIE
, 1);
646 if (ret_die
== NULL
) {
647 _dwarf_error(dbg
, error
, DW_DLE_ALLOC_FAIL
);
648 return (DW_DLV_ERROR
);
651 ret_die
->di_debug_info_ptr
= die_info_ptr
;
652 ret_die
->di_cu_context
=
653 die
== NULL
? dbg
->de_cu_context
: die
->di_cu_context
;
655 DECODE_LEB128_UWORD(die_info_ptr
, utmp
);
656 abbrev_code
= (Dwarf_Word
) utmp
;
657 if (abbrev_code
== 0) {
658 /* Zero means a null DIE */
659 dwarf_dealloc(dbg
, ret_die
, DW_DLA_DIE
);
660 return (DW_DLV_NO_ENTRY
);
662 ret_die
->di_abbrev_code
= abbrev_code
;
663 ret_die
->di_abbrev_list
=
664 _dwarf_get_abbrev_for_code(ret_die
->di_cu_context
, abbrev_code
);
665 if (ret_die
->di_abbrev_list
== NULL
|| (die
== NULL
&&
666 ret_die
->di_abbrev_list
->
668 DW_TAG_compile_unit
)) {
669 dwarf_dealloc(dbg
, ret_die
, DW_DLA_DIE
);
670 _dwarf_error(dbg
, error
, DW_DLE_FIRST_DIE_NOT_CU
);
671 return (DW_DLV_ERROR
);
674 *caller_ret_die
= ret_die
;
680 dwarf_child(Dwarf_Die die
,
681 Dwarf_Die
* caller_ret_die
, Dwarf_Error
* error
)
683 Dwarf_Byte_Ptr die_info_ptr
= 0;
685 /* die_info_end points one-past-end of die area. */
686 Dwarf_Byte_Ptr die_info_end
= 0;
687 Dwarf_Die ret_die
= 0;
688 Dwarf_Bool has_die_child
= 0;
690 Dwarf_Word abbrev_code
= 0;
691 Dwarf_Unsigned utmp
= 0;
694 CHECK_DIE(die
, DW_DLV_ERROR
);
695 dbg
= die
->di_cu_context
->cc_dbg
;
696 die_info_ptr
= die
->di_debug_info_ptr
;
698 /* NULL die has no child. */
699 if ((*die_info_ptr
) == 0)
700 return (DW_DLV_NO_ENTRY
);
702 die_info_end
= dbg
->de_debug_info
.dss_data
+
703 die
->di_cu_context
->cc_debug_info_offset
+
704 die
->di_cu_context
->cc_length
+
705 die
->di_cu_context
->cc_length_size
+
706 die
->di_cu_context
->cc_extension_size
;
709 _dwarf_next_die_info_ptr(die_info_ptr
, die
->di_cu_context
,
710 die_info_end
, NULL
, false,
712 if (die_info_ptr
== NULL
) {
713 _dwarf_error(dbg
, error
, DW_DLE_NEXT_DIE_PTR_NULL
);
714 return (DW_DLV_ERROR
);
718 return (DW_DLV_NO_ENTRY
);
720 ret_die
= (Dwarf_Die
) _dwarf_get_alloc(dbg
, DW_DLA_DIE
, 1);
721 if (ret_die
== NULL
) {
722 _dwarf_error(dbg
, error
, DW_DLE_ALLOC_FAIL
);
723 return (DW_DLV_ERROR
);
725 ret_die
->di_debug_info_ptr
= die_info_ptr
;
726 ret_die
->di_cu_context
= die
->di_cu_context
;
728 DECODE_LEB128_UWORD(die_info_ptr
, utmp
);
729 abbrev_code
= (Dwarf_Word
) utmp
;
730 if (abbrev_code
== 0) {
731 /* We have arrived at a null DIE, at the end of a CU or the end
732 of a list of siblings. */
734 dwarf_dealloc(dbg
, ret_die
, DW_DLA_DIE
);
735 return DW_DLV_NO_ENTRY
;
737 ret_die
->di_abbrev_code
= abbrev_code
;
738 ret_die
->di_abbrev_list
=
739 _dwarf_get_abbrev_for_code(die
->di_cu_context
, abbrev_code
);
740 if (ret_die
->di_abbrev_list
== NULL
) {
741 dwarf_dealloc(dbg
, ret_die
, DW_DLA_DIE
);
742 _dwarf_error(dbg
, error
, DW_DLE_DIE_BAD
);
743 return (DW_DLV_ERROR
);
746 *caller_ret_die
= ret_die
;
751 Given a (global, not cu_relative) die offset, this returns
752 a pointer to a DIE thru *new_die.
753 It is up to the caller to do a
754 dwarf_dealloc(dbg,*new_die,DW_DLE_DIE);
757 dwarf_offdie(Dwarf_Debug dbg
,
758 Dwarf_Off offset
, Dwarf_Die
* new_die
, Dwarf_Error
* error
)
760 Dwarf_CU_Context cu_context
= 0;
761 Dwarf_Off new_cu_offset
= 0;
763 Dwarf_Byte_Ptr info_ptr
= 0;
764 Dwarf_Unsigned abbrev_code
= 0;
765 Dwarf_Unsigned utmp
= 0;
768 _dwarf_error(NULL
, error
, DW_DLE_DBG_NULL
);
769 return (DW_DLV_ERROR
);
772 cu_context
= _dwarf_find_CU_Context(dbg
, offset
);
773 if (cu_context
== NULL
)
774 cu_context
= _dwarf_find_offdie_CU_Context(dbg
, offset
);
776 if (cu_context
== NULL
) {
777 int res
= _dwarf_load_debug_info(dbg
, error
);
779 if (res
!= DW_DLV_OK
) {
783 if (dbg
->de_offdie_cu_context_end
!= NULL
) {
784 Dwarf_CU_Context lcu_context
=
785 dbg
->de_offdie_cu_context_end
;
787 lcu_context
->cc_debug_info_offset
+
788 lcu_context
->cc_length
+
789 lcu_context
->cc_length_size
+
790 lcu_context
->cc_extension_size
;
796 _dwarf_length_of_cu_header_simple(dbg
)) >=
797 dbg
->de_debug_info
.dss_size
) {
798 _dwarf_error(dbg
, error
, DW_DLE_OFFSET_BAD
);
799 return (DW_DLV_ERROR
);
803 _dwarf_make_CU_Context(dbg
, new_cu_offset
, error
);
804 if (cu_context
== NULL
) {
805 /* Error if CU Context could not be made. Since
806 _dwarf_make_CU_Context has already registered an
807 error we do not do that here: we let the lower error
810 return (DW_DLV_ERROR
);
813 if (dbg
->de_offdie_cu_context
== NULL
) {
814 dbg
->de_offdie_cu_context
= cu_context
;
815 dbg
->de_offdie_cu_context_end
= cu_context
;
817 dbg
->de_offdie_cu_context_end
->cc_next
= cu_context
;
818 dbg
->de_offdie_cu_context_end
= cu_context
;
821 new_cu_offset
= new_cu_offset
+ cu_context
->cc_length
+
822 cu_context
->cc_length_size
;
824 } while (offset
>= new_cu_offset
);
827 die
= (Dwarf_Die
) _dwarf_get_alloc(dbg
, DW_DLA_DIE
, 1);
829 _dwarf_error(dbg
, error
, DW_DLE_ALLOC_FAIL
);
830 return (DW_DLV_ERROR
);
832 die
->di_cu_context
= cu_context
;
834 info_ptr
= dbg
->de_debug_info
.dss_data
+ offset
;
835 die
->di_debug_info_ptr
= info_ptr
;
836 DECODE_LEB128_UWORD(info_ptr
, utmp
);
838 if (abbrev_code
== 0) {
839 /* we are at a null DIE (or there is a bug). */
841 dwarf_dealloc(dbg
, die
, DW_DLA_DIE
);
842 return DW_DLV_NO_ENTRY
;
844 die
->di_abbrev_code
= abbrev_code
;
845 die
->di_abbrev_list
=
846 _dwarf_get_abbrev_for_code(cu_context
, abbrev_code
);
847 if (die
->di_abbrev_list
== NULL
) {
848 dwarf_dealloc(dbg
, die
, DW_DLA_DIE
);
849 _dwarf_error(dbg
, error
, DW_DLE_DIE_ABBREV_LIST_NULL
);
850 return (DW_DLV_ERROR
);