1 /* $NetBSD: dwarf_init.c,v 1.1.1.1 2009/12/23 00:03:22 darran Exp $ */
4 * Copyright (c) 2007 John Birrell (jb@freebsd.org)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
28 * $FreeBSD: src/lib/libdwarf/dwarf_init.c,v 1.1.4.1 2009/08/03 08:13:06 kensmith Exp $
33 #include "_libdwarf.h"
35 static const char *debug_snames
[DWARF_DEBUG_SNAMES
] = {
56 static uint64_t (*dwarf_read
) (Elf_Data
**, uint64_t *, int);
57 static void (*dwarf_write
) (Elf_Data
**, uint64_t *, uint64_t, int);
60 dwarf_read_lsb(Elf_Data
**dp
, uint64_t *offsetp
, int bytes_to_read
)
64 uint8_t *src
= (uint8_t *) (*dp
)->d_buf
+ *offsetp
;
66 switch (bytes_to_read
) {
68 ret
|= ((uint64_t) src
[4]) << 32 | ((uint64_t) src
[5]) << 40;
69 ret
|= ((uint64_t) src
[6]) << 48 | ((uint64_t) src
[7]) << 56;
71 ret
|= ((uint64_t) src
[2]) << 16 | ((uint64_t) src
[3]) << 24;
73 ret
|= ((uint64_t) src
[1]) << 8;
82 *offsetp
+= bytes_to_read
;
88 dwarf_read_msb(Elf_Data
**dp
, uint64_t *offsetp
, int bytes_to_read
)
92 uint8_t *src
= (uint8_t *) (*dp
)->d_buf
+ *offsetp
;
94 switch (bytes_to_read
) {
99 ret
= src
[1] | ((uint64_t) src
[0]) << 8;
102 ret
= src
[3] | ((uint64_t) src
[2]) << 8;
103 ret
|= ((uint64_t) src
[1]) << 16 | ((uint64_t) src
[0]) << 24;
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;
116 *offsetp
+= bytes_to_read
;
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
) {
128 dst
[7] = (value
>> 56) & 0xff;
129 dst
[6] = (value
>> 48) & 0xff;
130 dst
[5] = (value
>> 40) & 0xff;
131 dst
[4] = (value
>> 32) & 0xff;
133 dst
[3] = (value
>> 24) & 0xff;
134 dst
[2] = (value
>> 16) & 0xff;
136 dst
[1] = (value
>> 8) & 0xff;
138 dst
[0] = value
& 0xff;
145 *offsetp
+= bytes_to_write
;
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
) {
155 dst
[7] = value
& 0xff;
156 dst
[6] = (value
>> 8) & 0xff;
157 dst
[5] = (value
>> 16) & 0xff;
158 dst
[4] = (value
>> 24) & 0xff;
161 dst
[3] = value
& 0xff;
162 dst
[2] = (value
>> 8) & 0xff;
165 dst
[1] = value
& 0xff;
168 dst
[0] = value
& 0xff;
175 *offsetp
+= bytes_to_write
;
179 dwarf_read_sleb128(Elf_Data
**dp
, uint64_t *offsetp
)
185 uint8_t *src
= (uint8_t *) (*dp
)->d_buf
+ *offsetp
;
190 ret
|= ((b
& 0x7f) << shift
);
195 } while ((b
& 0x80) != 0);
197 if (shift
< 32 && (b
& 0x40) != 0)
198 ret
|= (-1 << shift
);
204 dwarf_read_uleb128(Elf_Data
**dp
, uint64_t *offsetp
)
210 uint8_t *src
= (uint8_t *) (*dp
)->d_buf
+ *offsetp
;
215 ret
|= ((b
& 0x7f) << shift
);
220 } while ((b
& 0x80) != 0);
226 dwarf_read_string(Elf_Data
**dp
, uint64_t *offsetp
)
230 char *src
= (char *) (*dp
)->d_buf
+ *offsetp
;
234 while (*src
!= '\0' && *offsetp
< (*dp
)->d_size
) {
239 if (*src
== '\0' && *offsetp
< (*dp
)->d_size
)
246 dwarf_read_block(Elf_Data
**dp
, uint64_t *offsetp
, uint64_t length
)
250 uint8_t *src
= (uint8_t *) (*dp
)->d_buf
+ *offsetp
;
254 (*offsetp
) += length
;
260 dwarf_apply_relocations(Dwarf_Debug dbg
, Elf_Data
*reld
, int secindx
)
265 int ret
= DWARF_E_NONE
;
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
) {
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
);
281 offset
= rela
.r_offset
;
283 dwarf_write(&d
, &offset
, rela
.r_addend
, dbg
->dbg_offsize
);
290 dwarf_relocate(Dwarf_Debug dbg
, Dwarf_Error
*error
)
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());
304 if (shdr
.sh_type
!= SHT_RELA
|| shdr
.sh_size
== 0)
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
) {
312 /* Get the relocation data. */
313 if ((rd
= elf_getdata(scn
, NULL
)) == NULL
) {
314 DWARF_SET_ELF_ERROR(error
, elf_errno());
318 /* Apply the relocations. */
319 dwarf_apply_relocations(dbg
, rd
, i
);
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
,
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
;
342 avref
.u
[0].u64
= dwarf_read(dp
, offsetp
, cu
->cu_pointer_size
);
345 avref
.u
[0].u64
= dwarf_read_uleb128(dp
, offsetp
);
346 avref
.u
[1].u8p
= dwarf_read_block(dp
, offsetp
, avref
.u
[0].u64
);
349 avref
.u
[0].u64
= dwarf_read(dp
, offsetp
, 1);
350 avref
.u
[1].u8p
= dwarf_read_block(dp
, offsetp
, avref
.u
[0].u64
);
353 avref
.u
[0].u64
= dwarf_read(dp
, offsetp
, 2);
354 avref
.u
[1].u8p
= dwarf_read_block(dp
, offsetp
, avref
.u
[0].u64
);
357 avref
.u
[0].u64
= dwarf_read(dp
, offsetp
, 4);
358 avref
.u
[1].u8p
= dwarf_read_block(dp
, offsetp
, avref
.u
[0].u64
);
363 avref
.u
[0].u64
= dwarf_read(dp
, offsetp
, 1);
367 avref
.u
[0].u64
= dwarf_read(dp
, offsetp
, 2);
371 avref
.u
[0].u64
= dwarf_read(dp
, offsetp
, 4);
375 avref
.u
[0].u64
= dwarf_read(dp
, offsetp
, 8);
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
);
386 case DW_FORM_ref_udata
:
388 avref
.u
[0].u64
= dwarf_read_uleb128(dp
, offsetp
);
391 avref
.u
[0].s64
= dwarf_read_sleb128(dp
, offsetp
);
394 avref
.u
[0].s
= dwarf_read_string(dp
, offsetp
);
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
);
402 DWARF_SET_ERROR(error
, DWARF_E_NOT_IMPLEMENTED
);
403 ret
= DWARF_E_NOT_IMPLEMENTED
;
407 if (ret
== DWARF_E_NONE
)
408 ret
= dwarf_attrval_add(die
, &avref
, NULL
, error
);
414 dwarf_init_abbrev(Dwarf_Debug dbg
, Dwarf_CU cu
, Dwarf_Error
*error
)
418 int ret
= DWARF_E_NONE
;
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: */
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
)
446 attr
= dwarf_read_uleb128(&d
, &offset
);
447 form
= dwarf_read_uleb128(&d
, &offset
);
450 if ((ret
= dwarf_attr_add(a
, attr
, form
, NULL
, error
)) != DWARF_E_NONE
)
459 dwarf_init_info(Dwarf_Debug dbg
, Dwarf_Error
*error
)
467 int ret
= DWARF_E_NONE
;
469 uint64_t next_offset
;
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;
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
) {
500 DWARF_SET_ERROR(error
, DWARF_E_INVALID_CU
);
501 return DWARF_E_INVALID_CU
;
504 /* Relocate the DWARF sections if necessary: */
506 if ((ret
= dwarf_relocate(dbg
, error
)) != DWARF_E_NONE
)
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
;
541 /* Parse the .debug_abbrev info for this CU: */
542 if ((ret
= dwarf_init_abbrev(dbg
, cu
, error
)) != DWARF_E_NONE
)
547 while (offset
< next_offset
&& offset
< d
->d_size
) {
552 uint64_t die_offset
= offset
;;
554 abnum
= dwarf_read_uleb128(&d
, &offset
);
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
)
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
)
576 if (a
->a_children
== DW_CHILDREN_yes
)
580 offset
= next_offset
;
587 dwarf_elf_read(Dwarf_Debug dbg
, Dwarf_Error
*error
)
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());
601 /* Check the ELF data format: */
602 switch (dbg
->dbg_ehdr
.e_ident
[EI_DATA
]) {
604 dwarf_read
= dwarf_read_msb
;
605 dwarf_write
= dwarf_write_msb
;
611 dwarf_read
= dwarf_read_lsb
;
612 dwarf_write
= dwarf_write_lsb
;
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());
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());
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());
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());
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
);
670 dwarf_elf_init(Elf
*elf
, int mode
, Dwarf_Debug
*ret_dbg
, Dwarf_Error
*error
)
673 int ret
= DWARF_E_NONE
;
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
;
687 dbg
->dbg_elf_close
= 0;
688 dbg
->dbg_mode
= mode
;
690 STAILQ_INIT(&dbg
->dbg_cu
);
694 /* Read the ELF sections. */
695 ret
= dwarf_elf_read(dbg
, error
);
702 dwarf_init(int fd
, int mode
, Dwarf_Debug
*ret_dbg
, Dwarf_Error
*error
)
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. */
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
);