Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / libdwarf / dist / dwarf_init.c
blob79d9609177424d67a65b3aaaf60a6234076df597
1 /* $NetBSD: dwarf_init.c,v 1.1.1.1 2009/12/23 00:03:22 darran Exp $ */
3 /*-
4 * Copyright (c) 2007 John Birrell (jb@freebsd.org)
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
28 * $FreeBSD: src/lib/libdwarf/dwarf_init.c,v 1.1.4.1 2009/08/03 08:13:06 kensmith Exp $
31 #include <stdlib.h>
32 #include <string.h>
33 #include "_libdwarf.h"
35 static const char *debug_snames[DWARF_DEBUG_SNAMES] = {
36 ".debug_abbrev",
37 ".debug_aranges",
38 ".debug_frame",
39 ".debug_info",
40 ".debug_line",
41 ".debug_pubnames",
42 ".eh_frame",
43 ".debug_macinfo",
44 ".debug_str",
45 ".debug_loc",
46 ".debug_pubtypes",
47 ".debug_ranges",
48 ".debug_static_func",
49 ".debug_static_vars",
50 ".debug_types",
51 ".debug_weaknames",
52 ".symtab",
53 ".strtab"
56 static uint64_t (*dwarf_read) (Elf_Data **, uint64_t *, int);
57 static void (*dwarf_write) (Elf_Data **, uint64_t *, uint64_t, int);
59 static uint64_t
60 dwarf_read_lsb(Elf_Data **dp, uint64_t *offsetp, int bytes_to_read)
62 uint64_t ret = 0;
64 uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp;
66 switch (bytes_to_read) {
67 case 8:
68 ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40;
69 ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56;
70 case 4:
71 ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24;
72 case 2:
73 ret |= ((uint64_t) src[1]) << 8;
74 case 1:
75 ret |= src[0];
76 break;
77 default:
78 return 0;
79 break;
82 *offsetp += bytes_to_read;
84 return ret;
87 static uint64_t
88 dwarf_read_msb(Elf_Data **dp, uint64_t *offsetp, int bytes_to_read)
90 uint64_t ret = 0;
92 uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp;
94 switch (bytes_to_read) {
95 case 1:
96 ret = src[0];
97 break;
98 case 2:
99 ret = src[1] | ((uint64_t) src[0]) << 8;
100 break;
101 case 4:
102 ret = src[3] | ((uint64_t) src[2]) << 8;
103 ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24;
104 break;
105 case 8:
106 ret = src[7] | ((uint64_t) src[6]) << 8;
107 ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24;
108 ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40;
109 ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56;
110 break;
111 default:
112 return 0;
113 break;
116 *offsetp += bytes_to_read;
118 return ret;
121 static void
122 dwarf_write_lsb(Elf_Data **dp, uint64_t *offsetp, uint64_t value, int bytes_to_write)
124 uint8_t *dst = (uint8_t *) (*dp)->d_buf + *offsetp;
126 switch (bytes_to_write) {
127 case 8:
128 dst[7] = (value >> 56) & 0xff;
129 dst[6] = (value >> 48) & 0xff;
130 dst[5] = (value >> 40) & 0xff;
131 dst[4] = (value >> 32) & 0xff;
132 case 4:
133 dst[3] = (value >> 24) & 0xff;
134 dst[2] = (value >> 16) & 0xff;
135 case 2:
136 dst[1] = (value >> 8) & 0xff;
137 case 1:
138 dst[0] = value & 0xff;
139 break;
140 default:
141 return;
142 break;
145 *offsetp += bytes_to_write;
148 static void
149 dwarf_write_msb(Elf_Data **dp, uint64_t *offsetp, uint64_t value, int bytes_to_write)
151 uint8_t *dst = (uint8_t *) (*dp)->d_buf + *offsetp;
153 switch (bytes_to_write) {
154 case 8:
155 dst[7] = value & 0xff;
156 dst[6] = (value >> 8) & 0xff;
157 dst[5] = (value >> 16) & 0xff;
158 dst[4] = (value >> 24) & 0xff;
159 value >>= 32;
160 case 4:
161 dst[3] = value & 0xff;
162 dst[2] = (value >> 8) & 0xff;
163 value >>= 16;
164 case 2:
165 dst[1] = value & 0xff;
166 value >>= 8;
167 case 1:
168 dst[0] = value & 0xff;
169 break;
170 default:
171 return;
172 break;
175 *offsetp += bytes_to_write;
178 static int64_t
179 dwarf_read_sleb128(Elf_Data **dp, uint64_t *offsetp)
181 int64_t ret = 0;
182 uint8_t b;
183 int shift = 0;
185 uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp;
187 do {
188 b = *src++;
190 ret |= ((b & 0x7f) << shift);
192 (*offsetp)++;
194 shift += 7;
195 } while ((b & 0x80) != 0);
197 if (shift < 32 && (b & 0x40) != 0)
198 ret |= (-1 << shift);
200 return ret;
203 static uint64_t
204 dwarf_read_uleb128(Elf_Data **dp, uint64_t *offsetp)
206 uint64_t ret = 0;
207 uint8_t b;
208 int shift = 0;
210 uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp;
212 do {
213 b = *src++;
215 ret |= ((b & 0x7f) << shift);
217 (*offsetp)++;
219 shift += 7;
220 } while ((b & 0x80) != 0);
222 return ret;
225 static const char *
226 dwarf_read_string(Elf_Data **dp, uint64_t *offsetp)
228 char *ret;
230 char *src = (char *) (*dp)->d_buf + *offsetp;
232 ret = src;
234 while (*src != '\0' && *offsetp < (*dp)->d_size) {
235 src++;
236 (*offsetp)++;
239 if (*src == '\0' && *offsetp < (*dp)->d_size)
240 (*offsetp)++;
242 return ret;
245 static uint8_t *
246 dwarf_read_block(Elf_Data **dp, uint64_t *offsetp, uint64_t length)
248 uint8_t *ret;
250 uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp;
252 ret = src;
254 (*offsetp) += length;
256 return ret;
259 static int
260 dwarf_apply_relocations(Dwarf_Debug dbg, Elf_Data *reld, int secindx)
262 Elf_Data *d;
263 GElf_Rela rela;
264 int indx = 0;
265 int ret = DWARF_E_NONE;
266 uint64_t offset;
268 /* Point to the data to be relocated: */
269 d = dbg->dbg_s[secindx].s_data;
271 /* Enter a loop to process each relocation addend: */
272 while (gelf_getrela(reld, indx++, &rela) != NULL) {
273 GElf_Sym sym;
274 Elf64_Xword symindx = ELF64_R_SYM(rela.r_info);
276 if (gelf_getsym(dbg->dbg_s[DWARF_symtab].s_data, symindx, &sym) == NULL) {
277 printf("Couldn't find symbol index %lu for relocation\n",(u_long) symindx);
278 continue;
281 offset = rela.r_offset;
283 dwarf_write(&d, &offset, rela.r_addend, dbg->dbg_offsize);
286 return ret;
289 static int
290 dwarf_relocate(Dwarf_Debug dbg, Dwarf_Error *error)
292 Elf_Scn *scn = NULL;
293 GElf_Shdr shdr;
294 int i;
295 int ret = DWARF_E_NONE;
297 /* Look for sections which relocate the debug sections. */
298 while ((scn = elf_nextscn(dbg->dbg_elf, scn)) != NULL) {
299 if (gelf_getshdr(scn, &shdr) == NULL) {
300 DWARF_SET_ELF_ERROR(error, elf_errno());
301 return DWARF_E_ELF;
304 if (shdr.sh_type != SHT_RELA || shdr.sh_size == 0)
305 continue;
307 for (i = 0; i < DWARF_DEBUG_SNAMES; i++) {
308 if (dbg->dbg_s[i].s_shnum == shdr.sh_info &&
309 dbg->dbg_s[DWARF_symtab].s_shnum == shdr.sh_link) {
310 Elf_Data *rd;
312 /* Get the relocation data. */
313 if ((rd = elf_getdata(scn, NULL)) == NULL) {
314 DWARF_SET_ELF_ERROR(error, elf_errno());
315 return DWARF_E_ELF;
318 /* Apply the relocations. */
319 dwarf_apply_relocations(dbg, rd, i);
320 break;
325 return ret;
328 static int
329 dwarf_init_attr(Dwarf_Debug dbg, Elf_Data **dp, uint64_t *offsetp,
330 Dwarf_CU cu, Dwarf_Die die, Dwarf_Attribute at, uint64_t form,
331 Dwarf_Error *error)
333 int ret = DWARF_E_NONE;
334 struct _Dwarf_AttrValue avref;
336 memset(&avref, 0, sizeof(avref));
337 avref.av_attrib = at->at_attrib;
338 avref.av_form = at->at_form;
340 switch (form) {
341 case DW_FORM_addr:
342 avref.u[0].u64 = dwarf_read(dp, offsetp, cu->cu_pointer_size);
343 break;
344 case DW_FORM_block:
345 avref.u[0].u64 = dwarf_read_uleb128(dp, offsetp);
346 avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64);
347 break;
348 case DW_FORM_block1:
349 avref.u[0].u64 = dwarf_read(dp, offsetp, 1);
350 avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64);
351 break;
352 case DW_FORM_block2:
353 avref.u[0].u64 = dwarf_read(dp, offsetp, 2);
354 avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64);
355 break;
356 case DW_FORM_block4:
357 avref.u[0].u64 = dwarf_read(dp, offsetp, 4);
358 avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64);
359 break;
360 case DW_FORM_data1:
361 case DW_FORM_flag:
362 case DW_FORM_ref1:
363 avref.u[0].u64 = dwarf_read(dp, offsetp, 1);
364 break;
365 case DW_FORM_data2:
366 case DW_FORM_ref2:
367 avref.u[0].u64 = dwarf_read(dp, offsetp, 2);
368 break;
369 case DW_FORM_data4:
370 case DW_FORM_ref4:
371 avref.u[0].u64 = dwarf_read(dp, offsetp, 4);
372 break;
373 case DW_FORM_data8:
374 case DW_FORM_ref8:
375 avref.u[0].u64 = dwarf_read(dp, offsetp, 8);
376 break;
377 case DW_FORM_indirect:
378 form = dwarf_read_uleb128(dp, offsetp);
379 return dwarf_init_attr(dbg, dp, offsetp, cu, die, at, form, error);
380 case DW_FORM_ref_addr:
381 if (cu->cu_version == 2)
382 avref.u[0].u64 = dwarf_read(dp, offsetp, cu->cu_pointer_size);
383 else if (cu->cu_version == 3)
384 avref.u[0].u64 = dwarf_read(dp, offsetp, dbg->dbg_offsize);
385 break;
386 case DW_FORM_ref_udata:
387 case DW_FORM_udata:
388 avref.u[0].u64 = dwarf_read_uleb128(dp, offsetp);
389 break;
390 case DW_FORM_sdata:
391 avref.u[0].s64 = dwarf_read_sleb128(dp, offsetp);
392 break;
393 case DW_FORM_string:
394 avref.u[0].s = dwarf_read_string(dp, offsetp);
395 break;
396 case DW_FORM_strp:
397 avref.u[0].u64 = dwarf_read(dp, offsetp, dbg->dbg_offsize);
398 avref.u[1].s = elf_strptr(dbg->dbg_elf,
399 dbg->dbg_s[DWARF_debug_str].s_shnum, avref.u[0].u64);
400 break;
401 default:
402 DWARF_SET_ERROR(error, DWARF_E_NOT_IMPLEMENTED);
403 ret = DWARF_E_NOT_IMPLEMENTED;
404 break;
407 if (ret == DWARF_E_NONE)
408 ret = dwarf_attrval_add(die, &avref, NULL, error);
410 return ret;
413 static int
414 dwarf_init_abbrev(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Error *error)
416 Dwarf_Abbrev a;
417 Elf_Data *d;
418 int ret = DWARF_E_NONE;
419 uint64_t attr;
420 uint64_t entry;
421 uint64_t form;
422 uint64_t offset;
423 uint64_t tag;
424 u_int8_t children;
426 d = dbg->dbg_s[DWARF_debug_abbrev].s_data;
428 offset = cu->cu_abbrev_offset;
430 while (offset < d->d_size) {
432 entry = dwarf_read_uleb128(&d, &offset);
434 /* Check if this is the end of the data: */
435 if (entry == 0)
436 break;
438 tag = dwarf_read_uleb128(&d, &offset);
440 children = dwarf_read(&d, &offset, 1);
442 if ((ret = dwarf_abbrev_add(cu, entry, tag, children, &a, error)) != DWARF_E_NONE)
443 break;
445 do {
446 attr = dwarf_read_uleb128(&d, &offset);
447 form = dwarf_read_uleb128(&d, &offset);
449 if (attr != 0)
450 if ((ret = dwarf_attr_add(a, attr, form, NULL, error)) != DWARF_E_NONE)
451 return ret;
452 } while (attr != 0);
455 return ret;
458 static int
459 dwarf_init_info(Dwarf_Debug dbg, Dwarf_Error *error)
461 Dwarf_CU cu;
462 Elf_Data *d = NULL;
463 Elf_Scn *scn;
464 int i;
465 int level = 0;
466 int relocated = 0;
467 int ret = DWARF_E_NONE;
468 uint64_t length;
469 uint64_t next_offset;
470 uint64_t offset = 0;
472 scn = dbg->dbg_s[DWARF_debug_info].s_scn;
474 d = dbg->dbg_s[DWARF_debug_info].s_data;
476 while (offset < d->d_size) {
477 /* Allocate memory for the first compilation unit. */
478 if ((cu = calloc(sizeof(struct _Dwarf_CU), 1)) == NULL) {
479 DWARF_SET_ERROR(error, DWARF_E_MEMORY);
480 return DWARF_E_MEMORY;
483 /* Save the offet to this compilation unit: */
484 cu->cu_offset = offset;
486 length = dwarf_read(&d, &offset, 4);
487 if (length == 0xffffffff) {
488 length = dwarf_read(&d, &offset, 8);
489 dbg->dbg_offsize = 8;
490 } else
491 dbg->dbg_offsize = 4;
494 * Check if there is enough ELF data for this CU.
495 * This assumes that libelf gives us the entire
496 * section in one Elf_Data object.
498 if (length > d->d_size - offset) {
499 free(cu);
500 DWARF_SET_ERROR(error, DWARF_E_INVALID_CU);
501 return DWARF_E_INVALID_CU;
504 /* Relocate the DWARF sections if necessary: */
505 if (!relocated) {
506 if ((ret = dwarf_relocate(dbg, error)) != DWARF_E_NONE)
507 return ret;
508 relocated = 1;
511 /* Compute the offset to the next compilation unit: */
512 next_offset = offset + length;
514 /* Initialise the compilation unit. */
515 cu->cu_length = length;
516 cu->cu_header_length = (dbg->dbg_offsize == 4) ? 4 : 12;
517 cu->cu_version = dwarf_read(&d, &offset, 2);
518 cu->cu_abbrev_offset = dwarf_read(&d, &offset, dbg->dbg_offsize);
519 cu->cu_pointer_size = dwarf_read(&d, &offset, 1);
520 cu->cu_next_offset = next_offset;
522 /* Initialise the list of abbrevs. */
523 STAILQ_INIT(&cu->cu_abbrev);
525 /* Initialise the list of dies. */
526 STAILQ_INIT(&cu->cu_die);
528 /* Initialise the hash table of dies. */
529 for (i = 0; i < DWARF_DIE_HASH_SIZE; i++)
530 STAILQ_INIT(&cu->cu_die_hash[i]);
532 /* Add the compilation unit to the list. */
533 STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next);
535 if (cu->cu_version != 2 && cu->cu_version != 3) {
536 DWARF_SET_ERROR(error, DWARF_E_CU_VERSION);
537 ret = DWARF_E_CU_VERSION;
538 break;
541 /* Parse the .debug_abbrev info for this CU: */
542 if ((ret = dwarf_init_abbrev(dbg, cu, error)) != DWARF_E_NONE)
543 break;
545 level = 0;
547 while (offset < next_offset && offset < d->d_size) {
548 Dwarf_Abbrev a;
549 Dwarf_Attribute at;
550 Dwarf_Die die;
551 uint64_t abnum;
552 uint64_t die_offset = offset;;
554 abnum = dwarf_read_uleb128(&d, &offset);
556 if (abnum == 0) {
557 level--;
558 continue;
561 if ((a = dwarf_abbrev_find(cu, abnum)) == NULL) {
562 DWARF_SET_ERROR(error, DWARF_E_MISSING_ABBREV);
563 return DWARF_E_MISSING_ABBREV;
566 if ((ret = dwarf_die_add(cu, level, die_offset,
567 abnum, a, &die, error)) != DWARF_E_NONE)
568 return ret;
570 STAILQ_FOREACH(at, &a->a_attrib, at_next) {
571 if ((ret = dwarf_init_attr(dbg, &d, &offset,
572 cu, die, at, at->at_form, error)) != DWARF_E_NONE)
573 return ret;
576 if (a->a_children == DW_CHILDREN_yes)
577 level++;
580 offset = next_offset;
583 return ret;
586 static int
587 dwarf_elf_read(Dwarf_Debug dbg, Dwarf_Error *error)
589 GElf_Shdr shdr;
590 Elf_Scn *scn = NULL;
591 char *sname;
592 int i;
593 int ret = DWARF_E_NONE;
595 /* Get a copy of the ELF header. */
596 if (gelf_getehdr(dbg->dbg_elf, &dbg->dbg_ehdr) == NULL) {
597 DWARF_SET_ELF_ERROR(error, elf_errno());
598 return DWARF_E_ELF;
601 /* Check the ELF data format: */
602 switch (dbg->dbg_ehdr.e_ident[EI_DATA]) {
603 case ELFDATA2MSB:
604 dwarf_read = dwarf_read_msb;
605 dwarf_write = dwarf_write_msb;
606 break;
608 case ELFDATA2LSB:
609 case ELFDATANONE:
610 default:
611 dwarf_read = dwarf_read_lsb;
612 dwarf_write = dwarf_write_lsb;
613 break;
616 /* Get the section index to the string table. */
617 if (elf_getshstrndx(dbg->dbg_elf, &dbg->dbg_stnum) == 0) {
618 DWARF_SET_ELF_ERROR(error, elf_errno());
619 return DWARF_E_ELF;
622 /* Look for the debug sections. */
623 while ((scn = elf_nextscn(dbg->dbg_elf, scn)) != NULL) {
624 /* Get a copy of the section header: */
625 if (gelf_getshdr(scn, &shdr) == NULL) {
626 DWARF_SET_ELF_ERROR(error, elf_errno());
627 return DWARF_E_ELF;
630 /* Get a pointer to the section name: */
631 if ((sname = elf_strptr(dbg->dbg_elf, dbg->dbg_stnum, shdr.sh_name)) == NULL) {
632 DWARF_SET_ELF_ERROR(error, elf_errno());
633 return DWARF_E_ELF;
637 * Look up the section name to check if it's
638 * one we need for DWARF.
640 for (i = 0; i < DWARF_DEBUG_SNAMES; i++) {
641 if (strcmp(sname, debug_snames[i]) == 0) {
642 dbg->dbg_s[i].s_sname = sname;
643 dbg->dbg_s[i].s_shnum = elf_ndxscn(scn);
644 dbg->dbg_s[i].s_scn = scn;
645 memcpy(&dbg->dbg_s[i].s_shdr, &shdr, sizeof(shdr));
646 if ((dbg->dbg_s[i].s_data = elf_getdata(scn, NULL)) == NULL) {
647 DWARF_SET_ELF_ERROR(error, elf_errno());
648 return DWARF_E_ELF;
650 break;
655 /* Check if any of the required sections are missing: */
656 if (dbg->dbg_s[DWARF_debug_abbrev].s_scn == NULL ||
657 dbg->dbg_s[DWARF_debug_info].s_scn == NULL) {
658 /* Missing debug information. */
659 DWARF_SET_ERROR(error, DWARF_E_DEBUG_INFO);
660 return DWARF_E_DEBUG_INFO;
663 /* Initialise the compilation-units: */
664 ret = dwarf_init_info(dbg, error);
666 return ret;
670 dwarf_elf_init(Elf *elf, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error)
672 Dwarf_Debug dbg;
673 int ret = DWARF_E_NONE;
675 if (error == NULL)
676 /* Can only return a generic error. */
677 return DWARF_E_ERROR;
679 if (elf == NULL || ret_dbg == NULL) {
680 DWARF_SET_ERROR(error, DWARF_E_ARGUMENT);
681 ret = DWARF_E_ARGUMENT;
682 } else if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) {
683 DWARF_SET_ERROR(error, DWARF_E_MEMORY);
684 ret = DWARF_E_MEMORY;
685 } else {
686 dbg->dbg_elf = elf;
687 dbg->dbg_elf_close = 0;
688 dbg->dbg_mode = mode;
690 STAILQ_INIT(&dbg->dbg_cu);
692 *ret_dbg = dbg;
694 /* Read the ELF sections. */
695 ret = dwarf_elf_read(dbg, error);
698 return ret;
702 dwarf_init(int fd, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error)
704 Dwarf_Error lerror;
705 Elf *elf;
706 Elf_Cmd c;
707 int ret;
709 if (error == NULL)
710 /* Can only return a generic error. */
711 return DWARF_E_ERROR;
713 if (fd < 0 || ret_dbg == NULL) {
714 DWARF_SET_ERROR(error, DWARF_E_ARGUMENT);
715 return DWARF_E_ERROR;
718 /* Translate the DWARF mode to ELF mode. */
719 switch (mode) {
720 default:
721 case DW_DLC_READ:
722 c = ELF_C_READ;
723 break;
726 if (elf_version(EV_CURRENT) == EV_NONE) {
727 DWARF_SET_ELF_ERROR(error, elf_errno());
728 return DWARF_E_ERROR;
731 if ((elf = elf_begin(fd, c, NULL)) == NULL) {
732 DWARF_SET_ELF_ERROR(error, elf_errno());
733 return DWARF_E_ERROR;
736 ret = dwarf_elf_init(elf, mode, ret_dbg, error);
738 if (*ret_dbg != NULL)
739 /* Remember to close the ELF file. */
740 (*ret_dbg)->dbg_elf_close = 1;
742 if (ret != DWARF_E_NONE) {
743 if (*ret_dbg != NULL) {
744 dwarf_finish(ret_dbg, &lerror);
745 } else
746 elf_end(elf);
749 return ret;