1
2 /*--------------------------------------------------------------------*/
3 /*--- Basic definitions and helper functions for DWARF3. ---*/
4 /*--- d3basics.c ---*/
5 /*--------------------------------------------------------------------*/
6
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright (C) 2008-2011 OpenWorks LLP
12 info@open-works.co.uk
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30
31 Neither the names of the U.S. Department of Energy nor the
32 University of California nor the names of its contributors may be
33 used to endorse or promote products derived from this software
34 without prior written permission.
35 */
36
37 #include "pub_core_basics.h"
38 #include "pub_core_debuginfo.h"
39 #include "pub_core_libcassert.h"
40 #include "pub_core_libcprint.h"
41 #include "pub_core_options.h"
42 #include "pub_core_xarray.h"
43
44 #include "pub_core_vki.h" /* VKI_PROT_READ */
45 #include "pub_core_aspacemgr.h" /* VG_(is_valid_for_client) */
46
47 #include "priv_misc.h"
48 #include "priv_d3basics.h" /* self */
49 #include "priv_storage.h"
50
ML_(pp_DW_children)51 HChar* ML_(pp_DW_children) ( DW_children hashch )
52 {
53 switch (hashch) {
54 case DW_children_no: return "no children";
55 case DW_children_yes: return "has children";
56 default: return "DW_children_???";
57 }
58 }
59
ML_(pp_DW_TAG)60 HChar* ML_(pp_DW_TAG) ( DW_TAG tag )
61 {
62 switch (tag) {
63 case DW_TAG_padding: return "DW_TAG_padding";
64 case DW_TAG_array_type: return "DW_TAG_array_type";
65 case DW_TAG_class_type: return "DW_TAG_class_type";
66 case DW_TAG_entry_point: return "DW_TAG_entry_point";
67 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
68 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
69 case DW_TAG_imported_declaration:
70 return "DW_TAG_imported_declaration";
71 case DW_TAG_label: return "DW_TAG_label";
72 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
73 case DW_TAG_member: return "DW_TAG_member";
74 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
75 case DW_TAG_reference_type: return "DW_TAG_reference_type";
76 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
77 case DW_TAG_string_type: return "DW_TAG_string_type";
78 case DW_TAG_structure_type: return "DW_TAG_structure_type";
79 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
80 case DW_TAG_typedef: return "DW_TAG_typedef";
81 case DW_TAG_union_type: return "DW_TAG_union_type";
82 case DW_TAG_unspecified_parameters:
83 return "DW_TAG_unspecified_parameters";
84 case DW_TAG_variant: return "DW_TAG_variant";
85 case DW_TAG_common_block: return "DW_TAG_common_block";
86 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
87 case DW_TAG_inheritance: return "DW_TAG_inheritance";
88 case DW_TAG_inlined_subroutine:
89 return "DW_TAG_inlined_subroutine";
90 case DW_TAG_module: return "DW_TAG_module";
91 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
92 case DW_TAG_set_type: return "DW_TAG_set_type";
93 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
94 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
95 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
96 case DW_TAG_base_type: return "DW_TAG_base_type";
97 case DW_TAG_catch_block: return "DW_TAG_catch_block";
98 case DW_TAG_const_type: return "DW_TAG_const_type";
99 case DW_TAG_constant: return "DW_TAG_constant";
100 case DW_TAG_enumerator: return "DW_TAG_enumerator";
101 case DW_TAG_file_type: return "DW_TAG_file_type";
102 case DW_TAG_friend: return "DW_TAG_friend";
103 case DW_TAG_namelist: return "DW_TAG_namelist";
104 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
105 case DW_TAG_packed_type: return "DW_TAG_packed_type";
106 case DW_TAG_subprogram: return "DW_TAG_subprogram";
107 case DW_TAG_template_type_param:
108 return "DW_TAG_template_type_param";
109 case DW_TAG_template_value_param:
110 return "DW_TAG_template_value_param";
111 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
112 case DW_TAG_try_block: return "DW_TAG_try_block";
113 case DW_TAG_variant_part: return "DW_TAG_variant_part";
114 case DW_TAG_variable: return "DW_TAG_variable";
115 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
116 /* DWARF 3. */
117 case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure";
118 case DW_TAG_restrict_type: return "DW_TAG_restrict_type";
119 case DW_TAG_interface_type: return "DW_TAG_interface_type";
120 case DW_TAG_namespace: return "DW_TAG_namespace";
121 case DW_TAG_imported_module: return "DW_TAG_imported_module";
122 case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type";
123 case DW_TAG_partial_unit: return "DW_TAG_partial_unit";
124 case DW_TAG_imported_unit: return "DW_TAG_imported_unit";
125 case DW_TAG_condition: return "DW_TAG_condition";
126 case DW_TAG_shared_type: return "DW_TAG_shared_type";
127 /* DWARF 4. */
128 case DW_TAG_type_unit: return "DW_TAG_type_unit";
129 case DW_TAG_rvalue_reference_type: return "DW_TAG_rvalue_reference_type";
130 case DW_TAG_template_alias: return "DW_TAG_template_alias";
131 /* SGI/MIPS Extensions. */
132 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
133 /* HP extensions. See:
134 ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz . */
135 case DW_TAG_HP_array_descriptor:
136 return "DW_TAG_HP_array_descriptor";
137 /* GNU extensions. */
138 case DW_TAG_format_label: return "DW_TAG_format_label";
139 case DW_TAG_function_template: return "DW_TAG_function_template";
140 case DW_TAG_class_template: return "DW_TAG_class_template";
141 case DW_TAG_GNU_BINCL: return "DW_TAG_GNU_BINCL";
142 case DW_TAG_GNU_EINCL: return "DW_TAG_GNU_EINCL";
143 /* Extensions for UPC. See: http://upc.gwu.edu/~upc. */
144 case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type";
145 case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type";
146 case DW_TAG_upc_relaxed_type: return "DW_TAG_upc_relaxed_type";
147 /* PGI (STMicroelectronics) extensions. No documentation available. */
148 case DW_TAG_PGI_kanji_type: return "DW_TAG_PGI_kanji_type";
149 case DW_TAG_PGI_interface_block:
150 return "DW_TAG_PGI_interface_block";
151 default: return "DW_TAG_???";
152 }
153 }
154
ML_(pp_DW_FORM)155 HChar* ML_(pp_DW_FORM) ( DW_FORM form )
156 {
157 switch (form) {
158 case DW_FORM_addr: return "DW_FORM_addr";
159 case DW_FORM_block2: return "DW_FORM_block2";
160 case DW_FORM_block4: return "DW_FORM_block4";
161 case DW_FORM_data2: return "DW_FORM_data2";
162 case DW_FORM_data4: return "DW_FORM_data4";
163 case DW_FORM_data8: return "DW_FORM_data8";
164 case DW_FORM_string: return "DW_FORM_string";
165 case DW_FORM_block: return "DW_FORM_block";
166 case DW_FORM_block1: return "DW_FORM_block1";
167 case DW_FORM_data1: return "DW_FORM_data1";
168 case DW_FORM_flag: return "DW_FORM_flag";
169 case DW_FORM_sdata: return "DW_FORM_sdata";
170 case DW_FORM_strp: return "DW_FORM_strp";
171 case DW_FORM_udata: return "DW_FORM_udata";
172 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
173 case DW_FORM_ref1: return "DW_FORM_ref1";
174 case DW_FORM_ref2: return "DW_FORM_ref2";
175 case DW_FORM_ref4: return "DW_FORM_ref4";
176 case DW_FORM_ref8: return "DW_FORM_ref8";
177 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
178 case DW_FORM_indirect: return "DW_FORM_indirect";
179 case DW_FORM_sec_offset:return "DW_FORM_sec_offset";
180 case DW_FORM_exprloc: return "DW_FORM_exprloc";
181 case DW_FORM_flag_present:return "DW_FORM_flag_present";
182 case DW_FORM_ref_sig8: return "DW_FORM_ref_sig8";
183 default: return "DW_FORM_???";
184 }
185 }
186
ML_(pp_DW_AT)187 HChar* ML_(pp_DW_AT) ( DW_AT attr )
188 {
189 switch (attr) {
190 case DW_AT_sibling: return "DW_AT_sibling";
191 case DW_AT_location: return "DW_AT_location";
192 case DW_AT_name: return "DW_AT_name";
193 case DW_AT_ordering: return "DW_AT_ordering";
194 case DW_AT_subscr_data: return "DW_AT_subscr_data";
195 case DW_AT_byte_size: return "DW_AT_byte_size";
196 case DW_AT_bit_offset: return "DW_AT_bit_offset";
197 case DW_AT_bit_size: return "DW_AT_bit_size";
198 case DW_AT_element_list: return "DW_AT_element_list";
199 case DW_AT_stmt_list: return "DW_AT_stmt_list";
200 case DW_AT_low_pc: return "DW_AT_low_pc";
201 case DW_AT_high_pc: return "DW_AT_high_pc";
202 case DW_AT_language: return "DW_AT_language";
203 case DW_AT_member: return "DW_AT_member";
204 case DW_AT_discr: return "DW_AT_discr";
205 case DW_AT_discr_value: return "DW_AT_discr_value";
206 case DW_AT_visibility: return "DW_AT_visibility";
207 case DW_AT_import: return "DW_AT_import";
208 case DW_AT_string_length: return "DW_AT_string_length";
209 case DW_AT_common_reference: return "DW_AT_common_reference";
210 case DW_AT_comp_dir: return "DW_AT_comp_dir";
211 case DW_AT_const_value: return "DW_AT_const_value";
212 case DW_AT_containing_type: return "DW_AT_containing_type";
213 case DW_AT_default_value: return "DW_AT_default_value";
214 case DW_AT_inline: return "DW_AT_inline";
215 case DW_AT_is_optional: return "DW_AT_is_optional";
216 case DW_AT_lower_bound: return "DW_AT_lower_bound";
217 case DW_AT_producer: return "DW_AT_producer";
218 case DW_AT_prototyped: return "DW_AT_prototyped";
219 case DW_AT_return_addr: return "DW_AT_return_addr";
220 case DW_AT_start_scope: return "DW_AT_start_scope";
221 case DW_AT_stride_size: return "DW_AT_stride_size";
222 case DW_AT_upper_bound: return "DW_AT_upper_bound";
223 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
224 case DW_AT_accessibility: return "DW_AT_accessibility";
225 case DW_AT_address_class: return "DW_AT_address_class";
226 case DW_AT_artificial: return "DW_AT_artificial";
227 case DW_AT_base_types: return "DW_AT_base_types";
228 case DW_AT_calling_convention: return "DW_AT_calling_convention";
229 case DW_AT_count: return "DW_AT_count";
230 case DW_AT_data_member_location: return "DW_AT_data_member_location";
231 case DW_AT_decl_column: return "DW_AT_decl_column";
232 case DW_AT_decl_file: return "DW_AT_decl_file";
233 case DW_AT_decl_line: return "DW_AT_decl_line";
234 case DW_AT_declaration: return "DW_AT_declaration";
235 case DW_AT_discr_list: return "DW_AT_discr_list";
236 case DW_AT_encoding: return "DW_AT_encoding";
237 case DW_AT_external: return "DW_AT_external";
238 case DW_AT_frame_base: return "DW_AT_frame_base";
239 case DW_AT_friend: return "DW_AT_friend";
240 case DW_AT_identifier_case: return "DW_AT_identifier_case";
241 case DW_AT_macro_info: return "DW_AT_macro_info";
242 case DW_AT_namelist_items: return "DW_AT_namelist_items";
243 case DW_AT_priority: return "DW_AT_priority";
244 case DW_AT_segment: return "DW_AT_segment";
245 case DW_AT_specification: return "DW_AT_specification";
246 case DW_AT_static_link: return "DW_AT_static_link";
247 case DW_AT_type: return "DW_AT_type";
248 case DW_AT_use_location: return "DW_AT_use_location";
249 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
250 case DW_AT_virtuality: return "DW_AT_virtuality";
251 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
252 /* DWARF 3 values. */
253 case DW_AT_allocated: return "DW_AT_allocated";
254 case DW_AT_associated: return "DW_AT_associated";
255 case DW_AT_data_location: return "DW_AT_data_location";
256 case DW_AT_stride: return "DW_AT_stride";
257 case DW_AT_entry_pc: return "DW_AT_entry_pc";
258 case DW_AT_use_UTF8: return "DW_AT_use_UTF8";
259 case DW_AT_extension: return "DW_AT_extension";
260 case DW_AT_ranges: return "DW_AT_ranges";
261 case DW_AT_trampoline: return "DW_AT_trampoline";
262 case DW_AT_call_column: return "DW_AT_call_column";
263 case DW_AT_call_file: return "DW_AT_call_file";
264 case DW_AT_call_line: return "DW_AT_call_line";
265 case DW_AT_description: return "DW_AT_description";
266 case DW_AT_binary_scale: return "DW_AT_binary_scale";
267 case DW_AT_decimal_scale: return "DW_AT_decimal_scale";
268 case DW_AT_small: return "DW_AT_small";
269 case DW_AT_decimal_sign: return "DW_AT_decimal_sign";
270 case DW_AT_digit_count: return "DW_AT_digit_count";
271 case DW_AT_picture_string: return "DW_AT_picture_string";
272 case DW_AT_mutable: return "DW_AT_mutable";
273 case DW_AT_threads_scaled: return "DW_AT_threads_scaled";
274 case DW_AT_explicit: return "DW_AT_explicit";
275 case DW_AT_object_pointer: return "DW_AT_object_pointer";
276 case DW_AT_endianity: return "DW_AT_endianity";
277 case DW_AT_elemental: return "DW_AT_elemental";
278 case DW_AT_pure: return "DW_AT_pure";
279 case DW_AT_recursive: return "DW_AT_recursive";
280 /* DWARF 4 values. */
281 case DW_AT_signature: return "DW_AT_signature";
282 case DW_AT_main_subprogram: return "DW_AT_main_subprogram";
283 case DW_AT_data_bit_offset: return "DW_AT_data_bit_offset";
284 case DW_AT_const_expr: return "DW_AT_const_expr";
285 case DW_AT_enum_class: return "DW_AT_enum_class";
286 case DW_AT_linkage_name: return "DW_AT_linkage_name";
287 /* SGI/MIPS extensions. */
288 /* case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde"; */
289 /* DW_AT_MIPS_fde == DW_AT_HP_unmodifiable */
290 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
291 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
292 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
293 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
294 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
295 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
296 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
297 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
298 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
299 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
300 /* HP extensions. */
301 case DW_AT_HP_block_index: return "DW_AT_HP_block_index";
302 case DW_AT_HP_unmodifiable: return "DW_AT_HP_unmodifiable";
303 case DW_AT_HP_actuals_stmt_list: return "DW_AT_HP_actuals_stmt_list";
304 case DW_AT_HP_proc_per_section: return "DW_AT_HP_proc_per_section";
305 case DW_AT_HP_raw_data_ptr: return "DW_AT_HP_raw_data_ptr";
306 case DW_AT_HP_pass_by_reference: return "DW_AT_HP_pass_by_reference";
307 case DW_AT_HP_opt_level: return "DW_AT_HP_opt_level";
308 case DW_AT_HP_prof_version_id: return "DW_AT_HP_prof_version_id";
309 case DW_AT_HP_opt_flags: return "DW_AT_HP_opt_flags";
310 case DW_AT_HP_cold_region_low_pc: return "DW_AT_HP_cold_region_low_pc";
311 case DW_AT_HP_cold_region_high_pc: return "DW_AT_HP_cold_region_high_pc";
312 case DW_AT_HP_all_variables_modifiable: return "DW_AT_HP_all_variables_modifiable";
313 case DW_AT_HP_linkage_name: return "DW_AT_HP_linkage_name";
314 case DW_AT_HP_prof_flags: return "DW_AT_HP_prof_flags";
315 /* GNU extensions. */
316 case DW_AT_sf_names: return "DW_AT_sf_names";
317 case DW_AT_src_info: return "DW_AT_src_info";
318 case DW_AT_mac_info: return "DW_AT_mac_info";
319 case DW_AT_src_coords: return "DW_AT_src_coords";
320 case DW_AT_body_begin: return "DW_AT_body_begin";
321 case DW_AT_body_end: return "DW_AT_body_end";
322 case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
323 /* VMS extensions. */
324 case DW_AT_VMS_rtnbeg_pd_address: return "DW_AT_VMS_rtnbeg_pd_address";
325 /* UPC extension. */
326 case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled";
327 /* PGI (STMicroelectronics) extensions. */
328 case DW_AT_PGI_lbase: return "DW_AT_PGI_lbase";
329 case DW_AT_PGI_soffset: return "DW_AT_PGI_soffset";
330 case DW_AT_PGI_lstride: return "DW_AT_PGI_lstride";
331 default: return "DW_AT_???";
332 }
333 }
334
335
336 /* ------ To do with evaluation of Dwarf expressions ------ */
337
338 /* FIXME: duplicated in readdwarf.c */
339 static
read_leb128(UChar * data,Int * length_return,Int sign)340 ULong read_leb128 ( UChar* data, Int* length_return, Int sign )
341 {
342 ULong result = 0;
343 UInt num_read = 0;
344 Int shift = 0;
345 UChar byte;
346
347 vg_assert(sign == 0 || sign == 1);
348
349 do
350 {
351 byte = * data ++;
352 num_read ++;
353
354 result |= ((ULong)(byte & 0x7f)) << shift;
355
356 shift += 7;
357
358 }
359 while (byte & 0x80);
360
361 if (length_return != NULL)
362 * length_return = num_read;
363
364 if (sign && (shift < 64) && (byte & 0x40))
365 result |= -(1ULL << shift);
366
367 return result;
368 }
369
370 /* Small helper functions easier to use
371 * value is returned and the given pointer is
372 * moved past end of leb128 data */
373 /* FIXME: duplicated in readdwarf.c */
read_leb128U(UChar ** data)374 static ULong read_leb128U( UChar **data )
375 {
376 Int len;
377 ULong val = read_leb128( *data, &len, 0 );
378 *data += len;
379 return val;
380 }
381
382 /* Same for signed data */
383 /* FIXME: duplicated in readdwarf.c */
read_leb128S(UChar ** data)384 static Long read_leb128S( UChar **data )
385 {
386 Int len;
387 ULong val = read_leb128( *data, &len, 1 );
388 *data += len;
389 return (Long)val;
390 }
391
392 /* FIXME: duplicates logic in readdwarf.c: copy_convert_CfiExpr_tree
393 and {FP,SP}_REG decls */
get_Dwarf_Reg(Addr * a,Word regno,RegSummary * regs)394 static Bool get_Dwarf_Reg( /*OUT*/Addr* a, Word regno, RegSummary* regs )
395 {
396 vg_assert(regs);
397 # if defined(VGP_x86_linux) || defined(VGP_x86_darwin)
398 if (regno == 5/*EBP*/) { *a = regs->fp; return True; }
399 if (regno == 4/*ESP*/) { *a = regs->sp; return True; }
400 # elif defined(VGP_amd64_linux) || defined(VGP_amd64_darwin)
401 if (regno == 6/*RBP*/) { *a = regs->fp; return True; }
402 if (regno == 7/*RSP*/) { *a = regs->sp; return True; }
403 # elif defined(VGP_ppc32_linux)
404 if (regno == 1/*SP*/) { *a = regs->sp; return True; }
405 # elif defined(VGP_ppc64_linux)
406 if (regno == 1/*SP*/) { *a = regs->sp; return True; }
407 # elif defined(VGP_arm_linux)
408 if (regno == 13) { *a = regs->sp; return True; }
409 if (regno == 11) { *a = regs->fp; return True; }
410 # elif defined(VGP_s390x_linux)
411 if (regno == 15) { *a = regs->sp; return True; }
412 if (regno == 11) { *a = regs->fp; return True; }
413 # else
414 # error "Unknown platform"
415 # endif
416 return False;
417 }
418
419 /* Convert a stated address to an actual address */
bias_address(Addr * a,const DebugInfo * di)420 static Bool bias_address( Addr* a, const DebugInfo* di )
421 {
422 if (di->text_present
423 && di->text_size > 0
424 && *a >= di->text_debug_svma && *a < di->text_debug_svma + di->text_size) {
425 *a += di->text_debug_bias;
426 }
427 else if (di->data_present
428 && di->data_size > 0
429 && *a >= di->data_debug_svma && *a < di->data_debug_svma + di->data_size) {
430 *a += di->data_debug_bias;
431 }
432 else if (di->sdata_present
433 && di->sdata_size > 0
434 && *a >= di->sdata_debug_svma && *a < di->sdata_debug_svma + di->sdata_size) {
435 *a += di->sdata_debug_bias;
436 }
437 else if (di->rodata_present
438 && di->rodata_size > 0
439 && *a >= di->rodata_debug_svma && *a < di->rodata_debug_svma + di->rodata_size) {
440 *a += di->rodata_debug_bias;
441 }
442 else if (di->bss_present
443 && di->bss_size > 0
444 && *a >= di->bss_debug_svma && *a < di->bss_debug_svma + di->bss_size) {
445 *a += di->bss_debug_bias;
446 }
447 else if (di->sbss_present
448 && di->sbss_size > 0
449 && *a >= di->sbss_debug_svma && *a < di->sbss_debug_svma + di->sbss_size) {
450 *a += di->sbss_debug_bias;
451 }
452 else {
453 return False;
454 }
455
456 return True;
457 }
458
459
460 /* Evaluate a standard DWARF3 expression. See detailed description in
461 priv_d3basics.h. Doesn't handle DW_OP_piece/DW_OP_bit_piece yet. */
ML_(evaluate_Dwarf3_Expr)462 GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB,
463 GExpr* fbGX, RegSummary* regs,
464 const DebugInfo* di,
465 Bool push_initial_zero )
466 {
467 # define N_EXPR_STACK 20
468
469 # define FAIL(_str) \
470 do { \
471 res.kind = GXR_Failure; \
472 res.word = (UWord)(_str); \
473 return res; \
474 } while (0)
475
476 # define PUSH(_arg) \
477 do { \
478 vg_assert(sp >= -1 && sp < N_EXPR_STACK); \
479 if (sp == N_EXPR_STACK-1) \
480 FAIL("evaluate_Dwarf3_Expr: stack overflow(1)"); \
481 sp++; \
482 stack[sp] = (_arg); \
483 } while (0)
484
485 # define POP(_lval) \
486 do { \
487 vg_assert(sp >= -1 && sp < N_EXPR_STACK); \
488 if (sp == -1) \
489 FAIL("evaluate_Dwarf3_Expr: stack underflow(1)"); \
490 _lval = stack[sp]; \
491 sp--; \
492 } while (0)
493
494 UChar opcode;
495 UChar* limit;
496 Int sp; /* # of top element: valid is -1 .. N_EXPR_STACK-1 */
497 Addr stack[N_EXPR_STACK]; /* stack of addresses, as per D3 spec */
498 GXResult fbval, res;
499 Addr a1;
500 Word sw1, sw2;
501 UWord uw1, uw2;
502 Bool ok;
503
504 sp = -1;
505 vg_assert(expr);
506 vg_assert(exprszB >= 0);
507 limit = expr + exprszB;
508
509 /* Deal with the case where the entire expression is a single
510 Register Name Operation (D3 spec sec 2.6.1). Then the
511 denotation of the expression as a whole is a register name. */
512 if (exprszB == 1
513 && expr[0] >= DW_OP_reg0 && expr[0] <= DW_OP_reg31) {
514 res.kind = GXR_RegNo;
515 res.word = (UWord)(expr[0] - DW_OP_reg0);
516 return res;
517 }
518 if (exprszB > 1
519 && expr[0] == DW_OP_regx) {
520 /* JRS: 2008Feb20: I believe the following is correct, but would
521 like to see a test case show up before enabling it. */
522 expr++;
523 res.kind = GXR_RegNo;
524 res.word = (UWord)read_leb128U( &expr );
525 if (expr != limit)
526 FAIL("evaluate_Dwarf3_Expr: DW_OP_regx*: invalid expr size");
527 else
528 return res;
529 /*NOTREACHED*/
530 }
531
532 /* Evidently this expression denotes a value, not a register name.
533 So evaluate it accordingly. */
534
535 if (push_initial_zero)
536 PUSH(0);
537
538 while (True) {
539
540 vg_assert(sp >= -1 && sp < N_EXPR_STACK);
541
542 if (expr > limit)
543 /* overrun - something's wrong */
544 FAIL("evaluate_Dwarf3_Expr: ran off end of expr");
545
546 if (expr == limit) {
547 /* end of expr - return expr on the top of stack. */
548 if (sp == -1)
549 /* stack empty. Bad. */
550 FAIL("evaluate_Dwarf3_Expr: stack empty at end of expr");
551 else
552 break;
553 }
554
555 opcode = *expr++;
556 switch (opcode) {
557 case DW_OP_addr:
558 /* Presumably what is given in the Dwarf3 is a SVMA (how
559 could it be otherwise?) So we add the appropriate bias
560 on before pushing the result. */
561 a1 = ML_(read_Addr)(expr);
562 if (bias_address(&a1, di)) {
563 PUSH( a1 );
564 expr += sizeof(Addr);
565 }
566 else {
567 FAIL("evaluate_Dwarf3_Expr: DW_OP_addr with address "
568 "in unknown section");
569 }
570 break;
571 case DW_OP_fbreg:
572 if (!fbGX)
573 FAIL("evaluate_Dwarf3_Expr: DW_OP_fbreg with "
574 "no expr for fbreg present");
575 fbval = ML_(evaluate_GX)(fbGX, NULL, regs, di);
576 /* Convert fbval into something we can use. If we got a
577 Value, no problem. However, as per D3 spec sec 3.3.5
578 (Low Level Information) sec 2, we could also get a
579 RegNo, and that is taken to mean the value in the
580 indicated register. So we have to manually
581 "dereference" it. */
582 a1 = 0;
583 switch (fbval.kind) {
584 case GXR_Failure:
585 return fbval; /* propagate failure */
586 case GXR_Addr:
587 a1 = fbval.word; break; /* use as-is */
588 case GXR_RegNo:
589 ok = get_Dwarf_Reg( &a1, fbval.word, regs );
590 if (!ok) return fbval; /* propagate failure */
591 break;
592 case GXR_Value:
593 FAIL("evaluate_Dwarf3_Expr: DW_OP_{implicit,stack}_value "
594 "in DW_AT_frame_base");
595 default:
596 vg_assert(0);
597 }
598 sw1 = (Word)read_leb128S( &expr );
599 PUSH( a1 + sw1 );
600 break;
601 /* DW_OP_breg* denotes 'contents of specified register, plus
602 constant offset'. So provided we know what the register's
603 value is, we can evaluate this. Contrast DW_OP_reg*,
604 which indicates that denoted location is in a register
605 itself. If DW_OP_reg* shows up here the expression is
606 malformed, since we are evaluating for value now, and
607 DW_OP_reg* denotes a register location, not a value. See
608 D3 Spec sec 2.6.1 ("Register Name Operations") for
609 details. */
610 case DW_OP_breg0 ... DW_OP_breg31:
611 if (!regs)
612 FAIL("evaluate_Dwarf3_Expr: DW_OP_breg* but no reg info");
613 a1 = 0;
614 if (!get_Dwarf_Reg( &a1, opcode - DW_OP_breg0, regs ))
615 FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_breg*");
616 sw1 = (Word)read_leb128S( &expr );
617 a1 += sw1;
618 PUSH( a1 );
619 break;
620 case DW_OP_bregx:
621 if (!regs)
622 FAIL("evaluate_Dwarf3_Expr: DW_OP_bregx but no reg info");
623 a1 = 0;
624 uw1 = (UWord)read_leb128U( &expr );
625 if (!get_Dwarf_Reg( &a1, uw1, regs ))
626 FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_bregx reg value");
627 sw1 = (Word)read_leb128S( &expr );
628 a1 += sw1;
629 PUSH( a1 );
630 break;
631 /* As per comment on DW_OP_breg*, the following denote that
632 the value in question is in a register, not in memory. So
633 we simply return failure. (iow, the expression is
634 malformed). */
635 case DW_OP_reg0 ... DW_OP_reg31:
636 case DW_OP_regx:
637 FAIL("evaluate_Dwarf3_Expr: DW_OP_reg* "
638 "whilst evaluating for a value");
639 break;
640 case DW_OP_plus_uconst:
641 POP(uw1);
642 uw1 += (UWord)read_leb128U( &expr );
643 PUSH(uw1);
644 break;
645 case DW_OP_GNU_push_tls_address:
646 /* GDB contains the following cryptic comment: */
647 /* Variable is at a constant offset in the thread-local
648 storage block into the objfile for the current thread and
649 the dynamic linker module containing this expression. Here
650 we return returns the offset from that base. The top of the
651 stack has the offset from the beginning of the thread
652 control block at which the variable is located. Nothing
653 should follow this operator, so the top of stack would be
654 returned. */
655 /* But no spec resulting from Googling. Punt for now. */
656 FAIL("warning: evaluate_Dwarf3_Expr: unhandled "
657 "DW_OP_GNU_push_tls_address");
658 /*NOTREACHED*/
659 case DW_OP_deref:
660 POP(uw1);
661 if (VG_(am_is_valid_for_client)( (Addr)uw1, sizeof(Addr),
662 VKI_PROT_READ )) {
663 uw1 = ML_(read_UWord)((void *)uw1);
664 PUSH(uw1);
665 } else {
666 FAIL("warning: evaluate_Dwarf3_Expr: DW_OP_deref: "
667 "address not valid for client");
668 }
669 break;
670 case DW_OP_deref_size:
671 POP(uw1);
672 uw2 = *expr++;
673 if (VG_(am_is_valid_for_client)( (Addr)uw1, uw2,
674 VKI_PROT_READ )) {
675 switch (uw2) {
676 case 1: uw1 = ML_(read_UChar)((void*)uw1); break;
677 case 2: uw1 = ML_(read_UShort)((void*)uw1); break;
678 case 4: uw1 = ML_(read_UInt)((void*)uw1); break;
679 case 8: uw1 = ML_(read_ULong)((void*)uw1); break;
680 default:
681 FAIL("warning: evaluate_Dwarf3_Expr: unhandled "
682 "DW_OP_deref_size size");
683 }
684 PUSH(uw1);
685 } else {
686 FAIL("warning: evaluate_Dwarf3_Expr: DW_OP_deref_size: "
687 "address not valid for client");
688 }
689 break;
690 case DW_OP_lit0 ... DW_OP_lit31:
691 PUSH(opcode - DW_OP_lit0);
692 break;
693 case DW_OP_const1u:
694 uw1 = *expr++;
695 PUSH(uw1);
696 break;
697 case DW_OP_const2u:
698 uw1 = ML_(read_UShort)(expr);
699 expr += 2;
700 PUSH(uw1);
701 break;
702 case DW_OP_const4u:
703 uw1 = ML_(read_UInt)(expr);
704 expr += 4;
705 PUSH(uw1);
706 break;
707 case DW_OP_const8u:
708 uw1 = ML_(read_ULong)(expr);
709 expr += 8;
710 PUSH(uw1);
711 break;
712 case DW_OP_constu:
713 uw1 = read_leb128U( &expr );
714 PUSH(uw1);
715 break;
716 case DW_OP_const1s:
717 uw1 = *(Char *)expr;
718 expr++;
719 PUSH(uw1);
720 break;
721 case DW_OP_const2s:
722 uw1 = ML_(read_Short)(expr);
723 expr += 2;
724 PUSH(uw1);
725 break;
726 case DW_OP_const4s:
727 uw1 = ML_(read_Int)(expr);
728 expr += 4;
729 PUSH(uw1);
730 break;
731 case DW_OP_const8s:
732 uw1 = ML_(read_Long)(expr);
733 expr += 8;
734 PUSH(uw1);
735 break;
736 case DW_OP_consts:
737 uw1 = read_leb128S( &expr );
738 PUSH(uw1);
739 break;
740 case DW_OP_dup:
741 POP(uw1);
742 PUSH(uw1);
743 PUSH(uw1);
744 break;
745 case DW_OP_drop:
746 POP(uw1);
747 break;
748 case DW_OP_over:
749 uw1 = 1;
750 goto do_pick;
751 case DW_OP_pick:
752 uw1 = *expr++;
753 do_pick:
754 if (sp < (Int)uw1)
755 FAIL("evaluate_Dwarf3_Expr: stack underflow");
756 uw1 = stack[sp - uw1];
757 PUSH(uw1);
758 break;
759 case DW_OP_swap:
760 if (sp < 1)
761 FAIL("evaluate_Dwarf3_Expr: stack underflow");
762 uw1 = stack[sp];
763 stack[sp] = stack[sp - 1];
764 stack[sp - 1] = uw1;
765 break;
766 case DW_OP_rot:
767 if (sp < 2)
768 FAIL("evaluate_Dwarf3_Expr: stack underflow");
769 uw1 = stack[sp];
770 stack[sp] = stack[sp - 1];
771 stack[sp - 1] = stack[sp - 2];
772 stack[sp - 2] = uw1;
773 break;
774 case DW_OP_abs:
775 POP(sw1);
776 if (sw1 < 0)
777 sw1 = -sw1;
778 PUSH(sw1);
779 break;
780 case DW_OP_div:
781 POP(sw2);
782 if (sw2 == 0)
783 FAIL("evaluate_Dwarf3_Expr: division by zero");
784 POP(sw1);
785 sw1 /= sw2;
786 PUSH(sw1);
787 break;
788 case DW_OP_mod:
789 POP(uw2);
790 if (uw2 == 0)
791 FAIL("evaluate_Dwarf3_Expr: division by zero");
792 POP(uw1);
793 uw1 %= uw2;
794 PUSH(uw1);
795 break;
796 #define BINARY(name, op, s) \
797 case DW_OP_##name: \
798 POP(s##w2); \
799 POP(s##w1); \
800 s##w1 = s##w1 op s##w2; \
801 PUSH(s##w1); \
802 break
803 #define UNARY(name, op, s) \
804 case DW_OP_##name: \
805 POP(s##w1); \
806 s##w1 = op s##w1; \
807 PUSH(s##w1); \
808 break
809 BINARY (and, &, u);
810 BINARY (minus, -, u);
811 BINARY (mul, *, u);
812 UNARY (neg, -, u);
813 UNARY (not, ~, u);
814 BINARY (or, |, u);
815 BINARY (plus, +, u);
816 BINARY (shl, <<, u);
817 BINARY (shr, >>, u);
818 BINARY (shra, >>, s);
819 BINARY (xor, ^, u);
820 BINARY (le, <=, s);
821 BINARY (lt, <, s);
822 BINARY (ge, >=, s);
823 BINARY (gt, >, s);
824 BINARY (ne, !=, u);
825 BINARY (eq, ==, u);
826 #undef UNARY
827 #undef BINARY
828 case DW_OP_skip:
829 sw1 = ML_(read_Short)(expr);
830 expr += 2;
831 if (expr + sw1 < limit - exprszB)
832 FAIL("evaluate_Dwarf3_Expr: DW_OP_skip before start of expr");
833 if (expr + sw1 >= limit)
834 FAIL("evaluate_Dwarf3_Expr: DW_OP_skip after end of expr");
835 expr += sw1;
836 break;
837 case DW_OP_bra:
838 sw1 = ML_(read_Short)(expr);
839 expr += 2;
840 if (expr + sw1 < limit - exprszB)
841 FAIL("evaluate_Dwarf3_Expr: DW_OP_bra before start of expr");
842 if (expr + sw1 >= limit)
843 FAIL("evaluate_Dwarf3_Expr: DW_OP_bra after end of expr");
844 POP(uw1);
845 if (uw1)
846 expr += sw1;
847 break;
848 case DW_OP_nop:
849 break;
850 case DW_OP_call_frame_cfa:
851 if (!regs)
852 FAIL("evaluate_Dwarf3_Expr: "
853 "DW_OP_call_frame_cfa but no reg info");
854 #if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
855 /* Valgrind on ppc32/ppc64 currently doesn't use unwind info. */
856 uw1 = ML_(read_Addr)((UChar*)regs->sp);
857 #else
858 uw1 = ML_(get_CFA)(regs->ip, regs->sp, regs->fp, 0, ~(UWord) 0);
859 #endif
860 /* we expect this to fail on arm-linux, since ML_(get_CFA)
861 always returns zero at present. */
862 if (!uw1)
863 FAIL("evaluate_Dwarf3_Expr: Could not resolve "
864 "DW_OP_call_frame_cfa");
865 PUSH(uw1);
866 break;
867 case DW_OP_implicit_value:
868 sw1 = (Word)read_leb128S( &expr );
869 uw1 = 0;
870 switch (sw1) {
871 case 1:
872 uw1 = ML_(read_UChar)(expr);
873 expr += 1;
874 break;
875 case 2:
876 uw1 = ML_(read_UShort)(expr);
877 expr += 2;
878 break;
879 case 4:
880 uw1 = ML_(read_UInt)(expr);
881 expr += 4;
882 break;
883 case 8:
884 uw1 = ML_(read_ULong)(expr);
885 expr += 8;
886 break;
887 default:
888 FAIL("evaluate_Dwarf3_Expr: Unhandled "
889 "DW_OP_implicit_value size");
890 }
891 if (expr != limit)
892 FAIL("evaluate_Dwarf3_Expr: DW_OP_implicit_value "
893 "does not terminate expression");
894 res.word = uw1;
895 res.kind = GXR_Value;
896 return res;
897 case DW_OP_stack_value:
898 POP (uw1);
899 res.word = uw1;
900 res.kind = GXR_Value;
901 if (expr != limit)
902 FAIL("evaluate_Dwarf3_Expr: DW_OP_stack_value "
903 "does not terminate expression");
904 break;
905 default:
906 if (!VG_(clo_xml))
907 VG_(message)(Vg_DebugMsg,
908 "warning: evaluate_Dwarf3_Expr: unhandled "
909 "DW_OP_ 0x%x\n", (Int)opcode);
910 FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_");
911 /*NOTREACHED*/
912 }
913
914 }
915
916 vg_assert(sp >= 0 && sp < N_EXPR_STACK);
917 res.word = stack[sp];
918 res.kind = GXR_Addr;
919 return res;
920
921 # undef POP
922 # undef PUSH
923 # undef FAIL
924 # undef N_EXPR_STACK
925 }
926
927
928 /* Evaluate a so-called Guarded (DWARF3) expression. See detailed
929 description in priv_d3basics.h. */
ML_(evaluate_GX)930 GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX,
931 RegSummary* regs, const DebugInfo* di )
932 {
933 GXResult res;
934 Addr aMin, aMax;
935 UChar uc;
936 UShort nbytes;
937 UWord nGuards = 0;
938 UChar* p = &gx->payload[0];
939 uc = *p++; /*biasMe*/
940 vg_assert(uc == 0 || uc == 1);
941 /* in fact it's senseless to evaluate if the guards need biasing.
942 So don't. */
943 vg_assert(uc == 0);
944 while (True) {
945 uc = *p++;
946 if (uc == 1) { /*isEnd*/
947 /* didn't find any matching range. */
948 res.kind = GXR_Failure;
949 res.word = (UWord)"no matching range";
950 return res;
951 }
952 vg_assert(uc == 0);
953 aMin = ML_(read_Addr)(p); p += sizeof(Addr);
954 aMax = ML_(read_Addr)(p); p += sizeof(Addr);
955 nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
956 nGuards++;
957 if (0) VG_(printf)(" guard %d: %#lx %#lx\n",
958 (Int)nGuards, aMin,aMax);
959 if (regs == NULL) {
960 vg_assert(aMin == (Addr)0);
961 vg_assert(aMax == ~(Addr)0);
962 /* Assert this is the first guard. */
963 vg_assert(nGuards == 1);
964 res = ML_(evaluate_Dwarf3_Expr)(
965 p, (UWord)nbytes, fbGX, regs, di,
966 False/*push_initial_zero*/ );
967 /* Now check there are no more guards. */
968 p += (UWord)nbytes;
969 vg_assert(*p == 1); /*isEnd*/
970 return res;
971 } else {
972 if (aMin <= regs->ip && regs->ip <= aMax) {
973 /* found a matching range. Evaluate the expression. */
974 return ML_(evaluate_Dwarf3_Expr)(
975 p, (UWord)nbytes, fbGX, regs, di,
976 False/*push_initial_zero*/ );
977 }
978 }
979 /* else keep searching */
980 p += (UWord)nbytes;
981 }
982 }
983
984
985 /* Evaluate a very simple Guarded (DWARF3) expression. The expression
986 is expected to denote a constant, with no reference to any
987 registers nor to any frame base expression. The expression is
988 expected to have at least one guard. If there is more than one
989 guard, all the sub-expressions are evaluated and compared. The
990 address ranges on the guards are ignored. GXR_Failure is returned
991 in the following circumstances:
992 * no guards
993 * any of the subexpressions require a frame base expression
994 * any of the subexpressions denote a register location
995 * any of the subexpressions do not produce a manifest constant
996 * there's more than one subexpression, all of which successfully
997 evaluate to a constant, but they don't all produce the same constant.
998 JRS 23Jan09: the special-casing in this function is a nasty kludge.
999 Really it ought to be pulled out and turned into a general
1000 constant- expression evaluator.
1001 */
ML_(evaluate_trivial_GX)1002 GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di )
1003 {
1004 GXResult res;
1005 Addr aMin, aMax;
1006 UChar uc;
1007 UShort nbytes;
1008 Word i, nGuards;
1009 MaybeULong *mul, *mul2;
1010
1011 HChar* badness = NULL;
1012 UChar* p = &gx->payload[0]; /* must remain unsigned */
1013 XArray* results = VG_(newXA)( ML_(dinfo_zalloc), "di.d3basics.etG.1",
1014 ML_(dinfo_free),
1015 sizeof(MaybeULong) );
1016
1017 uc = *p++; /*biasMe*/
1018 vg_assert(uc == 0 || uc == 1);
1019 /* in fact it's senseless to evaluate if the guards need biasing.
1020 So don't. */
1021 vg_assert(uc == 0);
1022
1023 nGuards = 0;
1024 while (True) {
1025 MaybeULong thisResult;
1026 uc = *p++;
1027 if (uc == 1) /*isEnd*/
1028 break;
1029 vg_assert(uc == 0);
1030 aMin = ML_(read_Addr)(p); p += sizeof(Addr);
1031 aMax = ML_(read_Addr)(p); p += sizeof(Addr);
1032 nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
1033 nGuards++;
1034 if (0) VG_(printf)(" guard %ld: %#lx %#lx\n",
1035 nGuards, aMin,aMax);
1036
1037 thisResult.b = False;
1038 thisResult.ul = 0;
1039
1040 /* Peer at this particular subexpression, to see if it's
1041 obviously a constant. */
1042 if (nbytes == 1 + sizeof(Addr) && *p == DW_OP_addr) {
1043 /* DW_OP_addr a */
1044 Addr a = ML_(read_Addr)((p+1));
1045 if (bias_address(&a, di)) {
1046 thisResult.b = True;
1047 thisResult.ul = (ULong)a;
1048 } else {
1049 if (!badness)
1050 badness = "trivial GExpr denotes constant address "
1051 "in unknown section (1)";
1052 }
1053 }
1054 else
1055 if (nbytes == 1 + sizeof(Addr) + 1 + 1
1056 /* 11 byte block: 3 c0 b6 2b 0 0 0 0 0 23 4
1057 (DW_OP_addr: 2bb6c0; DW_OP_plus_uconst: 4)
1058 This is really a nasty kludge - only matches if the
1059 trailing ULEB denotes a number in the range 0 .. 127
1060 inclusive. */
1061 && p[0] == DW_OP_addr
1062 && p[1 + sizeof(Addr)] == DW_OP_plus_uconst
1063 && p[1 + sizeof(Addr) + 1] < 0x80 /*1-byte ULEB*/) {
1064 Addr a = ML_(read_Addr)(&p[1]);
1065 if (bias_address(&a, di)) {
1066 thisResult.b = True;
1067 thisResult.ul = (ULong)a + (ULong)p[1 + sizeof(Addr) + 1];
1068 } else {
1069 if (!badness)
1070 badness = "trivial GExpr denotes constant address "
1071 "in unknown section (2)";
1072 }
1073 }
1074 else
1075 if (nbytes == 2 + sizeof(Addr)
1076 && *p == DW_OP_addr
1077 && *(p + 1 + sizeof(Addr)) == DW_OP_GNU_push_tls_address) {
1078 if (!badness)
1079 badness = "trivial GExpr is DW_OP_addr plus trailing junk";
1080 }
1081 else if (nbytes >= 1 && *p >= DW_OP_reg0 && *p <= DW_OP_reg31) {
1082 if (!badness)
1083 badness = "trivial GExpr denotes register (1)";
1084 }
1085 else if (nbytes >= 1 && *p == DW_OP_fbreg) {
1086 if (!badness)
1087 badness = "trivial GExpr requires fbGX";
1088 }
1089 else if (nbytes >= 1 && *p >= DW_OP_breg0 && *p <= DW_OP_breg31) {
1090 if (!badness)
1091 badness = "trivial GExpr requires register value";
1092 }
1093 else if (nbytes >= 1 && *p == DW_OP_regx) {
1094 if (!badness)
1095 badness = "trivial GExpr denotes register (2)";
1096 }
1097 else if (0) {
1098 VG_(printf)(" ML_(evaluate_trivial_GX): unhandled:\n ");
1099 ML_(pp_GX)( gx );
1100 VG_(printf)("\n");
1101 tl_assert(0);
1102 }
1103 else
1104 if (!badness)
1105 badness = "non-trivial GExpr";
1106
1107 VG_(addToXA)( results, &thisResult );
1108
1109 p += (UWord)nbytes;
1110 }
1111
1112 res.kind = GXR_Failure;
1113
1114 tl_assert(nGuards == VG_(sizeXA)( results ));
1115 tl_assert(nGuards >= 0);
1116 if (nGuards == 0) {
1117 tl_assert(!badness);
1118 res.word = (UWord)"trivial GExpr has no guards (!)";
1119 VG_(deleteXA)( results );
1120 return res;
1121 }
1122
1123 for (i = 0; i < nGuards; i++) {
1124 mul = VG_(indexXA)( results, i );
1125 if (mul->b == False)
1126 break;
1127 }
1128
1129 vg_assert(i >= 0 && i <= nGuards);
1130 if (i < nGuards) {
1131 /* at least one subexpression failed to produce a manifest constant. */
1132 vg_assert(badness);
1133 res.word = (UWord)badness;
1134 VG_(deleteXA)( results );
1135 return res;
1136 }
1137
1138 /* All the subexpressions produced a constant, but did they all produce
1139 the same one? */
1140 mul = VG_(indexXA)( results, 0 );
1141 tl_assert(mul->b == True); /* we just established that all exprs are ok */
1142
1143 for (i = 1; i < nGuards; i++) {
1144 mul2 = VG_(indexXA)( results, i );
1145 tl_assert(mul2->b == True);
1146 if (mul2->ul != mul->ul) {
1147 res.word = (UWord)"trivial GExpr: subexpressions disagree";
1148 VG_(deleteXA)( results );
1149 return res;
1150 }
1151 }
1152
1153 /* Well, we have success. All subexpressions evaluated, and
1154 they all agree. Hurrah. */
1155 res.kind = GXR_Addr;
1156 res.word = (UWord)mul->ul; /* NB: narrowing from ULong */
1157 VG_(deleteXA)( results );
1158 return res;
1159 }
1160
1161
ML_(pp_GXResult)1162 void ML_(pp_GXResult) ( GXResult res )
1163 {
1164 switch (res.kind) {
1165 case GXR_Failure:
1166 VG_(printf)("GXR_Failure(%s)", (HChar*)res.word); break;
1167 case GXR_Addr:
1168 VG_(printf)("GXR_Addr(0x%lx)", res.word); break;
1169 case GXR_Value:
1170 VG_(printf)("GXR_Value(0x%lx)", res.word); break;
1171 case GXR_RegNo:
1172 VG_(printf)("GXR_RegNo(%lu)", res.word); break;
1173 default:
1174 VG_(printf)("GXR_???"); break;
1175 }
1176 }
1177
1178
ML_(pp_GX)1179 void ML_(pp_GX) ( GExpr* gx ) {
1180 Addr aMin, aMax;
1181 UChar uc;
1182 UShort nbytes;
1183 UChar* p = &gx->payload[0];
1184 uc = *p++;
1185 VG_(printf)("GX(%s){", uc == 0 ? "final" : "Breqd" );
1186 vg_assert(uc == 0 || uc == 1);
1187 while (True) {
1188 uc = *p++;
1189 if (uc == 1)
1190 break; /*isEnd*/
1191 vg_assert(uc == 0);
1192 aMin = ML_(read_Addr)(p); p += sizeof(Addr);
1193 aMax = ML_(read_Addr)(p); p += sizeof(Addr);
1194 nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
1195 VG_(printf)("[%#lx,%#lx]=", aMin, aMax);
1196 while (nbytes > 0) {
1197 VG_(printf)("%02x", (UInt)*p++);
1198 nbytes--;
1199 }
1200 if (*p == 0)
1201 VG_(printf)(",");
1202 }
1203 VG_(printf)("}");
1204 }
1205
1206
1207 /*--------------------------------------------------------------------*/
1208 /*--- end d3basics.c ---*/
1209 /*--------------------------------------------------------------------*/
1210