1260684Skaiw/*-
2260684Skaiw * Copyright (c) 2009,2011 Kai Wang
3260684Skaiw * All rights reserved.
4260684Skaiw *
5260684Skaiw * Redistribution and use in source and binary forms, with or without
6260684Skaiw * modification, are permitted provided that the following conditions
7260684Skaiw * are met:
8260684Skaiw * 1. Redistributions of source code must retain the above copyright
9260684Skaiw *    notice, this list of conditions and the following disclaimer.
10260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright
11260684Skaiw *    notice, this list of conditions and the following disclaimer in the
12260684Skaiw *    documentation and/or other materials provided with the distribution.
13260684Skaiw *
14260684Skaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15260684Skaiw * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16260684Skaiw * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17260684Skaiw * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18260684Skaiw * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19260684Skaiw * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20260684Skaiw * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21260684Skaiw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22260684Skaiw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23260684Skaiw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24260684Skaiw * SUCH DAMAGE.
25260684Skaiw */
26260684Skaiw
27260684Skaiw#include "_libdwarf.h"
28260684Skaiw
29260684SkaiwELFTC_VCSID("$Id: dwarf_abbrev.c 2072 2011-10-27 03:26:49Z jkoshy $");
30260684Skaiw
31260684Skaiwint
32260684Skaiwdwarf_get_abbrev(Dwarf_Debug dbg, Dwarf_Unsigned offset,
33260684Skaiw    Dwarf_Abbrev *return_abbrev, Dwarf_Unsigned *length,
34260684Skaiw    Dwarf_Unsigned *attr_count, Dwarf_Error *error)
35260684Skaiw{
36260684Skaiw	Dwarf_Abbrev ab;
37260684Skaiw	int ret;
38260684Skaiw
39260684Skaiw	if (dbg == NULL || return_abbrev == NULL || length == NULL ||
40260684Skaiw	    attr_count == NULL) {
41260684Skaiw		DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT);
42260684Skaiw		return (DW_DLV_ERROR);
43260684Skaiw	}
44260684Skaiw
45260684Skaiw	ret = _dwarf_abbrev_parse(dbg, NULL, &offset, &ab, error);
46260684Skaiw	if (ret != DW_DLE_NONE) {
47260684Skaiw		if (ret == DW_DLE_NO_ENTRY) {
48260684Skaiw			DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY);
49260684Skaiw			return (DW_DLV_NO_ENTRY);
50260684Skaiw		} else
51260684Skaiw			return (DW_DLV_ERROR);
52260684Skaiw	}
53260684Skaiw
54260684Skaiw	*return_abbrev = ab;
55260684Skaiw	*length = ab->ab_length;
56260684Skaiw	*attr_count = ab->ab_atnum;
57260684Skaiw
58260684Skaiw	return (DW_DLV_OK);
59260684Skaiw}
60260684Skaiw
61260684Skaiwint
62260684Skaiwdwarf_get_abbrev_tag(Dwarf_Abbrev abbrev, Dwarf_Half *return_tag,
63260684Skaiw    Dwarf_Error *error)
64260684Skaiw{
65260684Skaiw
66260684Skaiw	if (abbrev == NULL || return_tag == NULL) {
67260684Skaiw		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
68260684Skaiw		return (DW_DLV_ERROR);
69260684Skaiw	}
70260684Skaiw
71260684Skaiw	*return_tag = (Dwarf_Half) abbrev->ab_tag;
72260684Skaiw
73260684Skaiw	return (DW_DLV_OK);
74260684Skaiw}
75260684Skaiw
76260684Skaiwint
77260684Skaiwdwarf_get_abbrev_code(Dwarf_Abbrev abbrev, Dwarf_Unsigned *return_code,
78260684Skaiw    Dwarf_Error *error)
79260684Skaiw{
80260684Skaiw
81260684Skaiw	if (abbrev == NULL || return_code == NULL) {
82260684Skaiw		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
83260684Skaiw		return (DW_DLV_ERROR);
84260684Skaiw	}
85260684Skaiw
86260684Skaiw	*return_code = abbrev->ab_entry;
87260684Skaiw
88260684Skaiw	return (DW_DLV_OK);
89260684Skaiw}
90260684Skaiw
91260684Skaiwint
92260684Skaiwdwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev, Dwarf_Signed *return_flag,
93260684Skaiw    Dwarf_Error *error)
94260684Skaiw{
95260684Skaiw
96260684Skaiw	if (abbrev == NULL || return_flag == NULL) {
97260684Skaiw		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
98260684Skaiw		return (DW_DLV_ERROR);
99260684Skaiw	}
100260684Skaiw
101260684Skaiw	*return_flag = (Dwarf_Signed) abbrev->ab_children;
102260684Skaiw
103260684Skaiw	return (DW_DLV_OK);
104260684Skaiw}
105260684Skaiw
106260684Skaiwint
107260684Skaiwdwarf_get_abbrev_entry(Dwarf_Abbrev abbrev, Dwarf_Signed ndx,
108260684Skaiw    Dwarf_Half *attr_num, Dwarf_Signed *form, Dwarf_Off *offset,
109260684Skaiw    Dwarf_Error *error)
110260684Skaiw{
111260684Skaiw	Dwarf_AttrDef ad;
112260684Skaiw	int i;
113260684Skaiw
114260684Skaiw	if (abbrev == NULL || attr_num == NULL || form == NULL ||
115260684Skaiw	    offset == NULL) {
116260684Skaiw		DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT);
117260684Skaiw		return (DW_DLV_ERROR);
118260684Skaiw	}
119260684Skaiw
120260684Skaiw	if (ndx < 0 || (uint64_t) ndx >= abbrev->ab_atnum) {
121260684Skaiw		DWARF_SET_ERROR(NULL, error, DW_DLE_NO_ENTRY);
122260684Skaiw		return (DW_DLV_NO_ENTRY);
123260684Skaiw	}
124260684Skaiw
125260684Skaiw	ad = STAILQ_FIRST(&abbrev->ab_attrdef);
126260684Skaiw	for (i = 0; i < ndx && ad != NULL; i++)
127260684Skaiw		ad = STAILQ_NEXT(ad, ad_next);
128260684Skaiw
129260684Skaiw	assert(ad != NULL);
130260684Skaiw
131260684Skaiw	*attr_num = ad->ad_attrib;
132260684Skaiw	*form = ad->ad_form;
133260684Skaiw	*offset = ad->ad_offset;
134260684Skaiw
135260684Skaiw	return (DW_DLV_OK);
136260684Skaiw}
137