From d52761f89a1826b1cca29b1a63269eafe7197756 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 14 Jul 2009 17:57:16 -0700 Subject: PR4166: Allow array-like indexing on pointers * dwflpp.cxx (dwflpp::translate_components): let pointers get treated the same as arrays, and add a final DIE dereference for array access. * loc2c.c (c_translate_array): tolerate pointer types * testsuite/systemtap.base/pointer_array.*: new test --- dwflpp.cxx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'dwflpp.cxx') diff --git a/dwflpp.cxx b/dwflpp.cxx index 8fa31c6a..3f30e3a8 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -1684,13 +1684,10 @@ dwflpp::translate_components(struct obstack *pool, break; case DW_TAG_pointer_type: - if (e->components[i].first == target_symbol::comp_literal_array_index) - throw semantic_error ("cannot index pointer", e->tok); - // XXX: of course, we should support this the same way C does, - // by explicit pointer arithmetic etc. PR4166. - c_translate_pointer (pool, 1, 0 /* PR9768*/, die, tail); - break; + if (e->components[i].first != target_symbol::comp_literal_array_index) + break; + /* else fall through as an array access */ case DW_TAG_array_type: if (e->components[i].first == target_symbol::comp_literal_array_index) @@ -1772,6 +1769,11 @@ dwflpp::translate_components(struct obstack *pool, if (dwarf_attr_integrate (die, DW_AT_type, attr_mem) == NULL) throw semantic_error ("cannot get type of field: " + string(dwarf_errmsg (-1)), e->tok); } + + /* For an array index, we need to dereference the final DIE */ + if (e->components.back().first == target_symbol::comp_literal_array_index) + die = dwarf_formref_die (attr_mem, die_mem); + return die; } -- cgit From 00b01a991cc4300f18c747853e85841d187b1fa4 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 15 Jul 2009 12:04:57 +0200 Subject: PR10388 Support DW_OP_call_frame_cfa. Depends on elfutils 0.142 cfi support. * loc2c.h (c_translate_location): Take (optional) Dwarf_Op *cfa_ops. * loc2c.c (translate): Recognize DW_OP_call_frame_cfa. (location_from_address): Take cfa_ops, examine fb_ops, if it is DW_OP_call_frame_cfa, pass cfa_ops to translate instead. (location_relative): Take cfa_ops, pass to location_from_address. (c_translate_location): Take cfa_ops, pass to location_from_address. * loc2c-test.c (handle_variable): Take cfa_ops, pass to c_translate_location when needed. (main): Fetch cfa_ops, pass to handle_variable. * dwflpp.h (struct dwflpp): Add new method get_cfa_ops. * dwflpp.cxx: Include elfutils/version.h. (translate_location): Fetch cfa_ops when necessary. (get_cfa_ops): New method. --- dwflpp.cxx | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'dwflpp.cxx') diff --git a/dwflpp.cxx b/dwflpp.cxx index 3f30e3a8..dc7af5d8 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -41,6 +41,9 @@ extern "C" { #include #include #include +#ifdef HAVE_ELFUTILS_VERSION_H +#include +#endif #include #include #include @@ -1497,10 +1500,11 @@ dwflpp::translate_location(struct obstack *pool, e->tok); } + Dwarf_Op *cfa_ops = get_cfa_ops (pc); return c_translate_location (pool, &loc2c_error, this, &loc2c_emit_address, 1, 0 /* PR9768 */, - pc, expr, len, tail, fb_attr); + pc, expr, len, tail, fb_attr, cfa_ops); } @@ -2085,7 +2089,7 @@ dwflpp::literal_stmt_for_return (Dwarf_Die *scope_die, &loc2c_emit_address, 1, 0 /* PR9768 */, pc, locops, nlocops, - &tail, NULL); + &tail, NULL, NULL); /* Translate the ->bar->baz[NN] parts. */ @@ -2489,5 +2493,36 @@ dwflpp::dwarf_getscopes_cached (Dwarf_Addr pc, Dwarf_Die **scopes) return num_cached_scopes; } +Dwarf_Op * +dwflpp::get_cfa_ops (Dwarf_Addr pc) +{ + Dwarf_Op *cfa_ops = NULL; + +#ifdef _ELFUTILS_PREREQ +#if _ELFUTILS_PREREQ(0,142) + // Try debug_frame first, then fall back on eh_frame. + Dwarf_Addr bias; + Dwarf_CFI *cfi = dwfl_module_dwarf_cfi (module, &bias); + if (cfi != NULL) + { + Dwarf_Frame *frame = NULL; + if (dwarf_cfi_addrframe (cfi, pc, &frame) == 0) + dwarf_frame_cfa (frame, &cfa_ops); + } + if (cfa_ops == NULL) + { + cfi = dwfl_module_eh_cfi (module, &bias); + if (cfi != NULL) + { + Dwarf_Frame *frame = NULL; + if (dwarf_cfi_addrframe (cfi, pc, &frame) == 0) + dwarf_frame_cfa (frame, &cfa_ops); + } + } +#endif +#endif + + return cfa_ops; +} /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ -- cgit From 03c75a4a21ef3dba8abbc7e596d2a102427a3d96 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 15 Jul 2009 18:21:56 -0700 Subject: PR5930: Address-op for $target and @cast members This allows the '&' operator to get the address of @cast and $target variable expressions. * staptree.h (target_symbol): add addressof field * staptree.cxx (target_symbol::print): print '&' for addressof (cast_op::print): ditto * parse.cxx (parser::parse_value): allow '&' prefix on $target/@cast * dwflpp.cxx (dwflpp::translate_final_fetch_or_store): allow taking the computed address without actually doing a final fetch. * tapset* (*::visit_target_symbol): throw errors for $vars w/o addresses * testsuite/systemtap.base/cast.stp: add &@cast test * testsuite/semok/target_addr.stp: test '&' on different member types * testsuite/semko/target_addr?.stp: test failure on bitfields/registers --- dwflpp.cxx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'dwflpp.cxx') diff --git a/dwflpp.cxx b/dwflpp.cxx index dc7af5d8..79561c73 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -1830,6 +1830,21 @@ dwflpp::translate_final_fetch_or_store (struct obstack *pool, typedie = resolve_unqualified_inner_typedie (&typedie_mem, attr_mem, e); typetag = dwarf_tag (typedie); + /* If we're looking for an address, then we can just provide what + we computed to this point, without using a fetch/store. */ + if (e->addressof) + { + if (lvalue) + throw semantic_error ("cannot write to member address", e->tok); + + if (dwarf_hasattr_integrate (die, DW_AT_bit_offset)) + throw semantic_error ("cannot take address of bit-field", e->tok); + + c_translate_addressof (pool, 1, 0, 0, die, tail, "THIS->__retvalue"); + ty = pe_long; + return; + } + /* Then switch behavior depending on the type of fetch/store we want, and the type and pointer-ness of the final location. */ -- cgit