1 /*- 2 * Copyright (c) 2009 Kai Wang 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include "_libdwarf.h" 28 29 ELFTC_VCSID("$Id: dwarf_pro_attr.c 2074 2011-10-27 03:34:33Z jkoshy $"); 30 31 Dwarf_P_Attribute 32 dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 33 Dwarf_P_Expr loc_expr, Dwarf_Error *error) 34 { 35 Dwarf_Attribute at; 36 37 if (dbg == NULL || die == NULL || loc_expr == NULL) { 38 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 39 return (DW_DLV_BADADDR); 40 } 41 42 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 43 return (DW_DLV_BADADDR); 44 45 at->at_die = die; 46 at->at_attrib = attr; 47 at->at_expr = loc_expr; 48 49 if (_dwarf_expr_into_block(loc_expr, error) != DW_DLE_NONE) { 50 free(at); 51 return (DW_DLV_BADADDR); 52 } 53 at->u[0].u64 = loc_expr->pe_length; 54 at->u[1].u8p = loc_expr->pe_block; 55 if (loc_expr->pe_length <= UCHAR_MAX) 56 at->at_form = DW_FORM_block1; 57 else if (loc_expr->pe_length <= USHRT_MAX) 58 at->at_form = DW_FORM_block2; 59 else if (loc_expr->pe_length <= UINT_MAX) 60 at->at_form = DW_FORM_block4; 61 else 62 at->at_form = DW_FORM_block; 63 64 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 65 66 return (at); 67 } 68 69 Dwarf_P_Attribute 70 dwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error *error) 71 { 72 Dwarf_Attribute at; 73 74 if (_dwarf_add_string_attr(die, &at, DW_AT_name, name, error) != 75 DW_DLE_NONE) 76 return (DW_DLV_BADADDR); 77 78 return (at); 79 } 80 81 Dwarf_P_Attribute 82 dwarf_add_AT_comp_dir(Dwarf_P_Die die, char *dir, Dwarf_Error *error) 83 { 84 Dwarf_Attribute at; 85 86 if (_dwarf_add_string_attr(die, &at, DW_AT_comp_dir, dir, error) != 87 DW_DLE_NONE) 88 return (DW_DLV_BADADDR); 89 90 return (at); 91 } 92 93 Dwarf_P_Attribute 94 dwarf_add_AT_producer(Dwarf_P_Die die, char *producer, Dwarf_Error *error) 95 { 96 Dwarf_Attribute at; 97 98 if (_dwarf_add_string_attr(die, &at, DW_AT_producer, producer, error) != 99 DW_DLE_NONE) 100 return (DW_DLV_BADADDR); 101 102 return (at); 103 } 104 105 Dwarf_P_Attribute 106 dwarf_add_AT_const_value_signedint(Dwarf_P_Die die, Dwarf_Signed value, 107 Dwarf_Error *error) 108 { 109 Dwarf_Attribute at; 110 Dwarf_Debug dbg; 111 112 dbg = die != NULL ? die->die_dbg : NULL; 113 114 if (die == NULL) { 115 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 116 return (DW_DLV_BADADDR); 117 } 118 119 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 120 return (DW_DLV_BADADDR); 121 122 at->at_die = die; 123 at->at_attrib = DW_AT_const_value; 124 at->at_form = DW_FORM_sdata; 125 at->u[0].s64 = value; 126 127 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 128 129 return (at); 130 } 131 132 Dwarf_P_Attribute 133 dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die die, Dwarf_Unsigned value, 134 Dwarf_Error *error) 135 { 136 Dwarf_Attribute at; 137 Dwarf_Debug dbg; 138 139 dbg = die != NULL ? die->die_dbg : NULL; 140 141 if (die == NULL) { 142 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 143 return (DW_DLV_BADADDR); 144 } 145 146 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 147 return (DW_DLV_BADADDR); 148 149 at->at_die = die; 150 at->at_attrib = DW_AT_const_value; 151 at->at_form = DW_FORM_udata; 152 at->u[0].u64 = value; 153 154 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 155 156 return (at); 157 } 158 159 Dwarf_P_Attribute 160 dwarf_add_AT_const_value_string(Dwarf_P_Die die, char *string, 161 Dwarf_Error *error) 162 { 163 Dwarf_Attribute at; 164 165 if (_dwarf_add_string_attr(die, &at, DW_AT_const_value, string, 166 error) != DW_DLE_NONE) 167 return (DW_DLV_BADADDR); 168 169 return (at); 170 } 171 172 Dwarf_P_Attribute 173 dwarf_add_AT_targ_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 174 Dwarf_Unsigned pc_value, Dwarf_Signed sym_index, Dwarf_Error *error) 175 { 176 177 return (dwarf_add_AT_targ_address_b(dbg, die, attr, pc_value, sym_index, 178 error)); 179 } 180 181 Dwarf_P_Attribute 182 dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 183 Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) 184 { 185 Dwarf_Attribute at; 186 187 if (dbg == NULL || die == NULL) { 188 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 189 return (DW_DLV_BADADDR); 190 } 191 192 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 193 return (DW_DLV_BADADDR); 194 195 at->at_die = die; 196 at->at_attrib = attr; 197 at->at_form = DW_FORM_addr; 198 at->at_relsym = sym_index; 199 at->u[0].u64 = pc_value; 200 201 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 202 203 return (at); 204 } 205 206 Dwarf_P_Attribute 207 dwarf_add_AT_dataref(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 208 Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) 209 { 210 Dwarf_Attribute at; 211 int ret; 212 213 if (dbg == NULL || die == NULL) { 214 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 215 return (DW_DLV_BADADDR); 216 } 217 218 ret = _dwarf_add_AT_dataref(dbg, die, attr, pc_value, sym_index, 219 NULL, &at, error); 220 if (ret != DW_DLE_NONE) 221 return (DW_DLV_BADADDR); 222 223 return (at); 224 225 } 226 227 Dwarf_P_Attribute 228 dwarf_add_AT_ref_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 229 Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) 230 { 231 Dwarf_Attribute at; 232 233 if (dbg == NULL || die == NULL) { 234 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 235 return (DW_DLV_BADADDR); 236 } 237 238 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 239 return (DW_DLV_BADADDR); 240 241 at->at_die = die; 242 at->at_attrib = attr; 243 at->at_form = DW_FORM_ref_addr; 244 at->at_relsym = sym_index; 245 at->u[0].u64 = pc_value; 246 247 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 248 249 return (at); 250 } 251 252 Dwarf_P_Attribute 253 dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 254 Dwarf_Unsigned value, Dwarf_Error *error) 255 { 256 Dwarf_Attribute at; 257 258 if (dbg == NULL || die == NULL) { 259 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 260 return (DW_DLV_BADADDR); 261 } 262 263 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 264 return (DW_DLV_BADADDR); 265 266 at->at_die = die; 267 at->at_attrib = attr; 268 at->u[0].u64 = value; 269 270 if (value <= UCHAR_MAX) 271 at->at_form = DW_FORM_data1; 272 else if (value <= USHRT_MAX) 273 at->at_form = DW_FORM_data2; 274 else if (value <= UINT_MAX) 275 at->at_form = DW_FORM_data4; 276 else 277 at->at_form = DW_FORM_data8; 278 279 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 280 281 return (at); 282 } 283 284 Dwarf_P_Attribute 285 dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 286 Dwarf_Signed value, Dwarf_Error *error) 287 { 288 Dwarf_Attribute at; 289 290 if (dbg == NULL || die == NULL) { 291 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 292 return (DW_DLV_BADADDR); 293 } 294 295 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 296 return (DW_DLV_BADADDR); 297 298 at->at_die = die; 299 at->at_attrib = attr; 300 at->u[0].u64 = value; 301 302 if (value >= SCHAR_MIN && value <= SCHAR_MAX) 303 at->at_form = DW_FORM_data1; 304 else if (value >= SHRT_MIN && value <= SHRT_MAX) 305 at->at_form = DW_FORM_data2; 306 else if (value >= INT_MIN && value <= INT_MAX) 307 at->at_form = DW_FORM_data4; 308 else 309 at->at_form = DW_FORM_data8; 310 311 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 312 313 return (at); 314 } 315 316 Dwarf_P_Attribute 317 dwarf_add_AT_reference(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 318 Dwarf_P_Die ref_die, Dwarf_Error *error) 319 { 320 Dwarf_Attribute at; 321 322 if (dbg == NULL || die == NULL) { 323 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 324 return (DW_DLV_BADADDR); 325 } 326 327 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 328 return (DW_DLV_BADADDR); 329 330 at->at_die = die; 331 at->at_attrib = attr; 332 if (dbg->dbg_offset_size == 4) 333 at->at_form = DW_FORM_ref4; 334 else 335 at->at_form = DW_FORM_ref8; 336 337 at->at_refdie = ref_die; 338 339 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 340 341 return (at); 342 } 343 344 Dwarf_P_Attribute 345 dwarf_add_AT_flag(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 346 Dwarf_Small flag, Dwarf_Error *error) 347 { 348 Dwarf_Attribute at; 349 350 if (dbg == NULL || die == NULL) { 351 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 352 return (DW_DLV_BADADDR); 353 } 354 355 if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 356 return (DW_DLV_BADADDR); 357 358 at->at_die = die; 359 at->at_attrib = attr; 360 at->at_form = DW_FORM_flag; 361 at->u[0].u64 = flag ? 1 : 0; 362 363 STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 364 365 return (at); 366 } 367 368 Dwarf_P_Attribute 369 dwarf_add_AT_string(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 370 char *string, Dwarf_Error *error) 371 { 372 Dwarf_Attribute at; 373 374 if (dbg == NULL || die == NULL) { 375 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 376 return (DW_DLV_BADADDR); 377 } 378 379 /* XXX Add DW_FORM_string style string instead? */ 380 381 if (_dwarf_add_string_attr(die, &at, attr, string, error) != 382 DW_DLE_NONE) 383 return (DW_DLV_BADADDR); 384 385 return (at); 386 } 387