1/*-
2 * Copyright (c) 2007 John Birrell (jb@freebsd.org)
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 * $FreeBSD$
27 */
28
29#ifndef	__LIBDWARF_H_
30#define	__LIBDWARF_H_
31
32#include <sys/param.h>
33#include <sys/queue.h>
34#include <stdio.h>
35#include <gelf.h>
36#include "dwarf.h"
37#include "libdwarf.h"
38
39#define DWARF_debug_abbrev		0
40#define DWARF_debug_aranges		1
41#define DWARF_debug_frame		2
42#define DWARF_debug_info		3
43#define DWARF_debug_line		4
44#define DWARF_debug_pubnames		5
45#define DWARF_eh_frame			6
46#define DWARF_debug_macinfo		7
47#define DWARF_debug_str			8
48#define DWARF_debug_loc			9
49#define DWARF_debug_pubtypes		10
50#define DWARF_debug_ranges		11
51#define DWARF_debug_static_func		12
52#define DWARF_debug_static_vars		13
53#define DWARF_debug_types		14
54#define DWARF_debug_weaknames		15
55#define DWARF_symtab			16
56#define DWARF_strtab			17
57#define DWARF_DEBUG_SNAMES		18
58
59#define DWARF_DIE_HASH_SIZE		8191
60
61#define	DWARF_SET_ERROR(_e, _err)	do { 		\
62	_e->err_error = _err;				\
63	_e->elf_error = 0;				\
64	_e->err_func  = __func__;			\
65	_e->err_line  = __LINE__;			\
66	_e->err_msg[0] = '\0';				\
67	} while (0)
68
69#define	DWARF_SET_ELF_ERROR(_e, _err)	do { 		\
70	_e->err_error = DWARF_E_ELF;			\
71	_e->elf_error = _err;				\
72	_e->err_func  = __func__;			\
73	_e->err_line  = __LINE__;			\
74	_e->err_msg[0] = '\0';				\
75	} while (0)
76
77struct _Dwarf_AttrValue {
78	uint64_t	av_attrib;	/* DW_AT_ */
79	uint64_t	av_form;	/* DW_FORM_ */
80	union {
81		uint64_t	u64;
82		int64_t		s64;
83		const char	*s;
84		uint8_t		*u8p;
85	} u[2];				/* Value. */
86	STAILQ_ENTRY(_Dwarf_AttrValue)
87			av_next;	/* Next attribute value. */
88};
89
90struct _Dwarf_Die {
91	int		die_level;	/* Parent-child level. */
92	uint64_t	die_offset;	/* DIE offset in section. */
93	uint64_t	die_abnum;	/* Abbrev number. */
94	Dwarf_Abbrev	die_a;		/* Abbrev pointer. */
95	Dwarf_CU	die_cu;		/* Compilation unit pointer. */
96	const char	*die_name;	/* Ptr to the name string. */
97	STAILQ_HEAD(, _Dwarf_AttrValue)
98			die_attrval;	/* List of attribute values. */
99	STAILQ_ENTRY(_Dwarf_Die)
100			die_next;	/* Next die in list. */
101	STAILQ_ENTRY(_Dwarf_Die)
102			die_hash;	/* Next die in hash table. */
103};
104
105struct _Dwarf_Attribute {
106	uint64_t	at_attrib;	/* DW_AT_ */
107	uint64_t	at_form;	/* DW_FORM_ */
108	STAILQ_ENTRY(_Dwarf_Attribute)
109			at_next;	/* Next attribute. */
110};
111
112struct _Dwarf_Abbrev {
113	uint64_t	a_entry;	/* Abbrev entry. */
114	uint64_t	a_tag;		/* Tag: DW_TAG_ */
115	uint8_t		a_children;	/* DW_CHILDREN_no or DW_CHILDREN_yes */
116	STAILQ_HEAD(, _Dwarf_Attribute)
117			a_attrib;	/* List of attributes. */
118	STAILQ_ENTRY(_Dwarf_Abbrev)
119			a_next;		/* Next abbrev. */
120};
121
122struct _Dwarf_CU {
123	uint64_t	cu_offset;	/* Offset to the this compilation unit. */
124	uint32_t	cu_length;	/* Length of CU data. */
125	uint32_t	cu_header_length;
126					/* Length of the CU header. */
127	uint16_t	cu_version;	/* DWARF version. */
128	uint64_t	cu_abbrev_offset;
129					/* Offset into .debug_abbrev. */
130	uint8_t		cu_pointer_size;
131					/* Number of bytes in pointer. */
132	uint64_t	cu_next_offset;
133					/* Offset to the next compilation unit. */
134	STAILQ_HEAD(, _Dwarf_Abbrev)
135			cu_abbrev;	/* List of abbrevs. */
136	STAILQ_HEAD(, _Dwarf_Die)
137			cu_die;		/* List of dies. */
138	STAILQ_HEAD(, _Dwarf_Die)
139			cu_die_hash[DWARF_DIE_HASH_SIZE];
140					/* Hash of dies. */
141	STAILQ_ENTRY(_Dwarf_CU)
142			cu_next;	/* Next compilation unit. */
143};
144
145typedef struct _Dwarf_section {
146	Elf_Scn		*s_scn;		/* Section pointer. */
147	GElf_Shdr	s_shdr;		/* Copy of the section header. */
148	char		*s_sname;	/* Ptr to the section name. */
149	uint32_t	s_shnum;	/* Section number. */
150	Elf_Data	*s_data;	/* Section data. */
151} Dwarf_section;
152
153struct _Dwarf_Debug {
154	Elf		*dbg_elf;	/* Ptr to the ELF handle. */
155	GElf_Ehdr	dbg_ehdr;	/* Copy of the ELF header. */
156	int		dbg_elf_close;	/* True if elf_end() required. */
157	int		dbg_mode;	/* Access mode. */
158	size_t		dbg_stnum;	/* Section header string table section number. */
159	int		dbg_offsize;	/* DWARF offset size. */
160	Dwarf_section	dbg_s[DWARF_DEBUG_SNAMES];
161					/* Array of section information. */
162	STAILQ_HEAD(, _Dwarf_CU)
163			dbg_cu;		/* List of compilation units. */
164	Dwarf_CU	dbg_cu_current;
165					/* Ptr to the current compilation unit. */
166
167	STAILQ_HEAD(, _Dwarf_Func) dbg_func; /* List of functions */
168};
169
170struct _Dwarf_Func {
171	Dwarf_Die	func_die;
172	const char	*func_name;
173	Dwarf_Addr	func_low_pc;
174	Dwarf_Addr	func_high_pc;
175	int		func_is_inlined;
176	/* inlined instance */
177	STAILQ_HEAD(, _Dwarf_Inlined_Func) func_inlined_instances;
178	STAILQ_ENTRY(_Dwarf_Func) func_next;
179};
180
181struct _Dwarf_Inlined_Func {
182	struct _Dwarf_Func *ifunc_origin;
183	Dwarf_Die	ifunc_abstract;
184	Dwarf_Die	ifunc_concrete;
185	Dwarf_Addr	ifunc_low_pc;
186	Dwarf_Addr	ifunc_high_pc;
187	STAILQ_ENTRY(_Dwarf_Inlined_Func) ifunc_next;
188};
189
190void	dwarf_build_function_table(Dwarf_Debug dbg);
191
192#ifdef DWARF_DEBUG
193#include <assert.h>
194#define DWARF_ASSERT(x)	assert(x)
195#else
196#define DWARF_ASSERT(x)
197#endif
198
199#endif /* !__LIBDWARF_H_ */
200