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