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