dwarf_pro_attr.c revision 260684
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 49260684Skaiw if (_dwarf_expr_into_block(loc_expr, error) != DW_DLE_NONE) 50260684Skaiw return (DW_DLV_BADADDR); 51260684Skaiw at->u[0].u64 = loc_expr->pe_length; 52260684Skaiw at->u[1].u8p = loc_expr->pe_block; 53260684Skaiw if (loc_expr->pe_length <= UCHAR_MAX) 54260684Skaiw at->at_form = DW_FORM_block1; 55260684Skaiw else if (loc_expr->pe_length <= USHRT_MAX) 56260684Skaiw at->at_form = DW_FORM_block2; 57260684Skaiw else if (loc_expr->pe_length <= UINT_MAX) 58260684Skaiw at->at_form = DW_FORM_block4; 59260684Skaiw else 60260684Skaiw at->at_form = DW_FORM_block; 61260684Skaiw 62260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 63260684Skaiw 64260684Skaiw return (at); 65260684Skaiw} 66260684Skaiw 67260684SkaiwDwarf_P_Attribute 68260684Skaiwdwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error *error) 69260684Skaiw{ 70260684Skaiw Dwarf_Attribute at; 71260684Skaiw 72260684Skaiw if (_dwarf_add_string_attr(die, &at, DW_AT_name, name, error) != 73260684Skaiw DW_DLE_NONE) 74260684Skaiw return (DW_DLV_BADADDR); 75260684Skaiw 76260684Skaiw return (at); 77260684Skaiw} 78260684Skaiw 79260684SkaiwDwarf_P_Attribute 80260684Skaiwdwarf_add_AT_comp_dir(Dwarf_P_Die die, char *dir, Dwarf_Error *error) 81260684Skaiw{ 82260684Skaiw Dwarf_Attribute at; 83260684Skaiw 84260684Skaiw if (_dwarf_add_string_attr(die, &at, DW_AT_comp_dir, dir, error) != 85260684Skaiw DW_DLE_NONE) 86260684Skaiw return (DW_DLV_BADADDR); 87260684Skaiw 88260684Skaiw return (at); 89260684Skaiw} 90260684Skaiw 91260684SkaiwDwarf_P_Attribute 92260684Skaiwdwarf_add_AT_producer(Dwarf_P_Die die, char *producer, Dwarf_Error *error) 93260684Skaiw{ 94260684Skaiw Dwarf_Attribute at; 95260684Skaiw 96260684Skaiw if (_dwarf_add_string_attr(die, &at, DW_AT_producer, producer, error) != 97260684Skaiw DW_DLE_NONE) 98260684Skaiw return (DW_DLV_BADADDR); 99260684Skaiw 100260684Skaiw return (at); 101260684Skaiw} 102260684Skaiw 103260684SkaiwDwarf_P_Attribute 104260684Skaiwdwarf_add_AT_const_value_signedint(Dwarf_P_Die die, Dwarf_Signed value, 105260684Skaiw Dwarf_Error *error) 106260684Skaiw{ 107260684Skaiw Dwarf_Attribute at; 108260684Skaiw Dwarf_Debug dbg; 109260684Skaiw 110260684Skaiw dbg = die != NULL ? die->die_dbg : NULL; 111260684Skaiw 112260684Skaiw if (die == NULL) { 113260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 114260684Skaiw return (DW_DLV_BADADDR); 115260684Skaiw } 116260684Skaiw 117260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 118260684Skaiw return (DW_DLV_BADADDR); 119260684Skaiw 120260684Skaiw at->at_die = die; 121260684Skaiw at->at_attrib = DW_AT_const_value; 122260684Skaiw at->at_form = DW_FORM_sdata; 123260684Skaiw at->u[0].s64 = value; 124260684Skaiw 125260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 126260684Skaiw 127260684Skaiw return (at); 128260684Skaiw} 129260684Skaiw 130260684SkaiwDwarf_P_Attribute 131260684Skaiwdwarf_add_AT_const_value_unsignedint(Dwarf_P_Die die, Dwarf_Unsigned value, 132260684Skaiw Dwarf_Error *error) 133260684Skaiw{ 134260684Skaiw Dwarf_Attribute at; 135260684Skaiw Dwarf_Debug dbg; 136260684Skaiw 137260684Skaiw dbg = die != NULL ? die->die_dbg : NULL; 138260684Skaiw 139260684Skaiw if (die == NULL) { 140260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 141260684Skaiw return (DW_DLV_BADADDR); 142260684Skaiw } 143260684Skaiw 144260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 145260684Skaiw return (DW_DLV_BADADDR); 146260684Skaiw 147260684Skaiw at->at_die = die; 148260684Skaiw at->at_attrib = DW_AT_const_value; 149260684Skaiw at->at_form = DW_FORM_udata; 150260684Skaiw at->u[0].u64 = value; 151260684Skaiw 152260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 153260684Skaiw 154260684Skaiw return (at); 155260684Skaiw} 156260684Skaiw 157260684SkaiwDwarf_P_Attribute 158260684Skaiwdwarf_add_AT_const_value_string(Dwarf_P_Die die, char *string, 159260684Skaiw Dwarf_Error *error) 160260684Skaiw{ 161260684Skaiw Dwarf_Attribute at; 162260684Skaiw 163260684Skaiw if (_dwarf_add_string_attr(die, &at, DW_AT_const_value, string, 164260684Skaiw error) != DW_DLE_NONE) 165260684Skaiw return (DW_DLV_BADADDR); 166260684Skaiw 167260684Skaiw return (at); 168260684Skaiw} 169260684Skaiw 170260684SkaiwDwarf_P_Attribute 171260684Skaiwdwarf_add_AT_targ_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 172260684Skaiw Dwarf_Unsigned pc_value, Dwarf_Signed sym_index, Dwarf_Error *error) 173260684Skaiw{ 174260684Skaiw 175260684Skaiw return (dwarf_add_AT_targ_address_b(dbg, die, attr, pc_value, sym_index, 176260684Skaiw error)); 177260684Skaiw} 178260684Skaiw 179260684SkaiwDwarf_P_Attribute 180260684Skaiwdwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 181260684Skaiw Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) 182260684Skaiw{ 183260684Skaiw Dwarf_Attribute at; 184260684Skaiw 185260684Skaiw if (dbg == NULL || die == NULL) { 186260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 187260684Skaiw return (DW_DLV_BADADDR); 188260684Skaiw } 189260684Skaiw 190260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 191260684Skaiw return (DW_DLV_BADADDR); 192260684Skaiw 193260684Skaiw at->at_die = die; 194260684Skaiw at->at_attrib = attr; 195260684Skaiw at->at_form = DW_FORM_addr; 196260684Skaiw at->at_relsym = sym_index; 197260684Skaiw at->u[0].u64 = pc_value; 198260684Skaiw 199260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 200260684Skaiw 201260684Skaiw return (at); 202260684Skaiw} 203260684Skaiw 204260684SkaiwDwarf_P_Attribute 205260684Skaiwdwarf_add_AT_dataref(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 206260684Skaiw Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) 207260684Skaiw{ 208260684Skaiw Dwarf_Attribute at; 209260684Skaiw int ret; 210260684Skaiw 211260684Skaiw if (dbg == NULL || die == NULL) { 212260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 213260684Skaiw return (DW_DLV_BADADDR); 214260684Skaiw } 215260684Skaiw 216260684Skaiw ret = _dwarf_add_AT_dataref(dbg, die, attr, pc_value, sym_index, 217260684Skaiw NULL, &at, error); 218260684Skaiw if (ret != DW_DLE_NONE) 219260684Skaiw return (DW_DLV_BADADDR); 220260684Skaiw 221260684Skaiw return (at); 222260684Skaiw 223260684Skaiw} 224260684Skaiw 225260684SkaiwDwarf_P_Attribute 226260684Skaiwdwarf_add_AT_ref_address(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 227260684Skaiw Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, Dwarf_Error *error) 228260684Skaiw{ 229260684Skaiw Dwarf_Attribute at; 230260684Skaiw 231260684Skaiw if (dbg == NULL || die == NULL) { 232260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 233260684Skaiw return (DW_DLV_BADADDR); 234260684Skaiw } 235260684Skaiw 236260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 237260684Skaiw return (DW_DLV_BADADDR); 238260684Skaiw 239260684Skaiw at->at_die = die; 240260684Skaiw at->at_attrib = attr; 241260684Skaiw at->at_form = DW_FORM_ref_addr; 242260684Skaiw at->at_relsym = sym_index; 243260684Skaiw at->u[0].u64 = pc_value; 244260684Skaiw 245260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 246260684Skaiw 247260684Skaiw return (at); 248260684Skaiw} 249260684Skaiw 250260684SkaiwDwarf_P_Attribute 251260684Skaiwdwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 252260684Skaiw Dwarf_Unsigned value, Dwarf_Error *error) 253260684Skaiw{ 254260684Skaiw Dwarf_Attribute at; 255260684Skaiw 256260684Skaiw if (dbg == NULL || die == NULL) { 257260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 258260684Skaiw return (DW_DLV_BADADDR); 259260684Skaiw } 260260684Skaiw 261260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 262260684Skaiw return (DW_DLV_BADADDR); 263260684Skaiw 264260684Skaiw at->at_die = die; 265260684Skaiw at->at_attrib = attr; 266260684Skaiw at->u[0].u64 = value; 267260684Skaiw 268260684Skaiw if (value <= UCHAR_MAX) 269260684Skaiw at->at_form = DW_FORM_data1; 270260684Skaiw else if (value <= USHRT_MAX) 271260684Skaiw at->at_form = DW_FORM_data2; 272260684Skaiw else if (value <= UINT_MAX) 273260684Skaiw at->at_form = DW_FORM_data4; 274260684Skaiw else 275260684Skaiw at->at_form = DW_FORM_data8; 276260684Skaiw 277260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 278260684Skaiw 279260684Skaiw return (at); 280260684Skaiw} 281260684Skaiw 282260684SkaiwDwarf_P_Attribute 283260684Skaiwdwarf_add_AT_signed_const(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 284260684Skaiw Dwarf_Signed value, Dwarf_Error *error) 285260684Skaiw{ 286260684Skaiw Dwarf_Attribute at; 287260684Skaiw 288260684Skaiw if (dbg == NULL || die == NULL) { 289260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 290260684Skaiw return (DW_DLV_BADADDR); 291260684Skaiw } 292260684Skaiw 293260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 294260684Skaiw return (DW_DLV_BADADDR); 295260684Skaiw 296260684Skaiw at->at_die = die; 297260684Skaiw at->at_attrib = attr; 298260684Skaiw at->u[0].u64 = value; 299260684Skaiw 300260684Skaiw if (value >= SCHAR_MIN && value <= SCHAR_MAX) 301260684Skaiw at->at_form = DW_FORM_data1; 302260684Skaiw else if (value >= SHRT_MIN && value <= SHRT_MAX) 303260684Skaiw at->at_form = DW_FORM_data2; 304260684Skaiw else if (value >= INT_MIN && value <= INT_MAX) 305260684Skaiw at->at_form = DW_FORM_data4; 306260684Skaiw else 307260684Skaiw at->at_form = DW_FORM_data8; 308260684Skaiw 309260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 310260684Skaiw 311260684Skaiw return (at); 312260684Skaiw} 313260684Skaiw 314260684SkaiwDwarf_P_Attribute 315260684Skaiwdwarf_add_AT_reference(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 316260684Skaiw Dwarf_P_Die ref_die, Dwarf_Error *error) 317260684Skaiw{ 318260684Skaiw Dwarf_Attribute at; 319260684Skaiw 320260684Skaiw if (dbg == NULL || die == NULL) { 321260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 322260684Skaiw return (DW_DLV_BADADDR); 323260684Skaiw } 324260684Skaiw 325260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 326260684Skaiw return (DW_DLV_BADADDR); 327260684Skaiw 328260684Skaiw at->at_die = die; 329260684Skaiw at->at_attrib = attr; 330260684Skaiw if (dbg->dbg_offset_size == 4) 331260684Skaiw at->at_form = DW_FORM_ref4; 332260684Skaiw else 333260684Skaiw at->at_form = DW_FORM_ref8; 334260684Skaiw 335260684Skaiw at->at_refdie = ref_die; 336260684Skaiw 337260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 338260684Skaiw 339260684Skaiw return (at); 340260684Skaiw} 341260684Skaiw 342260684SkaiwDwarf_P_Attribute 343260684Skaiwdwarf_add_AT_flag(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 344260684Skaiw Dwarf_Small flag, Dwarf_Error *error) 345260684Skaiw{ 346260684Skaiw Dwarf_Attribute at; 347260684Skaiw 348260684Skaiw if (dbg == NULL || die == NULL) { 349260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 350260684Skaiw return (DW_DLV_BADADDR); 351260684Skaiw } 352260684Skaiw 353260684Skaiw if (_dwarf_attr_alloc(die, &at, error) != DW_DLE_NONE) 354260684Skaiw return (DW_DLV_BADADDR); 355260684Skaiw 356260684Skaiw at->at_die = die; 357260684Skaiw at->at_attrib = attr; 358260684Skaiw at->at_form = DW_FORM_flag; 359260684Skaiw at->u[0].u64 = flag ? 1 : 0; 360260684Skaiw 361260684Skaiw STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 362260684Skaiw 363260684Skaiw return (at); 364260684Skaiw} 365260684Skaiw 366260684SkaiwDwarf_P_Attribute 367260684Skaiwdwarf_add_AT_string(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 368260684Skaiw char *string, Dwarf_Error *error) 369260684Skaiw{ 370260684Skaiw Dwarf_Attribute at; 371260684Skaiw 372260684Skaiw if (dbg == NULL || die == NULL) { 373260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 374260684Skaiw return (DW_DLV_BADADDR); 375260684Skaiw } 376260684Skaiw 377260684Skaiw /* XXX Add DW_FORM_string style string instead? */ 378260684Skaiw 379260684Skaiw if (_dwarf_add_string_attr(die, &at, attr, string, error) != 380260684Skaiw DW_DLE_NONE) 381260684Skaiw return (DW_DLV_BADADDR); 382260684Skaiw 383260684Skaiw return (at); 384260684Skaiw} 385