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