1260684Skaiw/*- 2260684Skaiw * Copyright (c) 2009 Kai Wang 3260684Skaiw * All rights reserved. 4260684Skaiw * 5260684Skaiw * Redistribution and use in source and binary forms, with or without 6260684Skaiw * modification, are permitted provided that the following conditions 7260684Skaiw * are met: 8260684Skaiw * 1. Redistributions of source code must retain the above copyright 9260684Skaiw * notice, this list of conditions and the following disclaimer. 10260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright 11260684Skaiw * notice, this list of conditions and the following disclaimer in the 12260684Skaiw * documentation and/or other materials provided with the distribution. 13260684Skaiw * 14260684Skaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15260684Skaiw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16260684Skaiw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17260684Skaiw * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18260684Skaiw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19260684Skaiw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20260684Skaiw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21260684Skaiw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22260684Skaiw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23260684Skaiw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24260684Skaiw * SUCH DAMAGE. 25260684Skaiw */ 26260684Skaiw 27260684Skaiw#include "_libdwarf.h" 28260684Skaiw 29260684SkaiwELFTC_VCSID("$Id: dwarf_pro_attr.c 2074 2011-10-27 03:34:33Z jkoshy $"); 30260684Skaiw 31260684SkaiwDwarf_P_Attribute 32260684Skaiwdwarf_add_AT_location_expr(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 33260684Skaiw Dwarf_P_Expr loc_expr, Dwarf_Error *error) 34260684Skaiw{ 35260684Skaiw Dwarf_Attribute at; 36260684Skaiw 37260684Skaiw if (dbg == NULL || die == NULL || loc_expr == NULL) { 38260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 39260684Skaiw return (DW_DLV_BADADDR); 40260684Skaiw } 41260684Skaiw 42260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 43260684Skaiw return (DW_DLV_BADADDR); 44260684Skaiw 45260684Skaiw at->at_die = die; 46260684Skaiw at->at_attrib = attr; 47260684Skaiw at->at_expr = loc_expr; 48260684Skaiw 49367466Sdim if (_dwarf_expr_into_block(loc_expr, error) != DW_DLE_NONE) { 50367466Sdim free(at); 51260684Skaiw return (DW_DLV_BADADDR); 52367466Sdim } 53260684Skaiw at->u[0].u64 = loc_expr->pe_length; 54260684Skaiw at->u[1].u8p = loc_expr->pe_block; 55260684Skaiw if (loc_expr->pe_length <= UCHAR_MAX) 56260684Skaiw at->at_form = DW_FORM_block1; 57260684Skaiw else if (loc_expr->pe_length <= USHRT_MAX) 58260684Skaiw at->at_form = DW_FORM_block2; 59260684Skaiw else if (loc_expr->pe_length <= UINT_MAX) 60260684Skaiw at->at_form = DW_FORM_block4; 61260684Skaiw else 62260684Skaiw at->at_form = DW_FORM_block; 63260684Skaiw 64260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 65260684Skaiw 66260684Skaiw return (at); 67260684Skaiw} 68260684Skaiw 69260684SkaiwDwarf_P_Attribute 70260684Skaiwdwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error *error) 71260684Skaiw{ 72260684Skaiw Dwarf_Attribute at; 73260684Skaiw 74260684Skaiw if (_dwarf_add_string_attr(die, &at, DW_AT_name, name, error) != 75260684Skaiw DW_DLE_NONE) 76260684Skaiw return (DW_DLV_BADADDR); 77260684Skaiw 78260684Skaiw return (at); 79260684Skaiw} 80260684Skaiw 81260684SkaiwDwarf_P_Attribute 82260684Skaiwdwarf_add_AT_comp_dir(Dwarf_P_Die die, char *dir, Dwarf_Error *error) 83260684Skaiw{ 84260684Skaiw Dwarf_Attribute at; 85260684Skaiw 86260684Skaiw if (_dwarf_add_string_attr(die, &at, DW_AT_comp_dir, dir, error) != 87260684Skaiw DW_DLE_NONE) 88260684Skaiw return (DW_DLV_BADADDR); 89260684Skaiw 90260684Skaiw return (at); 91260684Skaiw} 92260684Skaiw 93260684SkaiwDwarf_P_Attribute 94260684Skaiwdwarf_add_AT_producer(Dwarf_P_Die die, char *producer, Dwarf_Error *error) 95260684Skaiw{ 96260684Skaiw Dwarf_Attribute at; 97260684Skaiw 98260684Skaiw if (_dwarf_add_string_attr(die, &at, DW_AT_producer, producer, error) != 99260684Skaiw DW_DLE_NONE) 100260684Skaiw return (DW_DLV_BADADDR); 101260684Skaiw 102260684Skaiw return (at); 103260684Skaiw} 104260684Skaiw 105260684SkaiwDwarf_P_Attribute 106260684Skaiwdwarf_add_AT_const_value_signedint(Dwarf_P_Die die, Dwarf_Signed value, 107260684Skaiw Dwarf_Error *error) 108260684Skaiw{ 109260684Skaiw Dwarf_Attribute at; 110260684Skaiw Dwarf_Debug dbg; 111260684Skaiw 112260684Skaiw dbg = die != NULL ? die->die_dbg : NULL; 113260684Skaiw 114260684Skaiw if (die == NULL) { 115260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 116260684Skaiw return (DW_DLV_BADADDR); 117260684Skaiw } 118260684Skaiw 119260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 120260684Skaiw return (DW_DLV_BADADDR); 121260684Skaiw 122260684Skaiw at->at_die = die; 123260684Skaiw at->at_attrib = DW_AT_const_value; 124260684Skaiw at->at_form = DW_FORM_sdata; 125260684Skaiw at->u[0].s64 = value; 126260684Skaiw 127260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 128260684Skaiw 129260684Skaiw return (at); 130260684Skaiw} 131260684Skaiw 132260684SkaiwDwarf_P_Attribute 133260684Skaiwdwarf_add_AT_const_value_unsignedint(Dwarf_P_Die die, Dwarf_Unsigned value, 134260684Skaiw Dwarf_Error *error) 135260684Skaiw{ 136260684Skaiw Dwarf_Attribute at; 137260684Skaiw Dwarf_Debug dbg; 138260684Skaiw 139260684Skaiw dbg = die != NULL ? die->die_dbg : NULL; 140260684Skaiw 141260684Skaiw if (die == NULL) { 142260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 143260684Skaiw return (DW_DLV_BADADDR); 144260684Skaiw } 145260684Skaiw 146260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 147260684Skaiw return (DW_DLV_BADADDR); 148260684Skaiw 149260684Skaiw at->at_die = die; 150260684Skaiw at->at_attrib = DW_AT_const_value; 151260684Skaiw at->at_form = DW_FORM_udata; 152260684Skaiw at->u[0].u64 = value; 153260684Skaiw 154260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 155260684Skaiw 156260684Skaiw return (at); 157260684Skaiw} 158260684Skaiw 159260684SkaiwDwarf_P_Attribute 160260684Skaiwdwarf_add_AT_const_value_string(Dwarf_P_Die die, char *string, 161260684Skaiw Dwarf_Error *error) 162260684Skaiw{ 163260684Skaiw Dwarf_Attribute at; 164260684Skaiw 165260684Skaiw if (_dwarf_add_string_attr(die, &at, DW_AT_const_value, string, 166260684Skaiw error) != DW_DLE_NONE) 167260684Skaiw return (DW_DLV_BADADDR); 168260684Skaiw 169260684Skaiw return (at); 170260684Skaiw} 171260684Skaiw 172260684SkaiwDwarf_P_Attribute 173260684Skaiwdwarf_add_AT_targ_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 174260684Skaiw Dwarf_Unsigned pc_value, Dwarf_Signed sym_index, Dwarf_Error *error) 175260684Skaiw{ 176260684Skaiw 177260684Skaiw return (dwarf_add_AT_targ_address_b(dbg, die, attr, pc_value, sym_index, 178260684Skaiw error)); 179260684Skaiw} 180260684Skaiw 181260684SkaiwDwarf_P_Attribute 182260684Skaiwdwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 183260684Skaiw Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) 184260684Skaiw{ 185260684Skaiw Dwarf_Attribute at; 186260684Skaiw 187260684Skaiw if (dbg == NULL || die == NULL) { 188260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 189260684Skaiw return (DW_DLV_BADADDR); 190260684Skaiw } 191260684Skaiw 192260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 193260684Skaiw return (DW_DLV_BADADDR); 194260684Skaiw 195260684Skaiw at->at_die = die; 196260684Skaiw at->at_attrib = attr; 197260684Skaiw at->at_form = DW_FORM_addr; 198260684Skaiw at->at_relsym = sym_index; 199260684Skaiw at->u[0].u64 = pc_value; 200260684Skaiw 201260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 202260684Skaiw 203260684Skaiw return (at); 204260684Skaiw} 205260684Skaiw 206260684SkaiwDwarf_P_Attribute 207260684Skaiwdwarf_add_AT_dataref(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 208260684Skaiw Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) 209260684Skaiw{ 210260684Skaiw Dwarf_Attribute at; 211260684Skaiw int ret; 212260684Skaiw 213260684Skaiw if (dbg == NULL || die == NULL) { 214260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 215260684Skaiw return (DW_DLV_BADADDR); 216260684Skaiw } 217260684Skaiw 218260684Skaiw ret = _dwarf_add_AT_dataref(dbg, die, attr, pc_value, sym_index, 219260684Skaiw NULL, &at, error); 220260684Skaiw if (ret != DW_DLE_NONE) 221260684Skaiw return (DW_DLV_BADADDR); 222260684Skaiw 223260684Skaiw return (at); 224260684Skaiw 225260684Skaiw} 226260684Skaiw 227260684SkaiwDwarf_P_Attribute 228260684Skaiwdwarf_add_AT_ref_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 229260684Skaiw Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) 230260684Skaiw{ 231260684Skaiw Dwarf_Attribute at; 232260684Skaiw 233260684Skaiw if (dbg == NULL || die == NULL) { 234260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 235260684Skaiw return (DW_DLV_BADADDR); 236260684Skaiw } 237260684Skaiw 238260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 239260684Skaiw return (DW_DLV_BADADDR); 240260684Skaiw 241260684Skaiw at->at_die = die; 242260684Skaiw at->at_attrib = attr; 243260684Skaiw at->at_form = DW_FORM_ref_addr; 244260684Skaiw at->at_relsym = sym_index; 245260684Skaiw at->u[0].u64 = pc_value; 246260684Skaiw 247260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 248260684Skaiw 249260684Skaiw return (at); 250260684Skaiw} 251260684Skaiw 252260684SkaiwDwarf_P_Attribute 253260684Skaiwdwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 254260684Skaiw Dwarf_Unsigned value, Dwarf_Error *error) 255260684Skaiw{ 256260684Skaiw Dwarf_Attribute at; 257260684Skaiw 258260684Skaiw if (dbg == NULL || die == NULL) { 259260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 260260684Skaiw return (DW_DLV_BADADDR); 261260684Skaiw } 262260684Skaiw 263260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 264260684Skaiw return (DW_DLV_BADADDR); 265260684Skaiw 266260684Skaiw at->at_die = die; 267260684Skaiw at->at_attrib = attr; 268260684Skaiw at->u[0].u64 = value; 269260684Skaiw 270260684Skaiw if (value <= UCHAR_MAX) 271260684Skaiw at->at_form = DW_FORM_data1; 272260684Skaiw else if (value <= USHRT_MAX) 273260684Skaiw at->at_form = DW_FORM_data2; 274260684Skaiw else if (value <= UINT_MAX) 275260684Skaiw at->at_form = DW_FORM_data4; 276260684Skaiw else 277260684Skaiw at->at_form = DW_FORM_data8; 278260684Skaiw 279260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 280260684Skaiw 281260684Skaiw return (at); 282260684Skaiw} 283260684Skaiw 284260684SkaiwDwarf_P_Attribute 285260684Skaiwdwarf_add_AT_signed_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 286260684Skaiw Dwarf_Signed value, Dwarf_Error *error) 287260684Skaiw{ 288260684Skaiw Dwarf_Attribute at; 289260684Skaiw 290260684Skaiw if (dbg == NULL || die == NULL) { 291260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 292260684Skaiw return (DW_DLV_BADADDR); 293260684Skaiw } 294260684Skaiw 295260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 296260684Skaiw return (DW_DLV_BADADDR); 297260684Skaiw 298260684Skaiw at->at_die = die; 299260684Skaiw at->at_attrib = attr; 300260684Skaiw at->u[0].u64 = value; 301260684Skaiw 302260684Skaiw if (value >= SCHAR_MIN && value <= SCHAR_MAX) 303260684Skaiw at->at_form = DW_FORM_data1; 304260684Skaiw else if (value >= SHRT_MIN && value <= SHRT_MAX) 305260684Skaiw at->at_form = DW_FORM_data2; 306260684Skaiw else if (value >= INT_MIN && value <= INT_MAX) 307260684Skaiw at->at_form = DW_FORM_data4; 308260684Skaiw else 309260684Skaiw at->at_form = DW_FORM_data8; 310260684Skaiw 311260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 312260684Skaiw 313260684Skaiw return (at); 314260684Skaiw} 315260684Skaiw 316260684SkaiwDwarf_P_Attribute 317260684Skaiwdwarf_add_AT_reference(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 318260684Skaiw Dwarf_P_Die ref_die, Dwarf_Error *error) 319260684Skaiw{ 320260684Skaiw Dwarf_Attribute at; 321260684Skaiw 322260684Skaiw if (dbg == NULL || die == NULL) { 323260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 324260684Skaiw return (DW_DLV_BADADDR); 325260684Skaiw } 326260684Skaiw 327260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 328260684Skaiw return (DW_DLV_BADADDR); 329260684Skaiw 330260684Skaiw at->at_die = die; 331260684Skaiw at->at_attrib = attr; 332260684Skaiw if (dbg->dbg_offset_size == 4) 333260684Skaiw at->at_form = DW_FORM_ref4; 334260684Skaiw else 335260684Skaiw at->at_form = DW_FORM_ref8; 336260684Skaiw 337260684Skaiw at->at_refdie = ref_die; 338260684Skaiw 339260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 340260684Skaiw 341260684Skaiw return (at); 342260684Skaiw} 343260684Skaiw 344260684SkaiwDwarf_P_Attribute 345260684Skaiwdwarf_add_AT_flag(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 346260684Skaiw Dwarf_Small flag, Dwarf_Error *error) 347260684Skaiw{ 348260684Skaiw Dwarf_Attribute at; 349260684Skaiw 350260684Skaiw if (dbg == NULL || die == NULL) { 351260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 352260684Skaiw return (DW_DLV_BADADDR); 353260684Skaiw } 354260684Skaiw 355260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 356260684Skaiw return (DW_DLV_BADADDR); 357260684Skaiw 358260684Skaiw at->at_die = die; 359260684Skaiw at->at_attrib = attr; 360260684Skaiw at->at_form = DW_FORM_flag; 361260684Skaiw at->u[0].u64 = flag ? 1 : 0; 362260684Skaiw 363260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 364260684Skaiw 365260684Skaiw return (at); 366260684Skaiw} 367260684Skaiw 368260684SkaiwDwarf_P_Attribute 369260684Skaiwdwarf_add_AT_string(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 370260684Skaiw char *string, Dwarf_Error *error) 371260684Skaiw{ 372260684Skaiw Dwarf_Attribute at; 373260684Skaiw 374260684Skaiw if (dbg == NULL || die == NULL) { 375260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 376260684Skaiw return (DW_DLV_BADADDR); 377260684Skaiw } 378260684Skaiw 379260684Skaiw /* XXX Add DW_FORM_string style string instead? */ 380260684Skaiw 381260684Skaiw if (_dwarf_add_string_attr(die, &at, attr, string, error) != 382260684Skaiw DW_DLE_NONE) 383260684Skaiw return (DW_DLV_BADADDR); 384260684Skaiw 385260684Skaiw return (at); 386260684Skaiw} 387