dwarf_attrval.c revision 260684
1246145Shselasky/*- 2246145Shselasky * Copyright (c) 2007 John Birrell (jb@freebsd.org) 3246145Shselasky * All rights reserved. 4246145Shselasky * 5246145Shselasky * Redistribution and use in source and binary forms, with or without 6246145Shselasky * modification, are permitted provided that the following conditions 7246145Shselasky * are met: 8246145Shselasky * 1. Redistributions of source code must retain the above copyright 9246145Shselasky * notice, this list of conditions and the following disclaimer. 10246145Shselasky * 2. Redistributions in binary form must reproduce the above copyright 11246145Shselasky * notice, this list of conditions and the following disclaimer in the 12246145Shselasky * documentation and/or other materials provided with the distribution. 13246145Shselasky * 14246145Shselasky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15246145Shselasky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16246145Shselasky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17246145Shselasky * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18246145Shselasky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19246145Shselasky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20246145Shselasky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21246145Shselasky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22246145Shselasky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23246145Shselasky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24246145Shselasky * SUCH DAMAGE. 25246145Shselasky */ 26246145Shselasky 27246145Shselasky#include "_libdwarf.h" 28246145Shselasky 29246145ShselaskyELFTC_VCSID("$Id: dwarf_attrval.c 2072 2011-10-27 03:26:49Z jkoshy $"); 30246145Shselasky 31246145Shselaskyint 32246145Shselaskydwarf_attrval_flag(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *valp, Dwarf_Error *err) 33246145Shselasky{ 34246145Shselasky Dwarf_Attribute at; 35246145Shselasky Dwarf_Debug dbg; 36246145Shselasky 37246145Shselasky dbg = die != NULL ? die->die_dbg : NULL; 38246145Shselasky 39246145Shselasky if (die == NULL || valp == NULL) { 40246145Shselasky DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); 41246145Shselasky return (DW_DLV_ERROR); 42246145Shselasky } 43246145Shselasky 44246145Shselasky *valp = 0; 45246145Shselasky 46246145Shselasky if ((at = _dwarf_attr_find(die, attr)) == NULL) { 47246145Shselasky DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); 48246145Shselasky return (DW_DLV_NO_ENTRY); 49246145Shselasky } 50246145Shselasky 51246145Shselasky switch (at->at_form) { 52246145Shselasky case DW_FORM_flag: 53246145Shselasky *valp = (Dwarf_Bool) (!!at->u[0].u64); 54246145Shselasky break; 55246145Shselasky default: 56246145Shselasky DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); 57246145Shselasky return (DW_DLV_ERROR); 58246145Shselasky } 59246145Shselasky 60246145Shselasky return (DW_DLV_OK); 61246145Shselasky} 62246145Shselasky 63246145Shselaskyint 64246145Shselaskydwarf_attrval_string(Dwarf_Die die, Dwarf_Half attr, const char **strp, Dwarf_Error *err) 65246145Shselasky{ 66246145Shselasky Dwarf_Attribute at; 67246145Shselasky Dwarf_Debug dbg; 68246145Shselasky 69246145Shselasky dbg = die != NULL ? die->die_dbg : NULL; 70246145Shselasky 71246145Shselasky if (die == NULL || strp == NULL) { 72246145Shselasky DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); 73246145Shselasky return (DW_DLV_ERROR); 74246145Shselasky } 75246145Shselasky 76246145Shselasky *strp = NULL; 77246145Shselasky 78246145Shselasky if ((at = _dwarf_attr_find(die, attr)) == NULL) { 79246145Shselasky DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); 80246145Shselasky return (DW_DLV_NO_ENTRY); 81246145Shselasky } 82246145Shselasky 83246145Shselasky switch (at->at_form) { 84246145Shselasky case DW_FORM_strp: 85246145Shselasky *strp = at->u[1].s; 86246145Shselasky break; 87246145Shselasky case DW_FORM_string: 88246145Shselasky *strp = at->u[0].s; 89246145Shselasky break; 90246145Shselasky default: 91246145Shselasky DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); 92246145Shselasky return (DW_DLV_ERROR); 93246145Shselasky } 94246145Shselasky 95246145Shselasky return (DW_DLV_OK); 96246145Shselasky} 97246145Shselasky 98246145Shselaskyint 99246145Shselaskydwarf_attrval_signed(Dwarf_Die die, Dwarf_Half attr, Dwarf_Signed *valp, Dwarf_Error *err) 100246145Shselasky{ 101246145Shselasky Dwarf_Attribute at; 102246145Shselasky Dwarf_Debug dbg; 103246145Shselasky 104246145Shselasky dbg = die != NULL ? die->die_dbg : NULL; 105246145Shselasky 106246145Shselasky if (die == NULL || valp == NULL) { 107246145Shselasky DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); 108246145Shselasky return (DW_DLV_ERROR); 109246145Shselasky } 110246145Shselasky 111246145Shselasky *valp = 0; 112246145Shselasky 113246145Shselasky if ((at = _dwarf_attr_find(die, attr)) == NULL) { 114246145Shselasky DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); 115246145Shselasky return (DW_DLV_NO_ENTRY); 116246145Shselasky } 117246145Shselasky 118246145Shselasky switch (at->at_form) { 119246145Shselasky case DW_FORM_data1: 120246145Shselasky *valp = (int8_t) at->u[0].s64; 121246145Shselasky break; 122246145Shselasky case DW_FORM_data2: 123246145Shselasky *valp = (int16_t) at->u[0].s64; 124246145Shselasky break; 125246145Shselasky case DW_FORM_data4: 126246145Shselasky *valp = (int32_t) at->u[0].s64; 127246145Shselasky case DW_FORM_data8: 128246145Shselasky case DW_FORM_sdata: 129246145Shselasky *valp = at->u[0].s64; 130246145Shselasky break; 131246145Shselasky default: 132246145Shselasky DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); 133246145Shselasky return (DW_DLV_ERROR); 134246145Shselasky } 135246145Shselasky 136246145Shselasky return (DW_DLV_OK); 137246145Shselasky} 138246145Shselasky 139246145Shselaskyint 140246145Shselaskydwarf_attrval_unsigned(Dwarf_Die die, Dwarf_Half attr, Dwarf_Unsigned *valp, Dwarf_Error *err) 141246145Shselasky{ 142246145Shselasky Dwarf_Attribute at; 143246145Shselasky Dwarf_Die die1; 144246145Shselasky Dwarf_Unsigned val; 145246145Shselasky Dwarf_Debug dbg; 146246145Shselasky 147246145Shselasky dbg = die != NULL ? die->die_dbg : NULL; 148246145Shselasky 149246145Shselasky if (die == NULL || valp == NULL) { 150246145Shselasky DWARF_SET_ERROR(dbg, err, DW_DLE_ARGUMENT); 151246145Shselasky return (DW_DLV_ERROR); 152246145Shselasky } 153246145Shselasky 154246145Shselasky *valp = 0; 155246145Shselasky 156246145Shselasky if ((at = _dwarf_attr_find(die, attr)) == NULL && attr != DW_AT_type) { 157246145Shselasky DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); 158246145Shselasky return (DW_DLV_NO_ENTRY); 159246145Shselasky } 160246145Shselasky 161246145Shselasky die1 = NULL; 162246145Shselasky if (at == NULL && 163246145Shselasky (at = _dwarf_attr_find(die, DW_AT_abstract_origin)) != NULL) { 164246145Shselasky switch (at->at_form) { 165246145Shselasky case DW_FORM_ref1: 166246145Shselasky case DW_FORM_ref2: 167246145Shselasky case DW_FORM_ref4: 168246145Shselasky case DW_FORM_ref8: 169246145Shselasky case DW_FORM_ref_udata: 170246145Shselasky val = at->u[0].u64; 171246145Shselasky if ((die1 = _dwarf_die_find(die, val)) == NULL || 172246145Shselasky (at = _dwarf_attr_find(die1, attr)) == NULL) { 173246145Shselasky if (die1 != NULL) 174246145Shselasky dwarf_dealloc(dbg, die1, DW_DLA_DIE); 175246145Shselasky DWARF_SET_ERROR(dbg, err, DW_DLE_NO_ENTRY); 176246145Shselasky return (DW_DLV_NO_ENTRY); 177246145Shselasky } 178246145Shselasky break; 179246145Shselasky default: 180246145Shselasky DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); 181246145Shselasky return (DW_DLV_ERROR); 182246145Shselasky } 183246145Shselasky } 184246145Shselasky 185246145Shselasky switch (at->at_form) { 186246145Shselasky case DW_FORM_addr: 187246145Shselasky case DW_FORM_data1: 188246145Shselasky case DW_FORM_data2: 189246145Shselasky case DW_FORM_data4: 190246145Shselasky case DW_FORM_data8: 191246145Shselasky case DW_FORM_udata: 192246145Shselasky case DW_FORM_ref1: 193246145Shselasky case DW_FORM_ref2: 194246145Shselasky case DW_FORM_ref4: 195246145Shselasky case DW_FORM_ref8: 196246145Shselasky case DW_FORM_ref_udata: 197246145Shselasky *valp = at->u[0].u64; 198246145Shselasky break; 199246145Shselasky default: 200246145Shselasky if (die1 != NULL) 201246145Shselasky dwarf_dealloc(dbg, die1, DW_DLA_DIE); 202246145Shselasky DWARF_SET_ERROR(dbg, err, DW_DLE_ATTR_FORM_BAD); 203246145Shselasky return (DW_DLV_ERROR); 204246145Shselasky } 205246145Shselasky 206246145Shselasky if (die1 != NULL) 207246145Shselasky dwarf_dealloc(dbg, die1, DW_DLA_DIE); 208246145Shselasky 209246145Shselasky return (DW_DLV_OK); 210246145Shselasky} 211246145Shselasky