dwarf_init.c revision 179187
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: head/lib/libdwarf/dwarf_init.c 179187 2008-05-22 02:14:23Z jb $
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 < 32 && (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	default:
400		DWARF_SET_ERROR(error, DWARF_E_NOT_IMPLEMENTED);
401		ret = DWARF_E_NOT_IMPLEMENTED;
402		break;
403	}
404
405	if (ret == DWARF_E_NONE)
406		ret = dwarf_attrval_add(die, &avref, NULL, error);
407
408	return ret;
409}
410
411static int
412dwarf_init_abbrev(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Error *error)
413{
414	Dwarf_Abbrev a;
415	Elf_Data *d;
416	int ret = DWARF_E_NONE;
417	uint64_t attr;
418	uint64_t entry;
419	uint64_t form;
420	uint64_t offset;
421	uint64_t tag;
422	u_int8_t children;
423
424	d = dbg->dbg_s[DWARF_debug_abbrev].s_data;
425
426	offset = cu->cu_abbrev_offset;
427
428	while (offset < d->d_size) {
429
430		entry = dwarf_read_uleb128(&d, &offset);
431
432		/* Check if this is the end of the data: */
433		if (entry == 0)
434			break;
435
436		tag = dwarf_read_uleb128(&d, &offset);
437
438		children = dwarf_read(&d, &offset, 1);
439
440		if ((ret = dwarf_abbrev_add(cu, entry, tag, children, &a, error)) != DWARF_E_NONE)
441			break;
442
443		do {
444			attr = dwarf_read_uleb128(&d, &offset);
445			form = dwarf_read_uleb128(&d, &offset);
446
447			if (attr != 0)
448				if ((ret = dwarf_attr_add(a, attr, form, NULL, error)) != DWARF_E_NONE)
449					return ret;
450		} while (attr != 0);
451	}
452
453	return ret;
454}
455
456static int
457dwarf_init_info(Dwarf_Debug dbg, Dwarf_Error *error)
458{
459	Dwarf_CU cu;
460	Elf_Data *d = NULL;
461	Elf_Scn *scn;
462	int i;
463	int level = 0;
464	int relocated = 0;
465	int ret = DWARF_E_NONE;
466	uint64_t length;
467	uint64_t next_offset;
468	uint64_t offset = 0;
469
470	scn = dbg->dbg_s[DWARF_debug_info].s_scn;
471
472	d = dbg->dbg_s[DWARF_debug_info].s_data;
473
474	while (offset < d->d_size) {
475		/* Allocate memory for the first compilation unit. */
476		if ((cu = calloc(sizeof(struct _Dwarf_CU), 1)) == NULL) {
477			DWARF_SET_ERROR(error, DWARF_E_MEMORY);
478			return DWARF_E_MEMORY;
479		}
480
481		/* Save the offet to this compilation unit: */
482		cu->cu_offset = offset;
483
484		length = dwarf_read(&d, &offset, 4);
485		if (length == 0xffffffff) {
486			length = dwarf_read(&d, &offset, 8);
487			dbg->dbg_offsize = 8;
488		} else
489			dbg->dbg_offsize = 4;
490
491		/*
492		 * Check if there is enough ELF data for this CU.
493		 * This assumes that libelf gives us the entire
494		 * section in one Elf_Data object.
495		 */
496		if (length > d->d_size - offset) {
497			free(cu);
498			DWARF_SET_ERROR(error, DWARF_E_INVALID_CU);
499			return DWARF_E_INVALID_CU;
500		}
501
502		/* Relocate the DWARF sections if necessary: */
503		if (!relocated) {
504			if ((ret = dwarf_relocate(dbg, error)) != DWARF_E_NONE)
505				return ret;
506			relocated = 1;
507		}
508
509		/* Compute the offset to the next compilation unit: */
510		next_offset = offset + length;
511
512		/* Initialise the compilation unit. */
513		cu->cu_length 		= length;
514		cu->cu_header_length	= (dbg->dbg_offsize == 4) ? 4 : 12;
515		cu->cu_version		= dwarf_read(&d, &offset, 2);
516		cu->cu_abbrev_offset	= dwarf_read(&d, &offset, dbg->dbg_offsize);
517		cu->cu_pointer_size	= dwarf_read(&d, &offset, 1);
518		cu->cu_next_offset	= next_offset;
519
520		/* Initialise the list of abbrevs. */
521		STAILQ_INIT(&cu->cu_abbrev);
522
523		/* Initialise the list of dies. */
524		STAILQ_INIT(&cu->cu_die);
525
526		/* Initialise the hash table of dies. */
527		for (i = 0; i < DWARF_DIE_HASH_SIZE; i++)
528			STAILQ_INIT(&cu->cu_die_hash[i]);
529
530		/* Add the compilation unit to the list. */
531		STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next);
532
533		if (cu->cu_version != 2 && cu->cu_version != 3) {
534			DWARF_SET_ERROR(error, DWARF_E_CU_VERSION);
535			ret = DWARF_E_CU_VERSION;
536			break;
537		}
538
539		/* Parse the .debug_abbrev info for this CU: */
540		if ((ret = dwarf_init_abbrev(dbg, cu, error)) != DWARF_E_NONE)
541			break;
542
543		level = 0;
544
545		while (offset < next_offset && offset < d->d_size) {
546			Dwarf_Abbrev a;
547			Dwarf_Attribute at;
548			Dwarf_Die die;
549			uint64_t abnum;
550			uint64_t die_offset = offset;;
551
552			abnum = dwarf_read_uleb128(&d, &offset);
553
554			if (abnum == 0) {
555				level--;
556				continue;
557			}
558
559			if ((a = dwarf_abbrev_find(cu, abnum)) == NULL) {
560				DWARF_SET_ERROR(error, DWARF_E_MISSING_ABBREV);
561				return DWARF_E_MISSING_ABBREV;
562			}
563
564			if ((ret = dwarf_die_add(cu, level, die_offset,
565			    abnum, a, &die, error)) != DWARF_E_NONE)
566				return ret;
567
568			STAILQ_FOREACH(at, &a->a_attrib, at_next) {
569				if ((ret = dwarf_init_attr(dbg, &d, &offset,
570				    cu, die, at, at->at_form, error)) != DWARF_E_NONE)
571					return ret;
572			}
573
574			if (a->a_children == DW_CHILDREN_yes)
575				level++;
576		}
577
578		offset = next_offset;
579	}
580
581	return ret;
582}
583
584static int
585dwarf_elf_read(Dwarf_Debug dbg, Dwarf_Error *error)
586{
587	GElf_Shdr shdr;
588	Elf_Scn *scn = NULL;
589	char *sname;
590	int i;
591	int ret = DWARF_E_NONE;
592
593	/* Get a copy of the ELF header. */
594	if (gelf_getehdr(dbg->dbg_elf, &dbg->dbg_ehdr) == NULL) {
595		DWARF_SET_ELF_ERROR(error, elf_errno());
596		return DWARF_E_ELF;
597	}
598
599	/* Check the ELF data format: */
600	switch (dbg->dbg_ehdr.e_ident[EI_DATA]) {
601	case ELFDATA2MSB:
602		dwarf_read = dwarf_read_msb;
603		dwarf_write = dwarf_write_msb;
604		break;
605
606	case ELFDATA2LSB:
607	case ELFDATANONE:
608	default:
609		dwarf_read = dwarf_read_lsb;
610		dwarf_write = dwarf_write_lsb;
611		break;
612	}
613
614	/* Get the section index to the string table. */
615	if (elf_getshstrndx(dbg->dbg_elf, &dbg->dbg_stnum) == 0) {
616		DWARF_SET_ELF_ERROR(error, elf_errno());
617		return DWARF_E_ELF;
618	}
619
620	/* Look for the debug sections. */
621	while ((scn = elf_nextscn(dbg->dbg_elf, scn)) != NULL) {
622		/* Get a copy of the section header: */
623		if (gelf_getshdr(scn, &shdr) == NULL) {
624			DWARF_SET_ELF_ERROR(error, elf_errno());
625			return DWARF_E_ELF;
626		}
627
628		/* Get a pointer to the section name: */
629		if ((sname = elf_strptr(dbg->dbg_elf, dbg->dbg_stnum, shdr.sh_name)) == NULL) {
630			DWARF_SET_ELF_ERROR(error, elf_errno());
631			return DWARF_E_ELF;
632		}
633
634		/*
635		 * Look up the section name to check if it's
636		 * one we need for DWARF.
637		 */
638		for (i = 0; i < DWARF_DEBUG_SNAMES; i++) {
639			if (strcmp(sname, debug_snames[i]) == 0) {
640				dbg->dbg_s[i].s_sname = sname;
641				dbg->dbg_s[i].s_shnum = elf_ndxscn(scn);
642				dbg->dbg_s[i].s_scn = scn;
643				memcpy(&dbg->dbg_s[i].s_shdr, &shdr, sizeof(shdr));
644				if ((dbg->dbg_s[i].s_data = elf_getdata(scn, NULL)) == NULL) {
645					DWARF_SET_ELF_ERROR(error, elf_errno());
646					return DWARF_E_ELF;
647				}
648				break;
649			}
650		}
651	}
652
653	/* Check if any of the required sections are missing: */
654	if (dbg->dbg_s[DWARF_debug_abbrev].s_scn == NULL ||
655	    dbg->dbg_s[DWARF_debug_info].s_scn == NULL) {
656		/* Missing debug information. */
657		DWARF_SET_ERROR(error, DWARF_E_DEBUG_INFO);
658		return DWARF_E_DEBUG_INFO;
659	}
660
661	/* Initialise the compilation-units: */
662	ret = dwarf_init_info(dbg, error);
663
664	return ret;
665}
666
667int
668dwarf_elf_init(Elf *elf, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error)
669{
670	Dwarf_Debug dbg;
671	int ret = DWARF_E_NONE;
672
673	if (error == NULL)
674		/* Can only return a generic error. */
675		return DWARF_E_ERROR;
676
677	if (elf == NULL || ret_dbg == NULL) {
678		DWARF_SET_ERROR(error, DWARF_E_ARGUMENT);
679		ret = DWARF_E_ARGUMENT;
680	} else if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) {
681		DWARF_SET_ERROR(error, DWARF_E_MEMORY);
682		ret = DWARF_E_MEMORY;
683	} else {
684		dbg->dbg_elf		= elf;
685		dbg->dbg_elf_close 	= 0;
686		dbg->dbg_mode		= mode;
687
688		STAILQ_INIT(&dbg->dbg_cu);
689
690		*ret_dbg = dbg;
691
692		/* Read the ELF sections. */
693		ret = dwarf_elf_read(dbg, error);
694	}
695
696	return ret;
697}
698
699int
700dwarf_init(int fd, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error)
701{
702	Dwarf_Error lerror;
703	Elf *elf;
704	Elf_Cmd	c;
705	int ret;
706
707	if (error == NULL)
708		/* Can only return a generic error. */
709		return DWARF_E_ERROR;
710
711	if (fd < 0 || ret_dbg == NULL) {
712		DWARF_SET_ERROR(error, DWARF_E_ARGUMENT);
713		return DWARF_E_ERROR;
714	}
715
716	/* Translate the DWARF mode to ELF mode. */
717	switch (mode) {
718	default:
719	case DW_DLC_READ:
720		c = ELF_C_READ;
721		break;
722	}
723
724	if (elf_version(EV_CURRENT) == EV_NONE) {
725		DWARF_SET_ELF_ERROR(error, elf_errno());
726		return DWARF_E_ERROR;
727	}
728
729	if ((elf = elf_begin(fd, c, NULL)) == NULL) {
730		DWARF_SET_ELF_ERROR(error, elf_errno());
731		return DWARF_E_ERROR;
732	}
733
734	ret = dwarf_elf_init(elf, mode, ret_dbg, error);
735
736	if (*ret_dbg != NULL)
737		/* Remember to close the ELF file. */
738		(*ret_dbg)->dbg_elf_close = 1;
739
740	if (ret != DWARF_E_NONE) {
741		if (*ret_dbg != NULL) {
742			dwarf_finish(ret_dbg, &lerror);
743		} else
744			elf_end(elf);
745	}
746
747	return ret;
748}
749