1 /* Copyright (C) 2021 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
30 #include "StringBuilder.h"
32 #include "DbeSession.h"
34 #define CASE_S(x) case x: s = (char *) #x; break
37 gelf_st_type2str (int type
)
53 default: s
= NTXT ("???");
56 snprintf (buf
, sizeof (buf
), NTXT ("%s(%d)"), s
, type
);
57 buf
[sizeof (buf
) - 1] = 0;
62 special_opcode2str (int opcode
)
65 snprintf (buf
, sizeof (buf
), NTXT ("SpecialOpcode: %3d"), opcode
);
66 buf
[sizeof (buf
) - 1] = 0;
71 extended_opcode2str (int opcode
)
77 CASE_S (DW_LNE_end_sequence
);
78 CASE_S (DW_LNE_set_address
);
79 CASE_S (DW_LNE_define_file
);
81 snprintf (buf
, sizeof (buf
), NTXT ("??? (%d)"), opcode
);
82 buf
[sizeof (buf
) - 1] = 0;
90 standard_opcode2str (int opcode
)
97 CASE_S (DW_LNS_advance_pc
);
98 CASE_S (DW_LNS_advance_line
);
99 CASE_S (DW_LNS_set_file
);
100 CASE_S (DW_LNS_set_column
);
101 CASE_S (DW_LNS_negate_stmt
);
102 CASE_S (DW_LNS_set_basic_block
);
103 CASE_S (DW_LNS_const_add_pc
);
104 CASE_S (DW_LNS_fixed_advance_pc
);
106 snprintf (buf
, sizeof (buf
), NTXT ("??? (%d)"), opcode
);
107 buf
[sizeof (buf
) - 1] = 0;
114 template<> void Vector
<DwrInlinedSubr
*>
115 ::dump (const char *msg
)
117 Dprintf (1, NTXT ("%s Vector<DwrInlinedSubr *> [%lld]\n"),
118 msg
? msg
: NTXT (""), (long long) size ());
119 for (long i
= 0, sz
= size (); i
< sz
; i
++)
121 DwrInlinedSubr
*p
= get (i
);
122 Dprintf (1, NTXT ("%ld: "), (long) i
);
127 template<> void Vector
<DwrLine
*>
128 ::dump (const char *msg
)
130 Dprintf (1, "%s Vector<DwrLine *> [%lld]:\n address [file line column]\n",
131 msg
? msg
: NTXT (""), (long long) size ());
132 for (long i
= 0, sz
= size (); i
< sz
; i
++)
134 DwrLine
*lnp
= get (i
);
135 Dprintf (1, NTXT (" %2lld 0x%08llx [ %2lld, %lld, %lld ] \n"),
136 (long long) i
, (long long) lnp
->address
, (long long) lnp
->file
,
137 (long long) lnp
->line
, (long long) lnp
->column
);
139 Dprintf (1, NTXT ("\n\n"));
142 //////////////////////////////////////////////////////////
145 ElfReloc::ElfReloc (Elf
*_elf
)
152 ElfReloc::~ElfReloc ()
162 ElfReloc::dump_rela_debug_sec (int sec
)
166 Elf_Internal_Shdr
*shdr
= elf
->get_shdr (sec
);
170 Elf_Data
*data
= elf
->elf_getdata (sec
);
174 uint64_t ScnSize
= data
->d_size
;
175 uint64_t EntSize
= shdr
->sh_entsize
;
176 if (ScnSize
== 0 || EntSize
== 0)
179 Elf_Internal_Shdr
*shdr_sym
= elf
->get_shdr (shdr
->sh_link
);
180 if (shdr_sym
== NULL
)
182 Elf_Data
*data_sym
= elf
->elf_getdata (shdr
->sh_link
);
183 Elf_Data
*data_str
= elf
->elf_getdata (shdr_sym
->sh_link
);
184 char *Strtab
= data_str
? (char*) data_str
->d_buf
: NULL
;
185 Elf_Internal_Rela rela
;
186 int n
, cnt
= (int) (ScnSize
/ EntSize
);
188 char *sec_name
= elf
->get_sec_name (sec
);
189 if (sec_name
== NULL
) // It can not be, but let's check
191 Dprintf (DUMP_RELA_SEC
,
192 "======= DwarfLib::dump_rela_debug_sec Section:%2d '%s'\n",
194 Dprintf (DUMP_RELA_SEC
,
195 " N |addend| offset | r_info | stt_type |\n");
196 for (n
= 0; n
< cnt
; n
++)
198 if (strncmp (sec_name
, NTXT (".rela."), 6) == 0)
199 elf
->elf_getrela (data
, n
, &rela
);
202 elf
->elf_getrel (data
, n
, &rela
);
205 int ndx
= (int) GELF_R_SYM (rela
.r_info
);
206 Elf_Internal_Shdr
*secHdr
;
207 Elf_Internal_Sym sym
;
208 elf
->elf_getsym (data_sym
, ndx
, &sym
);
209 Dprintf (DUMP_RELA_SEC
, NTXT ("%3d:%5d |%11lld |0x%016llx | %-15s|"),
210 n
, (int) rela
.r_addend
,
211 (long long) rela
.r_offset
, (long long) rela
.r_info
,
212 gelf_st_type2str ((int) GELF_ST_TYPE (sym
.st_info
)));
213 switch (GELF_ST_TYPE (sym
.st_info
))
218 secHdr
= elf
->get_shdr (sym
.st_shndx
);
220 Dprintf (DUMP_RELA_SEC
, NTXT (" img_offset=0x%llx"),
221 (long long) (sym
.st_value
+ secHdr
->sh_offset
));
222 if (Strtab
&& sym
.st_name
)
223 Dprintf (DUMP_RELA_SEC
, NTXT (" %s"), Strtab
+ sym
.st_name
);
226 secHdr
= elf
->get_shdr (sym
.st_shndx
);
229 Dprintf (DUMP_RELA_SEC
, NTXT (" value=0x%016llx (%lld)"),
230 (long long) (secHdr
->sh_offset
+ rela
.r_addend
),
231 (long long) (secHdr
->sh_offset
+ rela
.r_addend
));
237 Dprintf (DUMP_RELA_SEC
, NTXT ("\n"));
239 Dprintf (DUMP_RELA_SEC
, NTXT ("\n"));
245 if (!DUMP_ELF_RELOC
|| (reloc
== NULL
) || (reloc
->size () == 0))
247 Dprintf (DUMP_ELF_RELOC
, NTXT ("======= ElfReloc::dump\n"));
248 Dprintf (DUMP_ELF_RELOC
, NTXT (" N | offset | value | STT_TYPE\n"));
249 for (int i
= 0; i
< reloc
->size (); i
++)
251 Sreloc
*srlc
= reloc
->fetch (i
);
252 Dprintf (DUMP_ELF_RELOC
, NTXT ("%3d:%11lld |%11lld | %s\n"),
253 i
, (long long) srlc
->offset
, (long long) srlc
->value
,
254 gelf_st_type2str (srlc
->stt_type
));
256 Dprintf (DUMP_ELF_RELOC
, NTXT ("\n"));
260 DwrRelocOffsetCmp (const void *a
, const void *b
)
262 ElfReloc::Sreloc
*item1
= *((ElfReloc::Sreloc
**) a
);
263 ElfReloc::Sreloc
*item2
= *((ElfReloc::Sreloc
**) b
);
264 return item1
->offset
< item2
->offset
? -1 :
265 item1
->offset
== item2
->offset
? 0 : 1;
269 ElfReloc::get_elf_reloc (Elf
*elfp
, char *sec_name
, ElfReloc
*rlc
)
271 int et
= elfp
->elf_getehdr ()->e_type
;
272 if (et
== ET_EXEC
|| et
== ET_DYN
)
274 int sec
= elfp
->elf_get_sec_num (sec_name
);
277 Elf_Internal_Shdr
*shdr
= elfp
->get_shdr (sec
);
278 if (shdr
== NULL
|| shdr
->sh_entsize
== 0)
281 Elf_Data
*data
= elfp
->elf_getdata (sec
);
282 if (data
== NULL
|| data
->d_size
== 0)
285 int cnt
= (int) (data
->d_size
/ shdr
->sh_entsize
);
286 Elf_Internal_Shdr
*shdr_sym
= elfp
->get_shdr (shdr
->sh_link
);
287 if (shdr_sym
== NULL
)
289 Elf_Data
*data_sym
= elfp
->elf_getdata (shdr
->sh_link
);
290 Vector
<Sreloc
*> *vp
= NULL
;
292 for (int n
= 0; n
< cnt
; n
++)
294 Elf_Internal_Shdr
*secHdr
;
296 Elf_Internal_Rela rela
;
297 if (strncmp (sec_name
, NTXT (".rela."), 6) == 0)
298 elfp
->elf_getrela (data
, n
, &rela
);
301 elfp
->elf_getrel (data
, n
, &rela
);
304 int ndx
= (int) GELF_R_SYM (rela
.r_info
);
305 Elf_Internal_Sym sym
;
306 elfp
->elf_getsym (data_sym
, ndx
, &sym
);
309 srlc
->offset
= rela
.r_offset
;
311 srlc
->stt_type
= (int) GELF_ST_TYPE (sym
.st_info
);
312 switch (GELF_ST_TYPE (sym
.st_info
))
315 secHdr
= elfp
->get_shdr (sym
.st_shndx
);
317 srlc
->value
= secHdr
->sh_offset
+ sym
.st_value
;
321 secHdr
= elfp
->get_shdr (shdr
->sh_info
);
324 srlc
->offset
= rela
.r_info
;
325 srlc
->value
= secHdr
->sh_offset
+ rela
.r_addend
;
329 secHdr
= elfp
->get_shdr (sym
.st_shndx
);
331 srlc
->value
= rela
.r_addend
;
339 rlc
= new ElfReloc (elfp
);
344 vp
= new Vector
<Sreloc
*>;
350 vp
->sort (DwrRelocOffsetCmp
);
353 rlc
->dump_rela_debug_sec (sec
);
360 ElfReloc::get_reloc_addr (long long offset
)
363 int i
= cur_reloc_ind
- 1;
364 if (i
>= 0 && i
< reloc
->size ())
366 srlc
= reloc
->fetch (i
);
367 if (srlc
->offset
> offset
) // need to reset
370 for (; cur_reloc_ind
< reloc
->size (); cur_reloc_ind
++)
372 srlc
= reloc
->fetch (cur_reloc_ind
);
373 if (srlc
->offset
== offset
)
375 if (srlc
->offset
> offset
)
382 DwrCU::dwr_get_location (DwrSec
*secp
, DwrLocation
*lp
)
384 lp
->offset
= secp
->offset
;
387 lp
->op
= secp
->Get_8 ();
425 lp
->lc_number
= secp
->GetULEB128 ();
459 lp
->lc_number
= secp
->GetSLEB128 ();
462 lp
->lc_number
= secp
->GetSLEB128 ();
465 lp
->lc_number
= secp
->GetULEB128 ();
466 lp
->lc_number2
= secp
->GetSLEB128 ();
500 lp
->lc_number
= lp
->op
- DW_OP_lit0
;
503 lp
->lc_number
= secp
->GetADDR ();
506 lp
->lc_number
= secp
->Get_8 ();
516 lp
->lc_number
= secp
->Get_16 ();
526 lp
->lc_number
= secp
->Get_32 ();
536 lp
->lc_number
= secp
->Get_64 ();
545 case DW_OP_plus_uconst
:
547 lp
->lc_number
= secp
->GetULEB128 ();
550 lp
->lc_number
= secp
->GetSLEB128 ();
555 case DW_OP_deref_size
:
556 case DW_OP_xderef_size
:
557 lp
->lc_number
= secp
->Get_8 ();
566 // Arithmetic and Logical Operations
591 lp
->lc_number
= secp
->Get_16 ();
594 lp
->lc_number
= secp
->GetULEB128 ();
596 case DW_OP_push_object_address
: /* DWARF3 */
598 case DW_OP_call2
: /* DWARF3 */
599 lp
->lc_number
= secp
->Get_16 ();
601 case DW_OP_call4
: /* DWARF3 */
602 lp
->lc_number
= secp
->Get_32 ();
604 case DW_OP_call_ref
: /* DWARF3 */
605 lp
->lc_number
= secp
->GetADDR ();
614 DwrCU::tag2str (int tag
)
616 static char buf
[128];
621 CASE_S (DW_TAG_array_type
);
622 CASE_S (DW_TAG_class_type
);
623 CASE_S (DW_TAG_entry_point
);
624 CASE_S (DW_TAG_enumeration_type
);
625 CASE_S (DW_TAG_formal_parameter
);
626 CASE_S (DW_TAG_imported_declaration
);
627 CASE_S (DW_TAG_label
);
628 CASE_S (DW_TAG_lexical_block
);
629 CASE_S (DW_TAG_member
);
630 CASE_S (DW_TAG_pointer_type
);
631 CASE_S (DW_TAG_reference_type
);
632 CASE_S (DW_TAG_compile_unit
);
633 CASE_S (DW_TAG_string_type
);
634 CASE_S (DW_TAG_structure_type
);
635 CASE_S (DW_TAG_subroutine_type
);
636 CASE_S (DW_TAG_typedef
);
637 CASE_S (DW_TAG_union_type
);
638 CASE_S (DW_TAG_unspecified_parameters
);
639 CASE_S (DW_TAG_variant
);
640 CASE_S (DW_TAG_common_block
);
641 CASE_S (DW_TAG_common_inclusion
);
642 CASE_S (DW_TAG_inheritance
);
643 CASE_S (DW_TAG_inlined_subroutine
);
644 CASE_S (DW_TAG_module
);
645 CASE_S (DW_TAG_ptr_to_member_type
);
646 CASE_S (DW_TAG_set_type
);
647 CASE_S (DW_TAG_subrange_type
);
648 CASE_S (DW_TAG_with_stmt
);
649 CASE_S (DW_TAG_access_declaration
);
650 CASE_S (DW_TAG_base_type
);
651 CASE_S (DW_TAG_catch_block
);
652 CASE_S (DW_TAG_const_type
);
653 CASE_S (DW_TAG_constant
);
654 CASE_S (DW_TAG_enumerator
);
655 CASE_S (DW_TAG_file_type
);
656 CASE_S (DW_TAG_friend
);
657 CASE_S (DW_TAG_namelist
);
658 CASE_S (DW_TAG_namelist_item
);
659 CASE_S (DW_TAG_packed_type
);
660 CASE_S (DW_TAG_subprogram
);
661 CASE_S (DW_TAG_template_type_param
);
662 CASE_S (DW_TAG_template_value_param
);
663 CASE_S (DW_TAG_thrown_type
);
664 CASE_S (DW_TAG_try_block
);
665 CASE_S (DW_TAG_variant_part
);
666 CASE_S (DW_TAG_variable
);
667 CASE_S (DW_TAG_volatile_type
);
668 CASE_S (DW_TAG_dwarf_procedure
);
669 CASE_S (DW_TAG_restrict_type
);
670 CASE_S (DW_TAG_interface_type
);
671 CASE_S (DW_TAG_namespace
);
672 CASE_S (DW_TAG_imported_module
);
673 CASE_S (DW_TAG_unspecified_type
);
674 CASE_S (DW_TAG_partial_unit
);
675 CASE_S (DW_TAG_imported_unit
);
676 CASE_S (DW_TAG_lo_user
);
677 CASE_S (DW_TAG_MIPS_loop
);
678 CASE_S (DW_TAG_format_label
);
679 CASE_S (DW_TAG_function_template
);
680 CASE_S (DW_TAG_class_template
);
681 CASE_S (DW_TAG_GNU_BINCL
);
682 CASE_S (DW_TAG_GNU_EINCL
);
683 CASE_S (DW_TAG_GNU_call_site
);
684 CASE_S (DW_TAG_GNU_call_site_parameter
);
685 CASE_S (DW_TAG_SUN_codeflags
);
686 CASE_S (DW_TAG_SUN_memop_info
);
687 CASE_S (DW_TAG_hi_user
);
688 CASE_S (DW_TAG_icc_compile_unit
);
689 default: s
= NTXT ("???");
692 snprintf (buf
, sizeof (buf
), NTXT ("%s(%d)"), s
, tag
);
693 buf
[sizeof (buf
) - 1] = 0;
698 DwrCU::at2str (int tag
)
700 static char buf
[128];
704 CASE_S (DW_AT_sibling
);
705 CASE_S (DW_AT_location
);
707 CASE_S (DW_AT_ordering
);
708 CASE_S (DW_AT_subscr_data
);
709 CASE_S (DW_AT_byte_size
);
710 CASE_S (DW_AT_bit_offset
);
711 CASE_S (DW_AT_bit_size
);
712 CASE_S (DW_AT_element_list
);
713 CASE_S (DW_AT_stmt_list
);
714 CASE_S (DW_AT_low_pc
);
715 CASE_S (DW_AT_high_pc
);
716 CASE_S (DW_AT_language
);
717 CASE_S (DW_AT_member
);
718 CASE_S (DW_AT_discr
);
719 CASE_S (DW_AT_discr_value
);
720 CASE_S (DW_AT_visibility
);
721 CASE_S (DW_AT_import
);
722 CASE_S (DW_AT_string_length
);
723 CASE_S (DW_AT_common_reference
);
724 CASE_S (DW_AT_comp_dir
);
725 CASE_S (DW_AT_const_value
);
726 CASE_S (DW_AT_containing_type
);
727 CASE_S (DW_AT_default_value
);
728 CASE_S (DW_AT_inline
);
729 CASE_S (DW_AT_is_optional
);
730 CASE_S (DW_AT_lower_bound
);
731 CASE_S (DW_AT_producer
);
732 CASE_S (DW_AT_prototyped
);
733 CASE_S (DW_AT_return_addr
);
734 CASE_S (DW_AT_start_scope
);
735 CASE_S (DW_AT_stride_size
);
736 CASE_S (DW_AT_upper_bound
);
737 CASE_S (DW_AT_abstract_origin
);
738 CASE_S (DW_AT_accessibility
);
739 CASE_S (DW_AT_address_class
);
740 CASE_S (DW_AT_artificial
);
741 CASE_S (DW_AT_base_types
);
742 CASE_S (DW_AT_calling_convention
);
743 CASE_S (DW_AT_count
);
744 CASE_S (DW_AT_data_member_location
);
745 CASE_S (DW_AT_decl_column
);
746 CASE_S (DW_AT_decl_file
);
747 CASE_S (DW_AT_decl_line
);
748 CASE_S (DW_AT_declaration
);
749 CASE_S (DW_AT_discr_list
);
750 CASE_S (DW_AT_encoding
);
751 CASE_S (DW_AT_external
);
752 CASE_S (DW_AT_frame_base
);
753 CASE_S (DW_AT_friend
);
754 CASE_S (DW_AT_identifier_case
);
755 CASE_S (DW_AT_macro_info
);
756 CASE_S (DW_AT_namelist_item
);
757 CASE_S (DW_AT_priority
);
758 CASE_S (DW_AT_segment
);
759 CASE_S (DW_AT_specification
);
760 CASE_S (DW_AT_static_link
);
762 CASE_S (DW_AT_use_location
);
763 CASE_S (DW_AT_variable_parameter
);
764 CASE_S (DW_AT_virtuality
);
765 CASE_S (DW_AT_vtable_elem_location
);
766 CASE_S (DW_AT_allocated
);
767 CASE_S (DW_AT_associated
);
768 CASE_S (DW_AT_data_location
);
769 CASE_S (DW_AT_byte_stride
);
770 CASE_S (DW_AT_entry_pc
);
771 CASE_S (DW_AT_use_UTF8
);
772 CASE_S (DW_AT_extension
);
773 CASE_S (DW_AT_ranges
);
774 CASE_S (DW_AT_trampoline
);
775 CASE_S (DW_AT_call_column
);
776 CASE_S (DW_AT_call_file
);
777 CASE_S (DW_AT_call_line
);
778 CASE_S (DW_AT_description
);
779 CASE_S (DW_AT_binary_scale
);
780 CASE_S (DW_AT_decimal_scale
);
781 CASE_S (DW_AT_small
);
782 CASE_S (DW_AT_decimal_sign
);
783 CASE_S (DW_AT_digit_count
);
784 CASE_S (DW_AT_picture_string
);
785 CASE_S (DW_AT_mutable
);
786 CASE_S (DW_AT_threads_scaled
);
787 CASE_S (DW_AT_explicit
);
788 CASE_S (DW_AT_object_pointer
);
789 CASE_S (DW_AT_endianity
);
790 CASE_S (DW_AT_elemental
);
792 CASE_S (DW_AT_recursive
);
793 CASE_S (DW_AT_signature
);
794 CASE_S (DW_AT_main_subprogram
);
795 CASE_S (DW_AT_data_bit_offset
);
796 CASE_S (DW_AT_const_expr
);
797 CASE_S (DW_AT_enum_class
);
798 CASE_S (DW_AT_linkage_name
);
799 CASE_S (DW_AT_lo_user
);
800 CASE_S (DW_AT_MIPS_fde
);
801 CASE_S (DW_AT_MIPS_loop_begin
);
802 CASE_S (DW_AT_MIPS_tail_loop_begin
);
803 CASE_S (DW_AT_MIPS_epilog_begin
);
804 CASE_S (DW_AT_MIPS_loop_unroll_factor
);
805 CASE_S (DW_AT_MIPS_software_pipeline_depth
);
806 CASE_S (DW_AT_MIPS_linkage_name
);
807 CASE_S (DW_AT_MIPS_stride
);
808 CASE_S (DW_AT_MIPS_abstract_name
);
809 CASE_S (DW_AT_MIPS_clone_origin
);
810 CASE_S (DW_AT_MIPS_has_inlines
);
811 CASE_S (DW_AT_sf_names
);
812 CASE_S (DW_AT_src_info
);
813 CASE_S (DW_AT_mac_info
);
814 CASE_S (DW_AT_src_coords
);
815 CASE_S (DW_AT_body_begin
);
816 CASE_S (DW_AT_body_end
);
817 CASE_S (DW_AT_GNU_vector
);
818 CASE_S (DW_AT_GNU_guarded_by
);
819 CASE_S (DW_AT_GNU_pt_guarded_by
);
820 CASE_S (DW_AT_GNU_guarded
);
821 CASE_S (DW_AT_GNU_pt_guarded
);
822 CASE_S (DW_AT_GNU_locks_excluded
);
823 CASE_S (DW_AT_GNU_exclusive_locks_required
);
824 CASE_S (DW_AT_GNU_shared_locks_required
);
825 CASE_S (DW_AT_GNU_odr_signature
);
826 CASE_S (DW_AT_GNU_template_name
);
827 CASE_S (DW_AT_GNU_call_site_value
);
828 CASE_S (DW_AT_GNU_call_site_data_value
);
829 CASE_S (DW_AT_GNU_call_site_target
);
830 CASE_S (DW_AT_GNU_call_site_target_clobbered
);
831 CASE_S (DW_AT_GNU_tail_call
);
832 CASE_S (DW_AT_GNU_all_tail_call_sites
);
833 CASE_S (DW_AT_GNU_all_call_sites
);
834 CASE_S (DW_AT_GNU_all_source_call_sites
);
835 CASE_S (DW_AT_SUN_command_line
);
836 CASE_S (DW_AT_SUN_func_offsets
);
837 CASE_S (DW_AT_SUN_cf_kind
);
838 CASE_S (DW_AT_SUN_func_offset
);
839 CASE_S (DW_AT_SUN_memop_type_ref
);
840 CASE_S (DW_AT_SUN_profile_id
);
841 CASE_S (DW_AT_SUN_memop_signature
);
842 CASE_S (DW_AT_SUN_obj_dir
);
843 CASE_S (DW_AT_SUN_obj_file
);
844 CASE_S (DW_AT_SUN_original_name
);
845 CASE_S (DW_AT_SUN_link_name
);
846 CASE_S (DW_AT_hi_user
);
847 CASE_S (DW_AT_icc_flags
);
848 default: s
= NTXT ("???");
851 snprintf (buf
, sizeof (buf
), NTXT ("%s(%d)"), s
, tag
);
852 buf
[sizeof (buf
) - 1] = 0;
857 DwrCU::form2str (int tag
)
859 static char buf
[128];
863 CASE_S (DW_FORM_addr
);
864 CASE_S (DW_FORM_block2
);
865 CASE_S (DW_FORM_block4
);
866 CASE_S (DW_FORM_data2
);
867 CASE_S (DW_FORM_data4
);
868 CASE_S (DW_FORM_data8
);
869 CASE_S (DW_FORM_string
);
870 CASE_S (DW_FORM_block
);
871 CASE_S (DW_FORM_block1
);
872 CASE_S (DW_FORM_data1
);
873 CASE_S (DW_FORM_flag
);
874 CASE_S (DW_FORM_sdata
);
875 CASE_S (DW_FORM_strp
);
876 CASE_S (DW_FORM_udata
);
877 CASE_S (DW_FORM_ref_addr
);
878 CASE_S (DW_FORM_ref1
);
879 CASE_S (DW_FORM_ref2
);
880 CASE_S (DW_FORM_ref4
);
881 CASE_S (DW_FORM_ref8
);
882 CASE_S (DW_FORM_ref_udata
);
883 CASE_S (DW_FORM_indirect
);
884 CASE_S (DW_FORM_sec_offset
);
885 CASE_S (DW_FORM_exprloc
);
886 CASE_S (DW_FORM_flag_present
);
887 CASE_S (DW_FORM_ref_sig8
);
888 default: s
= NTXT ("???");
891 snprintf (buf
, sizeof (buf
), NTXT ("%s(%d)"), s
, tag
);
892 buf
[sizeof (buf
) - 1] = 0;
899 Dprintf (DUMP_DWARFLIB
,
900 "\n<%2d>:<0x%08llx> %-30s <abbrev %lld> offset=0x%llx %s\n",
901 (int) level
, (long long) die
, DwrCU::tag2str (tag
), (long long) num
,
903 hasChild
? NTXT ("DW_children_yes") : NTXT ("DW_children_no"));
904 for (int i1
= firstAttribute
; i1
< lastAttribute
; i1
++)
906 Dwr_Attr
*atrp
= abbrevAtForm
->get (i1
);
907 Dprintf (DUMP_DWARFLIB
, " %-30s ", DwrCU::at2str (atrp
->at_name
));
908 switch (atrp
->at_form
)
912 Dprintf (DUMP_DWARFLIB
, " \"%s\" len=%ld",
913 atrp
->u
.str
? atrp
->u
.str
: NTXT ("<NULL>"),
920 Dprintf (DUMP_DWARFLIB
, " len=%3ld %p", (long) atrp
->len
,
931 case DW_FORM_ref_addr
:
936 case DW_FORM_ref_udata
:
937 case DW_FORM_indirect
:
938 case DW_FORM_sec_offset
:
939 case DW_FORM_exprloc
:
940 case DW_FORM_ref_sig8
:
941 case DW_FORM_flag_present
:
942 Dprintf (DUMP_DWARFLIB
, " 0x%llx (%lld)", (long long) atrp
->u
.val
,
943 (long long) atrp
->u
.val
);
948 Dprintf (1, "Attribute form 0x%llx (%lld) is not implemented\n",
949 (long long) atrp
->at_form
, (long long) atrp
->at_form
);
953 Dprintf (DUMP_DWARFLIB
, NTXT ("\n"));
958 //////////////////////////////////////////////////////////
961 DwrSec::DwrSec (unsigned char *_data
, uint64_t _size
, bool _need_swap_endian
, bool _addr32
)
966 size
= (data
? _size
: 0);
970 need_swap_endian
= _need_swap_endian
;
974 DwrSec::DwrSec (DwrSec
*secp
, uint64_t _offset
)
978 sizeSec
= secp
->sizeSec
;
983 need_swap_endian
= secp
->need_swap_endian
;
984 addr32
= secp
->addr32
;
994 DwrSec::bounds_violation (uint64_t sz
)
996 if (offset
+ sz
> size
)
998 Dprintf (DEBUG_ERR_MSG
, "DwrSec::bounds_violation: offset=%lld + sz=%lld > size=%lld\n",
999 (long long) offset
, (long long) sz
, (long long) size
);
1006 DwrSec::ReadLength ()
1009 uint64_t val
= Get_32 ();
1010 if (((uint32_t) val
) == 0xffffffff)
1015 size
= (val
+ offset
< sizeSec
) ? val
+ offset
: sizeSec
;
1022 unsigned char n
= 0;
1023 if (bounds_violation (sizeof (char)))
1026 offset
+= sizeof (char);
1033 unsigned short n
= 0;
1034 if (bounds_violation (sizeof (short)))
1036 memcpy ((char *) &n
, data
+ offset
, sizeof (short));
1037 offset
+= sizeof (short);
1038 if (need_swap_endian
)
1047 if (bounds_violation (sizeof (uint32_t)))
1049 memcpy ((char *) &n
, data
+ offset
, sizeof (uint32_t));
1050 offset
+= sizeof (uint32_t);
1051 if (need_swap_endian
)
1060 if (bounds_violation (sizeof (uint64_t)))
1062 memcpy ((char *) &n
, data
+ offset
, sizeof (uint64_t));
1063 offset
+= sizeof (uint64_t);
1064 if (need_swap_endian
)
1070 DwrSec::GetData (uint64_t len
)
1072 char *s
= ((char *) data
) + offset
;
1073 if (bounds_violation (len
))
1080 DwrSec::GetString (uint64_t *lenp
)
1085 for (char *s
= ((char *) data
) + offset
; offset
+ len
< size
; len
++)
1088 { // '\0' is inside section
1098 return NULL
; // The section is not '\0' terminated
1112 DwrSec::GetADDR_32 ()
1114 uint64_t res
= reloc
? reloc
->get_reloc_addr (offset
) : 0;
1120 DwrSec::GetADDR_64 ()
1122 uint64_t res
= reloc
? reloc
->get_reloc_addr (offset
) : 0;
1131 return GetADDR_32 ();
1132 return GetADDR_64 ();
1139 return GetADDR_64 ();
1140 return GetADDR_32 ();
1144 DwrSec::GetULEB128 ()
1147 for (int shift
= 0;; shift
+= 7)
1149 ULEB128 val
= Get_8 ();
1150 res
|= (val
& 0x7f) << shift
;
1151 if ((val
& 0x80) == 0)
1158 DwrSec::GetSLEB128 ()
1160 ULEB128 res
= 0, val
= 0;
1165 res
|= (val
& 0x7f) << shift
;
1167 if ((val
& 0x80) == 0)
1170 if ((val
& 0x40) && (shift
< 8 * sizeof (res
)))
1171 res
|= -(((ULEB128
) 1) << shift
);
1172 return (SLEB128
) res
;
1176 fillBuf (unsigned char *s
, int len
, int col
, unsigned char *buf
)
1178 const char *nameX
= "0123456789abcdef";
1179 int i
, n
, posCh
= 2 * col
+ col
/ 4 + 5;
1183 for (i
= n
= 0; i
< len
; i
++, n
+= 2)
1185 if ((i
% 4) == 0 && i
> 0)
1190 buf
[n
] = nameX
[s
[i
] >> 4];
1191 buf
[n
+ 1] = nameX
[s
[i
] & 0xf];
1192 buf
[posCh
+ i
] = isprint (s
[i
]) ? s
[i
] : ' ';
1195 for (i
= n
; i
< posCh
; i
++)
1200 dumpArr (unsigned char *s
, int len
, int col
, int num
)
1202 unsigned char buf
[128];
1205 for (int i
= 0; i
< len
; i
+= col
, num
+= col
)
1207 fillBuf (s
+ i
, len
- i
, col
, buf
);
1208 Dprintf (DUMP_DWARFLIB
, "%5d: %s\n", num
, buf
);
1213 DwrSec::dump (char *msg
)
1217 Dprintf (DUMP_DWARFLIB
, NTXT ("======= DwrSec::dump\n"));
1219 Dprintf (DUMP_DWARFLIB
, NTXT ("%s:\n"), msg
);
1220 dumpArr (data
, (int) sizeSec
, 32, 0);
1221 Dprintf (DUMP_DWARFLIB
, NTXT ("\n"));
1225 //////////////////////////////////////////////////////////
1226 // class DwrFileNames
1228 DwrFileName::DwrFileName (char *_fname
)
1238 DwrFileName::~DwrFileName ()
1245 //////////////////////////////////////////////////////////
1255 DwrLine::~DwrLine () { }
1258 //////////////////////////////////////////////////////////
1259 // class DwrLineRegs
1261 LineRegsCmp (const void *a
, const void *b
)
1263 DwrLine
*item1
= *((DwrLine
**) a
);
1264 DwrLine
*item2
= *((DwrLine
**) b
);
1265 return item1
->address
== item2
->address
? 0 :
1266 item1
->address
> item2
->address
? 1 : -1;
1269 DwrLineRegs::DwrLineRegs (DwrSec
*secp
, char *dirName
)
1271 // `dwarfdump -vv -l` shows a line section (.debug_line)
1272 debug_lineSec
= secp
;
1273 uint64_t stmt_offset
= debug_lineSec
->offset
;
1274 uint64_t next_cu_offset
= debug_lineSec
->ReadLength ();
1275 uint64_t header_offset
= debug_lineSec
->offset
;
1276 debug_lineSec
->size
= next_cu_offset
;
1277 version
= debug_lineSec
->Get_16 ();
1278 header_length
= debug_lineSec
->GetLong ();
1279 opcode_start
= debug_lineSec
->offset
+ header_length
;
1280 minimum_instruction_length
= debug_lineSec
->Get_8 ();
1281 op_index_register
= 0;
1283 maximum_operations_per_instruction
= debug_lineSec
->Get_8 ();
1285 maximum_operations_per_instruction
= 1;
1286 default_is_stmt
= debug_lineSec
->Get_8 ();
1287 is_stmt
= (default_is_stmt
!= 0);
1288 line_base
= debug_lineSec
->Get_8 ();
1289 line_range
= debug_lineSec
->Get_8 ();
1290 opcode_base
= debug_lineSec
->Get_8 ();
1291 standard_opcode_length
= (Dwarf_Small
*) debug_lineSec
->GetData (opcode_base
- 1);
1293 if (DUMP_DWR_LINE_REGS
)
1295 Dprintf (DUMP_DWR_LINE_REGS
,
1296 "\n.debug_line version=%d stmt_offset=0x%llx"
1297 "header_offset=0x%llx size=%lld dirname='%s'\n"
1298 " header_length=0x%llx opcode_start=0x%llx"
1299 "minimum_instruction_length=%d default_is_stmt=%d\n"
1300 " line_base=%d line_range=%d opcode_base=%d\n",
1301 (int) version
, (long long) stmt_offset
,
1302 (long long) header_offset
,
1303 (long long) (next_cu_offset
- header_offset
), STR (dirName
),
1304 (long long) header_length
, (long long) opcode_start
,
1305 (int) minimum_instruction_length
, (int) default_is_stmt
,
1306 (int) line_base
, (int) line_range
, (int) opcode_base
);
1307 if (standard_opcode_length
== NULL
)
1308 Dprintf (DUMP_DWR_LINE_REGS
, "ERROR: standard_opcode_length is NULL\n");
1309 for (int i
= 0, sz
= standard_opcode_length
? opcode_base
- 1 : 0;
1311 Dprintf (DUMP_DWR_LINE_REGS
, " opcode[%2d] length %2d\n", i
,
1312 (int) standard_opcode_length
[i
]);
1315 include_directories
= new Vector
<char *>;
1316 include_directories
->append (dirName
);
1319 char *s
= debug_lineSec
->GetString (NULL
);
1322 include_directories
->append (s
);
1325 file_names
= new Vector
<DwrFileName
*>;
1328 char *s
= debug_lineSec
->GetString (NULL
);
1331 DwrFileName
*fnp
= new DwrFileName (s
);
1334 fnp
->dir_index
= debug_lineSec
->GetULEB128_32 ();
1335 fnp
->timestamp
= debug_lineSec
->GetULEB128 ();
1336 fnp
->file_size
= debug_lineSec
->GetULEB128 ();
1337 file_names
->append (fnp
);
1343 DwrLineRegs::~DwrLineRegs ()
1345 Destroy (file_names
);
1347 delete debug_lineSec
;
1348 delete include_directories
;
1352 DwrLineRegs::dump ()
1354 if (!DUMP_DWR_LINE_REGS
)
1356 Dprintf (DUMP_DWR_LINE_REGS
, NTXT ("\ninclude_directories size=%lld\n"), (long long) VecSize (include_directories
));
1357 for (long i
= 0, sz
= VecSize (include_directories
); i
< sz
; i
++)
1359 char *s
= include_directories
->get (i
);
1360 Dprintf (DUMP_DWR_LINE_REGS
, NTXT (" %2lld %s\n"), (long long) i
, STR (s
));
1363 Dprintf (DUMP_DWR_LINE_REGS
, NTXT ("\nfile_names size=%lld\n"), (long long) VecSize (file_names
));
1364 for (long i
= 0, sz
= VecSize (file_names
); i
< sz
; i
++)
1366 DwrFileName
*fnp
= file_names
->get (i
);
1367 Dprintf (DUMP_DWR_LINE_REGS
, NTXT (" %2lld %-40s dir_index=%4lld timestamp=%8lld file_size=%lld\n"),
1368 (long long) i
, STR (fnp
->fname
),
1369 (long long) fnp
->dir_index
, (long long) fnp
->timestamp
, (long long) fnp
->file_size
);
1372 lines
->dump (fname
);
1373 Dprintf (DUMP_DWR_LINE_REGS
, NTXT ("\n\n"));
1377 DwrLineRegs::DoExtendedOpcode ()
1379 uint64_t size
= debug_lineSec
->GetULEB128 ();
1382 Dprintf (DUMP_DWR_LINE_REGS
, NTXT ("%-20s"), NTXT ("ExtendedOpCode: size=0"));
1385 Dwarf_Small opcode
= debug_lineSec
->Get_8 ();
1386 Dprintf (DUMP_DWR_LINE_REGS
, NTXT ("%-20s"), extended_opcode2str (opcode
));
1389 case DW_LNE_end_sequence
:
1390 end_sequence
= true;
1393 case DW_LNE_set_address
:
1394 address
= debug_lineSec
->GetADDR ();
1396 case DW_LNE_define_file
:
1397 // TODO, add file to file list
1398 fname
= debug_lineSec
->GetString (NULL
);
1399 dir_index
= debug_lineSec
->GetULEB128 ();
1400 timestamp
= debug_lineSec
->GetULEB128 ();
1401 file_size
= debug_lineSec
->GetULEB128 ();
1404 debug_lineSec
->GetData (size
- 1); // skip unknown opcode
1410 DwrLineRegs::DoStandardOpcode (int opcode
)
1415 basic_block
= false;
1418 case DW_LNS_advance_pc
:
1419 address
+= debug_lineSec
->GetULEB128 () * minimum_instruction_length
;
1421 case DW_LNS_advance_line
:
1422 line
+= (int) debug_lineSec
->GetSLEB128 ();
1424 case DW_LNS_set_file
:
1425 file
= debug_lineSec
->GetULEB128_32 ();
1427 case DW_LNS_set_column
:
1428 column
= debug_lineSec
->GetULEB128_32 ();
1430 case DW_LNS_negate_stmt
:
1433 case DW_LNS_set_basic_block
:
1436 case DW_LNS_const_add_pc
:
1437 address
+= ((255 - opcode_base
) / line_range
) * minimum_instruction_length
;
1439 case DW_LNS_fixed_advance_pc
:
1440 address
+= debug_lineSec
->Get_16 ();
1442 default: // skip unknown opcode/operands
1443 debug_lineSec
->GetData (standard_opcode_length
?
1444 standard_opcode_length
[opcode
] : 1);
1450 DwrLineRegs::DoSpecialOpcode (int opcode
)
1452 int max_op_per_instr
= maximum_operations_per_instruction
== 0 ? 1
1453 : maximum_operations_per_instruction
;
1454 int operation_advance
= (opcode
/ line_range
);
1455 address
+= minimum_instruction_length
* ((op_index_register
+ operation_advance
) / max_op_per_instr
);
1456 op_index_register
= (op_index_register
+ operation_advance
) % max_op_per_instr
;
1457 line
+= line_base
+ (opcode
% line_range
);
1458 basic_block
= false;
1463 DwrLineRegs::reset ()
1472 is_stmt
= (default_is_stmt
!= 0);
1473 basic_block
= false;
1474 end_sequence
= false;
1478 DwrLineRegs::EmitLine ()
1480 DwrLine
*lnp
= new DwrLine
;
1484 lnp
->column
= column
;
1485 lnp
->address
= address
;
1486 lines
->append (lnp
);
1487 if ((file
> 0) && (file
< VecSize (file_names
)))
1489 DwrFileName
*fnp
= file_names
->get (file
);
1495 DwrLineRegs::get_lines ()
1499 lines
= new Vector
<DwrLine
*>;
1500 debug_lineSec
->offset
= opcode_start
;
1502 Dprintf (DUMP_DWR_LINE_REGS
, "\n offset code address (file, line, column) stmt blck end_seq \n");
1503 while (debug_lineSec
->offset
< debug_lineSec
->size
)
1505 Dprintf (DUMP_DWR_LINE_REGS
, NTXT ("0x%08llx "),
1506 (long long) debug_lineSec
->offset
);
1507 Dwarf_Small opcode
= debug_lineSec
->Get_8 ();
1509 DoExtendedOpcode ();
1510 else if (opcode
< opcode_base
)
1512 DoStandardOpcode (opcode
);
1513 Dprintf (DUMP_DWR_LINE_REGS
, NTXT ("%-20s"), standard_opcode2str (opcode
));
1517 DoSpecialOpcode (opcode
- opcode_base
);
1518 Dprintf (DUMP_DWR_LINE_REGS
, NTXT ("%-20s"),
1519 special_opcode2str (opcode
- opcode_base
));
1521 Dprintf (DUMP_DWR_LINE_REGS
,
1522 " 0x%08llx (%lld, %lld, %lld) %c %c %c\n",
1523 (long long) address
, (long long) file
, (long long) line
,
1524 (long long) column
, is_stmt
? 'T' : 'F',
1525 basic_block
? 'T' : 'F', end_sequence
? 'T' : 'F');
1527 lines
->sort (LineRegsCmp
);
1528 if (DUMP_DWR_LINE_REGS
)
1529 lines
->dump (fname
);
1535 DwrLineRegs::getPath (int fn
)
1538 if ((fn
>= VecSize (file_names
)) || (fn
< 0))
1540 Dprintf (DEBUG_ERR_MSG
, NTXT ("DwrLineRegs::getPath: fn=0x%lld file_names->size()=%lld\n"),
1541 (long long) fn
, (long long) VecSize (file_names
));
1544 DwrFileName
*fnp
= file_names
->fetch (fn
);
1548 char *dir
= fnp
->dir_index
< include_directories
->size () ?
1549 include_directories
->fetch (fnp
->dir_index
) : NULL
;
1550 if ((fnp
->fname
[0] == '/') || (dir
== NULL
) || (*dir
== 0))
1552 fnp
->path
= fnp
->fname
;
1559 char *s
= include_directories
->fetch (0);
1565 sb
.append (fnp
->fname
);
1566 fnp
->path
= canonical_path (sb
.toString ());
1570 DwrCU::DwrCU (Dwarf
*_dwarf
)
1573 cu_offset
= dwarf
->debug_infoSec
->offset
;
1574 debug_infoSec
= new DwrSec (dwarf
->debug_infoSec
, cu_offset
);
1575 next_cu_offset
= debug_infoSec
->ReadLength ();
1576 if (next_cu_offset
> debug_infoSec
->sizeSec
)
1578 Dprintf (DEBUG_ERR_MSG
,
1579 "DwrCU::DwrCU: next_cu_offset(0x%llx) > debug_infoSec->sizeSec(%llx)\n",
1580 (long long) next_cu_offset
, (long long) debug_infoSec
->sizeSec
);
1581 next_cu_offset
= debug_infoSec
->sizeSec
;
1583 debug_infoSec
->size
= next_cu_offset
;
1584 version
= debug_infoSec
->Get_16 ();
1585 debug_abbrev_offset
= debug_infoSec
->GetLong ();
1586 address_size
= debug_infoSec
->Get_8 ();
1587 cu_header_offset
= debug_infoSec
->offset
;
1591 dwrInlinedSubrs
= NULL
;
1593 stmt_list_offset
= 0;
1599 build_abbrevTable (dwarf
->debug_abbrevSec
, debug_abbrev_offset
);
1603 Dprintf (DUMP_DWARFLIB
,
1604 "CU_HEADER: header_offset = 0x%08llx %lld"
1605 "next_header_offset=0x%08llx %lld\n"
1606 " abbrev_offset = 0x%08llx %lld\n"
1607 " unit_length = %lld\n"
1609 " address_size = %d\n"
1611 "debug_info: need_swap_endian=%s fmt64=%s addr32=%s\n",
1612 (long long) cu_offset
, (long long) cu_offset
,
1613 (long long) next_cu_offset
, (long long) next_cu_offset
,
1614 (long long) debug_abbrev_offset
, (long long) debug_abbrev_offset
,
1615 (long long) (next_cu_offset
- cu_offset
),
1616 (int) version
, (int) address_size
,
1617 debug_infoSec
->fmt64
? "true" : "false",
1618 debug_infoSec
->need_swap_endian
? "true" : "false",
1619 debug_infoSec
->fmt64
? "true" : "false",
1620 debug_infoSec
->addr32
? "true" : "false");
1621 Dprintf (DUMP_DWARFLIB
, "\n.debug_abbrev cnt=%d offset=0x%08llx %lld\n",
1622 (int) VecSize (abbrevTable
), (long long) debug_abbrev_offset
,
1623 (long long) debug_abbrev_offset
);
1624 for (int i
= 1, sz
= VecSize (abbrevTable
); i
< sz
; i
++)
1626 DwrAbbrevTable
*abbTbl
= abbrevTable
->get (i
);
1627 Dprintf (DUMP_DWARFLIB
, NTXT ("%5d: %-30s %-20s offset=0x%08llx\n"),
1628 (int) i
, DwrCU::tag2str (abbTbl
->tag
),
1629 abbTbl
->hasChild
? "DW_children_yes" : "DW_children_no",
1630 (long long) abbTbl
->offset
);
1631 for (int i1
= abbTbl
->firstAtForm
; i1
< abbTbl
->lastAtForm
; i1
++)
1633 Dwr_Attr
*atf
= abbrevAtForm
->get (i1
);
1634 Dprintf (DUMP_DWARFLIB
, " %-30s %s\n",
1635 DwrCU::at2str (atf
->at_name
),
1636 DwrCU::form2str (atf
->at_form
));
1645 delete debug_infoSec
;
1647 delete abbrevAtForm
;
1648 Destroy (dwrInlinedSubrs
);
1655 DwrCU::build_abbrevTable (DwrSec
*_debug_abbrevSec
, uint64_t _offset
)
1659 DwrSec
*debug_abbrevSec
= new DwrSec (_debug_abbrevSec
, _offset
);
1660 abbrevTable
= new DbeArray
<DwrAbbrevTable
>(128);
1661 abbrevAtForm
= new DbeArray
<Dwr_Attr
>(512);
1662 abbrevTable
->allocate (1); // skip first
1663 abbrevAtForm
->allocate (1); // skip first
1664 for (int i
= 1; debug_abbrevSec
->offset
< debug_abbrevSec
->size
; i
++)
1666 DwrAbbrevTable abbTbl
;
1667 abbTbl
.offset
= debug_abbrevSec
->offset
;
1668 abbTbl
.code
= debug_abbrevSec
->GetULEB128_32 ();
1669 if (abbTbl
.code
== 0)
1671 else if (i
!= abbTbl
.code
)
1673 dwarf
->elf
->append_msg (CMSG_ERROR
, GTXT ("%s: the abbreviations table is corrupted (%lld <--> %lld)\n"),
1674 get_basename (dwarf
->elf
->get_location ()),
1675 (long long) i
, (long long) abbTbl
.code
);
1678 abbTbl
.tag
= debug_abbrevSec
->GetULEB128_32 ();
1679 abbTbl
.hasChild
= (DW_children_yes
== debug_abbrevSec
->Get_8 ());
1680 abbTbl
.firstAtForm
= abbrevAtForm
->size ();
1681 while (debug_abbrevSec
->offset
< debug_abbrevSec
->size
)
1684 atf
.at_name
= debug_abbrevSec
->GetULEB128_32 ();
1685 atf
.at_form
= debug_abbrevSec
->GetULEB128_32 ();
1686 if (atf
.at_name
== 0 && atf
.at_form
== 0)
1688 abbrevAtForm
->append (atf
);
1690 abbTbl
.lastAtForm
= abbrevAtForm
->size ();
1691 abbrevTable
->append (abbTbl
);
1693 delete debug_abbrevSec
;
1697 DwrCU::set_die (Dwarf_Die die
)
1700 debug_infoSec
->offset
= die
;
1701 if (debug_infoSec
->offset
< cu_header_offset
1702 || debug_infoSec
->offset
>= debug_infoSec
->size
)
1703 return DW_DLV_ERROR
;
1704 dwrTag
.offset
= debug_infoSec
->offset
;
1705 dwrTag
.die
= debug_infoSec
->offset
- cu_offset
;
1706 dwrTag
.num
= debug_infoSec
->GetULEB128_32 ();
1707 if (dwrTag
.num
== 0)
1708 return DW_DLV_NO_ENTRY
;
1709 dwrTag
.abbrevAtForm
= abbrevAtForm
;
1710 DwrAbbrevTable
*abbTbl
= abbrevTable
->get (dwrTag
.num
);
1713 dwarf
->elf
->append_msg (CMSG_ERROR
, GTXT ("%s: the abbreviation code (%lld) does not match for the Dwarf entry (0x%llx)\n"),
1714 get_basename (dwarf
->elf
->get_location ()),
1715 (long long) dwrTag
.num
, (long long) dwrTag
.offset
);
1716 return DW_DLV_ERROR
;
1718 dwrTag
.tag
= abbTbl
->tag
;
1719 dwrTag
.hasChild
= abbTbl
->hasChild
;
1720 dwrTag
.firstAttribute
= abbTbl
->firstAtForm
;
1721 dwrTag
.lastAttribute
= abbTbl
->lastAtForm
;
1722 for (int k
= abbTbl
->firstAtForm
; k
< abbTbl
->lastAtForm
; k
++)
1724 Dwr_Attr
*atf
= abbrevAtForm
->get (k
);
1725 int at_form
= atf
->at_form
;
1726 if (at_form
== DW_FORM_indirect
)
1727 at_form
= debug_infoSec
->GetULEB128_32 ();
1731 atf
->u
.offset
= (address_size
== 4) ? debug_infoSec
->GetADDR_32 ()
1732 : debug_infoSec
->GetADDR_64 ();
1735 atf
->u
.offset
= debug_infoSec
->Get_8 ();
1738 atf
->len
= debug_infoSec
->GetULEB128 ();
1739 atf
->u
.str
= debug_infoSec
->GetData (atf
->len
);
1741 case DW_FORM_block1
:
1742 atf
->len
= debug_infoSec
->Get_8 ();
1743 atf
->u
.str
= debug_infoSec
->GetData (atf
->len
);
1745 case DW_FORM_block2
:
1746 atf
->len
= debug_infoSec
->Get_16 ();
1747 atf
->u
.str
= debug_infoSec
->GetData (atf
->len
);
1749 case DW_FORM_block4
:
1750 atf
->len
= debug_infoSec
->Get_32 ();
1751 atf
->u
.str
= debug_infoSec
->GetData (atf
->len
);
1754 atf
->u
.offset
= debug_infoSec
->Get_8 ();
1757 atf
->u
.offset
= debug_infoSec
->Get_16 ();
1760 atf
->u
.offset
= debug_infoSec
->Get_32 ();
1763 atf
->u
.offset
= debug_infoSec
->Get_64 ();
1765 case DW_FORM_ref_udata
:
1766 atf
->u
.offset
= debug_infoSec
->GetULEB128 ();
1769 atf
->u
.offset
= debug_infoSec
->Get_8 ();
1772 atf
->u
.offset
= debug_infoSec
->Get_16 ();
1775 atf
->u
.offset
= debug_infoSec
->Get_32 ();
1778 atf
->u
.offset
= debug_infoSec
->Get_64 ();
1780 case DW_FORM_string
:
1781 atf
->u
.str
= debug_infoSec
->GetString (&atf
->len
);
1784 atf
->u
.offset
= debug_infoSec
->GetRef ();
1785 if (dwarf
->debug_strSec
== NULL
)
1792 dwarf
->debug_strSec
->offset
= atf
->u
.offset
;
1793 atf
->u
.str
= dwarf
->debug_strSec
->GetString (&atf
->len
);
1797 atf
->u
.val
= debug_infoSec
->GetSLEB128 ();
1800 atf
->u
.offset
= debug_infoSec
->GetULEB128 ();
1802 case DW_FORM_ref_addr
:
1803 atf
->u
.offset
= debug_infoSec
->GetADDR ();
1805 case DW_FORM_sec_offset
:
1806 atf
->u
.offset
= debug_infoSec
->GetRef ();
1808 case DW_FORM_exprloc
:
1809 atf
->u
.offset
= debug_infoSec
->GetULEB128 ();
1810 debug_infoSec
->offset
+= atf
->u
.offset
;
1812 case DW_FORM_flag_present
:
1815 case DW_FORM_ref_sig8
:
1816 atf
->u
.offset
= debug_infoSec
->GetADDR_64 ();
1821 Dprintf (1, "Attribute form 0x%llx (%lld) is not implemented\n",
1822 (long long) atf
->at_form
, (long long) atf
->at_form
);
1835 composePath (char *dname
, char *fname
)
1838 if (*fname
== '/' || dname
== NULL
)
1839 s
= dbe_sprintf (NTXT ("%s"), fname
);
1841 s
= dbe_sprintf (NTXT ("%s/%s"), dname
, fname
);
1842 return canonical_path (s
);
1846 DwrCU::parse_cu_header (LoadObject
*lo
)
1848 // Is tag always DW_TAG_compile_unit?
1849 if (dwrTag
.tag
!= DW_TAG_compile_unit
)
1851 Dprintf (DEBUG_ERR_MSG
,
1852 "parse_cu_header: die=0x%llx tag=%lld is not DW_TAG_compile_unit\n",
1853 (long long) cu_offset
, (long long) dwrTag
.tag
);
1857 char *name
= Dwarf_string (DW_AT_name
);
1859 name
= NTXT ("UnnamedUnit");
1860 stmt_list_offset
= Dwarf_data (DW_AT_stmt_list
);
1861 comp_dir
= dbe_strdup (Dwarf_string (DW_AT_comp_dir
));
1862 char *dir_name
= comp_dir
? StrChr (comp_dir
, ':') : NULL
;
1863 char *orig_name
= Dwarf_string (DW_AT_SUN_original_name
);
1864 char *path
= composePath (dir_name
, orig_name
? orig_name
: name
);
1866 module
= dwarf
->stabs
->append_Module (lo
, path
);
1870 module
->hasDwarf
= true;
1872 module
->linkerStabName
= composePath (dir_name
, name
);
1873 module
->lang_code
= Dwarf_lang ();
1874 module
->comp_flags
= dbe_strdup (Dwarf_string (DW_AT_SUN_command_line
));
1875 if (module
->comp_flags
== NULL
)
1876 module
->comp_flags
= dbe_strdup (Dwarf_string (DW_AT_icc_flags
));
1877 module
->comp_dir
= dbe_strdup (dir_name
);
1879 char *obj_file
= Dwarf_string (DW_AT_SUN_obj_file
);
1880 char *obj_dir
= Dwarf_string (DW_AT_SUN_obj_dir
);
1881 if (obj_dir
&& obj_file
)
1883 // object information may not be available
1884 dir_name
= StrChr (obj_dir
, ':');
1885 path
= composePath (dir_name
, obj_file
);
1886 if (module
->dot_o_file
== NULL
)
1887 module
->dot_o_file
= module
->createLoadObject (path
);
1890 path
= dbe_strdup (dwarf
->stabs
->path
);
1891 module
->set_name (path
);
1896 Dwr_Tag::get_attr (Dwarf_Half attr
)
1898 for (long i
= firstAttribute
; i
< lastAttribute
; i
++)
1900 Dwr_Attr
*atf
= abbrevAtForm
->get (i
);
1901 if (atf
->at_name
== attr
)
1908 DwrCU::Dwarf_string (Dwarf_Half attr
)
1910 Dwr_Attr
*dwrAttr
= dwrTag
.get_attr (attr
);
1911 return dwrAttr
? dwrAttr
->u
.str
: NULL
;
1915 DwrCU::get_high_pc (uint64_t low_pc
)
1917 Dwr_Attr
*dwrAttr
= dwrTag
.get_attr (DW_AT_high_pc
);
1919 switch (dwrAttr
->at_form
)
1922 return dwrAttr
->u
.offset
;
1924 return dwrAttr
->u
.offset
+ low_pc
;
1930 DwrCU::Dwarf_addr (Dwarf_Half attr
)
1932 Dwr_Attr
*dwrAttr
= dwrTag
.get_attr (attr
);
1934 switch (dwrAttr
->at_form
)
1937 return dwrAttr
->u
.offset
;
1943 DwrCU::Dwarf_block (Dwarf_Half attr
)
1945 Dwr_Attr
*dwrAttr
= dwrTag
.get_attr (attr
);
1946 if (dwrAttr
&& dwrAttr
->u
.block
)
1947 switch (dwrAttr
->at_form
)
1950 case DW_FORM_block1
:
1951 case DW_FORM_block2
:
1952 case DW_FORM_block4
:
1953 return new DwrSec (dwrAttr
->u
.block
, dwrAttr
->len
,
1954 dwarf
->elf
->need_swap_endian
,
1955 dwarf
->elf
->elf_getclass () == ELFCLASS32
);
1961 DwrCU::read_data_attr (Dwarf_Half attr
, int64_t *retVal
)
1963 Dwr_Attr
*dwrAttr
= dwrTag
.get_attr (attr
);
1965 switch (dwrAttr
->at_form
)
1972 case DW_FORM_sec_offset
:
1973 *retVal
= dwrAttr
->u
.val
;
1977 return DW_DLV_ERROR
;
1981 DwrCU::read_ref_attr (Dwarf_Half attr
, int64_t *retVal
)
1983 Dwr_Attr
*dwrAttr
= dwrTag
.get_attr (attr
);
1985 switch (dwrAttr
->at_form
)
1991 case DW_FORM_ref_udata
:
1992 case DW_FORM_sec_offset
:
1993 case DW_FORM_exprloc
:
1994 case DW_FORM_ref_sig8
:
1995 *retVal
= dwrAttr
->u
.val
;
1998 return DW_DLV_ERROR
;
2002 DwrCU::Dwarf_data (Dwarf_Half attr
)
2005 if (read_data_attr (attr
, &retVal
) == DW_DLV_OK
)
2011 DwrCU::Dwarf_ref (Dwarf_Half attr
)
2014 if (read_ref_attr (attr
, &retVal
) == DW_DLV_OK
)
2020 DwrCU::Dwarf_location (Dwarf_Attribute attr
)
2022 DwrSec
*secp
= Dwarf_block (attr
);
2026 DwrLocation
*lp
= dwr_get_location (secp
, &loc
);
2029 return lp
->lc_number
;
2035 DwrCU::map_dwarf_lines (Module
*mod
)
2037 DwrLineRegs
*lineReg
= get_dwrLineReg ();
2038 long inlinedSubrCnt
= VecSize (dwrInlinedSubrs
);
2039 if (isGNU
&& (inlinedSubrCnt
> 0))
2041 Function
*func
= NULL
;
2042 mod
->inlinedSubr
= (InlinedSubr
*) malloc (inlinedSubrCnt
2043 * sizeof (InlinedSubr
));
2044 for (long i
= 0; i
< inlinedSubrCnt
; i
++)
2046 DwrInlinedSubr
*inlinedSubr
= dwrInlinedSubrs
->get (i
);
2048 Function
*f
= dwarf
->stabs
->map_PC_to_func (inlinedSubr
->low_pc
,
2049 low_pc
, mod
->functions
);
2055 func
->inlinedSubrCnt
= 0;
2056 func
->inlinedSubr
= mod
->inlinedSubr
+ i
;
2058 InlinedSubr
*p
= func
->inlinedSubr
+ func
->inlinedSubrCnt
;
2059 func
->inlinedSubrCnt
++;
2060 int fileno
= inlinedSubr
->file
- 1;
2061 SourceFile
*sf
= ((fileno
>= 0) && (fileno
< VecSize (srcFiles
))) ?
2062 srcFiles
->get (fileno
) : dbeSession
->get_Unknown_Source ();
2063 p
->dbeLine
= sf
->find_dbeline (inlinedSubr
->line
);
2064 p
->high_pc
= inlinedSubr
->high_pc
- low_pc
;
2065 p
->low_pc
= inlinedSubr
->low_pc
- low_pc
;
2066 p
->level
= inlinedSubr
->level
;
2069 if (set_die (inlinedSubr
->abstract_origin
) == DW_DLV_OK
)
2070 p
->fname
= dbe_strdup (Dwarf_string (DW_AT_name
));
2072 p
->func
= Stabs::find_func (p
->fname
, mod
->functions
,
2073 Stabs::is_fortran (mod
->lang_code
));
2076 Vector
<DwrLine
*> *lines
= lineReg
->get_lines ();
2078 Include
*includes
= new Include
;
2079 includes
->new_src_file (mod
->getMainSrc (), 0, NULL
);
2081 SourceFile
*cur_src
= NULL
;
2082 Function
*cur_func
= NULL
;
2083 for (long i
= 0, sz
= VecSize (lines
); i
< sz
; i
++)
2085 DwrLine
*dwrLine
= lines
->get (i
);
2086 char *filename
= dwrLineReg
->getPath (dwrLine
->file
);
2087 if (filename
== NULL
)
2089 uint64_t pc
= dwrLine
->address
;
2090 int lineno
= dwrLine
->line
;
2091 if (path
!= filename
)
2094 char *name
= StrChr (path
, ':');
2095 SourceFile
*src
= mod
->setIncludeFile (name
);
2098 includes
->new_src_file (src
, lineno
, cur_func
);
2103 Function
*func
= dwarf
->stabs
->map_PC_to_func (pc
, low_pc
, mod
->functions
);
2104 if (func
&& (func
->module
== mod
))
2106 if (func
!= cur_func
)
2109 while (cur_func
->popSrcFile () != NULL
)
2112 includes
->push_src_files (cur_func
);
2114 cur_func
->add_PC_info (pc
- low_pc
, lineno
);
2118 while (cur_func
->popSrcFile ())
2124 DwrCU::get_dwrLineReg ()
2126 if (dwrLineReg
== NULL
)
2127 dwrLineReg
= new DwrLineRegs (new DwrSec (dwarf
->debug_lineSec
,
2128 stmt_list_offset
), comp_dir
);
2133 DwrCU::parse_inlined_subroutine (Dwarf_cnt
*ctx
)
2135 int64_t abstract_origin
= Dwarf_ref (DW_AT_abstract_origin
);
2136 int fileno
= (int) Dwarf_data (DW_AT_call_file
);
2137 int lineno
= (int) Dwarf_data (DW_AT_call_line
);
2138 int level
= ctx
->inlinedSubr
? (ctx
->inlinedSubr
->level
+ 1) : 0;
2139 DwrInlinedSubr
*inlinedSubr_old
= ctx
->inlinedSubr
;
2141 if (dwrInlinedSubrs
== NULL
)
2142 dwrInlinedSubrs
= new Vector
<DwrInlinedSubr
*>;
2143 Dwr_Attr
*dwrAttr
= dwrTag
.get_attr (DW_AT_ranges
);
2146 uint64_t ranges
= Dwarf_ref (DW_AT_ranges
);
2147 if (dwarf
->debug_rangesSec
&& (ranges
< dwarf
->debug_rangesSec
->size
))
2149 dwarf
->debug_rangesSec
->offset
= ranges
;
2152 uint64_t low_pc
= dwarf
->debug_rangesSec
->GetADDR ();
2153 uint64_t high_pc
= dwarf
->debug_rangesSec
->GetADDR ();
2154 if ((low_pc
> 0) && (low_pc
<= high_pc
))
2156 DwrInlinedSubr
*p
= new DwrInlinedSubr (abstract_origin
,
2157 low_pc
, high_pc
, fileno
, lineno
, level
);
2158 dwrInlinedSubrs
->append (p
);
2159 ctx
->inlinedSubr
= p
;
2168 uint64_t low_pc
= Dwarf_addr (DW_AT_low_pc
);
2169 uint64_t high_pc
= get_high_pc (low_pc
);
2170 if ((low_pc
> 0) && (low_pc
<= high_pc
))
2172 DwrInlinedSubr
*p
= new DwrInlinedSubr (abstract_origin
, low_pc
,
2173 high_pc
, fileno
, lineno
, level
);
2174 dwrInlinedSubrs
->append (p
);
2175 ctx
->inlinedSubr
= p
;
2179 ctx
->inlinedSubr
= inlinedSubr_old
;
2183 //////////////////////////////////////////////////////////
2184 // class DwrInlinedSubr
2185 DwrInlinedSubr::DwrInlinedSubr (int64_t _abstract_origin
, uint64_t _low_pc
,
2186 uint64_t _high_pc
, int _file
, int _line
, int _level
)
2188 abstract_origin
= _abstract_origin
;
2197 DwrInlinedSubr::dump ()
2199 Dprintf (DUMP_DWARFLIB
,
2200 " level=%d 0x%08llx [0x%08llx - 0x%08llx] file=%d line=%d\n",
2201 (int) level
, (long long) abstract_origin
, (long long) low_pc
,
2202 (long long) high_pc
, (int) file
, (int) line
);