1 /*- 2 * Copyright (c) 2007 John Birrell (jb@freebsd.org) 3 * Copyright (c) 2009 Kai Wang 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include "_libdwarf.h" 29 30 ELFTC_VCSID("$Id: dwarf_attr.c 2072 2011-10-27 03:26:49Z jkoshy $"); 31 32 int 33 dwarf_attr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute *atp, 34 Dwarf_Error *error) 35 { 36 Dwarf_Debug dbg; 37 Dwarf_Attribute at; 38 39 dbg = die != NULL ? die->die_dbg : NULL; 40 41 if (die == NULL || atp == NULL) { 42 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 43 return (DW_DLV_ERROR); 44 } 45 46 if ((at = _dwarf_attr_find(die, attr)) == NULL) { 47 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 48 return (DW_DLV_NO_ENTRY); 49 } 50 51 *atp = at; 52 53 return (DW_DLV_OK); 54 } 55 56 int 57 dwarf_attrlist(Dwarf_Die die, Dwarf_Attribute **attrbuf, 58 Dwarf_Signed *attrcount, Dwarf_Error *error) 59 { 60 Dwarf_Attribute at; 61 Dwarf_Debug dbg; 62 int i; 63 64 dbg = die != NULL ? die->die_dbg : NULL; 65 66 if (die == NULL || attrbuf == NULL || attrcount == NULL) { 67 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 68 return (DW_DLV_ERROR); 69 } 70 71 if (die->die_ab->ab_atnum == 0) { 72 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 73 return (DW_DLV_NO_ENTRY); 74 } 75 76 *attrcount = die->die_ab->ab_atnum; 77 78 if (die->die_attrarray != NULL) { 79 *attrbuf = die->die_attrarray; 80 return (DW_DLV_OK); 81 } 82 83 if ((die->die_attrarray = malloc(*attrcount * sizeof(Dwarf_Attribute))) 84 == NULL) { 85 DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 86 return (DW_DLV_ERROR); 87 } 88 89 for (i = 0, at = STAILQ_FIRST(&die->die_attr); 90 i < *attrcount && at != NULL; i++, at = STAILQ_NEXT(at, at_next)) 91 die->die_attrarray[i] = at; 92 93 *attrbuf = die->die_attrarray; 94 95 return (DW_DLV_OK); 96 } 97 98 int 99 dwarf_hasattr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *ret_bool, 100 Dwarf_Error *error) 101 { 102 Dwarf_Debug dbg; 103 104 dbg = die != NULL ? die->die_dbg : NULL; 105 106 if (die == NULL || ret_bool == NULL) { 107 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 108 return (DW_DLV_ERROR); 109 } 110 111 *ret_bool = (_dwarf_attr_find(die, attr) != NULL); 112 113 return (DW_DLV_OK); 114 } 115 116 int 117 dwarf_lowpc(Dwarf_Die die, Dwarf_Addr *ret_lowpc, Dwarf_Error *error) 118 { 119 Dwarf_Attribute at; 120 Dwarf_Debug dbg; 121 122 dbg = die != NULL ? die->die_dbg : NULL; 123 124 if (die == NULL || ret_lowpc == NULL) { 125 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 126 return (DW_DLV_ERROR); 127 } 128 129 if ((at = _dwarf_attr_find(die, DW_AT_low_pc)) == NULL) { 130 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 131 return (DW_DLV_NO_ENTRY); 132 } 133 134 *ret_lowpc = at->u[0].u64; 135 136 return (DW_DLV_OK); 137 } 138 139 int 140 dwarf_highpc(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Error *error) 141 { 142 Dwarf_Attribute at; 143 Dwarf_Debug dbg; 144 145 dbg = die != NULL ? die->die_dbg : NULL; 146 147 if (die == NULL || ret_highpc == NULL) { 148 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 149 return (DW_DLV_ERROR); 150 } 151 152 if ((at = _dwarf_attr_find(die, DW_AT_high_pc)) == NULL) { 153 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 154 return (DW_DLV_NO_ENTRY); 155 } 156 157 *ret_highpc = at->u[0].u64; 158 159 return (DW_DLV_OK); 160 } 161 162 int 163 dwarf_bytesize(Dwarf_Die die, Dwarf_Unsigned *ret_size, Dwarf_Error *error) 164 { 165 Dwarf_Attribute at; 166 Dwarf_Debug dbg; 167 168 dbg = die != NULL ? die->die_dbg : NULL; 169 170 if (die == NULL || ret_size == NULL) { 171 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 172 return (DW_DLV_ERROR); 173 } 174 175 if ((at = _dwarf_attr_find(die, DW_AT_byte_size)) == NULL) { 176 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 177 return (DW_DLV_NO_ENTRY); 178 } 179 180 *ret_size = at->u[0].u64; 181 182 return (DW_DLV_OK); 183 } 184 185 int 186 dwarf_bitsize(Dwarf_Die die, Dwarf_Unsigned *ret_size, Dwarf_Error *error) 187 { 188 Dwarf_Attribute at; 189 Dwarf_Debug dbg; 190 191 dbg = die != NULL ? die->die_dbg : NULL; 192 193 if (die == NULL || ret_size == NULL) { 194 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 195 return (DW_DLV_ERROR); 196 } 197 198 if ((at = _dwarf_attr_find(die, DW_AT_bit_size)) == NULL) { 199 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 200 return (DW_DLV_NO_ENTRY); 201 } 202 203 *ret_size = at->u[0].u64; 204 205 return (DW_DLV_OK); 206 } 207 208 int 209 dwarf_bitoffset(Dwarf_Die die, Dwarf_Unsigned *ret_size, Dwarf_Error *error) 210 { 211 Dwarf_Attribute at; 212 Dwarf_Debug dbg; 213 214 dbg = die != NULL ? die->die_dbg : NULL; 215 216 if (die == NULL || ret_size == NULL) { 217 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 218 return (DW_DLV_ERROR); 219 } 220 221 if ((at = _dwarf_attr_find(die, DW_AT_bit_offset)) == NULL) { 222 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 223 return (DW_DLV_NO_ENTRY); 224 } 225 226 *ret_size = at->u[0].u64; 227 228 return (DW_DLV_OK); 229 } 230 231 int 232 dwarf_srclang(Dwarf_Die die, Dwarf_Unsigned *ret_lang, Dwarf_Error *error) 233 { 234 Dwarf_Attribute at; 235 Dwarf_Debug dbg; 236 237 dbg = die != NULL ? die->die_dbg : NULL; 238 239 if (die == NULL || ret_lang == NULL) { 240 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 241 return (DW_DLV_ERROR); 242 } 243 244 if ((at = _dwarf_attr_find(die, DW_AT_language)) == NULL) { 245 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 246 return (DW_DLV_NO_ENTRY); 247 } 248 249 *ret_lang = at->u[0].u64; 250 251 return (DW_DLV_OK); 252 } 253 254 int 255 dwarf_arrayorder(Dwarf_Die die, Dwarf_Unsigned *ret_order, Dwarf_Error *error) 256 { 257 Dwarf_Attribute at; 258 Dwarf_Debug dbg; 259 260 dbg = die != NULL ? die->die_dbg : NULL; 261 262 if (die == NULL || ret_order == NULL) { 263 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 264 return (DW_DLV_ERROR); 265 } 266 267 if ((at = _dwarf_attr_find(die, DW_AT_ordering)) == NULL) { 268 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 269 return (DW_DLV_NO_ENTRY); 270 } 271 272 *ret_order = at->u[0].u64; 273 274 return (DW_DLV_OK); 275 } 276