1260684Skaiw/*- 2260684Skaiw * Copyright (c) 2007 John Birrell (jb@freebsd.org) 3260684Skaiw * Copyright (c) 2009 Kai Wang 4260684Skaiw * All rights reserved. 5260684Skaiw * 6260684Skaiw * Redistribution and use in source and binary forms, with or without 7260684Skaiw * modification, are permitted provided that the following conditions 8260684Skaiw * are met: 9260684Skaiw * 1. Redistributions of source code must retain the above copyright 10260684Skaiw * notice, this list of conditions and the following disclaimer. 11260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright 12260684Skaiw * notice, this list of conditions and the following disclaimer in the 13260684Skaiw * documentation and/or other materials provided with the distribution. 14260684Skaiw * 15260684Skaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16260684Skaiw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17260684Skaiw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18260684Skaiw * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19260684Skaiw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20260684Skaiw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21260684Skaiw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22260684Skaiw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23260684Skaiw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24260684Skaiw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25260684Skaiw * SUCH DAMAGE. 26260684Skaiw */ 27260684Skaiw 28260684Skaiw#include "_libdwarf.h" 29260684Skaiw 30276371SemasteELFTC_VCSID("$Id: dwarf_attr.c 3064 2014-06-06 19:35:55Z kaiwang27 $"); 31260684Skaiw 32260684Skaiwint 33260684Skaiwdwarf_attr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute *atp, 34260684Skaiw Dwarf_Error *error) 35260684Skaiw{ 36260684Skaiw Dwarf_Debug dbg; 37260684Skaiw Dwarf_Attribute at; 38260684Skaiw 39260684Skaiw dbg = die != NULL ? die->die_dbg : NULL; 40260684Skaiw 41260684Skaiw if (die == NULL || atp == NULL) { 42260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 43260684Skaiw return (DW_DLV_ERROR); 44260684Skaiw } 45260684Skaiw 46260684Skaiw if ((at = _dwarf_attr_find(die, attr)) == NULL) { 47260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 48260684Skaiw return (DW_DLV_NO_ENTRY); 49260684Skaiw } 50260684Skaiw 51260684Skaiw *atp = at; 52260684Skaiw 53260684Skaiw return (DW_DLV_OK); 54260684Skaiw} 55260684Skaiw 56260684Skaiwint 57260684Skaiwdwarf_attrlist(Dwarf_Die die, Dwarf_Attribute **attrbuf, 58260684Skaiw Dwarf_Signed *attrcount, Dwarf_Error *error) 59260684Skaiw{ 60260684Skaiw Dwarf_Attribute at; 61260684Skaiw Dwarf_Debug dbg; 62260684Skaiw int i; 63260684Skaiw 64260684Skaiw dbg = die != NULL ? die->die_dbg : NULL; 65260684Skaiw 66260684Skaiw if (die == NULL || attrbuf == NULL || attrcount == NULL) { 67260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 68260684Skaiw return (DW_DLV_ERROR); 69260684Skaiw } 70260684Skaiw 71260684Skaiw if (die->die_ab->ab_atnum == 0) { 72260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 73260684Skaiw return (DW_DLV_NO_ENTRY); 74260684Skaiw } 75260684Skaiw 76260684Skaiw *attrcount = die->die_ab->ab_atnum; 77260684Skaiw 78260684Skaiw if (die->die_attrarray != NULL) { 79260684Skaiw *attrbuf = die->die_attrarray; 80260684Skaiw return (DW_DLV_OK); 81260684Skaiw } 82260684Skaiw 83260684Skaiw if ((die->die_attrarray = malloc(*attrcount * sizeof(Dwarf_Attribute))) 84260684Skaiw == NULL) { 85260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 86260684Skaiw return (DW_DLV_ERROR); 87260684Skaiw } 88260684Skaiw 89260684Skaiw for (i = 0, at = STAILQ_FIRST(&die->die_attr); 90260684Skaiw i < *attrcount && at != NULL; i++, at = STAILQ_NEXT(at, at_next)) 91260684Skaiw die->die_attrarray[i] = at; 92260684Skaiw 93260684Skaiw *attrbuf = die->die_attrarray; 94260684Skaiw 95260684Skaiw return (DW_DLV_OK); 96260684Skaiw} 97260684Skaiw 98260684Skaiwint 99260684Skaiwdwarf_hasattr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Bool *ret_bool, 100260684Skaiw Dwarf_Error *error) 101260684Skaiw{ 102260684Skaiw Dwarf_Debug dbg; 103260684Skaiw 104260684Skaiw dbg = die != NULL ? die->die_dbg : NULL; 105260684Skaiw 106260684Skaiw if (die == NULL || ret_bool == NULL) { 107260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 108260684Skaiw return (DW_DLV_ERROR); 109260684Skaiw } 110260684Skaiw 111260684Skaiw *ret_bool = (_dwarf_attr_find(die, attr) != NULL); 112260684Skaiw 113260684Skaiw return (DW_DLV_OK); 114260684Skaiw} 115260684Skaiw 116260684Skaiwint 117276371Semastedwarf_attroffset(Dwarf_Attribute at, Dwarf_Off *ret_off, Dwarf_Error *error) 118276371Semaste{ 119276371Semaste Dwarf_Debug dbg; 120276371Semaste 121276371Semaste dbg = at != NULL ? at->at_die->die_dbg : NULL; 122276371Semaste 123276371Semaste if (at == NULL || ret_off == NULL) { 124276371Semaste DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 125276371Semaste return (DW_DLV_ERROR); 126276371Semaste } 127276371Semaste 128276371Semaste *ret_off = at->at_offset; 129276371Semaste 130276371Semaste return (DW_DLV_OK); 131276371Semaste} 132276371Semaste 133276371Semasteint 134260684Skaiwdwarf_lowpc(Dwarf_Die die, Dwarf_Addr *ret_lowpc, 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 || ret_lowpc == NULL) { 142260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 143260684Skaiw return (DW_DLV_ERROR); 144260684Skaiw } 145260684Skaiw 146260684Skaiw if ((at = _dwarf_attr_find(die, DW_AT_low_pc)) == NULL) { 147260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 148260684Skaiw return (DW_DLV_NO_ENTRY); 149260684Skaiw } 150260684Skaiw 151260684Skaiw *ret_lowpc = at->u[0].u64; 152260684Skaiw 153260684Skaiw return (DW_DLV_OK); 154260684Skaiw} 155260684Skaiw 156260684Skaiwint 157260684Skaiwdwarf_highpc(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Error *error) 158260684Skaiw{ 159276371Semaste 160276371Semaste return (dwarf_highpc_b(die, ret_highpc, NULL, NULL, error)); 161276371Semaste} 162276371Semaste 163276371Semasteint 164276371Semastedwarf_highpc_b(Dwarf_Die die, Dwarf_Addr *ret_highpc, Dwarf_Half *ret_form, 165276371Semaste enum Dwarf_Form_Class *ret_class, Dwarf_Error *error) 166276371Semaste{ 167260684Skaiw Dwarf_Attribute at; 168260684Skaiw Dwarf_Debug dbg; 169276371Semaste Dwarf_CU cu; 170260684Skaiw 171260684Skaiw dbg = die != NULL ? die->die_dbg : NULL; 172260684Skaiw 173260684Skaiw if (die == NULL || ret_highpc == NULL) { 174260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 175260684Skaiw return (DW_DLV_ERROR); 176260684Skaiw } 177260684Skaiw 178260684Skaiw if ((at = _dwarf_attr_find(die, DW_AT_high_pc)) == NULL) { 179260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 180260684Skaiw return (DW_DLV_NO_ENTRY); 181260684Skaiw } 182260684Skaiw 183260684Skaiw *ret_highpc = at->u[0].u64; 184260684Skaiw 185276371Semaste if (ret_form != NULL) { 186276371Semaste *ret_form = at->at_form; 187276371Semaste } 188276371Semaste 189276371Semaste if (ret_class != NULL) { 190276371Semaste cu = die->die_cu; 191276371Semaste *ret_class = dwarf_get_form_class(cu->cu_version, 192276371Semaste DW_AT_high_pc, cu->cu_length_size == 4 ? 4 : 8, 193276371Semaste at->at_form); 194276371Semaste } 195276371Semaste 196260684Skaiw return (DW_DLV_OK); 197260684Skaiw} 198260684Skaiw 199260684Skaiwint 200260684Skaiwdwarf_bytesize(Dwarf_Die die, Dwarf_Unsigned *ret_size, Dwarf_Error *error) 201260684Skaiw{ 202260684Skaiw Dwarf_Attribute at; 203260684Skaiw Dwarf_Debug dbg; 204260684Skaiw 205260684Skaiw dbg = die != NULL ? die->die_dbg : NULL; 206260684Skaiw 207260684Skaiw if (die == NULL || ret_size == NULL) { 208260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 209260684Skaiw return (DW_DLV_ERROR); 210260684Skaiw } 211260684Skaiw 212260684Skaiw if ((at = _dwarf_attr_find(die, DW_AT_byte_size)) == NULL) { 213260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 214260684Skaiw return (DW_DLV_NO_ENTRY); 215260684Skaiw } 216260684Skaiw 217260684Skaiw *ret_size = at->u[0].u64; 218260684Skaiw 219260684Skaiw return (DW_DLV_OK); 220260684Skaiw} 221260684Skaiw 222260684Skaiwint 223260684Skaiwdwarf_bitsize(Dwarf_Die die, Dwarf_Unsigned *ret_size, Dwarf_Error *error) 224260684Skaiw{ 225260684Skaiw Dwarf_Attribute at; 226260684Skaiw Dwarf_Debug dbg; 227260684Skaiw 228260684Skaiw dbg = die != NULL ? die->die_dbg : NULL; 229260684Skaiw 230260684Skaiw if (die == NULL || ret_size == NULL) { 231260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 232260684Skaiw return (DW_DLV_ERROR); 233260684Skaiw } 234260684Skaiw 235260684Skaiw if ((at = _dwarf_attr_find(die, DW_AT_bit_size)) == NULL) { 236260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 237260684Skaiw return (DW_DLV_NO_ENTRY); 238260684Skaiw } 239260684Skaiw 240260684Skaiw *ret_size = at->u[0].u64; 241260684Skaiw 242260684Skaiw return (DW_DLV_OK); 243260684Skaiw} 244260684Skaiw 245260684Skaiwint 246260684Skaiwdwarf_bitoffset(Dwarf_Die die, Dwarf_Unsigned *ret_size, Dwarf_Error *error) 247260684Skaiw{ 248260684Skaiw Dwarf_Attribute at; 249260684Skaiw Dwarf_Debug dbg; 250260684Skaiw 251260684Skaiw dbg = die != NULL ? die->die_dbg : NULL; 252260684Skaiw 253260684Skaiw if (die == NULL || ret_size == NULL) { 254260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 255260684Skaiw return (DW_DLV_ERROR); 256260684Skaiw } 257260684Skaiw 258260684Skaiw if ((at = _dwarf_attr_find(die, DW_AT_bit_offset)) == NULL) { 259260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 260260684Skaiw return (DW_DLV_NO_ENTRY); 261260684Skaiw } 262260684Skaiw 263260684Skaiw *ret_size = at->u[0].u64; 264260684Skaiw 265260684Skaiw return (DW_DLV_OK); 266260684Skaiw} 267260684Skaiw 268260684Skaiwint 269260684Skaiwdwarf_srclang(Dwarf_Die die, Dwarf_Unsigned *ret_lang, Dwarf_Error *error) 270260684Skaiw{ 271260684Skaiw Dwarf_Attribute at; 272260684Skaiw Dwarf_Debug dbg; 273260684Skaiw 274260684Skaiw dbg = die != NULL ? die->die_dbg : NULL; 275260684Skaiw 276260684Skaiw if (die == NULL || ret_lang == NULL) { 277260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 278260684Skaiw return (DW_DLV_ERROR); 279260684Skaiw } 280260684Skaiw 281260684Skaiw if ((at = _dwarf_attr_find(die, DW_AT_language)) == NULL) { 282260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 283260684Skaiw return (DW_DLV_NO_ENTRY); 284260684Skaiw } 285260684Skaiw 286260684Skaiw *ret_lang = at->u[0].u64; 287260684Skaiw 288260684Skaiw return (DW_DLV_OK); 289260684Skaiw} 290260684Skaiw 291260684Skaiwint 292260684Skaiwdwarf_arrayorder(Dwarf_Die die, Dwarf_Unsigned *ret_order, Dwarf_Error *error) 293260684Skaiw{ 294260684Skaiw Dwarf_Attribute at; 295260684Skaiw Dwarf_Debug dbg; 296260684Skaiw 297260684Skaiw dbg = die != NULL ? die->die_dbg : NULL; 298260684Skaiw 299260684Skaiw if (die == NULL || ret_order == NULL) { 300260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 301260684Skaiw return (DW_DLV_ERROR); 302260684Skaiw } 303260684Skaiw 304260684Skaiw if ((at = _dwarf_attr_find(die, DW_AT_ordering)) == NULL) { 305260684Skaiw DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 306260684Skaiw return (DW_DLV_NO_ENTRY); 307260684Skaiw } 308260684Skaiw 309260684Skaiw *ret_order = at->u[0].u64; 310260684Skaiw 311260684Skaiw return (DW_DLV_OK); 312260684Skaiw} 313