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-2010 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_ppc32_aix5) || defined(VGP_ppc64_aix5)
411 vg_assert(0); /* this function should never be called */
412 # else
413 # error "Unknown platform"
414 # endif
415 return False;
416 }
417
418 /* Convert a stated address to an actual address */
bias_address(Addr * a,const DebugInfo * di)419 static Bool bias_address( Addr* a, const DebugInfo* di )
420 {
421 if (di->text_present
422 && di->text_size > 0
423 && *a >= di->text_debug_svma && *a < di->text_debug_svma + di->text_size) {
424 *a += di->text_debug_bias;
425 }
426 else if (di->data_present
427 && di->data_size > 0
428 && *a >= di->data_debug_svma && *a < di->data_debug_svma + di->data_size) {
429 *a += di->data_debug_bias;
430 }
431 else if (di->sdata_present
432 && di->sdata_size > 0
433 && *a >= di->sdata_debug_svma && *a < di->sdata_debug_svma + di->sdata_size) {
434 *a += di->sdata_debug_bias;
435 }
436 else if (di->rodata_present
437 && di->rodata_size > 0
438 && *a >= di->rodata_debug_svma && *a < di->rodata_debug_svma + di->rodata_size) {
439 *a += di->rodata_debug_bias;
440 }
441 else if (di->bss_present
442 && di->bss_size > 0
443 && *a >= di->bss_debug_svma && *a < di->bss_debug_svma + di->bss_size) {
444 *a += di->bss_debug_bias;
445 }
446 else if (di->sbss_present
447 && di->sbss_size > 0
448 && *a >= di->sbss_debug_svma && *a < di->sbss_debug_svma + di->sbss_size) {
449 *a += di->sbss_debug_bias;
450 }
451 else {
452 return False;
453 }
454
455 return True;
456 }
457
458
459 /* Evaluate a standard DWARF3 expression. See detailed description in
460 priv_d3basics.h. Doesn't handle DW_OP_piece/DW_OP_bit_piece yet. */
ML_(evaluate_Dwarf3_Expr)461 GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB,
462 GExpr* fbGX, RegSummary* regs,
463 const DebugInfo* di,
464 Bool push_initial_zero )
465 {
466 # define N_EXPR_STACK 20
467
468 # define FAIL(_str) \
469 do { \
470 res.kind = GXR_Failure; \
471 res.word = (UWord)(_str); \
472 return res; \
473 } while (0)
474
475 # define PUSH(_arg) \
476 do { \
477 vg_assert(sp >= -1 && sp < N_EXPR_STACK); \
478 if (sp == N_EXPR_STACK-1) \
479 FAIL("evaluate_Dwarf3_Expr: stack overflow(1)"); \
480 sp++; \
481 stack[sp] = (_arg); \
482 } while (0)
483
484 # define POP(_lval) \
485 do { \
486 vg_assert(sp >= -1 && sp < N_EXPR_STACK); \
487 if (sp == -1) \
488 FAIL("evaluate_Dwarf3_Expr: stack underflow(1)"); \
489 _lval = stack[sp]; \
490 sp--; \
491 } while (0)
492
493 UChar opcode;
494 UChar* limit;
495 Int sp; /* # of top element: valid is -1 .. N_EXPR_STACK-1 */
496 Addr stack[N_EXPR_STACK]; /* stack of addresses, as per D3 spec */
497 GXResult fbval, res;
498 Addr a1;
499 Word sw1, sw2;
500 UWord uw1, uw2;
501 Bool ok;
502
503 sp = -1;
504 vg_assert(expr);
505 vg_assert(exprszB >= 0);
506 limit = expr + exprszB;
507
508 /* Deal with the case where the entire expression is a single
509 Register Name Operation (D3 spec sec 2.6.1). Then the
510 denotation of the expression as a whole is a register name. */
511 if (exprszB == 1
512 && expr[0] >= DW_OP_reg0 && expr[0] <= DW_OP_reg31) {
513 res.kind = GXR_RegNo;
514 res.word = (UWord)(expr[0] - DW_OP_reg0);
515 return res;
516 }
517 if (exprszB > 1
518 && expr[0] == DW_OP_regx) {
519 /* JRS: 2008Feb20: I believe the following is correct, but would
520 like to see a test case show up before enabling it. */
521 expr++;
522 res.kind = GXR_RegNo;
523 res.word = (UWord)read_leb128U( &expr );
524 if (expr != limit)
525 FAIL("evaluate_Dwarf3_Expr: DW_OP_regx*: invalid expr size");
526 else
527 return res;
528 /*NOTREACHED*/
529 }
530
531 /* Evidently this expression denotes a value, not a register name.
532 So evaluate it accordingly. */
533
534 if (push_initial_zero)
535 PUSH(0);
536
537 while (True) {
538
539 vg_assert(sp >= -1 && sp < N_EXPR_STACK);
540
541 if (expr > limit)
542 /* overrun - something's wrong */
543 FAIL("evaluate_Dwarf3_Expr: ran off end of expr");
544
545 if (expr == limit) {
546 /* end of expr - return expr on the top of stack. */
547 if (sp == -1)
548 /* stack empty. Bad. */
549 FAIL("evaluate_Dwarf3_Expr: stack empty at end of expr");
550 else
551 break;
552 }
553
554 opcode = *expr++;
555 switch (opcode) {
556 case DW_OP_addr:
557 /* Presumably what is given in the Dwarf3 is a SVMA (how
558 could it be otherwise?) So we add the appropriate bias
559 on before pushing the result. */
560 a1 = *(Addr*)expr;
561 if (bias_address(&a1, di)) {
562 PUSH( a1 );
563 expr += sizeof(Addr);
564 }
565 else {
566 FAIL("evaluate_Dwarf3_Expr: DW_OP_addr with address "
567 "in unknown section");
568 }
569 break;
570 case DW_OP_fbreg:
571 if (!fbGX)
572 FAIL("evaluate_Dwarf3_Expr: DW_OP_fbreg with "
573 "no expr for fbreg present");
574 fbval = ML_(evaluate_GX)(fbGX, NULL, regs, di);
575 /* Convert fbval into something we can use. If we got a
576 Value, no problem. However, as per D3 spec sec 3.3.5
577 (Low Level Information) sec 2, we could also get a
578 RegNo, and that is taken to mean the value in the
579 indicated register. So we have to manually
580 "dereference" it. */
581 a1 = 0;
582 switch (fbval.kind) {
583 case GXR_Failure:
584 return fbval; /* propagate failure */
585 case GXR_Addr:
586 a1 = fbval.word; break; /* use as-is */
587 case GXR_RegNo:
588 ok = get_Dwarf_Reg( &a1, fbval.word, regs );
589 if (!ok) return fbval; /* propagate failure */
590 break;
591 case GXR_Value:
592 FAIL("evaluate_Dwarf3_Expr: DW_OP_{implicit,stack}_value "
593 "in DW_AT_frame_base");
594 default:
595 vg_assert(0);
596 }
597 sw1 = (Word)read_leb128S( &expr );
598 PUSH( a1 + sw1 );
599 break;
600 /* DW_OP_breg* denotes 'contents of specified register, plus
601 constant offset'. So provided we know what the register's
602 value is, we can evaluate this. Contrast DW_OP_reg*,
603 which indicates that denoted location is in a register
604 itself. If DW_OP_reg* shows up here the expression is
605 malformed, since we are evaluating for value now, and
606 DW_OP_reg* denotes a register location, not a value. See
607 D3 Spec sec 2.6.1 ("Register Name Operations") for
608 details. */
609 case DW_OP_breg0 ... DW_OP_breg31:
610 if (!regs)
611 FAIL("evaluate_Dwarf3_Expr: DW_OP_breg* but no reg info");
612 a1 = 0;
613 if (!get_Dwarf_Reg( &a1, opcode - DW_OP_breg0, regs ))
614 FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_breg*");
615 sw1 = (Word)read_leb128S( &expr );
616 a1 += sw1;
617 PUSH( a1 );
618 break;
619 case DW_OP_bregx:
620 if (!regs)
621 FAIL("evaluate_Dwarf3_Expr: DW_OP_bregx but no reg info");
622 a1 = 0;
623 uw1 = (UWord)read_leb128U( &expr );
624 if (!get_Dwarf_Reg( &a1, uw1, regs ))
625 FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_bregx reg value");
626 sw1 = (Word)read_leb128S( &expr );
627 a1 += sw1;
628 PUSH( a1 );
629 break;
630 /* As per comment on DW_OP_breg*, the following denote that
631 the value in question is in a register, not in memory. So
632 we simply return failure. (iow, the expression is
633 malformed). */
634 case DW_OP_reg0 ... DW_OP_reg31:
635 case DW_OP_regx:
636 FAIL("evaluate_Dwarf3_Expr: DW_OP_reg* "
637 "whilst evaluating for a value");
638 break;
639 case DW_OP_plus_uconst:
640 POP(uw1);
641 uw1 += (UWord)read_leb128U( &expr );
642 PUSH(uw1);
643 break;
644 case DW_OP_GNU_push_tls_address:
645 /* GDB contains the following cryptic comment: */
646 /* Variable is at a constant offset in the thread-local
647 storage block into the objfile for the current thread and
648 the dynamic linker module containing this expression. Here
649 we return returns the offset from that base. The top of the
650 stack has the offset from the beginning of the thread
651 control block at which the variable is located. Nothing
652 should follow this operator, so the top of stack would be
653 returned. */
654 /* But no spec resulting from Googling. Punt for now. */
655 FAIL("warning: evaluate_Dwarf3_Expr: unhandled "
656 "DW_OP_GNU_push_tls_address");
657 /*NOTREACHED*/
658 case DW_OP_deref:
659 POP(uw1);
660 if (VG_(am_is_valid_for_client)( (Addr)uw1, sizeof(Addr),
661 VKI_PROT_READ )) {
662 uw1 = *(UWord*)uw1;
663 PUSH(uw1);
664 } else {
665 FAIL("warning: evaluate_Dwarf3_Expr: DW_OP_deref: "
666 "address not valid for client");
667 }
668 break;
669 case DW_OP_deref_size:
670 POP(uw1);
671 uw2 = *expr++;
672 if (VG_(am_is_valid_for_client)( (Addr)uw1, uw2,
673 VKI_PROT_READ )) {
674 switch (uw2) {
675 case 1: uw1 = *(UChar*)uw1; break;
676 case 2: uw1 = *(UShort*)uw1; break;
677 case 4: uw1 = *(UInt*)uw1; break;
678 case 8: uw1 = *(ULong*)uw1; break;
679 default:
680 FAIL("warning: evaluate_Dwarf3_Expr: unhandled "
681 "DW_OP_deref_size size");
682 }
683 PUSH(uw1);
684 } else {
685 FAIL("warning: evaluate_Dwarf3_Expr: DW_OP_deref_size: "
686 "address not valid for client");
687 }
688 break;
689 case DW_OP_lit0 ... DW_OP_lit31:
690 PUSH(opcode - DW_OP_lit0);
691 break;
692 case DW_OP_const1u:
693 uw1 = *expr++;
694 PUSH(uw1);
695 break;
696 case DW_OP_const2u:
697 uw1 = *(UShort *)expr;
698 expr += 2;
699 PUSH(uw1);
700 break;
701 case DW_OP_const4u:
702 uw1 = *(UInt *)expr;
703 expr += 4;
704 PUSH(uw1);
705 break;
706 case DW_OP_const8u:
707 uw1 = *(ULong *)expr;
708 expr += 8;
709 PUSH(uw1);
710 break;
711 case DW_OP_constu:
712 uw1 = read_leb128U( &expr );
713 PUSH(uw1);
714 break;
715 case DW_OP_const1s:
716 uw1 = *(Char *)expr;
717 expr++;
718 PUSH(uw1);
719 break;
720 case DW_OP_const2s:
721 uw1 = *(Short *)expr;
722 expr += 2;
723 PUSH(uw1);
724 break;
725 case DW_OP_const4s:
726 uw1 = *(Int *)expr;
727 expr += 4;
728 PUSH(uw1);
729 break;
730 case DW_OP_const8s:
731 uw1 = *(Long *)expr;
732 expr += 8;
733 PUSH(uw1);
734 break;
735 case DW_OP_consts:
736 uw1 = read_leb128S( &expr );
737 PUSH(uw1);
738 break;
739 case DW_OP_dup:
740 POP(uw1);
741 PUSH(uw1);
742 PUSH(uw1);
743 break;
744 case DW_OP_drop:
745 POP(uw1);
746 break;
747 case DW_OP_over:
748 uw1 = 1;
749 goto do_pick;
750 case DW_OP_pick:
751 uw1 = *expr++;
752 do_pick:
753 if (sp < (Int)uw1)
754 FAIL("evaluate_Dwarf3_Expr: stack underflow");
755 uw1 = stack[sp - uw1];
756 PUSH(uw1);
757 break;
758 case DW_OP_swap:
759 if (sp < 1)
760 FAIL("evaluate_Dwarf3_Expr: stack underflow");
761 uw1 = stack[sp];
762 stack[sp] = stack[sp - 1];
763 stack[sp - 1] = uw1;
764 break;
765 case DW_OP_rot:
766 if (sp < 2)
767 FAIL("evaluate_Dwarf3_Expr: stack underflow");
768 uw1 = stack[sp];
769 stack[sp] = stack[sp - 1];
770 stack[sp - 1] = stack[sp - 2];
771 stack[sp - 2] = uw1;
772 break;
773 case DW_OP_abs:
774 POP(sw1);
775 if (sw1 < 0)
776 sw1 = -sw1;
777 PUSH(sw1);
778 break;
779 case DW_OP_div:
780 POP(sw2);
781 if (sw2 == 0)
782 FAIL("evaluate_Dwarf3_Expr: division by zero");
783 POP(sw1);
784 sw1 /= sw2;
785 PUSH(sw1);
786 break;
787 case DW_OP_mod:
788 POP(uw2);
789 if (uw2 == 0)
790 FAIL("evaluate_Dwarf3_Expr: division by zero");
791 POP(uw1);
792 uw1 %= uw2;
793 PUSH(uw1);
794 break;
795 #define BINARY(name, op, s) \
796 case DW_OP_##name: \
797 POP(s##w2); \
798 POP(s##w1); \
799 s##w1 = s##w1 op s##w2; \
800 PUSH(s##w1); \
801 break
802 #define UNARY(name, op, s) \
803 case DW_OP_##name: \
804 POP(s##w1); \
805 s##w1 = op s##w1; \
806 PUSH(s##w1); \
807 break
808 BINARY (and, &, u);
809 BINARY (minus, -, u);
810 BINARY (mul, *, u);
811 UNARY (neg, -, u);
812 UNARY (not, ~, u);
813 BINARY (or, |, u);
814 BINARY (plus, +, u);
815 BINARY (shl, <<, u);
816 BINARY (shr, >>, u);
817 BINARY (shra, >>, s);
818 BINARY (xor, ^, u);
819 BINARY (le, <=, s);
820 BINARY (lt, <, s);
821 BINARY (ge, >=, s);
822 BINARY (gt, >, s);
823 BINARY (ne, !=, u);
824 BINARY (eq, ==, u);
825 #undef UNARY
826 #undef BINARY
827 case DW_OP_skip:
828 sw1 = *(Short *)expr;
829 expr += 2;
830 if (expr + sw1 < limit - exprszB)
831 FAIL("evaluate_Dwarf3_Expr: DW_OP_skip before start of expr");
832 if (expr + sw1 >= limit)
833 FAIL("evaluate_Dwarf3_Expr: DW_OP_skip after end of expr");
834 expr += sw1;
835 break;
836 case DW_OP_bra:
837 sw1 = *(Short *)expr;
838 expr += 2;
839 if (expr + sw1 < limit - exprszB)
840 FAIL("evaluate_Dwarf3_Expr: DW_OP_bra before start of expr");
841 if (expr + sw1 >= limit)
842 FAIL("evaluate_Dwarf3_Expr: DW_OP_bra after end of expr");
843 POP(uw1);
844 if (uw1)
845 expr += sw1;
846 break;
847 case DW_OP_nop:
848 break;
849 case DW_OP_call_frame_cfa:
850 if (!regs)
851 FAIL("evaluate_Dwarf3_Expr: "
852 "DW_OP_call_frame_cfa but no reg info");
853 #if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
854 /* Valgrind on ppc32/ppc64 currently doesn't use unwind info. */
855 uw1 = *(Addr *)(regs->sp);
856 #else
857 uw1 = ML_(get_CFA)(regs->ip, regs->sp, regs->fp, 0, ~(UWord) 0);
858 #endif
859 /* we expect this to fail on arm-linux, since ML_(get_CFA)
860 always returns zero at present. */
861 if (!uw1)
862 FAIL("evaluate_Dwarf3_Expr: Could not resolve "
863 "DW_OP_call_frame_cfa");
864 PUSH(uw1);
865 break;
866 case DW_OP_implicit_value:
867 sw1 = (Word)read_leb128S( &expr );
868 uw1 = 0;
869 switch (sw1) {
870 case 1:
871 uw1 = *(UChar *)expr;
872 expr += 1;
873 break;
874 case 2:
875 uw1 = *(UShort *)expr;
876 expr += 2;
877 break;
878 case 4:
879 uw1 = *(UInt *)expr;
880 expr += 4;
881 break;
882 case 8:
883 uw1 = *(ULong *)expr;
884 expr += 8;
885 break;
886 default:
887 FAIL("evaluate_Dwarf3_Expr: Unhandled "
888 "DW_OP_implicit_value size");
889 }
890 if (expr != limit)
891 FAIL("evaluate_Dwarf3_Expr: DW_OP_implicit_value "
892 "does not terminate expression");
893 res.word = uw1;
894 res.kind = GXR_Value;
895 return res;
896 case DW_OP_stack_value:
897 POP (uw1);
898 res.word = uw1;
899 res.kind = GXR_Value;
900 if (expr != limit)
901 FAIL("evaluate_Dwarf3_Expr: DW_OP_stack_value "
902 "does not terminate expression");
903 break;
904 default:
905 if (!VG_(clo_xml))
906 VG_(message)(Vg_DebugMsg,
907 "warning: evaluate_Dwarf3_Expr: unhandled "
908 "DW_OP_ 0x%x\n", (Int)opcode);
909 FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_");
910 /*NOTREACHED*/
911 }
912
913 }
914
915 vg_assert(sp >= 0 && sp < N_EXPR_STACK);
916 res.word = stack[sp];
917 res.kind = GXR_Addr;
918 return res;
919
920 # undef POP
921 # undef PUSH
922 # undef FAIL
923 # undef N_EXPR_STACK
924 }
925
926
927 /* Evaluate a so-called Guarded (DWARF3) expression. See detailed
928 description in priv_d3basics.h. */
ML_(evaluate_GX)929 GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX,
930 RegSummary* regs, const DebugInfo* di )
931 {
932 GXResult res;
933 Addr aMin, aMax;
934 UChar uc;
935 UShort nbytes;
936 UWord nGuards = 0;
937 UChar* p = &gx->payload[0];
938 uc = *p++; /*biasMe*/
939 vg_assert(uc == 0 || uc == 1);
940 /* in fact it's senseless to evaluate if the guards need biasing.
941 So don't. */
942 vg_assert(uc == 0);
943 while (True) {
944 uc = *p++;
945 if (uc == 1) { /*isEnd*/
946 /* didn't find any matching range. */
947 res.kind = GXR_Failure;
948 res.word = (UWord)"no matching range";
949 return res;
950 }
951 vg_assert(uc == 0);
952 aMin = * (Addr*)p; p += sizeof(Addr);
953 aMax = * (Addr*)p; p += sizeof(Addr);
954 nbytes = * (UShort*)p; p += sizeof(UShort);
955 nGuards++;
956 if (0) VG_(printf)(" guard %d: %#lx %#lx\n",
957 (Int)nGuards, aMin,aMax);
958 if (regs == NULL) {
959 vg_assert(aMin == (Addr)0);
960 vg_assert(aMax == ~(Addr)0);
961 /* Assert this is the first guard. */
962 vg_assert(nGuards == 1);
963 res = ML_(evaluate_Dwarf3_Expr)(
964 p, (UWord)nbytes, fbGX, regs, di,
965 False/*push_initial_zero*/ );
966 /* Now check there are no more guards. */
967 p += (UWord)nbytes;
968 vg_assert(*p == 1); /*isEnd*/
969 return res;
970 } else {
971 if (aMin <= regs->ip && regs->ip <= aMax) {
972 /* found a matching range. Evaluate the expression. */
973 return ML_(evaluate_Dwarf3_Expr)(
974 p, (UWord)nbytes, fbGX, regs, di,
975 False/*push_initial_zero*/ );
976 }
977 }
978 /* else keep searching */
979 p += (UWord)nbytes;
980 }
981 }
982
983
984 /* Evaluate a very simple Guarded (DWARF3) expression. The expression
985 is expected to denote a constant, with no reference to any
986 registers nor to any frame base expression. The expression is
987 expected to have at least one guard. If there is more than one
988 guard, all the sub-expressions are evaluated and compared. The
989 address ranges on the guards are ignored. GXR_Failure is returned
990 in the following circumstances:
991 * no guards
992 * any of the subexpressions require a frame base expression
993 * any of the subexpressions denote a register location
994 * any of the subexpressions do not produce a manifest constant
995 * there's more than one subexpression, all of which successfully
996 evaluate to a constant, but they don't all produce the same constant.
997 JRS 23Jan09: the special-casing in this function is a nasty kludge.
998 Really it ought to be pulled out and turned into a general
999 constant- expression evaluator.
1000 */
ML_(evaluate_trivial_GX)1001 GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di )
1002 {
1003 GXResult res;
1004 Addr aMin, aMax;
1005 UChar uc;
1006 UShort nbytes;
1007 Word i, nGuards;
1008 MaybeULong *mul, *mul2;
1009
1010 HChar* badness = NULL;
1011 UChar* p = &gx->payload[0]; /* must remain unsigned */
1012 XArray* results = VG_(newXA)( ML_(dinfo_zalloc), "di.d3basics.etG.1",
1013 ML_(dinfo_free),
1014 sizeof(MaybeULong) );
1015
1016 uc = *p++; /*biasMe*/
1017 vg_assert(uc == 0 || uc == 1);
1018 /* in fact it's senseless to evaluate if the guards need biasing.
1019 So don't. */
1020 vg_assert(uc == 0);
1021
1022 nGuards = 0;
1023 while (True) {
1024 MaybeULong thisResult;
1025 uc = *p++;
1026 if (uc == 1) /*isEnd*/
1027 break;
1028 vg_assert(uc == 0);
1029 aMin = * (Addr*)p; p += sizeof(Addr);
1030 aMax = * (Addr*)p; p += sizeof(Addr);
1031 nbytes = * (UShort*)p; p += sizeof(UShort);
1032 nGuards++;
1033 if (0) VG_(printf)(" guard %ld: %#lx %#lx\n",
1034 nGuards, aMin,aMax);
1035
1036 thisResult.b = False;
1037 thisResult.ul = 0;
1038
1039 /* Peer at this particular subexpression, to see if it's
1040 obviously a constant. */
1041 if (nbytes == 1 + sizeof(Addr) && *p == DW_OP_addr) {
1042 /* DW_OP_addr a */
1043 Addr a = *(Addr*)(p+1);
1044 if (bias_address(&a, di)) {
1045 thisResult.b = True;
1046 thisResult.ul = (ULong)a;
1047 } else {
1048 if (!badness)
1049 badness = "trivial GExpr denotes constant address "
1050 "in unknown section (1)";
1051 }
1052 }
1053 else
1054 if (nbytes == 1 + sizeof(Addr) + 1 + 1
1055 /* 11 byte block: 3 c0 b6 2b 0 0 0 0 0 23 4
1056 (DW_OP_addr: 2bb6c0; DW_OP_plus_uconst: 4)
1057 This is really a nasty kludge - only matches if the
1058 trailing ULEB denotes a number in the range 0 .. 127
1059 inclusive. */
1060 && p[0] == DW_OP_addr
1061 && p[1 + sizeof(Addr)] == DW_OP_plus_uconst
1062 && p[1 + sizeof(Addr) + 1] < 0x80 /*1-byte ULEB*/) {
1063 Addr a = *(Addr*)&p[1];
1064 if (bias_address(&a, di)) {
1065 thisResult.b = True;
1066 thisResult.ul = (ULong)a + (ULong)p[1 + sizeof(Addr) + 1];
1067 } else {
1068 if (!badness)
1069 badness = "trivial GExpr denotes constant address "
1070 "in unknown section (2)";
1071 }
1072 }
1073 else
1074 if (nbytes == 2 + sizeof(Addr)
1075 && *p == DW_OP_addr
1076 && *(p + 1 + sizeof(Addr)) == DW_OP_GNU_push_tls_address) {
1077 if (!badness)
1078 badness = "trivial GExpr is DW_OP_addr plus trailing junk";
1079 }
1080 else if (nbytes >= 1 && *p >= DW_OP_reg0 && *p <= DW_OP_reg31) {
1081 if (!badness)
1082 badness = "trivial GExpr denotes register (1)";
1083 }
1084 else if (nbytes >= 1 && *p == DW_OP_fbreg) {
1085 if (!badness)
1086 badness = "trivial GExpr requires fbGX";
1087 }
1088 else if (nbytes >= 1 && *p >= DW_OP_breg0 && *p <= DW_OP_breg31) {
1089 if (!badness)
1090 badness = "trivial GExpr requires register value";
1091 }
1092 else if (nbytes >= 1 && *p == DW_OP_regx) {
1093 if (!badness)
1094 badness = "trivial GExpr denotes register (2)";
1095 }
1096 else if (0) {
1097 VG_(printf)(" ML_(evaluate_trivial_GX): unhandled:\n ");
1098 ML_(pp_GX)( gx );
1099 VG_(printf)("\n");
1100 tl_assert(0);
1101 }
1102 else
1103 if (!badness)
1104 badness = "non-trivial GExpr";
1105
1106 VG_(addToXA)( results, &thisResult );
1107
1108 p += (UWord)nbytes;
1109 }
1110
1111 res.kind = GXR_Failure;
1112
1113 tl_assert(nGuards == VG_(sizeXA)( results ));
1114 tl_assert(nGuards >= 0);
1115 if (nGuards == 0) {
1116 tl_assert(!badness);
1117 res.word = (UWord)"trivial GExpr has no guards (!)";
1118 VG_(deleteXA)( results );
1119 return res;
1120 }
1121
1122 for (i = 0; i < nGuards; i++) {
1123 mul = VG_(indexXA)( results, i );
1124 if (mul->b == False)
1125 break;
1126 }
1127
1128 vg_assert(i >= 0 && i <= nGuards);
1129 if (i < nGuards) {
1130 /* at least one subexpression failed to produce a manifest constant. */
1131 vg_assert(badness);
1132 res.word = (UWord)badness;
1133 VG_(deleteXA)( results );
1134 return res;
1135 }
1136
1137 /* All the subexpressions produced a constant, but did they all produce
1138 the same one? */
1139 mul = VG_(indexXA)( results, 0 );
1140 tl_assert(mul->b == True); /* we just established that all exprs are ok */
1141
1142 for (i = 1; i < nGuards; i++) {
1143 mul2 = VG_(indexXA)( results, i );
1144 tl_assert(mul2->b == True);
1145 if (mul2->ul != mul->ul) {
1146 res.word = (UWord)"trivial GExpr: subexpressions disagree";
1147 VG_(deleteXA)( results );
1148 return res;
1149 }
1150 }
1151
1152 /* Well, we have success. All subexpressions evaluated, and
1153 they all agree. Hurrah. */
1154 res.kind = GXR_Addr;
1155 res.word = (UWord)mul->ul; /* NB: narrowing from ULong */
1156 VG_(deleteXA)( results );
1157 return res;
1158 }
1159
1160
ML_(pp_GXResult)1161 void ML_(pp_GXResult) ( GXResult res )
1162 {
1163 switch (res.kind) {
1164 case GXR_Failure:
1165 VG_(printf)("GXR_Failure(%s)", (HChar*)res.word); break;
1166 case GXR_Addr:
1167 VG_(printf)("GXR_Addr(0x%lx)", res.word); break;
1168 case GXR_Value:
1169 VG_(printf)("GXR_Value(0x%lx)", res.word); break;
1170 case GXR_RegNo:
1171 VG_(printf)("GXR_RegNo(%lu)", res.word); break;
1172 default:
1173 VG_(printf)("GXR_???"); break;
1174 }
1175 }
1176
1177
ML_(pp_GX)1178 void ML_(pp_GX) ( GExpr* gx ) {
1179 Addr aMin, aMax;
1180 UChar uc;
1181 UShort nbytes;
1182 UChar* p = &gx->payload[0];
1183 uc = *p++;
1184 VG_(printf)("GX(%s){", uc == 0 ? "final" : "Breqd" );
1185 vg_assert(uc == 0 || uc == 1);
1186 while (True) {
1187 uc = *p++;
1188 if (uc == 1)
1189 break; /*isEnd*/
1190 vg_assert(uc == 0);
1191 aMin = * (Addr*)p; p += sizeof(Addr);
1192 aMax = * (Addr*)p; p += sizeof(Addr);
1193 nbytes = * (UShort*)p; p += sizeof(UShort);
1194 VG_(printf)("[%#lx,%#lx]=", aMin, aMax);
1195 while (nbytes > 0) {
1196 VG_(printf)("%02x", (UInt)*p++);
1197 nbytes--;
1198 }
1199 if (*p == 0)
1200 VG_(printf)(",");
1201 }
1202 VG_(printf)("}");
1203 }
1204
1205
1206 /*--------------------------------------------------------------------*/
1207 /*--- end d3basics.c ---*/
1208 /*--------------------------------------------------------------------*/
1209