blob: 616f21f7dbcd5583b1dbac3f1ac109439ce2afb3 [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
11 Copyright (C) 2008-2008 OpenWorks LLP
12 info@open-works.co.uk
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30
31 Neither the names of the U.S. Department of Energy nor the
32 University of California nor the names of its contributors may be
33 used to endorse or promote products derived from this software
34 without prior written permission.
35*/
36
37#include "pub_core_basics.h"
38#include "pub_core_libcassert.h"
39#include "pub_core_libcprint.h"
40#include "pub_core_options.h"
41
sewardjaa3c28a2008-03-08 10:44:39 +000042#include "pub_core_vki.h" /* VKI_PROT_READ */
43#include "pub_core_aspacemgr.h" /* VG_(is_valid_for_client) */
44
sewardjb8b79ad2008-03-03 01:35:41 +000045#include "priv_d3basics.h" /* self */
46
47HChar* ML_(pp_DW_children) ( DW_children hashch )
48{
49 switch (hashch) {
50 case DW_children_no: return "no children";
51 case DW_children_yes: return "has children";
52 default: return "DW_children_???";
53 }
54}
55
56HChar* ML_(pp_DW_TAG) ( DW_TAG tag )
57{
58 switch (tag) {
59 case DW_TAG_padding: return "DW_TAG_padding";
60 case DW_TAG_array_type: return "DW_TAG_array_type";
61 case DW_TAG_class_type: return "DW_TAG_class_type";
62 case DW_TAG_entry_point: return "DW_TAG_entry_point";
63 case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
64 case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
65 case DW_TAG_imported_declaration:
66 return "DW_TAG_imported_declaration";
67 case DW_TAG_label: return "DW_TAG_label";
68 case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
69 case DW_TAG_member: return "DW_TAG_member";
70 case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
71 case DW_TAG_reference_type: return "DW_TAG_reference_type";
72 case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
73 case DW_TAG_string_type: return "DW_TAG_string_type";
74 case DW_TAG_structure_type: return "DW_TAG_structure_type";
75 case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
76 case DW_TAG_typedef: return "DW_TAG_typedef";
77 case DW_TAG_union_type: return "DW_TAG_union_type";
78 case DW_TAG_unspecified_parameters:
79 return "DW_TAG_unspecified_parameters";
80 case DW_TAG_variant: return "DW_TAG_variant";
81 case DW_TAG_common_block: return "DW_TAG_common_block";
82 case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
83 case DW_TAG_inheritance: return "DW_TAG_inheritance";
84 case DW_TAG_inlined_subroutine:
85 return "DW_TAG_inlined_subroutine";
86 case DW_TAG_module: return "DW_TAG_module";
87 case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
88 case DW_TAG_set_type: return "DW_TAG_set_type";
89 case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
90 case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
91 case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
92 case DW_TAG_base_type: return "DW_TAG_base_type";
93 case DW_TAG_catch_block: return "DW_TAG_catch_block";
94 case DW_TAG_const_type: return "DW_TAG_const_type";
95 case DW_TAG_constant: return "DW_TAG_constant";
96 case DW_TAG_enumerator: return "DW_TAG_enumerator";
97 case DW_TAG_file_type: return "DW_TAG_file_type";
98 case DW_TAG_friend: return "DW_TAG_friend";
99 case DW_TAG_namelist: return "DW_TAG_namelist";
100 case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
101 case DW_TAG_packed_type: return "DW_TAG_packed_type";
102 case DW_TAG_subprogram: return "DW_TAG_subprogram";
103 case DW_TAG_template_type_param:
104 return "DW_TAG_template_type_param";
105 case DW_TAG_template_value_param:
106 return "DW_TAG_template_value_param";
107 case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
108 case DW_TAG_try_block: return "DW_TAG_try_block";
109 case DW_TAG_variant_part: return "DW_TAG_variant_part";
110 case DW_TAG_variable: return "DW_TAG_variable";
111 case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
112 /* DWARF 3. */
113 case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure";
114 case DW_TAG_restrict_type: return "DW_TAG_restrict_type";
115 case DW_TAG_interface_type: return "DW_TAG_interface_type";
116 case DW_TAG_namespace: return "DW_TAG_namespace";
117 case DW_TAG_imported_module: return "DW_TAG_imported_module";
118 case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type";
119 case DW_TAG_partial_unit: return "DW_TAG_partial_unit";
120 case DW_TAG_imported_unit: return "DW_TAG_imported_unit";
121 case DW_TAG_condition: return "DW_TAG_condition";
122 case DW_TAG_shared_type: return "DW_TAG_shared_type";
123 /* SGI/MIPS Extensions. */
124 case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
125 /* HP extensions. See:
126 ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz . */
127 case DW_TAG_HP_array_descriptor:
128 return "DW_TAG_HP_array_descriptor";
129 /* GNU extensions. */
130 case DW_TAG_format_label: return "DW_TAG_format_label";
131 case DW_TAG_function_template: return "DW_TAG_function_template";
132 case DW_TAG_class_template: return "DW_TAG_class_template";
133 case DW_TAG_GNU_BINCL: return "DW_TAG_GNU_BINCL";
134 case DW_TAG_GNU_EINCL: return "DW_TAG_GNU_EINCL";
135 /* Extensions for UPC. See: http://upc.gwu.edu/~upc. */
136 case DW_TAG_upc_shared_type: return "DW_TAG_upc_shared_type";
137 case DW_TAG_upc_strict_type: return "DW_TAG_upc_strict_type";
138 case DW_TAG_upc_relaxed_type: return "DW_TAG_upc_relaxed_type";
139 /* PGI (STMicroelectronics) extensions. No documentation available. */
140 case DW_TAG_PGI_kanji_type: return "DW_TAG_PGI_kanji_type";
141 case DW_TAG_PGI_interface_block:
142 return "DW_TAG_PGI_interface_block";
143 default: return "DW_TAG_???";
144 }
145}
146
147HChar* ML_(pp_DW_FORM) ( DW_FORM form )
148{
149 switch (form) {
150 case DW_FORM_addr: return "DW_FORM_addr";
151 case DW_FORM_block2: return "DW_FORM_block2";
152 case DW_FORM_block4: return "DW_FORM_block4";
153 case DW_FORM_data2: return "DW_FORM_data2";
154 case DW_FORM_data4: return "DW_FORM_data4";
155 case DW_FORM_data8: return "DW_FORM_data8";
156 case DW_FORM_string: return "DW_FORM_string";
157 case DW_FORM_block: return "DW_FORM_block";
158 case DW_FORM_block1: return "DW_FORM_block1";
159 case DW_FORM_data1: return "DW_FORM_data1";
160 case DW_FORM_flag: return "DW_FORM_flag";
161 case DW_FORM_sdata: return "DW_FORM_sdata";
162 case DW_FORM_strp: return "DW_FORM_strp";
163 case DW_FORM_udata: return "DW_FORM_udata";
164 case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
165 case DW_FORM_ref1: return "DW_FORM_ref1";
166 case DW_FORM_ref2: return "DW_FORM_ref2";
167 case DW_FORM_ref4: return "DW_FORM_ref4";
168 case DW_FORM_ref8: return "DW_FORM_ref8";
169 case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
170 case DW_FORM_indirect: return "DW_FORM_indirect";
171 default: return "DW_FORM_???";
172 }
173}
174
175HChar* ML_(pp_DW_AT) ( DW_AT attr )
176{
177 switch (attr) {
178 case DW_AT_sibling: return "DW_AT_sibling";
179 case DW_AT_location: return "DW_AT_location";
180 case DW_AT_name: return "DW_AT_name";
181 case DW_AT_ordering: return "DW_AT_ordering";
182 case DW_AT_subscr_data: return "DW_AT_subscr_data";
183 case DW_AT_byte_size: return "DW_AT_byte_size";
184 case DW_AT_bit_offset: return "DW_AT_bit_offset";
185 case DW_AT_bit_size: return "DW_AT_bit_size";
186 case DW_AT_element_list: return "DW_AT_element_list";
187 case DW_AT_stmt_list: return "DW_AT_stmt_list";
188 case DW_AT_low_pc: return "DW_AT_low_pc";
189 case DW_AT_high_pc: return "DW_AT_high_pc";
190 case DW_AT_language: return "DW_AT_language";
191 case DW_AT_member: return "DW_AT_member";
192 case DW_AT_discr: return "DW_AT_discr";
193 case DW_AT_discr_value: return "DW_AT_discr_value";
194 case DW_AT_visibility: return "DW_AT_visibility";
195 case DW_AT_import: return "DW_AT_import";
196 case DW_AT_string_length: return "DW_AT_string_length";
197 case DW_AT_common_reference: return "DW_AT_common_reference";
198 case DW_AT_comp_dir: return "DW_AT_comp_dir";
199 case DW_AT_const_value: return "DW_AT_const_value";
200 case DW_AT_containing_type: return "DW_AT_containing_type";
201 case DW_AT_default_value: return "DW_AT_default_value";
202 case DW_AT_inline: return "DW_AT_inline";
203 case DW_AT_is_optional: return "DW_AT_is_optional";
204 case DW_AT_lower_bound: return "DW_AT_lower_bound";
205 case DW_AT_producer: return "DW_AT_producer";
206 case DW_AT_prototyped: return "DW_AT_prototyped";
207 case DW_AT_return_addr: return "DW_AT_return_addr";
208 case DW_AT_start_scope: return "DW_AT_start_scope";
209 case DW_AT_stride_size: return "DW_AT_stride_size";
210 case DW_AT_upper_bound: return "DW_AT_upper_bound";
211 case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
212 case DW_AT_accessibility: return "DW_AT_accessibility";
213 case DW_AT_address_class: return "DW_AT_address_class";
214 case DW_AT_artificial: return "DW_AT_artificial";
215 case DW_AT_base_types: return "DW_AT_base_types";
216 case DW_AT_calling_convention: return "DW_AT_calling_convention";
217 case DW_AT_count: return "DW_AT_count";
218 case DW_AT_data_member_location: return "DW_AT_data_member_location";
219 case DW_AT_decl_column: return "DW_AT_decl_column";
220 case DW_AT_decl_file: return "DW_AT_decl_file";
221 case DW_AT_decl_line: return "DW_AT_decl_line";
222 case DW_AT_declaration: return "DW_AT_declaration";
223 case DW_AT_discr_list: return "DW_AT_discr_list";
224 case DW_AT_encoding: return "DW_AT_encoding";
225 case DW_AT_external: return "DW_AT_external";
226 case DW_AT_frame_base: return "DW_AT_frame_base";
227 case DW_AT_friend: return "DW_AT_friend";
228 case DW_AT_identifier_case: return "DW_AT_identifier_case";
229 case DW_AT_macro_info: return "DW_AT_macro_info";
230 case DW_AT_namelist_items: return "DW_AT_namelist_items";
231 case DW_AT_priority: return "DW_AT_priority";
232 case DW_AT_segment: return "DW_AT_segment";
233 case DW_AT_specification: return "DW_AT_specification";
234 case DW_AT_static_link: return "DW_AT_static_link";
235 case DW_AT_type: return "DW_AT_type";
236 case DW_AT_use_location: return "DW_AT_use_location";
237 case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
238 case DW_AT_virtuality: return "DW_AT_virtuality";
239 case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
240 /* DWARF 3 values. */
241 case DW_AT_allocated: return "DW_AT_allocated";
242 case DW_AT_associated: return "DW_AT_associated";
243 case DW_AT_data_location: return "DW_AT_data_location";
244 case DW_AT_stride: return "DW_AT_stride";
245 case DW_AT_entry_pc: return "DW_AT_entry_pc";
246 case DW_AT_use_UTF8: return "DW_AT_use_UTF8";
247 case DW_AT_extension: return "DW_AT_extension";
248 case DW_AT_ranges: return "DW_AT_ranges";
249 case DW_AT_trampoline: return "DW_AT_trampoline";
250 case DW_AT_call_column: return "DW_AT_call_column";
251 case DW_AT_call_file: return "DW_AT_call_file";
252 case DW_AT_call_line: return "DW_AT_call_line";
253 case DW_AT_description: return "DW_AT_description";
254 case DW_AT_binary_scale: return "DW_AT_binary_scale";
255 case DW_AT_decimal_scale: return "DW_AT_decimal_scale";
256 case DW_AT_small: return "DW_AT_small";
257 case DW_AT_decimal_sign: return "DW_AT_decimal_sign";
258 case DW_AT_digit_count: return "DW_AT_digit_count";
259 case DW_AT_picture_string: return "DW_AT_picture_string";
260 case DW_AT_mutable: return "DW_AT_mutable";
261 case DW_AT_threads_scaled: return "DW_AT_threads_scaled";
262 case DW_AT_explicit: return "DW_AT_explicit";
263 case DW_AT_object_pointer: return "DW_AT_object_pointer";
264 case DW_AT_endianity: return "DW_AT_endianity";
265 case DW_AT_elemental: return "DW_AT_elemental";
266 case DW_AT_pure: return "DW_AT_pure";
267 case DW_AT_recursive: return "DW_AT_recursive";
268 /* SGI/MIPS extensions. */
269 /* case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde"; */
270 /* DW_AT_MIPS_fde == DW_AT_HP_unmodifiable */
271 case DW_AT_MIPS_loop_begin: return "DW_AT_MIPS_loop_begin";
272 case DW_AT_MIPS_tail_loop_begin: return "DW_AT_MIPS_tail_loop_begin";
273 case DW_AT_MIPS_epilog_begin: return "DW_AT_MIPS_epilog_begin";
274 case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
275 case DW_AT_MIPS_software_pipeline_depth: return "DW_AT_MIPS_software_pipeline_depth";
276 case DW_AT_MIPS_linkage_name: return "DW_AT_MIPS_linkage_name";
277 case DW_AT_MIPS_stride: return "DW_AT_MIPS_stride";
278 case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
279 case DW_AT_MIPS_clone_origin: return "DW_AT_MIPS_clone_origin";
280 case DW_AT_MIPS_has_inlines: return "DW_AT_MIPS_has_inlines";
281 /* HP extensions. */
282 case DW_AT_HP_block_index: return "DW_AT_HP_block_index";
283 case DW_AT_HP_unmodifiable: return "DW_AT_HP_unmodifiable";
284 case DW_AT_HP_actuals_stmt_list: return "DW_AT_HP_actuals_stmt_list";
285 case DW_AT_HP_proc_per_section: return "DW_AT_HP_proc_per_section";
286 case DW_AT_HP_raw_data_ptr: return "DW_AT_HP_raw_data_ptr";
287 case DW_AT_HP_pass_by_reference: return "DW_AT_HP_pass_by_reference";
288 case DW_AT_HP_opt_level: return "DW_AT_HP_opt_level";
289 case DW_AT_HP_prof_version_id: return "DW_AT_HP_prof_version_id";
290 case DW_AT_HP_opt_flags: return "DW_AT_HP_opt_flags";
291 case DW_AT_HP_cold_region_low_pc: return "DW_AT_HP_cold_region_low_pc";
292 case DW_AT_HP_cold_region_high_pc: return "DW_AT_HP_cold_region_high_pc";
293 case DW_AT_HP_all_variables_modifiable: return "DW_AT_HP_all_variables_modifiable";
294 case DW_AT_HP_linkage_name: return "DW_AT_HP_linkage_name";
295 case DW_AT_HP_prof_flags: return "DW_AT_HP_prof_flags";
296 /* GNU extensions. */
297 case DW_AT_sf_names: return "DW_AT_sf_names";
298 case DW_AT_src_info: return "DW_AT_src_info";
299 case DW_AT_mac_info: return "DW_AT_mac_info";
300 case DW_AT_src_coords: return "DW_AT_src_coords";
301 case DW_AT_body_begin: return "DW_AT_body_begin";
302 case DW_AT_body_end: return "DW_AT_body_end";
303 case DW_AT_GNU_vector: return "DW_AT_GNU_vector";
304 /* VMS extensions. */
305 case DW_AT_VMS_rtnbeg_pd_address: return "DW_AT_VMS_rtnbeg_pd_address";
306 /* UPC extension. */
307 case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled";
308 /* PGI (STMicroelectronics) extensions. */
309 case DW_AT_PGI_lbase: return "DW_AT_PGI_lbase";
310 case DW_AT_PGI_soffset: return "DW_AT_PGI_soffset";
311 case DW_AT_PGI_lstride: return "DW_AT_PGI_lstride";
312 default: return "DW_AT_???";
313 }
314}
315
316
317/* ------ To do with evaluation of Dwarf expressions ------ */
318
319/* FIXME: duplicated in readdwarf.c */
320static
321ULong read_leb128 ( UChar* data, Int* length_return, Int sign )
322{
323 ULong result = 0;
324 UInt num_read = 0;
325 Int shift = 0;
326 UChar byte;
327
328 vg_assert(sign == 0 || sign == 1);
329
330 do
331 {
332 byte = * data ++;
333 num_read ++;
334
335 result |= ((ULong)(byte & 0x7f)) << shift;
336
337 shift += 7;
338
339 }
340 while (byte & 0x80);
341
342 if (length_return != NULL)
343 * length_return = num_read;
344
345 if (sign && (shift < 64) && (byte & 0x40))
346 result |= -(1ULL << shift);
347
348 return result;
349}
350
351/* Small helper functions easier to use
352 * value is returned and the given pointer is
353 * moved past end of leb128 data */
354/* FIXME: duplicated in readdwarf.c */
355static ULong read_leb128U( UChar **data )
356{
357 Int len;
358 ULong val = read_leb128( *data, &len, 0 );
359 *data += len;
360 return val;
361}
362
363/* Same for signed data */
364/* FIXME: duplicated in readdwarf.c */
365static Long read_leb128S( UChar **data )
366{
367 Int len;
368 ULong val = read_leb128( *data, &len, 1 );
369 *data += len;
370 return (Long)val;
371}
372
373
374/* FIXME: duplicates logic in readdwarf.c: copy_convert_CfiExpr_tree
375 and {FP,SP}_REG decls */
376static Bool get_Dwarf_Reg( /*OUT*/Addr* a, Word regno, RegSummary* regs )
377{
378 vg_assert(regs);
379# if defined(VGP_amd64_linux)
380 if (regno == 6/*RBP*/) { *a = regs->fp; return True; }
381 if (regno == 7/*RSP*/) { *a = regs->sp; return True; }
382# elif defined(VGP_x86_linux)
383 if (regno == 5/*EBP*/) { *a = regs->fp; return True; }
384 if (regno == 4/*ESP*/) { *a = regs->sp; return True; }
385# elif defined(VGP_ppc32_linux)
386 if (regno == 1/*SP*/) { *a = regs->sp; return True; }
387 VG_(printf)("get_Dwarf_Reg(ppc32-linux)(%ld)\n", regno);
388 if (regno == 31) return False;
389 vg_assert(0);
390# elif defined(VGP_ppc64_linux)
391 if (regno == 1/*SP*/) { *a = regs->sp; return True; }
392 VG_(printf)("get_Dwarf_Reg(ppc64-linux)(%ld)\n", regno);
393 if (regno == 31) return False;
394 vg_assert(0);
395# elif defined(VGP_ppc32_aix5) || defined(VGP_ppc64_aix5)
396 vg_assert(0); /* this function should never be called */
397# else
398# error "Unknown platform"
399# endif
400 return False;
401}
402
403
404/* Evaluate a standard DWARF3 expression. See detailed description in
405 priv_d3basics.h. */
406GXResult ML_(evaluate_Dwarf3_Expr) ( UChar* expr, UWord exprszB,
407 GExpr* fbGX, RegSummary* regs,
408 Addr data_bias,
409 Bool push_initial_zero )
410{
411# define N_EXPR_STACK 20
412
413# define FAIL(_str) \
414 do { \
415 res.kind = GXR_Failure; \
416 res.word = (UWord)(_str); \
417 return res; \
418 } while (0)
419
420# define PUSH(_arg) \
421 do { \
422 vg_assert(sp >= -1 && sp < N_EXPR_STACK); \
423 if (sp == N_EXPR_STACK-1) \
424 FAIL("evaluate_Dwarf3_Expr: stack overflow(1)"); \
425 sp++; \
426 stack[sp] = (_arg); \
427 } while (0)
428
429# define POP(_lval) \
430 do { \
431 vg_assert(sp >= -1 && sp < N_EXPR_STACK); \
432 if (sp == -1) \
433 FAIL("evaluate_Dwarf3_Expr: stack underflow(1)"); \
434 _lval = stack[sp]; \
435 sp--; \
436 } while (0)
437
438 UChar opcode;
439 UChar* limit;
440 Int sp; /* # of top element: valid is -1 .. N_EXPR_STACK-1 */
441 Addr stack[N_EXPR_STACK]; /* stack of addresses, as per D3 spec */
442 GXResult fbval, res;
443 Addr a1;
444 Word sw1;
445 UWord uw1;
446 Bool ok;
447
448 sp = -1;
449 vg_assert(expr);
450 vg_assert(exprszB >= 0);
451 limit = expr + exprszB;
452
453 /* Deal with the case where the entire expression is a single
454 Register Name Operation (D3 spec sec 2.6.1). Then the
455 denotation of the expression as a whole is a register name. */
456 if (exprszB == 1
457 && expr[0] >= DW_OP_reg0 && expr[0] <= DW_OP_reg31) {
458 res.kind = GXR_RegNo;
459 res.word = (UWord)(expr[0] - DW_OP_reg0);
460 return res;
461 }
462 if (exprszB > 1
463 && expr[0] == DW_OP_regx) {
464 /* JRS: 2008Feb20: I believe the following is correct, but would
465 like to see a test case show up before enabling it. */
466 vg_assert(0);
467 expr++;
468 res.kind = GXR_RegNo;
469 res.word = (UWord)read_leb128U( &expr );
470 if (expr != limit)
471 FAIL("evaluate_Dwarf3_Expr: DW_OP_regx*: invalid expr size");
472 else
473 return res;
474 /*NOTREACHED*/
475 }
476
477 /* Evidently this expresion denotes a value, not a register name.
478 So evaluate it accordingly. */
479
480 if (push_initial_zero)
481 PUSH(0);
482
483 while (True) {
484
485 vg_assert(sp >= -1 && sp < N_EXPR_STACK);
486
487 if (expr > limit)
488 /* overrun - something's wrong */
489 FAIL("evaluate_Dwarf3_Expr: ran off end of expr");
490
491 if (expr == limit) {
492 /* end of expr - return expr on the top of stack. */
493 if (sp == -1)
494 /* stack empty. Bad. */
495 FAIL("evaluate_Dwarf3_Expr: stack empty at end of expr");
496 else
497 break;
498 }
499
500 opcode = *expr++;
501 switch (opcode) {
502 case DW_OP_addr:
503 /* Presumably what is given in the Dwarf3 is a SVMA (how
504 could it be otherwise?) So we add the data bias on
505 before pushing the result. FIXME: how can we be sure
506 the data bias is intended, not the text bias? I don't
507 know. */
sewardj68a2ebd2008-03-07 22:17:31 +0000508 /* Furthermore, do we need to take into account the
509 horrible prelinking-induced complications as described
510 in "Comment_Regarding_DWARF3_Text_Biasing" in
511 readdwarf3.c? Currently I don't know. */
sewardjb8b79ad2008-03-03 01:35:41 +0000512 PUSH( *(Addr*)expr + data_bias );
513 expr += sizeof(Addr);
514 break;
515 case DW_OP_fbreg:
516 if (!fbGX)
517 FAIL("evaluate_Dwarf3_Expr: DW_OP_fbreg with "
518 "no expr for fbreg present");
519 fbval = ML_(evaluate_GX)(fbGX, NULL, regs, data_bias);
520 /* Convert fbval into something we can use. If we got a
521 Value, no problem. However, as per D3 spec sec 3.3.5
522 (Low Level Information) sec 2, we could also get a
523 RegNo, and that is taken to mean the value in the
524 indicated register. So we have to manually
525 "dereference" it. */
526 a1 = 0;
527 switch (fbval.kind) {
528 case GXR_Failure:
529 return fbval; /* propagate failure */
530 case GXR_Value:
531 a1 = fbval.word; break; /* use as-is */
532 case GXR_RegNo:
533 ok = get_Dwarf_Reg( &a1, fbval.word, regs );
534 if (!ok) return fbval; /* propagate failure */
535 break;
536 default:
537 vg_assert(0);
538 }
539 sw1 = (Word)read_leb128S( &expr );
540 PUSH( a1 + sw1 );
541 break;
542 /* DW_OP_breg* denotes 'contents of specified register, plus
543 constant offset'. So provided we know what the register's
544 value is, we can evaluate this. Contrast DW_OP_reg*,
545 which indicates that denoted location is in a register
546 itself. If DW_OP_reg* shows up here the expression is
547 malformed, since we are evaluating for value now, and
548 DW_OP_reg* denotes a register location, not a value. See
549 D3 Spec sec 2.6.1 ("Register Name Operations") for
550 details. */
551 case DW_OP_breg0 ... DW_OP_breg31:
552 if (!regs)
553 FAIL("evaluate_Dwarf3_Expr: DW_OP_breg* but no reg info");
554 a1 = 0;
555 if (!get_Dwarf_Reg( &a1, opcode - DW_OP_breg0, regs ))
556 FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_breg*");
557 sw1 = (Word)read_leb128S( &expr );
558 a1 += sw1;
559 PUSH( a1 );
560 break;
561 /* As per comment on DW_OP_breg*, the following denote that
562 the value in question is in a register, not in memory. So
563 we simply return failure. (iow, the expression is
564 malformed). */
565 case DW_OP_reg0 ... DW_OP_reg31:
566 FAIL("evaluate_Dwarf3_Expr: DW_OP_reg* "
567 "whilst evaluating for a value");
568 break;
569 case DW_OP_plus_uconst:
570 POP(uw1);
571 uw1 += (UWord)read_leb128U( &expr );
572 PUSH(uw1);
573 break;
574 case DW_OP_GNU_push_tls_address:
575 /* GDB contains the following cryptic comment: */
576 /* Variable is at a constant offset in the thread-local
577 storage block into the objfile for the current thread and
578 the dynamic linker module containing this expression. Here
579 we return returns the offset from that base. The top of the
580 stack has the offset from the beginning of the thread
581 control block at which the variable is located. Nothing
582 should follow this operator, so the top of stack would be
583 returned. */
584 /* But no spec resulting from Googling. Punt for now. */
585 FAIL("warning: evaluate_Dwarf3_Expr: unhandled "
586 "DW_OP_GNU_push_tls_address");
587 /*NOTREACHED*/
sewardjaa3c28a2008-03-08 10:44:39 +0000588 case DW_OP_deref:
589 POP(uw1);
590 if (VG_(am_is_valid_for_client)( (Addr)uw1, sizeof(Addr),
591 VKI_PROT_READ )) {
592 uw1 = *(UWord*)uw1;
593 PUSH(uw1);
594 } else {
595 FAIL("warning: evaluate_Dwarf3_Expr: DW_OP_deref: "
596 "address not valid for client");
597 }
598 break;
sewardjb8b79ad2008-03-03 01:35:41 +0000599 default:
600 if (!VG_(clo_xml))
601 VG_(message)(Vg_DebugMsg,
602 "warning: evaluate_Dwarf3_Expr: unhandled "
603 "DW_OP_ 0x%x", (Int)opcode);
604 FAIL("evaluate_Dwarf3_Expr: unhandled DW_OP_");
605 /*NOTREACHED*/
606 }
607
608 }
609
610 vg_assert(sp >= 0 && sp < N_EXPR_STACK);
611 res.word = stack[sp];
612 res.kind = GXR_Value;
613 return res;
614
615# undef POP
616# undef PUSH
617# undef FAIL
618# undef N_EXPR_STACK
619}
620
621
622/* Evaluate a so-called Guarded (DWARF3) expression. See detailed
623 description in priv_d3basics.h. */
624GXResult ML_(evaluate_GX)( GExpr* gx, GExpr* fbGX,
625 RegSummary* regs, Addr data_bias )
626{
627 GXResult res;
628 Addr aMin, aMax;
629 UChar uc;
630 UShort nbytes;
631 UWord nGuards = 0;
632 UChar* p = &gx->payload[0];
633 uc = *p++; /*biasMe*/
634 vg_assert(uc == 0 || uc == 1);
635 /* in fact it's senseless to evaluate if the guards need biasing.
636 So don't. */
637 vg_assert(uc == 0);
638 while (True) {
639 uc = *p++;
640 if (uc == 1) { /*isEnd*/
641 /* didn't find any matching range. */
642 res.kind = GXR_Failure;
643 res.word = (UWord)"no matching range";
644 return res;
645 }
646 vg_assert(uc == 0);
647 aMin = * (Addr*)p; p += sizeof(Addr);
648 aMax = * (Addr*)p; p += sizeof(Addr);
649 nbytes = * (UShort*)p; p += sizeof(UShort);
650 nGuards++;
651 if (0) VG_(printf)(" guard %d: %p %p\n",
652 (Int)nGuards, aMin,aMax);
653 if (regs == NULL) {
654 vg_assert(aMin == (Addr)0);
655 vg_assert(aMax == ~(Addr)0);
656 /* Assert this is the first guard. */
657 vg_assert(nGuards == 1);
658 res = ML_(evaluate_Dwarf3_Expr)(
659 p, (UWord)nbytes, fbGX, regs, data_bias,
660 False/*push_initial_zero*/ );
661 /* Now check there are no more guards. */
662 p += (UWord)nbytes;
663 vg_assert(*p == 1); /*isEnd*/
664 return res;
665 } else {
666 if (aMin <= regs->ip && regs->ip <= aMax) {
667 /* found a matching range. Evaluate the expression. */
668 return ML_(evaluate_Dwarf3_Expr)(
669 p, (UWord)nbytes, fbGX, regs, data_bias,
670 False/*push_initial_zero*/ );
671 }
672 }
673 /* else keep searching */
674 p += (UWord)nbytes;
675 }
676}
677
678
679void ML_(pp_GXResult) ( GXResult res )
680{
681 switch (res.kind) {
682 case GXR_Failure:
683 VG_(printf)("GXR_Failure(%s)", (HChar*)res.word); break;
684 case GXR_Value:
685 VG_(printf)("GXR_Value(0x%lx)", res.word); break;
686 case GXR_RegNo:
687 VG_(printf)("GXR_RegNo(%lu)", res.word); break;
688 default:
689 VG_(printf)("GXR_???"); break;
690 }
691}
692
693
694/*--------------------------------------------------------------------*/
695/*--- end d3basics.c ---*/
696/*--------------------------------------------------------------------*/