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#include <stdlib.h>
30#include <string.h>
31#include "_libdwarf.h"
32
33static const char *debug_snames[DWARF_DEBUG_SNAMES] = {
34	".debug_abbrev",
35	".debug_aranges",
36	".debug_frame",
37	".debug_info",
38	".debug_line",
39	".debug_pubnames",
40	".eh_frame",
41	".debug_macinfo",
42	".debug_str",
43	".debug_loc",
44	".debug_pubtypes",
45	".debug_ranges",
46	".debug_static_func",
47	".debug_static_vars",
48	".debug_types",
49	".debug_weaknames",
50	".symtab",
51	".strtab"
52};
53
54static uint64_t (*dwarf_read) (Elf_Data **, uint64_t *, int);
55static void (*dwarf_write) (Elf_Data **, uint64_t *, uint64_t, int);
56
57static uint64_t
58dwarf_read_lsb(Elf_Data **dp, uint64_t *offsetp, int bytes_to_read)
59{
60	uint64_t ret = 0;
61
62	uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp;
63
64	switch (bytes_to_read) {
65	case 8:
66		ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
67		ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
68	case 4:
69		ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
70	case 2:
71		ret |= ((uint64_t) src[1]) << 8;
72	case 1:
73		ret |= src[0];
74		break;
75	default:
76		return 0;
77		break;
78	}
79
80	*offsetp += bytes_to_read;
81
82	return ret;
83}
84
85static uint64_t
86dwarf_read_msb(Elf_Data **dp, uint64_t *offsetp, int bytes_to_read)
87{
88	uint64_t ret = 0;
89
90	uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp;
91
92	switch (bytes_to_read) {
93	case 1:
94		ret = src[0];
95		break;
96	case 2:
97		ret = src[1] | ((uint64_t) src[0]) << 8;
98		break;
99	case 4:
100		ret = src[3] | ((uint64_t) src[2]) << 8;
101		ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
102		break;
103	case 8:
104		ret = src[7] | ((uint64_t) src[6]) << 8;
105		ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
106		ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
107		ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
108		break;
109	default:
110		return 0;
111		break;
112	}
113
114	*offsetp += bytes_to_read;
115
116	return ret;
117}
118
119static void
120dwarf_write_lsb(Elf_Data **dp, uint64_t *offsetp, uint64_t value, int bytes_to_write)
121{
122	uint8_t *dst = (uint8_t *) (*dp)->d_buf + *offsetp;
123
124	switch (bytes_to_write) {
125	case 8:
126		dst[7] = (value >> 56) & 0xff;
127		dst[6] = (value >> 48) & 0xff;
128		dst[5] = (value >> 40) & 0xff;
129		dst[4] = (value >> 32) & 0xff;
130	case 4:
131		dst[3] = (value >> 24) & 0xff;
132		dst[2] = (value >> 16) & 0xff;
133	case 2:
134		dst[1] = (value >> 8) & 0xff;
135	case 1:
136		dst[0] = value & 0xff;
137		break;
138	default:
139		return;
140		break;
141	}
142
143	*offsetp += bytes_to_write;
144}
145
146static void
147dwarf_write_msb(Elf_Data **dp, uint64_t *offsetp, uint64_t value, int bytes_to_write)
148{
149	uint8_t *dst = (uint8_t *) (*dp)->d_buf + *offsetp;
150
151	switch (bytes_to_write) {
152	case 8:
153		dst[7] = value & 0xff;
154		dst[6] = (value >> 8) & 0xff;
155		dst[5] = (value >> 16) & 0xff;
156		dst[4] = (value >> 24) & 0xff;
157		value >>= 32;
158	case 4:
159		dst[3] = value & 0xff;
160		dst[2] = (value >> 8) & 0xff;
161		value >>= 16;
162	case 2:
163		dst[1] = value & 0xff;
164		value >>= 8;
165	case 1:
166		dst[0] = value & 0xff;
167		break;
168	default:
169		return;
170		break;
171	}
172
173	*offsetp += bytes_to_write;
174}
175
176static int64_t
177dwarf_read_sleb128(Elf_Data **dp, uint64_t *offsetp)
178{
179	int64_t ret = 0;
180	uint8_t b;
181	int shift = 0;
182
183	uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp;
184
185	do {
186		b = *src++;
187
188		ret |= ((b & 0x7f) << shift);
189
190		(*offsetp)++;
191
192		shift += 7;
193	} while ((b & 0x80) != 0);
194
195	if (shift < 64 && (b & 0x40) != 0)
196		ret |= (-1 << shift);
197
198	return ret;
199}
200
201static uint64_t
202dwarf_read_uleb128(Elf_Data **dp, uint64_t *offsetp)
203{
204	uint64_t ret = 0;
205	uint8_t b;
206	int shift = 0;
207
208	uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp;
209
210	do {
211		b = *src++;
212
213		ret |= ((b & 0x7f) << shift);
214
215		(*offsetp)++;
216
217		shift += 7;
218	} while ((b & 0x80) != 0);
219
220	return ret;
221}
222
223static const char *
224dwarf_read_string(Elf_Data **dp, uint64_t *offsetp)
225{
226	char *ret;
227
228	char *src = (char *) (*dp)->d_buf + *offsetp;
229
230	ret = src;
231
232	while (*src != '\0' && *offsetp < (*dp)->d_size) {
233		src++;
234		(*offsetp)++;
235	}
236
237	if (*src == '\0' && *offsetp < (*dp)->d_size)
238		(*offsetp)++;
239
240	return ret;
241}
242
243static uint8_t *
244dwarf_read_block(Elf_Data **dp, uint64_t *offsetp, uint64_t length)
245{
246	uint8_t *ret;
247
248	uint8_t *src = (char *) (*dp)->d_buf + *offsetp;
249
250	ret = src;
251
252	(*offsetp) += length;
253
254	return ret;
255}
256
257static int
258dwarf_apply_relocations(Dwarf_Debug dbg, Elf_Data *reld, int secindx)
259{
260	Elf_Data *d;
261	GElf_Rela rela;
262	int indx = 0;
263	int ret = DWARF_E_NONE;
264	uint64_t offset;
265
266	/* Point to the data to be relocated: */
267	d = dbg->dbg_s[secindx].s_data;
268
269	/* Enter a loop to process each relocation addend: */
270	while (gelf_getrela(reld, indx++, &rela) != NULL) {
271		GElf_Sym sym;
272		Elf64_Xword symindx = ELF64_R_SYM(rela.r_info);
273
274		if (gelf_getsym(dbg->dbg_s[DWARF_symtab].s_data, symindx, &sym) == NULL) {
275			printf("Couldn't find symbol index %lu for relocation\n",(u_long) symindx);
276			continue;
277		}
278
279		offset = rela.r_offset;
280
281		dwarf_write(&d, &offset, rela.r_addend, dbg->dbg_offsize);
282	}
283
284	return ret;
285}
286
287static int
288dwarf_relocate(Dwarf_Debug dbg, Dwarf_Error *error)
289{
290	Elf_Scn *scn = NULL;
291	GElf_Shdr shdr;
292	int i;
293	int ret = DWARF_E_NONE;
294
295	/* Look for sections which relocate the debug sections. */
296	while ((scn = elf_nextscn(dbg->dbg_elf, scn)) != NULL) {
297		if (gelf_getshdr(scn, &shdr) == NULL) {
298			DWARF_SET_ELF_ERROR(error, elf_errno());
299			return DWARF_E_ELF;
300		}
301
302		if (shdr.sh_type != SHT_RELA || shdr.sh_size == 0)
303			continue;
304
305		for (i = 0; i < DWARF_DEBUG_SNAMES; i++) {
306			if (dbg->dbg_s[i].s_shnum == shdr.sh_info &&
307			    dbg->dbg_s[DWARF_symtab].s_shnum == shdr.sh_link) {
308				Elf_Data *rd;
309
310				/* Get the relocation data. */
311				if ((rd = elf_getdata(scn, NULL)) == NULL) {
312					DWARF_SET_ELF_ERROR(error, elf_errno());
313					return DWARF_E_ELF;
314				}
315
316				/* Apply the relocations. */
317				dwarf_apply_relocations(dbg, rd, i);
318				break;
319			}
320		}
321	}
322
323	return ret;
324}
325
326static int
327dwarf_init_attr(Dwarf_Debug dbg, Elf_Data **dp, uint64_t *offsetp,
328    Dwarf_CU cu, Dwarf_Die die, Dwarf_Attribute at, uint64_t form,
329    Dwarf_Error *error)
330{
331	int ret = DWARF_E_NONE;
332	struct _Dwarf_AttrValue avref;
333
334	memset(&avref, 0, sizeof(avref));
335	avref.av_attrib	= at->at_attrib;
336	avref.av_form	= at->at_form;
337
338	switch (form) {
339	case DW_FORM_addr:
340		avref.u[0].u64 = dwarf_read(dp, offsetp, cu->cu_pointer_size);
341		break;
342	case DW_FORM_block:
343		avref.u[0].u64 = dwarf_read_uleb128(dp, offsetp);
344		avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64);
345		break;
346	case DW_FORM_block1:
347		avref.u[0].u64 = dwarf_read(dp, offsetp, 1);
348		avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64);
349		break;
350	case DW_FORM_block2:
351		avref.u[0].u64 = dwarf_read(dp, offsetp, 2);
352		avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64);
353		break;
354	case DW_FORM_block4:
355		avref.u[0].u64 = dwarf_read(dp, offsetp, 4);
356		avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64);
357		break;
358	case DW_FORM_data1:
359	case DW_FORM_flag:
360	case DW_FORM_ref1:
361		avref.u[0].u64 = dwarf_read(dp, offsetp, 1);
362		break;
363	case DW_FORM_data2:
364	case DW_FORM_ref2:
365		avref.u[0].u64 = dwarf_read(dp, offsetp, 2);
366		break;
367	case DW_FORM_data4:
368	case DW_FORM_ref4:
369		avref.u[0].u64 = dwarf_read(dp, offsetp, 4);
370		break;
371	case DW_FORM_data8:
372	case DW_FORM_ref8:
373		avref.u[0].u64 = dwarf_read(dp, offsetp, 8);
374		break;
375	case DW_FORM_indirect:
376		form = dwarf_read_uleb128(dp, offsetp);
377		return dwarf_init_attr(dbg, dp, offsetp, cu, die, at, form, error);
378	case DW_FORM_ref_addr:
379		if (cu->cu_version == 2)
380			avref.u[0].u64 = dwarf_read(dp, offsetp, cu->cu_pointer_size);
381		else if (cu->cu_version == 3)
382			avref.u[0].u64 = dwarf_read(dp, offsetp, dbg->dbg_offsize);
383		break;
384	case DW_FORM_ref_udata:
385	case DW_FORM_udata:
386		avref.u[0].u64 = dwarf_read_uleb128(dp, offsetp);
387		break;
388	case DW_FORM_sdata:
389		avref.u[0].s64 = dwarf_read_sleb128(dp, offsetp);
390		break;
391	case DW_FORM_string:
392		avref.u[0].s = dwarf_read_string(dp, offsetp);
393		break;
394	case DW_FORM_strp:
395		avref.u[0].u64 = dwarf_read(dp, offsetp, dbg->dbg_offsize);
396		avref.u[1].s = elf_strptr(dbg->dbg_elf,
397		    dbg->dbg_s[DWARF_debug_str].s_shnum, avref.u[0].u64);
398		break;
399	case DW_FORM_flag_present:
400		/* This form has no value encoded in the DIE. */
401		avref.u[0].u64 = 1;
402		break;
403	default:
404		DWARF_SET_ERROR(error, DWARF_E_NOT_IMPLEMENTED);
405		ret = DWARF_E_NOT_IMPLEMENTED;
406		break;
407	}
408
409	if (ret == DWARF_E_NONE)
410		ret = dwarf_attrval_add(die, &avref, NULL, error);
411
412	return ret;
413}
414
415static int
416dwarf_init_abbrev(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Error *error)
417{
418	Dwarf_Abbrev a;
419	Elf_Data *d;
420	int ret = DWARF_E_NONE;
421	uint64_t attr;
422	uint64_t entry;
423	uint64_t form;
424	uint64_t offset;
425	uint64_t tag;
426	u_int8_t children;
427
428	d = dbg->dbg_s[DWARF_debug_abbrev].s_data;
429
430	offset = cu->cu_abbrev_offset;
431
432	while (offset < d->d_size) {
433
434		entry = dwarf_read_uleb128(&d, &offset);
435
436		/* Check if this is the end of the data: */
437		if (entry == 0)
438			break;
439
440		tag = dwarf_read_uleb128(&d, &offset);
441
442		children = dwarf_read(&d, &offset, 1);
443
444		if ((ret = dwarf_abbrev_add(cu, entry, tag, children, &a, error)) != DWARF_E_NONE)
445			break;
446
447		do {
448			attr = dwarf_read_uleb128(&d, &offset);
449			form = dwarf_read_uleb128(&d, &offset);
450
451			if (attr != 0)
452				if ((ret = dwarf_attr_add(a, attr, form, NULL, error)) != DWARF_E_NONE)
453					return ret;
454		} while (attr != 0);
455	}
456
457	return ret;
458}
459
460static int
461dwarf_init_info(Dwarf_Debug dbg, Dwarf_Error *error)
462{
463	Dwarf_CU cu;
464	Elf_Data *d = NULL;
465	Elf_Scn *scn;
466	int i;
467	int level = 0;
468	int relocated = 0;
469	int ret = DWARF_E_NONE;
470	uint64_t length;
471	uint64_t next_offset;
472	uint64_t offset = 0;
473
474	scn = dbg->dbg_s[DWARF_debug_info].s_scn;
475
476	d = dbg->dbg_s[DWARF_debug_info].s_data;
477
478	while (offset < d->d_size) {
479		/* Allocate memory for the first compilation unit. */
480		if ((cu = calloc(sizeof(struct _Dwarf_CU), 1)) == NULL) {
481			DWARF_SET_ERROR(error, DWARF_E_MEMORY);
482			return DWARF_E_MEMORY;
483		}
484
485		/* Save the offet to this compilation unit: */
486		cu->cu_offset = offset;
487
488		length = dwarf_read(&d, &offset, 4);
489		if (length == 0xffffffff) {
490			length = dwarf_read(&d, &offset, 8);
491			dbg->dbg_offsize = 8;
492		} else
493			dbg->dbg_offsize = 4;
494
495		/*
496		 * Check if there is enough ELF data for this CU.
497		 * This assumes that libelf gives us the entire
498		 * section in one Elf_Data object.
499		 */
500		if (length > d->d_size - offset) {
501			free(cu);
502			DWARF_SET_ERROR(error, DWARF_E_INVALID_CU);
503			return DWARF_E_INVALID_CU;
504		}
505
506		/* Relocate the DWARF sections if necessary: */
507		if (!relocated) {
508			if ((ret = dwarf_relocate(dbg, error)) != DWARF_E_NONE)
509				return ret;
510			relocated = 1;
511		}
512
513		/* Compute the offset to the next compilation unit: */
514		next_offset = offset + length;
515
516		/* Initialise the compilation unit. */
517		cu->cu_length 		= length;
518		cu->cu_header_length	= (dbg->dbg_offsize == 4) ? 4 : 12;
519		cu->cu_version		= dwarf_read(&d, &offset, 2);
520		cu->cu_abbrev_offset	= dwarf_read(&d, &offset, dbg->dbg_offsize);
521		cu->cu_pointer_size	= dwarf_read(&d, &offset, 1);
522		cu->cu_next_offset	= next_offset;
523
524		/* Initialise the list of abbrevs. */
525		STAILQ_INIT(&cu->cu_abbrev);
526
527		/* Initialise the list of dies. */
528		STAILQ_INIT(&cu->cu_die);
529
530		/* Initialise the hash table of dies. */
531		for (i = 0; i < DWARF_DIE_HASH_SIZE; i++)
532			STAILQ_INIT(&cu->cu_die_hash[i]);
533
534		/* Add the compilation unit to the list. */
535		STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next);
536
537		if (cu->cu_version != 2 && cu->cu_version != 3) {
538			DWARF_SET_ERROR(error, DWARF_E_CU_VERSION);
539			ret = DWARF_E_CU_VERSION;
540			break;
541		}
542
543		/* Parse the .debug_abbrev info for this CU: */
544		if ((ret = dwarf_init_abbrev(dbg, cu, error)) != DWARF_E_NONE)
545			break;
546
547		level = 0;
548
549		while (offset < next_offset && offset < d->d_size) {
550			Dwarf_Abbrev a;
551			Dwarf_Attribute at;
552			Dwarf_Die die;
553			uint64_t abnum;
554			uint64_t die_offset = offset;
555
556			abnum = dwarf_read_uleb128(&d, &offset);
557
558			if (abnum == 0) {
559				level--;
560				continue;
561			}
562
563			if ((a = dwarf_abbrev_find(cu, abnum)) == NULL) {
564				DWARF_SET_ERROR(error, DWARF_E_MISSING_ABBREV);
565				return DWARF_E_MISSING_ABBREV;
566			}
567
568			if ((ret = dwarf_die_add(cu, level, die_offset,
569			    abnum, a, &die, error)) != DWARF_E_NONE)
570				return ret;
571
572			STAILQ_FOREACH(at, &a->a_attrib, at_next) {
573				if ((ret = dwarf_init_attr(dbg, &d, &offset,
574				    cu, die, at, at->at_form, error)) != DWARF_E_NONE)
575					return ret;
576			}
577
578			if (a->a_children == DW_CHILDREN_yes)
579				level++;
580		}
581
582		offset = next_offset;
583	}
584
585	/* Build the function table. */
586	dwarf_build_function_table(dbg);
587
588	return ret;
589}
590
591static int
592dwarf_elf_read(Dwarf_Debug dbg, Dwarf_Error *error)
593{
594	GElf_Shdr shdr;
595	Elf_Scn *scn = NULL;
596	char *sname;
597	int i;
598	int ret = DWARF_E_NONE;
599
600	/* Get a copy of the ELF header. */
601	if (gelf_getehdr(dbg->dbg_elf, &dbg->dbg_ehdr) == NULL) {
602		DWARF_SET_ELF_ERROR(error, elf_errno());
603		return DWARF_E_ELF;
604	}
605
606	/* Check the ELF data format: */
607	switch (dbg->dbg_ehdr.e_ident[EI_DATA]) {
608	case ELFDATA2MSB:
609		dwarf_read = dwarf_read_msb;
610		dwarf_write = dwarf_write_msb;
611		break;
612
613	case ELFDATA2LSB:
614	case ELFDATANONE:
615	default:
616		dwarf_read = dwarf_read_lsb;
617		dwarf_write = dwarf_write_lsb;
618		break;
619	}
620
621	/* Get the section index to the string table. */
622	if (elf_getshstrndx(dbg->dbg_elf, &dbg->dbg_stnum) == 0) {
623		DWARF_SET_ELF_ERROR(error, elf_errno());
624		return DWARF_E_ELF;
625	}
626
627	/* Look for the debug sections. */
628	while ((scn = elf_nextscn(dbg->dbg_elf, scn)) != NULL) {
629		/* Get a copy of the section header: */
630		if (gelf_getshdr(scn, &shdr) == NULL) {
631			DWARF_SET_ELF_ERROR(error, elf_errno());
632			return DWARF_E_ELF;
633		}
634
635		/* Get a pointer to the section name: */
636		if ((sname = elf_strptr(dbg->dbg_elf, dbg->dbg_stnum, shdr.sh_name)) == NULL) {
637			DWARF_SET_ELF_ERROR(error, elf_errno());
638			return DWARF_E_ELF;
639		}
640
641		/*
642		 * Look up the section name to check if it's
643		 * one we need for DWARF.
644		 */
645		for (i = 0; i < DWARF_DEBUG_SNAMES; i++) {
646			if (strcmp(sname, debug_snames[i]) == 0) {
647				dbg->dbg_s[i].s_sname = sname;
648				dbg->dbg_s[i].s_shnum = elf_ndxscn(scn);
649				dbg->dbg_s[i].s_scn = scn;
650				memcpy(&dbg->dbg_s[i].s_shdr, &shdr, sizeof(shdr));
651				if ((dbg->dbg_s[i].s_data = elf_getdata(scn, NULL)) == NULL) {
652					DWARF_SET_ELF_ERROR(error, elf_errno());
653					return DWARF_E_ELF;
654				}
655				break;
656			}
657		}
658	}
659
660	/* Check if any of the required sections are missing: */
661	if (dbg->dbg_s[DWARF_debug_abbrev].s_scn == NULL ||
662	    dbg->dbg_s[DWARF_debug_info].s_scn == NULL) {
663		/* Missing debug information. */
664		DWARF_SET_ERROR(error, DWARF_E_DEBUG_INFO);
665		return DWARF_E_DEBUG_INFO;
666	}
667
668	/* Initialise the compilation-units: */
669	ret = dwarf_init_info(dbg, error);
670
671	return ret;
672}
673
674int
675dwarf_elf_init(Elf *elf, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error)
676{
677	Dwarf_Debug dbg;
678	int ret = DWARF_E_NONE;
679
680	if (error == NULL)
681		/* Can only return a generic error. */
682		return DWARF_E_ERROR;
683
684	if (elf == NULL || ret_dbg == NULL) {
685		DWARF_SET_ERROR(error, DWARF_E_ARGUMENT);
686		ret = DWARF_E_ARGUMENT;
687	} else if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) {
688		DWARF_SET_ERROR(error, DWARF_E_MEMORY);
689		ret = DWARF_E_MEMORY;
690	} else {
691		dbg->dbg_elf		= elf;
692		dbg->dbg_elf_close 	= 0;
693		dbg->dbg_mode		= mode;
694
695		STAILQ_INIT(&dbg->dbg_cu);
696		STAILQ_INIT(&dbg->dbg_func);
697
698		*ret_dbg = dbg;
699
700		/* Read the ELF sections. */
701		ret = dwarf_elf_read(dbg, error);
702	}
703
704	return ret;
705}
706
707int
708dwarf_init(int fd, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error)
709{
710	Dwarf_Error lerror;
711	Elf *elf;
712	Elf_Cmd	c;
713	int ret;
714
715	if (error == NULL)
716		/* Can only return a generic error. */
717		return DWARF_E_ERROR;
718
719	if (fd < 0 || ret_dbg == NULL) {
720		DWARF_SET_ERROR(error, DWARF_E_ARGUMENT);
721		return DWARF_E_ERROR;
722	}
723
724	/* Translate the DWARF mode to ELF mode. */
725	switch (mode) {
726	default:
727	case DW_DLC_READ:
728		c = ELF_C_READ;
729		break;
730	}
731
732	if (elf_version(EV_CURRENT) == EV_NONE) {
733		DWARF_SET_ELF_ERROR(error, elf_errno());
734		return DWARF_E_ERROR;
735	}
736
737	if ((elf = elf_begin(fd, c, NULL)) == NULL) {
738		DWARF_SET_ELF_ERROR(error, elf_errno());
739		return DWARF_E_ERROR;
740	}
741
742	ret = dwarf_elf_init(elf, mode, ret_dbg, error);
743
744	if (*ret_dbg != NULL)
745		/* Remember to close the ELF file. */
746		(*ret_dbg)->dbg_elf_close = 1;
747
748	if (ret != DWARF_E_NONE) {
749		if (*ret_dbg != NULL) {
750			dwarf_finish(ret_dbg, &lerror);
751		} else
752			elf_end(elf);
753	}
754
755	return ret;
756}
757