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