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,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
+ }