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