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