rdwarf 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +28 -0
  6. data/README.md +39 -0
  7. data/Rakefile +8 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +7 -0
  10. data/ext/rdwarf/depend +5 -0
  11. data/ext/rdwarf/extconf.rb +29 -0
  12. data/ext/rdwarf/libdwarf/CHANGES +102 -0
  13. data/ext/rdwarf/libdwarf/CODINGSTYLE +71 -0
  14. data/ext/rdwarf/libdwarf/COPYING +28 -0
  15. data/ext/rdwarf/libdwarf/ChangeLog +619 -0
  16. data/ext/rdwarf/libdwarf/ChangeLog2006 +835 -0
  17. data/ext/rdwarf/libdwarf/ChangeLog2007 +217 -0
  18. data/ext/rdwarf/libdwarf/ChangeLog2008 +263 -0
  19. data/ext/rdwarf/libdwarf/ChangeLog2009 +348 -0
  20. data/ext/rdwarf/libdwarf/ChangeLog2010 +175 -0
  21. data/ext/rdwarf/libdwarf/ChangeLog2011 +297 -0
  22. data/ext/rdwarf/libdwarf/ChangeLog2012 +131 -0
  23. data/ext/rdwarf/libdwarf/ChangeLog2013 +238 -0
  24. data/ext/rdwarf/libdwarf/ChangeLog2014 +399 -0
  25. data/ext/rdwarf/libdwarf/LGPL.txt +504 -0
  26. data/ext/rdwarf/libdwarf/LIBDWARFCOPYRIGHT +40 -0
  27. data/ext/rdwarf/libdwarf/Makefile.in +220 -0
  28. data/ext/rdwarf/libdwarf/NEWS +535 -0
  29. data/ext/rdwarf/libdwarf/README +235 -0
  30. data/ext/rdwarf/libdwarf/checkexamples.c +1179 -0
  31. data/ext/rdwarf/libdwarf/cmplrs/dwarf_addr_finder.h +55 -0
  32. data/ext/rdwarf/libdwarf/common.c +62 -0
  33. data/ext/rdwarf/libdwarf/common.h +38 -0
  34. data/ext/rdwarf/libdwarf/config.h.in +146 -0
  35. data/ext/rdwarf/libdwarf/configure +5581 -0
  36. data/ext/rdwarf/libdwarf/configure.in +167 -0
  37. data/ext/rdwarf/libdwarf/dw-linetableheader.txt +39 -0
  38. data/ext/rdwarf/libdwarf/dwarf.h +1342 -0
  39. data/ext/rdwarf/libdwarf/dwarf_abbrev.c +291 -0
  40. data/ext/rdwarf/libdwarf/dwarf_abbrev.h +45 -0
  41. data/ext/rdwarf/libdwarf/dwarf_addr_finder.c +676 -0
  42. data/ext/rdwarf/libdwarf/dwarf_alloc.c +685 -0
  43. data/ext/rdwarf/libdwarf/dwarf_alloc.h +38 -0
  44. data/ext/rdwarf/libdwarf/dwarf_arange.c +595 -0
  45. data/ext/rdwarf/libdwarf/dwarf_arange.h +62 -0
  46. data/ext/rdwarf/libdwarf/dwarf_base_types.h +157 -0
  47. data/ext/rdwarf/libdwarf/dwarf_die_deliv.c +1802 -0
  48. data/ext/rdwarf/libdwarf/dwarf_die_deliv.h +46 -0
  49. data/ext/rdwarf/libdwarf/dwarf_elf_access.c +1348 -0
  50. data/ext/rdwarf/libdwarf/dwarf_elf_access.h +46 -0
  51. data/ext/rdwarf/libdwarf/dwarf_error.c +492 -0
  52. data/ext/rdwarf/libdwarf/dwarf_error.h +53 -0
  53. data/ext/rdwarf/libdwarf/dwarf_form.c +1302 -0
  54. data/ext/rdwarf/libdwarf/dwarf_frame.c +2454 -0
  55. data/ext/rdwarf/libdwarf/dwarf_frame.h +418 -0
  56. data/ext/rdwarf/libdwarf/dwarf_frame2.c +1533 -0
  57. data/ext/rdwarf/libdwarf/dwarf_frame3.c +282 -0
  58. data/ext/rdwarf/libdwarf/dwarf_funcs.c +123 -0
  59. data/ext/rdwarf/libdwarf/dwarf_funcs.h +33 -0
  60. data/ext/rdwarf/libdwarf/dwarf_gdbindex.c +520 -0
  61. data/ext/rdwarf/libdwarf/dwarf_gdbindex.h +97 -0
  62. data/ext/rdwarf/libdwarf/dwarf_global.c +612 -0
  63. data/ext/rdwarf/libdwarf/dwarf_global.h +117 -0
  64. data/ext/rdwarf/libdwarf/dwarf_harmless.c +228 -0
  65. data/ext/rdwarf/libdwarf/dwarf_harmless.h +31 -0
  66. data/ext/rdwarf/libdwarf/dwarf_incl.h +61 -0
  67. data/ext/rdwarf/libdwarf/dwarf_init_finish.c +1263 -0
  68. data/ext/rdwarf/libdwarf/dwarf_leb.c +159 -0
  69. data/ext/rdwarf/libdwarf/dwarf_line.c +1822 -0
  70. data/ext/rdwarf/libdwarf/dwarf_line.h +446 -0
  71. data/ext/rdwarf/libdwarf/dwarf_line2.c +98 -0
  72. data/ext/rdwarf/libdwarf/dwarf_line_table_reader_common.c +1583 -0
  73. data/ext/rdwarf/libdwarf/dwarf_loc.c +1525 -0
  74. data/ext/rdwarf/libdwarf/dwarf_loc.h +149 -0
  75. data/ext/rdwarf/libdwarf/dwarf_loc2.c +833 -0
  76. data/ext/rdwarf/libdwarf/dwarf_macro.c +479 -0
  77. data/ext/rdwarf/libdwarf/dwarf_macro.h +35 -0
  78. data/ext/rdwarf/libdwarf/dwarf_opaque.h +778 -0
  79. data/ext/rdwarf/libdwarf/dwarf_original_elf_init.c +219 -0
  80. data/ext/rdwarf/libdwarf/dwarf_print_lines.c +631 -0
  81. data/ext/rdwarf/libdwarf/dwarf_pubtypes.c +132 -0
  82. data/ext/rdwarf/libdwarf/dwarf_query.c +1594 -0
  83. data/ext/rdwarf/libdwarf/dwarf_ranges.c +194 -0
  84. data/ext/rdwarf/libdwarf/dwarf_reloc_arm.h +308 -0
  85. data/ext/rdwarf/libdwarf/dwarf_reloc_mips.h +117 -0
  86. data/ext/rdwarf/libdwarf/dwarf_reloc_ppc.h +242 -0
  87. data/ext/rdwarf/libdwarf/dwarf_reloc_ppc64.h +272 -0
  88. data/ext/rdwarf/libdwarf/dwarf_reloc_x86_64.h +127 -0
  89. data/ext/rdwarf/libdwarf/dwarf_sort_line.c +665 -0
  90. data/ext/rdwarf/libdwarf/dwarf_string.c +82 -0
  91. data/ext/rdwarf/libdwarf/dwarf_stubs.c +38 -0
  92. data/ext/rdwarf/libdwarf/dwarf_tied.c +423 -0
  93. data/ext/rdwarf/libdwarf/dwarf_tsearch.h +125 -0
  94. data/ext/rdwarf/libdwarf/dwarf_tsearchhash.c +675 -0
  95. data/ext/rdwarf/libdwarf/dwarf_types.c +121 -0
  96. data/ext/rdwarf/libdwarf/dwarf_types.h +32 -0
  97. data/ext/rdwarf/libdwarf/dwarf_util.c +913 -0
  98. data/ext/rdwarf/libdwarf/dwarf_util.h +324 -0
  99. data/ext/rdwarf/libdwarf/dwarf_vars.c +125 -0
  100. data/ext/rdwarf/libdwarf/dwarf_vars.h +29 -0
  101. data/ext/rdwarf/libdwarf/dwarf_weaks.c +123 -0
  102. data/ext/rdwarf/libdwarf/dwarf_weaks.h +29 -0
  103. data/ext/rdwarf/libdwarf/dwarf_xu_index.c +579 -0
  104. data/ext/rdwarf/libdwarf/dwarf_xu_index.h +68 -0
  105. data/ext/rdwarf/libdwarf/dwgetopt.c +181 -0
  106. data/ext/rdwarf/libdwarf/dwgetopt.h +51 -0
  107. data/ext/rdwarf/libdwarf/gennames.c +531 -0
  108. data/ext/rdwarf/libdwarf/install.sh +119 -0
  109. data/ext/rdwarf/libdwarf/libdwarf.h.in +3746 -0
  110. data/ext/rdwarf/libdwarf/libdwarf2.1.mm +9805 -0
  111. data/ext/rdwarf/libdwarf/libdwarf2.1.pdf +0 -0
  112. data/ext/rdwarf/libdwarf/libdwarf2p.1.mm +2807 -0
  113. data/ext/rdwarf/libdwarf/libdwarf2p.1.pdf +0 -0
  114. data/ext/rdwarf/libdwarf/libdwarfdefs.h +81 -0
  115. data/ext/rdwarf/libdwarf/malloc_check.c +327 -0
  116. data/ext/rdwarf/libdwarf/malloc_check.h +52 -0
  117. data/ext/rdwarf/libdwarf/mips_extensions.mm +1266 -0
  118. data/ext/rdwarf/libdwarf/mips_extensions.pdf +0 -0
  119. data/ext/rdwarf/libdwarf/pro_alloc.c +179 -0
  120. data/ext/rdwarf/libdwarf/pro_alloc.h +33 -0
  121. data/ext/rdwarf/libdwarf/pro_arange.c +310 -0
  122. data/ext/rdwarf/libdwarf/pro_arange.h +51 -0
  123. data/ext/rdwarf/libdwarf/pro_die.c +431 -0
  124. data/ext/rdwarf/libdwarf/pro_die.h +59 -0
  125. data/ext/rdwarf/libdwarf/pro_encode_nm.c +108 -0
  126. data/ext/rdwarf/libdwarf/pro_encode_nm.h +39 -0
  127. data/ext/rdwarf/libdwarf/pro_error.c +96 -0
  128. data/ext/rdwarf/libdwarf/pro_error.h +43 -0
  129. data/ext/rdwarf/libdwarf/pro_expr.c +575 -0
  130. data/ext/rdwarf/libdwarf/pro_expr.h +36 -0
  131. data/ext/rdwarf/libdwarf/pro_finish.c +45 -0
  132. data/ext/rdwarf/libdwarf/pro_forms.c +1271 -0
  133. data/ext/rdwarf/libdwarf/pro_frame.c +572 -0
  134. data/ext/rdwarf/libdwarf/pro_frame.h +120 -0
  135. data/ext/rdwarf/libdwarf/pro_funcs.c +50 -0
  136. data/ext/rdwarf/libdwarf/pro_incl.h +91 -0
  137. data/ext/rdwarf/libdwarf/pro_init.c +327 -0
  138. data/ext/rdwarf/libdwarf/pro_line.c +373 -0
  139. data/ext/rdwarf/libdwarf/pro_line.h +112 -0
  140. data/ext/rdwarf/libdwarf/pro_macinfo.c +457 -0
  141. data/ext/rdwarf/libdwarf/pro_macinfo.h +31 -0
  142. data/ext/rdwarf/libdwarf/pro_opaque.h +513 -0
  143. data/ext/rdwarf/libdwarf/pro_pubnames.c +60 -0
  144. data/ext/rdwarf/libdwarf/pro_reloc.c +253 -0
  145. data/ext/rdwarf/libdwarf/pro_reloc.h +38 -0
  146. data/ext/rdwarf/libdwarf/pro_reloc_stream.c +256 -0
  147. data/ext/rdwarf/libdwarf/pro_reloc_stream.h +52 -0
  148. data/ext/rdwarf/libdwarf/pro_reloc_symbolic.c +245 -0
  149. data/ext/rdwarf/libdwarf/pro_reloc_symbolic.h +45 -0
  150. data/ext/rdwarf/libdwarf/pro_section.c +2233 -0
  151. data/ext/rdwarf/libdwarf/pro_section.h +100 -0
  152. data/ext/rdwarf/libdwarf/pro_types.c +274 -0
  153. data/ext/rdwarf/libdwarf/pro_types.h +34 -0
  154. data/ext/rdwarf/libdwarf/pro_util.h +38 -0
  155. data/ext/rdwarf/libdwarf/pro_vars.c +52 -0
  156. data/ext/rdwarf/libdwarf/pro_weaks.c +51 -0
  157. data/ext/rdwarf/rdwarf.c +765 -0
  158. data/ext/rdwarf/rdwarf.h +52 -0
  159. data/ext/rdwarf/rdwarf_names_gen.rb +109 -0
  160. data/lib/rdwarf.rb +181 -0
  161. data/lib/rdwarf/version.rb +3 -0
  162. data/rdwarf.gemspec +30 -0
  163. metadata +251 -0
