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,418 @@
1
+ /*
2
+
3
+ Copyright (C) 2000, 2004, 2006 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
+ /* The dwarf 2.0 standard dictates that only the following
31
+ fields can be read when an unexpected augmentation string
32
+ (in the cie) is encountered: CIE length, CIE_id, version and
33
+ augmentation; FDE: length, CIE pointer, initial location and
34
+ address range. Unfortunately, with the above restrictions, it
35
+ is impossible to read the instruction table from a CIE or a FDE
36
+ when a new augmentation string is encountered.
37
+ To fix this problem, the following layout is used, if the
38
+ augmentation string starts with the string "z".
39
+ CIE FDE
40
+ length length
41
+ CIE_id CIE_pointer
42
+ version initial_location
43
+ augmentation address_range
44
+
45
+ - length_of_augmented_fields (*NEW*)
46
+ code_alignment_factor Any new fields as necessary
47
+ data_alignment_factor instruction_table
48
+ return_address
49
+ length_of_augmented fields
50
+ Any new fields as necessary
51
+ initial_instructions
52
+
53
+ The type of all the old data items are the same as what is
54
+ described in dwarf 2.0 standard. The length_of_augmented_fields
55
+ is an LEB128 data item that denotes the size (in bytes) of
56
+ the augmented fields (not including the size of
57
+ "length_of_augmented_fields" itself).
58
+
59
+ Handling of cie augmentation strings is necessarly a heuristic.
60
+ See dwarf_frame.c for the currently known augmentation strings.
61
+
62
+
63
+ ---START SGI-ONLY COMMENT:
64
+ SGI-IRIX versions of cie or fde were intended to use "z1", "z2" as the
65
+ augmenter strings if required for new augmentation.
66
+ However, that never happened (as of March 2005).
67
+
68
+ The fde's augmented by the string "z" have a new field
69
+ (signed constant, 4 byte field)
70
+ called offset_into_exception_tables, following the
71
+ length_of_augmented field. This field contains an offset
72
+ into the "_MIPS_eh_region", which describes
73
+ the IRIX CC exception handling tables.
74
+ ---END SGI-ONLY COMMENT
75
+
76
+
77
+ GNU .eh_frame has an augmentation string of z[RLP]* (gcc 3.4)
78
+ The similarity to IRIX 'z' (and proposed but never
79
+ implemented IRIX z1, z2 etc) was confusing things.
80
+ If the section is .eh_frame then 'z' means GNU exception
81
+ information 'Augmentation Data' not IRIX 'z'.
82
+ See The Linux Standard Base Core Specification version 3.0
83
+ */
84
+
85
+ #define DW_DEBUG_FRAME_VERSION 1 /* DWARF2 */
86
+ #define DW_DEBUG_FRAME_VERSION3 3 /* DWARF3 */
87
+ #define DW_DEBUG_FRAME_VERSION4 4 /* DWARF4 */
88
+ /* The following is SGI/IRIX specific, and probably no longer
89
+ in use anywhere. */
90
+ #define DW_DEBUG_FRAME_AUGMENTER_STRING "mti v1"
91
+
92
+ /* The value of the offset field for Cie's. */
93
+ #define DW_CIE_OFFSET ~(0x0)
94
+
95
+ /* The augmentation string may be NULL. */
96
+ #define DW_EMPTY_STRING ""
97
+
98
+ #define DW_FRAME_INSTR_OPCODE_SHIFT 6
99
+ #define DW_FRAME_INSTR_OFFSET_MASK 0x3f
100
+
101
+ /*
102
+ This struct denotes the rule for a register in a row of
103
+ the frame table. In other words, it is one element of
104
+ the table.
105
+ */
106
+ struct Dwarf_Reg_Rule_s {
107
+
108
+ /* Is a flag indicating whether the rule includes the offset
109
+ field, ie whether the ru_offset field is valid or not.
110
+ Applies only if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET.
111
+ It is important, since reg+offset (offset of 0) is different from
112
+ just 'register' since the former means 'read memory at address
113
+ given by the sum of register contents plus offset to get the
114
+ value'. whereas the latter means 'the value is in the register'.
115
+
116
+ The 'register' numbers are either real registers (ie, table
117
+ columns defined as real registers) or defined entries that are
118
+ not really hardware registers, such as DW_FRAME_SAME_VAL or
119
+ DW_FRAME_CFA_COL. */
120
+ Dwarf_Sbyte ru_is_off;
121
+
122
+ /* DW_EXPR_OFFSET (0, DWARF2)
123
+ DW_EXPR_VAL_OFFSET 1 (dwarf2/3)
124
+ DW_EXPR_EXPRESSION 2 (dwarf2/3)
125
+ DW_EXPR_VAL_EXPRESSION 3 (dwarf2/3)
126
+ See dwarf_frame.h. */
127
+ Dwarf_Sbyte ru_value_type;
128
+
129
+ /* Register involved in this rule. */
130
+ Dwarf_Half ru_register;
131
+
132
+ /* Offset to add to register, if indicated by ru_is_offset
133
+ and if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET.
134
+ If DW_EXPR_EXPRESSION or DW_EXPR_VAL_EXPRESSION
135
+ this is DW_FORM_block block-length, not offset. */
136
+ Dwarf_Unsigned ru_offset_or_block_len;
137
+
138
+ /* For DW_EXPR_EXPRESSION DW_EXPR_VAL_EXPRESSION these is set,
139
+ else 0. */
140
+ Dwarf_Small *ru_block;
141
+ };
142
+
143
+ typedef struct Dwarf_Frame_s *Dwarf_Frame;
144
+
145
+ /*
146
+ This structure represents a row of the frame table.
147
+ Fr_loc is the pc value for this row, and Fr_reg
148
+ contains the rule for each column.
149
+
150
+ Entry DW_FRAME_CFA_COL of fr_reg was the tradional MIPS
151
+ way of setting CFA. cfa_rule is the new one.
152
+ */
153
+ struct Dwarf_Frame_s {
154
+
155
+ /* Pc value corresponding to this row of the frame table. */
156
+ Dwarf_Addr fr_loc;
157
+
158
+ /* Rules for all the registers in this row. */
159
+ struct Dwarf_Reg_Rule_s fr_cfa_rule;
160
+
161
+ /* fr_reg_count is the the number of
162
+ entries of the fr_reg array. */
163
+ unsigned long fr_reg_count;
164
+ struct Dwarf_Reg_Rule_s *fr_reg;
165
+
166
+ Dwarf_Frame fr_next;
167
+ };
168
+
169
+ typedef struct Dwarf_Frame_Op_List_s *Dwarf_Frame_Op_List;
170
+
171
+ /* This is used to chain together Dwarf_Frame_Op structures. */
172
+ struct Dwarf_Frame_Op_List_s {
173
+ Dwarf_Frame_Op *fl_frame_instr;
174
+ Dwarf_Frame_Op_List fl_next;
175
+ };
176
+
177
+ /* See dwarf_frame.c for the heuristics used to set the
178
+ Dwarf_Cie ci_augmentation_type.
179
+
180
+ This succinctly helps interpret the size and meaning of .debug_frame
181
+ and (for gcc) .eh_frame.
182
+
183
+ In the case of gcc .eh_frame (gcc 3.3, 3.4)
184
+ z may be followed by one or more of
185
+ L R P.
186
+
187
+ */
188
+ enum Dwarf_augmentation_type {
189
+ aug_empty_string, /* Default empty augmentation string. */
190
+ aug_irix_exception_table, /* IRIX plain "z",
191
+ for exception handling, IRIX CC compiler.
192
+ Proposed z1 z2 ... never implemented. */
193
+ aug_gcc_eh_z, /* gcc z augmentation, (including
194
+ L R P variations). gcc 3.3 3.4 exception
195
+ handling in eh_frame. */
196
+ aug_irix_mti_v1, /* IRIX "mti v1" augmentation string. Probably
197
+ never in any released SGI-IRIX compiler. */
198
+ aug_eh, /* For gcc .eh_frame, "eh" is the string.,
199
+ gcc 1,2, egcs. Older values. */
200
+ aug_armcc, /* "armcc+" meaning the cfa calculation
201
+ is corrected to be standard (output by
202
+ Arm C RVCT 3.0 SP1 and later). See
203
+ http://sourceware.org/ml/gdb-patches/2006-12/msg00249.html
204
+ for details. */
205
+ aug_unknown, /* Unknown augmentation, we cannot do much. */
206
+ aug_past_last
207
+ };
208
+
209
+
210
+ /*
211
+ This structure contains all the pertinent info for a Cie. Most
212
+ of the fields are taken straight from the definition of a Cie.
213
+ Ci_cie_start points to the address (in .debug_frame) where this
214
+ Cie begins. Ci_cie_instr_start points to the first byte of the
215
+ frame instructions for this Cie. Ci_dbg points to the associated
216
+ Dwarf_Debug structure. Ci_initial_table is a pointer to the table
217
+ row generated by the instructions for this Cie.
218
+ */
219
+ struct Dwarf_Cie_s {
220
+ Dwarf_Unsigned ci_length;
221
+ char *ci_augmentation;
222
+ Dwarf_Small ci_code_alignment_factor;
223
+ Dwarf_Sbyte ci_data_alignment_factor;
224
+ Dwarf_Small ci_return_address_register;
225
+ Dwarf_Small *ci_cie_start;
226
+ Dwarf_Small *ci_cie_instr_start;
227
+ Dwarf_Debug ci_dbg;
228
+ Dwarf_Frame ci_initial_table;
229
+ Dwarf_Cie ci_next;
230
+ Dwarf_Small ci_length_size;
231
+ Dwarf_Small ci_extension_size;
232
+ Dwarf_Half ci_cie_version_number;
233
+ enum Dwarf_augmentation_type ci_augmentation_type;
234
+
235
+ /* The following 2 for GNU .eh_frame exception handling
236
+ Augmentation Data. Set if ci_augmentation_type
237
+ is aug_gcc_eh_z. Zero if unused. */
238
+ Dwarf_Unsigned ci_gnu_eh_augmentation_len;
239
+ Dwarf_Ptr ci_gnu_eh_augmentation_bytes;
240
+
241
+ /* These are extracted from the gnu eh_frame
242
+ augmentation if the
243
+ augmentation begins with 'z'. See Linux LSB documents.
244
+ Otherwize these are zero. */
245
+ unsigned char ci_gnu_personality_handler_encoding;
246
+ unsigned char ci_gnu_lsda_encoding;
247
+ unsigned char ci_gnu_fde_begin_encoding;
248
+
249
+ /* If 'P' augmentation present, is handler addr. Else
250
+ is zero. */
251
+ Dwarf_Addr ci_gnu_personality_handler_addr;
252
+
253
+
254
+ /* In creating list of cie's (which will become an array)
255
+ record the position so fde can get it on fde creation. */
256
+ Dwarf_Unsigned ci_index;
257
+ Dwarf_Small * ci_section_ptr;
258
+ /* DWARF4 adds address size and segment size to the CIE: the .debug_info
259
+ section may not always be present to allow libdwarf to
260
+ find address_size from the compilation-unit. */
261
+ Dwarf_Half ci_address_size;
262
+ Dwarf_Half ci_segment_size;
263
+
264
+ };
265
+
266
+ /*
267
+ This structure contains all the pertinent info for a Fde.
268
+ Most of the fields are taken straight from the definition.
269
+ fd_cie_index is the index of the Cie associated with this
270
+ Fde in the list of Cie's for this debug_frame. Fd_cie
271
+ points to the corresponsing Dwarf_Cie structure. Fd_fde_start
272
+ points to the start address of the Fde. Fd_fde_instr_start
273
+ points to the start of the instructions for this Fde. Fd_dbg
274
+ points to the associated Dwarf_Debug structure.
275
+ */
276
+ struct Dwarf_Fde_s {
277
+ Dwarf_Unsigned fd_length;
278
+ Dwarf_Addr fd_cie_offset;
279
+ Dwarf_Unsigned fd_cie_index;
280
+ Dwarf_Cie fd_cie;
281
+ Dwarf_Addr fd_initial_location;
282
+ Dwarf_Small *fd_initial_loc_pos;
283
+ Dwarf_Addr fd_address_range;
284
+ Dwarf_Small *fd_fde_start;
285
+ Dwarf_Small *fd_fde_instr_start;
286
+ Dwarf_Debug fd_dbg;
287
+
288
+ /* fd_offset_into_exception_tables is SGI/IRIX exception table
289
+ offset. Unused and zero if not IRIX .debug_frame. */
290
+ Dwarf_Signed fd_offset_into_exception_tables;
291
+
292
+ Dwarf_Fde fd_next;
293
+ Dwarf_Small fd_length_size;
294
+ Dwarf_Small fd_extension_size;
295
+ /* So we know from an fde which 'count' of fde-s in
296
+ Dwarf_Debug applies: eh or standard. */
297
+ Dwarf_Small fd_is_eh;
298
+ /* The following 2 for GNU .eh_frame exception handling
299
+ Augmentation Data. Set if CIE ci_augmentation_type
300
+ is aug_gcc_eh_z. Zero if unused. */
301
+ Dwarf_Unsigned fd_gnu_eh_augmentation_len;
302
+ Dwarf_Ptr fd_gnu_eh_augmentation_bytes;
303
+ Dwarf_Addr fd_gnu_eh_lsda; /* If 'L' augmentation letter
304
+ present: is address of the
305
+ Language Specific Data Area (LSDA). If not 'L" is zero. */
306
+
307
+ /* The following 3 are about the Elf section the FDEs come from. */
308
+ Dwarf_Small * fd_section_ptr;
309
+ Dwarf_Unsigned fd_section_length;
310
+ Dwarf_Unsigned fd_section_index;
311
+
312
+ };
313
+
314
+
315
+ int
316
+ _dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist,
317
+ Dwarf_Off ** offsetlist,
318
+ Dwarf_Signed * returncount,
319
+ Dwarf_Error * err);
320
+
321
+ int
322
+ _dwarf_get_fde_list_internal(Dwarf_Debug dbg,
323
+ Dwarf_Cie ** cie_data,
324
+ Dwarf_Signed * cie_element_count,
325
+ Dwarf_Fde ** fde_data,
326
+ Dwarf_Signed * fde_element_count,
327
+ Dwarf_Small * section_ptr,
328
+ Dwarf_Unsigned section_index,
329
+ Dwarf_Unsigned section_length,
330
+ Dwarf_Unsigned cie_id_value,
331
+ int use_gnu_cie_calc, /* If non-zero,
332
+ this is gcc eh_frame. */
333
+ Dwarf_Error * error);
334
+
335
+ enum Dwarf_augmentation_type
336
+ _dwarf_get_augmentation_type(Dwarf_Debug dbg,
337
+ Dwarf_Small *augmentation_string,
338
+ int is_gcc_eh_frame);
339
+
340
+ Dwarf_Unsigned _dwarf_get_return_address_reg(Dwarf_Small *frame_ptr,
341
+ int version,
342
+ unsigned long *size);
343
+
344
+ /* Temporary recording of crucial cie/fde prefix data.
345
+ Vastly simplifies some argument lists. */
346
+ struct cie_fde_prefix_s {
347
+ /* cf_start_addr is a pointer to the first byte
348
+ of this fde/cie (meaning the length field itself) */
349
+ Dwarf_Small * cf_start_addr;
350
+ /* cf_addr_after_prefix is a pointer
351
+ to the first byte of this fde/cie
352
+ we are reading now, immediately following
353
+ the length field read by READ_AREA_LENGTH. */
354
+ Dwarf_Small * cf_addr_after_prefix;
355
+ /* cf_length is the length field value from the cie/fde
356
+ header. */
357
+ Dwarf_Unsigned cf_length;
358
+ int cf_local_length_size;
359
+ int cf_local_extension_size;
360
+ Dwarf_Unsigned cf_cie_id;
361
+ Dwarf_Small * cf_cie_id_addr; /* used for eh_frame calculations. */
362
+
363
+ /* Simplifies passing around these values to create fde having
364
+ these here. */
365
+ /* cf_section_ptr is a pointer to the first byte
366
+ of the object section the prefix is read from. */
367
+ Dwarf_Small * cf_section_ptr;
368
+ Dwarf_Unsigned cf_section_index;
369
+ Dwarf_Unsigned cf_section_length;
370
+ };
371
+
372
+ int
373
+ _dwarf_exec_frame_instr(Dwarf_Bool make_instr,
374
+ Dwarf_Frame_Op ** ret_frame_instr,
375
+ Dwarf_Bool search_pc,
376
+ Dwarf_Addr search_pc_val,
377
+ Dwarf_Addr initial_loc,
378
+ Dwarf_Small * start_instr_ptr,
379
+ Dwarf_Small * final_instr_ptr,
380
+ Dwarf_Frame table,
381
+ Dwarf_Cie cie,
382
+ Dwarf_Debug dbg,
383
+ Dwarf_Half reg_num_of_cfa,
384
+ Dwarf_Sword * returned_count,
385
+ int *returned_error);
386
+
387
+
388
+ int dwarf_read_cie_fde_prefix(Dwarf_Debug dbg,
389
+ Dwarf_Small *frame_ptr_in,
390
+ Dwarf_Small *section_ptr_in,
391
+ Dwarf_Unsigned section_index_in,
392
+ Dwarf_Unsigned section_length_in,
393
+ struct cie_fde_prefix_s *prefix_out,
394
+ Dwarf_Error *error);
395
+
396
+ int dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
397
+ struct cie_fde_prefix_s * prefix,
398
+ Dwarf_Small *section_pointer,
399
+ Dwarf_Small *frame_ptr,
400
+ Dwarf_Small *section_ptr_end,
401
+ int use_gnu_cie_calc,
402
+ Dwarf_Cie cie_ptr_in,
403
+ Dwarf_Fde *fde_ptr_out,
404
+ Dwarf_Error *error);
405
+
406
+ int dwarf_create_cie_from_after_start(Dwarf_Debug dbg,
407
+ struct cie_fde_prefix_s *prefix,
408
+ Dwarf_Small* section_pointer,
409
+ Dwarf_Small* frame_ptr,
410
+ Dwarf_Small *section_ptr_end,
411
+ Dwarf_Unsigned cie_count,
412
+ int use_gnu_cie_calc,
413
+ Dwarf_Cie *cie_ptr_out,
414
+ Dwarf_Error *error);
415
+
416
+
417
+ int _dwarf_frame_constructor(Dwarf_Debug dbg,void * );
418
+ void _dwarf_frame_destructor (void *);
@@ -0,0 +1,1533 @@
1
+ /*
2
+
3
+ Copyright (C) 2000-2006 Silicon Graphics, Inc. All Rights Reserved.
4
+ Portions Copyright (C) 2007-2012 David Anderson. All Rights Reserved.
5
+ Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved.
6
+
7
+ This program is free software; you can redistribute it and/or modify it
8
+ under the terms of version 2.1 of the GNU Lesser General Public License
9
+ as published by the Free Software Foundation.
10
+
11
+ This program is distributed in the hope that it would be useful, but
12
+ WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
+
15
+ Further, this software is distributed without any warranty that it is
16
+ free of the rightful claim of any third person regarding infringement
17
+ or the like. Any license provided herein, whether implied or
18
+ otherwise, applies only to this software file. Patent licenses, if
19
+ any, provided herein do not apply to combinations of this program with
20
+ other software, or any other product whatsoever.
21
+
22
+ You should have received a copy of the GNU Lesser General Public
23
+ License along with this program; if not, write the Free Software
24
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
25
+ USA.
26
+
27
+ */
28
+
29
+ /* This implements _dwarf_get_fde_list_internal()
30
+ and related helper functions for reading cie/fde data. */
31
+
32
+ #include "config.h"
33
+ #include "dwarf_incl.h"
34
+ #include <stdio.h>
35
+ #include <stdlib.h>
36
+ #include "dwarf_frame.h"
37
+ #include "dwarf_arange.h" /* using Arange as a way to build a list */
38
+
39
+
40
+ static int dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr,
41
+ Dwarf_Cie cur_cie_ptr,
42
+ Dwarf_Cie * cie_ptr_to_use_out,
43
+ Dwarf_Cie head_cie_ptr);
44
+ static void dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr,
45
+ Dwarf_Cie head_cie_ptr);
46
+ static int dwarf_create_cie_from_start(Dwarf_Debug dbg,
47
+ Dwarf_Small * cie_ptr_val,
48
+ Dwarf_Small * section_ptr,
49
+ Dwarf_Unsigned section_index,
50
+ Dwarf_Unsigned section_length,
51
+ Dwarf_Small * section_ptr_end,
52
+ Dwarf_Unsigned cie_id_value,
53
+ Dwarf_Unsigned cie_count,
54
+ int use_gnu_cie_calc,
55
+ Dwarf_Cie * cie_ptr_to_use_out,
56
+ Dwarf_Error * error);
57
+
58
+ static Dwarf_Small *get_cieptr_given_offset(Dwarf_Unsigned cie_id_value,
59
+ int use_gnu_cie_calc,
60
+ Dwarf_Small * section_ptr,
61
+ Dwarf_Small * cie_id_addr);
62
+ static int get_gcc_eh_augmentation(Dwarf_Debug dbg,
63
+ Dwarf_Small * frame_ptr,
64
+ unsigned long
65
+ *size_of_augmentation_data,
66
+ enum Dwarf_augmentation_type augtype,
67
+ Dwarf_Small * section_pointer,
68
+ Dwarf_Small * fde_eh_encoding_out,
69
+ char *augmentation,
70
+ Dwarf_Error *error);
71
+
72
+ static int
73
+ gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation,
74
+ Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len,
75
+ Dwarf_Half address_size,
76
+ unsigned char *pers_hand_enc_out,
77
+ unsigned char *lsda_enc_out,
78
+ unsigned char *fde_begin_enc_out,
79
+ Dwarf_Addr * gnu_pers_addr_out,
80
+ Dwarf_Error *error);
81
+
82
+
83
+ static int read_encoded_ptr(Dwarf_Debug dbg,
84
+ Dwarf_Small * section_pointer,
85
+ Dwarf_Small * input_field,
86
+ int gnu_encoding,
87
+ Dwarf_Half address_size,
88
+ Dwarf_Unsigned * addr,
89
+ Dwarf_Small ** input_field_out,
90
+ Dwarf_Error *error);
91
+
92
+
93
+
94
+ static int qsort_compare(const void *elem1, const void *elem2);
95
+
96
+
97
+ /* Adds 'newone' to the end of the list starting at 'head'
98
+ and makes the new one 'cur'rent. */
99
+ static void
100
+ chain_up_fde(Dwarf_Fde newone, Dwarf_Fde * head, Dwarf_Fde * cur)
101
+ {
102
+ if (*head == NULL)
103
+ *head = newone;
104
+ else {
105
+ (*cur)->fd_next = newone;
106
+ }
107
+ *cur = newone;
108
+
109
+ }
110
+
111
+ /* Adds 'newone' to the end of the list starting at 'head'
112
+ and makes the new one 'cur'rent. */
113
+ static void
114
+ chain_up_cie(Dwarf_Cie newone, Dwarf_Cie * head, Dwarf_Cie * cur)
115
+ {
116
+ if (*head == NULL) {
117
+ *head = newone;
118
+ } else {
119
+ (*cur)->ci_next = newone;
120
+ }
121
+ *cur = newone;
122
+ }
123
+
124
+ /* The size of the length field plus the
125
+ value of length must be an integral
126
+ multiple of the address size. Dwarf4 standard.
127
+
128
+ A constant that gives the number of bytes of the CIE
129
+ structure, not including the length field itself
130
+ (where length mod <size of an address> == 0)
131
+ (see Section 7.2.2). Dwarf3 standard.
132
+
133
+ A uword constant that gives the number of bytes of
134
+ the CIE structure, not including the
135
+ length field, itself (length mod <addressing unit size> == 0).
136
+ Dwarf2 standard.*/
137
+ static void
138
+ validate_length(Dwarf_Debug dbg,
139
+ Dwarf_Cie cieptr, Dwarf_Unsigned length,
140
+ Dwarf_Unsigned length_size,
141
+ Dwarf_Unsigned extension_size,
142
+ Dwarf_Small * section_ptr,
143
+ Dwarf_Small * ciefde_start,
144
+ const char * cieorfde)
145
+ {
146
+ Dwarf_Unsigned address_size = cieptr->ci_address_size;
147
+ Dwarf_Unsigned length_field_summed = length_size + extension_size;
148
+ Dwarf_Unsigned total_len = length + length_field_summed;
149
+ Dwarf_Unsigned mod = total_len % address_size;
150
+
151
+ if (mod != 0) {
152
+ char msg[DW_HARMLESS_ERROR_MSG_STRING_SIZE];
153
+ Dwarf_Unsigned sectionoffset = ciefde_start - section_ptr;
154
+ snprintf(msg,sizeof(msg),
155
+ "DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE"
156
+ " len=0x%" DW_PR_XZEROS DW_PR_DUx
157
+ ", len size=0x%" DW_PR_XZEROS DW_PR_DUx
158
+ ", extn size=0x%" DW_PR_XZEROS DW_PR_DUx
159
+ ", totl length=0x%" DW_PR_XZEROS DW_PR_DUx
160
+ ", addr size=0x%" DW_PR_XZEROS DW_PR_DUx
161
+ ", mod=0x%" DW_PR_XZEROS DW_PR_DUx " must be zero"
162
+ " in %s"
163
+ ", offset 0x%" DW_PR_XZEROS DW_PR_DUx ".",
164
+ length,
165
+ length_size,
166
+ extension_size,
167
+ total_len,address_size, mod,
168
+ cieorfde,
169
+ sectionoffset);
170
+ dwarf_insert_harmless_error(dbg,msg);
171
+ }
172
+ return;
173
+ }
174
+
175
+
176
+ #if 0 /* FOR DEBUGGING */
177
+ /* For debugging only. */
178
+ static void
179
+ print_prefix(struct cie_fde_prefix_s *prefix, int line)
180
+ {
181
+ printf("prefix-print, prefix at 0x%lx, line %d\n",
182
+ (long) prefix, line);
183
+ printf(" start addr 0x%lx after prefix 0x%lx\n",
184
+ (long) prefix->cf_start_addr,
185
+ (long) prefix->cf_addr_after_prefix);
186
+ printf(" length 0x%" DW_PR_DUx ", len size %d ext size %d\n",
187
+ (Dwarf_Unsigned) prefix->cf_length,
188
+ prefix->cf_local_length_size,
189
+ prefix->cf_local_extension_size);
190
+ printf(" cie_id 0x%" DW_PR_DUx " cie_id cie_id_addr 0x%lx\n",
191
+ (Dwarf_Unsigned) prefix->cf_cie_id,
192
+ (long) prefix->cf_cie_id_addr);
193
+ printf
194
+ (" sec ptr 0x%lx sec index %" DW_PR_DSd " sec len 0x%" DW_PR_DUx " sec past end 0x%lx\n",
195
+ (long) prefix->cf_section_ptr,
196
+ (Dwarf_Signed) prefix->cf_section_index,
197
+ (Dwarf_Unsigned) prefix->cf_section_length,
198
+ (long) prefix->cf_section_ptr + prefix->cf_section_length);
199
+ }
200
+ #endif
201
+
202
+
203
+
204
+ /* Internal function called from various places to create
205
+ lists of CIEs and FDEs. Not directly called
206
+ by consumer code */
207
+ int
208
+ _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data,
209
+ Dwarf_Signed * cie_element_count,
210
+ Dwarf_Fde ** fde_data,
211
+ Dwarf_Signed * fde_element_count,
212
+ Dwarf_Small * section_ptr,
213
+ Dwarf_Unsigned section_index,
214
+ Dwarf_Unsigned section_length,
215
+ Dwarf_Unsigned cie_id_value,
216
+ int use_gnu_cie_calc, Dwarf_Error * error)
217
+ {
218
+ /* Scans the debug_frame section. */
219
+ Dwarf_Small *frame_ptr = section_ptr;
220
+ Dwarf_Small *section_ptr_end = section_ptr + section_length;
221
+
222
+
223
+
224
+ /* New_cie points to the Cie being read, and head_cie_ptr and
225
+ cur_cie_ptr are used for chaining them up in sequence.
226
+ In case cie's are reused aggressively we need tail_cie_ptr
227
+ to add to the chain. If we re-use an early cie
228
+ later on, that does not mean we chain a new cie to the early one,
229
+ we always chain it to the tail. */
230
+ Dwarf_Cie head_cie_ptr = NULL;
231
+ Dwarf_Cie cur_cie_ptr = NULL;
232
+ Dwarf_Cie tail_cie_ptr = NULL;
233
+ Dwarf_Word cie_count = 0;
234
+
235
+ /* Points to a list of contiguous pointers to Dwarf_Cie structures.
236
+ */
237
+ Dwarf_Cie *cie_list_ptr = 0;
238
+
239
+
240
+ /* New_fde points to the Fde being created, and head_fde_ptr and
241
+ cur_fde_ptr are used to chain them up. */
242
+ Dwarf_Fde head_fde_ptr = NULL;
243
+ Dwarf_Fde cur_fde_ptr = NULL;
244
+ Dwarf_Word fde_count = 0;
245
+
246
+ /* Points to a list of contiguous pointers to Dwarf_Fde structures.
247
+ */
248
+ Dwarf_Fde *fde_list_ptr = NULL;
249
+
250
+ Dwarf_Word i = 0;
251
+ int res = DW_DLV_ERROR;
252
+
253
+ if (frame_ptr == 0) {
254
+ return DW_DLV_NO_ENTRY;
255
+ }
256
+
257
+ /* We create the fde and cie arrays. Processing each CIE as we come
258
+ to it or as an FDE refers to it. We cannot process 'late' CIEs
259
+ late as GNU .eh_frame complexities mean we need the whole CIE
260
+ before we can process the FDE correctly. */
261
+ while (frame_ptr < section_ptr_end) {
262
+
263
+ struct cie_fde_prefix_s prefix;
264
+
265
+ /* First read in the 'common prefix' to figure out what we are
266
+ to do with this entry. */
267
+ memset(&prefix, 0, sizeof(prefix));
268
+ res = dwarf_read_cie_fde_prefix(dbg,
269
+ frame_ptr, section_ptr,
270
+ section_index,
271
+ section_length, &prefix, error);
272
+ if (res == DW_DLV_ERROR) {
273
+ dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
274
+ return res;
275
+ }
276
+ if (res == DW_DLV_NO_ENTRY)
277
+ break;
278
+ frame_ptr = prefix.cf_addr_after_prefix;
279
+ if (frame_ptr >= section_ptr_end) {
280
+ dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
281
+ _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
282
+ return DW_DLV_ERROR;
283
+ }
284
+
285
+ if (prefix.cf_cie_id == cie_id_value) {
286
+ /* This is a CIE. */
287
+ Dwarf_Cie cie_ptr_to_use = 0;
288
+
289
+ int resc = dwarf_find_existing_cie_ptr(prefix.cf_start_addr,
290
+ cur_cie_ptr,
291
+ &cie_ptr_to_use,
292
+ head_cie_ptr);
293
+ if (resc == DW_DLV_OK) {
294
+ cur_cie_ptr = cie_ptr_to_use;
295
+ /* Ok. Seen already. */
296
+ } else if (resc == DW_DLV_NO_ENTRY) {
297
+ /* CIE before its FDE in this case. */
298
+ resc = dwarf_create_cie_from_after_start(dbg,
299
+ &prefix,
300
+ section_ptr,
301
+ frame_ptr,
302
+ section_ptr_end,
303
+ cie_count,
304
+ use_gnu_cie_calc,
305
+ &cie_ptr_to_use,
306
+ error);
307
+ /* ASSERT: res==DW_DLV_NO_ENTRY impossible. */
308
+ if (resc == DW_DLV_ERROR) {
309
+ dealloc_fde_cie_list_internal(head_fde_ptr,
310
+ head_cie_ptr);
311
+ return resc;
312
+ }
313
+ /* ASSERT res != DW_DLV_NO_ENTRY */
314
+ cie_count++;
315
+ chain_up_cie(cie_ptr_to_use, &head_cie_ptr,
316
+ &tail_cie_ptr);
317
+ cur_cie_ptr = tail_cie_ptr;
318
+ } else { /* res == DW_DLV_ERROR */
319
+
320
+ dealloc_fde_cie_list_internal(head_fde_ptr,
321
+ head_cie_ptr);
322
+ return resc;
323
+ }
324
+ frame_ptr = cie_ptr_to_use->ci_cie_start +
325
+ cie_ptr_to_use->ci_length +
326
+ cie_ptr_to_use->ci_length_size +
327
+ cie_ptr_to_use->ci_extension_size;
328
+ continue;
329
+ } else {
330
+ /* This is an FDE, Frame Description Entry, see the Dwarf
331
+ Spec, section 6.4.1 */
332
+ int resf = DW_DLV_ERROR;
333
+ Dwarf_Cie cie_ptr_to_use = 0;
334
+ Dwarf_Fde fde_ptr_to_use = 0;
335
+
336
+ /* Do not call this twice on one prefix, as
337
+ prefix.cf_cie_id_addr is altered as a side effect. */
338
+ Dwarf_Small *cieptr_val =
339
+ get_cieptr_given_offset(prefix.cf_cie_id,
340
+ use_gnu_cie_calc,
341
+ section_ptr,
342
+ prefix.cf_cie_id_addr);
343
+
344
+ resf = dwarf_find_existing_cie_ptr(cieptr_val,
345
+ cur_cie_ptr,
346
+ &cie_ptr_to_use,
347
+ head_cie_ptr);
348
+ if (resf == DW_DLV_OK) {
349
+ cur_cie_ptr = cie_ptr_to_use;
350
+ /* Ok. Seen CIE already. */
351
+ } else if (resf == DW_DLV_NO_ENTRY) {
352
+ resf = dwarf_create_cie_from_start(dbg,
353
+ cieptr_val,
354
+ section_ptr,
355
+ section_index,
356
+ section_length,
357
+ section_ptr_end,
358
+ cie_id_value,
359
+ cie_count,
360
+ use_gnu_cie_calc,
361
+ &cie_ptr_to_use,
362
+ error);
363
+ if (resf == DW_DLV_ERROR) {
364
+ dealloc_fde_cie_list_internal(head_fde_ptr,
365
+ head_cie_ptr);
366
+ return resf;
367
+ } else if (res == DW_DLV_NO_ENTRY) {
368
+ return resf;
369
+ }
370
+ ++cie_count;
371
+ chain_up_cie(cie_ptr_to_use, &head_cie_ptr,
372
+ &tail_cie_ptr);
373
+ cur_cie_ptr = tail_cie_ptr;
374
+
375
+ } else {
376
+ /* DW_DLV_ERROR */
377
+ return resf;
378
+ }
379
+
380
+ resf = dwarf_create_fde_from_after_start(dbg,
381
+ &prefix,
382
+ section_ptr,
383
+ frame_ptr,
384
+ section_ptr_end,
385
+ use_gnu_cie_calc,
386
+ cie_ptr_to_use,
387
+ &fde_ptr_to_use,
388
+ error);
389
+ if (resf == DW_DLV_ERROR) {
390
+ return resf;
391
+ }
392
+ chain_up_fde(fde_ptr_to_use, &head_fde_ptr, &cur_fde_ptr);
393
+ fde_count++;
394
+ /* ASSERT: DW_DLV_OK. */
395
+ frame_ptr = fde_ptr_to_use->fd_fde_start +
396
+ fde_ptr_to_use->fd_length +
397
+ fde_ptr_to_use->fd_length_size +
398
+ fde_ptr_to_use->fd_extension_size;
399
+ if (frame_ptr < fde_ptr_to_use->fd_fde_instr_start) {
400
+ /* Sanity check. With a really short fde instruction
401
+ set and address_size we think is 8
402
+ as it is ELF64 (but is
403
+ really 4, as in DWARF{2,3} where we have
404
+ no FDE address_size) we emit an error.
405
+ This error means things will not go well. */
406
+ _dwarf_error(dbg,error,
407
+ DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH);
408
+ return DW_DLV_ERROR;
409
+ }
410
+
411
+
412
+ continue;
413
+ }
414
+ }
415
+ /* Now build list of CIEs from the list. If there are no CIEs
416
+ there should be no FDEs. */
417
+ if (cie_count > 0) {
418
+ cie_list_ptr = (Dwarf_Cie *)
419
+ _dwarf_get_alloc(dbg, DW_DLA_LIST, cie_count);
420
+ } else {
421
+ if (fde_count > 0) {
422
+ dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
423
+ _dwarf_error(dbg, error, DW_DLE_ORPHAN_FDE);
424
+ return DW_DLV_ERROR;
425
+ }
426
+ dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
427
+ return DW_DLV_NO_ENTRY;
428
+ }
429
+ if (cie_list_ptr == NULL) {
430
+ dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
431
+ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
432
+ return DW_DLV_ERROR;
433
+ }
434
+ cur_cie_ptr = head_cie_ptr;
435
+ for (i = 0; i < cie_count; i++) {
436
+ *(cie_list_ptr + i) = cur_cie_ptr;
437
+ cur_cie_ptr = cur_cie_ptr->ci_next;
438
+ }
439
+
440
+ /* Now build array of FDEs from the list.
441
+ With orphan CIEs (meaning no FDEs)
442
+ lets not return DW_DLV_NO_ENTRY */
443
+ if (fde_count > 0) {
444
+ fde_list_ptr = (Dwarf_Fde *)
445
+ _dwarf_get_alloc(dbg, DW_DLA_LIST, fde_count);
446
+ }
447
+
448
+ /* It is ok if fde_list_ptr is NULL, we just have no fdes. */
449
+ cur_fde_ptr = head_fde_ptr;
450
+ for (i = 0; i < fde_count; i++) {
451
+ *(fde_list_ptr + i) = cur_fde_ptr;
452
+ cur_fde_ptr = cur_fde_ptr->fd_next;
453
+ }
454
+
455
+
456
+ /* Return arguments. */
457
+ *cie_data = cie_list_ptr;
458
+ *cie_element_count = cie_count;
459
+
460
+ *fde_data = fde_list_ptr;
461
+ *fde_element_count = fde_count;
462
+ if (use_gnu_cie_calc) {
463
+ dbg->de_fde_data_eh = fde_list_ptr;
464
+ dbg->de_fde_count_eh = fde_count;
465
+ dbg->de_cie_data_eh = cie_list_ptr;
466
+ dbg->de_cie_count_eh = cie_count;
467
+ } else {
468
+ dbg->de_fde_data = fde_list_ptr;
469
+ dbg->de_fde_count = fde_count;
470
+ dbg->de_cie_data = cie_list_ptr;
471
+ dbg->de_cie_count = cie_count;
472
+ }
473
+
474
+ /* Sort the list by the address so that dwarf_get_fde_at_pc() can
475
+ binary search this list. */
476
+ if (fde_count > 0) {
477
+ qsort((void *) fde_list_ptr, fde_count, sizeof(Dwarf_Ptr),
478
+ qsort_compare);
479
+ }
480
+
481
+ return (DW_DLV_OK);
482
+ }
483
+
484
+ /* Internal function, not called by consumer code.
485
+ 'prefix' has accumulated the info up thru the cie-id
486
+ and now we consume the rest and build a Dwarf_Cie_s structure.
487
+ */
488
+ int
489
+ dwarf_create_cie_from_after_start(Dwarf_Debug dbg,
490
+ struct cie_fde_prefix_s *prefix,
491
+ Dwarf_Small * section_pointer,
492
+ Dwarf_Small * frame_ptr,
493
+ Dwarf_Small * section_ptr_end,
494
+ Dwarf_Unsigned cie_count,
495
+ int use_gnu_cie_calc,
496
+ Dwarf_Cie * cie_ptr_out,
497
+ Dwarf_Error * error)
498
+ {
499
+ Dwarf_Cie new_cie = 0;
500
+
501
+ /* egcs-1.1.2 .eh_frame uses 0 as the distinguishing id. sgi uses
502
+ -1 (in .debug_frame). .eh_frame not quite identical to
503
+ .debug_frame */
504
+ /* We here default the address size as it is not present
505
+ in DWARF2 or DWARF3 cie data, below we set it right if
506
+ it is present. */
507
+ Dwarf_Half address_size = dbg->de_pointer_size;
508
+ Dwarf_Small eh_fde_encoding = 0;
509
+ Dwarf_Small *augmentation = 0;
510
+ Dwarf_Half segment_size = 0;
511
+ Dwarf_Sword data_alignment_factor = -1;
512
+ Dwarf_Word code_alignment_factor = 4;
513
+ Dwarf_Unsigned return_address_register = 31;
514
+ int local_length_size = 0;
515
+ Dwarf_Word leb128_length = 0;
516
+ Dwarf_Unsigned cie_aug_data_len = 0;
517
+ Dwarf_Small *cie_aug_data = 0;
518
+ Dwarf_Addr gnu_personality_handler_addr = 0;
519
+ unsigned char gnu_personality_handler_encoding = 0;
520
+ unsigned char gnu_lsda_encoding = 0;
521
+ unsigned char gnu_fde_begin_encoding = 0;
522
+ int res = 0;
523
+
524
+
525
+ enum Dwarf_augmentation_type augt = aug_unknown;
526
+
527
+
528
+ /* This is a CIE, Common Information Entry: See the dwarf spec,
529
+ section 6.4.1 */
530
+ Dwarf_Small version = *(Dwarf_Small *) frame_ptr;
531
+
532
+ frame_ptr++;
533
+ if (version != DW_CIE_VERSION && version != DW_CIE_VERSION3 &&
534
+ version != DW_CIE_VERSION4) {
535
+ _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD);
536
+ return (DW_DLV_ERROR);
537
+ }
538
+
539
+ augmentation = frame_ptr;
540
+
541
+ res = _dwarf_check_string_valid(dbg,section_pointer,
542
+ frame_ptr,section_ptr_end,error);
543
+ if (res != DW_DLV_OK) {
544
+ return res;
545
+ }
546
+ frame_ptr = frame_ptr + strlen((char *) frame_ptr) + 1;
547
+ augt = _dwarf_get_augmentation_type(dbg,
548
+ augmentation, use_gnu_cie_calc);
549
+ if (augt == aug_eh) {
550
+ /* REFERENCED *//* Not used in this instance */
551
+ Dwarf_Unsigned exception_table_addr;
552
+
553
+ /* this is per egcs-1.1.2 as on RH 6.0 */
554
+ READ_UNALIGNED(dbg, exception_table_addr,
555
+ Dwarf_Unsigned, frame_ptr, local_length_size);
556
+ frame_ptr += local_length_size;
557
+ }
558
+ {
559
+ Dwarf_Unsigned lreg = 0;
560
+ unsigned long size = 0;
561
+
562
+ if (version == DW_CIE_VERSION4) {
563
+ address_size = *((unsigned char *)frame_ptr);
564
+ if (address_size > sizeof(Dwarf_Addr)) {
565
+ _dwarf_error(dbg, error, DW_DLE_ADDRESS_SIZE_ERROR);
566
+ return (DW_DLV_ERROR);
567
+ }
568
+ ++frame_ptr;
569
+ segment_size = *((unsigned char *)frame_ptr);
570
+ ++frame_ptr;
571
+ if (segment_size > sizeof(Dwarf_Addr)) {
572
+ _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD);
573
+ return (DW_DLV_ERROR);
574
+ }
575
+ }
576
+
577
+ DECODE_LEB128_UWORD(frame_ptr, lreg);
578
+ code_alignment_factor = (Dwarf_Word) lreg;
579
+ data_alignment_factor =
580
+ (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr,
581
+ &leb128_length);
582
+ frame_ptr = frame_ptr + leb128_length;
583
+ return_address_register =
584
+ _dwarf_get_return_address_reg(frame_ptr, version, &size);
585
+ if (return_address_register > dbg->de_frame_reg_rules_entry_count) {
586
+ _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR);
587
+ return (DW_DLV_ERROR);
588
+ }
589
+ frame_ptr += size;
590
+ }
591
+ switch (augt) {
592
+ case aug_empty_string:
593
+ break;
594
+ case aug_irix_mti_v1:
595
+ break;
596
+ case aug_irix_exception_table:{
597
+ Dwarf_Unsigned lreg = 0;
598
+ Dwarf_Word length_of_augmented_fields;
599
+
600
+ /* Decode the length of augmented fields. */
601
+ DECODE_LEB128_UWORD(frame_ptr, lreg);
602
+ length_of_augmented_fields = (Dwarf_Word) lreg;
603
+ /* set the frame_ptr to point at the instruction start. */
604
+ frame_ptr += length_of_augmented_fields;
605
+ }
606
+ break;
607
+
608
+ case aug_eh:{
609
+ int err = 0;
610
+ unsigned long increment = 0;
611
+
612
+ if (!use_gnu_cie_calc) {
613
+ /* This should be impossible. */
614
+ _dwarf_error(dbg, error,DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
615
+ return DW_DLV_ERROR;
616
+ }
617
+
618
+ err = get_gcc_eh_augmentation(dbg, frame_ptr, &increment,
619
+ augt,
620
+ prefix->cf_section_ptr,
621
+ &eh_fde_encoding,
622
+ (char *) augmentation,error);
623
+ if (err == DW_DLV_ERROR) {
624
+ _dwarf_error(dbg, error,DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
625
+ return DW_DLV_ERROR;
626
+ }
627
+ frame_ptr += increment;
628
+ }
629
+ break;
630
+ case aug_gcc_eh_z:{
631
+ /* Here we have Augmentation Data Length (uleb128) followed
632
+ by Augmentation Data bytes. */
633
+ int res = DW_DLV_ERROR;
634
+ Dwarf_Unsigned adlen = 0;
635
+
636
+ DECODE_LEB128_UWORD(frame_ptr, adlen);
637
+ cie_aug_data_len = adlen;
638
+ cie_aug_data = frame_ptr;
639
+ res = gnu_aug_encodings(dbg,
640
+ (char *) augmentation,
641
+ cie_aug_data,
642
+ cie_aug_data_len,
643
+ address_size,
644
+ &gnu_personality_handler_encoding,
645
+ &gnu_lsda_encoding,
646
+ &gnu_fde_begin_encoding,
647
+ &gnu_personality_handler_addr,
648
+ error);
649
+ if (res != DW_DLV_OK) {
650
+ _dwarf_error(dbg, error,
651
+ DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
652
+ return res;
653
+ }
654
+ frame_ptr += adlen;
655
+ }
656
+ break;
657
+ case aug_armcc:
658
+ break;
659
+ default:{
660
+ /* We do not understand the augmentation string. No
661
+ assumption can be made about any fields other than what
662
+ we have already read. */
663
+ frame_ptr = prefix->cf_start_addr +
664
+ prefix->cf_length + prefix->cf_local_length_size
665
+ + prefix->cf_local_extension_size;
666
+ /* FIX -- What are the values of data_alignment_factor,
667
+ code_alignement_factor, return_address_register and
668
+ instruction start? They were clearly uninitalized in the
669
+ previous version and I am leaving them the same way. */
670
+ }
671
+ break;
672
+ } /* End switch on augmentation type. */
673
+
674
+ new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1);
675
+ if (new_cie == NULL) {
676
+ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
677
+ return (DW_DLV_ERROR);
678
+ }
679
+
680
+ new_cie->ci_cie_version_number = version;
681
+ new_cie->ci_initial_table = NULL;
682
+ new_cie->ci_length = (Dwarf_Word) prefix->cf_length;
683
+ new_cie->ci_length_size = prefix->cf_local_length_size;
684
+ new_cie->ci_extension_size = prefix->cf_local_extension_size;
685
+ new_cie->ci_augmentation = (char *) augmentation;
686
+
687
+ new_cie->ci_data_alignment_factor =
688
+ (Dwarf_Sbyte) data_alignment_factor;
689
+ new_cie->ci_code_alignment_factor =
690
+ (Dwarf_Small) code_alignment_factor;
691
+ new_cie->ci_return_address_register = return_address_register;
692
+ new_cie->ci_cie_start = prefix->cf_start_addr;
693
+ new_cie->ci_cie_instr_start = frame_ptr;
694
+ new_cie->ci_dbg = dbg;
695
+ new_cie->ci_augmentation_type = augt;
696
+ new_cie->ci_gnu_eh_augmentation_len = cie_aug_data_len;
697
+ new_cie->ci_gnu_eh_augmentation_bytes = cie_aug_data;
698
+ new_cie->ci_gnu_personality_handler_encoding =
699
+ gnu_personality_handler_encoding;
700
+ new_cie->ci_gnu_personality_handler_addr =
701
+ gnu_personality_handler_addr;
702
+ new_cie->ci_gnu_lsda_encoding = gnu_lsda_encoding;
703
+ new_cie->ci_gnu_fde_begin_encoding = gnu_fde_begin_encoding;
704
+
705
+ new_cie->ci_index = cie_count;
706
+ new_cie->ci_section_ptr = prefix->cf_section_ptr;
707
+ /* The Following new in DWARF4 */
708
+ new_cie->ci_address_size = address_size;
709
+ new_cie->ci_segment_size = segment_size;
710
+ validate_length(dbg,new_cie,new_cie->ci_length,
711
+ new_cie->ci_length_size, new_cie->ci_extension_size,
712
+ new_cie->ci_section_ptr,
713
+ new_cie->ci_cie_start,"cie");
714
+
715
+ *cie_ptr_out = new_cie;
716
+ return DW_DLV_OK;
717
+
718
+ }
719
+
720
+
721
+ /* Internal function, not called by consumer code.
722
+ 'prefix' has accumulated the info up thru the cie-id
723
+ and now we consume the rest and build a Dwarf_Fde_s structure. */
724
+
725
+ int
726
+ dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
727
+ struct cie_fde_prefix_s *prefix,
728
+ Dwarf_Small * section_pointer,
729
+ Dwarf_Small * frame_ptr,
730
+ Dwarf_Small * section_ptr_end,
731
+ int use_gnu_cie_calc,
732
+ Dwarf_Cie cie_ptr_in,
733
+ Dwarf_Fde * fde_ptr_out,
734
+ Dwarf_Error * error)
735
+ {
736
+ Dwarf_Fde new_fde = 0;
737
+ Dwarf_Cie cieptr = cie_ptr_in;
738
+ Dwarf_Small *saved_frame_ptr = 0;
739
+
740
+ Dwarf_Small *initloc = frame_ptr;
741
+ Dwarf_Signed offset_into_exception_tables
742
+ /* must be min dwarf_sfixed in size */
743
+ = (Dwarf_Signed) DW_DLX_NO_EH_OFFSET;
744
+ Dwarf_Small *fde_aug_data = 0;
745
+ Dwarf_Unsigned fde_aug_data_len = 0;
746
+ Dwarf_Addr cie_base_offset = prefix->cf_cie_id;
747
+ Dwarf_Addr initial_location = 0; /* must be min de_pointer_size
748
+ bytes in size */
749
+ Dwarf_Addr address_range = 0; /* must be min de_pointer_size
750
+ bytes in size */
751
+ Dwarf_Half address_size = cie_ptr_in->ci_address_size;
752
+
753
+ enum Dwarf_augmentation_type augt = cieptr->ci_augmentation_type;
754
+
755
+ if (augt == aug_gcc_eh_z) {
756
+ /* If z augmentation this is eh_frame, and initial_location and
757
+ address_range in the FDE are read according to the CIE
758
+ augmentation string instructions. */
759
+
760
+ {
761
+ Dwarf_Small *fp_updated = 0;
762
+ int res = read_encoded_ptr(dbg,
763
+ section_pointer,
764
+ frame_ptr,
765
+ cieptr-> ci_gnu_fde_begin_encoding,
766
+ address_size,
767
+ &initial_location,
768
+ &fp_updated,error);
769
+ if (res != DW_DLV_OK) {
770
+ return res;
771
+ }
772
+ frame_ptr = fp_updated;
773
+ /* For the address-range it makes no sense to be
774
+ pc-relative, so we turn it off with a section_pointer of
775
+ NULL. Masking off DW_EH_PE_pcrel from the
776
+ ci_gnu_fde_begin_encoding in this call would also work
777
+ to turn off DW_EH_PE_pcrel. */
778
+ res = read_encoded_ptr(dbg, (Dwarf_Small *) NULL,
779
+ frame_ptr,
780
+ cieptr->ci_gnu_fde_begin_encoding,
781
+ address_size,
782
+ &address_range, &fp_updated,error);
783
+ if (res != DW_DLV_OK) {
784
+ return res;
785
+ }
786
+ frame_ptr = fp_updated;
787
+ }
788
+ {
789
+ Dwarf_Unsigned adlen = 0;
790
+
791
+ DECODE_LEB128_UWORD(frame_ptr, adlen);
792
+ fde_aug_data_len = adlen;
793
+ fde_aug_data = frame_ptr;
794
+ frame_ptr += adlen;
795
+ }
796
+
797
+ } else {
798
+ READ_UNALIGNED(dbg, initial_location, Dwarf_Addr,
799
+ frame_ptr, address_size);
800
+ frame_ptr += address_size;
801
+ READ_UNALIGNED(dbg, address_range, Dwarf_Addr,
802
+ frame_ptr, address_size);
803
+ frame_ptr += address_size;
804
+ }
805
+ switch (augt) {
806
+ case aug_irix_mti_v1:
807
+ case aug_empty_string:
808
+ break;
809
+ case aug_irix_exception_table:{
810
+ Dwarf_Unsigned lreg = 0;
811
+ Dwarf_Word length_of_augmented_fields = 0;
812
+
813
+ DECODE_LEB128_UWORD(frame_ptr, lreg);
814
+ length_of_augmented_fields = (Dwarf_Word) lreg;
815
+
816
+ saved_frame_ptr = frame_ptr;
817
+ /* The first word is an offset into exception tables.
818
+ Defined as a 32bit offset even for CC -64. */
819
+ READ_UNALIGNED(dbg, offset_into_exception_tables,
820
+ Dwarf_Addr, frame_ptr, sizeof(Dwarf_sfixed));
821
+ SIGN_EXTEND(offset_into_exception_tables,
822
+ sizeof(Dwarf_sfixed));
823
+ frame_ptr = saved_frame_ptr + length_of_augmented_fields;
824
+ }
825
+ break;
826
+ case aug_eh:{
827
+ Dwarf_Unsigned eh_table_value = 0;
828
+
829
+ if (!use_gnu_cie_calc) {
830
+ /* This should be impossible. */
831
+ _dwarf_error(dbg, error,DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
832
+ return DW_DLV_ERROR;
833
+ }
834
+
835
+ /* gnu eh fde case. we do not need to do anything */
836
+ /*REFERENCED*/ /* Not used in this instance of the macro */
837
+ READ_UNALIGNED(dbg, eh_table_value,
838
+ Dwarf_Unsigned, frame_ptr,
839
+ address_size);
840
+ frame_ptr += address_size;
841
+ }
842
+ break;
843
+
844
+ case aug_gcc_eh_z:{
845
+ /* The Augmentation Data Length is here, followed by the
846
+ Augmentation Data bytes themselves. */
847
+ }
848
+ break;
849
+ case aug_armcc:
850
+ break;
851
+ case aug_past_last:
852
+ break;
853
+ case aug_unknown:
854
+ _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
855
+ return DW_DLV_ERROR;
856
+ } /* End switch on augmentation type */
857
+ new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1);
858
+ if (new_fde == NULL) {
859
+ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
860
+ return (DW_DLV_ERROR);
861
+ }
862
+
863
+ new_fde->fd_length = prefix->cf_length;
864
+ new_fde->fd_length_size = prefix->cf_local_length_size;
865
+ new_fde->fd_extension_size = prefix->cf_local_extension_size;
866
+ new_fde->fd_is_eh = use_gnu_cie_calc;
867
+ new_fde->fd_cie_offset = cie_base_offset;
868
+ new_fde->fd_cie_index = cieptr->ci_index;
869
+ new_fde->fd_cie = cieptr;
870
+ new_fde->fd_initial_location = initial_location;
871
+ new_fde->fd_initial_loc_pos = initloc;
872
+ new_fde->fd_address_range = address_range;
873
+ new_fde->fd_fde_start = prefix->cf_start_addr;
874
+ new_fde->fd_fde_instr_start = frame_ptr;
875
+ new_fde->fd_dbg = dbg;
876
+ new_fde->fd_offset_into_exception_tables =
877
+ offset_into_exception_tables;
878
+
879
+ new_fde->fd_section_ptr = prefix->cf_section_ptr;
880
+ new_fde->fd_section_index = prefix->cf_section_index;
881
+ new_fde->fd_section_length = prefix->cf_section_length;
882
+
883
+ new_fde->fd_gnu_eh_augmentation_bytes = fde_aug_data;
884
+ new_fde->fd_gnu_eh_augmentation_len = fde_aug_data_len;
885
+ validate_length(dbg,cieptr,new_fde->fd_length,
886
+ new_fde->fd_length_size, new_fde->fd_extension_size,
887
+ new_fde->fd_section_ptr,new_fde->fd_fde_start,"fde");
888
+
889
+
890
+ *fde_ptr_out = new_fde;
891
+ return DW_DLV_OK;
892
+ }
893
+
894
+ /* Called by qsort to compare FDE entries.
895
+ Consumer code expects the array of FDE pointers to be
896
+ in address order.
897
+ */
898
+ static int
899
+ qsort_compare(const void *elem1, const void *elem2)
900
+ {
901
+ const Dwarf_Fde fde1 = *(const Dwarf_Fde *) elem1;
902
+ const Dwarf_Fde fde2 = *(const Dwarf_Fde *) elem2;
903
+ Dwarf_Addr addr1 = fde1->fd_initial_location;
904
+ Dwarf_Addr addr2 = fde2->fd_initial_location;
905
+
906
+ if (addr1 < addr2) {
907
+ return -1;
908
+ } else if (addr1 > addr2) {
909
+ return 1;
910
+ }
911
+ return 0;
912
+ }
913
+
914
+
915
+ /* Read in the common cie/fde prefix, including reading
916
+ the cie-value which shows which this is: cie or fde. */
917
+ int
918
+ dwarf_read_cie_fde_prefix(Dwarf_Debug dbg,
919
+ Dwarf_Small * frame_ptr_in,
920
+ Dwarf_Small * section_ptr_in,
921
+ Dwarf_Unsigned section_index_in,
922
+ Dwarf_Unsigned section_length_in,
923
+ struct cie_fde_prefix_s *data_out,
924
+ Dwarf_Error * error)
925
+ {
926
+ Dwarf_Unsigned length = 0;
927
+ int local_length_size = 0;
928
+ int local_extension_size = 0;
929
+ Dwarf_Small *frame_ptr = frame_ptr_in;
930
+ Dwarf_Small *cie_ptr_addr = 0;
931
+ Dwarf_Unsigned cie_id = 0;
932
+
933
+ /* READ_AREA_LENGTH updates frame_ptr for consumed bytes */
934
+ READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
935
+ frame_ptr, local_length_size,
936
+ local_extension_size);
937
+
938
+ if (length == 0) {
939
+ /* nul bytes at end of section, seen at end of egcs eh_frame
940
+ sections (in a.out). Take this as meaning no more CIE/FDE
941
+ data. We should be very close to end of section. */
942
+ return DW_DLV_NO_ENTRY;
943
+ }
944
+
945
+ cie_ptr_addr = frame_ptr;
946
+ READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned,
947
+ frame_ptr, local_length_size);
948
+ SIGN_EXTEND(cie_id, local_length_size);
949
+ frame_ptr += local_length_size;
950
+
951
+ data_out->cf_start_addr = frame_ptr_in;
952
+ data_out->cf_addr_after_prefix = frame_ptr;
953
+
954
+ data_out->cf_length = length;
955
+ data_out->cf_local_length_size = local_length_size;
956
+ data_out->cf_local_extension_size = local_extension_size;
957
+ data_out->cf_cie_id = cie_id;
958
+ data_out->cf_cie_id_addr = cie_ptr_addr;
959
+ data_out->cf_section_ptr = section_ptr_in;
960
+ data_out->cf_section_index = section_index_in;
961
+ data_out->cf_section_length = section_length_in;
962
+ return DW_DLV_OK;
963
+ }
964
+
965
+ /* On various errors previously-allocated CIEs and FDEs
966
+ must be cleaned up.
967
+ This helps avoid leaks in case of errors.
968
+ */
969
+ static void
970
+ dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr,
971
+ Dwarf_Cie head_cie_ptr)
972
+ {
973
+ Dwarf_Fde curfde = 0;
974
+ Dwarf_Cie curcie = 0;
975
+ Dwarf_Fde nextfde = 0;
976
+ Dwarf_Cie nextcie = 0;
977
+
978
+ for (curfde = head_fde_ptr; curfde; curfde = nextfde) {
979
+ nextfde = curfde->fd_next;
980
+ dwarf_dealloc(curfde->fd_dbg, curfde, DW_DLA_FDE);
981
+ }
982
+ for (curcie = head_cie_ptr; curcie; curcie = nextcie) {
983
+ Dwarf_Frame frame = curcie->ci_initial_table;
984
+
985
+ nextcie = curcie->ci_next;
986
+ if (frame)
987
+ dwarf_dealloc(curcie->ci_dbg, frame, DW_DLA_FRAME);
988
+ dwarf_dealloc(curcie->ci_dbg, curcie, DW_DLA_CIE);
989
+ }
990
+ }
991
+
992
+ /* Find the cie whose id value is given: the id
993
+ value is, per DWARF2/3, an offset in the section.
994
+ For .debug_frame, zero is a legal offset. For
995
+ GNU .eh_frame it is not a legal offset.
996
+ 'cie_ptr' is a pointer into our section, not an offset. */
997
+ static int
998
+ dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr,
999
+ Dwarf_Cie cur_cie_ptr,
1000
+ Dwarf_Cie * cie_ptr_to_use_out,
1001
+ Dwarf_Cie head_cie_ptr)
1002
+ {
1003
+ Dwarf_Cie next = 0;
1004
+
1005
+ if (cur_cie_ptr && cie_ptr == cur_cie_ptr->ci_cie_start) {
1006
+ /* Usually, we use the same cie again and again. */
1007
+ *cie_ptr_to_use_out = cur_cie_ptr;
1008
+ return DW_DLV_OK;
1009
+ }
1010
+ for (next = head_cie_ptr; next; next = next->ci_next) {
1011
+ if (cie_ptr == next->ci_cie_start) {
1012
+ *cie_ptr_to_use_out = next;
1013
+ return DW_DLV_OK;
1014
+ }
1015
+ }
1016
+ return DW_DLV_NO_ENTRY;
1017
+ }
1018
+
1019
+
1020
+ /* We have a valid cie_ptr_val that has not been
1021
+ turned into an internal Cie yet. Do so now.
1022
+ Returns DW_DLV_OK or DW_DLV_ERROR, never
1023
+ DW_DLV_NO_ENTRY.
1024
+
1025
+ 'section_ptr' - Points to first byte of section data.
1026
+ 'section_length' - Length of the section, in bytes.
1027
+ 'section_ptr_end' - Points 1-past last byte of section data. */
1028
+ static int
1029
+ dwarf_create_cie_from_start(Dwarf_Debug dbg,
1030
+ Dwarf_Small * cie_ptr_val,
1031
+ Dwarf_Small * section_ptr,
1032
+ Dwarf_Unsigned section_index,
1033
+ Dwarf_Unsigned section_length,
1034
+ Dwarf_Small * section_ptr_end,
1035
+ Dwarf_Unsigned cie_id_value,
1036
+ Dwarf_Unsigned cie_count,
1037
+ int use_gnu_cie_calc,
1038
+ Dwarf_Cie * cie_ptr_to_use_out,
1039
+ Dwarf_Error * error)
1040
+ {
1041
+ struct cie_fde_prefix_s prefix;
1042
+ int res = DW_DLV_ERROR;
1043
+ Dwarf_Small *frame_ptr = cie_ptr_val;
1044
+
1045
+ if (frame_ptr < section_ptr || frame_ptr >= section_ptr_end) {
1046
+ _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
1047
+ return DW_DLV_ERROR;
1048
+ }
1049
+ /* First read in the 'common prefix' to figure out what * we are to
1050
+ do with this entry. If it is not a cie * we are in big trouble. */
1051
+ memset(&prefix, 0, sizeof(prefix));
1052
+ res = dwarf_read_cie_fde_prefix(dbg, frame_ptr, section_ptr,
1053
+ section_index, section_length,
1054
+ &prefix, error);
1055
+ if (res == DW_DLV_ERROR) {
1056
+ return res;
1057
+ }
1058
+ if (res == DW_DLV_NO_ENTRY) {
1059
+ /* error. */
1060
+ _dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR);
1061
+ return DW_DLV_ERROR;
1062
+
1063
+ }
1064
+
1065
+ if (prefix.cf_cie_id != cie_id_value) {
1066
+ _dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR);
1067
+ return DW_DLV_ERROR;
1068
+ }
1069
+ frame_ptr = prefix.cf_addr_after_prefix;
1070
+ res = dwarf_create_cie_from_after_start(dbg,
1071
+ &prefix,
1072
+ section_ptr,
1073
+ frame_ptr,
1074
+ section_ptr_end,
1075
+ cie_count,
1076
+ use_gnu_cie_calc,
1077
+ cie_ptr_to_use_out, error);
1078
+ return res;
1079
+
1080
+ }
1081
+
1082
+
1083
+ /* This is for gnu eh frames, the 'z' case.
1084
+ We find the letter involved
1085
+ Return the augmentation character and, if applicable,
1086
+ the personality routine address.
1087
+
1088
+ personality_routine_out -
1089
+ if 'P' is augchar, is personality handler addr.
1090
+ Otherwise is not set.
1091
+ aug_data - if 'P' points to data space of the
1092
+ aug_data_len - length of areas aug_data points to.
1093
+
1094
+ */
1095
+ #if 0 /* FOR DEBUGGING */
1096
+ /* For debugging only. */
1097
+ void
1098
+ dump_bytes(Dwarf_Small * start, long len)
1099
+ {
1100
+ Dwarf_Small *end = start + len;
1101
+ Dwarf_Small *cur = start;
1102
+
1103
+ for (; cur < end; cur++) {
1104
+ printf(" byte %d, data %02x\n", (int) (cur - start), *cur);
1105
+ }
1106
+
1107
+ }
1108
+ #endif
1109
+ static int
1110
+ gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation,
1111
+ Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len,
1112
+ Dwarf_Half address_size,
1113
+ unsigned char *pers_hand_enc_out,
1114
+ unsigned char *lsda_enc_out,
1115
+ unsigned char *fde_begin_enc_out,
1116
+ Dwarf_Addr * gnu_pers_addr_out,
1117
+ Dwarf_Error * error)
1118
+ {
1119
+ char *nc = 0;
1120
+ Dwarf_Small *cur_aug_p = aug_data;
1121
+ Dwarf_Small *end_aug_p = aug_data + aug_data_len;
1122
+
1123
+ for (nc = augmentation; *nc; ++nc) {
1124
+ char c = *nc;
1125
+
1126
+ switch (c) {
1127
+ case 'z':
1128
+ /* Means that the augmentation data is present. */
1129
+ continue;
1130
+
1131
+ case 'S':
1132
+ /* Indicates this is a signal stack frame.
1133
+ Debuggers have to do
1134
+ special handling. We don't need to do more than
1135
+ print this flag at the right time, though
1136
+ (see dwarfdump where it prints the augmentation
1137
+ string).
1138
+ A signal stack frame (in some OS's) can only be
1139
+ unwound (backtraced) by knowing it is a signal
1140
+ stack frame (perhaps by noticing the name of the
1141
+ function for the stack frame if the name can be
1142
+ found somehow) and figuring
1143
+ out (or knowing) how the kernel and libc
1144
+ pushed a structure
1145
+ onto the stack and loading registers from that structure.
1146
+ Totally different from normal stack unwinding.
1147
+ This flag gives an unwinder a big leg up by
1148
+ decoupling the 'hint: this is a stack frame'
1149
+ from knowledge like
1150
+ the function name (the name might be
1151
+ unavailable at unwind time).
1152
+ */
1153
+ break;
1154
+
1155
+ case 'L':
1156
+ if (cur_aug_p > end_aug_p) {
1157
+ _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1158
+ return DW_DLV_ERROR;
1159
+ }
1160
+ *lsda_enc_out = *(unsigned char *) cur_aug_p;
1161
+ ++cur_aug_p;
1162
+ break;
1163
+ case 'R':
1164
+ /* Followed by a one byte argument giving the
1165
+ pointer encoding for the address pointers in the fde. */
1166
+ if (cur_aug_p >= end_aug_p) {
1167
+ _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1168
+ return DW_DLV_ERROR;
1169
+ }
1170
+ *fde_begin_enc_out = *(unsigned char *) cur_aug_p;
1171
+ ++cur_aug_p;
1172
+ break;
1173
+ case 'P':{
1174
+ int res = DW_DLV_ERROR;
1175
+ Dwarf_Small *updated_aug_p = 0;
1176
+ unsigned char encoding = 0;
1177
+
1178
+ if (cur_aug_p >= end_aug_p) {
1179
+ _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1180
+ return DW_DLV_ERROR;
1181
+ }
1182
+ encoding = *(unsigned char *) cur_aug_p;
1183
+ *pers_hand_enc_out = encoding;
1184
+ ++cur_aug_p;
1185
+ if (cur_aug_p > end_aug_p) {
1186
+ _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1187
+ return DW_DLV_ERROR;
1188
+ }
1189
+ /* DW_EH_PE_pcrel makes no sense here, so we turn it
1190
+ off via a section pointer of NULL. */
1191
+ res = read_encoded_ptr(dbg,
1192
+ (Dwarf_Small *) NULL,
1193
+ cur_aug_p,
1194
+ encoding,
1195
+ address_size,
1196
+ gnu_pers_addr_out,
1197
+ &updated_aug_p,
1198
+ error);
1199
+ if (res != DW_DLV_OK) {
1200
+ return res;
1201
+ }
1202
+ cur_aug_p = updated_aug_p;
1203
+ if (cur_aug_p > end_aug_p) {
1204
+ _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1205
+ return DW_DLV_ERROR;
1206
+ }
1207
+ }
1208
+ break;
1209
+ default:
1210
+ _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1211
+ return DW_DLV_ERROR;
1212
+
1213
+ }
1214
+ }
1215
+ return DW_DLV_OK;
1216
+ }
1217
+
1218
+ /* Given augmentation character (the encoding) giving the
1219
+ address format, read the address from input_field
1220
+ and return an incremented value 1 past the input bytes of the
1221
+ address.
1222
+ Push the address read back thru the *addr pointer.
1223
+ See LSB (Linux Standard Base) exception handling documents. */
1224
+ static int
1225
+ read_encoded_ptr(Dwarf_Debug dbg,
1226
+ Dwarf_Small * section_pointer,
1227
+ Dwarf_Small * input_field,
1228
+ int gnu_encoding,
1229
+ Dwarf_Half address_size,
1230
+ Dwarf_Unsigned * addr,
1231
+ Dwarf_Small ** input_field_updated,
1232
+ Dwarf_Error *error)
1233
+ {
1234
+ Dwarf_Word length = 0;
1235
+ int value_type = gnu_encoding & 0xf;
1236
+ Dwarf_Small *input_field_original = input_field;
1237
+
1238
+ if (gnu_encoding == 0xff) {
1239
+ /* There is no data here. */
1240
+
1241
+ *addr = 0;
1242
+ *input_field_updated = input_field;
1243
+ /* Should we return DW_DLV_NO_ENTRY? */
1244
+ return DW_DLV_OK;
1245
+ }
1246
+ switch (value_type) {
1247
+ case DW_EH_PE_absptr:{
1248
+ /* value_type is zero. Treat as pointer size of the object.
1249
+ */
1250
+ Dwarf_Unsigned ret_value = 0;
1251
+
1252
+ READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
1253
+ input_field, address_size);
1254
+ *addr = ret_value;
1255
+ *input_field_updated = input_field + address_size;
1256
+ }
1257
+ break;
1258
+ case DW_EH_PE_uleb128:{
1259
+ Dwarf_Unsigned val = _dwarf_decode_u_leb128(input_field,
1260
+ &length);
1261
+
1262
+ *addr = val;
1263
+ *input_field_updated = input_field + length;
1264
+ }
1265
+ break;
1266
+ case DW_EH_PE_udata2:{
1267
+ Dwarf_Unsigned ret_value = 0;
1268
+
1269
+ READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
1270
+ input_field, 2);
1271
+ *addr = ret_value;
1272
+ *input_field_updated = input_field + 2;
1273
+ }
1274
+ break;
1275
+
1276
+ case DW_EH_PE_udata4:{
1277
+ Dwarf_Unsigned ret_value = 0;
1278
+
1279
+ /* ASSERT: sizeof(Dwarf_ufixed) == 4 */
1280
+ READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
1281
+ input_field, sizeof(Dwarf_ufixed));
1282
+ *addr = ret_value;
1283
+ *input_field_updated = input_field + sizeof(Dwarf_ufixed);
1284
+ }
1285
+ break;
1286
+
1287
+ case DW_EH_PE_udata8:{
1288
+ Dwarf_Unsigned ret_value = 0;
1289
+
1290
+ /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */
1291
+ READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
1292
+ input_field, sizeof(Dwarf_Unsigned));
1293
+ *addr = ret_value;
1294
+ *input_field_updated = input_field + sizeof(Dwarf_Unsigned);
1295
+ }
1296
+ break;
1297
+
1298
+ case DW_EH_PE_sleb128:{
1299
+ Dwarf_Signed val = _dwarf_decode_s_leb128(input_field,
1300
+ &length);
1301
+
1302
+ *addr = (Dwarf_Unsigned) val;
1303
+ *input_field_updated = input_field + length;
1304
+ }
1305
+ break;
1306
+ case DW_EH_PE_sdata2:{
1307
+ Dwarf_Unsigned val = 0;
1308
+
1309
+ READ_UNALIGNED(dbg, val, Dwarf_Unsigned, input_field, 2);
1310
+ SIGN_EXTEND(val, 2);
1311
+ *addr = (Dwarf_Unsigned) val;
1312
+ *input_field_updated = input_field + 2;
1313
+ }
1314
+ break;
1315
+
1316
+ case DW_EH_PE_sdata4:{
1317
+ Dwarf_Unsigned val = 0;
1318
+
1319
+ /* ASSERT: sizeof(Dwarf_ufixed) == 4 */
1320
+ READ_UNALIGNED(dbg, val,
1321
+ Dwarf_Unsigned, input_field,
1322
+ sizeof(Dwarf_ufixed));
1323
+ SIGN_EXTEND(val, sizeof(Dwarf_ufixed));
1324
+ *addr = (Dwarf_Unsigned) val;
1325
+ *input_field_updated = input_field + sizeof(Dwarf_ufixed);
1326
+ }
1327
+ break;
1328
+ case DW_EH_PE_sdata8:{
1329
+ Dwarf_Unsigned val = 0;
1330
+
1331
+ /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */
1332
+ READ_UNALIGNED(dbg, val,
1333
+ Dwarf_Unsigned, input_field,
1334
+ sizeof(Dwarf_Unsigned));
1335
+ *addr = (Dwarf_Unsigned) val;
1336
+ *input_field_updated = input_field + sizeof(Dwarf_Unsigned);
1337
+ }
1338
+ break;
1339
+ default:
1340
+ _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1341
+ return DW_DLV_ERROR;
1342
+
1343
+ };
1344
+ /* The ELF ABI for gnu does not document the meaning of
1345
+ DW_EH_PE_pcrel, which is awkward. It apparently means the value
1346
+ we got above is pc-relative (meaning section-relative), so we
1347
+ adjust the value. Section_pointer may be null if it is known
1348
+ DW_EH_PE_pcrel cannot apply, such as for .debug_frame or for an
1349
+ address-range value. */
1350
+ if (section_pointer && ((gnu_encoding & 0x70) == DW_EH_PE_pcrel)) {
1351
+ /* Address (*addr) above is pc relative with respect to a
1352
+ section. Add to the offset the base address (from elf) of
1353
+ section and the distance of the field we are reading from
1354
+ the section-beginning to get the actual address. */
1355
+ /* ASSERT: input_field_original >= section_pointer */
1356
+ Dwarf_Unsigned distance =
1357
+ input_field_original - section_pointer;
1358
+ *addr += dbg->de_debug_frame_eh_gnu.dss_addr + distance;
1359
+ }
1360
+ return DW_DLV_OK;
1361
+ }
1362
+
1363
+
1364
+
1365
+
1366
+ /* All augmentation string checking done here now.
1367
+
1368
+ For .eh_frame, gcc from 3.3 uses the z style, earlier used
1369
+ only "eh" as augmentation. We don't yet handle
1370
+ decoding .eh_frame with the z style extensions like L P.
1371
+
1372
+ These are nasty heuristics, but then that's life
1373
+ as augmentations are implementation specific. */
1374
+ /* ARGSUSED */
1375
+ enum Dwarf_augmentation_type
1376
+ _dwarf_get_augmentation_type(Dwarf_Debug dbg,
1377
+ Dwarf_Small * augmentation_string,
1378
+ int is_gcc_eh_frame)
1379
+ {
1380
+ enum Dwarf_augmentation_type t = aug_unknown;
1381
+ char *ag_string = (char *) augmentation_string;
1382
+
1383
+ if (ag_string[0] == 0) {
1384
+ /* Empty string. We'll just guess that we know what this means:
1385
+ standard dwarf2/3 with no implementation-defined fields. */
1386
+ t = aug_empty_string;
1387
+ } else if (strcmp(ag_string, DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) {
1388
+ /* The string is "mti v1". Used internally at SGI, probably
1389
+ never shipped. Replaced by "z". Treat like 'nothing
1390
+ special'. */
1391
+ t = aug_irix_mti_v1;
1392
+ } else if (ag_string[0] == 'z') {
1393
+ /* If it's IRIX cc, z means aug_irix_exception_table. z1 z2
1394
+ were designed as for IRIX CC, but never implemented */
1395
+ /* If it's gcc, z may be any of several things. "z" or z
1396
+ followed optionally followed by one or more of L R P, each
1397
+ of which means a value may be present. Should be in eh_frame
1398
+ only, I think. */
1399
+ if (is_gcc_eh_frame) {
1400
+ t = aug_gcc_eh_z;
1401
+ } else if (ag_string[1] == 0) {
1402
+ /* This is the normal IRIX C++ case, where there is an
1403
+ offset into a table in each fde. The table being for
1404
+ IRIX CC exception handling. */
1405
+ /* DW_CIE_AUGMENTER_STRING_V0 "z" */
1406
+ t = aug_irix_exception_table;
1407
+ } /* Else unknown. */
1408
+ } else if (strncmp(ag_string, "eh", 2) == 0) {
1409
+ /* gcc .eh_frame augmentation for egcs and gcc 2.x, at least
1410
+ for x86. */
1411
+ t = aug_eh;
1412
+ } else if (strcmp(ag_string, "armcc+") == 0) {
1413
+ /* Arm uses this string to mean a bug in
1414
+ in Arm compilers was fixed, changing to the standard
1415
+ calculation of the CFA. See
1416
+ http://sourceware.org/ml/gdb-patches/2006-12/msg00249.html
1417
+ for details. */
1418
+ t = aug_armcc;
1419
+ } else {
1420
+
1421
+ }
1422
+ return t;
1423
+ }
1424
+
1425
+ /* Using augmentation, and version
1426
+ read in the augmentation data for GNU eh.
1427
+
1428
+ Return DW_DLV_OK if we succeeded,
1429
+ DW_DLV_ERR if we fail.
1430
+
1431
+ On success, update 'size_of_augmentation_data' with
1432
+ the length of the fields that are part of augmentation (so the
1433
+ caller can increment frame_ptr appropriately).
1434
+
1435
+ 'frame_ptr' points within section.
1436
+ 'section_pointer' points to section base address in memory.
1437
+ */
1438
+ /* ARGSUSED */
1439
+ static int
1440
+ get_gcc_eh_augmentation(Dwarf_Debug dbg, Dwarf_Small * frame_ptr,
1441
+ unsigned long *size_of_augmentation_data,
1442
+ enum Dwarf_augmentation_type augtype,
1443
+ Dwarf_Small * section_pointer,
1444
+ Dwarf_Small * fde_eh_encoding_out,
1445
+ char *augmentation,
1446
+ Dwarf_Error *error)
1447
+ {
1448
+ char *suffix = 0;
1449
+ unsigned long augdata_size = 0;
1450
+
1451
+ if (augtype == aug_gcc_eh_z) {
1452
+ /* Has leading 'z'. */
1453
+ Dwarf_Word leb128_length = 0;
1454
+
1455
+ /* Dwarf_Unsigned eh_value = */
1456
+ _dwarf_decode_u_leb128(frame_ptr, &leb128_length);
1457
+ augdata_size += leb128_length;
1458
+ frame_ptr += leb128_length;
1459
+ suffix = augmentation + 1;
1460
+ } else {
1461
+ /* Prefix is 'eh'. As in gcc 3.2. No suffix present
1462
+ apparently. */
1463
+ suffix = augmentation + 2;
1464
+ }
1465
+ for (; *suffix; ++suffix) {
1466
+ /* We have no idea what this is as yet. Some extensions beyond
1467
+ dwarf exist which we do not yet handle. */
1468
+ _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1469
+ return DW_DLV_ERROR;
1470
+
1471
+ }
1472
+
1473
+ *size_of_augmentation_data = augdata_size;
1474
+ return DW_DLV_OK;
1475
+ }
1476
+
1477
+
1478
+ /* Make the 'cie_id_addr' consistent across .debug_frame and .eh_frame.
1479
+ Calculate a pointer into section bytes given a cie_id, which is
1480
+ trivial for .debug_frame, but a bit more work for .eh_frame.
1481
+ */
1482
+ static Dwarf_Small *
1483
+ get_cieptr_given_offset(Dwarf_Unsigned cie_id_value,
1484
+ int use_gnu_cie_calc,
1485
+ Dwarf_Small * section_ptr,
1486
+ Dwarf_Small * cie_id_addr)
1487
+ {
1488
+ Dwarf_Small *cieptr = 0;
1489
+
1490
+ if (use_gnu_cie_calc) {
1491
+ /* cie_id value is offset, in section, of the cie_id itself, to
1492
+ use vm ptr of the value, less the value, to get to the cie
1493
+ itself. In addition, munge *cie_id_addr to look *as if* it
1494
+ was from real dwarf. */
1495
+ cieptr = (Dwarf_Small *) ((Dwarf_Unsigned) cie_id_addr) -
1496
+ ((Dwarf_Unsigned) cie_id_value);
1497
+ } else {
1498
+ /* Traditional dwarf section offset is in cie_id */
1499
+ cieptr = (section_ptr + cie_id_value);
1500
+ }
1501
+ return cieptr;
1502
+ }
1503
+
1504
+ /* To properly release all spaced used.
1505
+ Earlier approaches (before July 15, 2005)
1506
+ letting client do the dealloc directly left
1507
+ some data allocated.
1508
+ This is directly called by consumer code.
1509
+ */
1510
+ void
1511
+ dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg,
1512
+ Dwarf_Cie * cie_data,
1513
+ Dwarf_Signed cie_element_count,
1514
+ Dwarf_Fde * fde_data,
1515
+ Dwarf_Signed fde_element_count)
1516
+ {
1517
+ Dwarf_Signed i = 0;
1518
+
1519
+ for (i = 0; i < cie_element_count; ++i) {
1520
+ Dwarf_Frame frame = cie_data[i]->ci_initial_table;
1521
+
1522
+ if (frame)
1523
+ dwarf_dealloc(dbg, frame, DW_DLA_FRAME);
1524
+ dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE);
1525
+ }
1526
+ for (i = 0; i < fde_element_count; ++i) {
1527
+ dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE);
1528
+ }
1529
+ if (cie_data)
1530
+ dwarf_dealloc(dbg, cie_data, DW_DLA_LIST);
1531
+ if (fde_data)
1532
+ dwarf_dealloc(dbg, fde_data, DW_DLA_LIST);
1533
+ }