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#include <stdlib.h>
30179187Sjb#include <string.h>
31179187Sjb#include "_libdwarf.h"
32179187Sjb
33179187Sjbstatic const char *debug_snames[DWARF_DEBUG_SNAMES] = {
34179187Sjb	".debug_abbrev",
35179187Sjb	".debug_aranges",
36179187Sjb	".debug_frame",
37179187Sjb	".debug_info",
38179187Sjb	".debug_line",
39179187Sjb	".debug_pubnames",
40179187Sjb	".eh_frame",
41179187Sjb	".debug_macinfo",
42179187Sjb	".debug_str",
43179187Sjb	".debug_loc",
44179187Sjb	".debug_pubtypes",
45179187Sjb	".debug_ranges",
46179187Sjb	".debug_static_func",
47179187Sjb	".debug_static_vars",
48179187Sjb	".debug_types",
49179187Sjb	".debug_weaknames",
50179187Sjb	".symtab",
51179187Sjb	".strtab"
52179187Sjb};
53179187Sjb
54179187Sjbstatic uint64_t (*dwarf_read) (Elf_Data **, uint64_t *, int);
55179187Sjbstatic void (*dwarf_write) (Elf_Data **, uint64_t *, uint64_t, int);
56179187Sjb
57179187Sjbstatic uint64_t
58179187Sjbdwarf_read_lsb(Elf_Data **dp, uint64_t *offsetp, int bytes_to_read)
59179187Sjb{
60179187Sjb	uint64_t ret = 0;
61179187Sjb
62179187Sjb	uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp;
63179187Sjb
64179187Sjb	switch (bytes_to_read) {
65179187Sjb	case 8:
66179187Sjb		ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
67179187Sjb		ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
68179187Sjb	case 4:
69179187Sjb		ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
70179187Sjb	case 2:
71179187Sjb		ret |= ((uint64_t) src[1]) << 8;
72179187Sjb	case 1:
73179187Sjb		ret |= src[0];
74179187Sjb		break;
75179187Sjb	default:
76179187Sjb		return 0;
77179187Sjb		break;
78179187Sjb	}
79179187Sjb
80179187Sjb	*offsetp += bytes_to_read;
81179187Sjb
82179187Sjb	return ret;
83179187Sjb}
84179187Sjb
85179187Sjbstatic uint64_t
86179187Sjbdwarf_read_msb(Elf_Data **dp, uint64_t *offsetp, int bytes_to_read)
87179187Sjb{
88179187Sjb	uint64_t ret = 0;
89179187Sjb
90179187Sjb	uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp;
91179187Sjb
92179187Sjb	switch (bytes_to_read) {
93179187Sjb	case 1:
94179187Sjb		ret = src[0];
95179187Sjb		break;
96179187Sjb	case 2:
97179187Sjb		ret = src[1] | ((uint64_t) src[0]) << 8;
98179187Sjb		break;
99179187Sjb	case 4:
100179187Sjb		ret = src[3] | ((uint64_t) src[2]) << 8;
101179187Sjb		ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
102179187Sjb		break;
103179187Sjb	case 8:
104179187Sjb		ret = src[7] | ((uint64_t) src[6]) << 8;
105179187Sjb		ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
106179187Sjb		ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
107179187Sjb		ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
108179187Sjb		break;
109179187Sjb	default:
110179187Sjb		return 0;
111179187Sjb		break;
112179187Sjb	}
113179187Sjb
114179187Sjb	*offsetp += bytes_to_read;
115179187Sjb
116179187Sjb	return ret;
117179187Sjb}
118179187Sjb
119179187Sjbstatic void
120179187Sjbdwarf_write_lsb(Elf_Data **dp, uint64_t *offsetp, uint64_t value, int bytes_to_write)
121179187Sjb{
122179187Sjb	uint8_t *dst = (uint8_t *) (*dp)->d_buf + *offsetp;
123179187Sjb
124179187Sjb	switch (bytes_to_write) {
125179187Sjb	case 8:
126179187Sjb		dst[7] = (value >> 56) & 0xff;
127179187Sjb		dst[6] = (value >> 48) & 0xff;
128179187Sjb		dst[5] = (value >> 40) & 0xff;
129179187Sjb		dst[4] = (value >> 32) & 0xff;
130179187Sjb	case 4:
131179187Sjb		dst[3] = (value >> 24) & 0xff;
132179187Sjb		dst[2] = (value >> 16) & 0xff;
133179187Sjb	case 2:
134179187Sjb		dst[1] = (value >> 8) & 0xff;
135179187Sjb	case 1:
136179187Sjb		dst[0] = value & 0xff;
137179187Sjb		break;
138179187Sjb	default:
139179187Sjb		return;
140179187Sjb		break;
141179187Sjb	}
142179187Sjb
143179187Sjb	*offsetp += bytes_to_write;
144179187Sjb}
145179187Sjb
146179187Sjbstatic void
147179187Sjbdwarf_write_msb(Elf_Data **dp, uint64_t *offsetp, uint64_t value, int bytes_to_write)
148179187Sjb{
149179187Sjb	uint8_t *dst = (uint8_t *) (*dp)->d_buf + *offsetp;
150179187Sjb
151179187Sjb	switch (bytes_to_write) {
152179187Sjb	case 8:
153179187Sjb		dst[7] = value & 0xff;
154179187Sjb		dst[6] = (value >> 8) & 0xff;
155179187Sjb		dst[5] = (value >> 16) & 0xff;
156179187Sjb		dst[4] = (value >> 24) & 0xff;
157179187Sjb		value >>= 32;
158179187Sjb	case 4:
159179187Sjb		dst[3] = value & 0xff;
160179187Sjb		dst[2] = (value >> 8) & 0xff;
161179187Sjb		value >>= 16;
162179187Sjb	case 2:
163179187Sjb		dst[1] = value & 0xff;
164179187Sjb		value >>= 8;
165179187Sjb	case 1:
166179187Sjb		dst[0] = value & 0xff;
167179187Sjb		break;
168179187Sjb	default:
169179187Sjb		return;
170179187Sjb		break;
171179187Sjb	}
172179187Sjb
173179187Sjb	*offsetp += bytes_to_write;
174179187Sjb}
175179187Sjb
176179187Sjbstatic int64_t
177179187Sjbdwarf_read_sleb128(Elf_Data **dp, uint64_t *offsetp)
178179187Sjb{
179179187Sjb	int64_t ret = 0;
180179187Sjb	uint8_t b;
181179187Sjb	int shift = 0;
182179187Sjb
183179187Sjb	uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp;
184179187Sjb
185179187Sjb	do {
186179187Sjb		b = *src++;
187179187Sjb
188179187Sjb		ret |= ((b & 0x7f) << shift);
189179187Sjb
190179187Sjb		(*offsetp)++;
191179187Sjb
192179187Sjb		shift += 7;
193179187Sjb	} while ((b & 0x80) != 0);
194179187Sjb
195252430Skaiw	if (shift < 64 && (b & 0x40) != 0)
196179187Sjb		ret |= (-1 << shift);
197179187Sjb
198179187Sjb	return ret;
199179187Sjb}
200179187Sjb
201179187Sjbstatic uint64_t
202179187Sjbdwarf_read_uleb128(Elf_Data **dp, uint64_t *offsetp)
203179187Sjb{
204179187Sjb	uint64_t ret = 0;
205179187Sjb	uint8_t b;
206179187Sjb	int shift = 0;
207179187Sjb
208179187Sjb	uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp;
209179187Sjb
210179187Sjb	do {
211179187Sjb		b = *src++;
212179187Sjb
213179187Sjb		ret |= ((b & 0x7f) << shift);
214179187Sjb
215179187Sjb		(*offsetp)++;
216179187Sjb
217179187Sjb		shift += 7;
218179187Sjb	} while ((b & 0x80) != 0);
219179187Sjb
220179187Sjb	return ret;
221179187Sjb}
222179187Sjb
223179187Sjbstatic const char *
224179187Sjbdwarf_read_string(Elf_Data **dp, uint64_t *offsetp)
225179187Sjb{
226179187Sjb	char *ret;
227179187Sjb
228179187Sjb	char *src = (char *) (*dp)->d_buf + *offsetp;
229179187Sjb
230179187Sjb	ret = src;
231179187Sjb
232179187Sjb	while (*src != '\0' && *offsetp < (*dp)->d_size) {
233179187Sjb		src++;
234179187Sjb		(*offsetp)++;
235179187Sjb	}
236179187Sjb
237179187Sjb	if (*src == '\0' && *offsetp < (*dp)->d_size)
238179187Sjb		(*offsetp)++;
239179187Sjb
240179187Sjb	return ret;
241179187Sjb}
242179187Sjb
243179187Sjbstatic uint8_t *
244179187Sjbdwarf_read_block(Elf_Data **dp, uint64_t *offsetp, uint64_t length)
245179187Sjb{
246179187Sjb	uint8_t *ret;
247179187Sjb
248179187Sjb	uint8_t *src = (char *) (*dp)->d_buf + *offsetp;
249179187Sjb
250179187Sjb	ret = src;
251179187Sjb
252179187Sjb	(*offsetp) += length;
253179187Sjb
254179187Sjb	return ret;
255179187Sjb}
256179187Sjb
257179187Sjbstatic int
258179187Sjbdwarf_apply_relocations(Dwarf_Debug dbg, Elf_Data *reld, int secindx)
259179187Sjb{
260179187Sjb	Elf_Data *d;
261179187Sjb	GElf_Rela rela;
262179187Sjb	int indx = 0;
263179187Sjb	int ret = DWARF_E_NONE;
264179187Sjb	uint64_t offset;
265179187Sjb
266179187Sjb	/* Point to the data to be relocated: */
267179187Sjb	d = dbg->dbg_s[secindx].s_data;
268179187Sjb
269179187Sjb	/* Enter a loop to process each relocation addend: */
270179187Sjb	while (gelf_getrela(reld, indx++, &rela) != NULL) {
271179187Sjb		GElf_Sym sym;
272179187Sjb		Elf64_Xword symindx = ELF64_R_SYM(rela.r_info);
273179187Sjb
274179187Sjb		if (gelf_getsym(dbg->dbg_s[DWARF_symtab].s_data, symindx, &sym) == NULL) {
275179187Sjb			printf("Couldn't find symbol index %lu for relocation\n",(u_long) symindx);
276179187Sjb			continue;
277179187Sjb		}
278179187Sjb
279179187Sjb		offset = rela.r_offset;
280179187Sjb
281179187Sjb		dwarf_write(&d, &offset, rela.r_addend, dbg->dbg_offsize);
282179187Sjb	}
283179187Sjb
284179187Sjb	return ret;
285179187Sjb}
286179187Sjb
287179187Sjbstatic int
288179187Sjbdwarf_relocate(Dwarf_Debug dbg, Dwarf_Error *error)
289179187Sjb{
290179187Sjb	Elf_Scn *scn = NULL;
291179187Sjb	GElf_Shdr shdr;
292179187Sjb	int i;
293179187Sjb	int ret = DWARF_E_NONE;
294179187Sjb
295179187Sjb	/* Look for sections which relocate the debug sections. */
296179187Sjb	while ((scn = elf_nextscn(dbg->dbg_elf, scn)) != NULL) {
297179187Sjb		if (gelf_getshdr(scn, &shdr) == NULL) {
298179187Sjb			DWARF_SET_ELF_ERROR(error, elf_errno());
299179187Sjb			return DWARF_E_ELF;
300179187Sjb		}
301179187Sjb
302179187Sjb		if (shdr.sh_type != SHT_RELA || shdr.sh_size == 0)
303179187Sjb			continue;
304179187Sjb
305179187Sjb		for (i = 0; i < DWARF_DEBUG_SNAMES; i++) {
306179187Sjb			if (dbg->dbg_s[i].s_shnum == shdr.sh_info &&
307179187Sjb			    dbg->dbg_s[DWARF_symtab].s_shnum == shdr.sh_link) {
308179187Sjb				Elf_Data *rd;
309179187Sjb
310179187Sjb				/* Get the relocation data. */
311179187Sjb				if ((rd = elf_getdata(scn, NULL)) == NULL) {
312179187Sjb					DWARF_SET_ELF_ERROR(error, elf_errno());
313179187Sjb					return DWARF_E_ELF;
314179187Sjb				}
315179187Sjb
316179187Sjb				/* Apply the relocations. */
317179187Sjb				dwarf_apply_relocations(dbg, rd, i);
318179187Sjb				break;
319179187Sjb			}
320179187Sjb		}
321179187Sjb	}
322179187Sjb
323179187Sjb	return ret;
324179187Sjb}
325179187Sjb
326179187Sjbstatic int
327179187Sjbdwarf_init_attr(Dwarf_Debug dbg, Elf_Data **dp, uint64_t *offsetp,
328179187Sjb    Dwarf_CU cu, Dwarf_Die die, Dwarf_Attribute at, uint64_t form,
329179187Sjb    Dwarf_Error *error)
330179187Sjb{
331179187Sjb	int ret = DWARF_E_NONE;
332179187Sjb	struct _Dwarf_AttrValue avref;
333179187Sjb
334179187Sjb	memset(&avref, 0, sizeof(avref));
335179187Sjb	avref.av_attrib	= at->at_attrib;
336179187Sjb	avref.av_form	= at->at_form;
337179187Sjb
338179187Sjb	switch (form) {
339179187Sjb	case DW_FORM_addr:
340179187Sjb		avref.u[0].u64 = dwarf_read(dp, offsetp, cu->cu_pointer_size);
341179187Sjb		break;
342179187Sjb	case DW_FORM_block:
343179187Sjb		avref.u[0].u64 = dwarf_read_uleb128(dp, offsetp);
344179187Sjb		avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64);
345179187Sjb		break;
346179187Sjb	case DW_FORM_block1:
347179187Sjb		avref.u[0].u64 = dwarf_read(dp, offsetp, 1);
348179187Sjb		avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64);
349179187Sjb		break;
350179187Sjb	case DW_FORM_block2:
351179187Sjb		avref.u[0].u64 = dwarf_read(dp, offsetp, 2);
352179187Sjb		avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64);
353179187Sjb		break;
354179187Sjb	case DW_FORM_block4:
355179187Sjb		avref.u[0].u64 = dwarf_read(dp, offsetp, 4);
356179187Sjb		avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64);
357179187Sjb		break;
358179187Sjb	case DW_FORM_data1:
359179187Sjb	case DW_FORM_flag:
360179187Sjb	case DW_FORM_ref1:
361179187Sjb		avref.u[0].u64 = dwarf_read(dp, offsetp, 1);
362179187Sjb		break;
363179187Sjb	case DW_FORM_data2:
364179187Sjb	case DW_FORM_ref2:
365179187Sjb		avref.u[0].u64 = dwarf_read(dp, offsetp, 2);
366179187Sjb		break;
367179187Sjb	case DW_FORM_data4:
368179187Sjb	case DW_FORM_ref4:
369179187Sjb		avref.u[0].u64 = dwarf_read(dp, offsetp, 4);
370179187Sjb		break;
371179187Sjb	case DW_FORM_data8:
372179187Sjb	case DW_FORM_ref8:
373179187Sjb		avref.u[0].u64 = dwarf_read(dp, offsetp, 8);
374179187Sjb		break;
375179187Sjb	case DW_FORM_indirect:
376179187Sjb		form = dwarf_read_uleb128(dp, offsetp);
377179187Sjb		return dwarf_init_attr(dbg, dp, offsetp, cu, die, at, form, error);
378179187Sjb	case DW_FORM_ref_addr:
379179187Sjb		if (cu->cu_version == 2)
380179187Sjb			avref.u[0].u64 = dwarf_read(dp, offsetp, cu->cu_pointer_size);
381179187Sjb		else if (cu->cu_version == 3)
382179187Sjb			avref.u[0].u64 = dwarf_read(dp, offsetp, dbg->dbg_offsize);
383179187Sjb		break;
384179187Sjb	case DW_FORM_ref_udata:
385179187Sjb	case DW_FORM_udata:
386179187Sjb		avref.u[0].u64 = dwarf_read_uleb128(dp, offsetp);
387179187Sjb		break;
388179187Sjb	case DW_FORM_sdata:
389179187Sjb		avref.u[0].s64 = dwarf_read_sleb128(dp, offsetp);
390179187Sjb		break;
391179187Sjb	case DW_FORM_string:
392179187Sjb		avref.u[0].s = dwarf_read_string(dp, offsetp);
393179187Sjb		break;
394179187Sjb	case DW_FORM_strp:
395179187Sjb		avref.u[0].u64 = dwarf_read(dp, offsetp, dbg->dbg_offsize);
396179187Sjb		avref.u[1].s = elf_strptr(dbg->dbg_elf,
397179187Sjb		    dbg->dbg_s[DWARF_debug_str].s_shnum, avref.u[0].u64);
398179187Sjb		break;
399239872Sdim	case DW_FORM_flag_present:
400239872Sdim		/* This form has no value encoded in the DIE. */
401239872Sdim		avref.u[0].u64 = 1;
402239872Sdim		break;
403179187Sjb	default:
404179187Sjb		DWARF_SET_ERROR(error, DWARF_E_NOT_IMPLEMENTED);
405179187Sjb		ret = DWARF_E_NOT_IMPLEMENTED;
406179187Sjb		break;
407179187Sjb	}
408179187Sjb
409179187Sjb	if (ret == DWARF_E_NONE)
410179187Sjb		ret = dwarf_attrval_add(die, &avref, NULL, error);
411179187Sjb
412179187Sjb	return ret;
413179187Sjb}
414179187Sjb
415179187Sjbstatic int
416179187Sjbdwarf_init_abbrev(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Error *error)
417179187Sjb{
418179187Sjb	Dwarf_Abbrev a;
419179187Sjb	Elf_Data *d;
420179187Sjb	int ret = DWARF_E_NONE;
421179187Sjb	uint64_t attr;
422179187Sjb	uint64_t entry;
423179187Sjb	uint64_t form;
424179187Sjb	uint64_t offset;
425179187Sjb	uint64_t tag;
426179187Sjb	u_int8_t children;
427179187Sjb
428179187Sjb	d = dbg->dbg_s[DWARF_debug_abbrev].s_data;
429179187Sjb
430179187Sjb	offset = cu->cu_abbrev_offset;
431179187Sjb
432179187Sjb	while (offset < d->d_size) {
433179187Sjb
434179187Sjb		entry = dwarf_read_uleb128(&d, &offset);
435179187Sjb
436179187Sjb		/* Check if this is the end of the data: */
437179187Sjb		if (entry == 0)
438179187Sjb			break;
439179187Sjb
440179187Sjb		tag = dwarf_read_uleb128(&d, &offset);
441179187Sjb
442179187Sjb		children = dwarf_read(&d, &offset, 1);
443179187Sjb
444179187Sjb		if ((ret = dwarf_abbrev_add(cu, entry, tag, children, &a, error)) != DWARF_E_NONE)
445179187Sjb			break;
446179187Sjb
447179187Sjb		do {
448179187Sjb			attr = dwarf_read_uleb128(&d, &offset);
449179187Sjb			form = dwarf_read_uleb128(&d, &offset);
450179187Sjb
451179187Sjb			if (attr != 0)
452179187Sjb				if ((ret = dwarf_attr_add(a, attr, form, NULL, error)) != DWARF_E_NONE)
453179187Sjb					return ret;
454179187Sjb		} while (attr != 0);
455179187Sjb	}
456179187Sjb
457179187Sjb	return ret;
458179187Sjb}
459179187Sjb
460179187Sjbstatic int
461179187Sjbdwarf_init_info(Dwarf_Debug dbg, Dwarf_Error *error)
462179187Sjb{
463179187Sjb	Dwarf_CU cu;
464179187Sjb	Elf_Data *d = NULL;
465179187Sjb	Elf_Scn *scn;
466179187Sjb	int i;
467179187Sjb	int level = 0;
468179187Sjb	int relocated = 0;
469179187Sjb	int ret = DWARF_E_NONE;
470179187Sjb	uint64_t length;
471179187Sjb	uint64_t next_offset;
472179187Sjb	uint64_t offset = 0;
473179187Sjb
474179187Sjb	scn = dbg->dbg_s[DWARF_debug_info].s_scn;
475179187Sjb
476179187Sjb	d = dbg->dbg_s[DWARF_debug_info].s_data;
477179187Sjb
478179187Sjb	while (offset < d->d_size) {
479179187Sjb		/* Allocate memory for the first compilation unit. */
480179187Sjb		if ((cu = calloc(sizeof(struct _Dwarf_CU), 1)) == NULL) {
481179187Sjb			DWARF_SET_ERROR(error, DWARF_E_MEMORY);
482179187Sjb			return DWARF_E_MEMORY;
483179187Sjb		}
484179187Sjb
485179187Sjb		/* Save the offet to this compilation unit: */
486179187Sjb		cu->cu_offset = offset;
487179187Sjb
488179187Sjb		length = dwarf_read(&d, &offset, 4);
489179187Sjb		if (length == 0xffffffff) {
490179187Sjb			length = dwarf_read(&d, &offset, 8);
491179187Sjb			dbg->dbg_offsize = 8;
492179187Sjb		} else
493179187Sjb			dbg->dbg_offsize = 4;
494179187Sjb
495179187Sjb		/*
496179187Sjb		 * Check if there is enough ELF data for this CU.
497179187Sjb		 * This assumes that libelf gives us the entire
498179187Sjb		 * section in one Elf_Data object.
499179187Sjb		 */
500179187Sjb		if (length > d->d_size - offset) {
501179187Sjb			free(cu);
502179187Sjb			DWARF_SET_ERROR(error, DWARF_E_INVALID_CU);
503179187Sjb			return DWARF_E_INVALID_CU;
504179187Sjb		}
505179187Sjb
506179187Sjb		/* Relocate the DWARF sections if necessary: */
507179187Sjb		if (!relocated) {
508179187Sjb			if ((ret = dwarf_relocate(dbg, error)) != DWARF_E_NONE)
509179187Sjb				return ret;
510179187Sjb			relocated = 1;
511179187Sjb		}
512179187Sjb
513179187Sjb		/* Compute the offset to the next compilation unit: */
514179187Sjb		next_offset = offset + length;
515179187Sjb
516179187Sjb		/* Initialise the compilation unit. */
517179187Sjb		cu->cu_length 		= length;
518179187Sjb		cu->cu_header_length	= (dbg->dbg_offsize == 4) ? 4 : 12;
519179187Sjb		cu->cu_version		= dwarf_read(&d, &offset, 2);
520179187Sjb		cu->cu_abbrev_offset	= dwarf_read(&d, &offset, dbg->dbg_offsize);
521179187Sjb		cu->cu_pointer_size	= dwarf_read(&d, &offset, 1);
522179187Sjb		cu->cu_next_offset	= next_offset;
523179187Sjb
524179187Sjb		/* Initialise the list of abbrevs. */
525179187Sjb		STAILQ_INIT(&cu->cu_abbrev);
526179187Sjb
527179187Sjb		/* Initialise the list of dies. */
528179187Sjb		STAILQ_INIT(&cu->cu_die);
529179187Sjb
530179187Sjb		/* Initialise the hash table of dies. */
531179187Sjb		for (i = 0; i < DWARF_DIE_HASH_SIZE; i++)
532179187Sjb			STAILQ_INIT(&cu->cu_die_hash[i]);
533179187Sjb
534179187Sjb		/* Add the compilation unit to the list. */
535179187Sjb		STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next);
536179187Sjb
537179187Sjb		if (cu->cu_version != 2 && cu->cu_version != 3) {
538179187Sjb			DWARF_SET_ERROR(error, DWARF_E_CU_VERSION);
539179187Sjb			ret = DWARF_E_CU_VERSION;
540179187Sjb			break;
541179187Sjb		}
542179187Sjb
543179187Sjb		/* Parse the .debug_abbrev info for this CU: */
544179187Sjb		if ((ret = dwarf_init_abbrev(dbg, cu, error)) != DWARF_E_NONE)
545179187Sjb			break;
546179187Sjb
547179187Sjb		level = 0;
548179187Sjb
549179187Sjb		while (offset < next_offset && offset < d->d_size) {
550179187Sjb			Dwarf_Abbrev a;
551179187Sjb			Dwarf_Attribute at;
552179187Sjb			Dwarf_Die die;
553179187Sjb			uint64_t abnum;
554241844Seadler			uint64_t die_offset = offset;
555179187Sjb
556179187Sjb			abnum = dwarf_read_uleb128(&d, &offset);
557179187Sjb
558179187Sjb			if (abnum == 0) {
559179187Sjb				level--;
560179187Sjb				continue;
561179187Sjb			}
562179187Sjb
563179187Sjb			if ((a = dwarf_abbrev_find(cu, abnum)) == NULL) {
564179187Sjb				DWARF_SET_ERROR(error, DWARF_E_MISSING_ABBREV);
565179187Sjb				return DWARF_E_MISSING_ABBREV;
566179187Sjb			}
567179187Sjb
568179187Sjb			if ((ret = dwarf_die_add(cu, level, die_offset,
569179187Sjb			    abnum, a, &die, error)) != DWARF_E_NONE)
570179187Sjb				return ret;
571179187Sjb
572179187Sjb			STAILQ_FOREACH(at, &a->a_attrib, at_next) {
573179187Sjb				if ((ret = dwarf_init_attr(dbg, &d, &offset,
574179187Sjb				    cu, die, at, at->at_form, error)) != DWARF_E_NONE)
575179187Sjb					return ret;
576179187Sjb			}
577179187Sjb
578179187Sjb			if (a->a_children == DW_CHILDREN_yes)
579179187Sjb				level++;
580179187Sjb		}
581179187Sjb
582179187Sjb		offset = next_offset;
583179187Sjb	}
584179187Sjb
585221569Sobrien	/* Build the function table. */
586221569Sobrien	dwarf_build_function_table(dbg);
587221569Sobrien
588179187Sjb	return ret;
589179187Sjb}
590179187Sjb
591179187Sjbstatic int
592179187Sjbdwarf_elf_read(Dwarf_Debug dbg, Dwarf_Error *error)
593179187Sjb{
594179187Sjb	GElf_Shdr shdr;
595179187Sjb	Elf_Scn *scn = NULL;
596179187Sjb	char *sname;
597179187Sjb	int i;
598179187Sjb	int ret = DWARF_E_NONE;
599179187Sjb
600179187Sjb	/* Get a copy of the ELF header. */
601179187Sjb	if (gelf_getehdr(dbg->dbg_elf, &dbg->dbg_ehdr) == NULL) {
602179187Sjb		DWARF_SET_ELF_ERROR(error, elf_errno());
603179187Sjb		return DWARF_E_ELF;
604179187Sjb	}
605179187Sjb
606179187Sjb	/* Check the ELF data format: */
607179187Sjb	switch (dbg->dbg_ehdr.e_ident[EI_DATA]) {
608179187Sjb	case ELFDATA2MSB:
609179187Sjb		dwarf_read = dwarf_read_msb;
610179187Sjb		dwarf_write = dwarf_write_msb;
611179187Sjb		break;
612179187Sjb
613179187Sjb	case ELFDATA2LSB:
614179187Sjb	case ELFDATANONE:
615179187Sjb	default:
616179187Sjb		dwarf_read = dwarf_read_lsb;
617179187Sjb		dwarf_write = dwarf_write_lsb;
618179187Sjb		break;
619179187Sjb	}
620179187Sjb
621179187Sjb	/* Get the section index to the string table. */
622179187Sjb	if (elf_getshstrndx(dbg->dbg_elf, &dbg->dbg_stnum) == 0) {
623179187Sjb		DWARF_SET_ELF_ERROR(error, elf_errno());
624179187Sjb		return DWARF_E_ELF;
625179187Sjb	}
626179187Sjb
627179187Sjb	/* Look for the debug sections. */
628179187Sjb	while ((scn = elf_nextscn(dbg->dbg_elf, scn)) != NULL) {
629179187Sjb		/* Get a copy of the section header: */
630179187Sjb		if (gelf_getshdr(scn, &shdr) == NULL) {
631179187Sjb			DWARF_SET_ELF_ERROR(error, elf_errno());
632179187Sjb			return DWARF_E_ELF;
633179187Sjb		}
634179187Sjb
635179187Sjb		/* Get a pointer to the section name: */
636179187Sjb		if ((sname = elf_strptr(dbg->dbg_elf, dbg->dbg_stnum, shdr.sh_name)) == NULL) {
637179187Sjb			DWARF_SET_ELF_ERROR(error, elf_errno());
638179187Sjb			return DWARF_E_ELF;
639179187Sjb		}
640179187Sjb
641179187Sjb		/*
642179187Sjb		 * Look up the section name to check if it's
643179187Sjb		 * one we need for DWARF.
644179187Sjb		 */
645179187Sjb		for (i = 0; i < DWARF_DEBUG_SNAMES; i++) {
646179187Sjb			if (strcmp(sname, debug_snames[i]) == 0) {
647179187Sjb				dbg->dbg_s[i].s_sname = sname;
648179187Sjb				dbg->dbg_s[i].s_shnum = elf_ndxscn(scn);
649179187Sjb				dbg->dbg_s[i].s_scn = scn;
650179187Sjb				memcpy(&dbg->dbg_s[i].s_shdr, &shdr, sizeof(shdr));
651179187Sjb				if ((dbg->dbg_s[i].s_data = elf_getdata(scn, NULL)) == NULL) {
652179187Sjb					DWARF_SET_ELF_ERROR(error, elf_errno());
653179187Sjb					return DWARF_E_ELF;
654179187Sjb				}
655179187Sjb				break;
656179187Sjb			}
657179187Sjb		}
658179187Sjb	}
659179187Sjb
660179187Sjb	/* Check if any of the required sections are missing: */
661179187Sjb	if (dbg->dbg_s[DWARF_debug_abbrev].s_scn == NULL ||
662179187Sjb	    dbg->dbg_s[DWARF_debug_info].s_scn == NULL) {
663179187Sjb		/* Missing debug information. */
664179187Sjb		DWARF_SET_ERROR(error, DWARF_E_DEBUG_INFO);
665179187Sjb		return DWARF_E_DEBUG_INFO;
666179187Sjb	}
667179187Sjb
668179187Sjb	/* Initialise the compilation-units: */
669179187Sjb	ret = dwarf_init_info(dbg, error);
670179187Sjb
671179187Sjb	return ret;
672179187Sjb}
673179187Sjb
674179187Sjbint
675179187Sjbdwarf_elf_init(Elf *elf, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error)
676179187Sjb{
677179187Sjb	Dwarf_Debug dbg;
678179187Sjb	int ret = DWARF_E_NONE;
679179187Sjb
680179187Sjb	if (error == NULL)
681179187Sjb		/* Can only return a generic error. */
682179187Sjb		return DWARF_E_ERROR;
683179187Sjb
684179187Sjb	if (elf == NULL || ret_dbg == NULL) {
685179187Sjb		DWARF_SET_ERROR(error, DWARF_E_ARGUMENT);
686179187Sjb		ret = DWARF_E_ARGUMENT;
687179187Sjb	} else if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) {
688179187Sjb		DWARF_SET_ERROR(error, DWARF_E_MEMORY);
689179187Sjb		ret = DWARF_E_MEMORY;
690179187Sjb	} else {
691179187Sjb		dbg->dbg_elf		= elf;
692179187Sjb		dbg->dbg_elf_close 	= 0;
693179187Sjb		dbg->dbg_mode		= mode;
694179187Sjb
695179187Sjb		STAILQ_INIT(&dbg->dbg_cu);
696221569Sobrien		STAILQ_INIT(&dbg->dbg_func);
697179187Sjb
698179187Sjb		*ret_dbg = dbg;
699179187Sjb
700179187Sjb		/* Read the ELF sections. */
701179187Sjb		ret = dwarf_elf_read(dbg, error);
702179187Sjb	}
703179187Sjb
704179187Sjb	return ret;
705179187Sjb}
706179187Sjb
707179187Sjbint
708179187Sjbdwarf_init(int fd, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error)
709179187Sjb{
710179187Sjb	Dwarf_Error lerror;
711179187Sjb	Elf *elf;
712179187Sjb	Elf_Cmd	c;
713179187Sjb	int ret;
714179187Sjb
715179187Sjb	if (error == NULL)
716179187Sjb		/* Can only return a generic error. */
717179187Sjb		return DWARF_E_ERROR;
718179187Sjb
719179187Sjb	if (fd < 0 || ret_dbg == NULL) {
720179187Sjb		DWARF_SET_ERROR(error, DWARF_E_ARGUMENT);
721179187Sjb		return DWARF_E_ERROR;
722179187Sjb	}
723179187Sjb
724179187Sjb	/* Translate the DWARF mode to ELF mode. */
725179187Sjb	switch (mode) {
726179187Sjb	default:
727179187Sjb	case DW_DLC_READ:
728179187Sjb		c = ELF_C_READ;
729179187Sjb		break;
730179187Sjb	}
731179187Sjb
732179187Sjb	if (elf_version(EV_CURRENT) == EV_NONE) {
733179187Sjb		DWARF_SET_ELF_ERROR(error, elf_errno());
734179187Sjb		return DWARF_E_ERROR;
735179187Sjb	}
736179187Sjb
737179187Sjb	if ((elf = elf_begin(fd, c, NULL)) == NULL) {
738179187Sjb		DWARF_SET_ELF_ERROR(error, elf_errno());
739179187Sjb		return DWARF_E_ERROR;
740179187Sjb	}
741179187Sjb
742179187Sjb	ret = dwarf_elf_init(elf, mode, ret_dbg, error);
743179187Sjb
744179187Sjb	if (*ret_dbg != NULL)
745179187Sjb		/* Remember to close the ELF file. */
746179187Sjb		(*ret_dbg)->dbg_elf_close = 1;
747179187Sjb
748179187Sjb	if (ret != DWARF_E_NONE) {
749179187Sjb		if (*ret_dbg != NULL) {
750179187Sjb			dwarf_finish(ret_dbg, &lerror);
751179187Sjb		} else
752179187Sjb			elf_end(elf);
753179187Sjb	}
754179187Sjb
755179187Sjb	return ret;
756179187Sjb}
757