Home | History | Annotate | Line # | Download | only in libdwarf
dwarf_pro_attr.c revision 1.5
      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
     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
     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
     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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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