]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/elftoolchain/libdwarf/dwarf_attrval.c
Merge apr-1.4.8 -> apr-1.5.1 and update.
[FreeBSD/FreeBSD.git] / contrib / elftoolchain / libdwarf / dwarf_attrval.c
1 /*-
2  * Copyright (c) 2007 John Birrell (jb@freebsd.org)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #include "_libdwarf.h"
28
29 ELFTC_VCSID("$Id: dwarf_attrval.c 2072 2011-10-27 03:26:49Z jkoshy $");
30
31 int
32 dwarf_attrval_flag(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *valp, Dwarf_Error *err)
33 {
34         Dwarf_Attribute at;
35         Dwarf_Debug dbg;
36
37         dbg = die != NULL ? die->die_dbg : NULL;
38
39         if (die == NULL || valp == NULL) {
40                 DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT);
41                 return (DW_DLV_ERROR);
42         }
43
44         *valp = 0;
45
46         if ((at = _dwarf_attr_find(die, attr)) == NULL) {
47                 DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
48                 return (DW_DLV_NO_ENTRY);
49         }
50
51         switch (at->at_form) {
52         case DW_FORM_flag:
53         case DW_FORM_flag_present:
54                 *valp = (Dwarf_Bool) (!!at->u[0].u64);
55                 break;
56         default:
57                 DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
58                 return (DW_DLV_ERROR);
59         }
60
61         return (DW_DLV_OK);
62 }
63
64 int
65 dwarf_attrval_string(Dwarf_Die die, Dwarf_Half attr, const char **strp, Dwarf_Error *err)
66 {
67         Dwarf_Attribute at;
68         Dwarf_Debug dbg;
69
70         dbg = die != NULL ? die->die_dbg : NULL;
71
72         if (die == NULL || strp == NULL) {
73                 DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT);
74                 return (DW_DLV_ERROR);
75         }
76
77         *strp = NULL;
78
79         if ((at = _dwarf_attr_find(die, attr)) == NULL) {
80                 DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
81                 return (DW_DLV_NO_ENTRY);
82         }
83
84         switch (at->at_form) {
85         case DW_FORM_strp:
86                 *strp = at->u[1].s;
87                 break;
88         case DW_FORM_string:
89                 *strp = at->u[0].s;
90                 break;
91         default:
92                 DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
93                 return (DW_DLV_ERROR);
94         }
95
96         return (DW_DLV_OK);
97 }
98
99 int
100 dwarf_attrval_signed(Dwarf_Die die, Dwarf_Half attr, Dwarf_Signed *valp, Dwarf_Error *err)
101 {
102         Dwarf_Attribute at;
103         Dwarf_Debug dbg;
104
105         dbg = die != NULL ? die->die_dbg : NULL;
106
107         if (die == NULL || valp == NULL) {
108                 DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT);
109                 return (DW_DLV_ERROR);
110         }
111
112         *valp = 0;
113
114         if ((at = _dwarf_attr_find(die, attr)) == NULL) {
115                 DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
116                 return (DW_DLV_NO_ENTRY);
117         }
118
119         switch (at->at_form) {
120         case DW_FORM_data1:
121                 *valp = (int8_t) at->u[0].s64;
122                 break;
123         case DW_FORM_data2:
124                 *valp = (int16_t) at->u[0].s64;
125                 break;
126         case DW_FORM_data4:
127                 *valp = (int32_t) at->u[0].s64;
128         case DW_FORM_data8:
129         case DW_FORM_sdata:
130                 *valp = at->u[0].s64;
131                 break;
132         default:
133                 DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
134                 return (DW_DLV_ERROR);
135         }
136
137         return (DW_DLV_OK);
138 }
139
140 int
141 dwarf_attrval_unsigned(Dwarf_Die die, Dwarf_Half attr, Dwarf_Unsigned *valp, Dwarf_Error *err)
142 {
143         Dwarf_Attribute at;
144         Dwarf_Die die1;
145         Dwarf_Unsigned val;
146         Dwarf_Debug dbg;
147
148         dbg = die != NULL ? die->die_dbg : NULL;
149
150         if (die == NULL || valp == NULL) {
151                 DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT);
152                 return (DW_DLV_ERROR);
153         }
154
155         *valp = 0;
156
157         if ((at = _dwarf_attr_find(die, attr)) == NULL && attr != DW_AT_type) {
158                 DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
159                 return (DW_DLV_NO_ENTRY);
160         }
161
162         die1 = NULL;
163         if (at == NULL &&
164             (at = _dwarf_attr_find(die, DW_AT_abstract_origin)) != NULL) {
165                 switch (at->at_form) {
166                 case DW_FORM_ref1:
167                 case DW_FORM_ref2:
168                 case DW_FORM_ref4:
169                 case DW_FORM_ref8:
170                 case DW_FORM_ref_udata:
171                         val = at->u[0].u64;
172                         if ((die1 = _dwarf_die_find(die, val)) == NULL ||
173                             (at = _dwarf_attr_find(die1, attr)) == NULL) {
174                                 if (die1 != NULL)
175                                         dwarf_dealloc(dbg, die1, DW_DLA_DIE);
176                                 DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
177                                 return (DW_DLV_NO_ENTRY);
178                         }
179                         break;
180                 default:
181                         DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
182                         return (DW_DLV_ERROR);
183                 }
184         }
185
186         switch (at->at_form) {
187         case DW_FORM_addr:
188         case DW_FORM_data1:
189         case DW_FORM_data2:
190         case DW_FORM_data4:
191         case DW_FORM_data8:
192         case DW_FORM_udata:
193         case DW_FORM_ref1:
194         case DW_FORM_ref2:
195         case DW_FORM_ref4:
196         case DW_FORM_ref8:
197         case DW_FORM_ref_udata:
198                 *valp = at->u[0].u64;
199                 break;
200         default:
201                 if (die1 != NULL)
202                         dwarf_dealloc(dbg, die1, DW_DLA_DIE);
203                 DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
204                 return (DW_DLV_ERROR);
205         }
206
207         if (die1 != NULL)
208                 dwarf_dealloc(dbg, die1, DW_DLA_DIE);
209
210         return (DW_DLV_OK);
211 }