blob: 399953345b8ce012b4c1862ca1df39d34dcf1413 [file] [log] [blame]
sewardjb8b79ad2008-03-03 01:35:41 +00001
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
sewardj0f157dd2013-10-18 14:27:36 +000011 Copyright (C) 2008-2013 OpenWorks LLP
sewardjb8b79ad2008-03-03 01:35:41 +000012 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"
tom588658b2009-01-22 13:40:12 +000038#include "pub_core_debuginfo.h"
sewardjb8b79ad2008-03-03 01:35:41 +000039#include "pub_core_libcassert.h"
40#include "pub_core_libcprint.h"
sewardj5d616df2013-07-02 08:07:15 +000041#include "pub_core_libcbase.h"
sewardjb8b79ad2008-03-03 01:35:41 +000042#include "pub_core_options.h"
sewardj9c606bd2008-09-18 18:12:50 +000043#include "pub_core_xarray.h"
sewardjb8b79ad2008-03-03 01:35:41 +000044
sewardjaa3c28a2008-03-08 10:44:39 +000045#include "pub_core_vki.h" /* VKI_PROT_READ */
46#include "pub_core_aspacemgr.h" /* VG_(is_valid_for_client) */
47
sewardj9c606bd2008-09-18 18:12:50 +000048#include "priv_misc.h"
sewardj5d616df2013-07-02 08:07:15 +000049#include "priv_image.h"
sewardjb8b79ad2008-03-03 01:35:41 +000050#include "priv_d3basics.h" /* self */
tom588658b2009-01-22 13:40:12 +000051#include "priv_storage.h"
sewardjb8b79ad2008-03-03 01:35:41 +000052
florian6bd9dc12012-11-23 16:17:43 +000053const HChar* ML_(pp_DW_children) ( DW_children hashch )
sewardjb8b79ad2008-03-03 01:35:41 +000054{
55 switch (hashch) {
56 case DW_children_no: return "no children";
57 case DW_children_yes: return "has children";
sewardjb8b79ad2008-03-03 01:35:41 +000058 }
bartdac47792012-01-16 09:22:25 +000059 return "DW_children_???";
sewardjb8b79ad2008-03-03 01:35:41 +000060}
61
florian6bd9dc12012-11-23 16:17:43 +000062const HChar* ML_(pp_DW_TAG) ( DW_TAG tag )
sewardjb8b79ad2008-03-03 01:35:41 +000063{
64 switch (tag) {
65 case DW_TAG_padding: return "DW_TAG_padding";
66 case DW_TAG_array_type: return "DW_TAG_array_type";
67 case DW_TAG_class_type: return "DW_TAG_class_type";
68 case DW_TAG_entry_point: return "DW_TAG_entry_point";
69 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
70 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
71 case DW_TAG_imported_declaration:
72 return "DW_TAG_imported_declaration";
73 case DW_TAG_label: return "DW_TAG_label";
74 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
75 case DW_TAG_member: return "DW_TAG_member";
76 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
77 case DW_TAG_reference_type: return "DW_TAG_reference_type";
78 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
79 case DW_TAG_string_type: return "DW_TAG_string_type";
80 case DW_TAG_structure_type: return "DW_TAG_structure_type";
81 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
82 case DW_TAG_typedef: return "DW_TAG_typedef";
83 case DW_TAG_union_type: return "DW_TAG_union_type";
84 case DW_TAG_unspecified_parameters:
85 return "DW_TAG_unspecified_parameters";
86 case DW_TAG_variant: return "DW_TAG_variant";
87 case DW_TAG_common_block: return "DW_TAG_common_block";
88 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
89 case DW_TAG_inheritance: return "DW_TAG_inheritance";
90 case DW_TAG_inlined_subroutine:
91 return "DW_TAG_inlined_subroutine";
92 case DW_TAG_module: return "DW_TAG_module";
93 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
94 case DW_TAG_set_type: return "DW_TAG_set_type";
95 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
96 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
97 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
98 case DW_TAG_base_type: return "DW_TAG_base_type";
99 case DW_TAG_catch_block: return "DW_TAG_catch_block";
100 case DW_TAG_const_type: return "DW_TAG_const_type";
101 case DW_TAG_constant: return "DW_TAG_constant";
102 case DW_TAG_enumerator: return "DW_TAG_enumerator";
103 case DW_TAG_file_type: return "DW_TAG_file_type";
104 case DW_TAG_friend: return "DW_TAG_friend";
105 case DW_TAG_namelist: return "DW_TAG_namelist";
106 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
107 case DW_TAG_packed_type: return "DW_TAG_packed_type";
108 case DW_TAG_subprogram: return "DW_TAG_subprogram";
109 case DW_TAG_template_type_param:
110 return "DW_TAG_template_type_param";
111 case DW_TAG_template_value_param:
112 return "DW_TAG_template_value_param";
113 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
114 case DW_TAG_try_block: return "DW_TAG_try_block";
115 case DW_TAG_variant_part: return "DW_TAG_variant_part";
116 case DW_TAG_variable: return "DW_TAG_variable";
117 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
118 /* DWARF 3. */
119 case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure";
120 case DW_TAG_restrict_type: return "DW_TAG_restrict_type";
121 case DW_TAG_interface_type: return "DW_TAG_interface_type";
122 case DW_TAG_namespace: return "DW_TAG_namespace";
123 case DW_TAG_imported_module: return "DW_TAG_imported_module";
124 case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type";
125 case DW_TAG_partial_unit: return "DW_TAG_partial_unit";
126 case DW_TAG_imported_unit: return "DW_TAG_imported_unit";
127 case DW_TAG_condition: return "DW_TAG_condition";
128 case DW_TAG_shared_type: return "DW_TAG_shared_type";
tomfba428c2010-04-28 08:09:30 +0000129 /* DWARF 4. */
130 case DW_TAG_type_unit: return "DW_TAG_type_unit";
131 case DW_TAG_rvalue_reference_type: return "DW_TAG_rvalue_reference_type";
132 case DW_TAG_template_alias: return "DW_TAG_template_alias";
sewardjb8b79ad2008-03-03 01:35:41 +0000133 /* SGI/MIPS Extensions. */
134 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
135 /* HP extensions. See:
136 ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz . */
137 case DW_TAG_HP_array_descriptor:
138 return "DW_TAG_HP_array_descriptor";
139 /* GNU extensions. */
140 case DW_TAG_format_label: return "DW_TAG_format_label";
141 case DW_TAG_function_template: return "DW_TAG_function_template";
142 case DW_TAG_class_template: return "DW_TAG_class_template";
143 case DW_TAG_GNU_BINCL: return "DW_TAG_GNU_BINCL";
144 case DW_TAG_GNU_EINCL: return "DW_TAG_GNU_EINCL";
145 /* Extensions for UPC. See: http://upc.gwu.edu/~upc. */
146 case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type";
147 case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type";
148 case DW_TAG_upc_relaxed_type: return "DW_TAG_upc_relaxed_type";
149 /* PGI (STMicroelectronics) extensions. No documentation available. */
150 case DW_TAG_PGI_kanji_type: return "DW_TAG_PGI_kanji_type";
151 case DW_TAG_PGI_interface_block:
152 return "DW_TAG_PGI_interface_block";
sewardjb8b79ad2008-03-03 01:35:41 +0000153 }
bartdac47792012-01-16 09:22:25 +0000154 return "DW_TAG_???";
sewardjb8b79ad2008-03-03 01:35:41 +0000155}
156
florian6bd9dc12012-11-23 16:17:43 +0000157const HChar* ML_(pp_DW_FORM) ( DW_FORM form )
sewardjb8b79ad2008-03-03 01:35:41 +0000158{
159 switch (form) {
160 case DW_FORM_addr: return "DW_FORM_addr";
161 case DW_FORM_block2: return "DW_FORM_block2";
162 case DW_FORM_block4: return "DW_FORM_block4";
163 case DW_FORM_data2: return "DW_FORM_data2";
164 case DW_FORM_data4: return "DW_FORM_data4";
165 case DW_FORM_data8: return "DW_FORM_data8";
166 case DW_FORM_string: return "DW_FORM_string";
167 case DW_FORM_block: return "DW_FORM_block";
168 case DW_FORM_block1: return "DW_FORM_block1";
169 case DW_FORM_data1: return "DW_FORM_data1";
170 case DW_FORM_flag: return "DW_FORM_flag";
171 case DW_FORM_sdata: return "DW_FORM_sdata";
172 case DW_FORM_strp: return "DW_FORM_strp";
173 case DW_FORM_udata: return "DW_FORM_udata";
174 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
175 case DW_FORM_ref1: return "DW_FORM_ref1";
176 case DW_FORM_ref2: return "DW_FORM_ref2";
177 case DW_FORM_ref4: return "DW_FORM_ref4";
178 case DW_FORM_ref8: return "DW_FORM_ref8";
179 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
180 case DW_FORM_indirect: return "DW_FORM_indirect";
tomfba428c2010-04-28 08:09:30 +0000181 case DW_FORM_sec_offset:return "DW_FORM_sec_offset";
182 case DW_FORM_exprloc: return "DW_FORM_exprloc";
183 case DW_FORM_flag_present:return "DW_FORM_flag_present";
184 case DW_FORM_ref_sig8: return "DW_FORM_ref_sig8";
sewardjf7c97142012-07-14 09:59:01 +0000185 case DW_FORM_GNU_ref_alt:return "DW_FORM_GNU_ref_alt";
186 case DW_FORM_GNU_strp_alt:return "DW_FORM_GNU_strp_alt";
sewardjb8b79ad2008-03-03 01:35:41 +0000187 }
bartdac47792012-01-16 09:22:25 +0000188 return "DW_FORM_???";
sewardjb8b79ad2008-03-03 01:35:41 +0000189}
190
florian6bd9dc12012-11-23 16:17:43 +0000191const HChar* ML_(pp_DW_AT) ( DW_AT attr )
sewardjb8b79ad2008-03-03 01:35:41 +0000192{
193 switch (attr) {
194 case DW_AT_sibling: return "DW_AT_sibling";
195 case DW_AT_location: return "DW_AT_location";
196 case DW_AT_name: return "DW_AT_name";
197 case DW_AT_ordering: return "DW_AT_ordering";
198 case DW_AT_subscr_data: return "DW_AT_subscr_data";
199 case DW_AT_byte_size: return "DW_AT_byte_size";
200 case DW_AT_bit_offset: return "DW_AT_bit_offset";
201 case DW_AT_bit_size: return "DW_AT_bit_size";
202 case DW_AT_element_list: return "DW_AT_element_list";
203 case DW_AT_stmt_list: return "DW_AT_stmt_list";
204 case DW_AT_low_pc: return "DW_AT_low_pc";
205 case DW_AT_high_pc: return "DW_AT_high_pc";
206 case DW_AT_language: return "DW_AT_language";
207 case DW_AT_member: return "DW_AT_member";
208 case DW_AT_discr: return "DW_AT_discr";
209 case DW_AT_discr_value: return "DW_AT_discr_value";
210 case DW_AT_visibility: return "DW_AT_visibility";
211 case DW_AT_import: return "DW_AT_import";
212 case DW_AT_string_length: return "DW_AT_string_length";
213 case DW_AT_common_reference: return "DW_AT_common_reference";
214 case DW_AT_comp_dir: return "DW_AT_comp_dir";
215 case DW_AT_const_value: return "DW_AT_const_value";
216 case DW_AT_containing_type: return "DW_AT_containing_type";
217 case DW_AT_default_value: return "DW_AT_default_value";
218 case DW_AT_inline: return "DW_AT_inline";
219 case DW_AT_is_optional: return "DW_AT_is_optional";
220 case DW_AT_lower_bound: return "DW_AT_lower_bound";
221 case DW_AT_producer: return "DW_AT_producer";
222 case DW_AT_prototyped: return "DW_AT_prototyped";
223 case DW_AT_return_addr: return "DW_AT_return_addr";
224 case DW_AT_start_scope: return "DW_AT_start_scope";
225 case DW_AT_stride_size: return "DW_AT_stride_size";
226 case DW_AT_upper_bound: return "DW_AT_upper_bound";
227 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
228 case DW_AT_accessibility: return "DW_AT_accessibility";
229 case DW_AT_address_class: return "DW_AT_address_class";
230 case DW_AT_artificial: return "DW_AT_artificial";
231 case DW_AT_base_types: return "DW_AT_base_types";
232 case DW_AT_calling_convention: return "DW_AT_calling_convention";
233 case DW_AT_count: return "DW_AT_count";
234 case DW_AT_data_member_location: return "DW_AT_data_member_location";
235 case DW_AT_decl_column: return "DW_AT_decl_column";
236 case DW_AT_decl_file: return "DW_AT_decl_file";
237 case DW_AT_decl_line: return "DW_AT_decl_line";
238 case DW_AT_declaration: return "DW_AT_declaration";
239 case DW_AT_discr_list: return "DW_AT_discr_list";
240 case DW_AT_encoding: return "DW_AT_encoding";
241 case DW_AT_external: return "DW_AT_external";
242 case DW_AT_frame_base: return "DW_AT_frame_base";
243 case DW_AT_friend: return "DW_AT_friend";
244 case DW_AT_identifier_case: return "DW_AT_identifier_case";
245 case DW_AT_macro_info: return "DW_AT_macro_info";
246 case DW_AT_namelist_items: return "DW_AT_namelist_items";
247 case DW_AT_priority: return "DW_AT_priority";
248 case DW_AT_segment: return "DW_AT_segment";
249 case DW_AT_specification: return "DW_AT_specification";
250 case DW_AT_static_link: return "DW_AT_static_link";
251 case DW_AT_type: return "DW_AT_type";
252 case DW_AT_use_location: return "DW_AT_use_location";
253 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
254 case DW_AT_virtuality: return "DW_AT_virtuality";
255 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
256 /* DWARF 3 values. */
257 case DW_AT_allocated: return "DW_AT_allocated";
258 case DW_AT_associated: return "DW_AT_associated";
259 case DW_AT_data_location: return "DW_AT_data_location";
260 case DW_AT_stride: return "DW_AT_stride";
261 case DW_AT_entry_pc: return "DW_AT_entry_pc";
262 case DW_AT_use_UTF8: return "DW_AT_use_UTF8";
263 case DW_AT_extension: return "DW_AT_extension";
264 case DW_AT_ranges: return "DW_AT_ranges";
265 case DW_AT_trampoline: return "DW_AT_trampoline";
266 case DW_AT_call_column: return "DW_AT_call_column";
267 case DW_AT_call_file: return "DW_AT_call_file";
268 case DW_AT_call_line: return "DW_AT_call_line";
269 case DW_AT_description: return "DW_AT_description";
270 case DW_AT_binary_scale: return "DW_AT_binary_scale";
271 case DW_AT_decimal_scale: return "DW_AT_decimal_scale";
272 case DW_AT_small: return "DW_AT_small";
273 case DW_AT_decimal_sign: return "DW_AT_decimal_sign";
274 case DW_AT_digit_count: return "DW_AT_digit_count";
275 case DW_AT_picture_string: return "DW_AT_picture_string";
276 case DW_AT_mutable: return "DW_AT_mutable";
277 case DW_AT_threads_scaled: return "DW_AT_threads_scaled";
278 case DW_AT_explicit: return "DW_AT_explicit";
279 case DW_AT_object_pointer: return "DW_AT_object_pointer";
280 case DW_AT_endianity: return "DW_AT_endianity";
281 case DW_AT_elemental: return "DW_AT_elemental";
282 case DW_AT_pure: return "DW_AT_pure";
283 case DW_AT_recursive: return "DW_AT_recursive";
tomfba428c2010-04-28 08:09:30 +0000284 /* DWARF 4 values. */
285 case DW_AT_signature: return "DW_AT_signature";
286 case DW_AT_main_subprogram: return "DW_AT_main_subprogram";
287 case DW_AT_data_bit_offset: return "DW_AT_data_bit_offset";
288 case DW_AT_const_expr: return "DW_AT_const_expr";
289 case DW_AT_enum_class: return "DW_AT_enum_class";
290 case DW_AT_linkage_name: return "DW_AT_linkage_name";
sewardjb8b79ad2008-03-03 01:35:41 +0000291 /* SGI/MIPS extensions. */
292 /* case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde"; */
293 /* DW_AT_MIPS_fde == DW_AT_HP_unmodifiable */
294 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
295 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
296 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
297 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
298 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
299 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
300 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
301 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
302 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
303 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
304 /* HP extensions. */
305 case DW_AT_HP_block_index: return "DW_AT_HP_block_index";
306 case DW_AT_HP_unmodifiable: return "DW_AT_HP_unmodifiable";
307 case DW_AT_HP_actuals_stmt_list: return "DW_AT_HP_actuals_stmt_list";
308 case DW_AT_HP_proc_per_section: return "DW_AT_HP_proc_per_section";
309 case DW_AT_HP_raw_data_ptr: return "DW_AT_HP_raw_data_ptr";
310 case DW_AT_HP_pass_by_reference: return "DW_AT_HP_pass_by_reference";
311 case DW_AT_HP_opt_level: return "DW_AT_HP_opt_level";
312 case DW_AT_HP_prof_version_id: return "DW_AT_HP_prof_version_id";
313 case DW_AT_HP_opt_flags: return "DW_AT_HP_opt_flags";
314 case DW_AT_HP_cold_region_low_pc: return "DW_AT_HP_cold_region_low_pc";
315 case DW_AT_HP_cold_region_high_pc: return "DW_AT_HP_cold_region_high_pc";
316 case DW_AT_HP_all_variables_modifiable: return "DW_AT_HP_all_variables_modifiable";
317 case DW_AT_HP_linkage_name: return "DW_AT_HP_linkage_name";
318 case DW_AT_HP_prof_flags: return "DW_AT_HP_prof_flags";
319 /* GNU extensions. */
320 case DW_AT_sf_names: return "DW_AT_sf_names";
321 case DW_AT_src_info: return "DW_AT_src_info";
322 case DW_AT_mac_info: return "DW_AT_mac_info";
323 case DW_AT_src_coords: return "DW_AT_src_coords";
324 case DW_AT_body_begin: return "DW_AT_body_begin";
325 case DW_AT_body_end: return "DW_AT_body_end";
326 case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
327 /* VMS extensions. */
328 case DW_AT_VMS_rtnbeg_pd_address: return "DW_AT_VMS_rtnbeg_pd_address";
329 /* UPC extension. */
330 case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled";
331 /* PGI (STMicroelectronics) extensions. */
332 case DW_AT_PGI_lbase: return "DW_AT_PGI_lbase";
333 case DW_AT_PGI_soffset: return "DW_AT_PGI_soffset";
334 case DW_AT_PGI_lstride: return "DW_AT_PGI_lstride";
sewardjb8b79ad2008-03-03 01:35:41 +0000335 }
bartdac47792012-01-16 09:22:25 +0000336 return "DW_AT_???";
sewardjb8b79ad2008-03-03 01:35:41 +0000337}
338
339
340/* ------ To do with evaluation of Dwarf expressions ------ */
341
342/* FIXME: duplicated in readdwarf.c */
343static
344ULong read_leb128 ( UChar* data, Int* length_return, Int sign )
345{
346 ULong result = 0;
347 UInt num_read = 0;
348 Int shift = 0;
349 UChar byte;
350
351 vg_assert(sign == 0 || sign == 1);
352
353 do
354 {
355 byte = * data ++;
356 num_read ++;
357
358 result |= ((ULong)(byte & 0x7f)) << shift;
359
360 shift += 7;
361
362 }
363 while (byte & 0x80);
364
365 if (length_return != NULL)
366 * length_return = num_read;
367
368 if (sign && (shift < 64) && (byte & 0x40))
369 result |= -(1ULL << shift);
370
371 return result;
372}
373
374/* Small helper functions easier to use
375 * value is returned and the given pointer is
376 * moved past end of leb128 data */
377/* FIXME: duplicated in readdwarf.c */
378static ULong read_leb128U( UChar **data )
379{
380 Int len;
381 ULong val = read_leb128( *data, &len, 0 );
382 *data += len;
383 return val;
384}
385
386/* Same for signed data */
387/* FIXME: duplicated in readdwarf.c */
388static Long read_leb128S( UChar **data )
389{
390 Int len;
391 ULong val = read_leb128( *data, &len, 1 );
392 *data += len;
393 return (Long)val;
394}
395
sewardjb8b79ad2008-03-03 01:35:41 +0000396/* FIXME: duplicates logic in readdwarf.c: copy_convert_CfiExpr_tree
397 and {FP,SP}_REG decls */
398static Bool get_Dwarf_Reg( /*OUT*/Addr* a, Word regno, RegSummary* regs )
399{
400 vg_assert(regs);
njnf76d27a2009-05-28 01:53:07 +0000401# if defined(VGP_x86_linux) || defined(VGP_x86_darwin)
sewardjb8b79ad2008-03-03 01:35:41 +0000402 if (regno == 5/*EBP*/) { *a = regs->fp; return True; }
403 if (regno == 4/*ESP*/) { *a = regs->sp; return True; }
njnf76d27a2009-05-28 01:53:07 +0000404# elif defined(VGP_amd64_linux) || defined(VGP_amd64_darwin)
njnde706e32009-05-20 02:27:00 +0000405 if (regno == 6/*RBP*/) { *a = regs->fp; return True; }
406 if (regno == 7/*RSP*/) { *a = regs->sp; return True; }
sewardjb8b79ad2008-03-03 01:35:41 +0000407# elif defined(VGP_ppc32_linux)
408 if (regno == 1/*SP*/) { *a = regs->sp; return True; }
sewardjb8b79ad2008-03-03 01:35:41 +0000409# elif defined(VGP_ppc64_linux)
410 if (regno == 1/*SP*/) { *a = regs->sp; return True; }
sewardj59570ff2010-01-01 11:59:33 +0000411# elif defined(VGP_arm_linux)
412 if (regno == 13) { *a = regs->sp; return True; }
413 if (regno == 11) { *a = regs->fp; return True; }
sewardjb5b87402011-03-07 16:05:35 +0000414# elif defined(VGP_s390x_linux)
415 if (regno == 15) { *a = regs->sp; return True; }
416 if (regno == 11) { *a = regs->fp; return True; }
sewardj5db15402012-06-07 09:13:21 +0000417# elif defined(VGP_mips32_linux)
418 if (regno == 29) { *a = regs->sp; return True; }
419 if (regno == 30) { *a = regs->fp; return True; }
petarj4df0bfc2013-02-27 23:17:33 +0000420# elif defined(VGP_mips64_linux)
421 if (regno == 29) { *a = regs->sp; return True; }
422 if (regno == 30) { *a = regs->fp; return True; }
sewardjf0c12502014-01-12 12:54:00 +0000423# elif defined(VGP_arm64_linux)
424 I_die_here;
sewardjb8b79ad2008-03-03 01:35:41 +0000425# else
426# error "Unknown platform"
427# endif
428 return False;
429}
430
tom588658b2009-01-22 13:40:12 +0000431/* Convert a stated address to an actual address */
432static Bool bias_address( Addr* a, const DebugInfo* di )
433{
434 if (di->text_present
435 && di->text_size > 0
tom402c9ee2009-03-09 09:19:03 +0000436 && *a >= di->text_debug_svma && *a < di->text_debug_svma + di->text_size) {
437 *a += di->text_debug_bias;
tom588658b2009-01-22 13:40:12 +0000438 }
439 else if (di->data_present
440 && di->data_size > 0
tom402c9ee2009-03-09 09:19:03 +0000441 && *a >= di->data_debug_svma && *a < di->data_debug_svma + di->data_size) {
442 *a += di->data_debug_bias;
tom588658b2009-01-22 13:40:12 +0000443 }
444 else if (di->sdata_present
445 && di->sdata_size > 0
tom402c9ee2009-03-09 09:19:03 +0000446 && *a >= di->sdata_debug_svma && *a < di->sdata_debug_svma + di->sdata_size) {
447 *a += di->sdata_debug_bias;
tom588658b2009-01-22 13:40:12 +0000448 }
tom160d5a82009-01-22 14:14:13 +0000449 else if (di->rodata_present
450 && di->rodata_size > 0
tom402c9ee2009-03-09 09:19:03 +0000451 && *a >= di->rodata_debug_svma && *a < di->rodata_debug_svma + di->rodata_size) {
452 *a += di->rodata_debug_bias;
tom160d5a82009-01-22 14:14:13 +0000453 }
tom588658b2009-01-22 13:40:12 +0000454 else if (di->bss_present
455 && di->bss_size > 0
tom402c9ee2009-03-09 09:19:03 +0000456 && *a >= di->bss_debug_svma && *a < di->bss_debug_svma + di->bss_size) {
457 *a += di->bss_debug_bias;
tom588658b2009-01-22 13:40:12 +0000458 }
tom160d5a82009-01-22 14:14:13 +0000459 else if (di->sbss_present
460 && di->sbss_size > 0
tom402c9ee2009-03-09 09:19:03 +0000461 && *a >= di->sbss_debug_svma && *a < di->sbss_debug_svma + di->sbss_size) {
462 *a += di->sbss_debug_bias;
tom160d5a82009-01-22 14:14:13 +0000463 }
tom588658b2009-01-22 13:40:12 +0000464 else {
465 return False;
466 }
467
468 return True;
469}
470
sewardjb8b79ad2008-03-03 01:35:41 +0000471
472/* Evaluate a standard DWARF3 expression. See detailed description in
tom3c9cf342009-11-12 13:28:34 +0000473 priv_d3basics.h. Doesn't handle DW_OP_piece/DW_OP_bit_piece yet. */
sewardjb8b79ad2008-03-03 01:35:41 +0000474GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB,
475 GExpr* fbGX, RegSummary* regs,
tom588658b2009-01-22 13:40:12 +0000476 const DebugInfo* di,
sewardjb8b79ad2008-03-03 01:35:41 +0000477 Bool push_initial_zero )
478{
479# define N_EXPR_STACK 20
480
481# define FAIL(_str) \
482 do { \
483 res.kind = GXR_Failure; \
484 res.word = (UWord)(_str); \
485 return res; \
486 } while (0)
487
488# define PUSH(_arg) \
489 do { \
490 vg_assert(sp >= -1 && sp < N_EXPR_STACK); \
491 if (sp == N_EXPR_STACK-1) \
492 FAIL("evaluate_Dwarf3_Expr: stack overflow(1)"); \
493 sp++; \
494 stack[sp] = (_arg); \
495 } while (0)
496
497# define POP(_lval) \
498 do { \
499 vg_assert(sp >= -1 && sp < N_EXPR_STACK); \
500 if (sp == -1) \
501 FAIL("evaluate_Dwarf3_Expr: stack underflow(1)"); \
502 _lval = stack[sp]; \
503 sp--; \
504 } while (0)
505
506 UChar opcode;
507 UChar* limit;
508 Int sp; /* # of top element: valid is -1 .. N_EXPR_STACK-1 */
509 Addr stack[N_EXPR_STACK]; /* stack of addresses, as per D3 spec */
510 GXResult fbval, res;
511 Addr a1;
tom3c9cf342009-11-12 13:28:34 +0000512 Word sw1, sw2;
513 UWord uw1, uw2;
sewardjb8b79ad2008-03-03 01:35:41 +0000514 Bool ok;
515
516 sp = -1;
517 vg_assert(expr);
518 vg_assert(exprszB >= 0);
519 limit = expr + exprszB;
520
521 /* Deal with the case where the entire expression is a single
522 Register Name Operation (D3 spec sec 2.6.1). Then the
523 denotation of the expression as a whole is a register name. */
524 if (exprszB == 1
525 && expr[0] >= DW_OP_reg0 && expr[0] <= DW_OP_reg31) {
526 res.kind = GXR_RegNo;
527 res.word = (UWord)(expr[0] - DW_OP_reg0);
528 return res;
529 }
530 if (exprszB > 1
531 && expr[0] == DW_OP_regx) {
532 /* JRS: 2008Feb20: I believe the following is correct, but would
533 like to see a test case show up before enabling it. */
sewardjb8b79ad2008-03-03 01:35:41 +0000534 expr++;
535 res.kind = GXR_RegNo;
536 res.word = (UWord)read_leb128U( &expr );
537 if (expr != limit)
538 FAIL("evaluate_Dwarf3_Expr: DW_OP_regx*: invalid expr size");
539 else
540 return res;
541 /*NOTREACHED*/
542 }
543
sewardj9c606bd2008-09-18 18:12:50 +0000544 /* Evidently this expression denotes a value, not a register name.
sewardjb8b79ad2008-03-03 01:35:41 +0000545 So evaluate it accordingly. */
546
547 if (push_initial_zero)
548 PUSH(0);
549
550 while (True) {
551
552 vg_assert(sp >= -1 && sp < N_EXPR_STACK);
553
554 if (expr > limit)
555 /* overrun - something's wrong */
556 FAIL("evaluate_Dwarf3_Expr: ran off end of expr");
557
558 if (expr == limit) {
559 /* end of expr - return expr on the top of stack. */
560 if (sp == -1)
561 /* stack empty. Bad. */
562 FAIL("evaluate_Dwarf3_Expr: stack empty at end of expr");
563 else
564 break;
565 }
566
567 opcode = *expr++;
568 switch (opcode) {
569 case DW_OP_addr:
570 /* Presumably what is given in the Dwarf3 is a SVMA (how
tom402c9ee2009-03-09 09:19:03 +0000571 could it be otherwise?) So we add the appropriate bias
572 on before pushing the result. */
tom86781fa2011-10-05 08:48:07 +0000573 a1 = ML_(read_Addr)(expr);
tom588658b2009-01-22 13:40:12 +0000574 if (bias_address(&a1, di)) {
575 PUSH( a1 );
576 expr += sizeof(Addr);
577 }
578 else {
579 FAIL("evaluate_Dwarf3_Expr: DW_OP_addr with address "
580 "in unknown section");
581 }
sewardjb8b79ad2008-03-03 01:35:41 +0000582 break;
583 case DW_OP_fbreg:
584 if (!fbGX)
585 FAIL("evaluate_Dwarf3_Expr: DW_OP_fbreg with "
586 "no expr for fbreg present");
tom588658b2009-01-22 13:40:12 +0000587 fbval = ML_(evaluate_GX)(fbGX, NULL, regs, di);
sewardjb8b79ad2008-03-03 01:35:41 +0000588 /* Convert fbval into something we can use. If we got a
589 Value, no problem. However, as per D3 spec sec 3.3.5
590 (Low Level Information) sec 2, we could also get a
591 RegNo, and that is taken to mean the value in the
592 indicated register. So we have to manually
593 "dereference" it. */
594 a1 = 0;
595 switch (fbval.kind) {
596 case GXR_Failure:
597 return fbval; /* propagate failure */
tom3c9cf342009-11-12 13:28:34 +0000598 case GXR_Addr:
sewardjb8b79ad2008-03-03 01:35:41 +0000599 a1 = fbval.word; break; /* use as-is */
600 case GXR_RegNo:
601 ok = get_Dwarf_Reg( &a1, fbval.word, regs );
602 if (!ok) return fbval; /* propagate failure */
603 break;
tom3c9cf342009-11-12 13:28:34 +0000604 case GXR_Value:
605 FAIL("evaluate_Dwarf3_Expr: DW_OP_{implicit,stack}_value "
606 "in DW_AT_frame_base");
sewardjb8b79ad2008-03-03 01:35:41 +0000607 default:
608 vg_assert(0);
609 }
610 sw1 = (Word)read_leb128S( &expr );
611 PUSH( a1 + sw1 );
612 break;
613 /* DW_OP_breg* denotes 'contents of specified register, plus
614 constant offset'. So provided we know what the register's
615 value is, we can evaluate this. Contrast DW_OP_reg*,
616 which indicates that denoted location is in a register
617 itself. If DW_OP_reg* shows up here the expression is
618 malformed, since we are evaluating for value now, and
619 DW_OP_reg* denotes a register location, not a value. See
620 D3 Spec sec 2.6.1 ("Register Name Operations") for
621 details. */
622 case DW_OP_breg0 ... DW_OP_breg31:
623 if (!regs)
624 FAIL("evaluate_Dwarf3_Expr: DW_OP_breg* but no reg info");
625 a1 = 0;
626 if (!get_Dwarf_Reg( &a1, opcode - DW_OP_breg0, regs ))
627 FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_breg*");
628 sw1 = (Word)read_leb128S( &expr );
629 a1 += sw1;
630 PUSH( a1 );
631 break;
tom3c9cf342009-11-12 13:28:34 +0000632 case DW_OP_bregx:
633 if (!regs)
634 FAIL("evaluate_Dwarf3_Expr: DW_OP_bregx but no reg info");
635 a1 = 0;
636 uw1 = (UWord)read_leb128U( &expr );
637 if (!get_Dwarf_Reg( &a1, uw1, regs ))
638 FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_bregx reg value");
639 sw1 = (Word)read_leb128S( &expr );
640 a1 += sw1;
641 PUSH( a1 );
642 break;
sewardjb8b79ad2008-03-03 01:35:41 +0000643 /* As per comment on DW_OP_breg*, the following denote that
644 the value in question is in a register, not in memory. So
645 we simply return failure. (iow, the expression is
646 malformed). */
647 case DW_OP_reg0 ... DW_OP_reg31:
tom3c9cf342009-11-12 13:28:34 +0000648 case DW_OP_regx:
sewardjb8b79ad2008-03-03 01:35:41 +0000649 FAIL("evaluate_Dwarf3_Expr: DW_OP_reg* "
650 "whilst evaluating for a value");
651 break;
652 case DW_OP_plus_uconst:
653 POP(uw1);
654 uw1 += (UWord)read_leb128U( &expr );
655 PUSH(uw1);
656 break;
657 case DW_OP_GNU_push_tls_address:
658 /* GDB contains the following cryptic comment: */
659 /* Variable is at a constant offset in the thread-local
660 storage block into the objfile for the current thread and
661 the dynamic linker module containing this expression. Here
662 we return returns the offset from that base. The top of the
663 stack has the offset from the beginning of the thread
664 control block at which the variable is located. Nothing
665 should follow this operator, so the top of stack would be
666 returned. */
667 /* But no spec resulting from Googling. Punt for now. */
668 FAIL("warning: evaluate_Dwarf3_Expr: unhandled "
669 "DW_OP_GNU_push_tls_address");
670 /*NOTREACHED*/
sewardjaa3c28a2008-03-08 10:44:39 +0000671 case DW_OP_deref:
672 POP(uw1);
673 if (VG_(am_is_valid_for_client)( (Addr)uw1, sizeof(Addr),
674 VKI_PROT_READ )) {
tom86781fa2011-10-05 08:48:07 +0000675 uw1 = ML_(read_UWord)((void *)uw1);
sewardjaa3c28a2008-03-08 10:44:39 +0000676 PUSH(uw1);
677 } else {
678 FAIL("warning: evaluate_Dwarf3_Expr: DW_OP_deref: "
679 "address not valid for client");
680 }
681 break;
tom3c9cf342009-11-12 13:28:34 +0000682 case DW_OP_deref_size:
683 POP(uw1);
684 uw2 = *expr++;
685 if (VG_(am_is_valid_for_client)( (Addr)uw1, uw2,
686 VKI_PROT_READ )) {
687 switch (uw2) {
tom86781fa2011-10-05 08:48:07 +0000688 case 1: uw1 = ML_(read_UChar)((void*)uw1); break;
689 case 2: uw1 = ML_(read_UShort)((void*)uw1); break;
690 case 4: uw1 = ML_(read_UInt)((void*)uw1); break;
691 case 8: uw1 = ML_(read_ULong)((void*)uw1); break;
tom3c9cf342009-11-12 13:28:34 +0000692 default:
693 FAIL("warning: evaluate_Dwarf3_Expr: unhandled "
694 "DW_OP_deref_size size");
695 }
696 PUSH(uw1);
697 } else {
698 FAIL("warning: evaluate_Dwarf3_Expr: DW_OP_deref_size: "
699 "address not valid for client");
700 }
701 break;
702 case DW_OP_lit0 ... DW_OP_lit31:
703 PUSH(opcode - DW_OP_lit0);
704 break;
705 case DW_OP_const1u:
706 uw1 = *expr++;
707 PUSH(uw1);
708 break;
709 case DW_OP_const2u:
tom86781fa2011-10-05 08:48:07 +0000710 uw1 = ML_(read_UShort)(expr);
tom3c9cf342009-11-12 13:28:34 +0000711 expr += 2;
712 PUSH(uw1);
713 break;
714 case DW_OP_const4u:
tom86781fa2011-10-05 08:48:07 +0000715 uw1 = ML_(read_UInt)(expr);
tom3c9cf342009-11-12 13:28:34 +0000716 expr += 4;
717 PUSH(uw1);
718 break;
719 case DW_OP_const8u:
tom86781fa2011-10-05 08:48:07 +0000720 uw1 = ML_(read_ULong)(expr);
tom3c9cf342009-11-12 13:28:34 +0000721 expr += 8;
722 PUSH(uw1);
723 break;
724 case DW_OP_constu:
725 uw1 = read_leb128U( &expr );
726 PUSH(uw1);
727 break;
728 case DW_OP_const1s:
729 uw1 = *(Char *)expr;
730 expr++;
731 PUSH(uw1);
732 break;
733 case DW_OP_const2s:
tom86781fa2011-10-05 08:48:07 +0000734 uw1 = ML_(read_Short)(expr);
tom3c9cf342009-11-12 13:28:34 +0000735 expr += 2;
736 PUSH(uw1);
737 break;
738 case DW_OP_const4s:
tom86781fa2011-10-05 08:48:07 +0000739 uw1 = ML_(read_Int)(expr);
tom3c9cf342009-11-12 13:28:34 +0000740 expr += 4;
741 PUSH(uw1);
742 break;
743 case DW_OP_const8s:
tom86781fa2011-10-05 08:48:07 +0000744 uw1 = ML_(read_Long)(expr);
tom3c9cf342009-11-12 13:28:34 +0000745 expr += 8;
746 PUSH(uw1);
747 break;
748 case DW_OP_consts:
749 uw1 = read_leb128S( &expr );
750 PUSH(uw1);
751 break;
752 case DW_OP_dup:
753 POP(uw1);
754 PUSH(uw1);
755 PUSH(uw1);
756 break;
757 case DW_OP_drop:
758 POP(uw1);
759 break;
760 case DW_OP_over:
761 uw1 = 1;
762 goto do_pick;
763 case DW_OP_pick:
764 uw1 = *expr++;
765 do_pick:
766 if (sp < (Int)uw1)
767 FAIL("evaluate_Dwarf3_Expr: stack underflow");
768 uw1 = stack[sp - uw1];
769 PUSH(uw1);
770 break;
771 case DW_OP_swap:
772 if (sp < 1)
773 FAIL("evaluate_Dwarf3_Expr: stack underflow");
774 uw1 = stack[sp];
775 stack[sp] = stack[sp - 1];
776 stack[sp - 1] = uw1;
777 break;
778 case DW_OP_rot:
779 if (sp < 2)
780 FAIL("evaluate_Dwarf3_Expr: stack underflow");
781 uw1 = stack[sp];
782 stack[sp] = stack[sp - 1];
783 stack[sp - 1] = stack[sp - 2];
784 stack[sp - 2] = uw1;
785 break;
786 case DW_OP_abs:
787 POP(sw1);
788 if (sw1 < 0)
789 sw1 = -sw1;
790 PUSH(sw1);
791 break;
792 case DW_OP_div:
793 POP(sw2);
794 if (sw2 == 0)
795 FAIL("evaluate_Dwarf3_Expr: division by zero");
796 POP(sw1);
797 sw1 /= sw2;
798 PUSH(sw1);
799 break;
800 case DW_OP_mod:
tomb9c17d22010-01-21 10:19:46 +0000801 POP(uw2);
802 if (uw2 == 0)
tom3c9cf342009-11-12 13:28:34 +0000803 FAIL("evaluate_Dwarf3_Expr: division by zero");
tomb9c17d22010-01-21 10:19:46 +0000804 POP(uw1);
805 uw1 %= uw2;
806 PUSH(uw1);
tom3c9cf342009-11-12 13:28:34 +0000807 break;
808#define BINARY(name, op, s) \
809 case DW_OP_##name: \
810 POP(s##w2); \
811 POP(s##w1); \
812 s##w1 = s##w1 op s##w2; \
813 PUSH(s##w1); \
814 break
815#define UNARY(name, op, s) \
816 case DW_OP_##name: \
817 POP(s##w1); \
818 s##w1 = op s##w1; \
819 PUSH(s##w1); \
820 break
821 BINARY (and, &, u);
822 BINARY (minus, -, u);
823 BINARY (mul, *, u);
824 UNARY (neg, -, u);
825 UNARY (not, ~, u);
826 BINARY (or, |, u);
827 BINARY (plus, +, u);
828 BINARY (shl, <<, u);
829 BINARY (shr, >>, u);
830 BINARY (shra, >>, s);
831 BINARY (xor, ^, u);
832 BINARY (le, <=, s);
833 BINARY (lt, <, s);
834 BINARY (ge, >=, s);
835 BINARY (gt, >, s);
836 BINARY (ne, !=, u);
837 BINARY (eq, ==, u);
838#undef UNARY
839#undef BINARY
840 case DW_OP_skip:
tom86781fa2011-10-05 08:48:07 +0000841 sw1 = ML_(read_Short)(expr);
tom3c9cf342009-11-12 13:28:34 +0000842 expr += 2;
843 if (expr + sw1 < limit - exprszB)
844 FAIL("evaluate_Dwarf3_Expr: DW_OP_skip before start of expr");
845 if (expr + sw1 >= limit)
846 FAIL("evaluate_Dwarf3_Expr: DW_OP_skip after end of expr");
847 expr += sw1;
848 break;
849 case DW_OP_bra:
tom86781fa2011-10-05 08:48:07 +0000850 sw1 = ML_(read_Short)(expr);
tom3c9cf342009-11-12 13:28:34 +0000851 expr += 2;
852 if (expr + sw1 < limit - exprszB)
853 FAIL("evaluate_Dwarf3_Expr: DW_OP_bra before start of expr");
854 if (expr + sw1 >= limit)
855 FAIL("evaluate_Dwarf3_Expr: DW_OP_bra after end of expr");
856 POP(uw1);
857 if (uw1)
858 expr += sw1;
859 break;
860 case DW_OP_nop:
861 break;
862 case DW_OP_call_frame_cfa:
863 if (!regs)
sewardj3026f712010-01-01 18:46:41 +0000864 FAIL("evaluate_Dwarf3_Expr: "
865 "DW_OP_call_frame_cfa but no reg info");
tom3c9cf342009-11-12 13:28:34 +0000866#if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
sewardj3026f712010-01-01 18:46:41 +0000867 /* Valgrind on ppc32/ppc64 currently doesn't use unwind info. */
sewardj50f5cea2011-10-20 10:41:37 +0000868 uw1 = ML_(read_Addr)((UChar*)regs->sp);
tom3c9cf342009-11-12 13:28:34 +0000869#else
870 uw1 = ML_(get_CFA)(regs->ip, regs->sp, regs->fp, 0, ~(UWord) 0);
871#endif
sewardj3026f712010-01-01 18:46:41 +0000872 /* we expect this to fail on arm-linux, since ML_(get_CFA)
873 always returns zero at present. */
tom3c9cf342009-11-12 13:28:34 +0000874 if (!uw1)
875 FAIL("evaluate_Dwarf3_Expr: Could not resolve "
876 "DW_OP_call_frame_cfa");
877 PUSH(uw1);
878 break;
879 case DW_OP_implicit_value:
880 sw1 = (Word)read_leb128S( &expr );
881 uw1 = 0;
882 switch (sw1) {
883 case 1:
tom86781fa2011-10-05 08:48:07 +0000884 uw1 = ML_(read_UChar)(expr);
tom3c9cf342009-11-12 13:28:34 +0000885 expr += 1;
886 break;
887 case 2:
tom86781fa2011-10-05 08:48:07 +0000888 uw1 = ML_(read_UShort)(expr);
tom3c9cf342009-11-12 13:28:34 +0000889 expr += 2;
890 break;
891 case 4:
tom86781fa2011-10-05 08:48:07 +0000892 uw1 = ML_(read_UInt)(expr);
tom3c9cf342009-11-12 13:28:34 +0000893 expr += 4;
894 break;
895 case 8:
tom86781fa2011-10-05 08:48:07 +0000896 uw1 = ML_(read_ULong)(expr);
tom3c9cf342009-11-12 13:28:34 +0000897 expr += 8;
898 break;
899 default:
900 FAIL("evaluate_Dwarf3_Expr: Unhandled "
901 "DW_OP_implicit_value size");
902 }
903 if (expr != limit)
904 FAIL("evaluate_Dwarf3_Expr: DW_OP_implicit_value "
905 "does not terminate expression");
906 res.word = uw1;
907 res.kind = GXR_Value;
908 return res;
909 case DW_OP_stack_value:
910 POP (uw1);
911 res.word = uw1;
912 res.kind = GXR_Value;
913 if (expr != limit)
914 FAIL("evaluate_Dwarf3_Expr: DW_OP_stack_value "
915 "does not terminate expression");
916 break;
sewardjb8b79ad2008-03-03 01:35:41 +0000917 default:
918 if (!VG_(clo_xml))
919 VG_(message)(Vg_DebugMsg,
920 "warning: evaluate_Dwarf3_Expr: unhandled "
sewardj738856f2009-07-15 14:48:32 +0000921 "DW_OP_ 0x%x\n", (Int)opcode);
sewardjb8b79ad2008-03-03 01:35:41 +0000922 FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_");
923 /*NOTREACHED*/
924 }
925
926 }
927
928 vg_assert(sp >= 0 && sp < N_EXPR_STACK);
929 res.word = stack[sp];
tom3c9cf342009-11-12 13:28:34 +0000930 res.kind = GXR_Addr;
sewardjb8b79ad2008-03-03 01:35:41 +0000931 return res;
932
933# undef POP
934# undef PUSH
935# undef FAIL
936# undef N_EXPR_STACK
937}
938
939
940/* Evaluate a so-called Guarded (DWARF3) expression. See detailed
941 description in priv_d3basics.h. */
942GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX,
tom588658b2009-01-22 13:40:12 +0000943 RegSummary* regs, const DebugInfo* di )
sewardjb8b79ad2008-03-03 01:35:41 +0000944{
945 GXResult res;
946 Addr aMin, aMax;
947 UChar uc;
948 UShort nbytes;
949 UWord nGuards = 0;
950 UChar* p = &gx->payload[0];
951 uc = *p++; /*biasMe*/
952 vg_assert(uc == 0 || uc == 1);
953 /* in fact it's senseless to evaluate if the guards need biasing.
954 So don't. */
955 vg_assert(uc == 0);
956 while (True) {
957 uc = *p++;
958 if (uc == 1) { /*isEnd*/
959 /* didn't find any matching range. */
960 res.kind = GXR_Failure;
961 res.word = (UWord)"no matching range";
962 return res;
963 }
964 vg_assert(uc == 0);
tom86781fa2011-10-05 08:48:07 +0000965 aMin = ML_(read_Addr)(p); p += sizeof(Addr);
966 aMax = ML_(read_Addr)(p); p += sizeof(Addr);
967 nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
sewardjb8b79ad2008-03-03 01:35:41 +0000968 nGuards++;
barta0b6b2c2008-07-07 06:49:24 +0000969 if (0) VG_(printf)(" guard %d: %#lx %#lx\n",
sewardjb8b79ad2008-03-03 01:35:41 +0000970 (Int)nGuards, aMin,aMax);
971 if (regs == NULL) {
972 vg_assert(aMin == (Addr)0);
973 vg_assert(aMax == ~(Addr)0);
974 /* Assert this is the first guard. */
975 vg_assert(nGuards == 1);
976 res = ML_(evaluate_Dwarf3_Expr)(
tom588658b2009-01-22 13:40:12 +0000977 p, (UWord)nbytes, fbGX, regs, di,
sewardjb8b79ad2008-03-03 01:35:41 +0000978 False/*push_initial_zero*/ );
979 /* Now check there are no more guards. */
980 p += (UWord)nbytes;
981 vg_assert(*p == 1); /*isEnd*/
982 return res;
983 } else {
984 if (aMin <= regs->ip && regs->ip <= aMax) {
985 /* found a matching range. Evaluate the expression. */
986 return ML_(evaluate_Dwarf3_Expr)(
tom588658b2009-01-22 13:40:12 +0000987 p, (UWord)nbytes, fbGX, regs, di,
sewardjb8b79ad2008-03-03 01:35:41 +0000988 False/*push_initial_zero*/ );
989 }
990 }
991 /* else keep searching */
992 p += (UWord)nbytes;
993 }
994}
995
996
sewardj9c606bd2008-09-18 18:12:50 +0000997/* Evaluate a very simple Guarded (DWARF3) expression. The expression
998 is expected to denote a constant, with no reference to any
999 registers nor to any frame base expression. The expression is
1000 expected to have at least one guard. If there is more than one
1001 guard, all the sub-expressions are evaluated and compared. The
1002 address ranges on the guards are ignored. GXR_Failure is returned
1003 in the following circumstances:
1004 * no guards
1005 * any of the subexpressions require a frame base expression
1006 * any of the subexpressions denote a register location
1007 * any of the subexpressions do not produce a manifest constant
1008 * there's more than one subexpression, all of which successfully
1009 evaluate to a constant, but they don't all produce the same constant.
sewardjec3f2ce2009-01-24 00:06:13 +00001010 JRS 23Jan09: the special-casing in this function is a nasty kludge.
1011 Really it ought to be pulled out and turned into a general
1012 constant- expression evaluator.
1013*/
tom588658b2009-01-22 13:40:12 +00001014GXResult ML_(evaluate_trivial_GX)( GExpr* gx, const DebugInfo* di )
sewardj9c606bd2008-09-18 18:12:50 +00001015{
1016 GXResult res;
1017 Addr aMin, aMax;
1018 UChar uc;
1019 UShort nbytes;
1020 Word i, nGuards;
sewardj50fde232008-10-20 16:08:55 +00001021 MaybeULong *mul, *mul2;
sewardj9c606bd2008-09-18 18:12:50 +00001022
florian6bd9dc12012-11-23 16:17:43 +00001023 const HChar* badness = NULL;
sewardjec3f2ce2009-01-24 00:06:13 +00001024 UChar* p = &gx->payload[0]; /* must remain unsigned */
sewardj9c606bd2008-09-18 18:12:50 +00001025 XArray* results = VG_(newXA)( ML_(dinfo_zalloc), "di.d3basics.etG.1",
1026 ML_(dinfo_free),
sewardj50fde232008-10-20 16:08:55 +00001027 sizeof(MaybeULong) );
sewardj9c606bd2008-09-18 18:12:50 +00001028
1029 uc = *p++; /*biasMe*/
1030 vg_assert(uc == 0 || uc == 1);
1031 /* in fact it's senseless to evaluate if the guards need biasing.
1032 So don't. */
1033 vg_assert(uc == 0);
1034
1035 nGuards = 0;
1036 while (True) {
sewardj50fde232008-10-20 16:08:55 +00001037 MaybeULong thisResult;
sewardj9c606bd2008-09-18 18:12:50 +00001038 uc = *p++;
1039 if (uc == 1) /*isEnd*/
1040 break;
1041 vg_assert(uc == 0);
tom86781fa2011-10-05 08:48:07 +00001042 aMin = ML_(read_Addr)(p); p += sizeof(Addr);
1043 aMax = ML_(read_Addr)(p); p += sizeof(Addr);
1044 nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
sewardj9c606bd2008-09-18 18:12:50 +00001045 nGuards++;
1046 if (0) VG_(printf)(" guard %ld: %#lx %#lx\n",
1047 nGuards, aMin,aMax);
1048
sewardj50fde232008-10-20 16:08:55 +00001049 thisResult.b = False;
1050 thisResult.ul = 0;
sewardj9c606bd2008-09-18 18:12:50 +00001051
1052 /* Peer at this particular subexpression, to see if it's
1053 obviously a constant. */
1054 if (nbytes == 1 + sizeof(Addr) && *p == DW_OP_addr) {
sewardjec3f2ce2009-01-24 00:06:13 +00001055 /* DW_OP_addr a */
tom86781fa2011-10-05 08:48:07 +00001056 Addr a = ML_(read_Addr)((p+1));
tom588658b2009-01-22 13:40:12 +00001057 if (bias_address(&a, di)) {
1058 thisResult.b = True;
1059 thisResult.ul = (ULong)a;
sewardjec3f2ce2009-01-24 00:06:13 +00001060 } else {
1061 if (!badness)
1062 badness = "trivial GExpr denotes constant address "
1063 "in unknown section (1)";
tom588658b2009-01-22 13:40:12 +00001064 }
sewardj9c606bd2008-09-18 18:12:50 +00001065 }
sewardjec3f2ce2009-01-24 00:06:13 +00001066 else
1067 if (nbytes == 1 + sizeof(Addr) + 1 + 1
1068 /* 11 byte block: 3 c0 b6 2b 0 0 0 0 0 23 4
1069 (DW_OP_addr: 2bb6c0; DW_OP_plus_uconst: 4)
1070 This is really a nasty kludge - only matches if the
1071 trailing ULEB denotes a number in the range 0 .. 127
1072 inclusive. */
1073 && p[0] == DW_OP_addr
1074 && p[1 + sizeof(Addr)] == DW_OP_plus_uconst
1075 && p[1 + sizeof(Addr) + 1] < 0x80 /*1-byte ULEB*/) {
tom86781fa2011-10-05 08:48:07 +00001076 Addr a = ML_(read_Addr)(&p[1]);
sewardjec3f2ce2009-01-24 00:06:13 +00001077 if (bias_address(&a, di)) {
1078 thisResult.b = True;
1079 thisResult.ul = (ULong)a + (ULong)p[1 + sizeof(Addr) + 1];
1080 } else {
1081 if (!badness)
1082 badness = "trivial GExpr denotes constant address "
1083 "in unknown section (2)";
1084 }
1085 }
1086 else
1087 if (nbytes == 2 + sizeof(Addr)
1088 && *p == DW_OP_addr
1089 && *(p + 1 + sizeof(Addr)) == DW_OP_GNU_push_tls_address) {
sewardj9c606bd2008-09-18 18:12:50 +00001090 if (!badness)
1091 badness = "trivial GExpr is DW_OP_addr plus trailing junk";
1092 }
1093 else if (nbytes >= 1 && *p >= DW_OP_reg0 && *p <= DW_OP_reg31) {
1094 if (!badness)
1095 badness = "trivial GExpr denotes register (1)";
1096 }
1097 else if (nbytes >= 1 && *p == DW_OP_fbreg) {
1098 if (!badness)
1099 badness = "trivial GExpr requires fbGX";
1100 }
1101 else if (nbytes >= 1 && *p >= DW_OP_breg0 && *p <= DW_OP_breg31) {
1102 if (!badness)
1103 badness = "trivial GExpr requires register value";
1104 }
1105 else if (nbytes >= 1 && *p == DW_OP_regx) {
1106 if (!badness)
1107 badness = "trivial GExpr denotes register (2)";
1108 }
tom3c9cf342009-11-12 13:28:34 +00001109 else if (0) {
sewardj9c606bd2008-09-18 18:12:50 +00001110 VG_(printf)(" ML_(evaluate_trivial_GX): unhandled:\n ");
1111 ML_(pp_GX)( gx );
1112 VG_(printf)("\n");
1113 tl_assert(0);
1114 }
tom3c9cf342009-11-12 13:28:34 +00001115 else
1116 if (!badness)
1117 badness = "non-trivial GExpr";
sewardj9c606bd2008-09-18 18:12:50 +00001118
1119 VG_(addToXA)( results, &thisResult );
1120
1121 p += (UWord)nbytes;
1122 }
1123
1124 res.kind = GXR_Failure;
1125
1126 tl_assert(nGuards == VG_(sizeXA)( results ));
1127 tl_assert(nGuards >= 0);
1128 if (nGuards == 0) {
1129 tl_assert(!badness);
1130 res.word = (UWord)"trivial GExpr has no guards (!)";
1131 VG_(deleteXA)( results );
1132 return res;
1133 }
1134
1135 for (i = 0; i < nGuards; i++) {
sewardj50fde232008-10-20 16:08:55 +00001136 mul = VG_(indexXA)( results, i );
1137 if (mul->b == False)
sewardj9c606bd2008-09-18 18:12:50 +00001138 break;
1139 }
1140
1141 vg_assert(i >= 0 && i <= nGuards);
1142 if (i < nGuards) {
1143 /* at least one subexpression failed to produce a manifest constant. */
1144 vg_assert(badness);
1145 res.word = (UWord)badness;
1146 VG_(deleteXA)( results );
1147 return res;
1148 }
1149
1150 /* All the subexpressions produced a constant, but did they all produce
1151 the same one? */
sewardj50fde232008-10-20 16:08:55 +00001152 mul = VG_(indexXA)( results, 0 );
1153 tl_assert(mul->b == True); /* we just established that all exprs are ok */
sewardj9c606bd2008-09-18 18:12:50 +00001154
1155 for (i = 1; i < nGuards; i++) {
sewardj50fde232008-10-20 16:08:55 +00001156 mul2 = VG_(indexXA)( results, i );
1157 tl_assert(mul2->b == True);
1158 if (mul2->ul != mul->ul) {
sewardj9c606bd2008-09-18 18:12:50 +00001159 res.word = (UWord)"trivial GExpr: subexpressions disagree";
1160 VG_(deleteXA)( results );
1161 return res;
1162 }
1163 }
1164
1165 /* Well, we have success. All subexpressions evaluated, and
1166 they all agree. Hurrah. */
tom3c9cf342009-11-12 13:28:34 +00001167 res.kind = GXR_Addr;
sewardj50fde232008-10-20 16:08:55 +00001168 res.word = (UWord)mul->ul; /* NB: narrowing from ULong */
sewardj9c606bd2008-09-18 18:12:50 +00001169 VG_(deleteXA)( results );
1170 return res;
1171}
1172
1173
sewardjb8b79ad2008-03-03 01:35:41 +00001174void ML_(pp_GXResult) ( GXResult res )
1175{
1176 switch (res.kind) {
1177 case GXR_Failure:
1178 VG_(printf)("GXR_Failure(%s)", (HChar*)res.word); break;
tom3c9cf342009-11-12 13:28:34 +00001179 case GXR_Addr:
1180 VG_(printf)("GXR_Addr(0x%lx)", res.word); break;
sewardjb8b79ad2008-03-03 01:35:41 +00001181 case GXR_Value:
1182 VG_(printf)("GXR_Value(0x%lx)", res.word); break;
1183 case GXR_RegNo:
1184 VG_(printf)("GXR_RegNo(%lu)", res.word); break;
1185 default:
1186 VG_(printf)("GXR_???"); break;
1187 }
1188}
1189
1190
sewardj9c606bd2008-09-18 18:12:50 +00001191void ML_(pp_GX) ( GExpr* gx ) {
1192 Addr aMin, aMax;
1193 UChar uc;
1194 UShort nbytes;
1195 UChar* p = &gx->payload[0];
1196 uc = *p++;
1197 VG_(printf)("GX(%s){", uc == 0 ? "final" : "Breqd" );
1198 vg_assert(uc == 0 || uc == 1);
1199 while (True) {
1200 uc = *p++;
1201 if (uc == 1)
1202 break; /*isEnd*/
1203 vg_assert(uc == 0);
tom86781fa2011-10-05 08:48:07 +00001204 aMin = ML_(read_Addr)(p); p += sizeof(Addr);
1205 aMax = ML_(read_Addr)(p); p += sizeof(Addr);
1206 nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
sewardj9c606bd2008-09-18 18:12:50 +00001207 VG_(printf)("[%#lx,%#lx]=", aMin, aMax);
1208 while (nbytes > 0) {
1209 VG_(printf)("%02x", (UInt)*p++);
1210 nbytes--;
1211 }
1212 if (*p == 0)
1213 VG_(printf)(",");
1214 }
1215 VG_(printf)("}");
1216}
1217
1218
sewardjb8b79ad2008-03-03 01:35:41 +00001219/*--------------------------------------------------------------------*/
1220/*--- end d3basics.c ---*/
1221/*--------------------------------------------------------------------*/