dwarf_pro_attr.c revision 1.1.1.3 1 /* $NetBSD: dwarf_pro_attr.c,v 1.1.1.3 2024/03/03 14:41:48 christos Exp $ */
2
3 /*-
4 * Copyright (c) 2009 Kai Wang
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
15 *
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
26 * SUCH DAMAGE.
27 */
28
29 #include "_libdwarf.h"
30
31 ELFTC_VCSID("Id: dwarf_pro_attr.c 3802 2020-02-07 02:13:19Z emaste");
32
33 Dwarf_P_Attribute
34 dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
35 Dwarf_P_Expr loc_expr, Dwarf_Error *error)
36 {
37 Dwarf_Attribute at;
38
39 if (dbg == NULL || die == NULL || loc_expr == NULL) {
40 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
41 return (DW_DLV_BADADDR);
42 }
43
44 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
45 return (DW_DLV_BADADDR);
46
47 at->at_die = die;
48 at->at_attrib = attr;
49 at->at_expr = loc_expr;
50
51 if (_dwarf_expr_into_block(loc_expr, error) != DW_DLE_NONE) {
52 free(at);
53 return (DW_DLV_BADADDR);
54 }
55 at->u[0].u64 = loc_expr->pe_length;
56 at->u[1].u8p = loc_expr->pe_block;
57 if (loc_expr->pe_length <= UCHAR_MAX)
58 at->at_form = DW_FORM_block1;
59 else if (loc_expr->pe_length <= USHRT_MAX)
60 at->at_form = DW_FORM_block2;
61 else if (loc_expr->pe_length <= UINT_MAX)
62 at->at_form = DW_FORM_block4;
63 else
64 at->at_form = DW_FORM_block;
65
66 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
67
68 return (at);
69 }
70
71 Dwarf_P_Attribute
72 dwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error *error)
73 {
74 Dwarf_Attribute at;
75
76 if (_dwarf_add_string_attr(die, &at, DW_AT_name, name, error) !=
77 DW_DLE_NONE)
78 return (DW_DLV_BADADDR);
79
80 return (at);
81 }
82
83 Dwarf_P_Attribute
84 dwarf_add_AT_comp_dir(Dwarf_P_Die die, char *dir, Dwarf_Error *error)
85 {
86 Dwarf_Attribute at;
87
88 if (_dwarf_add_string_attr(die, &at, DW_AT_comp_dir, dir, error) !=
89 DW_DLE_NONE)
90 return (DW_DLV_BADADDR);
91
92 return (at);
93 }
94
95 Dwarf_P_Attribute
96 dwarf_add_AT_producer(Dwarf_P_Die die, char *producer, Dwarf_Error *error)
97 {
98 Dwarf_Attribute at;
99
100 if (_dwarf_add_string_attr(die, &at, DW_AT_producer, producer, error) !=
101 DW_DLE_NONE)
102 return (DW_DLV_BADADDR);
103
104 return (at);
105 }
106
107 Dwarf_P_Attribute
108 dwarf_add_AT_const_value_signedint(Dwarf_P_Die die, Dwarf_Signed value,
109 Dwarf_Error *error)
110 {
111 Dwarf_Attribute at;
112 Dwarf_Debug dbg;
113
114 dbg = die != NULL ? die->die_dbg : NULL;
115
116 if (die == NULL) {
117 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
118 return (DW_DLV_BADADDR);
119 }
120
121 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
122 return (DW_DLV_BADADDR);
123
124 at->at_die = die;
125 at->at_attrib = DW_AT_const_value;
126 at->at_form = DW_FORM_sdata;
127 at->u[0].s64 = value;
128
129 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
130
131 return (at);
132 }
133
134 Dwarf_P_Attribute
135 dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die die, Dwarf_Unsigned value,
136 Dwarf_Error *error)
137 {
138 Dwarf_Attribute at;
139 Dwarf_Debug dbg;
140
141 dbg = die != NULL ? die->die_dbg : NULL;
142
143 if (die == NULL) {
144 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
145 return (DW_DLV_BADADDR);
146 }
147
148 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
149 return (DW_DLV_BADADDR);
150
151 at->at_die = die;
152 at->at_attrib = DW_AT_const_value;
153 at->at_form = DW_FORM_udata;
154 at->u[0].u64 = value;
155
156 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
157
158 return (at);
159 }
160
161 Dwarf_P_Attribute
162 dwarf_add_AT_const_value_string(Dwarf_P_Die die, char *string,
163 Dwarf_Error *error)
164 {
165 Dwarf_Attribute at;
166
167 if (_dwarf_add_string_attr(die, &at, DW_AT_const_value, string,
168 error) != DW_DLE_NONE)
169 return (DW_DLV_BADADDR);
170
171 return (at);
172 }
173
174 Dwarf_P_Attribute
175 dwarf_add_AT_targ_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
176 Dwarf_Unsigned pc_value, Dwarf_Signed sym_index, Dwarf_Error *error)
177 {
178
179 return (dwarf_add_AT_targ_address_b(dbg, die, attr, pc_value, sym_index,
180 error));
181 }
182
183 Dwarf_P_Attribute
184 dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
185 Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error)
186 {
187 Dwarf_Attribute at;
188
189 if (dbg == NULL || die == NULL) {
190 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
191 return (DW_DLV_BADADDR);
192 }
193
194 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
195 return (DW_DLV_BADADDR);
196
197 at->at_die = die;
198 at->at_attrib = attr;
199 at->at_form = DW_FORM_addr;
200 at->at_relsym = sym_index;
201 at->u[0].u64 = pc_value;
202
203 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
204
205 return (at);
206 }
207
208 Dwarf_P_Attribute
209 dwarf_add_AT_dataref(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
210 Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error)
211 {
212 Dwarf_Attribute at;
213 int ret;
214
215 if (dbg == NULL || die == NULL) {
216 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
217 return (DW_DLV_BADADDR);
218 }
219
220 ret = _dwarf_add_AT_dataref(dbg, die, attr, pc_value, sym_index,
221 NULL, &at, error);
222 if (ret != DW_DLE_NONE)
223 return (DW_DLV_BADADDR);
224
225 return (at);
226
227 }
228
229 Dwarf_P_Attribute
230 dwarf_add_AT_ref_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
231 Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error)
232 {
233 Dwarf_Attribute at;
234
235 if (dbg == NULL || die == NULL) {
236 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
237 return (DW_DLV_BADADDR);
238 }
239
240 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
241 return (DW_DLV_BADADDR);
242
243 at->at_die = die;
244 at->at_attrib = attr;
245 at->at_form = DW_FORM_ref_addr;
246 at->at_relsym = sym_index;
247 at->u[0].u64 = pc_value;
248
249 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
250
251 return (at);
252 }
253
254 Dwarf_P_Attribute
255 dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
256 Dwarf_Unsigned value, Dwarf_Error *error)
257 {
258 Dwarf_Attribute at;
259
260 if (dbg == NULL || die == NULL) {
261 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
262 return (DW_DLV_BADADDR);
263 }
264
265 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
266 return (DW_DLV_BADADDR);
267
268 at->at_die = die;
269 at->at_attrib = attr;
270 at->u[0].u64 = value;
271
272 if (value <= UCHAR_MAX)
273 at->at_form = DW_FORM_data1;
274 else if (value <= USHRT_MAX)
275 at->at_form = DW_FORM_data2;
276 else if (value <= UINT_MAX)
277 at->at_form = DW_FORM_data4;
278 else
279 at->at_form = DW_FORM_data8;
280
281 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
282
283 return (at);
284 }
285
286 Dwarf_P_Attribute
287 dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
288 Dwarf_Signed value, Dwarf_Error *error)
289 {
290 Dwarf_Attribute at;
291
292 if (dbg == NULL || die == NULL) {
293 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
294 return (DW_DLV_BADADDR);
295 }
296
297 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
298 return (DW_DLV_BADADDR);
299
300 at->at_die = die;
301 at->at_attrib = attr;
302 at->u[0].u64 = value;
303
304 if (value >= SCHAR_MIN && value <= SCHAR_MAX)
305 at->at_form = DW_FORM_data1;
306 else if (value >= SHRT_MIN && value <= SHRT_MAX)
307 at->at_form = DW_FORM_data2;
308 else if (value >= INT_MIN && value <= INT_MAX)
309 at->at_form = DW_FORM_data4;
310 else
311 at->at_form = DW_FORM_data8;
312
313 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
314
315 return (at);
316 }
317
318 Dwarf_P_Attribute
319 dwarf_add_AT_reference(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
320 Dwarf_P_Die ref_die, Dwarf_Error *error)
321 {
322 Dwarf_Attribute at;
323
324 if (dbg == NULL || die == NULL) {
325 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
326 return (DW_DLV_BADADDR);
327 }
328
329 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
330 return (DW_DLV_BADADDR);
331
332 at->at_die = die;
333 at->at_attrib = attr;
334 if (dbg->dbg_offset_size == 4)
335 at->at_form = DW_FORM_ref4;
336 else
337 at->at_form = DW_FORM_ref8;
338
339 at->at_refdie = ref_die;
340
341 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
342
343 return (at);
344 }
345
346 Dwarf_P_Attribute
347 dwarf_add_AT_flag(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
348 Dwarf_Small flag, Dwarf_Error *error)
349 {
350 Dwarf_Attribute at;
351
352 if (dbg == NULL || die == NULL) {
353 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
354 return (DW_DLV_BADADDR);
355 }
356
357 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE)
358 return (DW_DLV_BADADDR);
359
360 at->at_die = die;
361 at->at_attrib = attr;
362 at->at_form = DW_FORM_flag;
363 at->u[0].u64 = flag ? 1 : 0;
364
365 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next);
366
367 return (at);
368 }
369
370 Dwarf_P_Attribute
371 dwarf_add_AT_string(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr,
372 char *string, Dwarf_Error *error)
373 {
374 Dwarf_Attribute at;
375
376 if (dbg == NULL || die == NULL) {
377 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
378 return (DW_DLV_BADADDR);
379 }
380
381 /* XXX Add DW_FORM_string style string instead? */
382
383 if (_dwarf_add_string_attr(die, &at, attr, string, error) !=
384 DW_DLE_NONE)
385 return (DW_DLV_BADADDR);
386
387 return (at);
388 }
389