1 /*- 2 * Copyright (c) 2009,2011 Kai Wang 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include "_libdwarf.h" 28 29 ELFTC_VCSID("$Id: dwarf_abbrev.c 2072 2011-10-27 03:26:49Z jkoshy $"); 30 31 int 32 dwarf_get_abbrev(Dwarf_Debug dbg, Dwarf_Unsigned offset, 33 Dwarf_Abbrev *return_abbrev, Dwarf_Unsigned *length, 34 Dwarf_Unsigned *attr_count, Dwarf_Error *error) 35 { 36 Dwarf_Abbrev ab; 37 int ret; 38 39 if (dbg == NULL || return_abbrev == NULL || length == NULL || 40 attr_count == NULL) { 41 DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 42 return (DW_DLV_ERROR); 43 } 44 45 ret = _dwarf_abbrev_parse(dbg, NULL, &offset, &ab, error); 46 if (ret != DW_DLE_NONE) { 47 if (ret == DW_DLE_NO_ENTRY) { 48 DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 49 return (DW_DLV_NO_ENTRY); 50 } else 51 return (DW_DLV_ERROR); 52 } 53 54 *return_abbrev = ab; 55 *length = ab->ab_length; 56 *attr_count = ab->ab_atnum; 57 58 return (DW_DLV_OK); 59 } 60 61 int 62 dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev, Dwarf_Half *return_tag, 63 Dwarf_Error *error) 64 { 65 66 if (abbrev == NULL || return_tag == NULL) { 67 DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 68 return (DW_DLV_ERROR); 69 } 70 71 *return_tag = (Dwarf_Half) abbrev->ab_tag; 72 73 return (DW_DLV_OK); 74 } 75 76 int 77 dwarf_get_abbrev_code(Dwarf_Abbrev abbrev, Dwarf_Unsigned *return_code, 78 Dwarf_Error *error) 79 { 80 81 if (abbrev == NULL || return_code == NULL) { 82 DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 83 return (DW_DLV_ERROR); 84 } 85 86 *return_code = abbrev->ab_entry; 87 88 return (DW_DLV_OK); 89 } 90 91 int 92 dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev, Dwarf_Signed *return_flag, 93 Dwarf_Error *error) 94 { 95 96 if (abbrev == NULL || return_flag == NULL) { 97 DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 98 return (DW_DLV_ERROR); 99 } 100 101 *return_flag = (Dwarf_Signed) abbrev->ab_children; 102 103 return (DW_DLV_OK); 104 } 105 106 int 107 dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev, Dwarf_Signed ndx, 108 Dwarf_Half *attr_num, Dwarf_Signed *form, Dwarf_Off *offset, 109 Dwarf_Error *error) 110 { 111 Dwarf_AttrDef ad; 112 int i; 113 114 if (abbrev == NULL || attr_num == NULL || form == NULL || 115 offset == NULL) { 116 DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 117 return (DW_DLV_ERROR); 118 } 119 120 if (ndx < 0 || (uint64_t) ndx >= abbrev->ab_atnum) { 121 DWARF_SET_ERROR(NULL, error, DW_DLE_NO_ENTRY); 122 return (DW_DLV_NO_ENTRY); 123 } 124 125 ad = STAILQ_FIRST(&abbrev->ab_attrdef); 126 for (i = 0; i < ndx && ad != NULL; i++) 127 ad = STAILQ_NEXT(ad, ad_next); 128 129 assert(ad != NULL); 130 131 *attr_num = ad->ad_attrib; 132 *form = ad->ad_form; 133 *offset = ad->ad_offset; 134 135 return (DW_DLV_OK); 136 } 137