]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/elftoolchain/libdwarf/dwarf_attrval.c
MFC r317075: Update ELF Tool Chain to upstream r3520
[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 3509 2016-12-29 03:58:41Z emaste $");
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                 break;
129         case DW_FORM_data8:
130         case DW_FORM_sdata:
131                 *valp = at->u[0].s64;
132                 break;
133         default:
134                 DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
135                 return (DW_DLV_ERROR);
136         }
137
138         return (DW_DLV_OK);
139 }
140
141 int
142 dwarf_attrval_unsigned(Dwarf_Die die, Dwarf_Half attr, Dwarf_Unsigned *valp, Dwarf_Error *err)
143 {
144         Dwarf_Attribute at;
145         Dwarf_Die die1;
146         Dwarf_Unsigned val;
147         Dwarf_Debug dbg;
148         int first;
149
150         dbg = die != NULL ? die->die_dbg : NULL;
151
152         if (die == NULL || valp == NULL) {
153                 DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT);
154                 return (DW_DLV_ERROR);
155         }
156
157         *valp = 0;
158
159         die1 = NULL;
160         for (;;) {
161                 if ((at = _dwarf_attr_find(die, attr)) != NULL ||
162                     attr != DW_AT_type)
163                         break;
164                 if ((at = _dwarf_attr_find(die, DW_AT_abstract_origin)) ==
165                     NULL &&
166                     (at = _dwarf_attr_find(die, DW_AT_specification)) == NULL)
167                         break;
168
169                 switch (at->at_form) {
170                 case DW_FORM_ref1:
171                 case DW_FORM_ref2:
172                 case DW_FORM_ref4:
173                 case DW_FORM_ref8:
174                 case DW_FORM_ref_udata:
175                         val = at->u[0].u64;
176                         first = (die1 == NULL);
177                         die1 = _dwarf_die_find(die, val);
178                         if (!first)
179                                 dwarf_dealloc(dbg, die, DW_DLA_DIE);
180                         if (die1 == NULL) {
181                                 DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
182                                 return (DW_DLV_NO_ENTRY);
183                         }
184                         die = die1;
185                         break;
186                 default:
187                         DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
188                         return (DW_DLV_ERROR);
189                 }
190         }
191
192         if (at == NULL) {
193                 DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY);
194                 return (DW_DLV_NO_ENTRY);
195         }
196
197         switch (at->at_form) {
198         case DW_FORM_addr:
199         case DW_FORM_data1:
200         case DW_FORM_data2:
201         case DW_FORM_data4:
202         case DW_FORM_data8:
203         case DW_FORM_udata:
204         case DW_FORM_ref1:
205         case DW_FORM_ref2:
206         case DW_FORM_ref4:
207         case DW_FORM_ref8:
208         case DW_FORM_ref_udata:
209                 *valp = at->u[0].u64;
210                 break;
211         default:
212                 if (die1 != NULL)
213                         dwarf_dealloc(dbg, die1, DW_DLA_DIE);
214                 DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD);
215                 return (DW_DLV_ERROR);
216         }
217
218         if (die1 != NULL)
219                 dwarf_dealloc(dbg, die1, DW_DLA_DIE);
220
221         return (DW_DLV_OK);
222 }