1179187Sjb/*-
2179187Sjb * Copyright (c) 2007 John Birrell (jb@freebsd.org)
3179187Sjb * All rights reserved.
4179187Sjb *
5179187Sjb * Redistribution and use in source and binary forms, with or without
6179187Sjb * modification, are permitted provided that the following conditions
7179187Sjb * are met:
8179187Sjb * 1. Redistributions of source code must retain the above copyright
9179187Sjb *    notice, this list of conditions and the following disclaimer.
10179187Sjb * 2. Redistributions in binary form must reproduce the above copyright
11179187Sjb *    notice, this list of conditions and the following disclaimer in the
12179187Sjb *    documentation and/or other materials provided with the distribution.
13179187Sjb *
14179187Sjb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15179187Sjb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16179187Sjb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17179187Sjb * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18179187Sjb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19179187Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20179187Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21179187Sjb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22179187Sjb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23179187Sjb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24179187Sjb * SUCH DAMAGE.
25179187Sjb *
26179187Sjb * $FreeBSD$
27179187Sjb */
28179187Sjb
29179187Sjb#ifndef	__LIBDWARF_H_
30179187Sjb#define	__LIBDWARF_H_
31179187Sjb
32179187Sjb#include <sys/param.h>
33179187Sjb#include <sys/queue.h>
34179187Sjb#include <stdio.h>
35179187Sjb#include <gelf.h>
36179187Sjb#include "dwarf.h"
37179187Sjb#include "libdwarf.h"
38179187Sjb
39179187Sjb#define DWARF_debug_abbrev		0
40179187Sjb#define DWARF_debug_aranges		1
41179187Sjb#define DWARF_debug_frame		2
42179187Sjb#define DWARF_debug_info		3
43179187Sjb#define DWARF_debug_line		4
44179187Sjb#define DWARF_debug_pubnames		5
45179187Sjb#define DWARF_eh_frame			6
46179187Sjb#define DWARF_debug_macinfo		7
47179187Sjb#define DWARF_debug_str			8
48179187Sjb#define DWARF_debug_loc			9
49179187Sjb#define DWARF_debug_pubtypes		10
50179187Sjb#define DWARF_debug_ranges		11
51179187Sjb#define DWARF_debug_static_func		12
52179187Sjb#define DWARF_debug_static_vars		13
53179187Sjb#define DWARF_debug_types		14
54179187Sjb#define DWARF_debug_weaknames		15
55179187Sjb#define DWARF_symtab			16
56179187Sjb#define DWARF_strtab			17
57179187Sjb#define DWARF_DEBUG_SNAMES		18
58179187Sjb
59179187Sjb#define DWARF_DIE_HASH_SIZE		8191
60179187Sjb
61179187Sjb#define	DWARF_SET_ERROR(_e, _err)	do { 		\
62179187Sjb	_e->err_error = _err;				\
63179187Sjb	_e->elf_error = 0;				\
64179187Sjb	_e->err_func  = __func__;			\
65179187Sjb	_e->err_line  = __LINE__;			\
66179187Sjb	_e->err_msg[0] = '\0';				\
67179187Sjb	} while (0)
68179187Sjb
69179187Sjb#define	DWARF_SET_ELF_ERROR(_e, _err)	do { 		\
70179187Sjb	_e->err_error = DWARF_E_ELF;			\
71179187Sjb	_e->elf_error = _err;				\
72179187Sjb	_e->err_func  = __func__;			\
73179187Sjb	_e->err_line  = __LINE__;			\
74179187Sjb	_e->err_msg[0] = '\0';				\
75179187Sjb	} while (0)
76179187Sjb
77179187Sjbstruct _Dwarf_AttrValue {
78179187Sjb	uint64_t	av_attrib;	/* DW_AT_ */
79179187Sjb	uint64_t	av_form;	/* DW_FORM_ */
80179187Sjb	union {
81179187Sjb		uint64_t	u64;
82179187Sjb		int64_t		s64;
83179187Sjb		const char	*s;
84179187Sjb		uint8_t		*u8p;
85179187Sjb	} u[2];				/* Value. */
86179187Sjb	STAILQ_ENTRY(_Dwarf_AttrValue)
87179187Sjb			av_next;	/* Next attribute value. */
88179187Sjb};
89179187Sjb
90179187Sjbstruct _Dwarf_Die {
91179187Sjb	int		die_level;	/* Parent-child level. */
92179187Sjb	uint64_t	die_offset;	/* DIE offset in section. */
93179187Sjb	uint64_t	die_abnum;	/* Abbrev number. */
94179187Sjb	Dwarf_Abbrev	die_a;		/* Abbrev pointer. */
95179187Sjb	Dwarf_CU	die_cu;		/* Compilation unit pointer. */
96179187Sjb	const char	*die_name;	/* Ptr to the name string. */
97179187Sjb	STAILQ_HEAD(, _Dwarf_AttrValue)
98179187Sjb			die_attrval;	/* List of attribute values. */
99179187Sjb	STAILQ_ENTRY(_Dwarf_Die)
100179187Sjb			die_next;	/* Next die in list. */
101179187Sjb	STAILQ_ENTRY(_Dwarf_Die)
102179187Sjb			die_hash;	/* Next die in hash table. */
103179187Sjb};
104179187Sjb
105179187Sjbstruct _Dwarf_Attribute {
106179187Sjb	uint64_t	at_attrib;	/* DW_AT_ */
107179187Sjb	uint64_t	at_form;	/* DW_FORM_ */
108179187Sjb	STAILQ_ENTRY(_Dwarf_Attribute)
109179187Sjb			at_next;	/* Next attribute. */
110179187Sjb};
111179187Sjb
112179187Sjbstruct _Dwarf_Abbrev {
113179187Sjb	uint64_t	a_entry;	/* Abbrev entry. */
114179187Sjb	uint64_t	a_tag;		/* Tag: DW_TAG_ */
115179187Sjb	uint8_t		a_children;	/* DW_CHILDREN_no or DW_CHILDREN_yes */
116179187Sjb	STAILQ_HEAD(, _Dwarf_Attribute)
117179187Sjb			a_attrib;	/* List of attributes. */
118179187Sjb	STAILQ_ENTRY(_Dwarf_Abbrev)
119179187Sjb			a_next;		/* Next abbrev. */
120179187Sjb};
121179187Sjb
122179187Sjbstruct _Dwarf_CU {
123179187Sjb	uint64_t	cu_offset;	/* Offset to the this compilation unit. */
124179187Sjb	uint32_t	cu_length;	/* Length of CU data. */
125179187Sjb	uint32_t	cu_header_length;
126179187Sjb					/* Length of the CU header. */
127179187Sjb	uint16_t	cu_version;	/* DWARF version. */
128179187Sjb	uint64_t	cu_abbrev_offset;
129179187Sjb					/* Offset into .debug_abbrev. */
130179187Sjb	uint8_t		cu_pointer_size;
131179187Sjb					/* Number of bytes in pointer. */
132179187Sjb	uint64_t	cu_next_offset;
133179187Sjb					/* Offset to the next compilation unit. */
134179187Sjb	STAILQ_HEAD(, _Dwarf_Abbrev)
135179187Sjb			cu_abbrev;	/* List of abbrevs. */
136179187Sjb	STAILQ_HEAD(, _Dwarf_Die)
137179187Sjb			cu_die;		/* List of dies. */
138179187Sjb	STAILQ_HEAD(, _Dwarf_Die)
139179187Sjb			cu_die_hash[DWARF_DIE_HASH_SIZE];
140179187Sjb					/* Hash of dies. */
141179187Sjb	STAILQ_ENTRY(_Dwarf_CU)
142179187Sjb			cu_next;	/* Next compilation unit. */
143179187Sjb};
144179187Sjb
145179187Sjbtypedef struct _Dwarf_section {
146179187Sjb	Elf_Scn		*s_scn;		/* Section pointer. */
147179187Sjb	GElf_Shdr	s_shdr;		/* Copy of the section header. */
148179187Sjb	char		*s_sname;	/* Ptr to the section name. */
149179187Sjb	uint32_t	s_shnum;	/* Section number. */
150179187Sjb	Elf_Data	*s_data;	/* Section data. */
151179187Sjb} Dwarf_section;
152179187Sjb
153179187Sjbstruct _Dwarf_Debug {
154179187Sjb	Elf		*dbg_elf;	/* Ptr to the ELF handle. */
155179187Sjb	GElf_Ehdr	dbg_ehdr;	/* Copy of the ELF header. */
156179187Sjb	int		dbg_elf_close;	/* True if elf_end() required. */
157179187Sjb	int		dbg_mode;	/* Access mode. */
158179187Sjb	size_t		dbg_stnum;	/* Section header string table section number. */
159179187Sjb	int		dbg_offsize;	/* DWARF offset size. */
160179187Sjb	Dwarf_section	dbg_s[DWARF_DEBUG_SNAMES];
161179187Sjb					/* Array of section information. */
162179187Sjb	STAILQ_HEAD(, _Dwarf_CU)
163179187Sjb			dbg_cu;		/* List of compilation units. */
164179187Sjb	Dwarf_CU	dbg_cu_current;
165179187Sjb					/* Ptr to the current compilation unit. */
166221569Sobrien
167221569Sobrien	STAILQ_HEAD(, _Dwarf_Func) dbg_func; /* List of functions */
168179187Sjb};
169179187Sjb
170221569Sobrienstruct _Dwarf_Func {
171221569Sobrien	Dwarf_Die	func_die;
172221569Sobrien	const char	*func_name;
173221569Sobrien	Dwarf_Addr	func_low_pc;
174221569Sobrien	Dwarf_Addr	func_high_pc;
175221569Sobrien	int		func_is_inlined;
176221569Sobrien	/* inlined instance */
177221569Sobrien	STAILQ_HEAD(, _Dwarf_Inlined_Func) func_inlined_instances;
178221569Sobrien	STAILQ_ENTRY(_Dwarf_Func) func_next;
179221569Sobrien};
180221569Sobrien
181221569Sobrienstruct _Dwarf_Inlined_Func {
182221569Sobrien	struct _Dwarf_Func *ifunc_origin;
183221569Sobrien	Dwarf_Die	ifunc_abstract;
184221569Sobrien	Dwarf_Die	ifunc_concrete;
185221569Sobrien	Dwarf_Addr	ifunc_low_pc;
186221569Sobrien	Dwarf_Addr	ifunc_high_pc;
187221569Sobrien	STAILQ_ENTRY(_Dwarf_Inlined_Func) ifunc_next;
188221569Sobrien};
189221569Sobrien
190221569Sobrienvoid	dwarf_build_function_table(Dwarf_Debug dbg);
191221569Sobrien
192221569Sobrien#ifdef DWARF_DEBUG
193221569Sobrien#include <assert.h>
194221569Sobrien#define DWARF_ASSERT(x)	assert(x)
195221569Sobrien#else
196221569Sobrien#define DWARF_ASSERT(x)
197221569Sobrien#endif
198221569Sobrien
199179187Sjb#endif /* !__LIBDWARF_H_ */
200