xref: /netbsd-src/external/bsd/elftoolchain/dist/libdwarf/dwarf_pro_attr.c (revision 5ac3bc719ce6e70593039505b491894133237d12)
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