1 /* $NetBSD: dwarf_pro_attr.c,v 1.2 2014/03/09 16:58:04 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.2 2014/03/09 16:58:04 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