rdwarf 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,2454 @@
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 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
+ #include "config.h"
30
+ #include "dwarf_incl.h"
31
+ #include <stdio.h>
32
+ #include <stdlib.h>
33
+ #include "dwarf_frame.h"
34
+ #include "dwarf_arange.h" /* Using Arange as a way to build a list */
35
+
36
+ #define FDE_NULL_CHECKS_AND_SET_DBG(fde,dbg ) \
37
+ do { \
38
+ if ((fde) == NULL) { \
39
+ _dwarf_error(NULL, error, DW_DLE_FDE_NULL);\
40
+ return (DW_DLV_ERROR); \
41
+ } \
42
+ (dbg)= (fde)->fd_dbg; \
43
+ if ((dbg) == NULL) { \
44
+ _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);\
45
+ return (DW_DLV_ERROR); \
46
+ } } while (0)
47
+
48
+
49
+ #define MIN(a,b) (((a) < (b))? a:b)
50
+
51
+ static int dwarf_initialize_fde_table(Dwarf_Debug dbg,
52
+ struct Dwarf_Frame_s *fde_table,
53
+ unsigned table_real_data_size,
54
+ Dwarf_Error * error);
55
+ static void dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table);
56
+ static void dwarf_init_reg_rules_ru(struct Dwarf_Reg_Rule_s *base,
57
+ unsigned first, unsigned last,int initial_value);
58
+ static void dwarf_init_reg_rules_dw(struct Dwarf_Regtable_Entry_s *base,
59
+ unsigned first, unsigned last,int initial_value);
60
+ static void dwarf_init_reg_rules_dw3(struct Dwarf_Regtable_Entry3_s *base,
61
+ unsigned first, unsigned last,int initial_value);
62
+
63
+
64
+ #if 0 /* FOR DEBUGGING */
65
+ /* Only used for debugging libdwarf. */
66
+ static void dump_frame_rule(char *msg,
67
+ struct Dwarf_Reg_Rule_s *reg_rule);
68
+ #endif
69
+
70
+
71
+
72
+ /*
73
+ This function is the heart of the debug_frame stuff. Don't even
74
+ think of reading this without reading both the Libdwarf and
75
+ consumer API carefully first. This function basically executes
76
+ frame instructions contained in a Cie or an Fde, but does in a
77
+ number of different ways depending on the information sought.
78
+ Start_instr_ptr points to the first byte of the frame instruction
79
+ stream, and final_instr_ptr to the to the first byte after the
80
+ last.
81
+
82
+ The offsets returned in the frame instructions are factored. That
83
+ is they need to be multiplied by either the code_alignment_factor
84
+ or the data_alignment_factor, as appropriate to obtain the actual
85
+ offset. This makes it possible to expand an instruction stream
86
+ without the corresponding Cie. However, when an Fde frame instr
87
+ sequence is being expanded there must be a valid Cie with a pointer
88
+ to an initial table row.
89
+
90
+
91
+ If successful, returns DW_DLV_OK
92
+ And sets returned_count thru the pointer
93
+ if make_instr is true.
94
+ If make_instr is false returned_count
95
+ should NOT be used by the caller (returned_count
96
+ is set to 0 thru the pointer by this routine...)
97
+ If unsuccessful, returns DW_DLV_ERROR
98
+ and sets returned_error to the error code
99
+
100
+ It does not do a whole lot of input validation being a private
101
+ function. Please make sure inputs are valid.
102
+
103
+ (1) If make_instr is true, it makes a list of pointers to
104
+ Dwarf_Frame_Op structures containing the frame instructions
105
+ executed. A pointer to this list is returned in ret_frame_instr.
106
+ Make_instr is true only when a list of frame instructions is to be
107
+ returned. In this case since we are not interested in the contents
108
+ of the table, the input Cie can be NULL. This is the only case
109
+ where the inpute Cie can be NULL.
110
+
111
+ (2) If search_pc is true, frame instructions are executed till
112
+ either a location is reached that is greater than the search_pc_val
113
+ provided, or all instructions are executed. At this point the
114
+ last row of the table generated is returned in a structure.
115
+ A pointer to this structure is supplied in table.
116
+
117
+ (3) This function is also used to create the initial table row
118
+ defined by a Cie. In this case, the Dwarf_Cie pointer cie, is
119
+ NULL. For an FDE, however, cie points to the associated Cie.
120
+
121
+ make_instr - make list of frame instr? 0/1
122
+ ret_frame_instr - Ptr to list of ptrs to frame instrs
123
+ search_pc - Search for a pc value? 0/1
124
+ search_pc_val - Search for this pc value
125
+ initial_loc - Initial code location value.
126
+ start_instr_ptr - Ptr to start of frame instrs.
127
+ final_instr_ptr - Ptr just past frame instrs.
128
+ table - Ptr to struct with last row.
129
+ cie - Ptr to Cie used by the Fde.
130
+
131
+ Different cies may have distinct address-sizes, so the cie
132
+ is used, not de_pointer_size.
133
+
134
+ */
135
+
136
+ int
137
+ _dwarf_exec_frame_instr(Dwarf_Bool make_instr,
138
+ Dwarf_Frame_Op ** ret_frame_instr,
139
+ Dwarf_Bool search_pc,
140
+ Dwarf_Addr search_pc_val,
141
+ Dwarf_Addr initial_loc,
142
+ Dwarf_Small * start_instr_ptr,
143
+ Dwarf_Small * final_instr_ptr,
144
+ Dwarf_Frame table,
145
+ Dwarf_Cie cie,
146
+ Dwarf_Debug dbg,
147
+ Dwarf_Half reg_num_of_cfa,
148
+ Dwarf_Sword * returned_count,
149
+ int *returned_error)
150
+ {
151
+ /* The following macro depends on macreg and
152
+ machigh_reg both being unsigned to avoid
153
+ unintended behavior and to avoid compiler warnings when
154
+ high warning levels are turned on. */
155
+ #define ERROR_IF_REG_NUM_TOO_HIGH(macreg,machigh_reg) \
156
+ do { \
157
+ if ((macreg) >= (machigh_reg)) { \
158
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH); \
159
+ } \
160
+ } /*CONSTCOND */ while (0)
161
+ #define SIMPLE_ERROR_RETURN(code) \
162
+ free(localregtab); \
163
+ *returned_error = code; \
164
+ return DW_DLV_ERROR
165
+
166
+ /* Sweeps the frame instructions. */
167
+ Dwarf_Small *instr_ptr;
168
+
169
+ /* Register numbers not limited to just 255, thus not using
170
+ Dwarf_Small. */
171
+ typedef unsigned reg_num_type;
172
+
173
+ Dwarf_Unsigned factored_N_value;
174
+ Dwarf_Signed signed_factored_N_value;
175
+ Dwarf_Addr current_loc = initial_loc; /* code location/
176
+ pc-value corresponding to the frame instructions.
177
+ Starts at zero when the caller has no value to pass in. */
178
+
179
+ /* Must be min de_pointer_size bytes and must be at least sizeof
180
+ Dwarf_ufixed */
181
+ Dwarf_Unsigned adv_loc = 0;
182
+
183
+ unsigned reg_count = dbg->de_frame_reg_rules_entry_count;
184
+ struct Dwarf_Reg_Rule_s *localregtab = calloc(reg_count,
185
+ sizeof(struct Dwarf_Reg_Rule_s));
186
+
187
+ struct Dwarf_Reg_Rule_s cfa_reg;
188
+
189
+
190
+ /* This is used to end executing frame instructions. */
191
+ /* Becomes true when search_pc is true and current_loc */
192
+ /* is greater than search_pc_val. */
193
+ Dwarf_Bool search_over = false;
194
+
195
+ /* Used by the DW_FRAME_advance_loc instr */
196
+ /* to hold the increment in pc value. */
197
+ Dwarf_Addr adv_pc;
198
+
199
+ /* Contains the length in bytes of */
200
+ /* an leb128 encoded number. */
201
+ Dwarf_Word leb128_length;
202
+
203
+ Dwarf_Half address_size = (cie)? cie->ci_address_size:
204
+ dbg->de_pointer_size;
205
+
206
+ /* Counts the number of frame instructions executed. */
207
+ Dwarf_Word instr_count = 0;
208
+
209
+ /* These contain the current fields of the current frame
210
+ instruction. */
211
+ Dwarf_Small fp_base_op = 0;
212
+ Dwarf_Small fp_extended_op;
213
+ reg_num_type fp_register;
214
+
215
+ /* The value in fp_offset may be signed, though we call it
216
+ unsigned. This works ok for 2-s complement arithmetic. */
217
+ Dwarf_Unsigned fp_offset;
218
+ Dwarf_Off fp_instr_offset;
219
+
220
+ /* Stack_table points to the row (Dwarf_Frame ie) being pushed or
221
+ popped by a remember or restore instruction. Top_stack points to
222
+ the top of the stack of rows. */
223
+ Dwarf_Frame stack_table = NULL;
224
+ Dwarf_Frame top_stack = NULL;
225
+
226
+ /* These are used only when make_instr is true. Curr_instr is a
227
+ pointer to the current frame instruction executed.
228
+ Curr_instr_ptr, head_instr_list, and curr_instr_list are used to
229
+ form a chain of Dwarf_Frame_Op structs. Dealloc_instr_ptr is
230
+ used to deallocate the structs used to form the chain.
231
+ Head_instr_block points to a contiguous list of pointers to the
232
+ Dwarf_Frame_Op structs executed. */
233
+ Dwarf_Frame_Op *curr_instr;
234
+ Dwarf_Chain curr_instr_item, dealloc_instr_item;
235
+ Dwarf_Chain head_instr_chain = NULL;
236
+ Dwarf_Chain tail_instr_chain = NULL;
237
+ Dwarf_Frame_Op *head_instr_block;
238
+
239
+ /* These are the alignment_factors taken from the Cie provided.
240
+ When no input Cie is provided they are set to 1, because only
241
+ factored offsets are required. */
242
+ Dwarf_Sword code_alignment_factor = 1;
243
+ Dwarf_Sword data_alignment_factor = 1;
244
+
245
+ /* This flag indicates when an actual alignment factor is needed.
246
+ So if a frame instruction that computes an offset using an
247
+ alignment factor is encountered when this flag is set, an error
248
+ is returned because the Cie did not have a valid augmentation. */
249
+ Dwarf_Bool need_augmentation = false;
250
+
251
+ Dwarf_Word i;
252
+
253
+ /* Initialize first row from associated Cie. Using temp regs
254
+ explicity */
255
+
256
+ if (localregtab == 0) {
257
+ SIMPLE_ERROR_RETURN(DW_DLE_ALLOC_FAIL);
258
+ }
259
+ {
260
+ struct Dwarf_Reg_Rule_s *t1reg = localregtab;
261
+ if (cie != NULL && cie->ci_initial_table != NULL) {
262
+ unsigned minregcount = 0;
263
+ unsigned curreg = 0;
264
+ struct Dwarf_Reg_Rule_s *t2reg = cie->ci_initial_table->fr_reg;
265
+
266
+ if (reg_count != cie->ci_initial_table->fr_reg_count) {
267
+ /* Should never happen, it makes no sense to have the
268
+ table sizes change. There is no real allowance for
269
+ the set of registers to change dynamically in a
270
+ single Dwarf_Debug (except the size can be set near
271
+ initial Dwarf_Debug creation time). */
272
+ SIMPLE_ERROR_RETURN
273
+ (DW_DLE_FRAME_REGISTER_COUNT_MISMATCH);
274
+ }
275
+ minregcount = MIN(reg_count,cie->ci_initial_table->fr_reg_count);
276
+ for (; curreg < minregcount ;curreg++, t1reg++, t2reg++) {
277
+ *t1reg = *t2reg;
278
+ }
279
+ cfa_reg = cie->ci_initial_table->fr_cfa_rule;
280
+ } else {
281
+ dwarf_init_reg_rules_ru(localregtab,0,reg_count,
282
+ dbg->de_frame_rule_initial_value);
283
+ dwarf_init_reg_rules_ru(&cfa_reg,0, 1,
284
+ dbg->de_frame_rule_initial_value);
285
+ }
286
+ }
287
+
288
+ /* The idea here is that the code_alignment_factor and
289
+ data_alignment_factor which are needed for certain instructions
290
+ are valid only when the Cie has a proper augmentation string. So
291
+ if the augmentation is not right, only Frame instruction can be
292
+ read. */
293
+ if (cie != NULL && cie->ci_augmentation != NULL) {
294
+ code_alignment_factor = cie->ci_code_alignment_factor;
295
+ data_alignment_factor = cie->ci_data_alignment_factor;
296
+ } else {
297
+ need_augmentation = !make_instr;
298
+ }
299
+
300
+ instr_ptr = start_instr_ptr;
301
+ while ((instr_ptr < final_instr_ptr) && (!search_over)) {
302
+ Dwarf_Small instr = 0;
303
+ Dwarf_Small opcode = 0;
304
+ reg_num_type reg_no = 0;
305
+
306
+ fp_instr_offset = instr_ptr - start_instr_ptr;
307
+ instr = *(Dwarf_Small *) instr_ptr;
308
+ instr_ptr += sizeof(Dwarf_Small);
309
+
310
+ fp_base_op = (instr & 0xc0) >> 6;
311
+ if ((instr & 0xc0) == 0x00) {
312
+ opcode = instr; /* is really extended op */
313
+ fp_extended_op = (instr & (~(0xc0))) & 0xff;
314
+ } else {
315
+ opcode = instr & 0xc0; /* is base op */
316
+ fp_extended_op = 0;
317
+ }
318
+
319
+ fp_register = 0;
320
+ fp_offset = 0;
321
+ switch (opcode) {
322
+ case DW_CFA_advance_loc:
323
+ {
324
+ /* base op */
325
+ fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK;
326
+
327
+ if (need_augmentation) {
328
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
329
+ }
330
+ adv_pc = adv_pc * code_alignment_factor;
331
+
332
+ search_over = search_pc &&
333
+ (current_loc + adv_pc > search_pc_val);
334
+ /* If gone past pc needed, retain old pc. */
335
+ if (!search_over) {
336
+ current_loc = current_loc + adv_pc;
337
+ }
338
+ break;
339
+ }
340
+
341
+ case DW_CFA_offset:
342
+ { /* base op */
343
+ reg_no =
344
+ (reg_num_type) (instr & DW_FRAME_INSTR_OFFSET_MASK);
345
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
346
+
347
+ factored_N_value =
348
+ _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
349
+ instr_ptr = instr_ptr + leb128_length;
350
+
351
+ fp_register = reg_no;
352
+ fp_offset = factored_N_value;
353
+
354
+ if (need_augmentation) {
355
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
356
+ }
357
+
358
+ localregtab[reg_no].ru_is_off = 1;
359
+ localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
360
+ localregtab[reg_no].ru_register = reg_num_of_cfa;
361
+ localregtab[reg_no].ru_offset_or_block_len =
362
+ factored_N_value * data_alignment_factor;
363
+
364
+ break;
365
+ }
366
+
367
+ case DW_CFA_restore:
368
+ { /* base op */
369
+ reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK);
370
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
371
+
372
+ fp_register = reg_no;
373
+
374
+ if (cie != NULL && cie->ci_initial_table != NULL)
375
+ localregtab[reg_no] =
376
+ cie->ci_initial_table->fr_reg[reg_no];
377
+ else if (!make_instr) {
378
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_MAKE_INSTR_NO_INIT);
379
+ }
380
+
381
+ break;
382
+ }
383
+ case DW_CFA_set_loc:
384
+ {
385
+ Dwarf_Addr new_loc = 0;
386
+
387
+ READ_UNALIGNED(dbg, new_loc, Dwarf_Addr,
388
+ instr_ptr, address_size);
389
+ instr_ptr += address_size;
390
+ if (new_loc != 0 && current_loc != 0) {
391
+ /* Pre-relocation or before current_loc is set the
392
+ test comparing new_loc and current_loc makes no
393
+ sense. Testing for non-zero (above) is a way
394
+ (fallible) to check that current_loc, new_loc
395
+ are already relocated. */
396
+ if (new_loc <= current_loc) {
397
+ /* Within a frame, address must increase.
398
+ Seemingly it has not. Seems to be an error. */
399
+
400
+ SIMPLE_ERROR_RETURN
401
+ (DW_DLE_DF_NEW_LOC_LESS_OLD_LOC);
402
+ }
403
+ }
404
+
405
+ search_over = search_pc && (new_loc > search_pc_val);
406
+
407
+ /* If gone past pc needed, retain old pc. */
408
+ if (!search_over) {
409
+ current_loc = new_loc;
410
+ }
411
+ fp_offset = new_loc;
412
+ break;
413
+ }
414
+
415
+ case DW_CFA_advance_loc1:
416
+ {
417
+ fp_offset = adv_loc = *(Dwarf_Small *) instr_ptr;
418
+ instr_ptr += sizeof(Dwarf_Small);
419
+
420
+ if (need_augmentation) {
421
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
422
+ }
423
+ adv_loc *= code_alignment_factor;
424
+
425
+ search_over = search_pc &&
426
+ (current_loc + adv_loc > search_pc_val);
427
+
428
+ /* If gone past pc needed, retain old pc. */
429
+ if (!search_over) {
430
+ current_loc = current_loc + adv_loc;
431
+ }
432
+ break;
433
+ }
434
+
435
+ case DW_CFA_advance_loc2:
436
+ {
437
+ READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
438
+ instr_ptr, sizeof(Dwarf_Half));
439
+ instr_ptr += sizeof(Dwarf_Half);
440
+ fp_offset = adv_loc;
441
+
442
+ if (need_augmentation) {
443
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
444
+ }
445
+ adv_loc *= code_alignment_factor;
446
+
447
+ search_over = search_pc &&
448
+ (current_loc + adv_loc > search_pc_val);
449
+
450
+ /* If gone past pc needed, retain old pc. */
451
+ if (!search_over) {
452
+ current_loc = current_loc + adv_loc;
453
+ }
454
+ break;
455
+ }
456
+
457
+ case DW_CFA_advance_loc4:
458
+ {
459
+ READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
460
+ instr_ptr, sizeof(Dwarf_ufixed));
461
+ instr_ptr += sizeof(Dwarf_ufixed);
462
+ fp_offset = adv_loc;
463
+
464
+ if (need_augmentation) {
465
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
466
+ }
467
+ adv_loc *= code_alignment_factor;
468
+
469
+ search_over = search_pc &&
470
+ (current_loc + adv_loc > search_pc_val);
471
+
472
+ /* If gone past pc needed, retain old pc. */
473
+ if (!search_over) {
474
+ current_loc = current_loc + adv_loc;
475
+ }
476
+ break;
477
+ }
478
+
479
+ case DW_CFA_offset_extended:
480
+ {
481
+ Dwarf_Unsigned lreg;
482
+
483
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
484
+ reg_no = (reg_num_type) lreg;
485
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);;
486
+ factored_N_value =
487
+ _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
488
+ instr_ptr += leb128_length;
489
+
490
+ if (need_augmentation) {
491
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
492
+ }
493
+ localregtab[reg_no].ru_is_off = 1;
494
+ localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
495
+ localregtab[reg_no].ru_register = reg_num_of_cfa;
496
+ localregtab[reg_no].ru_offset_or_block_len = factored_N_value *
497
+ data_alignment_factor;
498
+
499
+ fp_register = reg_no;
500
+ fp_offset = factored_N_value;
501
+ break;
502
+ }
503
+
504
+ case DW_CFA_restore_extended:
505
+ {
506
+ Dwarf_Unsigned lreg;
507
+
508
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
509
+ reg_no = (reg_num_type) lreg;
510
+
511
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
512
+
513
+ if (cie != NULL && cie->ci_initial_table != NULL) {
514
+ localregtab[reg_no] = cie->ci_initial_table->fr_reg[reg_no];
515
+ } else {
516
+ if (!make_instr) {
517
+ SIMPLE_ERROR_RETURN
518
+ (DW_DLE_DF_MAKE_INSTR_NO_INIT);
519
+ }
520
+ }
521
+
522
+ fp_register = reg_no;
523
+ break;
524
+ }
525
+
526
+ case DW_CFA_undefined:
527
+ {
528
+ Dwarf_Unsigned lreg;
529
+
530
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
531
+ reg_no = (reg_num_type) lreg;
532
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
533
+
534
+ localregtab[reg_no].ru_is_off = 0;
535
+ localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
536
+ localregtab[reg_no].ru_register =
537
+ dbg->de_frame_undefined_value_number;
538
+ localregtab[reg_no].ru_offset_or_block_len = 0;
539
+
540
+ fp_register = reg_no;
541
+ break;
542
+ }
543
+
544
+ case DW_CFA_same_value:
545
+ {
546
+ Dwarf_Unsigned lreg;
547
+
548
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
549
+ reg_no = (reg_num_type) lreg;
550
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
551
+
552
+ localregtab[reg_no].ru_is_off = 0;
553
+ localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
554
+ localregtab[reg_no].ru_register =
555
+ dbg->de_frame_same_value_number;
556
+ localregtab[reg_no].ru_offset_or_block_len = 0;
557
+ fp_register = reg_no;
558
+ break;
559
+ }
560
+
561
+ case DW_CFA_register:
562
+ {
563
+ Dwarf_Unsigned lreg;
564
+ reg_num_type reg_noA = 0;
565
+ reg_num_type reg_noB = 0;
566
+
567
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
568
+ reg_noA = (reg_num_type) lreg;
569
+
570
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_noA, reg_count);
571
+
572
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
573
+ reg_noB = (reg_num_type) lreg;
574
+
575
+ if (reg_noB > reg_count) {
576
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH);
577
+ }
578
+
579
+
580
+ localregtab[reg_noA].ru_is_off = 0;
581
+ localregtab[reg_noA].ru_value_type = DW_EXPR_OFFSET;
582
+ localregtab[reg_noA].ru_register = reg_noB;
583
+ localregtab[reg_noA].ru_offset_or_block_len = 0;
584
+
585
+ fp_register = reg_noA;
586
+ fp_offset = reg_noB;
587
+ break;
588
+ }
589
+
590
+ case DW_CFA_remember_state:
591
+ {
592
+ stack_table = (Dwarf_Frame)
593
+ _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
594
+ if (stack_table == NULL) {
595
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
596
+ }
597
+
598
+ for (i = 0; i < reg_count; i++)
599
+ stack_table->fr_reg[i] = localregtab[i];
600
+ stack_table->fr_cfa_rule = cfa_reg;
601
+
602
+ if (top_stack != NULL)
603
+ stack_table->fr_next = top_stack;
604
+ top_stack = stack_table;
605
+
606
+ break;
607
+ }
608
+
609
+ case DW_CFA_restore_state:
610
+ {
611
+ if (top_stack == NULL) {
612
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_POP_EMPTY_STACK);
613
+ }
614
+ stack_table = top_stack;
615
+ top_stack = stack_table->fr_next;
616
+
617
+ for (i = 0; i < reg_count; i++)
618
+ localregtab[i] = stack_table->fr_reg[i];
619
+ cfa_reg = stack_table->fr_cfa_rule;
620
+
621
+ dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
622
+ break;
623
+ }
624
+
625
+ case DW_CFA_def_cfa:
626
+ {
627
+ Dwarf_Unsigned lreg;
628
+
629
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
630
+ reg_no = (reg_num_type) lreg;
631
+
632
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
633
+
634
+ factored_N_value =
635
+ _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
636
+ instr_ptr += leb128_length;
637
+
638
+ if (need_augmentation) {
639
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
640
+ }
641
+ cfa_reg.ru_is_off = 1;
642
+ cfa_reg.ru_value_type = DW_EXPR_OFFSET;
643
+ cfa_reg.ru_register = reg_no;
644
+ cfa_reg.ru_offset_or_block_len = factored_N_value;
645
+
646
+ fp_register = reg_no;
647
+ fp_offset = factored_N_value;
648
+ break;
649
+ }
650
+
651
+ case DW_CFA_def_cfa_register:
652
+ {
653
+ Dwarf_Unsigned lreg;
654
+
655
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
656
+ reg_no = (reg_num_type) lreg;
657
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
658
+
659
+ cfa_reg.ru_register = reg_no;
660
+ /* Do NOT set ru_offset_or_block_len or ru_is_off here.
661
+ See dwarf2/3 spec. */
662
+ fp_register = reg_no;
663
+ break;
664
+ }
665
+
666
+ case DW_CFA_def_cfa_offset:
667
+ {
668
+ factored_N_value =
669
+ _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
670
+ instr_ptr += leb128_length;
671
+
672
+ if (need_augmentation) {
673
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
674
+ }
675
+ /* Do set ru_is_off here, as here factored_N_value
676
+ counts. */
677
+ cfa_reg.ru_is_off = 1;
678
+ cfa_reg.ru_value_type = DW_EXPR_OFFSET;
679
+ cfa_reg.ru_offset_or_block_len = factored_N_value;
680
+
681
+ fp_offset = factored_N_value;
682
+ break;
683
+ }
684
+ case DW_CFA_nop:
685
+ {
686
+ break;
687
+ }
688
+ /* DWARF3 ops begin here. */
689
+ case DW_CFA_def_cfa_expression:
690
+ {
691
+ /* A single DW_FORM_block representing a dwarf
692
+ expression. The form block establishes the way to
693
+ compute the CFA. */
694
+ Dwarf_Unsigned block_len = 0;
695
+
696
+ DECODE_LEB128_UWORD(instr_ptr, block_len);
697
+ cfa_reg.ru_is_off = 0; /* arbitrary */
698
+ cfa_reg.ru_value_type = DW_EXPR_EXPRESSION;
699
+ cfa_reg.ru_offset_or_block_len = block_len;
700
+ cfa_reg.ru_block = instr_ptr;
701
+ fp_offset = (Dwarf_Unsigned) instr_ptr;
702
+ instr_ptr += block_len;
703
+ }
704
+ break;
705
+ case DW_CFA_expression:
706
+ {
707
+ /* An unsigned leb128 value is the first operand (a
708
+ register number). The second operand is single
709
+ DW_FORM_block representing a dwarf expression. The
710
+ evaluator pushes the CFA on the evaluation stack
711
+ then evaluates the expression to compute the value
712
+ of the register contents. */
713
+ Dwarf_Unsigned lreg = 0;
714
+ Dwarf_Unsigned block_len = 0;
715
+
716
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
717
+ reg_no = (reg_num_type) lreg;
718
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
719
+ DECODE_LEB128_UWORD(instr_ptr, block_len);
720
+ localregtab[lreg].ru_is_off = 0; /* arbitrary */
721
+ localregtab[lreg].ru_value_type = DW_EXPR_EXPRESSION;
722
+ localregtab[lreg].ru_offset_or_block_len = block_len;
723
+ localregtab[lreg].ru_block = instr_ptr;
724
+ fp_offset = (Dwarf_Unsigned) instr_ptr;
725
+ fp_register = reg_no;
726
+ instr_ptr += block_len;
727
+ }
728
+ break;
729
+ case DW_CFA_offset_extended_sf:
730
+ {
731
+ /* The first operand is an unsigned leb128 register
732
+ number. The second is a signed factored offset.
733
+ Identical to DW_CFA_offset_extended except the
734
+ second operand is signed */
735
+ Dwarf_Unsigned lreg;
736
+
737
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
738
+ reg_no = (reg_num_type) lreg;
739
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
740
+ signed_factored_N_value =
741
+ _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
742
+ instr_ptr += leb128_length;
743
+
744
+ if (need_augmentation) {
745
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
746
+ }
747
+ localregtab[reg_no].ru_is_off = 1;
748
+ localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
749
+ localregtab[reg_no].ru_register = reg_num_of_cfa;
750
+ localregtab[reg_no].ru_offset_or_block_len =
751
+ signed_factored_N_value * data_alignment_factor;
752
+
753
+ fp_register = reg_no;
754
+ fp_offset = signed_factored_N_value;
755
+ }
756
+ break;
757
+ case DW_CFA_def_cfa_sf:
758
+ {
759
+ /* The first operand is an unsigned leb128 register
760
+ number. The second is a signed leb128 factored
761
+ offset. Identical to DW_CFA_def_cfa except that the
762
+ second operand is signed and factored. */
763
+ Dwarf_Unsigned lreg;
764
+
765
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
766
+ reg_no = (reg_num_type) lreg;
767
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
768
+
769
+ signed_factored_N_value =
770
+ _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
771
+ instr_ptr += leb128_length;
772
+
773
+ if (need_augmentation) {
774
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
775
+ }
776
+ cfa_reg.ru_is_off = 1;
777
+ cfa_reg.ru_value_type = DW_EXPR_OFFSET;
778
+ cfa_reg.ru_register = reg_no;
779
+ cfa_reg.ru_offset_or_block_len =
780
+ signed_factored_N_value * data_alignment_factor;
781
+
782
+ fp_register = reg_no;
783
+ fp_offset = signed_factored_N_value;
784
+ }
785
+ break;
786
+ case DW_CFA_def_cfa_offset_sf:
787
+ {
788
+ /* The operand is a signed leb128 operand representing
789
+ a factored offset. Identical to
790
+ DW_CFA_def_cfa_offset excep the operand is signed
791
+ and factored. */
792
+
793
+ signed_factored_N_value =
794
+ _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
795
+ instr_ptr += leb128_length;
796
+
797
+ if (need_augmentation) {
798
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
799
+ }
800
+ /* Do set ru_is_off here, as here factored_N_value
801
+ counts. */
802
+ cfa_reg.ru_is_off = 1;
803
+ cfa_reg.ru_value_type = DW_EXPR_OFFSET;
804
+ cfa_reg.ru_offset_or_block_len =
805
+ signed_factored_N_value * data_alignment_factor;
806
+
807
+ fp_offset = signed_factored_N_value;
808
+ }
809
+ break;
810
+ case DW_CFA_val_offset:
811
+ {
812
+ /* The first operand is an unsigned leb128 register
813
+ number. The second is a factored unsigned offset.
814
+ Makes the register be a val_offset(N) rule with N =
815
+ factored_offset*data_alignment_factor. */
816
+
817
+ Dwarf_Unsigned lreg;
818
+
819
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
820
+ reg_no = (reg_num_type) lreg;
821
+
822
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
823
+
824
+ factored_N_value =
825
+ _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
826
+ instr_ptr += leb128_length;
827
+
828
+ if (need_augmentation) {
829
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
830
+ }
831
+ /* Do set ru_is_off here, as here factored_N_value
832
+ counts. */
833
+ localregtab[reg_no].ru_is_off = 1;
834
+ localregtab[reg_no].ru_register = reg_num_of_cfa;
835
+ localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
836
+ localregtab[reg_no].ru_offset_or_block_len =
837
+ factored_N_value * data_alignment_factor;
838
+
839
+ fp_offset = factored_N_value;
840
+ break;
841
+ }
842
+ case DW_CFA_val_offset_sf:
843
+ {
844
+ /* The first operand is an unsigned leb128 register
845
+ number. The second is a factored signed offset.
846
+ Makes the register be a val_offset(N) rule with N =
847
+ factored_offset*data_alignment_factor. */
848
+ Dwarf_Unsigned lreg;
849
+
850
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
851
+ reg_no = (reg_num_type) lreg;
852
+
853
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
854
+ signed_factored_N_value =
855
+ _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
856
+ instr_ptr += leb128_length;
857
+
858
+ if (need_augmentation) {
859
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
860
+ }
861
+ /* Do set ru_is_off here, as here factored_N_value
862
+ counts. */
863
+ localregtab[reg_no].ru_is_off = 1;
864
+ localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
865
+ localregtab[reg_no].ru_offset_or_block_len =
866
+ signed_factored_N_value * data_alignment_factor;
867
+
868
+ fp_offset = signed_factored_N_value;
869
+
870
+ }
871
+ break;
872
+ case DW_CFA_val_expression:
873
+ {
874
+ /* The first operand is an unsigned leb128 register
875
+ number. The second is a DW_FORM_block representing a
876
+ DWARF expression. The rule for the register number
877
+ becomes a val_expression(E) rule. */
878
+ Dwarf_Unsigned lreg = 0;
879
+ Dwarf_Unsigned block_len = 0;
880
+
881
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
882
+ reg_no = (reg_num_type) lreg;
883
+ ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
884
+ DECODE_LEB128_UWORD(instr_ptr, block_len);
885
+ localregtab[lreg].ru_is_off = 0; /* arbitrary */
886
+ localregtab[lreg].ru_value_type = DW_EXPR_VAL_EXPRESSION;
887
+ localregtab[lreg].ru_offset_or_block_len = block_len;
888
+ localregtab[lreg].ru_block = instr_ptr;
889
+ fp_offset = (Dwarf_Unsigned) instr_ptr;
890
+
891
+ instr_ptr += block_len;
892
+ fp_register = reg_no;
893
+
894
+ }
895
+ break;
896
+
897
+ /* END DWARF3 new ops. */
898
+
899
+
900
+ #ifdef DW_CFA_GNU_window_save
901
+ case DW_CFA_GNU_window_save:
902
+ {
903
+ /* No information: this just tells unwinder to restore
904
+ the window registers from the previous frame's
905
+ window save area */
906
+ break;
907
+ }
908
+ #endif
909
+ #ifdef DW_CFA_GNU_args_size
910
+ /* Single uleb128 is the current arg area size in bytes. No
911
+ register exists yet to save this in */
912
+ case DW_CFA_GNU_args_size:
913
+ {
914
+ Dwarf_Unsigned lreg;
915
+
916
+ DECODE_LEB128_UWORD(instr_ptr, lreg);
917
+ reg_no = (reg_num_type) lreg;
918
+
919
+ break;
920
+ }
921
+ #endif
922
+ default:
923
+ /* ERROR, we have an opcode we know nothing about. Memory
924
+ leak here, but an error like this is not supposed to
925
+ happen so we ignore the leak. These used to be ignored,
926
+ now we notice and report. */
927
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
928
+
929
+ }
930
+
931
+ if (make_instr) {
932
+ instr_count++;
933
+
934
+ curr_instr = (Dwarf_Frame_Op *)
935
+ _dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1);
936
+ if (curr_instr == NULL) {
937
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
938
+ }
939
+
940
+ curr_instr->fp_base_op = fp_base_op;
941
+ curr_instr->fp_extended_op = fp_extended_op;
942
+ curr_instr->fp_register = fp_register;
943
+ curr_instr->fp_offset = fp_offset;
944
+ curr_instr->fp_instr_offset = fp_instr_offset;
945
+
946
+ curr_instr_item = (Dwarf_Chain)
947
+ _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
948
+ if (curr_instr_item == NULL) {
949
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
950
+ }
951
+
952
+ curr_instr_item->ch_item = curr_instr;
953
+ if (head_instr_chain == NULL)
954
+ head_instr_chain = tail_instr_chain = curr_instr_item;
955
+ else {
956
+ tail_instr_chain->ch_next = curr_instr_item;
957
+ tail_instr_chain = curr_instr_item;
958
+ }
959
+ }
960
+ }
961
+
962
+ /* If frame instruction decoding was right we would stop exactly at
963
+ final_instr_ptr. */
964
+ if (instr_ptr > final_instr_ptr) {
965
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
966
+ }
967
+
968
+ /* Fill in the actual output table, the space the caller passed in. */
969
+ if (table != NULL) {
970
+
971
+ struct Dwarf_Reg_Rule_s *t2reg = table->fr_reg;
972
+ struct Dwarf_Reg_Rule_s *t3reg = localregtab;
973
+ unsigned minregcount = MIN(table->fr_reg_count,reg_count);
974
+ unsigned curreg = 0;
975
+
976
+ table->fr_loc = current_loc;
977
+ for (; curreg < minregcount ; curreg++, t3reg++, t2reg++) {
978
+ *t2reg = *t3reg;
979
+ }
980
+
981
+ /* CONSTCOND */
982
+ /* Do not update the main table with the cfa_reg.
983
+ Just leave cfa_reg as cfa_reg. */
984
+ table->fr_cfa_rule = cfa_reg;
985
+ }
986
+
987
+ /* Dealloc anything remaining on stack. */
988
+ for (; top_stack != NULL;) {
989
+ stack_table = top_stack;
990
+ top_stack = top_stack->fr_next;
991
+ dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
992
+ }
993
+
994
+ if (make_instr) {
995
+ /* Allocate list of pointers to Dwarf_Frame_Op's. */
996
+ head_instr_block = (Dwarf_Frame_Op *)
997
+ _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count);
998
+ if (head_instr_block == NULL) {
999
+ SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
1000
+ }
1001
+
1002
+ /* Store pointers to Dwarf_Frame_Op's in this list and
1003
+ deallocate the structs that chain the Dwarf_Frame_Op's. */
1004
+ curr_instr_item = head_instr_chain;
1005
+ for (i = 0; i < instr_count; i++) {
1006
+ *(head_instr_block + i) =
1007
+ *(Dwarf_Frame_Op *) curr_instr_item->ch_item;
1008
+ dealloc_instr_item = curr_instr_item;
1009
+ curr_instr_item = curr_instr_item->ch_next;
1010
+ dwarf_dealloc(dbg, dealloc_instr_item->ch_item,
1011
+ DW_DLA_FRAME_OP);
1012
+ dwarf_dealloc(dbg, dealloc_instr_item, DW_DLA_CHAIN);
1013
+ }
1014
+ *ret_frame_instr = head_instr_block;
1015
+ *returned_count = (Dwarf_Sword) instr_count;
1016
+ } else {
1017
+ *returned_count = 0;
1018
+ }
1019
+ free(localregtab);
1020
+ return DW_DLV_OK;
1021
+ #undef ERROR_IF_REG_NUM_TOO_HIGH
1022
+ #undef SIMPLE_ERROR_RETURN
1023
+ }
1024
+
1025
+ /* Depending on version, either read the return address register
1026
+ as a ubyte or as an leb number.
1027
+ The form of this value changed for DWARF3.
1028
+ */
1029
+ Dwarf_Unsigned
1030
+ _dwarf_get_return_address_reg(Dwarf_Small * frame_ptr,
1031
+ int version, unsigned long *size)
1032
+ {
1033
+ Dwarf_Unsigned uvalue = 0;
1034
+ Dwarf_Word leb128_length = 0;
1035
+
1036
+ if (version == 1) {
1037
+ *size = 1;
1038
+ uvalue = *(unsigned char *) frame_ptr;
1039
+ return uvalue;
1040
+ }
1041
+ uvalue = _dwarf_decode_u_leb128(frame_ptr, &leb128_length);
1042
+ *size = leb128_length;
1043
+ return uvalue;
1044
+ }
1045
+
1046
+
1047
+ /* Trivial consumer function.
1048
+ */
1049
+ int
1050
+ dwarf_get_cie_of_fde(Dwarf_Fde fde,
1051
+ Dwarf_Cie * cie_returned, Dwarf_Error * error)
1052
+ {
1053
+ if (fde == NULL) {
1054
+ _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
1055
+ return (DW_DLV_ERROR);
1056
+ }
1057
+
1058
+ *cie_returned = fde->fd_cie;
1059
+ return DW_DLV_OK;
1060
+
1061
+ }
1062
+
1063
+ int dwarf_get_cie_index(
1064
+ Dwarf_Cie cie,
1065
+ Dwarf_Signed* indx,
1066
+ Dwarf_Error* error )
1067
+ {
1068
+ if (cie == NULL)
1069
+ {
1070
+ _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
1071
+ return (DW_DLV_ERROR);
1072
+ }
1073
+
1074
+ *indx = cie->ci_index;
1075
+ return (DW_DLV_OK);
1076
+ }
1077
+
1078
+ /* For g++ .eh_frame fde and cie.
1079
+ the cie id is different as the
1080
+ definition of the cie_id in an fde
1081
+ is the distance back from the address of the
1082
+ value to the cie.
1083
+ Or 0 if this is a true cie.
1084
+ Non standard dwarf, designed this way to be
1085
+ convenient at run time for an allocated
1086
+ (mapped into memory as part of the running image) section.
1087
+ */
1088
+ int
1089
+ dwarf_get_fde_list_eh(Dwarf_Debug dbg,
1090
+ Dwarf_Cie ** cie_data,
1091
+ Dwarf_Signed * cie_element_count,
1092
+ Dwarf_Fde ** fde_data,
1093
+ Dwarf_Signed * fde_element_count,
1094
+ Dwarf_Error * error)
1095
+ {
1096
+ int res = _dwarf_load_section(dbg, &dbg->de_debug_frame_eh_gnu,error);
1097
+ if (res != DW_DLV_OK) {
1098
+ return res;
1099
+ }
1100
+
1101
+ res = _dwarf_get_fde_list_internal(dbg,
1102
+ cie_data,
1103
+ cie_element_count,
1104
+ fde_data,
1105
+ fde_element_count,
1106
+ dbg->de_debug_frame_eh_gnu.dss_data,
1107
+ dbg->de_debug_frame_eh_gnu.dss_index,
1108
+ dbg->de_debug_frame_eh_gnu.dss_size,
1109
+ /* cie_id_value */ 0,
1110
+ /* use_gnu_cie_calc= */ 1,
1111
+ error);
1112
+ return res;
1113
+ }
1114
+
1115
+
1116
+
1117
+ /* For standard dwarf .debug_frame
1118
+ cie_id is -1 in a cie, and
1119
+ is the section offset in the .debug_frame section
1120
+ of the cie otherwise. Standard dwarf
1121
+ */
1122
+ int
1123
+ dwarf_get_fde_list(Dwarf_Debug dbg,
1124
+ Dwarf_Cie ** cie_data,
1125
+ Dwarf_Signed * cie_element_count,
1126
+ Dwarf_Fde ** fde_data,
1127
+ Dwarf_Signed * fde_element_count,
1128
+ Dwarf_Error * error)
1129
+ {
1130
+ int res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error);
1131
+ if (res != DW_DLV_OK) {
1132
+ return res;
1133
+ }
1134
+
1135
+ res = _dwarf_get_fde_list_internal(dbg, cie_data,
1136
+ cie_element_count,
1137
+ fde_data,
1138
+ fde_element_count,
1139
+ dbg->de_debug_frame.dss_data,
1140
+ dbg->de_debug_frame.dss_index,
1141
+ dbg->de_debug_frame.dss_size,
1142
+ DW_CIE_ID,
1143
+ /* use_gnu_cie_calc= */ 0,
1144
+ error);
1145
+
1146
+ return res;
1147
+ }
1148
+
1149
+
1150
+ /* Only works on dwarf sections, not eh_frame
1151
+ because based on DW_AT_MIPS_fde.
1152
+ Given a Dwarf_Die, see if it has a
1153
+ DW_AT_MIPS_fde attribute and if so use that
1154
+ to get an fde offset.
1155
+ Then create a Dwarf_Fde to return thru the ret_fde pointer.
1156
+ Also creates a cie (pointed at from the Dwarf_Fde). */
1157
+ int
1158
+ dwarf_get_fde_for_die(Dwarf_Debug dbg,
1159
+ Dwarf_Die die,
1160
+ Dwarf_Fde * ret_fde, Dwarf_Error * error)
1161
+ {
1162
+ Dwarf_Attribute attr;
1163
+ Dwarf_Unsigned fde_offset = 0;
1164
+ Dwarf_Signed signdval = 0;
1165
+ Dwarf_Fde new_fde = 0;
1166
+ unsigned char *fde_ptr = 0;
1167
+ unsigned char *fde_start_ptr = 0;
1168
+ unsigned char *fde_end_ptr = 0;
1169
+ unsigned char *cie_ptr = 0;
1170
+ Dwarf_Unsigned cie_id = 0;
1171
+
1172
+ /* Fields for the current Cie being read. */
1173
+ int res = 0;
1174
+ int resattr = 0;
1175
+ int sdatares = 0;
1176
+
1177
+ struct cie_fde_prefix_s prefix;
1178
+ struct cie_fde_prefix_s prefix_c;
1179
+
1180
+ if (die == NULL) {
1181
+ _dwarf_error(NULL, error, DW_DLE_DIE_NULL);
1182
+ return (DW_DLV_ERROR);
1183
+ }
1184
+
1185
+ resattr = dwarf_attr(die, DW_AT_MIPS_fde, &attr, error);
1186
+ if (resattr != DW_DLV_OK) {
1187
+ return resattr;
1188
+ }
1189
+
1190
+ /* why is this formsdata? FIX */
1191
+ sdatares = dwarf_formsdata(attr, &signdval, error);
1192
+ if (sdatares != DW_DLV_OK) {
1193
+ return sdatares;
1194
+ }
1195
+
1196
+ res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error);
1197
+ if (res != DW_DLV_OK) {
1198
+ return res;
1199
+ }
1200
+
1201
+ fde_offset = signdval;
1202
+ fde_start_ptr = dbg->de_debug_frame.dss_data;
1203
+ fde_ptr = fde_start_ptr + fde_offset;
1204
+ fde_end_ptr = fde_start_ptr + dbg->de_debug_frame.dss_size;
1205
+
1206
+
1207
+ /* First read in the 'common prefix' to figure out what * we are to
1208
+ do with this entry. */
1209
+ memset(&prefix_c, 0, sizeof(prefix_c));
1210
+ memset(&prefix, 0, sizeof(prefix));
1211
+ res = dwarf_read_cie_fde_prefix(dbg, fde_ptr,
1212
+ dbg->de_debug_frame.dss_data,
1213
+ dbg->de_debug_frame.dss_index,
1214
+ dbg->de_debug_frame.dss_size,
1215
+ &prefix,
1216
+ error);
1217
+ if (res == DW_DLV_ERROR) {
1218
+ return res;
1219
+ }
1220
+ if (res == DW_DLV_NO_ENTRY)
1221
+ return res;
1222
+ fde_ptr = prefix.cf_addr_after_prefix;
1223
+ cie_id = prefix.cf_cie_id;
1224
+ /* Pass NULL, not section pointer, for 3rd argument.
1225
+ de_debug_frame.dss_data has no eh_frame relevance. */
1226
+ res = dwarf_create_fde_from_after_start(dbg, &prefix,
1227
+ fde_start_ptr,
1228
+ fde_ptr,
1229
+ fde_end_ptr,
1230
+ /* use_gnu_cie_calc= */ 0,
1231
+ /* Dwarf_Cie = */ 0,
1232
+ &new_fde, error);
1233
+ if (res == DW_DLV_ERROR) {
1234
+ return res;
1235
+ } else if (res == DW_DLV_NO_ENTRY) {
1236
+ return res;
1237
+ }
1238
+ /* DW_DLV_OK */
1239
+
1240
+ /* now read the cie corresponding to the fde */
1241
+ cie_ptr = new_fde->fd_section_ptr + cie_id;
1242
+ res = dwarf_read_cie_fde_prefix(dbg, cie_ptr,
1243
+ dbg->de_debug_frame.dss_data,
1244
+ dbg->de_debug_frame.dss_index,
1245
+ dbg->de_debug_frame.dss_size,
1246
+ &prefix_c, error);
1247
+ if (res == DW_DLV_ERROR) {
1248
+ return res;
1249
+ }
1250
+ if (res == DW_DLV_NO_ENTRY)
1251
+ return res;
1252
+
1253
+ cie_ptr = prefix_c.cf_addr_after_prefix;
1254
+ cie_id = prefix_c.cf_cie_id;
1255
+
1256
+ if (cie_id == (Dwarf_Unsigned)DW_CIE_ID) {
1257
+ int res2 = 0;
1258
+ Dwarf_Cie new_cie = 0;
1259
+
1260
+ /* Pass NULL, not section pointer, for 3rd argument.
1261
+ de_debug_frame.dss_data has no eh_frame relevance. */
1262
+ res2 = dwarf_create_cie_from_after_start(dbg,
1263
+ &prefix_c,
1264
+ fde_start_ptr,
1265
+ cie_ptr,
1266
+ fde_end_ptr,
1267
+ /* cie_count= */ 0,
1268
+ /* use_gnu_cie_calc= */
1269
+ 0, &new_cie, error);
1270
+ if (res2 == DW_DLV_ERROR) {
1271
+ dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
1272
+ return res;
1273
+ } else if (res2 == DW_DLV_NO_ENTRY) {
1274
+ dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
1275
+ return res;
1276
+ }
1277
+ new_fde->fd_cie = new_cie;
1278
+ } else {
1279
+ _dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE);
1280
+ return (DW_DLV_ERROR);
1281
+ }
1282
+
1283
+ *ret_fde = new_fde;
1284
+ return DW_DLV_OK;
1285
+ }
1286
+
1287
+ /* A dwarf consumer operation, see the consumer library documentation.
1288
+ */
1289
+ int
1290
+ dwarf_get_fde_range(Dwarf_Fde fde,
1291
+ Dwarf_Addr * low_pc,
1292
+ Dwarf_Unsigned * func_length,
1293
+ Dwarf_Ptr * fde_bytes,
1294
+ Dwarf_Unsigned * fde_byte_length,
1295
+ Dwarf_Off * cie_offset,
1296
+ Dwarf_Signed * cie_index,
1297
+ Dwarf_Off * fde_offset, Dwarf_Error * error)
1298
+ {
1299
+ Dwarf_Debug dbg;
1300
+
1301
+ if (fde == NULL) {
1302
+ _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
1303
+ return (DW_DLV_ERROR);
1304
+ }
1305
+
1306
+ dbg = fde->fd_dbg;
1307
+ if (dbg == NULL) {
1308
+ _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
1309
+ return (DW_DLV_ERROR);
1310
+ }
1311
+
1312
+
1313
+ /* We have always already done the section load here, so no need to
1314
+ load the section. We did the section load in order to create the
1315
+ Dwarf_Fde pointer passed in here. */
1316
+
1317
+
1318
+ if (low_pc != NULL)
1319
+ *low_pc = fde->fd_initial_location;
1320
+ if (func_length != NULL)
1321
+ *func_length = fde->fd_address_range;
1322
+ if (fde_bytes != NULL)
1323
+ *fde_bytes = fde->fd_fde_start;
1324
+ if (fde_byte_length != NULL)
1325
+ *fde_byte_length = fde->fd_length;
1326
+ if (cie_offset != NULL)
1327
+ *cie_offset = fde->fd_cie_offset;
1328
+ if (cie_index != NULL)
1329
+ *cie_index = fde->fd_cie_index;
1330
+ if (fde_offset != NULL)
1331
+ *fde_offset = fde->fd_fde_start - fde->fd_section_ptr;
1332
+
1333
+ return DW_DLV_OK;
1334
+ }
1335
+
1336
+ /* IRIX specific function. The exception tables
1337
+ have C++ destructor information and are
1338
+ at present undocumented. */
1339
+ int
1340
+ dwarf_get_fde_exception_info(Dwarf_Fde fde,
1341
+ Dwarf_Signed *
1342
+ offset_into_exception_tables,
1343
+ Dwarf_Error * error)
1344
+ {
1345
+ Dwarf_Debug dbg;
1346
+
1347
+ dbg = fde->fd_dbg;
1348
+ if (dbg == NULL) {
1349
+ _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
1350
+ return (DW_DLV_ERROR);
1351
+ }
1352
+ *offset_into_exception_tables =
1353
+ fde->fd_offset_into_exception_tables;
1354
+ return DW_DLV_OK;
1355
+ }
1356
+
1357
+
1358
+
1359
+ /* A consumer code function.
1360
+ Given a CIE pointer, return the normal CIE data thru
1361
+ pointers.
1362
+ Special augmentation data is not returned here.
1363
+ */
1364
+ int
1365
+ dwarf_get_cie_info(Dwarf_Cie cie,
1366
+ Dwarf_Unsigned * bytes_in_cie,
1367
+ Dwarf_Small * ptr_to_version,
1368
+ char **augmenter,
1369
+ Dwarf_Unsigned * code_alignment_factor,
1370
+ Dwarf_Signed * data_alignment_factor,
1371
+ Dwarf_Half * return_address_register,
1372
+ Dwarf_Ptr * initial_instructions,
1373
+ Dwarf_Unsigned * initial_instructions_length,
1374
+ Dwarf_Error * error)
1375
+ {
1376
+ Dwarf_Half offset_size = 0;
1377
+ return dwarf_get_cie_info_b(cie,
1378
+ bytes_in_cie,
1379
+ ptr_to_version,
1380
+ augmenter,
1381
+ code_alignment_factor,
1382
+ data_alignment_factor,
1383
+ return_address_register,
1384
+ initial_instructions,
1385
+ initial_instructions_length,
1386
+ &offset_size,
1387
+ error);
1388
+ }
1389
+ int
1390
+ dwarf_get_cie_info_b(Dwarf_Cie cie,
1391
+ Dwarf_Unsigned * bytes_in_cie,
1392
+ Dwarf_Small * ptr_to_version,
1393
+ char **augmenter,
1394
+ Dwarf_Unsigned * code_alignment_factor,
1395
+ Dwarf_Signed * data_alignment_factor,
1396
+ Dwarf_Half * return_address_register,
1397
+ Dwarf_Ptr * initial_instructions,
1398
+ Dwarf_Unsigned * initial_instructions_length,
1399
+ Dwarf_Half * offset_size,
1400
+ Dwarf_Error * error)
1401
+ {
1402
+ Dwarf_Debug dbg = 0;
1403
+
1404
+ if (cie == NULL) {
1405
+ _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
1406
+ return (DW_DLV_ERROR);
1407
+ }
1408
+
1409
+ dbg = cie->ci_dbg;
1410
+ if (dbg == NULL) {
1411
+ _dwarf_error(NULL, error, DW_DLE_CIE_DBG_NULL);
1412
+ return (DW_DLV_ERROR);
1413
+ }
1414
+
1415
+ if (ptr_to_version != NULL)
1416
+ *ptr_to_version = cie->ci_cie_version_number;
1417
+ if (augmenter != NULL)
1418
+ *augmenter = cie->ci_augmentation;
1419
+ if (code_alignment_factor != NULL)
1420
+ *code_alignment_factor = cie->ci_code_alignment_factor;
1421
+ if (data_alignment_factor != NULL)
1422
+ *data_alignment_factor = cie->ci_data_alignment_factor;
1423
+ if (return_address_register != NULL)
1424
+ *return_address_register = cie->ci_return_address_register;
1425
+ if (initial_instructions != NULL)
1426
+ *initial_instructions = cie->ci_cie_instr_start;
1427
+ if (initial_instructions_length != NULL) {
1428
+ *initial_instructions_length = cie->ci_length +
1429
+ cie->ci_length_size +
1430
+ cie->ci_extension_size -
1431
+ (cie->ci_cie_instr_start - cie->ci_cie_start);
1432
+ }
1433
+ if (offset_size) {
1434
+ *offset_size = cie->ci_length_size;
1435
+ }
1436
+ *bytes_in_cie = (cie->ci_length);
1437
+ return (DW_DLV_OK);
1438
+ }
1439
+
1440
+ /* Return the register rules for all registers at a given pc.
1441
+ */
1442
+ static int
1443
+ _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde,
1444
+ Dwarf_Addr pc_requested,
1445
+ Dwarf_Frame table,
1446
+ Dwarf_Half cfa_reg_col_num,
1447
+ Dwarf_Error * error)
1448
+ {
1449
+ Dwarf_Debug dbg = 0;
1450
+ Dwarf_Cie cie = 0;
1451
+ int dw_err = 0;
1452
+ Dwarf_Sword icount = 0;
1453
+ int res = 0;
1454
+
1455
+ if (fde == NULL) {
1456
+ _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
1457
+ return (DW_DLV_ERROR);
1458
+ }
1459
+
1460
+ dbg = fde->fd_dbg;
1461
+ if (dbg == NULL) {
1462
+ _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
1463
+ return (DW_DLV_ERROR);
1464
+ }
1465
+
1466
+ if (pc_requested < fde->fd_initial_location ||
1467
+ pc_requested >=
1468
+ fde->fd_initial_location + fde->fd_address_range) {
1469
+ _dwarf_error(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
1470
+ return (DW_DLV_ERROR);
1471
+ }
1472
+
1473
+ cie = fde->fd_cie;
1474
+ if (cie->ci_initial_table == NULL) {
1475
+ cie->ci_initial_table = (Dwarf_Frame)_dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
1476
+
1477
+ if (cie->ci_initial_table == NULL) {
1478
+ _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1479
+ return (DW_DLV_ERROR);
1480
+ }
1481
+ dwarf_init_reg_rules_ru(cie->ci_initial_table->fr_reg,
1482
+ 0, cie->ci_initial_table->fr_reg_count,dbg->de_frame_rule_initial_value);
1483
+ dwarf_init_reg_rules_ru(&cie->ci_initial_table->fr_cfa_rule,
1484
+ 0,1,dbg->de_frame_rule_initial_value);
1485
+ res = _dwarf_exec_frame_instr( /* make_instr= */ false,
1486
+ /* ret_frame_instr= */ NULL,
1487
+ /* search_pc */ false,
1488
+ /* search_pc_val */ 0,
1489
+ /* location */ 0,
1490
+ cie->ci_cie_instr_start,
1491
+ cie->ci_cie_instr_start + (cie->ci_length +
1492
+ cie->ci_length_size +
1493
+ cie->ci_extension_size -
1494
+ (cie->ci_cie_instr_start -
1495
+ cie->ci_cie_start)),
1496
+ cie->ci_initial_table, cie, dbg,
1497
+ cfa_reg_col_num, &icount,
1498
+ &dw_err);
1499
+ if (res == DW_DLV_ERROR) {
1500
+ _dwarf_error(dbg, error, dw_err);
1501
+ return (res);
1502
+ } else if (res == DW_DLV_NO_ENTRY) {
1503
+ return res;
1504
+ }
1505
+ }
1506
+
1507
+ {
1508
+ Dwarf_Small *instr_end = fde->fd_fde_instr_start +
1509
+ fde->fd_length +
1510
+ fde->fd_length_size +
1511
+ fde->fd_extension_size - (fde->fd_fde_instr_start -
1512
+ fde->fd_fde_start);
1513
+
1514
+ res = _dwarf_exec_frame_instr( /* make_instr= */ false,
1515
+ /* ret_frame_instr= */ NULL,
1516
+ /* search_pc */ true,
1517
+ /* search_pc_val */ pc_requested,
1518
+ fde->fd_initial_location,
1519
+ fde->fd_fde_instr_start,
1520
+ instr_end,
1521
+ table,
1522
+ cie, dbg,
1523
+ cfa_reg_col_num, &icount,
1524
+ &dw_err);
1525
+ }
1526
+ if (res == DW_DLV_ERROR) {
1527
+ _dwarf_error(dbg, error, dw_err);
1528
+ return (res);
1529
+ } else if (res == DW_DLV_NO_ENTRY) {
1530
+ return res;
1531
+ }
1532
+
1533
+ return DW_DLV_OK;
1534
+ }
1535
+
1536
+ /* A consumer call for efficiently getting the register info
1537
+ for all registers in one call.
1538
+
1539
+ The output table rules array is size DW_REG_TABLE_SIZE.
1540
+ The frame info rules array in fde_table is of size
1541
+ DW_REG_TABLE_SIZE too.
1542
+
1543
+ This interface really only works well with MIPS/IRIX
1544
+ where DW_FRAME_CFA_COL is zero (in that case it's safe).
1545
+
1546
+ It is also restricted to the case where
1547
+ DW_REG_TABLE_SIZE == DW_FRAME_LAST_REG_NUM ==
1548
+ dbg->de_frame_reg_rules_entry_count (true for MIPS/IRIX).
1549
+ If this condition is not met calling this routine can result in
1550
+ incorrect output or in memory corruption.
1551
+
1552
+ It is much better to use dwarf_get_fde_info_for_all_regs3()
1553
+ instead of this interface.
1554
+ */
1555
+ int
1556
+ dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde,
1557
+ Dwarf_Addr pc_requested,
1558
+ Dwarf_Regtable * reg_table,
1559
+ Dwarf_Addr * row_pc,
1560
+ Dwarf_Error * error)
1561
+ {
1562
+
1563
+ /* Table size: DW_REG_TABLE_SIZE */
1564
+ struct Dwarf_Frame_s fde_table;
1565
+ Dwarf_Sword i = 0;
1566
+ struct Dwarf_Reg_Rule_s *rule = NULL;
1567
+ struct Dwarf_Regtable_Entry_s *out_rule = NULL;
1568
+ int res = 0;
1569
+ Dwarf_Debug dbg = 0;
1570
+
1571
+ /* For this interface the size is fixed at compile time. */
1572
+ int output_table_real_data_size = DW_REG_TABLE_SIZE;
1573
+
1574
+ FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1575
+
1576
+ res = dwarf_initialize_fde_table(dbg, &fde_table,
1577
+ output_table_real_data_size,
1578
+ error);
1579
+ if (res != DW_DLV_OK)
1580
+ return res;
1581
+
1582
+ /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
1583
+ */
1584
+ res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
1585
+ &fde_table, dbg->de_frame_cfa_col_number, error);
1586
+ if (res != DW_DLV_OK) {
1587
+ dwarf_free_fde_table(&fde_table);
1588
+ return res;
1589
+ }
1590
+
1591
+ out_rule = &reg_table->rules[0];
1592
+ rule = &fde_table.fr_reg[0];
1593
+ for (i = 0; i < output_table_real_data_size;
1594
+ i++, ++out_rule, ++rule) {
1595
+ out_rule->dw_offset_relevant = rule->ru_is_off;
1596
+ out_rule->dw_value_type = rule->ru_value_type;
1597
+ out_rule->dw_regnum = rule->ru_register;
1598
+ out_rule->dw_offset = rule->ru_offset_or_block_len;
1599
+ }
1600
+ dwarf_init_reg_rules_dw(&reg_table->rules[0],i,DW_REG_TABLE_SIZE,
1601
+ dbg->de_frame_undefined_value_number);
1602
+
1603
+ /* The test is just in case it's not inside the table. For non-MIPS
1604
+ it could be outside the table and that is just fine, it was
1605
+ really a mistake to put it in the table in 1993. */
1606
+ /* CONSTCOND */
1607
+ if (dbg->de_frame_cfa_col_number < DW_REG_TABLE_SIZE) {
1608
+ out_rule = &reg_table->rules[dbg->de_frame_cfa_col_number];
1609
+ out_rule->dw_offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
1610
+ out_rule->dw_value_type = fde_table.fr_cfa_rule.ru_value_type;
1611
+ out_rule->dw_regnum = fde_table.fr_cfa_rule.ru_register;
1612
+ out_rule->dw_offset =
1613
+ fde_table.fr_cfa_rule.ru_offset_or_block_len;
1614
+ }
1615
+
1616
+ if (row_pc != NULL)
1617
+ *row_pc = fde_table.fr_loc;
1618
+ dwarf_free_fde_table(&fde_table);
1619
+ return DW_DLV_OK;
1620
+ }
1621
+
1622
+ /* A consumer call for efficiently getting the register info
1623
+ for all registers in one call.
1624
+
1625
+ The output table rules array is size output_table_real_data_size.
1626
+ (normally DW_REG_TABLE_SIZE).
1627
+ The frame info rules array in fde_table is normally of size
1628
+ DW_FRAME_LAST_REG_NUM. */
1629
+ int
1630
+ dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,
1631
+ Dwarf_Addr pc_requested,
1632
+ Dwarf_Regtable3 * reg_table,
1633
+ Dwarf_Addr * row_pc,
1634
+ Dwarf_Error * error)
1635
+ {
1636
+
1637
+ struct Dwarf_Frame_s fde_table;
1638
+ Dwarf_Sword i = 0;
1639
+ int res = 0;
1640
+ struct Dwarf_Reg_Rule_s *rule = NULL;
1641
+ struct Dwarf_Regtable_Entry3_s *out_rule = NULL;
1642
+ Dwarf_Debug dbg = 0;
1643
+ int output_table_real_data_size = reg_table->rt3_reg_table_size;
1644
+
1645
+ FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1646
+
1647
+ output_table_real_data_size =
1648
+ MIN(output_table_real_data_size,
1649
+ dbg->de_frame_reg_rules_entry_count);
1650
+
1651
+ res = dwarf_initialize_fde_table(dbg, &fde_table,
1652
+ output_table_real_data_size,
1653
+ error);
1654
+
1655
+ /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
1656
+ */
1657
+ res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
1658
+ &fde_table,
1659
+ dbg->de_frame_cfa_col_number,
1660
+ error);
1661
+ if (res != DW_DLV_OK) {
1662
+ dwarf_free_fde_table(&fde_table);
1663
+ return res;
1664
+ }
1665
+
1666
+ out_rule = &reg_table->rt3_rules[0];
1667
+ rule = &fde_table.fr_reg[0];
1668
+ for (i = 0; i < output_table_real_data_size;
1669
+ i++, ++out_rule, ++rule) {
1670
+ out_rule->dw_offset_relevant = rule->ru_is_off;
1671
+ out_rule->dw_value_type = rule->ru_value_type;
1672
+ out_rule->dw_regnum = rule->ru_register;
1673
+ out_rule->dw_offset_or_block_len = rule->ru_offset_or_block_len;
1674
+ out_rule->dw_block_ptr = rule->ru_block;
1675
+ }
1676
+ dwarf_init_reg_rules_dw3(&reg_table->rt3_rules[0],i,reg_table->rt3_reg_table_size,
1677
+ dbg->de_frame_undefined_value_number);
1678
+
1679
+ reg_table->rt3_cfa_rule.dw_offset_relevant =
1680
+ fde_table.fr_cfa_rule.ru_is_off;
1681
+ reg_table->rt3_cfa_rule.dw_value_type =
1682
+ fde_table.fr_cfa_rule.ru_value_type;
1683
+ reg_table->rt3_cfa_rule.dw_regnum =
1684
+ fde_table.fr_cfa_rule.ru_register;
1685
+ reg_table->rt3_cfa_rule.dw_offset_or_block_len =
1686
+ fde_table.fr_cfa_rule.ru_offset_or_block_len;
1687
+ reg_table->rt3_cfa_rule.dw_block_ptr =
1688
+ fde_table.fr_cfa_rule.ru_block;
1689
+
1690
+ if (row_pc != NULL)
1691
+ *row_pc = fde_table.fr_loc;
1692
+
1693
+ dwarf_free_fde_table(&fde_table);
1694
+ return DW_DLV_OK;
1695
+ }
1696
+
1697
+
1698
+ /* Gets the register info for a single register at a given PC value
1699
+ for the FDE specified.
1700
+
1701
+ This is the old MIPS interface and should no longer be used.
1702
+ Use dwarf_get_fde_info_for_reg3() instead. */
1703
+ int
1704
+ dwarf_get_fde_info_for_reg(Dwarf_Fde fde,
1705
+ Dwarf_Half table_column,
1706
+ Dwarf_Addr pc_requested,
1707
+ Dwarf_Signed * offset_relevant,
1708
+ Dwarf_Signed * register_num,
1709
+ Dwarf_Signed * offset,
1710
+ Dwarf_Addr * row_pc, Dwarf_Error * error)
1711
+ {
1712
+ struct Dwarf_Frame_s fde_table;
1713
+ int res = DW_DLV_ERROR;
1714
+ Dwarf_Debug dbg = 0;
1715
+ int output_table_real_data_size = 0;
1716
+
1717
+ FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1718
+ output_table_real_data_size = dbg->de_frame_reg_rules_entry_count;
1719
+
1720
+ res = dwarf_initialize_fde_table(dbg, &fde_table,
1721
+ output_table_real_data_size,
1722
+ error);
1723
+ if (res != DW_DLV_OK)
1724
+ return res;
1725
+
1726
+ if (table_column >= output_table_real_data_size) {
1727
+ dwarf_free_fde_table(&fde_table);
1728
+ _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
1729
+ return (DW_DLV_ERROR);
1730
+ }
1731
+
1732
+ /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
1733
+ */
1734
+ res =
1735
+ _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
1736
+ dbg->de_frame_cfa_col_number, error);
1737
+ if (res != DW_DLV_OK) {
1738
+ dwarf_free_fde_table(&fde_table);
1739
+ return res;
1740
+ }
1741
+
1742
+ if (fde_table.fr_reg[table_column].ru_value_type != DW_EXPR_OFFSET) {
1743
+ /* The problem here is that this interface cannot deal with
1744
+ other sorts of (newer) dwarf frame values. Code must
1745
+ use dwarf_get_fde_info_for_reg3() to get these
1746
+ values correctly. We error rather than return
1747
+ misleading incomplete data. */
1748
+ dwarf_free_fde_table(&fde_table);
1749
+ _dwarf_error(NULL, error,
1750
+ DW_DLE_FRAME_REGISTER_UNREPRESENTABLE);
1751
+ return (DW_DLV_ERROR);
1752
+ }
1753
+ if (table_column == dbg->de_frame_cfa_col_number) {
1754
+ if (register_num != NULL)
1755
+ *register_num = fde_table.fr_cfa_rule.ru_register;
1756
+ if (offset != NULL)
1757
+ *offset = fde_table.fr_cfa_rule.ru_offset_or_block_len;
1758
+ if (row_pc != NULL)
1759
+ *row_pc = fde_table.fr_loc;
1760
+ *offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
1761
+
1762
+ } else {
1763
+ if (register_num != NULL)
1764
+ *register_num = fde_table.fr_reg[table_column].ru_register;
1765
+ if (offset != NULL)
1766
+ *offset = fde_table.fr_reg[table_column].ru_offset_or_block_len;
1767
+ if (row_pc != NULL)
1768
+ *row_pc = fde_table.fr_loc;
1769
+
1770
+ *offset_relevant = fde_table.fr_reg[table_column].ru_is_off;
1771
+ }
1772
+ dwarf_free_fde_table(&fde_table);
1773
+ return DW_DLV_OK;
1774
+ }
1775
+
1776
+ /* In this interface, table_column of DW_FRAME_CFA_COL
1777
+ is not meaningful.
1778
+ Use dwarf_get_fde_info_for_cfa_reg3() to get the CFA.
1779
+ Call dwarf_set_frame_cfa_value() to set the correct column
1780
+ after calling dwarf_init()
1781
+ (DW_FRAME_CFA_COL3 is a sensible column to use).
1782
+ */
1783
+ int
1784
+ dwarf_get_fde_info_for_reg3(Dwarf_Fde fde,
1785
+ Dwarf_Half table_column,
1786
+ Dwarf_Addr pc_requested,
1787
+ Dwarf_Small * value_type,
1788
+ Dwarf_Signed * offset_relevant,
1789
+ Dwarf_Signed * register_num,
1790
+ Dwarf_Signed * offset_or_block_len,
1791
+ Dwarf_Ptr * block_ptr,
1792
+ Dwarf_Addr * row_pc_out,
1793
+ Dwarf_Error * error)
1794
+ {
1795
+ struct Dwarf_Frame_s fde_table;
1796
+ int res = DW_DLV_ERROR;
1797
+
1798
+ Dwarf_Debug dbg = 0;
1799
+ int table_real_data_size = 0;
1800
+
1801
+ FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1802
+ table_real_data_size = dbg->de_frame_reg_rules_entry_count;
1803
+ res = dwarf_initialize_fde_table(dbg, &fde_table,
1804
+ table_real_data_size, error);
1805
+ if (res != DW_DLV_OK)
1806
+ return res;
1807
+ if (table_column >= table_real_data_size) {
1808
+ dwarf_free_fde_table(&fde_table);
1809
+ _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
1810
+ return (DW_DLV_ERROR);
1811
+ }
1812
+
1813
+ /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
1814
+ */
1815
+ res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
1816
+ dbg->de_frame_cfa_col_number,
1817
+ error);
1818
+ if (res != DW_DLV_OK) {
1819
+ dwarf_free_fde_table(&fde_table);
1820
+ return res;
1821
+ }
1822
+
1823
+ if (register_num != NULL)
1824
+ *register_num = fde_table.fr_reg[table_column].ru_register;
1825
+ if (offset_or_block_len != NULL)
1826
+ *offset_or_block_len =
1827
+ fde_table.fr_reg[table_column].ru_offset_or_block_len;
1828
+ if (row_pc_out != NULL)
1829
+ *row_pc_out = fde_table.fr_loc;
1830
+ if (block_ptr)
1831
+ *block_ptr = fde_table.fr_reg[table_column].ru_block;
1832
+
1833
+ /* Without value_type the data cannot be understood, so we insist
1834
+ on it being present, we don't test it. */
1835
+ *value_type = fde_table.fr_reg[table_column].ru_value_type;
1836
+ *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off);
1837
+ dwarf_free_fde_table(&fde_table);
1838
+ return DW_DLV_OK;
1839
+
1840
+ }
1841
+
1842
+ /* For latest DWARF, this is the preferred interface.
1843
+ It more portably deals with the CFA by not
1844
+ making the CFA a column number, which means
1845
+ DW_FRAME_CFA_COL3 becomes, like DW_CFA_SAME_VALUE,
1846
+ a special value, not something one uses as an index.
1847
+
1848
+ Call dwarf_set_frame_cfa_value() to set the correct column
1849
+ after calling dwarf_init()
1850
+ (DW_FRAME_CFA_COL3 is a sensible column to use, and
1851
+ is the default unless '--enable-oldframecol'
1852
+ is used to configure libdwarf). */
1853
+ int
1854
+ dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde,
1855
+ Dwarf_Addr pc_requested,
1856
+ Dwarf_Small * value_type,
1857
+ Dwarf_Signed * offset_relevant,
1858
+ Dwarf_Signed * register_num,
1859
+ Dwarf_Signed * offset_or_block_len,
1860
+ Dwarf_Ptr * block_ptr,
1861
+ Dwarf_Addr * row_pc_out,
1862
+ Dwarf_Error * error)
1863
+ {
1864
+ struct Dwarf_Frame_s fde_table;
1865
+ int res = DW_DLV_ERROR;
1866
+ Dwarf_Debug dbg = 0;
1867
+
1868
+ int table_real_data_size = 0;
1869
+
1870
+ FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1871
+
1872
+ table_real_data_size = dbg->de_frame_reg_rules_entry_count;
1873
+ res = dwarf_initialize_fde_table(dbg, &fde_table,
1874
+ table_real_data_size, error);
1875
+ if (res != DW_DLV_OK)
1876
+ return res;
1877
+ res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
1878
+ dbg->de_frame_cfa_col_number,error);
1879
+ if (res != DW_DLV_OK) {
1880
+ dwarf_free_fde_table(&fde_table);
1881
+ return res;
1882
+ }
1883
+
1884
+ if (register_num != NULL)
1885
+ *register_num = fde_table.fr_cfa_rule.ru_register;
1886
+ if (offset_or_block_len != NULL)
1887
+ *offset_or_block_len =
1888
+ fde_table.fr_cfa_rule.ru_offset_or_block_len;
1889
+ if (row_pc_out != NULL)
1890
+ *row_pc_out = fde_table.fr_loc;
1891
+ if (block_ptr)
1892
+ *block_ptr = fde_table.fr_cfa_rule.ru_block;
1893
+
1894
+ /* Without value_type the data cannot be understood, so we insist
1895
+ on it being present, we don't test it. */
1896
+ *value_type = fde_table.fr_cfa_rule.ru_value_type;
1897
+ *offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
1898
+ dwarf_free_fde_table(&fde_table);
1899
+ return DW_DLV_OK;
1900
+ }
1901
+
1902
+
1903
+
1904
+ /* Return pointer to the instructions in the dwarf fde. */
1905
+ int
1906
+ dwarf_get_fde_instr_bytes(Dwarf_Fde inFde, Dwarf_Ptr * outinstraddr,
1907
+ Dwarf_Unsigned * outaddrlen,
1908
+ Dwarf_Error * error)
1909
+ {
1910
+ Dwarf_Unsigned len = 0;
1911
+ unsigned char *instrs = 0;
1912
+ Dwarf_Debug dbg = 0;
1913
+
1914
+ if (inFde == NULL) {
1915
+ _dwarf_error(dbg, error, DW_DLE_FDE_NULL);
1916
+ return (DW_DLV_ERROR);
1917
+ }
1918
+
1919
+ dbg = inFde->fd_dbg;
1920
+ if (dbg == NULL) {
1921
+ _dwarf_error(dbg, error, DW_DLE_FDE_DBG_NULL);
1922
+ return (DW_DLV_ERROR);
1923
+ }
1924
+
1925
+ instrs = inFde->fd_fde_instr_start;
1926
+
1927
+ len = (inFde->fd_fde_start + inFde->fd_length +
1928
+ inFde->fd_length_size + inFde->fd_extension_size) - instrs;
1929
+
1930
+ *outinstraddr = instrs;
1931
+ *outaddrlen = len;
1932
+ return DW_DLV_OK;
1933
+ }
1934
+
1935
+ /* Allows getting an fde from its table via an index.
1936
+ With more error checking than simply indexing oneself. */
1937
+ int
1938
+ dwarf_get_fde_n(Dwarf_Fde * fde_data,
1939
+ Dwarf_Unsigned fde_index,
1940
+ Dwarf_Fde * returned_fde, Dwarf_Error * error)
1941
+ {
1942
+ Dwarf_Debug dbg = 0;
1943
+ Dwarf_Unsigned fdecount = 0;
1944
+
1945
+ if (fde_data == NULL) {
1946
+ _dwarf_error(dbg, error, DW_DLE_FDE_PTR_NULL);
1947
+ return (DW_DLV_ERROR);
1948
+ }
1949
+
1950
+ FDE_NULL_CHECKS_AND_SET_DBG(*fde_data, dbg);
1951
+ /* Assumes fde_data table has at least one entry. */
1952
+ fdecount = fde_data[0]->fd_is_eh?
1953
+ dbg->de_fde_count_eh:dbg->de_fde_count;
1954
+ if (fde_index >= fdecount) {
1955
+ return (DW_DLV_NO_ENTRY);
1956
+ }
1957
+ *returned_fde = (*(fde_data + fde_index));
1958
+ return DW_DLV_OK;
1959
+ }
1960
+
1961
+
1962
+ /* Lopc and hipc are extensions to the interface to
1963
+ return the range of addresses that are described
1964
+ by the returned fde. */
1965
+ int
1966
+ dwarf_get_fde_at_pc(Dwarf_Fde * fde_data,
1967
+ Dwarf_Addr pc_of_interest,
1968
+ Dwarf_Fde * returned_fde,
1969
+ Dwarf_Addr * lopc,
1970
+ Dwarf_Addr * hipc, Dwarf_Error * error)
1971
+ {
1972
+ Dwarf_Debug dbg = NULL;
1973
+ Dwarf_Fde fde = NULL;
1974
+ Dwarf_Fde entryfde = NULL;
1975
+ Dwarf_Signed fdecount = 0;
1976
+
1977
+ if (fde_data == NULL) {
1978
+ _dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL);
1979
+ return (DW_DLV_ERROR);
1980
+ }
1981
+
1982
+ /* Assumes fde_data table has at least one entry. */
1983
+ entryfde = *fde_data;
1984
+ FDE_NULL_CHECKS_AND_SET_DBG(entryfde, dbg);
1985
+
1986
+ if (dbg == NULL) {
1987
+ _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
1988
+ return (DW_DLV_ERROR);
1989
+ }
1990
+ fdecount = entryfde->fd_is_eh?
1991
+ dbg->de_fde_count_eh:dbg->de_fde_count;
1992
+ {
1993
+ /* The fdes are sorted by their addresses. Binary search to
1994
+ find correct fde. */
1995
+ Dwarf_Signed low = 0;
1996
+ Dwarf_Signed high = fdecount - 1L;
1997
+ Dwarf_Signed middle = 0;
1998
+ Dwarf_Fde cur_fde;
1999
+
2000
+ while (low <= high) {
2001
+ middle = (low + high) / 2;
2002
+ cur_fde = fde_data[middle];
2003
+ if (pc_of_interest < cur_fde->fd_initial_location) {
2004
+ high = middle - 1;
2005
+ } else if (pc_of_interest >=
2006
+ (cur_fde->fd_initial_location +
2007
+ cur_fde->fd_address_range)) {
2008
+ low = middle + 1;
2009
+ } else {
2010
+ fde = fde_data[middle];
2011
+ break;
2012
+ }
2013
+ }
2014
+ }
2015
+
2016
+ if (fde) {
2017
+ if (lopc != NULL)
2018
+ *lopc = fde->fd_initial_location;
2019
+ if (hipc != NULL)
2020
+ *hipc =
2021
+ fde->fd_initial_location + fde->fd_address_range - 1;
2022
+ *returned_fde = fde;
2023
+ return (DW_DLV_OK);
2024
+ }
2025
+
2026
+ return (DW_DLV_NO_ENTRY);
2027
+ }
2028
+
2029
+
2030
+ /* Expands a single frame instruction block
2031
+ from a specific cie
2032
+ into a n array of Dwarf_Frame_Op-s.
2033
+ This depends on having the cfa column set sensibly.
2034
+
2035
+ Call dwarf_set_frame_cfa_value() to set the correct column
2036
+ after calling dwarf_init() unless you are using
2037
+ the old MIPS frame interfaces (in which case the default
2038
+ will be ok). (DW_FRAME_CFA_COL3 is a sensible column to use ).
2039
+ */
2040
+ int
2041
+ dwarf_expand_frame_instructions(Dwarf_Cie cie,
2042
+ Dwarf_Ptr instruction,
2043
+ Dwarf_Unsigned i_length,
2044
+ Dwarf_Frame_Op ** returned_op_list,
2045
+ Dwarf_Signed * returned_op_count,
2046
+ Dwarf_Error * error)
2047
+ {
2048
+ Dwarf_Sword instr_count;
2049
+ int res = DW_DLV_ERROR;
2050
+ int dw_err;
2051
+ Dwarf_Debug dbg = 0;
2052
+
2053
+ if (cie == 0) {
2054
+ _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
2055
+ return (DW_DLV_ERROR);
2056
+ }
2057
+ dbg = cie->ci_dbg;
2058
+
2059
+ if (returned_op_list == 0 || returned_op_count == 0) {
2060
+ _dwarf_error(dbg, error, DW_DLE_RET_OP_LIST_NULL);
2061
+ return (DW_DLV_ERROR);
2062
+ }
2063
+
2064
+ /* The cast to Dwarf_Ptr may get a compiler warning, but it is safe
2065
+ as it is just an i_length offset from 'instruction' itself. A
2066
+ caller has made a big mistake if the result is not a valid
2067
+ pointer. */
2068
+ res = _dwarf_exec_frame_instr( /* make_instr= */ true,
2069
+ returned_op_list,
2070
+ /* search_pc */ false,
2071
+ /* search_pc_val */ 0,
2072
+ /* location */ 0,
2073
+ instruction,
2074
+ (Dwarf_Ptr) ((Dwarf_Unsigned) instruction + i_length),
2075
+ /* Dwarf_Frame */ NULL,
2076
+ cie,
2077
+ dbg,
2078
+ dbg->de_frame_cfa_col_number, &instr_count,
2079
+ &dw_err);
2080
+ if (res != DW_DLV_OK) {
2081
+ if (res == DW_DLV_ERROR) {
2082
+ _dwarf_error(dbg, error, dw_err);
2083
+ }
2084
+ return (res);
2085
+ }
2086
+
2087
+ *returned_op_count = instr_count;
2088
+ return DW_DLV_OK;
2089
+ }
2090
+
2091
+
2092
+ /* Used by dwarfdump -v to print offsets, for debugging
2093
+ dwarf info.
2094
+ The dwarf_ version is preferred over the obsolete _dwarf version.
2095
+ _dwarf version kept for compatibility.
2096
+ */
2097
+ /* ARGSUSED 4 */
2098
+ int
2099
+ _dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
2100
+ Dwarf_Off * fde_off, Dwarf_Off * cie_off,
2101
+ Dwarf_Error * err)
2102
+ {
2103
+ return dwarf_fde_section_offset(dbg,in_fde,fde_off,
2104
+ cie_off,err);
2105
+ }
2106
+ /* ARGSUSED 4 */
2107
+ int
2108
+ dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
2109
+ Dwarf_Off * fde_off, Dwarf_Off * cie_off,
2110
+ Dwarf_Error * err)
2111
+ {
2112
+ char *start = 0;
2113
+ char *loc = 0;
2114
+
2115
+
2116
+
2117
+ start = (char *) in_fde->fd_section_ptr;
2118
+ loc = (char *) in_fde->fd_fde_start;
2119
+
2120
+ *fde_off = (loc - start);
2121
+ *cie_off = in_fde->fd_cie_offset;
2122
+ return DW_DLV_OK;
2123
+ }
2124
+
2125
+ /* Used by dwarfdump -v to print offsets, for debugging
2126
+ dwarf info.
2127
+ The dwarf_ version is preferred over the obsolete _dwarf version.
2128
+ _dwarf version kept for compatibility.
2129
+ */
2130
+ /* ARGSUSED 4 */
2131
+ int
2132
+ _dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
2133
+ Dwarf_Off * cie_off, Dwarf_Error * err)
2134
+ {
2135
+ return dwarf_cie_section_offset(dbg,in_cie,cie_off,err);
2136
+ }
2137
+ /* ARGSUSED 4 */
2138
+ int
2139
+ dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
2140
+ Dwarf_Off * cie_off, Dwarf_Error * err)
2141
+ {
2142
+ char *start = 0;
2143
+ char *loc = 0;
2144
+
2145
+ start = (char *) in_cie->ci_section_ptr;
2146
+ loc = (char *) in_cie->ci_cie_start;
2147
+
2148
+ *cie_off = (loc - start);
2149
+ return DW_DLV_OK;
2150
+ }
2151
+
2152
+ /* Returns a pointer to target-specific augmentation data thru augdata
2153
+ and returns the length of the data thru augdata_len.
2154
+
2155
+ It's up to the consumer code to know how to interpret the bytes
2156
+ of target-specific data (endian issues apply too, these
2157
+ are just raw bytes pointed to).
2158
+ See Linux Standard Base Core Specification version 3.0 for
2159
+ the details on .eh_frame info.
2160
+
2161
+ Returns DW_DLV_ERROR if fde is NULL or some other serious
2162
+ error.
2163
+ Returns DW_DLV_NO_ENTRY if there is no target-specific
2164
+ augmentation data.
2165
+
2166
+ The bytes pointed to are in the Dwarf_Cie, and as long as that
2167
+ is valid the bytes are there. No 'dealloc' call is needed
2168
+ for the bytes. */
2169
+ int
2170
+ dwarf_get_cie_augmentation_data(Dwarf_Cie cie,
2171
+ Dwarf_Small ** augdata,
2172
+ Dwarf_Unsigned * augdata_len,
2173
+ Dwarf_Error * error)
2174
+ {
2175
+ if (cie == NULL) {
2176
+ _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
2177
+ return (DW_DLV_ERROR);
2178
+ }
2179
+ if (cie->ci_gnu_eh_augmentation_len == 0) {
2180
+ return DW_DLV_NO_ENTRY;
2181
+ }
2182
+ *augdata = (Dwarf_Small *) (cie->ci_gnu_eh_augmentation_bytes);
2183
+ *augdata_len = cie->ci_gnu_eh_augmentation_len;
2184
+ return DW_DLV_OK;
2185
+ }
2186
+
2187
+
2188
+ /* Returns a pointer to target-specific augmentation data thru augdata
2189
+ and returns the length of the data thru augdata_len.
2190
+
2191
+ It's up to the consumer code to know how to interpret the bytes
2192
+ of target-specific data (endian issues apply too, these
2193
+ are just raw bytes pointed to).
2194
+ See Linux Standard Base Core Specification version 3.0 for
2195
+ the details on .eh_frame info.
2196
+
2197
+ Returns DW_DLV_ERROR if fde is NULL or some other serious
2198
+ error.
2199
+ Returns DW_DLV_NO_ENTRY if there is no target-specific
2200
+ augmentation data.
2201
+
2202
+ The bytes pointed to are in the Dwarf_Fde, and as long as that
2203
+ is valid the bytes are there. No 'dealloc' call is needed
2204
+ for the bytes. */
2205
+ int
2206
+ dwarf_get_fde_augmentation_data(Dwarf_Fde fde,
2207
+ Dwarf_Small * *augdata,
2208
+ Dwarf_Unsigned * augdata_len,
2209
+ Dwarf_Error * error)
2210
+ {
2211
+ Dwarf_Cie cie = 0;
2212
+
2213
+ if (fde == NULL) {
2214
+ _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
2215
+ return (DW_DLV_ERROR);
2216
+ }
2217
+ cie = fde->fd_cie;
2218
+ if (cie == NULL) {
2219
+ _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
2220
+ return (DW_DLV_ERROR);
2221
+ }
2222
+ if (cie->ci_gnu_eh_augmentation_len == 0) {
2223
+ return DW_DLV_NO_ENTRY;
2224
+ }
2225
+ *augdata = (Dwarf_Small *) fde->fd_gnu_eh_augmentation_bytes;
2226
+ *augdata_len = fde->fd_gnu_eh_augmentation_len;
2227
+ return DW_DLV_OK;
2228
+ }
2229
+
2230
+
2231
+ #if 0 /* FOR DEBUGGING */
2232
+ /* Used solely for debugging libdwarf. */
2233
+ static void
2234
+ dump_frame_rule(char *msg, struct Dwarf_Reg_Rule_s *reg_rule)
2235
+ {
2236
+ printf
2237
+ ("%s type %s (0x%" DW_PR_XZEROS DW_PR_DUx
2238
+ "), is_off %" DW_PR_DUu
2239
+ " reg %" DW_PR_DUu " offset 0x%" DW_PR_XZEROS DW_PR_DUx
2240
+ " blockp 0x%" DW_PR_XZEROS DW_PR_DUx "\n",
2241
+ msg,
2242
+ (reg_rule->ru_value_type == DW_EXPR_OFFSET) ?
2243
+ "DW_EXPR_OFFSET" :
2244
+ (reg_rule->ru_value_type == DW_EXPR_VAL_OFFSET) ?
2245
+ "DW_EXPR_VAL_OFFSET" :
2246
+ (reg_rule->ru_value_type == DW_EXPR_VAL_EXPRESSION) ?
2247
+ "DW_EXPR_VAL_EXPRESSION" :
2248
+ (reg_rule->ru_value_type == DW_EXPR_EXPRESSION) ?
2249
+ "DW_EXPR_EXPRESSION" : "Unknown",
2250
+ (Dwarf_Unsigned) reg_rule->ru_value_type,
2251
+ (Dwarf_Unsigned) reg_rule->ru_is_off,
2252
+ (Dwarf_Unsigned) reg_rule->ru_register,
2253
+ (Dwarf_Unsigned) reg_rule->ru_offset_or_block_len,
2254
+ (Dwarf_Unsigned) reg_rule->ru_block);
2255
+ return;
2256
+ }
2257
+ #endif
2258
+
2259
+ /* This allows consumers to set the 'initial value' so that
2260
+ an ISA/ABI specific default can be used, dynamically,
2261
+ at run time. Useful for dwarfdump and non-MIPS architectures..
2262
+ The value defaults to one of
2263
+ DW_FRAME_SAME_VALUE or DW_FRAME_UNKNOWN_VALUE
2264
+ but dwarfdump can dump multiple ISA/ABI objects so
2265
+ we may want to get this set to what the ABI says is correct.
2266
+
2267
+ Returns the value that was present before we changed it here. */
2268
+ Dwarf_Half
2269
+ dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg, Dwarf_Half value)
2270
+ {
2271
+ Dwarf_Half orig = dbg->de_frame_rule_initial_value;
2272
+ dbg->de_frame_rule_initial_value = value;
2273
+ return orig;
2274
+ }
2275
+
2276
+ /* The following spelling for backwards compatibility. */
2277
+ Dwarf_Half
2278
+ dwarf_set_frame_rule_inital_value(Dwarf_Debug dbg, Dwarf_Half value)
2279
+ {
2280
+ return dwarf_set_frame_rule_initial_value(dbg,value);
2281
+ }
2282
+
2283
+ /* This allows consumers to set the array size of the reg rules
2284
+ table so that
2285
+ an ISA/ABI specific value can be used, dynamically,
2286
+ at run time. Useful for non-MIPS archtectures.
2287
+ The value defaults to DW_FRAME_LAST_REG_NUM.
2288
+ but dwarfdump can dump multiple ISA/ABI objects so
2289
+ consumers want to get this set to what the ABI says is correct.
2290
+
2291
+ Returns the value that was present before we changed it here.
2292
+ */
2293
+
2294
+ Dwarf_Half
2295
+ dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value)
2296
+ {
2297
+ Dwarf_Half orig = dbg->de_frame_reg_rules_entry_count;
2298
+ dbg->de_frame_reg_rules_entry_count = value;
2299
+
2300
+ /* Take the caller-specified value, but do not
2301
+ let the value be too small. Keep it at least to
2302
+ DW_FRAME_LAST_REG_NUM.
2303
+ This helps prevent libdwarf (mistakenly) indexing outside
2304
+ of of a register array when the ABI reg count is really small. */
2305
+ if (value < DW_FRAME_LAST_REG_NUM) {
2306
+ dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM;
2307
+ }
2308
+ return orig;
2309
+ }
2310
+ /* This allows consumers to set the CFA register value
2311
+ so that an ISA/ABI specific value can be used, dynamically,
2312
+ at run time. Useful for non-MIPS archtectures.
2313
+ The value defaults to DW_FRAME_CFA_COL3 and should be
2314
+ higher than any real register in the ABI.
2315
+ Dwarfdump can dump multiple ISA/ABI objects so
2316
+ consumers want to get this set to what the ABI says is correct.
2317
+
2318
+ Returns the value that was present before we changed it here. */
2319
+
2320
+ Dwarf_Half
2321
+ dwarf_set_frame_cfa_value(Dwarf_Debug dbg, Dwarf_Half value)
2322
+ {
2323
+ Dwarf_Half orig = dbg->de_frame_cfa_col_number;
2324
+ dbg->de_frame_cfa_col_number = value;
2325
+ return orig;
2326
+ }
2327
+ /* Similar to above, but for the other crucial fields for frames. */
2328
+ Dwarf_Half
2329
+ dwarf_set_frame_same_value(Dwarf_Debug dbg, Dwarf_Half value)
2330
+ {
2331
+ Dwarf_Half orig = dbg->de_frame_same_value_number;
2332
+ dbg->de_frame_same_value_number = value;
2333
+ return orig;
2334
+ }
2335
+ Dwarf_Half
2336
+ dwarf_set_frame_undefined_value(Dwarf_Debug dbg, Dwarf_Half value)
2337
+ {
2338
+ Dwarf_Half orig = dbg->de_frame_same_value_number;
2339
+ dbg->de_frame_undefined_value_number = value;
2340
+ return orig;
2341
+ }
2342
+
2343
+ /* Does something only if value passed in is greater than 0 and
2344
+ a size than we can handle (in number of bytes). */
2345
+ Dwarf_Small dwarf_set_default_address_size(Dwarf_Debug dbg,
2346
+ Dwarf_Small value )
2347
+ {
2348
+ Dwarf_Small orig = dbg->de_pointer_size;
2349
+ if (value > 0 && value <= sizeof(Dwarf_Addr)) {
2350
+ dbg->de_pointer_size = value;
2351
+ }
2352
+ return orig;
2353
+ }
2354
+
2355
+ static int
2356
+ init_reg_rules_alloc(Dwarf_Debug dbg,struct Dwarf_Frame_s *f,
2357
+ unsigned count, Dwarf_Error * error)
2358
+ {
2359
+ f->fr_reg_count = count;
2360
+ f->fr_reg = (struct Dwarf_Reg_Rule_s *)
2361
+ calloc(sizeof(struct Dwarf_Reg_Rule_s), count);
2362
+ if (f->fr_reg == 0) {
2363
+ if (error) {
2364
+ _dwarf_error(dbg, error, DW_DLE_DF_ALLOC_FAIL);
2365
+ }
2366
+ return (DW_DLV_ERROR);
2367
+ }
2368
+ dwarf_init_reg_rules_ru(f->fr_reg,0, count,
2369
+ dbg->de_frame_rule_initial_value);
2370
+ return DW_DLV_OK;
2371
+ }
2372
+ static int
2373
+ dwarf_initialize_fde_table(Dwarf_Debug dbg,
2374
+ struct Dwarf_Frame_s *fde_table,
2375
+ unsigned table_real_data_size,
2376
+ Dwarf_Error * error)
2377
+ {
2378
+ unsigned entry_size = sizeof(struct Dwarf_Frame_s);
2379
+ memset(fde_table,0,entry_size);
2380
+ fde_table->fr_loc = 0;
2381
+ fde_table->fr_next = 0;
2382
+
2383
+ return init_reg_rules_alloc(dbg,fde_table,table_real_data_size,error);
2384
+ }
2385
+ static void
2386
+ dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table)
2387
+ {
2388
+ free(fde_table->fr_reg);
2389
+ fde_table->fr_reg_count = 0;
2390
+ fde_table->fr_reg = 0;
2391
+ }
2392
+
2393
+
2394
+ /* Return DW_DLV_OK if we succeed. else return DW_DLV_ERROR.
2395
+ */
2396
+ int
2397
+ _dwarf_frame_constructor(Dwarf_Debug dbg, void *frame)
2398
+ {
2399
+ struct Dwarf_Frame_s *fp = frame;
2400
+
2401
+ if (!dbg) {
2402
+ return DW_DLV_ERROR;
2403
+ }
2404
+ return init_reg_rules_alloc(dbg,fp,dbg->de_frame_reg_rules_entry_count, 0);
2405
+ }
2406
+
2407
+ void
2408
+ _dwarf_frame_destructor(void *frame)
2409
+ {
2410
+ struct Dwarf_Frame_s *fp = frame;
2411
+ dwarf_free_fde_table(fp);
2412
+ }
2413
+
2414
+ static void
2415
+ dwarf_init_reg_rules_ru(struct Dwarf_Reg_Rule_s *base,
2416
+ unsigned first, unsigned last,int initial_value)
2417
+ {
2418
+ struct Dwarf_Reg_Rule_s *r = base+first;
2419
+ unsigned i = first;
2420
+ for (; i < last; ++i,++r) {
2421
+ r->ru_is_off = 0;
2422
+ r->ru_value_type = DW_EXPR_OFFSET;
2423
+ r->ru_register = initial_value;
2424
+ r->ru_offset_or_block_len = 0;
2425
+ r->ru_block = 0;
2426
+ }
2427
+ }
2428
+ static void
2429
+ dwarf_init_reg_rules_dw(struct Dwarf_Regtable_Entry_s *base,
2430
+ unsigned first, unsigned last,int initial_value)
2431
+ {
2432
+ struct Dwarf_Regtable_Entry_s *r = base+first;
2433
+ unsigned i = first;
2434
+ for (; i < last; ++i,++r) {
2435
+ r->dw_offset_relevant = 0;
2436
+ r->dw_value_type = DW_EXPR_OFFSET;
2437
+ r->dw_regnum = initial_value;
2438
+ r->dw_offset = 0;
2439
+ }
2440
+ }
2441
+ static void
2442
+ dwarf_init_reg_rules_dw3(struct Dwarf_Regtable_Entry3_s *base,
2443
+ unsigned first, unsigned last,int initial_value)
2444
+ {
2445
+ struct Dwarf_Regtable_Entry3_s *r = base+first;
2446
+ unsigned i = first;
2447
+ for (; i < last; ++i,++r) {
2448
+ r->dw_offset_relevant = 0;
2449
+ r->dw_value_type = DW_EXPR_OFFSET;
2450
+ r->dw_regnum = initial_value;
2451
+ r->dw_offset_or_block_len = 0;
2452
+ r->dw_block_ptr = 0;
2453
+ }
2454
+ }