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: stable/10/lib/libdwarf/dwarf_init.c 252430 2013-06-30 21:06:47Z kaiw $
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
dwarf_read_lsb(Elf_Data ** dp,uint64_t * offsetp,int bytes_to_read)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
dwarf_read_msb(Elf_Data ** dp,uint64_t * offsetp,int bytes_to_read)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
dwarf_write_lsb(Elf_Data ** dp,uint64_t * offsetp,uint64_t value,int bytes_to_write)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
dwarf_write_msb(Elf_Data ** dp,uint64_t * offsetp,uint64_t value,int bytes_to_write)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
dwarf_read_sleb128(Elf_Data ** dp,uint64_t * offsetp)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 < 64 && (b & 0x40) != 0)
196 ret |= (-1 << shift);
197
198 return ret;
199 }
200
201 static uint64_t
dwarf_read_uleb128(Elf_Data ** dp,uint64_t * offsetp)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 *
dwarf_read_string(Elf_Data ** dp,uint64_t * offsetp)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 *
dwarf_read_block(Elf_Data ** dp,uint64_t * offsetp,uint64_t length)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
dwarf_apply_relocations(Dwarf_Debug dbg,Elf_Data * reld,int secindx)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
dwarf_relocate(Dwarf_Debug dbg,Dwarf_Error * error)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
dwarf_init_attr(Dwarf_Debug dbg,Elf_Data ** dp,uint64_t * offsetp,Dwarf_CU cu,Dwarf_Die die,Dwarf_Attribute at,uint64_t form,Dwarf_Error * error)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
dwarf_init_abbrev(Dwarf_Debug dbg,Dwarf_CU cu,Dwarf_Error * error)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
dwarf_init_info(Dwarf_Debug dbg,Dwarf_Error * error)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
dwarf_elf_read(Dwarf_Debug dbg,Dwarf_Error * error)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
dwarf_elf_init(Elf * elf,int mode,Dwarf_Debug * ret_dbg,Dwarf_Error * error)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
dwarf_init(int fd,int mode,Dwarf_Debug * ret_dbg,Dwarf_Error * error)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 }
757