@@ -0,0 +1,62 @@
1
+ /*
2
+
3
+ Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved.
4
+ Portions Copyright (C) 2011 David Anderson. All Rights Reserved.
5
+
6
+ This program is free software; you can redistribute it and/or modify it
7
+ under the terms of version 2.1 of the GNU Lesser General Public License
8
+ as published by the Free Software Foundation.
9
+
10
+ This program is distributed in the hope that it would be useful, but
11
+ WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+
14
+ Further, this software is distributed without any warranty that it is
15
+ free of the rightful claim of any third person regarding infringement
16
+ or the like. Any license provided herein, whether implied or
17
+ otherwise, applies only to this software file. Patent licenses, if
18
+ any, provided herein do not apply to combinations of this program with
19
+ other software, or any other product whatsoever.
20
+
21
+ You should have received a copy of the GNU Lesser General Public
22
+ License along with this program; if not, write the Free Software
23
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24
+ USA.
25
+
26
+ */
27
+
28
+
29
+
30
+ /* This structure is used to read an arange into. */
31
+ struct Dwarf_Arange_s {
32
+
33
+ /* The segment selector. Only non-zero if Dwarf4, only
34
+ meaningful if ar_segment_selector_size non-zero */
35
+ Dwarf_Unsigned ar_segment_selector;
36
+
37
+ /* Starting address of the arange, ie low-pc. */
38
+ Dwarf_Addr ar_address;
39
+
40
+ /* Length of the arange. */
41
+ Dwarf_Unsigned ar_length;
42
+
43
+
44
+ /* Offset into .debug_info of the start of the compilation-unit
45
+ containing this set of aranges.
46
+ Applies only to .debug_info, not .debug_types. */
47
+ Dwarf_Off ar_info_offset;
48
+
49
+ /* Corresponding Dwarf_Debug. */
50
+ Dwarf_Debug ar_dbg;
51
+
52
+ Dwarf_Half ar_segment_selector_size;
53
+ };
54
+
55
+
56
+
57
+ int
58
+ _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg,
59
+ Dwarf_Addr ** addrs,
60
+ Dwarf_Off ** offsets,
61
+ Dwarf_Signed * count,
62
+ Dwarf_Error * error);
@@ -0,0 +1,157 @@
1
+ /*
2
+
3
+ Copyright (C) 2000,2005 Silicon Graphics, Inc. All Rights Reserved.
4
+ Portions Copyright (C) 2008-2012 David Anderson. All Rights Reserved.
5
+
6
+ This program is free software; you can redistribute it and/or modify it
7
+ under the terms of version 2.1 of the GNU Lesser General Public License
8
+ as published by the Free Software Foundation.
9
+
10
+ This program is distributed in the hope that it would be useful, but
11
+ WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+
14
+ Further, this software is distributed without any warranty that it is
15
+ free of the rightful claim of any third person regarding infringement
16
+ or the like. Any license provided herein, whether implied or
17
+ otherwise, applies only to this software file. Patent licenses, if
18
+ any, provided herein do not apply to combinations of this program with
19
+ other software, or any other product whatsoever.
20
+
21
+ You should have received a copy of the GNU Lesser General Public
22
+ License along with this program; if not, write the Free Software
23
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24
+ USA.
25
+
26
+ */
27
+
28
+
29
+
30
+ #include "libdwarfdefs.h"
31
+
32
+ #define true 1
33
+ #define false 0
34
+
35
+ /* .debug_addr new in DWARF5 */
36
+ #define DW_ADDR_VERSION5 5
37
+
38
+ /* To identify a cie. That is, for .debug_frame */
39
+ #define DW_CIE_ID ~(0x0)
40
+ #define DW_CIE_VERSION 1 /* DWARF2 */
41
+ #define DW_CIE_VERSION3 3 /* DWARF3 */
42
+ #define DW_CIE_VERSION4 4 /* DWARF4 */
43
+ #define DW_CIE_VERSION5 5 /* DWARF5 */
44
+
45
+ /* For .debug_info DWARF2,3,4,5.
46
+ .debug_types in DWARF4 only, and gets DW_CU_VERSION4. */
47
+ #define DW_CU_VERSION2 2
48
+ #define DW_CU_VERSION3 3
49
+ #define DW_CU_VERSION4 4
50
+ #define DW_CU_VERSION5 5
51
+
52
+ /* DWARF2,3, 4 and 5.*/
53
+ #define DW_ARANGES_VERSION2 2
54
+
55
+ #define DW_LINE_VERSION2 2
56
+ #define DW_LINE_VERSION3 3
57
+ #define DW_LINE_VERSION4 4
58
+ #define DW_LINE_VERSION5 5
59
+
60
+ /* .debug_line_str (and .dwo) new in DWARF5. */
61
+ #define DW_LINE_STR_VERSION5 5
62
+ #define EXPERIMENTAL_LINE_TABLES_VERSION 0xf006 /* Experimental two-level line tables */
63
+
64
+ /* .debug_loc (and .dwo) First header version number is DWARF5. */
65
+ #define DW_LOC_VERSION5 5
66
+
67
+
68
+
69
+ /* .debug_macro (and .dwo) new in DWARF5. */
70
+ #define DW_MACRO_VERSION5 5
71
+ /* .debug_names new in DWARF5. */
72
+ #define DW_NAMES_VERSION5 5
73
+
74
+ /* .debug_pubnames in DWARF2,3,4. */
75
+ #define DW_PUBNAMES_VERSION2 2
76
+ /* .debug_pubnames in DWARF3,4. */
77
+ #define DW_PUBTYPES_VERSION2 2
78
+
79
+ /* .debug_ranges gets a version number in header in DWARF5. */
80
+ #define DW_RANGES_VERSION5 5
81
+
82
+
83
+ /* .debug_str_offsets (and .dwo) new in DWARF5. */
84
+ #define DW_STR_OFFSETS_VERSION5 5
85
+
86
+ /* .debug_sup new in DWARF5. */
87
+ #define DW_SUP_VERSION5 5
88
+
89
+ /* .debug_cu_index new in DWARF5. */
90
+ #define DW_CU_INDEX_VERSION5 5
91
+ /* .debug_tu_index new in DWARF5. */
92
+ #define DW_TU_INDEX_VERSION5 5
93
+
94
+
95
+
96
+
97
+
98
+ /* These are allocation type codes for structs that
99
+ are internal to the Libdwarf Consumer library. */
100
+ #define DW_DLA_ABBREV_LIST 0x1e
101
+ #define DW_DLA_CHAIN 0x1f
102
+ #define DW_DLA_CU_CONTEXT 0x20
103
+ #define DW_DLA_FRAME 0x21
104
+ #define DW_DLA_GLOBAL_CONTEXT 0x22
105
+ #define DW_DLA_FILE_ENTRY 0x23
106
+ #define DW_DLA_LINE_CONTEXT 0x24
107
+ #define DW_DLA_LOC_CHAIN 0x25
108
+ #define DW_DLA_HASH_TABLE 0x26
109
+ #define DW_DLA_FUNC_CONTEXT 0x27
110
+ #define DW_DLA_TYPENAME_CONTEXT 0x28
111
+ #define DW_DLA_VAR_CONTEXT 0x29
112
+ #define DW_DLA_WEAK_CONTEXT 0x2a
113
+ #define DW_DLA_PUBTYPES_CONTEXT 0x2b /* DWARF3 */
114
+ #define DW_DLA_HASH_TABLE_ENTRY 0x2c
115
+ #define DW_DLA_FISSION_PERCU 0x2d
116
+ /* Thru 0x36 reserved for internal future use. */
117
+
118
+ /* Maximum number of allocation types for allocation routines.
119
+ Only used with malloc_check.c and that is basically obsolete. */
120
+ #define MAX_DW_DLA 0x3a
121
+
122
+ /*Dwarf_Word is unsigned word usable for index, count in memory */
123
+ /*Dwarf_Sword is signed word usable for index, count in memory */
124
+ /* They are 32 or 64 bits depending if 64 bit longs or not, which
125
+ fits the ILP32 and LP64 models
126
+ These work equally well with ILP64. */
127
+
128
+ typedef unsigned long Dwarf_Word;
129
+ typedef signed long Dwarf_Sword;
130
+
131
+ typedef signed char Dwarf_Sbyte;
132
+ typedef unsigned char Dwarf_Ubyte;
133
+ typedef signed short Dwarf_Shalf;
134
+ typedef Dwarf_Small *Dwarf_Byte_Ptr;
135
+
136
+ /* These 2 are fixed sizes which must not vary with the
137
+ ILP32/LP64 model. Between these two, stay at 32 bit. */
138
+ typedef __uint32_t Dwarf_ufixed;
139
+ typedef __int32_t Dwarf_sfixed;
140
+
141
+ /* In various places the code mistakenly associates
142
+ forms 8 bytes long with Dwarf_Signed or Dwarf_Unsigned
143
+ This is not a very portable assumption.
144
+ The following should be used instead for 64 bit integers.
145
+ */
146
+ typedef __uint64_t Dwarf_ufixed64;
147
+ typedef __int64_t Dwarf_sfixed64;
148
+
149
+
150
+ typedef struct Dwarf_Abbrev_List_s *Dwarf_Abbrev_List;
151
+ typedef struct Dwarf_File_Entry_s *Dwarf_File_Entry;
152
+ typedef struct Dwarf_CU_Context_s *Dwarf_CU_Context;
153
+ typedef struct Dwarf_Hash_Table_s *Dwarf_Hash_Table;
154
+ typedef struct Dwarf_Hash_Table_Entry_s *Dwarf_Hash_Table_Entry;
155
+
156
+
157
+ typedef struct Dwarf_Alloc_Hdr_s *Dwarf_Alloc_Hdr;
@@ -0,0 +1,1802 @@
1
+ /*
2
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
3
+ Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved.
4
+ Portions Copyright 2012 SN Systems Ltd. All rights reserved.
5
+
6
+ This program is free software; you can redistribute it and/or modify it
7
+ under the terms of version 2.1 of the GNU Lesser General Public License
8
+ as published by the Free Software Foundation.
9
+
10
+ This program is distributed in the hope that it would be useful, but
11
+ WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
+
14
+ Further, this software is distributed without any warranty that it is
15
+ free of the rightful claim of any third person regarding infringement
16
+ or the like. Any license provided herein, whether implied or
17
+ otherwise, applies only to this software file. Patent licenses, if
18
+ any, provided herein do not apply to combinations of this program with
19
+ other software, or any other product whatsoever.
20
+
21
+ You should have received a copy of the GNU Lesser General Public
22
+ License along with this program; if not, write the Free Software
23
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24
+ USA.
25
+
26
+ */
27
+
28
+ #include "config.h"
29
+ #include "dwarf_incl.h"
30
+ #ifdef HAVE_ELF_H
31
+ #include <elf.h>
32
+ #endif
33
+ #include <stdio.h>
34
+ #include "dwarf_die_deliv.h"
35
+
36
+ #define FALSE 0
37
+ #define TRUE 1
38
+
39
+ /* New October 2011. Enables client code to know if
40
+ it is a debug_info or debug_types context. */
41
+ Dwarf_Bool
42
+ dwarf_get_die_infotypes_flag(Dwarf_Die die)
43
+ {
44
+ return die->di_is_info;
45
+ }
46
+
47
+ /*
48
+ For a given Dwarf_Debug dbg, this function checks
49
+ if a CU that includes the given offset has been read
50
+ or not. If yes, it returns the Dwarf_CU_Context
51
+ for the CU. Otherwise it returns NULL. Being an
52
+ internal routine, it is assumed that a valid dbg
53
+ is passed.
54
+
55
+ **This is a sequential search. May be too slow.
56
+
57
+ If debug_info and debug_abbrev not loaded, this will
58
+ wind up returning NULL. So no need to load before calling
59
+ this.
60
+ */
61
+ static Dwarf_CU_Context
62
+ _dwarf_find_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset,Dwarf_Bool is_info)
63
+ {
64
+ Dwarf_CU_Context cu_context = 0;
65
+ Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading:
66
+ &dbg->de_types_reading;
67
+
68
+ if (offset >= dis->de_last_offset)
69
+ return (NULL);
70
+
71
+ if (dis->de_cu_context != NULL &&
72
+ dis->de_cu_context->cc_next != NULL &&
73
+ dis->de_cu_context->cc_next->cc_debug_offset == offset) {
74
+
75
+ return (dis->de_cu_context->cc_next);
76
+ }
77
+
78
+ if (dis->de_cu_context != NULL &&
79
+ dis->de_cu_context->cc_debug_offset <= offset) {
80
+
81
+ for (cu_context = dis->de_cu_context;
82
+ cu_context != NULL; cu_context = cu_context->cc_next) {
83
+
84
+ if (offset >= cu_context->cc_debug_offset &&
85
+ offset < cu_context->cc_debug_offset +
86
+ cu_context->cc_length + cu_context->cc_length_size
87
+ + cu_context->cc_extension_size) {
88
+
89
+ return (cu_context);
90
+ }
91
+ }
92
+ }
93
+
94
+ for (cu_context = dis->de_cu_context_list;
95
+ cu_context != NULL; cu_context = cu_context->cc_next) {
96
+
97
+ if (offset >= cu_context->cc_debug_offset &&
98
+ offset < cu_context->cc_debug_offset +
99
+ cu_context->cc_length + cu_context->cc_length_size
100
+ + cu_context->cc_extension_size) {
101
+
102
+ return (cu_context);
103
+ }
104
+ }
105
+
106
+ return (NULL);
107
+ }
108
+
109
+
110
+ /* This routine checks the dwarf_offdie() list of
111
+ CU contexts for the right CU context. */
112
+ static Dwarf_CU_Context
113
+ _dwarf_find_offdie_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset,
114
+ Dwarf_Bool is_info)
115
+ {
116
+ Dwarf_CU_Context cu_context = 0;
117
+ Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading:
118
+ &dbg->de_types_reading;
119
+
120
+ for (cu_context = dis->de_offdie_cu_context;
121
+ cu_context != NULL; cu_context = cu_context->cc_next)
122
+
123
+ if (offset >= cu_context->cc_debug_offset &&
124
+ offset < cu_context->cc_debug_offset +
125
+ cu_context->cc_length + cu_context->cc_length_size
126
+ + cu_context->cc_extension_size)
127
+
128
+ return (cu_context);
129
+
130
+ return (NULL);
131
+ }
132
+
133
+ int
134
+ dwarf_get_debugfission_for_die(Dwarf_Die die,
135
+ struct Dwarf_Debug_Fission_Per_CU_s *fission_out,
136
+ Dwarf_Error *error)
137
+ {
138
+ Dwarf_CU_Context context = die->di_cu_context;
139
+ Dwarf_Debug dbg = context->cc_dbg;
140
+ struct Dwarf_Debug_Fission_Per_CU_s * percu = 0;
141
+
142
+ if (!_dwarf_file_has_debug_fission_index(dbg)) {
143
+ return DW_DLV_NO_ENTRY;
144
+ }
145
+
146
+ if (context->cc_unit_type == DW_UT_type ) {
147
+ if (!_dwarf_file_has_debug_fission_tu_index(dbg)) {
148
+ return DW_DLV_NO_ENTRY;
149
+ }
150
+ } else {
151
+ if (!_dwarf_file_has_debug_fission_cu_index(dbg)) {
152
+ return DW_DLV_NO_ENTRY;
153
+ }
154
+ }
155
+ percu = &context->cc_dwp_offsets;
156
+ if (!percu->pcu_type) {
157
+ return DW_DLV_NO_ENTRY;
158
+ }
159
+ *fission_out = *percu;
160
+ return DW_DLV_OK;
161
+ }
162
+
163
+ /* ASSERT: whichone is a DW_SECT* macro value. */
164
+ Dwarf_Unsigned
165
+ _dwarf_get_dwp_extra_offset(struct Dwarf_Debug_Fission_Per_CU_s* dwp,
166
+ unsigned whichone, Dwarf_Unsigned * size)
167
+ {
168
+ Dwarf_Unsigned abbrevoff = 0;
169
+ if (!dwp->pcu_type) {
170
+ return 0;
171
+ }
172
+ abbrevoff = dwp->pcu_offset[whichone];
173
+ *size = dwp->pcu_size[whichone];
174
+ return abbrevoff;
175
+ }
176
+
177
+
178
+ /* _dwarf_get_fission_addition_die return DW_DLV_OK etc instead.
179
+ */
180
+ int
181
+ _dwarf_get_fission_addition_die(Dwarf_Die die, int dw_sect_index,
182
+ Dwarf_Unsigned *offset,
183
+ Dwarf_Unsigned *size,
184
+ Dwarf_Error *error)
185
+ {
186
+ /* We do not yet know the DIE hash, so we cannot use it
187
+ to identify the offset. */
188
+ Dwarf_CU_Context context = die->di_cu_context;
189
+ Dwarf_Unsigned dwpadd = 0;
190
+ Dwarf_Unsigned dwpsize = 0;
191
+
192
+ dwpadd = _dwarf_get_dwp_extra_offset(&context->cc_dwp_offsets,
193
+ dw_sect_index,&dwpsize);
194
+ *offset = dwpadd;
195
+ *size = dwpsize;
196
+ return DW_DLV_OK;
197
+ }
198
+
199
+ /* Not sure if this is the only way to be sure early on in
200
+ reading a compile unit. */
201
+ static int
202
+ section_name_ends_with_dwo(const char *name)
203
+ {
204
+ int lenstr = 0;
205
+ int dotpos = 0;
206
+ if (!name) {
207
+ return FALSE;
208
+ }
209
+ lenstr = strlen(name);
210
+ if (lenstr < 5) {
211
+ return FALSE;
212
+ }
213
+ dotpos = lenstr - 4;
214
+ if(strcmp(name+dotpos,".dwo")) {
215
+ return FALSE;
216
+ }
217
+ return TRUE;
218
+ }
219
+
220
+
221
+ /* This function is used to create a CU Context for
222
+ a compilation-unit that begins at offset in
223
+ .debug_info. The CU Context is attached to the
224
+ list of CU Contexts for this dbg. It is assumed
225
+ that the CU at offset has not been read before,
226
+ and so do not call this routine before making
227
+ sure of this with _dwarf_find_CU_Context().
228
+ Returns NULL on error. As always, being an
229
+ internal routine, assumes a good dbg.
230
+
231
+ The offset argument is global offset, the offset
232
+ in the section, irrespective of CUs.
233
+ The offset has the DWP Package File offset built in
234
+ as it comes from the actual section.
235
+
236
+ max_cu_local_offset is a local offset in this CU.
237
+ So zero of this field is immediately following the length
238
+ field of the CU header. so max_cu_local_offset is
239
+ identical to the CU length field.
240
+ max_cu_global_offset is the offset one-past the end
241
+ of this entire CU. */
242
+ static int
243
+ _dwarf_make_CU_Context(Dwarf_Debug dbg,
244
+ Dwarf_Off offset,Dwarf_Bool is_info,
245
+ Dwarf_CU_Context * context_out,Dwarf_Error * error)
246
+ {
247
+ Dwarf_CU_Context cu_context = 0;
248
+ Dwarf_Unsigned length = 0;
249
+ Dwarf_Signed abbrev_offset = 0;
250
+ Dwarf_Unsigned typeoffset = 0;
251
+ Dwarf_Sig8 signaturedata;
252
+ Dwarf_Unsigned types_extra_len = 0;
253
+ Dwarf_Unsigned max_cu_local_offset = 0;
254
+ Dwarf_Unsigned max_cu_global_offset = 0;
255
+ Dwarf_Byte_Ptr cu_ptr = 0;
256
+ int local_extension_size = 0;
257
+ int local_length_size = 0;
258
+
259
+ const char *secname = is_info?dbg->de_debug_info.dss_name:
260
+ dbg->de_debug_types.dss_name;
261
+ Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading:
262
+ &dbg->de_types_reading;
263
+ Dwarf_Unsigned section_size = is_info? dbg->de_debug_info.dss_size:
264
+ dbg->de_debug_types.dss_size;
265
+ int unit_type = 0;
266
+ int version = 0;
267
+ int is_type_tu = 0;
268
+
269
+ cu_context =
270
+ (Dwarf_CU_Context) _dwarf_get_alloc(dbg, DW_DLA_CU_CONTEXT, 1);
271
+ if (cu_context == NULL) {
272
+ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
273
+ return DW_DLV_ERROR;
274
+ }
275
+ cu_context->cc_dbg = dbg;
276
+ cu_context->cc_is_info = is_info;
277
+
278
+ {
279
+ Dwarf_Small *dataptr = is_info? dbg->de_debug_info.dss_data:
280
+ dbg->de_debug_types.dss_data;
281
+ cu_ptr = (Dwarf_Byte_Ptr) (dataptr+offset);
282
+ }
283
+
284
+ if (section_name_ends_with_dwo(secname)) {
285
+ cu_context->cc_is_dwo = TRUE;
286
+ }
287
+ /* READ_AREA_LENGTH updates cu_ptr for consumed bytes */
288
+ READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
289
+ cu_ptr, local_length_size, local_extension_size);
290
+ cu_context->cc_length_size = local_length_size;
291
+ cu_context->cc_extension_size = local_extension_size;
292
+
293
+
294
+ cu_context->cc_length = length;
295
+ max_cu_local_offset = length;
296
+ max_cu_global_offset = offset + length +
297
+ local_extension_size + local_length_size;
298
+
299
+ READ_UNALIGNED(dbg, cu_context->cc_version_stamp, Dwarf_Half,
300
+ cu_ptr, sizeof(Dwarf_Half));
301
+ version = cu_context->cc_version_stamp;
302
+ cu_ptr += sizeof(Dwarf_Half);
303
+ if (version == DW_CU_VERSION5) {
304
+ unsigned char ub = 0;
305
+ READ_UNALIGNED(dbg, ub, unsigned char,
306
+ cu_ptr, sizeof(ub));
307
+ cu_ptr += sizeof(ub);
308
+ unit_type = ub;
309
+ if (unit_type != DW_UT_compile && unit_type != DW_UT_partial
310
+ && unit_type != DW_UT_type) {
311
+ _dwarf_error(dbg, error, DW_DLE_CU_UT_TYPE_ERROR);
312
+ return DW_DLV_ERROR;
313
+ }
314
+ } else {
315
+ /* We don't know if it is or DW_UT_partial or not. */
316
+ unit_type = is_info?DW_UT_compile:DW_UT_type;
317
+ }
318
+
319
+ READ_UNALIGNED(dbg, abbrev_offset, Dwarf_Unsigned,
320
+ cu_ptr, local_length_size);
321
+
322
+ cu_ptr += local_length_size;
323
+
324
+ /* In a dwp context, this offset is incomplete.
325
+ We need to add in the base from the .debug_cu_index
326
+ or .debug_tu_index . Done below */
327
+ cu_context->cc_abbrev_offset = abbrev_offset;
328
+
329
+ cu_context->cc_address_size = *(Dwarf_Small *) cu_ptr;
330
+ /* The CU header has no selector size. See DW_AT_segment
331
+ and the DWARF5 line table header and the
332
+ DWARF5 .debug_aranges header. */
333
+ cu_context->cc_segment_selector_size = 0;
334
+ ++cu_ptr;
335
+
336
+
337
+
338
+ if (cu_context->cc_address_size > sizeof(Dwarf_Addr)) {
339
+ _dwarf_error(dbg, error, DW_DLE_CU_ADDRESS_SIZE_BAD);
340
+ return DW_DLV_ERROR;
341
+ }
342
+
343
+ is_type_tu = FALSE;
344
+ if (!is_info ||
345
+ (version == DW_CU_VERSION5 && unit_type == DW_UT_type )) {
346
+ is_type_tu = TRUE;
347
+ }
348
+ if (is_type_tu) {
349
+ /* types CU headers have extra header bytes. */
350
+ types_extra_len = sizeof(signaturedata) + local_length_size;
351
+ }
352
+ if ((length < (CU_VERSION_STAMP_SIZE + local_length_size +
353
+ CU_ADDRESS_SIZE_SIZE + types_extra_len)) ||
354
+ (max_cu_global_offset > section_size)) {
355
+
356
+ dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
357
+ _dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR);
358
+ return DW_DLV_ERROR;
359
+ }
360
+
361
+ if (cu_context->cc_version_stamp != DW_CU_VERSION2
362
+ && cu_context->cc_version_stamp != DW_CU_VERSION3
363
+ && cu_context->cc_version_stamp != DW_CU_VERSION4
364
+ && cu_context->cc_version_stamp != DW_CU_VERSION5) {
365
+ dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
366
+ _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
367
+ return DW_DLV_ERROR;
368
+ }
369
+ if (is_type_tu) {
370
+ if (version != DW_CU_VERSION4 &&
371
+ version != DW_CU_VERSION5) {
372
+ dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
373
+ /* Error name misleading, version 5 has types too. */
374
+ _dwarf_error(dbg, error, DW_DLE_DEBUG_TYPES_ONLY_DWARF4);
375
+ return DW_DLV_ERROR;
376
+ }
377
+ /* Now read the debug_types extra header fields of
378
+ the signature (8 bytes) and the typeoffset.
379
+ This can be in executable, ordinary object,
380
+ or .dwo or .dwp object. */
381
+ memcpy(&signaturedata,cu_ptr,sizeof(signaturedata));
382
+ cu_context->cc_signature_present = TRUE;
383
+ cu_ptr += sizeof(signaturedata);
384
+ READ_UNALIGNED(dbg, typeoffset, Dwarf_Unsigned,
385
+ cu_ptr, local_length_size);
386
+ cu_context->cc_type_signature = signaturedata;
387
+ cu_context->cc_type_signature_offset = typeoffset;
388
+ {
389
+ if (typeoffset >= max_cu_local_offset) {
390
+ dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
391
+ _dwarf_error(dbg, error, DW_DLE_DEBUG_TYPEOFFSET_BAD);
392
+ return DW_DLV_ERROR;
393
+ }
394
+ }
395
+ }
396
+ cu_context->cc_unit_type = unit_type;
397
+ if (is_type_tu) {
398
+ if (_dwarf_file_has_debug_fission_tu_index(dbg) ){
399
+ int resdf = 0;
400
+ resdf = dwarf_get_debugfission_for_key(dbg,
401
+ &signaturedata,
402
+ "tu",
403
+ &cu_context->cc_dwp_offsets,
404
+ error);
405
+ if (resdf != DW_DLV_OK) {
406
+ dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
407
+ _dwarf_error(dbg, error,
408
+ DW_DLE_MISSING_REQUIRED_TU_OFFSET_HASH);
409
+ return DW_DLV_ERROR;
410
+ }
411
+ }
412
+ } else {
413
+ if (_dwarf_file_has_debug_fission_cu_index(dbg) ){
414
+ int resdf = 0;
415
+ resdf = _dwarf_get_debugfission_for_offset(dbg,
416
+ offset,
417
+ &cu_context->cc_dwp_offsets,
418
+ error);
419
+ if (resdf != DW_DLV_OK) {
420
+ dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
421
+ _dwarf_error(dbg, error,
422
+ DW_DLE_MISSING_REQUIRED_CU_OFFSET_HASH);
423
+ return DW_DLV_ERROR;
424
+ }
425
+ /* Eventually we will see the DW_AT_dwo_id
426
+ or DW_AT_GNU_dwo_id
427
+ and we should check against this signature
428
+ at that time. */
429
+ cu_context->cc_type_signature =
430
+ cu_context->cc_dwp_offsets.pcu_hash;
431
+ }
432
+ }
433
+ if (cu_context->cc_dwp_offsets.pcu_type) {
434
+ /* We need to update certain offsets as this is a package file.
435
+ This is to reflect how DWP files are organized. */
436
+ Dwarf_Unsigned absize = 0;
437
+ Dwarf_Unsigned aboff = 0;
438
+ aboff = _dwarf_get_dwp_extra_offset(&cu_context->cc_dwp_offsets,
439
+ DW_SECT_ABBREV, &absize);
440
+ cu_context->cc_abbrev_offset += aboff;
441
+ abbrev_offset = cu_context->cc_abbrev_offset;
442
+ }
443
+
444
+ if ((Dwarf_Unsigned)abbrev_offset >= dbg->de_debug_abbrev.dss_size) {
445
+ dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
446
+ _dwarf_error(dbg, error, DW_DLE_ABBREV_OFFSET_ERROR);
447
+ return DW_DLV_ERROR;
448
+ }
449
+
450
+ cu_context->cc_abbrev_hash_table =
451
+ (Dwarf_Hash_Table) _dwarf_get_alloc(dbg, DW_DLA_HASH_TABLE, 1);
452
+ if (cu_context->cc_abbrev_hash_table == NULL) {
453
+ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
454
+ return DW_DLV_ERROR;
455
+ }
456
+
457
+ cu_context->cc_debug_offset = offset;
458
+
459
+ dis->de_last_offset = max_cu_global_offset;
460
+
461
+ if (dis->de_cu_context_list == NULL) {
462
+ dis->de_cu_context_list = cu_context;
463
+ dis->de_cu_context_list_end = cu_context;
464
+ } else {
465
+ dis->de_cu_context_list_end->cc_next = cu_context;
466
+ dis->de_cu_context_list_end = cu_context;
467
+ }
468
+ *context_out = cu_context;
469
+ return DW_DLV_OK;
470
+ }
471
+
472
+ static int
473
+ reloc_incomplete(Dwarf_Error err)
474
+ {
475
+ int e = dwarf_errno(err);
476
+ if (e == DW_DLE_RELOC_MISMATCH_INDEX ||
477
+ e == DW_DLE_RELOC_MISMATCH_RELOC_INDEX ||
478
+ e == DW_DLE_RELOC_MISMATCH_STRTAB_INDEX ||
479
+ e == DW_DLE_RELOC_SECTION_MISMATCH ||
480
+ e == DW_DLE_RELOC_SECTION_MISSING_INDEX ||
481
+ e == DW_DLE_RELOC_SECTION_LENGTH_ODD ||
482
+ e == DW_DLE_RELOC_SECTION_PTR_NULL ||
483
+ e == DW_DLE_RELOC_SECTION_MALLOC_FAIL ||
484
+ e == DW_DLE_RELOC_SECTION_SYMBOL_INDEX_BAD ) {
485
+ return 1;
486
+ }
487
+ return 0;
488
+ }
489
+
490
+
491
+
492
+ /* Returns offset of next compilation-unit thru next_cu_offset
493
+ pointer.
494
+ It sequentially moves from one
495
+ cu to the next. The current cu is recorded
496
+ internally by libdwarf.
497
+
498
+ The _b form is new for DWARF4 adding new returned fields. */
499
+ int
500
+ dwarf_next_cu_header(Dwarf_Debug dbg,
501
+ Dwarf_Unsigned * cu_header_length,
502
+ Dwarf_Half * version_stamp,
503
+ Dwarf_Unsigned * abbrev_offset,
504
+ Dwarf_Half * address_size,
505
+ Dwarf_Unsigned * next_cu_offset,
506
+ Dwarf_Error * error)
507
+ {
508
+ Dwarf_Bool is_info = true;
509
+ Dwarf_Half header_type = 0;
510
+ return _dwarf_next_cu_header_internal(dbg,
511
+ is_info,
512
+ cu_header_length,
513
+ version_stamp,
514
+ abbrev_offset,
515
+ address_size,
516
+ 0,0,0,0,0,
517
+ next_cu_offset,
518
+ &header_type,
519
+ error);
520
+ }
521
+ int
522
+ dwarf_next_cu_header_b(Dwarf_Debug dbg,
523
+ Dwarf_Unsigned * cu_header_length,
524
+ Dwarf_Half * version_stamp,
525
+ Dwarf_Unsigned * abbrev_offset,
526
+ Dwarf_Half * address_size,
527
+ Dwarf_Half * offset_size,
528
+ Dwarf_Half * extension_size,
529
+ Dwarf_Unsigned * next_cu_offset,
530
+ Dwarf_Error * error)
531
+ {
532
+ Dwarf_Bool is_info = true;
533
+ Dwarf_Half header_type = 0;
534
+ return _dwarf_next_cu_header_internal(dbg,
535
+ is_info,
536
+ cu_header_length,
537
+ version_stamp,
538
+ abbrev_offset,
539
+ address_size,
540
+ offset_size,extension_size,
541
+ 0,0,0,
542
+ next_cu_offset,
543
+ &header_type,
544
+ error);
545
+ }
546
+
547
+ int
548
+ dwarf_next_cu_header_c(Dwarf_Debug dbg,
549
+ Dwarf_Bool is_info,
550
+ Dwarf_Unsigned * cu_header_length,
551
+ Dwarf_Half * version_stamp,
552
+ Dwarf_Unsigned * abbrev_offset,
553
+ Dwarf_Half * address_size,
554
+ Dwarf_Half * offset_size,
555
+ Dwarf_Half * extension_size,
556
+ Dwarf_Sig8 * signature,
557
+ Dwarf_Unsigned * typeoffset,
558
+ Dwarf_Unsigned * next_cu_offset,
559
+ Dwarf_Error * error)
560
+ {
561
+ Dwarf_Half header_type = 0;
562
+ int res =_dwarf_next_cu_header_internal(dbg,
563
+ is_info,
564
+ cu_header_length,
565
+ version_stamp,
566
+ abbrev_offset,
567
+ address_size,
568
+ offset_size,
569
+ extension_size,
570
+ signature,
571
+ 0,
572
+ typeoffset,
573
+ next_cu_offset,
574
+ &header_type,
575
+ error);
576
+ return res;
577
+ }
578
+ int
579
+ dwarf_next_cu_header_d(Dwarf_Debug dbg,
580
+ Dwarf_Bool is_info,
581
+ Dwarf_Unsigned * cu_header_length,
582
+ Dwarf_Half * version_stamp,
583
+ Dwarf_Unsigned * abbrev_offset,
584
+ Dwarf_Half * address_size,
585
+ Dwarf_Half * offset_size,
586
+ Dwarf_Half * extension_size,
587
+ Dwarf_Sig8 * signature,
588
+ Dwarf_Unsigned * typeoffset,
589
+ Dwarf_Unsigned * next_cu_offset,
590
+ Dwarf_Half * header_cu_type,
591
+ Dwarf_Error * error)
592
+ {
593
+ int res = _dwarf_next_cu_header_internal(dbg,
594
+ is_info,
595
+ cu_header_length,
596
+ version_stamp,
597
+ abbrev_offset,
598
+ address_size,
599
+ offset_size,
600
+ extension_size,
601
+ signature,
602
+ 0,
603
+ typeoffset,
604
+ next_cu_offset,
605
+ header_cu_type,
606
+ error);
607
+ return res;
608
+ }
609
+
610
+
611
+
612
+ /* If sig_present_return not set TRUE here
613
+ then something must be wrong. ??
614
+ Compiler bug?
615
+ A DWO/DWP CU has different base fields than
616
+ a normal object/executable, but this finds
617
+ the base fields for both types.
618
+ */
619
+ static int
620
+ find_context_base_fields(Dwarf_Debug dbg,
621
+ Dwarf_Die cudie,
622
+ Dwarf_Sig8 *sig_return,
623
+ Dwarf_Bool *sig_present_return,
624
+ Dwarf_Unsigned *str_offsets_base_return,
625
+ Dwarf_Bool *str_offsets_base_present_return,
626
+ Dwarf_Unsigned *addr_base_return,
627
+ Dwarf_Bool *addr_base_present_return,
628
+ Dwarf_Unsigned *ranges_base_return,
629
+ Dwarf_Bool *ranges_base_present_return,
630
+ Dwarf_Error* error)
631
+ {
632
+ Dwarf_Sig8 signature;
633
+ Dwarf_Bool sig_present = FALSE;
634
+ Dwarf_Off str_offsets_base = 0;
635
+ Dwarf_Off ranges_base = 0;
636
+ Dwarf_Off addr_base = 0;
637
+ Dwarf_Bool str_offsets_base_present = FALSE;
638
+ Dwarf_Bool addr_base_present = FALSE;
639
+ Dwarf_Bool ranges_base_present = FALSE;
640
+
641
+ Dwarf_Attribute * alist = 0;
642
+ Dwarf_Signed atcount = 0;
643
+ int alres = 0;
644
+
645
+ alres = dwarf_attrlist(cudie, &alist,
646
+ &atcount,error);
647
+ if(alres == DW_DLV_OK) {
648
+ Dwarf_Signed i = 0;
649
+ for(i = 0; i < atcount; ++i) {
650
+ Dwarf_Half attrnum;
651
+ int ares = 0;
652
+ Dwarf_Attribute attr = alist[i];
653
+ ares = dwarf_whatattr(attr,&attrnum,error);
654
+ if (ares == DW_DLV_OK) {
655
+ if (attrnum == DW_AT_dwo_id ||
656
+ attrnum == DW_AT_GNU_dwo_id ) {
657
+ int sres = 0;
658
+ sres = dwarf_formsig8_const(attr,
659
+ &signature,error);
660
+ if(sres == DW_DLV_OK) {
661
+ sig_present = TRUE;
662
+ } else {
663
+ /* Something is badly wrong. */
664
+ dwarf_dealloc(dbg,attr,DW_DLA_ATTR);
665
+ dwarf_dealloc(dbg,alist,DW_DLA_LIST);
666
+ return sres;
667
+ }
668
+ } else if (attrnum == DW_AT_str_offsets_base){
669
+ int udres = 0;
670
+ udres = dwarf_global_formref(attr,&str_offsets_base,
671
+ error);
672
+ if(udres == DW_DLV_OK) {
673
+ str_offsets_base_present = TRUE;
674
+ } else {
675
+ dwarf_dealloc(dbg,attr,DW_DLA_ATTR);
676
+ dwarf_dealloc(dbg,alist,DW_DLA_LIST);
677
+ /* Something is badly wrong. */
678
+ return udres;
679
+ }
680
+ } else if (attrnum == DW_AT_addr_base
681
+ || attrnum == DW_AT_GNU_addr_base){
682
+ int udres = 0;
683
+ udres = dwarf_global_formref(attr,&addr_base,
684
+ error);
685
+ if(udres == DW_DLV_OK) {
686
+ addr_base_present = TRUE;
687
+ } else {
688
+ dwarf_dealloc(dbg,attr,DW_DLA_ATTR);
689
+ dwarf_dealloc(dbg,alist,DW_DLA_LIST);
690
+ /* Something is badly wrong. */
691
+ return udres;
692
+ }
693
+ } else if (attrnum == DW_AT_ranges_base
694
+ || attrnum == DW_AT_GNU_ranges_base){
695
+ int udres = 0;
696
+ udres = dwarf_global_formref(attr,&ranges_base,
697
+ error);
698
+ if(udres == DW_DLV_OK) {
699
+ ranges_base_present = TRUE;
700
+ } else {
701
+ dwarf_dealloc(dbg,attr,DW_DLA_ATTR);
702
+ dwarf_dealloc(dbg,alist,DW_DLA_LIST);
703
+ /* Something is badly wrong. */
704
+ return udres;
705
+ }
706
+ } /* else nothing to do here. */
707
+ }
708
+ dwarf_dealloc(dbg,attr,DW_DLA_ATTR);
709
+ }
710
+ dwarf_dealloc(dbg,alist,DW_DLA_LIST);
711
+ } else {
712
+ /* Something is badly wrong. No attrlist. FIXME */
713
+ _dwarf_error(dbg,error, DW_DLE_DWP_MISSING_DWO_ID);
714
+ return DW_DLV_ERROR;
715
+ }
716
+ *sig_present_return = sig_present;
717
+ if (sig_present) {
718
+ *sig_return = signature;
719
+ }
720
+ *str_offsets_base_present_return = str_offsets_base_present;
721
+ if (str_offsets_base_present) {
722
+ *str_offsets_base_return = str_offsets_base;
723
+ }
724
+ *addr_base_present_return = addr_base_present;
725
+ if (addr_base_present) {
726
+ *addr_base_return = addr_base;
727
+ }
728
+ *ranges_base_present_return = ranges_base_present;
729
+ if (ranges_base_present) {
730
+ *ranges_base_return = ranges_base;
731
+ }
732
+ return DW_DLV_OK;
733
+ }
734
+
735
+
736
+ int
737
+ _dwarf_next_cu_header_internal(Dwarf_Debug dbg,
738
+ Dwarf_Bool is_info,
739
+ Dwarf_Unsigned * cu_header_length,
740
+ Dwarf_Half * version_stamp,
741
+ Dwarf_Unsigned * abbrev_offset,
742
+ Dwarf_Half * address_size,
743
+ Dwarf_Half * offset_size,
744
+ Dwarf_Half * extension_size,
745
+ Dwarf_Sig8 * signature,
746
+ Dwarf_Bool * has_signature,
747
+ Dwarf_Unsigned *typeoffset,
748
+ Dwarf_Unsigned * next_cu_offset,
749
+
750
+ /* header_type: DW_UT_compile, DW_UT_partial, DW_UT_type
751
+ returned through the pointer.
752
+ A new item in DWARF5, synthesized for earlier DWARF
753
+ CUs (& TUs). */
754
+ Dwarf_Half * header_type,
755
+ Dwarf_Error * error)
756
+ {
757
+ /* Offset for current and new CU. */
758
+ Dwarf_Unsigned new_offset = 0;
759
+
760
+ /* CU Context for current CU. */
761
+ Dwarf_CU_Context cu_context = 0;
762
+ Dwarf_Debug_InfoTypes dis = 0;
763
+ Dwarf_Unsigned section_size = 0;
764
+ int res = 0;
765
+
766
+
767
+
768
+ /* ***** BEGIN CODE ***** */
769
+
770
+ if (dbg == NULL) {
771
+ _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
772
+ return (DW_DLV_ERROR);
773
+ }
774
+ dis = is_info? &dbg->de_info_reading: &dbg->de_types_reading;
775
+ /* Get offset into .debug_info of next CU. If dbg has no context,
776
+ this has to be the first one. */
777
+ if (dis->de_cu_context == NULL) {
778
+ Dwarf_Small *dataptr = is_info? dbg->de_debug_info.dss_data:
779
+ dbg->de_debug_types.dss_data;
780
+ new_offset = 0;
781
+ if (!dataptr) {
782
+ Dwarf_Error err2= 0;
783
+ int res = is_info?_dwarf_load_debug_info(dbg, &err2):
784
+ _dwarf_load_debug_types(dbg,&err2);
785
+
786
+ if (res != DW_DLV_OK) {
787
+ if (reloc_incomplete(err2)) {
788
+ /* We will assume all is ok, though it is not.
789
+ Relocation errors need not be fatal. */
790
+ char msg_buf[200];
791
+ snprintf(msg_buf,sizeof(msg_buf),
792
+ "Relocations did not complete successfully, but we are "
793
+ " ignoring error: %s",dwarf_errmsg(err2));
794
+ dwarf_insert_harmless_error(dbg,msg_buf);
795
+ res = DW_DLV_OK;
796
+ } else {
797
+ if (error) {
798
+ *error = err2;
799
+ }
800
+ return res;
801
+ }
802
+
803
+ }
804
+ }
805
+
806
+ } else {
807
+ new_offset = dis->de_cu_context->cc_debug_offset +
808
+ dis->de_cu_context->cc_length +
809
+ dis->de_cu_context->cc_length_size +
810
+ dis->de_cu_context->cc_extension_size;
811
+ }
812
+
813
+ /* Check that there is room in .debug_info beyond
814
+ the new offset for at least a new cu header.
815
+ If not, return -1 (DW_DLV_NO_ENTRY) to indicate end
816
+ of debug_info section, and reset
817
+ de_cu_debug_info_offset to
818
+ enable looping back through the cu's. */
819
+ section_size = is_info? dbg->de_debug_info.dss_size:
820
+ dbg->de_debug_types.dss_size;
821
+ if ((new_offset + _dwarf_length_of_cu_header_simple(dbg,is_info)) >=
822
+ section_size) {
823
+ dis->de_cu_context = NULL;
824
+ return (DW_DLV_NO_ENTRY);
825
+ }
826
+
827
+ /* Check if this CU has been read before. */
828
+ cu_context = _dwarf_find_CU_Context(dbg, new_offset,is_info);
829
+
830
+ /* If not, make CU Context for it. */
831
+ if (cu_context == NULL) {
832
+ res = _dwarf_make_CU_Context(dbg, new_offset,is_info,
833
+ &cu_context,error);
834
+ if (res != DW_DLV_OK) {
835
+ return res;
836
+ }
837
+ }
838
+
839
+ dis->de_cu_context = cu_context;
840
+
841
+ if (cu_header_length != NULL) {
842
+ *cu_header_length = cu_context->cc_length;
843
+ }
844
+
845
+ if (version_stamp != NULL) {
846
+ *version_stamp = cu_context->cc_version_stamp;
847
+ }
848
+ if (abbrev_offset != NULL) {
849
+ *abbrev_offset = cu_context->cc_abbrev_offset;
850
+ }
851
+
852
+ if (address_size != NULL) {
853
+ *address_size = cu_context->cc_address_size;
854
+ }
855
+ if (offset_size != NULL) {
856
+ *offset_size = cu_context->cc_length_size;
857
+ }
858
+ if (extension_size != NULL) {
859
+ *extension_size = cu_context->cc_extension_size;
860
+ }
861
+ if (header_type) {
862
+ *header_type = cu_context->cc_unit_type;
863
+ }
864
+
865
+ if ( (dbg->de_tied_data.td_is_tied_object ||
866
+ _dwarf_file_has_debug_fission_cu_index(dbg)) &&
867
+ (cu_context->cc_unit_type == DW_UT_compile ||
868
+ cu_context->cc_unit_type == DW_UT_partial)) {
869
+ /* ASSERT: !cu_context->cc_type_signature_present */
870
+ /* Look for DW_AT_dwo_id and
871
+ if there is one pick up the hash
872
+ and the base array.
873
+ Also pick up cc_str_offset_base. */
874
+ Dwarf_Die cudie = 0;
875
+
876
+ int resdwo = dwarf_siblingof_b(dbg,NULL,is_info,
877
+ &cudie, error);
878
+ if (resdwo == DW_DLV_OK) {
879
+ int dwo_idres = 0;
880
+ Dwarf_Sig8 signature;
881
+ Dwarf_Bool sig_present = FALSE;
882
+ Dwarf_Unsigned str_offsets_base = 0;
883
+ Dwarf_Unsigned addr_base = 0;
884
+ Dwarf_Unsigned ranges_base = 0;
885
+ Dwarf_Bool str_offsets_base_present = FALSE;
886
+ Dwarf_Bool addr_base_present = FALSE;
887
+ Dwarf_Bool ranges_base_present = FALSE;
888
+ dwo_idres = find_context_base_fields(dbg,
889
+ cudie,&signature,&sig_present,
890
+ &str_offsets_base,&str_offsets_base_present,
891
+ &addr_base,&addr_base_present,
892
+ &ranges_base,&ranges_base_present,
893
+ error);
894
+
895
+ if (dwo_idres == DW_DLV_OK) {
896
+ if(sig_present) {
897
+ /* This can be in executable or ordinary .o
898
+ or .dwo or .dwp */
899
+ cu_context->cc_type_signature = signature;
900
+ cu_context->cc_signature_present = TRUE;
901
+ }
902
+ if (addr_base_present) {
903
+ /* This can be in executable or ordinary .o */
904
+ cu_context->cc_addr_base = addr_base;
905
+ cu_context->cc_addr_base_present = TRUE;
906
+ }
907
+
908
+ if(str_offsets_base_present) {
909
+ /* This can be in executable or ordinary .o
910
+ or .dwo or .dwp */
911
+ cu_context->cc_str_offsets_base = str_offsets_base;
912
+ cu_context->cc_str_offsets_base_present = TRUE;
913
+ }
914
+ if(ranges_base_present) {
915
+ /* This can be in executable or ordinary .o */
916
+ cu_context->cc_ranges_base = ranges_base;
917
+ cu_context->cc_ranges_base_present = TRUE;
918
+ }
919
+ }
920
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
921
+ } else if (resdwo == DW_DLV_NO_ENTRY) {
922
+ /* Impossible */
923
+ _dwarf_error(NULL, error, DW_DLE_DWP_SIBLING_ERROR);
924
+ return DW_DLV_ERROR;
925
+ } else {
926
+ /* Something is badly wrong. */
927
+ return resdwo;
928
+ }
929
+ }
930
+ if (typeoffset) {
931
+ *typeoffset = cu_context->cc_type_signature_offset;
932
+ }
933
+ if (signature ) {
934
+ *signature = cu_context->cc_type_signature;
935
+ }
936
+ if (has_signature ) {
937
+ *has_signature = cu_context->cc_signature_present;
938
+ }
939
+ new_offset = new_offset + cu_context->cc_length +
940
+ cu_context->cc_length_size + cu_context->cc_extension_size;
941
+ *next_cu_offset = new_offset;
942
+ return (DW_DLV_OK);
943
+ }
944
+
945
+ /* Given hash signature, return the CU_die of the applicable CU.
946
+ The hash is assumed to be from 'somewhere',
947
+ such as from a skeleton DIE DW_AT_dwo_id ("cu" case) or
948
+ from a DW_FORM_ref_sig8 ("tu" case).
949
+
950
+ If "tu" request, the CU_die
951
+ of of the type unit.
952
+ Works on either a dwp package file or a dwo object.
953
+
954
+ If "cu" request, the CU_die
955
+ of the compilation unit.
956
+ Works on either a dwp package file or a dwo object.
957
+
958
+ If the hash passed is not present, returns DW_DLV_NO_ENTRY
959
+ (but read the next two paragraphs for more detail).
960
+
961
+ If a dwp package file with the hash signature
962
+ is present in the applicable index but no matching
963
+ compilation unit can be found, it returns DW_DLV_ERROR.
964
+
965
+ If a .dwo object there is no index and we look at the
966
+ compilation units (possibly all of them). If not present
967
+ then we return DW_DLV_NO_ENTRY.
968
+
969
+ The returned_die is a CU DIE if the sig_type is "cu".
970
+ The returned_die is a type DIE if the sig_type is "tu".
971
+ Perhaps both should return CU die. FIXME
972
+
973
+ New 27 April, 2015
974
+ */
975
+ int
976
+ dwarf_die_from_hash_signature(Dwarf_Debug dbg,
977
+ Dwarf_Sig8 * hash_sig,
978
+ const char * sig_type /* "tu" or "cu"*/,
979
+ Dwarf_Die * returned_die,
980
+ Dwarf_Error* error)
981
+ {
982
+ Dwarf_Bool is_type_unit = FALSE;
983
+ int sres = 0;
984
+
985
+ sres = _dwarf_load_debug_info(dbg,error);
986
+ if (sres == DW_DLV_ERROR) {
987
+ return sres;
988
+ }
989
+ sres = _dwarf_load_debug_types(dbg,error);
990
+ if (sres == DW_DLV_ERROR) {
991
+ return sres;
992
+ }
993
+
994
+ if (!strcmp(sig_type,"tu")) {
995
+ is_type_unit = TRUE;
996
+ } else if (!strcmp(sig_type,"cu")) {
997
+ is_type_unit = FALSE;
998
+ } else {
999
+ _dwarf_error(dbg,error,DW_DLE_SIG_TYPE_WRONG_STRING);
1000
+ return DW_DLV_ERROR;
1001
+ }
1002
+
1003
+ if (_dwarf_file_has_debug_fission_index(dbg)) {
1004
+ /* This is a dwp package file. */
1005
+ int fisres = 0;
1006
+ Dwarf_Bool is_info2 = 0;
1007
+ Dwarf_Off cu_header_off = 0;
1008
+ Dwarf_Off cu_size = 0;
1009
+ Dwarf_Off cu_die_off = 0;
1010
+ Dwarf_Off typeoffset = 0;
1011
+ Dwarf_Die cudie = 0;
1012
+ Dwarf_Die typedie = 0;
1013
+ Dwarf_CU_Context context = 0;
1014
+ Dwarf_Debug_Fission_Per_CU fiss;
1015
+
1016
+ memset(&fiss,0,sizeof(fiss));
1017
+ fisres = dwarf_get_debugfission_for_key(dbg,hash_sig,
1018
+ sig_type,&fiss,error);
1019
+ if (fisres != DW_DLV_OK) {
1020
+ return fisres;
1021
+ }
1022
+ /* Found it */
1023
+ if(is_type_unit) {
1024
+ /* DW4 has debug_types, so look in .debug_types.
1025
+ Else look in .debug_info. */
1026
+ is_info2 = dbg->de_debug_types.dss_size?FALSE:TRUE;
1027
+ } else {
1028
+ is_info2 = TRUE;
1029
+ }
1030
+
1031
+ cu_header_off = _dwarf_get_dwp_extra_offset(&fiss,
1032
+ is_info2?DW_SECT_INFO:DW_SECT_TYPES,
1033
+ &cu_size);
1034
+
1035
+ fisres = dwarf_get_cu_die_offset_given_cu_header_offset_b(
1036
+ dbg,cu_header_off,
1037
+ is_info2,
1038
+ &cu_die_off,error);
1039
+ if (fisres != DW_DLV_OK) {
1040
+ return fisres;
1041
+ }
1042
+ fisres = dwarf_offdie_b(dbg,cu_die_off,is_info2,
1043
+ &cudie,error);
1044
+ if (fisres != DW_DLV_OK) {
1045
+ return fisres;
1046
+ }
1047
+ if (!is_type_unit) {
1048
+ *returned_die = cudie;
1049
+ return DW_DLV_OK;
1050
+ }
1051
+ context = cudie->di_cu_context;
1052
+ typeoffset = context->cc_type_signature_offset;
1053
+ typeoffset += cu_header_off;
1054
+ fisres = dwarf_offdie_b(dbg,typeoffset,is_info2,
1055
+ &typedie,error);
1056
+ if (fisres != DW_DLV_OK) {
1057
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1058
+ return fisres;
1059
+ }
1060
+ *returned_die = typedie;
1061
+ dwarf_dealloc(dbg,cudie,DW_DLA_DIE);
1062
+ return DW_DLV_OK;
1063
+ }
1064
+ /* Look thru all the CUs, there is no DWP tu/cu index.
1065
+ There will be COMDAT sections for the type TUs
1066
+ (DW_UT_type).
1067
+ A single non-comdat for the DW_UT_compile. */
1068
+ /* FIXME: DW_DLE_DEBUG_FISSION_INCOMPLETE */
1069
+ _dwarf_error(dbg,error,DW_DLE_DEBUG_FISSION_INCOMPLETE);
1070
+ return DW_DLV_ERROR;
1071
+ }
1072
+
1073
+ static int
1074
+ dwarf_ptr_CU_offset(Dwarf_CU_Context cu_context,
1075
+ Dwarf_Byte_Ptr di_ptr,
1076
+ Dwarf_Bool is_info,
1077
+ Dwarf_Off * cu_off)
1078
+ {
1079
+ Dwarf_Debug dbg = cu_context->cc_dbg;
1080
+ Dwarf_Small *dataptr = is_info? dbg->de_debug_info.dss_data:
1081
+ dbg->de_debug_types.dss_data;
1082
+ *cu_off = (di_ptr - dataptr);
1083
+ return DW_DLV_OK;
1084
+ }
1085
+ #if 0 /* FOR DEBUGGING */
1086
+ /* Just for debug purposes */
1087
+ void print_sib_offset(Dwarf_Die sibling)
1088
+ {
1089
+ Dwarf_Off sib_off;
1090
+ Dwarf_Error error;
1091
+ dwarf_dieoffset(sibling,&sib_off,&error);
1092
+ fprintf(stderr," SIB OFF = 0x%" DW_PR_XZEROS DW_PR_DUx,sib_off);
1093
+ }
1094
+ void print_ptr_offset(Dwarf_CU_Context cu_context,Dwarf_Byte_Ptr di_ptr)
1095
+ {
1096
+ Dwarf_Off ptr_off;
1097
+ dwarf_ptr_CU_offset(cu_context,di_ptr,&ptr_off);
1098
+ fprintf(stderr," PTR OFF = 0x%" DW_PR_XZEROS DW_PR_DUx,ptr_off);
1099
+ }
1100
+ #endif
1101
+
1102
+
1103
+ /* Validate the sibling DIE. This only makes sense to call
1104
+ if the sibling's DIEs have been travsersed and
1105
+ dwarf_child() called on each,
1106
+ so that the last DIE dwarf_child saw was the last.
1107
+ Essentially ensuring that (after such traversal) that we
1108
+ are in the same place a sibling attribute would identify.
1109
+ In case we return DW_DLV_ERROR, the global offset of the last
1110
+ DIE traversed by dwarf_child is returned through *offset
1111
+
1112
+ It is essentially guaranteed that dbg->de_last_die
1113
+ is a stale DIE pointer of a deallocated DIE when we get here.
1114
+ It must not be used as a DIE pointer here,
1115
+ just as a sort of anonymous pointer that we just check against
1116
+ NULL.
1117
+
1118
+ There is a (subtle?) dependence on the fact that when we call this
1119
+ the last dwarf_child() call would have been for this sibling.
1120
+ Meaning that this works in a depth-first traversal even though there
1121
+ is no stack of 'de_last_die' values.
1122
+
1123
+ The check for dbg->de_last_die just ensures sanity.
1124
+
1125
+ If one is switching between normal debug_frame and eh_frame
1126
+ (traversing them in tandem, let us say) in a single
1127
+ Dwarf_Debug this validator makes no sense.
1128
+ It works if one processes a .debug_frame (entirely) and
1129
+ then an eh_frame (or vice versa) though.
1130
+ Use caution.
1131
+ */
1132
+ int
1133
+ dwarf_validate_die_sibling(Dwarf_Die sibling,Dwarf_Off *offset)
1134
+ {
1135
+ Dwarf_Debug dbg = 0;
1136
+ Dwarf_Error *error = 0;
1137
+ Dwarf_Debug_InfoTypes dis = 0;
1138
+ CHECK_DIE(sibling, DW_DLV_ERROR);
1139
+ dbg = sibling->di_cu_context->cc_dbg;
1140
+
1141
+ dis = sibling->di_is_info? &dbg->de_info_reading: &dbg->de_types_reading;
1142
+
1143
+ *offset = 0;
1144
+ if (dis->de_last_die && dis->de_last_di_ptr) {
1145
+ if (sibling->di_debug_ptr == dis->de_last_di_ptr) {
1146
+ return (DW_DLV_OK);
1147
+ }
1148
+ }
1149
+ /* Calculate global offset used for error reporting */
1150
+ dwarf_ptr_CU_offset(sibling->di_cu_context,
1151
+ dis->de_last_di_ptr,sibling->di_is_info,offset);
1152
+ return (DW_DLV_ERROR);
1153
+ }
1154
+
1155
+ /* This function does two slightly different things
1156
+ depending on the input flag want_AT_sibling. If
1157
+ this flag is true, it checks if the input die has
1158
+ a DW_AT_sibling attribute. If it does it returns
1159
+ a pointer to the start of the sibling die in the
1160
+ .debug_info section. Otherwise it behaves the
1161
+ same as the want_AT_sibling false case.
1162
+
1163
+ If the want_AT_sibling flag is false, it returns
1164
+ a pointer to the immediately adjacent die in the
1165
+ .debug_info section.
1166
+
1167
+ Die_info_end points to the end of the .debug_info
1168
+ portion for the cu the die belongs to. It is used
1169
+ to check that the search for the next die does not
1170
+ cross the end of the current cu. Cu_info_start points
1171
+ to the start of the .debug_info portion for the
1172
+ current cu, and is used to add to the offset for
1173
+ DW_AT_sibling attributes. Finally, has_die_child
1174
+ is a pointer to a Dwarf_Bool that is set true if
1175
+ the present die has children, false otherwise.
1176
+ However, in case want_AT_child is true and the die
1177
+ has a DW_AT_sibling attribute *has_die_child is set
1178
+ false to indicate that the children are being skipped.
1179
+
1180
+ die_info_end points to the last byte+1 of the cu. */
1181
+ static int
1182
+ _dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr,
1183
+ Dwarf_CU_Context cu_context,
1184
+ Dwarf_Byte_Ptr die_info_end,
1185
+ Dwarf_Byte_Ptr cu_info_start,
1186
+ Dwarf_Bool want_AT_sibling,
1187
+ Dwarf_Bool * has_die_child,
1188
+ Dwarf_Byte_Ptr *next_die_ptr_out,
1189
+ Dwarf_Error *error)
1190
+ {
1191
+ Dwarf_Byte_Ptr info_ptr = 0;
1192
+ Dwarf_Byte_Ptr abbrev_ptr = 0;
1193
+ Dwarf_Word abbrev_code = 0;
1194
+ Dwarf_Abbrev_List abbrev_list;
1195
+ Dwarf_Half attr = 0;
1196
+ Dwarf_Half attr_form = 0;
1197
+ Dwarf_Unsigned offset = 0;
1198
+ Dwarf_Word leb128_length = 0;
1199
+ Dwarf_Unsigned utmp = 0;
1200
+ Dwarf_Debug dbg = 0;
1201
+
1202
+ info_ptr = die_info_ptr;
1203
+ DECODE_LEB128_UWORD(info_ptr, utmp);
1204
+ abbrev_code = (Dwarf_Word) utmp;
1205
+ if (abbrev_code == 0) {
1206
+ /* Should never happen. Tested before we got here. */
1207
+ _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL);
1208
+ return DW_DLV_ERROR;
1209
+ }
1210
+
1211
+
1212
+ abbrev_list = _dwarf_get_abbrev_for_code(cu_context, abbrev_code);
1213
+ if (abbrev_list == NULL) {
1214
+ _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_NO_ABBREV_LIST);
1215
+ return DW_DLV_ERROR;
1216
+ }
1217
+ dbg = cu_context->cc_dbg;
1218
+
1219
+ *has_die_child = abbrev_list->ab_has_child;
1220
+
1221
+ abbrev_ptr = abbrev_list->ab_abbrev_ptr;
1222
+ do {
1223
+ Dwarf_Unsigned utmp2;
1224
+
1225
+ DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
1226
+ attr = (Dwarf_Half) utmp2;
1227
+ DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
1228
+ attr_form = (Dwarf_Half) utmp2;
1229
+ if (attr_form == DW_FORM_indirect) {
1230
+ Dwarf_Unsigned utmp6;
1231
+
1232
+ /* DECODE_LEB128_UWORD updates info_ptr */
1233
+ DECODE_LEB128_UWORD(info_ptr, utmp6);
1234
+ attr_form = (Dwarf_Half) utmp6;
1235
+
1236
+ }
1237
+
1238
+ if (want_AT_sibling && attr == DW_AT_sibling) {
1239
+ switch (attr_form) {
1240
+ case DW_FORM_ref1:
1241
+ offset = *(Dwarf_Small *) info_ptr;
1242
+ break;
1243
+ case DW_FORM_ref2:
1244
+ /* READ_UNALIGNED does not update info_ptr */
1245
+ READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
1246
+ info_ptr, sizeof(Dwarf_Half));
1247
+ break;
1248
+ case DW_FORM_ref4:
1249
+ READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
1250
+ info_ptr, sizeof(Dwarf_ufixed));
1251
+ break;
1252
+ case DW_FORM_ref8:
1253
+ READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
1254
+ info_ptr, sizeof(Dwarf_Unsigned));
1255
+ break;
1256
+ case DW_FORM_ref_udata:
1257
+ offset =
1258
+ _dwarf_decode_u_leb128(info_ptr, &leb128_length);
1259
+ break;
1260
+ case DW_FORM_ref_addr:
1261
+ /* Very unusual. The FORM is intended to refer to
1262
+ a different CU, but a different CU cannot
1263
+ be a sibling, can it?
1264
+ We could ignore this and treat as if no DW_AT_sibling
1265
+ present. Or derive the offset from it and if
1266
+ it is in the same CU use it directly.
1267
+ The offset here is *supposed* to be a global offset,
1268
+ so adding cu_info_start is wrong to any offset
1269
+ we find here unless cu_info_start
1270
+ is zero! Lets pretend there is no DW_AT_sibling
1271
+ attribute. */
1272
+ goto no_sibling_attr;
1273
+ default:
1274
+ _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_WRONG_FORM);
1275
+ return DW_DLV_ERROR;
1276
+ }
1277
+
1278
+ /* Reset *has_die_child to indicate children skipped. */
1279
+ *has_die_child = false;
1280
+
1281
+ /* A value beyond die_info_end indicates an error. Exactly
1282
+ at die_info_end means 1-past-cu-end and simply means we
1283
+ are at the end, do not return error. Higher level
1284
+ will detect that we are at the end. */
1285
+ if (cu_info_start + offset > die_info_end) {
1286
+ /* Error case, bad DWARF. */
1287
+ _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PAST_END);
1288
+ return DW_DLV_ERROR;
1289
+ }
1290
+ /* At or before end-of-cu */
1291
+ *next_die_ptr_out = cu_info_start + offset;
1292
+ return DW_DLV_OK;
1293
+ }
1294
+
1295
+ no_sibling_attr:
1296
+ if (attr_form != 0) {
1297
+ int res = 0;
1298
+ Dwarf_Unsigned sizeofval = 0;
1299
+ res = _dwarf_get_size_of_val(cu_context->cc_dbg,
1300
+ attr_form,
1301
+ cu_context->cc_version_stamp,
1302
+ cu_context->cc_address_size,
1303
+ info_ptr,
1304
+ cu_context->cc_length_size,
1305
+ &sizeofval,
1306
+ error);
1307
+ if(res != DW_DLV_OK) {
1308
+ return res;
1309
+ }
1310
+ /* It is ok for info_ptr == die_info_end, as we will test
1311
+ later before using a too-large info_ptr */
1312
+ info_ptr += sizeofval;
1313
+ if (info_ptr > die_info_end) {
1314
+ /* More than one-past-end indicates a bug somewhere,
1315
+ likely bad dwarf generation. */
1316
+ _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PAST_END);
1317
+ return DW_DLV_ERROR;
1318
+ }
1319
+ }
1320
+ } while (attr != 0 || attr_form != 0);
1321
+ *next_die_ptr_out = info_ptr;
1322
+ return DW_DLV_OK;
1323
+ }
1324
+
1325
+ /* Multiple TAGs are in fact compile units.
1326
+ Allow them all.
1327
+ Return non-zero if a CU tag.
1328
+ Else return 0.
1329
+ */
1330
+ static int
1331
+ is_cu_tag(int t)
1332
+ {
1333
+ if (t == DW_TAG_compile_unit ||
1334
+ t == DW_TAG_partial_unit ||
1335
+ t == DW_TAG_imported_unit ||
1336
+ t == DW_TAG_type_unit) {
1337
+ return 1;
1338
+ }
1339
+ return 0;
1340
+ }
1341
+
1342
+ /* Given a Dwarf_Debug dbg, and a Dwarf_Die die, it returns
1343
+ a Dwarf_Die for the sibling of die. In case die is NULL,
1344
+ it returns (thru ptr) a Dwarf_Die for the first die in the current
1345
+ cu in dbg. Returns DW_DLV_ERROR on error.
1346
+
1347
+ It is assumed that every sibling chain including those with
1348
+ only one element is terminated with a NULL die, except a
1349
+ chain with only a NULL die.
1350
+
1351
+ The algorithm moves from one die to the adjacent one. It
1352
+ returns when the depth of children it sees equals the number
1353
+ of sibling chain terminations. A single count, child_depth
1354
+ is used to track the depth of children and sibling terminations
1355
+ encountered. Child_depth is incremented when a die has the
1356
+ Has-Child flag set unless the child happens to be a NULL die.
1357
+ Child_depth is decremented when a die has Has-Child false,
1358
+ and the adjacent die is NULL. Algorithm returns when
1359
+ child_depth is 0.
1360
+
1361
+ **NOTE: Do not modify input die, since it is used at the end. */
1362
+ int
1363
+ dwarf_siblingof(Dwarf_Debug dbg,
1364
+ Dwarf_Die die,
1365
+ Dwarf_Die * caller_ret_die, Dwarf_Error * error)
1366
+ {
1367
+ Dwarf_Bool is_info = true;
1368
+ return dwarf_siblingof_b(dbg,die,is_info,caller_ret_die,error);
1369
+ }
1370
+ /* This is the new form, October 2011. On calling with 'die' NULL,
1371
+ we cannot tell if this is debug_info or debug_types, so
1372
+ we must be informed!. */
1373
+ int
1374
+ dwarf_siblingof_b(Dwarf_Debug dbg,
1375
+ Dwarf_Die die,
1376
+ Dwarf_Bool is_info,
1377
+ Dwarf_Die * caller_ret_die, Dwarf_Error * error)
1378
+ {
1379
+ Dwarf_Die ret_die = 0;
1380
+ Dwarf_Byte_Ptr die_info_ptr = 0;
1381
+ Dwarf_Byte_Ptr cu_info_start = 0;
1382
+
1383
+ /* die_info_end points 1-past end of die (once set) */
1384
+ Dwarf_Byte_Ptr die_info_end = 0;
1385
+ Dwarf_Word abbrev_code = 0;
1386
+ Dwarf_Unsigned utmp = 0;
1387
+ /* Since die may be NULL, we rely on the input argument. */
1388
+ Dwarf_Debug_InfoTypes dis = is_info? &dbg->de_info_reading:
1389
+ &dbg->de_types_reading;
1390
+ Dwarf_Small *dataptr = is_info? dbg->de_debug_info.dss_data:
1391
+ dbg->de_debug_types.dss_data;
1392
+
1393
+
1394
+
1395
+ if (dbg == NULL) {
1396
+ _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
1397
+ return (DW_DLV_ERROR);
1398
+ }
1399
+
1400
+ if (die == NULL) {
1401
+ /* Find root die of cu */
1402
+ /* die_info_end is untouched here, need not be set in this
1403
+ branch. */
1404
+ Dwarf_Off off2;
1405
+ Dwarf_CU_Context context=0;
1406
+ Dwarf_Unsigned headerlen = 0;
1407
+
1408
+ /* If we've not loaded debug_info
1409
+ de_cu_context will be NULL. */
1410
+
1411
+ context = dis->de_cu_context;
1412
+ if (context == NULL) {
1413
+ _dwarf_error(dbg, error, DW_DLE_DBG_NO_CU_CONTEXT);
1414
+ return (DW_DLV_ERROR);
1415
+ }
1416
+
1417
+ off2 = context->cc_debug_offset;
1418
+ cu_info_start = dataptr + off2;
1419
+ headerlen = _dwarf_length_of_cu_header(dbg, off2,is_info);
1420
+ die_info_ptr = cu_info_start + headerlen;
1421
+ die_info_end = _dwarf_calculate_section_end_ptr(context);
1422
+ /* Recording the CU die pointer so we can later access
1423
+ for special FORMs relating to .debug_str_offsets
1424
+ and .debug_addr */
1425
+ context->cc_cu_die_offset_present = TRUE;
1426
+ context->cc_cu_die_global_sec_offset = off2 + headerlen;
1427
+ } else {
1428
+ /* Find sibling die. */
1429
+ Dwarf_Bool has_child = false;
1430
+ Dwarf_Sword child_depth = 0;
1431
+ Dwarf_CU_Context context=0;
1432
+
1433
+ /* We cannot have a legal die unless debug_info was loaded, so
1434
+ no need to load debug_info here. */
1435
+ CHECK_DIE(die, DW_DLV_ERROR);
1436
+
1437
+ die_info_ptr = die->di_debug_ptr;
1438
+ if (*die_info_ptr == 0) {
1439
+ return (DW_DLV_NO_ENTRY);
1440
+ }
1441
+ context = die->di_cu_context;
1442
+ cu_info_start = dataptr+ context->cc_debug_offset;
1443
+ die_info_end = _dwarf_calculate_section_end_ptr(context);
1444
+
1445
+ if ((*die_info_ptr) == 0) {
1446
+ return (DW_DLV_NO_ENTRY);
1447
+ }
1448
+ child_depth = 0;
1449
+ do {
1450
+ int res2 = 0;
1451
+ Dwarf_Byte_Ptr die_info_ptr2 = 0;
1452
+ res2 = _dwarf_next_die_info_ptr(die_info_ptr,
1453
+ die->di_cu_context, die_info_end,
1454
+ cu_info_start, true, &has_child,
1455
+ &die_info_ptr2,
1456
+ error);
1457
+ if(res2 != DW_DLV_OK) {
1458
+ return res2;
1459
+ }
1460
+ if (die_info_ptr2 < die_info_ptr) {
1461
+ /* There is something very wrong, our die value
1462
+ decreased. Bad DWARF. */
1463
+ _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_LOW_ERROR);
1464
+ return (DW_DLV_ERROR);
1465
+ }
1466
+ if (die_info_ptr2 > die_info_end) {
1467
+ _dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PAST_END);
1468
+ return (DW_DLV_ERROR);
1469
+ }
1470
+ die_info_ptr = die_info_ptr2;
1471
+
1472
+ /* die_info_end is one past end. Do not read it!
1473
+ A test for ``!= die_info_end'' would work as well,
1474
+ but perhaps < reads more like the meaning. */
1475
+ if (die_info_ptr < die_info_end) {
1476
+ if ((*die_info_ptr) == 0 && has_child) {
1477
+ die_info_ptr++;
1478
+ has_child = false;
1479
+ }
1480
+ }
1481
+
1482
+ /* die_info_ptr can be one-past-end. */
1483
+ if ((die_info_ptr == die_info_end) ||
1484
+ ((*die_info_ptr) == 0)) {
1485
+ for (; child_depth > 0 && *die_info_ptr == 0;
1486
+ child_depth--, die_info_ptr++) {
1487
+ }
1488
+ } else {
1489
+ child_depth = has_child ? child_depth + 1 : child_depth;
1490
+ }
1491
+
1492
+ } while (child_depth != 0);
1493
+ }
1494
+
1495
+ /* die_info_ptr > die_info_end is really a bug (possibly in dwarf
1496
+ generation)(but we are past end, no more DIEs here), whereas
1497
+ die_info_ptr == die_info_end means 'one past end, no more DIEs
1498
+ here'. */
1499
+ if (die_info_ptr >= die_info_end) {
1500
+ return (DW_DLV_NO_ENTRY);
1501
+ }
1502
+
1503
+ if ((*die_info_ptr) == 0) {
1504
+ return (DW_DLV_NO_ENTRY);
1505
+ }
1506
+
1507
+ ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
1508
+ if (ret_die == NULL) {
1509
+ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1510
+ return (DW_DLV_ERROR);
1511
+ }
1512
+
1513
+ ret_die->di_is_info = is_info;
1514
+ ret_die->di_debug_ptr = die_info_ptr;
1515
+ ret_die->di_cu_context =
1516
+ die == NULL ? dis->de_cu_context : die->di_cu_context;
1517
+
1518
+ DECODE_LEB128_UWORD(die_info_ptr, utmp);
1519
+ if (die_info_ptr > die_info_end) {
1520
+ /* We managed to go past the end of the CU!.
1521
+ Something is badly wrong. */
1522
+ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
1523
+ _dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
1524
+ return (DW_DLV_ERROR);
1525
+ }
1526
+ abbrev_code = (Dwarf_Word) utmp;
1527
+ if (abbrev_code == 0) {
1528
+ /* Zero means a null DIE */
1529
+ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
1530
+ return (DW_DLV_NO_ENTRY);
1531
+ }
1532
+ ret_die->di_abbrev_code = abbrev_code;
1533
+ ret_die->di_abbrev_list =
1534
+ _dwarf_get_abbrev_for_code(ret_die->di_cu_context, abbrev_code);
1535
+ if (ret_die->di_abbrev_list == NULL ) {
1536
+ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
1537
+ _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL);
1538
+ return (DW_DLV_ERROR);
1539
+ }
1540
+ if (die == NULL && !is_cu_tag(ret_die->di_abbrev_list->ab_tag)) {
1541
+ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
1542
+ _dwarf_error(dbg, error, DW_DLE_FIRST_DIE_NOT_CU);
1543
+ return (DW_DLV_ERROR);
1544
+ }
1545
+
1546
+ *caller_ret_die = ret_die;
1547
+ return (DW_DLV_OK);
1548
+ }
1549
+
1550
+
1551
+ int
1552
+ dwarf_child(Dwarf_Die die,
1553
+ Dwarf_Die * caller_ret_die,
1554
+ Dwarf_Error * error)
1555
+ {
1556
+ Dwarf_Byte_Ptr die_info_ptr = 0;
1557
+ Dwarf_Byte_Ptr die_info_ptr2 = 0;
1558
+
1559
+ /* die_info_end points one-past-end of die area. */
1560
+ Dwarf_Byte_Ptr die_info_end = 0;
1561
+ Dwarf_Die ret_die = 0;
1562
+ Dwarf_Bool has_die_child = 0;
1563
+ Dwarf_Debug dbg;
1564
+ Dwarf_Word abbrev_code = 0;
1565
+ Dwarf_Unsigned utmp = 0;
1566
+ Dwarf_Debug_InfoTypes dis = 0;
1567
+ int res = 0;
1568
+ Dwarf_CU_Context context = 0;
1569
+
1570
+ CHECK_DIE(die, DW_DLV_ERROR);
1571
+ dbg = die->di_cu_context->cc_dbg;
1572
+ dis = die->di_is_info? &dbg->de_info_reading:
1573
+ &dbg->de_types_reading;
1574
+ die_info_ptr = die->di_debug_ptr;
1575
+
1576
+ /* We are saving a DIE pointer here, but the pointer
1577
+ will not be presumed live later, when it is tested. */
1578
+ dis->de_last_die = die;
1579
+ dis->de_last_di_ptr = die_info_ptr;
1580
+
1581
+ /* NULL die has no child. */
1582
+ if ((*die_info_ptr) == 0)
1583
+ return (DW_DLV_NO_ENTRY);
1584
+
1585
+ context = die->di_cu_context;
1586
+ die_info_end = _dwarf_calculate_section_end_ptr(context);
1587
+
1588
+ res = _dwarf_next_die_info_ptr(die_info_ptr, die->di_cu_context,
1589
+ die_info_end,
1590
+ NULL, false,
1591
+ &has_die_child,
1592
+ &die_info_ptr2,
1593
+ error);
1594
+ if(res != DW_DLV_OK) {
1595
+ return res;
1596
+ }
1597
+ die_info_ptr = die_info_ptr2;
1598
+
1599
+ dis->de_last_di_ptr = die_info_ptr;
1600
+
1601
+ if (!has_die_child) {
1602
+ /* Look for end of sibling chain. */
1603
+ while (dis->de_last_di_ptr < die_info_end) {
1604
+ if (*dis->de_last_di_ptr) {
1605
+ break;
1606
+ }
1607
+ ++dis->de_last_di_ptr;
1608
+ }
1609
+ return (DW_DLV_NO_ENTRY);
1610
+ }
1611
+
1612
+ ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
1613
+ if (ret_die == NULL) {
1614
+ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1615
+ return (DW_DLV_ERROR);
1616
+ }
1617
+ ret_die->di_debug_ptr = die_info_ptr;
1618
+ ret_die->di_cu_context = die->di_cu_context;
1619
+ ret_die->di_is_info = die->di_is_info;
1620
+
1621
+ DECODE_LEB128_UWORD(die_info_ptr, utmp);
1622
+ abbrev_code = (Dwarf_Word) utmp;
1623
+
1624
+ dis->de_last_di_ptr = die_info_ptr;
1625
+
1626
+ if (abbrev_code == 0) {
1627
+ /* Look for end of sibling chain */
1628
+ while (dis->de_last_di_ptr < die_info_end) {
1629
+ if (*dis->de_last_di_ptr) {
1630
+ break;
1631
+ }
1632
+ ++dis->de_last_di_ptr;
1633
+ }
1634
+
1635
+ /* We have arrived at a null DIE, at the end of a CU or the end
1636
+ of a list of siblings. */
1637
+ *caller_ret_die = 0;
1638
+ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
1639
+ return DW_DLV_NO_ENTRY;
1640
+ }
1641
+ ret_die->di_abbrev_code = abbrev_code;
1642
+ ret_die->di_abbrev_list =
1643
+ _dwarf_get_abbrev_for_code(die->di_cu_context, abbrev_code);
1644
+ if (ret_die->di_abbrev_list == NULL) {
1645
+ dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
1646
+ _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
1647
+ return (DW_DLV_ERROR);
1648
+ }
1649
+
1650
+ *caller_ret_die = ret_die;
1651
+ return (DW_DLV_OK);
1652
+ }
1653
+
1654
+ /* Given a (global, not cu_relative) die offset, this returns
1655
+ a pointer to a DIE thru *new_die.
1656
+ It is up to the caller to do a
1657
+ dwarf_dealloc(dbg,*new_die,DW_DLE_DIE);
1658
+ The old form only works with debug_info.
1659
+ The new _b form works with debug_info or debug_types.
1660
+ */
1661
+ int
1662
+ dwarf_offdie(Dwarf_Debug dbg,
1663
+ Dwarf_Off offset, Dwarf_Die * new_die, Dwarf_Error * error)
1664
+ {
1665
+ Dwarf_Bool is_info = true;
1666
+ return dwarf_offdie_b(dbg,offset,is_info,new_die,error);
1667
+ }
1668
+
1669
+ int
1670
+ dwarf_offdie_b(Dwarf_Debug dbg,
1671
+ Dwarf_Off offset, Dwarf_Bool is_info,
1672
+ Dwarf_Die * new_die, Dwarf_Error * error)
1673
+ {
1674
+ Dwarf_CU_Context cu_context = 0;
1675
+ Dwarf_Off new_cu_offset = 0;
1676
+ Dwarf_Die die = 0;
1677
+ Dwarf_Byte_Ptr info_ptr = 0;
1678
+ Dwarf_Unsigned abbrev_code = 0;
1679
+ Dwarf_Unsigned utmp = 0;
1680
+ Dwarf_Debug_InfoTypes dis = 0;
1681
+
1682
+ if (dbg == NULL) {
1683
+ _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
1684
+ return (DW_DLV_ERROR);
1685
+ }
1686
+ dis = is_info? &dbg->de_info_reading:
1687
+ &dbg->de_types_reading;
1688
+
1689
+ cu_context = _dwarf_find_CU_Context(dbg, offset,is_info);
1690
+ if (cu_context == NULL)
1691
+ cu_context = _dwarf_find_offdie_CU_Context(dbg, offset,is_info);
1692
+
1693
+ if (cu_context == NULL) {
1694
+ Dwarf_Unsigned section_size = is_info? dbg->de_debug_info.dss_size:
1695
+ dbg->de_debug_types.dss_size;
1696
+ int res = is_info?_dwarf_load_debug_info(dbg, error):
1697
+ _dwarf_load_debug_types(dbg,error);
1698
+
1699
+ if (res != DW_DLV_OK) {
1700
+ return res;
1701
+ }
1702
+
1703
+ if (dis->de_offdie_cu_context_end != NULL) {
1704
+ Dwarf_CU_Context lcu_context =
1705
+ dis->de_offdie_cu_context_end;
1706
+ new_cu_offset =
1707
+ lcu_context->cc_debug_offset +
1708
+ lcu_context->cc_length +
1709
+ lcu_context->cc_length_size +
1710
+ lcu_context->cc_extension_size;
1711
+ }
1712
+
1713
+
1714
+ do {
1715
+ if ((new_cu_offset +
1716
+ _dwarf_length_of_cu_header_simple(dbg,is_info)) >=
1717
+ section_size) {
1718
+ _dwarf_error(dbg, error, DW_DLE_OFFSET_BAD);
1719
+ return (DW_DLV_ERROR);
1720
+ }
1721
+ res = _dwarf_make_CU_Context(dbg, new_cu_offset,is_info,
1722
+ &cu_context,error);
1723
+ if (res != DW_DLV_OK) {
1724
+ return res;
1725
+ }
1726
+ if (dis->de_offdie_cu_context == NULL) {
1727
+ dis->de_offdie_cu_context = cu_context;
1728
+ dis->de_offdie_cu_context_end = cu_context;
1729
+ } else {
1730
+ dis->de_offdie_cu_context_end->cc_next = cu_context;
1731
+ dis->de_offdie_cu_context_end = cu_context;
1732
+ }
1733
+
1734
+ new_cu_offset = new_cu_offset + cu_context->cc_length +
1735
+ cu_context->cc_length_size +
1736
+ cu_context->cc_extension_size;
1737
+
1738
+ } while (offset >= new_cu_offset);
1739
+ }
1740
+
1741
+ die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
1742
+ if (die == NULL) {
1743
+ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1744
+ return (DW_DLV_ERROR);
1745
+ }
1746
+ die->di_cu_context = cu_context;
1747
+ die->di_is_info = is_info;
1748
+
1749
+ {
1750
+ Dwarf_Small *dataptr = is_info? dbg->de_debug_info.dss_data:
1751
+ dbg->de_debug_types.dss_data;
1752
+ info_ptr = dataptr + offset;
1753
+ }
1754
+ die->di_debug_ptr = info_ptr;
1755
+ DECODE_LEB128_UWORD(info_ptr, utmp);
1756
+ abbrev_code = utmp;
1757
+ if (abbrev_code == 0) {
1758
+ /* we are at a null DIE (or there is a bug). */
1759
+ *new_die = 0;
1760
+ dwarf_dealloc(dbg, die, DW_DLA_DIE);
1761
+ return DW_DLV_NO_ENTRY;
1762
+ }
1763
+ die->di_abbrev_code = abbrev_code;
1764
+ die->di_abbrev_list =
1765
+ _dwarf_get_abbrev_for_code(cu_context, abbrev_code);
1766
+ if (die->di_abbrev_list == NULL) {
1767
+ dwarf_dealloc(dbg, die, DW_DLA_DIE);
1768
+ _dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL);
1769
+ return (DW_DLV_ERROR);
1770
+ }
1771
+
1772
+ *new_die = die;
1773
+ return (DW_DLV_OK);
1774
+ }
1775
+
1776
+ /* This is useful when printing DIE data.
1777
+ The string pointer returned must not be freed.
1778
+ With non-elf objects it is possible the
1779
+ string returned might be empty or NULL,
1780
+ so callers should be prepared for that kind
1781
+ of return. */
1782
+ int
1783
+ dwarf_get_die_section_name(Dwarf_Debug dbg,
1784
+ Dwarf_Bool is_info,
1785
+ const char ** sec_name,
1786
+ Dwarf_Error * error)
1787
+ {
1788
+ struct Dwarf_Section_s *sec = 0;
1789
+ if (is_info) {
1790
+ sec = &dbg->de_debug_info;
1791
+ } else {
1792
+ sec = &dbg->de_debug_types;
1793
+ }
1794
+ if (sec->dss_size == 0) {
1795
+ /* We don't have such a section at all. */
1796
+ return DW_DLV_NO_ENTRY;
1797
+ }
1798
+ *sec_name = sec->dss_name;
1799
+ return DW_DLV_OK;
1800
+ }
1801
+
1802
+