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