]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - lib/libdwarf/dwarf_init.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / lib / libdwarf / dwarf_init.c
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
33 static 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
54 static uint64_t (*dwarf_read) (Elf_Data **, uint64_t *, int);
55 static void (*dwarf_write) (Elf_Data **, uint64_t *, uint64_t, int);
56
57 static uint64_t
58 dwarf_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
85 static uint64_t
86 dwarf_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
119 static void
120 dwarf_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
146 static void
147 dwarf_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
176 static int64_t
177 dwarf_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
201 static uint64_t
202 dwarf_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
223 static const char *
224 dwarf_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
243 static uint8_t *
244 dwarf_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
257 static int
258 dwarf_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
287 static int
288 dwarf_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
326 static int
327 dwarf_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
415 static int
416 dwarf_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
460 static int
461 dwarf_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
591 static int
592 dwarf_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
674 int
675 dwarf_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
707 int
708 dwarf_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 }