4 * Copyright (c) 2007 John Birrell (jb@freebsd.org)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * $FreeBSD: src/lib/libdwarf/dwarf_die.c,v 1.1.4.1 2009/08/03 08:13:06 kensmith Exp $
32 #include "_libdwarf.h"
34 static const char *anon_name
= "__anon__";
37 dwarf_die_add(Dwarf_CU cu
, int level
, uint64_t offset
, uint64_t abnum
, Dwarf_Abbrev a
, Dwarf_Die
*diep
, Dwarf_Error
*err
)
41 int ret
= DWARF_E_NONE
;
46 if (cu
== NULL
|| a
== NULL
) {
47 DWARF_SET_ERROR(err
, DWARF_E_ARGUMENT
);
48 return DWARF_E_ARGUMENT
;
51 if ((die
= malloc(sizeof(struct _Dwarf_Die
))) == NULL
) {
52 DWARF_SET_ERROR(err
, DWARF_E_MEMORY
);
53 return DWARF_E_MEMORY
;
56 /* Initialise the abbrev structure. */
57 die
->die_level
= level
;
58 die
->die_offset
= offset
;
59 die
->die_abnum
= abnum
;
62 die
->die_name
= anon_name
;
64 /* Initialise the list of attribute values. */
65 STAILQ_INIT(&die
->die_attrval
);
67 /* Add the die to the list in the compilation unit. */
68 STAILQ_INSERT_TAIL(&cu
->cu_die
, die
, die_next
);
70 /* Add the die to the hash table in the compilation unit. */
71 key
= offset
% DWARF_DIE_HASH_SIZE
;
72 STAILQ_INSERT_TAIL(&cu
->cu_die_hash
[key
], die
, die_hash
);
81 dwarf_dieoffset(Dwarf_Die die
, Dwarf_Off
*ret_offset
, Dwarf_Error
*err __unused
)
83 *ret_offset
= die
->die_offset
;
89 dwarf_child(Dwarf_Die die
, Dwarf_Die
*ret_die
, Dwarf_Error
*err
)
92 int ret
= DWARF_E_NONE
;
97 if (die
== NULL
|| ret_die
== NULL
) {
98 DWARF_SET_ERROR(err
, DWARF_E_ARGUMENT
);
99 return DWARF_E_ARGUMENT
;
102 if ((next
= STAILQ_NEXT(die
, die_next
)) == NULL
||
103 next
->die_level
!= die
->die_level
+ 1) {
105 DWARF_SET_ERROR(err
, DWARF_E_NO_ENTRY
);
106 ret
= DWARF_E_NO_ENTRY
;
114 dwarf_tag(Dwarf_Die die
, Dwarf_Half
*tag
, Dwarf_Error
*err
)
119 return DWARF_E_ERROR
;
121 if (die
== NULL
|| tag
== NULL
|| (a
= die
->die_a
) == NULL
) {
122 DWARF_SET_ERROR(err
, DWARF_E_ARGUMENT
);
123 return DWARF_E_ARGUMENT
;
132 dwarf_siblingof(Dwarf_Debug dbg
, Dwarf_Die die
, Dwarf_Die
*caller_ret_die
, Dwarf_Error
*err
)
136 int ret
= DWARF_E_NONE
;
139 return DWARF_E_ERROR
;
141 if (dbg
== NULL
|| caller_ret_die
== NULL
) {
142 DWARF_SET_ERROR(err
, DWARF_E_ARGUMENT
);
143 return DWARF_E_ARGUMENT
;
146 if ((cu
= dbg
->dbg_cu_current
) == NULL
) {
147 DWARF_SET_ERROR(err
, DWARF_E_CU_CURRENT
);
148 return DWARF_E_CU_CURRENT
;
152 *caller_ret_die
= STAILQ_FIRST(&cu
->cu_die
);
154 if (*caller_ret_die
== NULL
) {
155 DWARF_SET_ERROR(err
, DWARF_E_NO_ENTRY
);
156 ret
= DWARF_E_NO_ENTRY
;
160 while ((next
= STAILQ_NEXT(next
, die_next
)) != NULL
) {
161 if (next
->die_level
< die
->die_level
) {
165 if (next
->die_level
== die
->die_level
) {
166 *caller_ret_die
= next
;
172 *caller_ret_die
= NULL
;
173 DWARF_SET_ERROR(err
, DWARF_E_NO_ENTRY
);
174 ret
= DWARF_E_NO_ENTRY
;
182 dwarf_die_find(Dwarf_Die die
, Dwarf_Unsigned off
)
184 Dwarf_CU cu
= die
->die_cu
;
187 STAILQ_FOREACH(die1
, &cu
->cu_die
, die_next
) {
188 if (die1
->die_offset
== off
)