blob: 088fa075c479ffe5c8fa9f6045239aa41f4a5c6d [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
Elliott Hughesed398002017-06-21 14:41:24 -070011 Copyright (C) 2008-2017 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";
philippeaf186892014-10-07 21:25:36 +0000327 case DW_AT_GNU_all_tail_call_sites: return "DW_AT_GNU_all_tail_call_sites";
328 case DW_AT_GNU_all_call_sites: return "DW_AT_GNU_all_call_sites";
sewardjb8b79ad2008-03-03 01:35:41 +0000329 /* VMS extensions. */
330 case DW_AT_VMS_rtnbeg_pd_address: return "DW_AT_VMS_rtnbeg_pd_address";
331 /* UPC extension. */
332 case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled";
333 /* PGI (STMicroelectronics) extensions. */
334 case DW_AT_PGI_lbase: return "DW_AT_PGI_lbase";
335 case DW_AT_PGI_soffset: return "DW_AT_PGI_soffset";
336 case DW_AT_PGI_lstride: return "DW_AT_PGI_lstride";
sewardjb8b79ad2008-03-03 01:35:41 +0000337 }
bartdac47792012-01-16 09:22:25 +0000338 return "DW_AT_???";
sewardjb8b79ad2008-03-03 01:35:41 +0000339}
340
341
342/* ------ To do with evaluation of Dwarf expressions ------ */
343
344/* FIXME: duplicated in readdwarf.c */
345static
florian518850b2014-10-22 22:25:30 +0000346ULong read_leb128 ( const UChar* data, Int* length_return, Int sign )
sewardjb8b79ad2008-03-03 01:35:41 +0000347{
348 ULong result = 0;
349 UInt num_read = 0;
350 Int shift = 0;
351 UChar byte;
352
353 vg_assert(sign == 0 || sign == 1);
354
355 do
356 {
357 byte = * data ++;
358 num_read ++;
359
360 result |= ((ULong)(byte & 0x7f)) << shift;
361
362 shift += 7;
363
364 }
365 while (byte & 0x80);
366
367 if (length_return != NULL)
368 * length_return = num_read;
369
370 if (sign && (shift < 64) && (byte & 0x40))
371 result |= -(1ULL << shift);
372
373 return result;
374}
375
376/* Small helper functions easier to use
377 * value is returned and the given pointer is
378 * moved past end of leb128 data */
379/* FIXME: duplicated in readdwarf.c */
florian32971242014-10-23 17:47:15 +0000380static ULong read_leb128U( const UChar **data )
sewardjb8b79ad2008-03-03 01:35:41 +0000381{
382 Int len;
383 ULong val = read_leb128( *data, &len, 0 );
384 *data += len;
385 return val;
386}
387
388/* Same for signed data */
389/* FIXME: duplicated in readdwarf.c */
florian32971242014-10-23 17:47:15 +0000390static Long read_leb128S( const UChar **data )
sewardjb8b79ad2008-03-03 01:35:41 +0000391{
392 Int len;
393 ULong val = read_leb128( *data, &len, 1 );
394 *data += len;
395 return (Long)val;
396}
397
sewardjb8b79ad2008-03-03 01:35:41 +0000398/* FIXME: duplicates logic in readdwarf.c: copy_convert_CfiExpr_tree
399 and {FP,SP}_REG decls */
florian518850b2014-10-22 22:25:30 +0000400static Bool get_Dwarf_Reg( /*OUT*/Addr* a, Word regno, const RegSummary* regs )
sewardjb8b79ad2008-03-03 01:35:41 +0000401{
402 vg_assert(regs);
sewardj8eb8bab2015-07-21 14:44:28 +0000403# if defined(VGP_x86_linux) || defined(VGP_x86_darwin) \
404 || defined(VGP_x86_solaris)
sewardjb8b79ad2008-03-03 01:35:41 +0000405 if (regno == 5/*EBP*/) { *a = regs->fp; return True; }
406 if (regno == 4/*ESP*/) { *a = regs->sp; return True; }
sewardj8eb8bab2015-07-21 14:44:28 +0000407# elif defined(VGP_amd64_linux) || defined(VGP_amd64_darwin) \
408 || defined(VGP_amd64_solaris)
njnde706e32009-05-20 02:27:00 +0000409 if (regno == 6/*RBP*/) { *a = regs->fp; return True; }
410 if (regno == 7/*RSP*/) { *a = regs->sp; return True; }
sewardjb8b79ad2008-03-03 01:35:41 +0000411# elif defined(VGP_ppc32_linux)
412 if (regno == 1/*SP*/) { *a = regs->sp; return True; }
carllcae0cc22014-08-07 23:17:29 +0000413# elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
sewardjb8b79ad2008-03-03 01:35:41 +0000414 if (regno == 1/*SP*/) { *a = regs->sp; return True; }
sewardj59570ff2010-01-01 11:59:33 +0000415# elif defined(VGP_arm_linux)
416 if (regno == 13) { *a = regs->sp; return True; }
417 if (regno == 11) { *a = regs->fp; return True; }
sewardjb5b87402011-03-07 16:05:35 +0000418# elif defined(VGP_s390x_linux)
419 if (regno == 15) { *a = regs->sp; return True; }
420 if (regno == 11) { *a = regs->fp; return True; }
sewardj5db15402012-06-07 09:13:21 +0000421# elif defined(VGP_mips32_linux)
422 if (regno == 29) { *a = regs->sp; return True; }
423 if (regno == 30) { *a = regs->fp; return True; }
petarj4df0bfc2013-02-27 23:17:33 +0000424# elif defined(VGP_mips64_linux)
425 if (regno == 29) { *a = regs->sp; return True; }
426 if (regno == 30) { *a = regs->fp; return True; }
sewardjf0c12502014-01-12 12:54:00 +0000427# elif defined(VGP_arm64_linux)
sewardje22cbf32014-07-15 15:22:41 +0000428 if (regno == 31) { *a = regs->sp; return True; }
sewardjb8b79ad2008-03-03 01:35:41 +0000429# else
430# error "Unknown platform"
431# endif
432 return False;
433}
434
tom588658b2009-01-22 13:40:12 +0000435/* Convert a stated address to an actual address */
436static Bool bias_address( Addr* a, const DebugInfo* di )
437{
438 if (di->text_present
439 && di->text_size > 0
tom402c9ee2009-03-09 09:19:03 +0000440 && *a >= di->text_debug_svma && *a < di->text_debug_svma + di->text_size) {
441 *a += di->text_debug_bias;
tom588658b2009-01-22 13:40:12 +0000442 }
443 else if (di->data_present
444 && di->data_size > 0
tom402c9ee2009-03-09 09:19:03 +0000445 && *a >= di->data_debug_svma && *a < di->data_debug_svma + di->data_size) {
446 *a += di->data_debug_bias;
tom588658b2009-01-22 13:40:12 +0000447 }
448 else if (di->sdata_present
449 && di->sdata_size > 0
tom402c9ee2009-03-09 09:19:03 +0000450 && *a >= di->sdata_debug_svma && *a < di->sdata_debug_svma + di->sdata_size) {
451 *a += di->sdata_debug_bias;
tom588658b2009-01-22 13:40:12 +0000452 }
tom160d5a82009-01-22 14:14:13 +0000453 else if (di->rodata_present
454 && di->rodata_size > 0
tom402c9ee2009-03-09 09:19:03 +0000455 && *a >= di->rodata_debug_svma && *a < di->rodata_debug_svma + di->rodata_size) {
456 *a += di->rodata_debug_bias;
tom160d5a82009-01-22 14:14:13 +0000457 }
tom588658b2009-01-22 13:40:12 +0000458 else if (di->bss_present
459 && di->bss_size > 0
tom402c9ee2009-03-09 09:19:03 +0000460 && *a >= di->bss_debug_svma && *a < di->bss_debug_svma + di->bss_size) {
461 *a += di->bss_debug_bias;
tom588658b2009-01-22 13:40:12 +0000462 }
tom160d5a82009-01-22 14:14:13 +0000463 else if (di->sbss_present
464 && di->sbss_size > 0
tom402c9ee2009-03-09 09:19:03 +0000465 && *a >= di->sbss_debug_svma && *a < di->sbss_debug_svma + di->sbss_size) {
466 *a += di->sbss_debug_bias;
tom160d5a82009-01-22 14:14:13 +0000467 }
tom588658b2009-01-22 13:40:12 +0000468 else {
469 return False;
470 }
471
472 return True;
473}
474
sewardjb8b79ad2008-03-03 01:35:41 +0000475
476/* Evaluate a standard DWARF3 expression. See detailed description in
tom3c9cf342009-11-12 13:28:34 +0000477 priv_d3basics.h. Doesn't handle DW_OP_piece/DW_OP_bit_piece yet. */
florian32971242014-10-23 17:47:15 +0000478GXResult ML_(evaluate_Dwarf3_Expr) ( const UChar* expr, UWord exprszB,
479 const GExpr* fbGX, const RegSummary* regs,
tom588658b2009-01-22 13:40:12 +0000480 const DebugInfo* di,
sewardjb8b79ad2008-03-03 01:35:41 +0000481 Bool push_initial_zero )
482{
483# define N_EXPR_STACK 20
484
485# define FAIL(_str) \
486 do { \
487 res.kind = GXR_Failure; \
488 res.word = (UWord)(_str); \
489 return res; \
490 } while (0)
491
492# define PUSH(_arg) \
493 do { \
494 vg_assert(sp >= -1 && sp < N_EXPR_STACK); \
495 if (sp == N_EXPR_STACK-1) \
496 FAIL("evaluate_Dwarf3_Expr: stack overflow(1)"); \
497 sp++; \
498 stack[sp] = (_arg); \
499 } while (0)
500
501# define POP(_lval) \
502 do { \
503 vg_assert(sp >= -1 && sp < N_EXPR_STACK); \
504 if (sp == -1) \
505 FAIL("evaluate_Dwarf3_Expr: stack underflow(1)"); \
506 _lval = stack[sp]; \
507 sp--; \
508 } while (0)
509
510 UChar opcode;
florian32971242014-10-23 17:47:15 +0000511 const UChar* limit;
sewardjb8b79ad2008-03-03 01:35:41 +0000512 Int sp; /* # of top element: valid is -1 .. N_EXPR_STACK-1 */
513 Addr stack[N_EXPR_STACK]; /* stack of addresses, as per D3 spec */
514 GXResult fbval, res;
515 Addr a1;
tom3c9cf342009-11-12 13:28:34 +0000516 Word sw1, sw2;
517 UWord uw1, uw2;
sewardjb8b79ad2008-03-03 01:35:41 +0000518 Bool ok;
519
520 sp = -1;
521 vg_assert(expr);
522 vg_assert(exprszB >= 0);
523 limit = expr + exprszB;
524
525 /* Deal with the case where the entire expression is a single
526 Register Name Operation (D3 spec sec 2.6.1). Then the
527 denotation of the expression as a whole is a register name. */
528 if (exprszB == 1
529 && expr[0] >= DW_OP_reg0 && expr[0] <= DW_OP_reg31) {
530 res.kind = GXR_RegNo;
531 res.word = (UWord)(expr[0] - DW_OP_reg0);
532 return res;
533 }
534 if (exprszB > 1
535 && expr[0] == DW_OP_regx) {
536 /* JRS: 2008Feb20: I believe the following is correct, but would
537 like to see a test case show up before enabling it. */
sewardjb8b79ad2008-03-03 01:35:41 +0000538 expr++;
539 res.kind = GXR_RegNo;
540 res.word = (UWord)read_leb128U( &expr );
541 if (expr != limit)
542 FAIL("evaluate_Dwarf3_Expr: DW_OP_regx*: invalid expr size");
543 else
544 return res;
545 /*NOTREACHED*/
546 }
547
sewardj9c606bd2008-09-18 18:12:50 +0000548 /* Evidently this expression denotes a value, not a register name.
sewardjb8b79ad2008-03-03 01:35:41 +0000549 So evaluate it accordingly. */
550
551 if (push_initial_zero)
552 PUSH(0);
553
554 while (True) {
555
556 vg_assert(sp >= -1 && sp < N_EXPR_STACK);
557
558 if (expr > limit)
559 /* overrun - something's wrong */
560 FAIL("evaluate_Dwarf3_Expr: ran off end of expr");
561
562 if (expr == limit) {
563 /* end of expr - return expr on the top of stack. */
564 if (sp == -1)
565 /* stack empty. Bad. */
566 FAIL("evaluate_Dwarf3_Expr: stack empty at end of expr");
567 else
568 break;
569 }
570
571 opcode = *expr++;
572 switch (opcode) {
573 case DW_OP_addr:
574 /* Presumably what is given in the Dwarf3 is a SVMA (how
tom402c9ee2009-03-09 09:19:03 +0000575 could it be otherwise?) So we add the appropriate bias
576 on before pushing the result. */
tom86781fa2011-10-05 08:48:07 +0000577 a1 = ML_(read_Addr)(expr);
tom588658b2009-01-22 13:40:12 +0000578 if (bias_address(&a1, di)) {
579 PUSH( a1 );
580 expr += sizeof(Addr);
581 }
582 else {
583 FAIL("evaluate_Dwarf3_Expr: DW_OP_addr with address "
584 "in unknown section");
585 }
sewardjb8b79ad2008-03-03 01:35:41 +0000586 break;
587 case DW_OP_fbreg:
588 if (!fbGX)
589 FAIL("evaluate_Dwarf3_Expr: DW_OP_fbreg with "
590 "no expr for fbreg present");
tom588658b2009-01-22 13:40:12 +0000591 fbval = ML_(evaluate_GX)(fbGX, NULL, regs, di);
sewardjb8b79ad2008-03-03 01:35:41 +0000592 /* Convert fbval into something we can use. If we got a
593 Value, no problem. However, as per D3 spec sec 3.3.5
594 (Low Level Information) sec 2, we could also get a
595 RegNo, and that is taken to mean the value in the
596 indicated register. So we have to manually
597 "dereference" it. */
598 a1 = 0;
599 switch (fbval.kind) {
600 case GXR_Failure:
601 return fbval; /* propagate failure */
tom3c9cf342009-11-12 13:28:34 +0000602 case GXR_Addr:
sewardjb8b79ad2008-03-03 01:35:41 +0000603 a1 = fbval.word; break; /* use as-is */
604 case GXR_RegNo:
605 ok = get_Dwarf_Reg( &a1, fbval.word, regs );
606 if (!ok) return fbval; /* propagate failure */
607 break;
tom3c9cf342009-11-12 13:28:34 +0000608 case GXR_Value:
609 FAIL("evaluate_Dwarf3_Expr: DW_OP_{implicit,stack}_value "
610 "in DW_AT_frame_base");
sewardjb8b79ad2008-03-03 01:35:41 +0000611 default:
612 vg_assert(0);
613 }
614 sw1 = (Word)read_leb128S( &expr );
615 PUSH( a1 + sw1 );
616 break;
617 /* DW_OP_breg* denotes 'contents of specified register, plus
618 constant offset'. So provided we know what the register's
619 value is, we can evaluate this. Contrast DW_OP_reg*,
620 which indicates that denoted location is in a register
621 itself. If DW_OP_reg* shows up here the expression is
622 malformed, since we are evaluating for value now, and
623 DW_OP_reg* denotes a register location, not a value. See
624 D3 Spec sec 2.6.1 ("Register Name Operations") for
625 details. */
626 case DW_OP_breg0 ... DW_OP_breg31:
627 if (!regs)
628 FAIL("evaluate_Dwarf3_Expr: DW_OP_breg* but no reg info");
629 a1 = 0;
630 if (!get_Dwarf_Reg( &a1, opcode - DW_OP_breg0, regs ))
631 FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_breg*");
632 sw1 = (Word)read_leb128S( &expr );
633 a1 += sw1;
634 PUSH( a1 );
635 break;
tom3c9cf342009-11-12 13:28:34 +0000636 case DW_OP_bregx:
637 if (!regs)
638 FAIL("evaluate_Dwarf3_Expr: DW_OP_bregx but no reg info");
639 a1 = 0;
640 uw1 = (UWord)read_leb128U( &expr );
641 if (!get_Dwarf_Reg( &a1, uw1, regs ))
642 FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_bregx reg value");
643 sw1 = (Word)read_leb128S( &expr );
644 a1 += sw1;
645 PUSH( a1 );
646 break;
sewardjb8b79ad2008-03-03 01:35:41 +0000647 /* As per comment on DW_OP_breg*, the following denote that
648 the value in question is in a register, not in memory. So
649 we simply return failure. (iow, the expression is
650 malformed). */
651 case DW_OP_reg0 ... DW_OP_reg31:
tom3c9cf342009-11-12 13:28:34 +0000652 case DW_OP_regx:
sewardjb8b79ad2008-03-03 01:35:41 +0000653 FAIL("evaluate_Dwarf3_Expr: DW_OP_reg* "
654 "whilst evaluating for a value");
655 break;
656 case DW_OP_plus_uconst:
657 POP(uw1);
658 uw1 += (UWord)read_leb128U( &expr );
659 PUSH(uw1);
660 break;
661 case DW_OP_GNU_push_tls_address:
662 /* GDB contains the following cryptic comment: */
663 /* Variable is at a constant offset in the thread-local
664 storage block into the objfile for the current thread and
665 the dynamic linker module containing this expression. Here
666 we return returns the offset from that base. The top of the
667 stack has the offset from the beginning of the thread
668 control block at which the variable is located. Nothing
669 should follow this operator, so the top of stack would be
670 returned. */
671 /* But no spec resulting from Googling. Punt for now. */
672 FAIL("warning: evaluate_Dwarf3_Expr: unhandled "
673 "DW_OP_GNU_push_tls_address");
674 /*NOTREACHED*/
sewardjaa3c28a2008-03-08 10:44:39 +0000675 case DW_OP_deref:
676 POP(uw1);
677 if (VG_(am_is_valid_for_client)( (Addr)uw1, sizeof(Addr),
678 VKI_PROT_READ )) {
tom86781fa2011-10-05 08:48:07 +0000679 uw1 = ML_(read_UWord)((void *)uw1);
sewardjaa3c28a2008-03-08 10:44:39 +0000680 PUSH(uw1);
681 } else {
682 FAIL("warning: evaluate_Dwarf3_Expr: DW_OP_deref: "
683 "address not valid for client");
684 }
685 break;
tom3c9cf342009-11-12 13:28:34 +0000686 case DW_OP_deref_size:
687 POP(uw1);
688 uw2 = *expr++;
689 if (VG_(am_is_valid_for_client)( (Addr)uw1, uw2,
690 VKI_PROT_READ )) {
691 switch (uw2) {
tom86781fa2011-10-05 08:48:07 +0000692 case 1: uw1 = ML_(read_UChar)((void*)uw1); break;
693 case 2: uw1 = ML_(read_UShort)((void*)uw1); break;
694 case 4: uw1 = ML_(read_UInt)((void*)uw1); break;
695 case 8: uw1 = ML_(read_ULong)((void*)uw1); break;
tom3c9cf342009-11-12 13:28:34 +0000696 default:
697 FAIL("warning: evaluate_Dwarf3_Expr: unhandled "
698 "DW_OP_deref_size size");
699 }
700 PUSH(uw1);
701 } else {
702 FAIL("warning: evaluate_Dwarf3_Expr: DW_OP_deref_size: "
703 "address not valid for client");
704 }
705 break;
706 case DW_OP_lit0 ... DW_OP_lit31:
707 PUSH(opcode - DW_OP_lit0);
708 break;
709 case DW_OP_const1u:
710 uw1 = *expr++;
711 PUSH(uw1);
712 break;
713 case DW_OP_const2u:
tom86781fa2011-10-05 08:48:07 +0000714 uw1 = ML_(read_UShort)(expr);
tom3c9cf342009-11-12 13:28:34 +0000715 expr += 2;
716 PUSH(uw1);
717 break;
718 case DW_OP_const4u:
tom86781fa2011-10-05 08:48:07 +0000719 uw1 = ML_(read_UInt)(expr);
tom3c9cf342009-11-12 13:28:34 +0000720 expr += 4;
721 PUSH(uw1);
722 break;
723 case DW_OP_const8u:
tom86781fa2011-10-05 08:48:07 +0000724 uw1 = ML_(read_ULong)(expr);
tom3c9cf342009-11-12 13:28:34 +0000725 expr += 8;
726 PUSH(uw1);
727 break;
728 case DW_OP_constu:
729 uw1 = read_leb128U( &expr );
730 PUSH(uw1);
731 break;
732 case DW_OP_const1s:
florian32971242014-10-23 17:47:15 +0000733 uw1 = *(const Char *)expr;
tom3c9cf342009-11-12 13:28:34 +0000734 expr++;
735 PUSH(uw1);
736 break;
737 case DW_OP_const2s:
tom86781fa2011-10-05 08:48:07 +0000738 uw1 = ML_(read_Short)(expr);
tom3c9cf342009-11-12 13:28:34 +0000739 expr += 2;
740 PUSH(uw1);
741 break;
742 case DW_OP_const4s:
tom86781fa2011-10-05 08:48:07 +0000743 uw1 = ML_(read_Int)(expr);
tom3c9cf342009-11-12 13:28:34 +0000744 expr += 4;
745 PUSH(uw1);
746 break;
747 case DW_OP_const8s:
tom86781fa2011-10-05 08:48:07 +0000748 uw1 = ML_(read_Long)(expr);
tom3c9cf342009-11-12 13:28:34 +0000749 expr += 8;
750 PUSH(uw1);
751 break;
752 case DW_OP_consts:
753 uw1 = read_leb128S( &expr );
754 PUSH(uw1);
755 break;
756 case DW_OP_dup:
757 POP(uw1);
758 PUSH(uw1);
759 PUSH(uw1);
760 break;
761 case DW_OP_drop:
762 POP(uw1);
763 break;
764 case DW_OP_over:
765 uw1 = 1;
766 goto do_pick;
767 case DW_OP_pick:
768 uw1 = *expr++;
769 do_pick:
770 if (sp < (Int)uw1)
771 FAIL("evaluate_Dwarf3_Expr: stack underflow");
772 uw1 = stack[sp - uw1];
773 PUSH(uw1);
774 break;
775 case DW_OP_swap:
776 if (sp < 1)
777 FAIL("evaluate_Dwarf3_Expr: stack underflow");
778 uw1 = stack[sp];
779 stack[sp] = stack[sp - 1];
780 stack[sp - 1] = uw1;
781 break;
782 case DW_OP_rot:
783 if (sp < 2)
784 FAIL("evaluate_Dwarf3_Expr: stack underflow");
785 uw1 = stack[sp];
786 stack[sp] = stack[sp - 1];
787 stack[sp - 1] = stack[sp - 2];
788 stack[sp - 2] = uw1;
789 break;
790 case DW_OP_abs:
791 POP(sw1);
792 if (sw1 < 0)
793 sw1 = -sw1;
794 PUSH(sw1);
795 break;
796 case DW_OP_div:
797 POP(sw2);
798 if (sw2 == 0)
799 FAIL("evaluate_Dwarf3_Expr: division by zero");
800 POP(sw1);
801 sw1 /= sw2;
802 PUSH(sw1);
803 break;
804 case DW_OP_mod:
tomb9c17d22010-01-21 10:19:46 +0000805 POP(uw2);
806 if (uw2 == 0)
tom3c9cf342009-11-12 13:28:34 +0000807 FAIL("evaluate_Dwarf3_Expr: division by zero");
tomb9c17d22010-01-21 10:19:46 +0000808 POP(uw1);
809 uw1 %= uw2;
810 PUSH(uw1);
tom3c9cf342009-11-12 13:28:34 +0000811 break;
812#define BINARY(name, op, s) \
813 case DW_OP_##name: \
814 POP(s##w2); \
815 POP(s##w1); \
816 s##w1 = s##w1 op s##w2; \
817 PUSH(s##w1); \
818 break
819#define UNARY(name, op, s) \
820 case DW_OP_##name: \
821 POP(s##w1); \
822 s##w1 = op s##w1; \
823 PUSH(s##w1); \
824 break
825 BINARY (and, &, u);
826 BINARY (minus, -, u);
827 BINARY (mul, *, u);
828 UNARY (neg, -, u);
829 UNARY (not, ~, u);
830 BINARY (or, |, u);
831 BINARY (plus, +, u);
832 BINARY (shl, <<, u);
833 BINARY (shr, >>, u);
834 BINARY (shra, >>, s);
835 BINARY (xor, ^, u);
836 BINARY (le, <=, s);
837 BINARY (lt, <, s);
838 BINARY (ge, >=, s);
839 BINARY (gt, >, s);
840 BINARY (ne, !=, u);
841 BINARY (eq, ==, u);
842#undef UNARY
843#undef BINARY
844 case DW_OP_skip:
tom86781fa2011-10-05 08:48:07 +0000845 sw1 = ML_(read_Short)(expr);
tom3c9cf342009-11-12 13:28:34 +0000846 expr += 2;
847 if (expr + sw1 < limit - exprszB)
848 FAIL("evaluate_Dwarf3_Expr: DW_OP_skip before start of expr");
849 if (expr + sw1 >= limit)
850 FAIL("evaluate_Dwarf3_Expr: DW_OP_skip after end of expr");
851 expr += sw1;
852 break;
853 case DW_OP_bra:
tom86781fa2011-10-05 08:48:07 +0000854 sw1 = ML_(read_Short)(expr);
tom3c9cf342009-11-12 13:28:34 +0000855 expr += 2;
856 if (expr + sw1 < limit - exprszB)
857 FAIL("evaluate_Dwarf3_Expr: DW_OP_bra before start of expr");
858 if (expr + sw1 >= limit)
859 FAIL("evaluate_Dwarf3_Expr: DW_OP_bra after end of expr");
860 POP(uw1);
861 if (uw1)
862 expr += sw1;
863 break;
864 case DW_OP_nop:
865 break;
866 case DW_OP_call_frame_cfa:
867 if (!regs)
sewardj3026f712010-01-01 18:46:41 +0000868 FAIL("evaluate_Dwarf3_Expr: "
869 "DW_OP_call_frame_cfa but no reg info");
carllcae0cc22014-08-07 23:17:29 +0000870#if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
871 || defined(VGP_ppc64le_linux)
sewardj3026f712010-01-01 18:46:41 +0000872 /* Valgrind on ppc32/ppc64 currently doesn't use unwind info. */
sewardj50f5cea2011-10-20 10:41:37 +0000873 uw1 = ML_(read_Addr)((UChar*)regs->sp);
tom3c9cf342009-11-12 13:28:34 +0000874#else
875 uw1 = ML_(get_CFA)(regs->ip, regs->sp, regs->fp, 0, ~(UWord) 0);
876#endif
sewardj3026f712010-01-01 18:46:41 +0000877 /* we expect this to fail on arm-linux, since ML_(get_CFA)
878 always returns zero at present. */
tom3c9cf342009-11-12 13:28:34 +0000879 if (!uw1)
880 FAIL("evaluate_Dwarf3_Expr: Could not resolve "
881 "DW_OP_call_frame_cfa");
882 PUSH(uw1);
883 break;
884 case DW_OP_implicit_value:
885 sw1 = (Word)read_leb128S( &expr );
886 uw1 = 0;
887 switch (sw1) {
888 case 1:
tom86781fa2011-10-05 08:48:07 +0000889 uw1 = ML_(read_UChar)(expr);
tom3c9cf342009-11-12 13:28:34 +0000890 expr += 1;
891 break;
892 case 2:
tom86781fa2011-10-05 08:48:07 +0000893 uw1 = ML_(read_UShort)(expr);
tom3c9cf342009-11-12 13:28:34 +0000894 expr += 2;
895 break;
896 case 4:
tom86781fa2011-10-05 08:48:07 +0000897 uw1 = ML_(read_UInt)(expr);
tom3c9cf342009-11-12 13:28:34 +0000898 expr += 4;
899 break;
900 case 8:
tom86781fa2011-10-05 08:48:07 +0000901 uw1 = ML_(read_ULong)(expr);
tom3c9cf342009-11-12 13:28:34 +0000902 expr += 8;
903 break;
904 default:
905 FAIL("evaluate_Dwarf3_Expr: Unhandled "
906 "DW_OP_implicit_value size");
907 }
908 if (expr != limit)
909 FAIL("evaluate_Dwarf3_Expr: DW_OP_implicit_value "
910 "does not terminate expression");
911 res.word = uw1;
912 res.kind = GXR_Value;
913 return res;
914 case DW_OP_stack_value:
915 POP (uw1);
916 res.word = uw1;
917 res.kind = GXR_Value;
918 if (expr != limit)
919 FAIL("evaluate_Dwarf3_Expr: DW_OP_stack_value "
920 "does not terminate expression");
921 break;
sewardjb8b79ad2008-03-03 01:35:41 +0000922 default:
923 if (!VG_(clo_xml))
924 VG_(message)(Vg_DebugMsg,
925 "warning: evaluate_Dwarf3_Expr: unhandled "
sewardj738856f2009-07-15 14:48:32 +0000926 "DW_OP_ 0x%x\n", (Int)opcode);
sewardjb8b79ad2008-03-03 01:35:41 +0000927 FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_");
928 /*NOTREACHED*/
929 }
930
931 }
932
933 vg_assert(sp >= 0 && sp < N_EXPR_STACK);
934 res.word = stack[sp];
tom3c9cf342009-11-12 13:28:34 +0000935 res.kind = GXR_Addr;
sewardjb8b79ad2008-03-03 01:35:41 +0000936 return res;
937
938# undef POP
939# undef PUSH
940# undef FAIL
941# undef N_EXPR_STACK
942}
943
944
945/* Evaluate a so-called Guarded (DWARF3) expression. See detailed
946 description in priv_d3basics.h. */
florian32971242014-10-23 17:47:15 +0000947GXResult ML_(evaluate_GX)( const GExpr* gx, const GExpr* fbGX,
florian518850b2014-10-22 22:25:30 +0000948 const RegSummary* regs, const DebugInfo* di )
sewardjb8b79ad2008-03-03 01:35:41 +0000949{
950 GXResult res;
951 Addr aMin, aMax;
952 UChar uc;
953 UShort nbytes;
954 UWord nGuards = 0;
florian32971242014-10-23 17:47:15 +0000955 const UChar* p = &gx->payload[0];
sewardjb8b79ad2008-03-03 01:35:41 +0000956 uc = *p++; /*biasMe*/
957 vg_assert(uc == 0 || uc == 1);
958 /* in fact it's senseless to evaluate if the guards need biasing.
959 So don't. */
960 vg_assert(uc == 0);
961 while (True) {
962 uc = *p++;
963 if (uc == 1) { /*isEnd*/
964 /* didn't find any matching range. */
965 res.kind = GXR_Failure;
966 res.word = (UWord)"no matching range";
967 return res;
968 }
969 vg_assert(uc == 0);
tom86781fa2011-10-05 08:48:07 +0000970 aMin = ML_(read_Addr)(p); p += sizeof(Addr);
971 aMax = ML_(read_Addr)(p); p += sizeof(Addr);
972 nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
sewardjb8b79ad2008-03-03 01:35:41 +0000973 nGuards++;
florianc6e5d762015-08-05 22:27:24 +0000974 if (0) VG_(printf)(" guard %lu: %#lx %#lx\n",
975 nGuards, aMin,aMax);
sewardjb8b79ad2008-03-03 01:35:41 +0000976 if (regs == NULL) {
977 vg_assert(aMin == (Addr)0);
978 vg_assert(aMax == ~(Addr)0);
979 /* Assert this is the first guard. */
980 vg_assert(nGuards == 1);
981 res = ML_(evaluate_Dwarf3_Expr)(
tom588658b2009-01-22 13:40:12 +0000982 p, (UWord)nbytes, fbGX, regs, di,
sewardjb8b79ad2008-03-03 01:35:41 +0000983 False/*push_initial_zero*/ );
984 /* Now check there are no more guards. */
985 p += (UWord)nbytes;
986 vg_assert(*p == 1); /*isEnd*/
987 return res;
988 } else {
989 if (aMin <= regs->ip && regs->ip <= aMax) {
990 /* found a matching range. Evaluate the expression. */
991 return ML_(evaluate_Dwarf3_Expr)(
tom588658b2009-01-22 13:40:12 +0000992 p, (UWord)nbytes, fbGX, regs, di,
sewardjb8b79ad2008-03-03 01:35:41 +0000993 False/*push_initial_zero*/ );
994 }
995 }
996 /* else keep searching */
997 p += (UWord)nbytes;
998 }
999}
1000
1001
sewardj9c606bd2008-09-18 18:12:50 +00001002/* Evaluate a very simple Guarded (DWARF3) expression. The expression
1003 is expected to denote a constant, with no reference to any
1004 registers nor to any frame base expression. The expression is
1005 expected to have at least one guard. If there is more than one
1006 guard, all the sub-expressions are evaluated and compared. The
1007 address ranges on the guards are ignored. GXR_Failure is returned
1008 in the following circumstances:
1009 * no guards
1010 * any of the subexpressions require a frame base expression
1011 * any of the subexpressions denote a register location
1012 * any of the subexpressions do not produce a manifest constant
1013 * there's more than one subexpression, all of which successfully
1014 evaluate to a constant, but they don't all produce the same constant.
sewardjec3f2ce2009-01-24 00:06:13 +00001015 JRS 23Jan09: the special-casing in this function is a nasty kludge.
1016 Really it ought to be pulled out and turned into a general
1017 constant- expression evaluator.
1018*/
florian32971242014-10-23 17:47:15 +00001019GXResult ML_(evaluate_trivial_GX)( const GExpr* gx, const DebugInfo* di )
sewardj9c606bd2008-09-18 18:12:50 +00001020{
1021 GXResult res;
1022 Addr aMin, aMax;
1023 UChar uc;
1024 UShort nbytes;
1025 Word i, nGuards;
sewardj50fde232008-10-20 16:08:55 +00001026 MaybeULong *mul, *mul2;
sewardj9c606bd2008-09-18 18:12:50 +00001027
florian6bd9dc12012-11-23 16:17:43 +00001028 const HChar* badness = NULL;
florian32971242014-10-23 17:47:15 +00001029 const UChar* p = &gx->payload[0]; /* must remain unsigned */
sewardj9c606bd2008-09-18 18:12:50 +00001030 XArray* results = VG_(newXA)( ML_(dinfo_zalloc), "di.d3basics.etG.1",
1031 ML_(dinfo_free),
sewardj50fde232008-10-20 16:08:55 +00001032 sizeof(MaybeULong) );
sewardj9c606bd2008-09-18 18:12:50 +00001033
1034 uc = *p++; /*biasMe*/
1035 vg_assert(uc == 0 || uc == 1);
1036 /* in fact it's senseless to evaluate if the guards need biasing.
1037 So don't. */
1038 vg_assert(uc == 0);
1039
1040 nGuards = 0;
1041 while (True) {
sewardj50fde232008-10-20 16:08:55 +00001042 MaybeULong thisResult;
sewardj9c606bd2008-09-18 18:12:50 +00001043 uc = *p++;
1044 if (uc == 1) /*isEnd*/
1045 break;
1046 vg_assert(uc == 0);
tom86781fa2011-10-05 08:48:07 +00001047 aMin = ML_(read_Addr)(p); p += sizeof(Addr);
1048 aMax = ML_(read_Addr)(p); p += sizeof(Addr);
1049 nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
sewardj9c606bd2008-09-18 18:12:50 +00001050 nGuards++;
1051 if (0) VG_(printf)(" guard %ld: %#lx %#lx\n",
1052 nGuards, aMin,aMax);
1053
sewardj50fde232008-10-20 16:08:55 +00001054 thisResult.b = False;
1055 thisResult.ul = 0;
sewardj9c606bd2008-09-18 18:12:50 +00001056
1057 /* Peer at this particular subexpression, to see if it's
1058 obviously a constant. */
1059 if (nbytes == 1 + sizeof(Addr) && *p == DW_OP_addr) {
sewardjec3f2ce2009-01-24 00:06:13 +00001060 /* DW_OP_addr a */
tom86781fa2011-10-05 08:48:07 +00001061 Addr a = ML_(read_Addr)((p+1));
tom588658b2009-01-22 13:40:12 +00001062 if (bias_address(&a, di)) {
1063 thisResult.b = True;
1064 thisResult.ul = (ULong)a;
sewardjec3f2ce2009-01-24 00:06:13 +00001065 } else {
1066 if (!badness)
1067 badness = "trivial GExpr denotes constant address "
1068 "in unknown section (1)";
tom588658b2009-01-22 13:40:12 +00001069 }
sewardj9c606bd2008-09-18 18:12:50 +00001070 }
sewardjec3f2ce2009-01-24 00:06:13 +00001071 else
1072 if (nbytes == 1 + sizeof(Addr) + 1 + 1
1073 /* 11 byte block: 3 c0 b6 2b 0 0 0 0 0 23 4
1074 (DW_OP_addr: 2bb6c0; DW_OP_plus_uconst: 4)
1075 This is really a nasty kludge - only matches if the
1076 trailing ULEB denotes a number in the range 0 .. 127
1077 inclusive. */
1078 && p[0] == DW_OP_addr
1079 && p[1 + sizeof(Addr)] == DW_OP_plus_uconst
1080 && p[1 + sizeof(Addr) + 1] < 0x80 /*1-byte ULEB*/) {
tom86781fa2011-10-05 08:48:07 +00001081 Addr a = ML_(read_Addr)(&p[1]);
sewardjec3f2ce2009-01-24 00:06:13 +00001082 if (bias_address(&a, di)) {
1083 thisResult.b = True;
1084 thisResult.ul = (ULong)a + (ULong)p[1 + sizeof(Addr) + 1];
1085 } else {
1086 if (!badness)
1087 badness = "trivial GExpr denotes constant address "
1088 "in unknown section (2)";
1089 }
1090 }
1091 else
1092 if (nbytes == 2 + sizeof(Addr)
1093 && *p == DW_OP_addr
1094 && *(p + 1 + sizeof(Addr)) == DW_OP_GNU_push_tls_address) {
sewardj9c606bd2008-09-18 18:12:50 +00001095 if (!badness)
1096 badness = "trivial GExpr is DW_OP_addr plus trailing junk";
1097 }
1098 else if (nbytes >= 1 && *p >= DW_OP_reg0 && *p <= DW_OP_reg31) {
1099 if (!badness)
1100 badness = "trivial GExpr denotes register (1)";
1101 }
1102 else if (nbytes >= 1 && *p == DW_OP_fbreg) {
1103 if (!badness)
1104 badness = "trivial GExpr requires fbGX";
1105 }
1106 else if (nbytes >= 1 && *p >= DW_OP_breg0 && *p <= DW_OP_breg31) {
1107 if (!badness)
1108 badness = "trivial GExpr requires register value";
1109 }
1110 else if (nbytes >= 1 && *p == DW_OP_regx) {
1111 if (!badness)
1112 badness = "trivial GExpr denotes register (2)";
1113 }
tom3c9cf342009-11-12 13:28:34 +00001114 else if (0) {
sewardj9c606bd2008-09-18 18:12:50 +00001115 VG_(printf)(" ML_(evaluate_trivial_GX): unhandled:\n ");
1116 ML_(pp_GX)( gx );
1117 VG_(printf)("\n");
floriane2800c92014-09-15 20:57:45 +00001118 vg_assert(0);
sewardj9c606bd2008-09-18 18:12:50 +00001119 }
tom3c9cf342009-11-12 13:28:34 +00001120 else
1121 if (!badness)
1122 badness = "non-trivial GExpr";
sewardj9c606bd2008-09-18 18:12:50 +00001123
1124 VG_(addToXA)( results, &thisResult );
1125
1126 p += (UWord)nbytes;
1127 }
1128
1129 res.kind = GXR_Failure;
1130
floriane2800c92014-09-15 20:57:45 +00001131 vg_assert(nGuards == VG_(sizeXA)( results ));
1132 vg_assert(nGuards >= 0);
sewardj9c606bd2008-09-18 18:12:50 +00001133 if (nGuards == 0) {
floriane2800c92014-09-15 20:57:45 +00001134 vg_assert(!badness);
sewardj9c606bd2008-09-18 18:12:50 +00001135 res.word = (UWord)"trivial GExpr has no guards (!)";
1136 VG_(deleteXA)( results );
1137 return res;
1138 }
1139
1140 for (i = 0; i < nGuards; i++) {
sewardj50fde232008-10-20 16:08:55 +00001141 mul = VG_(indexXA)( results, i );
1142 if (mul->b == False)
sewardj9c606bd2008-09-18 18:12:50 +00001143 break;
1144 }
1145
1146 vg_assert(i >= 0 && i <= nGuards);
1147 if (i < nGuards) {
1148 /* at least one subexpression failed to produce a manifest constant. */
1149 vg_assert(badness);
1150 res.word = (UWord)badness;
1151 VG_(deleteXA)( results );
1152 return res;
1153 }
1154
1155 /* All the subexpressions produced a constant, but did they all produce
1156 the same one? */
sewardj50fde232008-10-20 16:08:55 +00001157 mul = VG_(indexXA)( results, 0 );
floriane2800c92014-09-15 20:57:45 +00001158 vg_assert(mul->b == True); /* we just established that all exprs are ok */
sewardj9c606bd2008-09-18 18:12:50 +00001159
1160 for (i = 1; i < nGuards; i++) {
sewardj50fde232008-10-20 16:08:55 +00001161 mul2 = VG_(indexXA)( results, i );
floriane2800c92014-09-15 20:57:45 +00001162 vg_assert(mul2->b == True);
sewardj50fde232008-10-20 16:08:55 +00001163 if (mul2->ul != mul->ul) {
sewardj9c606bd2008-09-18 18:12:50 +00001164 res.word = (UWord)"trivial GExpr: subexpressions disagree";
1165 VG_(deleteXA)( results );
1166 return res;
1167 }
1168 }
1169
1170 /* Well, we have success. All subexpressions evaluated, and
1171 they all agree. Hurrah. */
tom3c9cf342009-11-12 13:28:34 +00001172 res.kind = GXR_Addr;
sewardj50fde232008-10-20 16:08:55 +00001173 res.word = (UWord)mul->ul; /* NB: narrowing from ULong */
sewardj9c606bd2008-09-18 18:12:50 +00001174 VG_(deleteXA)( results );
1175 return res;
1176}
1177
1178
sewardjb8b79ad2008-03-03 01:35:41 +00001179void ML_(pp_GXResult) ( GXResult res )
1180{
1181 switch (res.kind) {
1182 case GXR_Failure:
1183 VG_(printf)("GXR_Failure(%s)", (HChar*)res.word); break;
tom3c9cf342009-11-12 13:28:34 +00001184 case GXR_Addr:
1185 VG_(printf)("GXR_Addr(0x%lx)", res.word); break;
sewardjb8b79ad2008-03-03 01:35:41 +00001186 case GXR_Value:
1187 VG_(printf)("GXR_Value(0x%lx)", res.word); break;
1188 case GXR_RegNo:
1189 VG_(printf)("GXR_RegNo(%lu)", res.word); break;
1190 default:
1191 VG_(printf)("GXR_???"); break;
1192 }
1193}
1194
1195
florian518850b2014-10-22 22:25:30 +00001196void ML_(pp_GX) ( const GExpr* gx )
1197{
sewardj9c606bd2008-09-18 18:12:50 +00001198 Addr aMin, aMax;
1199 UChar uc;
1200 UShort nbytes;
florian518850b2014-10-22 22:25:30 +00001201 const UChar* p = &gx->payload[0];
sewardj9c606bd2008-09-18 18:12:50 +00001202 uc = *p++;
1203 VG_(printf)("GX(%s){", uc == 0 ? "final" : "Breqd" );
1204 vg_assert(uc == 0 || uc == 1);
1205 while (True) {
1206 uc = *p++;
1207 if (uc == 1)
1208 break; /*isEnd*/
1209 vg_assert(uc == 0);
tom86781fa2011-10-05 08:48:07 +00001210 aMin = ML_(read_Addr)(p); p += sizeof(Addr);
1211 aMax = ML_(read_Addr)(p); p += sizeof(Addr);
1212 nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
sewardj9c606bd2008-09-18 18:12:50 +00001213 VG_(printf)("[%#lx,%#lx]=", aMin, aMax);
1214 while (nbytes > 0) {
1215 VG_(printf)("%02x", (UInt)*p++);
1216 nbytes--;
1217 }
1218 if (*p == 0)
1219 VG_(printf)(",");
1220 }
1221 VG_(printf)("}");
1222}
1223
1224
sewardjb8b79ad2008-03-03 01:35:41 +00001225/*--------------------------------------------------------------------*/
1226/*--- end d3basics.c ---*/
1227/*--------------------------------------------------------------------*/