From 1b8f849b45ded567cf10c7da022447a775270a0e Mon Sep 17 00:00:00 2001 From: Gabriel Corona Date: Mon, 12 Oct 2015 15:56:36 +0200 Subject: [PATCH] [mc] OOify DWARF stack/evaluation expression --- ...arf_expression.cpp => DwarfExpression.cpp} | 259 ++++++------------ src/mc/DwarfExpression.hpp | 93 +++++++ src/mc/Type.hpp | 2 +- src/mc/mc_dwarf.cpp | 2 +- src/mc/mc_location.h | 58 ++-- src/mc/mc_member.cpp | 16 +- .../mc/dwarf_expression/dwarf_expression.cpp | 123 +++++---- tools/cmake/DefinePackages.cmake | 3 +- 8 files changed, 280 insertions(+), 276 deletions(-) rename src/mc/{mc_dwarf_expression.cpp => DwarfExpression.cpp} (57%) create mode 100644 src/mc/DwarfExpression.hpp diff --git a/src/mc/mc_dwarf_expression.cpp b/src/mc/DwarfExpression.cpp similarity index 57% rename from src/mc/mc_dwarf_expression.cpp rename to src/mc/DwarfExpression.cpp index cc9b6a6731..924b5f2f2e 100644 --- a/src/mc/mc_dwarf_expression.cpp +++ b/src/mc/DwarfExpression.cpp @@ -16,19 +16,19 @@ #include "mc/AddressSpace.hpp" #include "mc/Frame.hpp" #include "mc/ObjectInformation.hpp" +#include "mc/DwarfExpression.hpp" using simgrid::mc::remote; -extern "C" { +namespace simgrid { +namespace dwarf { -static int mc_dwarf_push_value(mc_expression_state_t state, Dwarf_Off value) -{ - if (state->stack_size >= MC_EXPRESSION_STACK_SIZE) - return MC_EXPRESSION_E_STACK_OVERFLOW; +evaluation_error::~evaluation_error() {} - state->stack[state->stack_size++] = value; - return 0; } +} + +extern "C" { /** Convert a DWARF register into a libunwind register * @@ -101,11 +101,16 @@ static int mc_dwarf_register_to_libunwind(int dwarf_register) #endif } -int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, - mc_expression_state_t state) +} + +namespace simgrid { +namespace dwarf { + +void execute( + const Dwarf_Op* ops, std::size_t n, + const ExpressionContext& context, ExpressionStack& stack) { for (size_t i = 0; i != n; ++i) { - int error = 0; const Dwarf_Op *op = ops + i; std::uint8_t atom = op->atom; @@ -148,10 +153,10 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, int register_id = mc_dwarf_register_to_libunwind(op->atom - DW_OP_breg0); unw_word_t res; - if (!state->cursor) - return MC_EXPRESSION_E_MISSING_STACK_CONTEXT; - unw_get_reg(state->cursor, register_id, &res); - error = mc_dwarf_push_value(state, res + op->number); + if (!context.cursor) + throw evaluation_error("Missin stack context"); + unw_get_reg(context.cursor, register_id, &res); + stack.push(res + op->number); break; } @@ -162,30 +167,24 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, // (it is a synonym for UNW_X86_64_RSP) so copy the cursor, // unwind it once in order to find the parent SP: - if (!state->cursor) - return MC_EXPRESSION_E_MISSING_STACK_CONTEXT; + if (!context.cursor) + throw evaluation_error("Missint cursor"); // Get frame: - unw_cursor_t cursor = *(state->cursor); + unw_cursor_t cursor = *(context.cursor); unw_step(&cursor); unw_word_t res; unw_get_reg(&cursor, UNW_REG_SP, &res); - error = mc_dwarf_push_value(state, res); + stack.push(res); break; } // Frame base: case DW_OP_fbreg: - { - if (!state->frame_base) - return MC_EXPRESSION_E_MISSING_FRAME_BASE; - std::uintptr_t fb = ((std::uintptr_t) state->frame_base) + op->number; - error = mc_dwarf_push_value(state, fb); - break; - } - + stack.push((std::uintptr_t) context.frame_base + op->number); + break; // ***** Constants: @@ -223,19 +222,17 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: - error = mc_dwarf_push_value(state, atom - DW_OP_lit0); + stack.push(atom - DW_OP_lit0); break; // Address from the base address of this ELF object. // Push the address on the stack (base_address + argument). case DW_OP_addr: { - if (!state->object_info) - return MC_EXPRESSION_E_NO_BASE_ADDRESS; - if (state->stack_size == MC_EXPRESSION_STACK_SIZE) - return MC_EXPRESSION_E_STACK_OVERFLOW; + if (!context.object_info) + throw evaluation_error("No base address"); Dwarf_Off addr = (Dwarf_Off) (std::uintptr_t) - state->object_info->base_address() + op->number; - error = mc_dwarf_push_value(state, addr); + context.object_info->base_address() + op->number; + stack.push(addr); break; } @@ -251,46 +248,29 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, case DW_OP_const8s: case DW_OP_constu: case DW_OP_consts: - if (state->stack_size == MC_EXPRESSION_STACK_SIZE) - return MC_EXPRESSION_E_STACK_OVERFLOW; - error = mc_dwarf_push_value(state, op->number); + stack.push(op->number); break; // ***** Stack manipulation: // Push another copy/duplicate the value at the top of the stack: case DW_OP_dup: - if (state->stack_size == 0) - return MC_EXPRESSION_E_STACK_UNDERFLOW; - else - error = mc_dwarf_push_value(state, state->stack[state->stack_size - 1]); + stack.dup(); break; // Pop/drop the top of the stack: case DW_OP_drop: - if (state->stack_size == 0) - return MC_EXPRESSION_E_STACK_UNDERFLOW; - else - state->stack_size--; + stack.pop(); break; // Swap the two top-most value of the stack: case DW_OP_swap: - if (state->stack_size < 2) - return MC_EXPRESSION_E_STACK_UNDERFLOW; - { - std::uintptr_t temp = state->stack[state->stack_size - 2]; - state->stack[state->stack_size - 2] = - state->stack[state->stack_size - 1]; - state->stack[state->stack_size - 1] = temp; - } + std::swap(stack.top(), stack.top(1)); break; // Duplicate the value under the top of the stack: case DW_OP_over: - if (state->stack_size < 2) - return MC_EXPRESSION_E_STACK_UNDERFLOW; - error = mc_dwarf_push_value(state, state->stack[state->stack_size - 2]); + stack.push(stack.top(1)); break; // ***** Operations: @@ -299,99 +279,39 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, // (stack.top() += stack.before_top()). case DW_OP_plus: - if (state->stack_size < 2) - return MC_EXPRESSION_E_STACK_UNDERFLOW; - { - std::uintptr_t result = - state->stack[state->stack_size - 2] + - state->stack[state->stack_size - 1]; - state->stack[state->stack_size - 2] = result; - state->stack_size--; - } + stack.push(stack.pop() + stack.pop()); break; case DW_OP_mul: - if (state->stack_size < 2) - return MC_EXPRESSION_E_STACK_UNDERFLOW; - { - std::uintptr_t result = - state->stack[state->stack_size - 2] - - state->stack[state->stack_size - 1]; - state->stack[state->stack_size - 2] = result; - state->stack_size--; - } + stack.push(stack.pop() * stack.pop()); break; case DW_OP_plus_uconst: - if (state->stack_size == 0) - return MC_EXPRESSION_E_STACK_UNDERFLOW; - state->stack[state->stack_size - 1] += op->number; + stack.top() += op->number; break; case DW_OP_not: - if (state->stack_size == 0) - return MC_EXPRESSION_E_STACK_UNDERFLOW; - state->stack[state->stack_size - 1] = - ~state->stack[state->stack_size - 1]; + stack.top() = ~stack.top(); break; case DW_OP_neg: - if (state->stack_size == 0) - return MC_EXPRESSION_E_STACK_UNDERFLOW; - { - intptr_t value = state->stack[state->stack_size - 1]; - if (value < 0) - value = -value; - state->stack[state->stack_size - 1] = value; - } + stack.top() = - (intptr_t) stack.top(); break; case DW_OP_minus: - if (state->stack_size < 2) - return MC_EXPRESSION_E_STACK_UNDERFLOW; - { - std::uintptr_t result = - state->stack[state->stack_size - 2] - - state->stack[state->stack_size - 1]; - state->stack[state->stack_size - 2] = result; - state->stack_size--; - } + stack.push(stack.pop() - stack.pop()); break; case DW_OP_and: - if (state->stack_size < 2) - return MC_EXPRESSION_E_STACK_UNDERFLOW; - { - std::uintptr_t result = - state->stack[state->stack_size - - 2] & state->stack[state->stack_size - 1]; - state->stack[state->stack_size - 2] = result; - state->stack_size--; - } + stack.push(stack.pop() & stack.pop()); break; case DW_OP_or: - if (state->stack_size < 2) - return MC_EXPRESSION_E_STACK_UNDERFLOW; - { - std::uintptr_t result = - state->stack[state->stack_size - - 2] | state->stack[state->stack_size - 1]; - state->stack[state->stack_size - 2] = result; - state->stack_size--; - } + stack.push(stack.pop() | stack.pop()); break; case DW_OP_xor: - if (state->stack_size < 2) - return MC_EXPRESSION_E_STACK_UNDERFLOW; - { - std::uintptr_t result = - state->stack[state->stack_size - - 2] ^ state->stack[state->stack_size - 1]; - state->stack[state->stack_size - 2] = result; - state->stack_size--; - } + stack.push(stack.pop() ^ stack.pop()); break; case DW_OP_nop: @@ -400,31 +320,23 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, // ***** Deference (memory fetch) case DW_OP_deref_size: - return MC_EXPRESSION_E_UNSUPPORTED_OPERATION; + throw evaluation_error("Unsupported operation"); case DW_OP_deref: - if (state->stack_size == 0) - return MC_EXPRESSION_E_STACK_UNDERFLOW; - { - // Computed address: - std::uintptr_t address = (std::uintptr_t) state->stack[state->stack_size - 1]; - if (!state->address_space) - xbt_die("Missing address space"); - state->address_space->read_bytes( - &state->stack[state->stack_size - 1], sizeof(uintptr_t), - remote(address), state->process_index); - } + // Computed address: + if (!context.address_space) + throw evaluation_error("Missing address space"); + context.address_space->read_bytes( + &stack.top(), sizeof(uintptr_t), remote(stack.top()), + context.process_index); break; // Not handled: default: - return MC_EXPRESSION_E_UNSUPPORTED_OPERATION; + throw evaluation_error("Unsupported operation"); } - if (error) - return error; } - return 0; } // ***** Location @@ -432,25 +344,24 @@ int mc_dwarf_execute_expression(size_t n, const Dwarf_Op * ops, /** \brief Resolve a location expression * \deprecated Use mc_dwarf_resolve_expression */ -void mc_dwarf_resolve_location(mc_location_t location, - simgrid::mc::DwarfExpression* expression, - simgrid::mc::ObjectInformation* object_info, - unw_cursor_t * c, - void *frame_pointer_address, - simgrid::mc::AddressSpace* address_space, int process_index) +void resolve_location(mc_location_t location, + simgrid::dwarf::DwarfExpression const& expression, + simgrid::mc::ObjectInformation* object_info, + unw_cursor_t * c, + void *frame_pointer_address, + simgrid::mc::AddressSpace* address_space, int process_index) { - s_mc_expression_state_t state; - memset(&state, 0, sizeof(s_mc_expression_state_t)); - state.frame_base = frame_pointer_address; - state.cursor = c; - state.address_space = address_space; - state.object_info = object_info; - state.process_index = process_index; - - if (expression->size() >= 1 - && (*expression)[0].atom >=DW_OP_reg0 - && (*expression)[0].atom <= DW_OP_reg31) { - int dwarf_register = (*expression)[0].atom - DW_OP_reg0; + simgrid::dwarf::ExpressionContext context; + context.frame_base = frame_pointer_address; + context.cursor = c; + context.address_space = address_space; + context.object_info = object_info; + context.process_index = process_index; + + if (!expression.empty() + && expression[0].atom >= DW_OP_reg0 + && expression[0].atom <= DW_OP_reg31) { + int dwarf_register = expression[0].atom - DW_OP_reg0; xbt_assert(c, "Missing frame context for register operation DW_OP_reg%i", dwarf_register); @@ -460,20 +371,19 @@ void mc_dwarf_resolve_location(mc_location_t location, return; } - if (mc_dwarf_execute_expression( - expression->size(), expression->data(), &state)) - xbt_die("Error evaluating DWARF expression"); - if (state.stack_size == 0) - xbt_die("No value on the stack"); - else { - location->memory_location = (void*) state.stack[state.stack_size - 1]; - location->cursor = NULL; - location->register_id = 0; - } + simgrid::dwarf::ExpressionStack stack; + simgrid::dwarf::execute(expression, context, stack); + + location->memory_location = (void*) stack.top(); + location->cursor = NULL; + location->register_id = 0; +} + +} } // TODO, move this in a method of LocationList -static simgrid::mc::DwarfExpression* mc_find_expression( +static simgrid::dwarf::DwarfExpression* mc_find_expression( simgrid::mc::LocationList* locations, unw_word_t ip) { for (simgrid::mc::LocationListEntry& entry : *locations) @@ -482,6 +392,8 @@ static simgrid::mc::DwarfExpression* mc_find_expression( return nullptr; } +extern "C" { + void mc_dwarf_resolve_locations(mc_location_t location, simgrid::mc::LocationList* locations, simgrid::mc::ObjectInformation* object_info, @@ -497,10 +409,11 @@ void mc_dwarf_resolve_locations(mc_location_t location, xbt_die("Could not resolve IP"); } - simgrid::mc::DwarfExpression* expression = mc_find_expression(locations, ip); + simgrid::dwarf::DwarfExpression* expression = + mc_find_expression(locations, ip); if (expression) { - mc_dwarf_resolve_location(location, - expression, object_info, c, + simgrid::dwarf::resolve_location(location, + *expression, object_info, c, frame_pointer_address, address_space, process_index); } else { xbt_die("Could not resolve location"); @@ -560,7 +473,7 @@ void mc_dwarf_location_list_init( xbt_die("Error while loading location list"); simgrid::mc::LocationListEntry entry; - entry.expression = simgrid::mc::DwarfExpression(ops, ops + len); + entry.expression = simgrid::dwarf::DwarfExpression(ops, ops + len); void *base = info->base_address(); // If start == 0, this is not a location list: diff --git a/src/mc/DwarfExpression.hpp b/src/mc/DwarfExpression.hpp new file mode 100644 index 0000000000..7a64654cfe --- /dev/null +++ b/src/mc/DwarfExpression.hpp @@ -0,0 +1,93 @@ +#ifndef SIMGRID_MC_DWARF_EXPRESSION_HPP +#define SIMGRID_MC_DWARF_EXPRESSION_HPP + +#include + +#include + +#include + +namespace simgrid { +namespace dwarf { + +class evaluation_error : std::runtime_error { +public: + evaluation_error(const char* what) : std::runtime_error(what) {} + ~evaluation_error(); +}; + +struct ExpressionContext { + ExpressionContext() : + cursor(nullptr), frame_base(nullptr), address_space(nullptr), + object_info(nullptr), process_index(simgrid::mc::ProcessIndexMissing) {} + + unw_cursor_t* cursor; + void* frame_base; + simgrid::mc::AddressSpace* address_space; + simgrid::mc::ObjectInformation* object_info; + int process_index; +}; + +typedef std::vector DwarfExpression; + +class ExpressionStack { +public: + typedef std::uintptr_t value_type; + static const std::size_t max_size = 64; +private: + uintptr_t stack_[max_size]; + size_t size_; +public: + ExpressionStack() : size_(0) {} + + // Access: + std::size_t size() const { return size_; } + bool empty() const { return size_ == 0; } + void clear() { size_ = 0; } + uintptr_t& operator[](int i) { return stack_[i]; } + uintptr_t const& operator[](int i) const { return stack_[i]; } + value_type& top() + { + if (size_ == 0) + throw evaluation_error("Empty stack"); + return stack_[size_ - 1]; + } + value_type& top(unsigned i) + { + if (size_ < i) + throw evaluation_error("Invalid element"); + return stack_[size_ - 1 - i]; + } + + // Push/pop: + void push(value_type value) + { + if (size_ == max_size) + throw evaluation_error("Dwarf stack overflow"); + stack_[size_++] = value; + } + value_type pop() + { + if (size_ == 0) + throw evaluation_error("Stack underflow"); + return stack_[--size_]; + } + + // Other operations: + void dup() { push(top()); } +}; + +void execute(const Dwarf_Op* ops, std::size_t n, + ExpressionContext const& context, ExpressionStack& stack); + +inline +void execute(simgrid::dwarf::DwarfExpression const& expression, + ExpressionContext const& context, ExpressionStack& stack) +{ + execute(expression.data(), expression.size(), context, stack); +} + +} +} + +#endif \ No newline at end of file diff --git a/src/mc/Type.hpp b/src/mc/Type.hpp index 540bf4ca37..42978af47b 100644 --- a/src/mc/Type.hpp +++ b/src/mc/Type.hpp @@ -25,7 +25,7 @@ public: bool inheritance; std::string name; - simgrid::mc::DwarfExpression location_expression; + simgrid::dwarf::DwarfExpression location_expression; std::size_t byte_size; // Do we really need this? unsigned type_id; simgrid::mc::Type* type; diff --git a/src/mc/mc_dwarf.cpp b/src/mc/mc_dwarf.cpp index 90fd3d61a1..9d30fcffe1 100644 --- a/src/mc/mc_dwarf.cpp +++ b/src/mc/mc_dwarf.cpp @@ -517,7 +517,7 @@ static void MC_dwarf_fill_member_location( ("Could not read location expression DW_AT_data_member_location in DW_TAG_member %s of type <%" PRIx64 ">%s", MC_dwarf_attr_integrate_string(child, DW_AT_name), (uint64_t) type->id, type->name.c_str()); - member->location_expression = simgrid::mc::DwarfExpression(expr, expr+len); + member->location_expression = simgrid::dwarf::DwarfExpression(expr, expr+len); break; } case simgrid::dwarf::FormClass::Constant: diff --git a/src/mc/mc_location.h b/src/mc/mc_location.h index 1f82a16d34..06be71b1ed 100644 --- a/src/mc/mc_location.h +++ b/src/mc/mc_location.h @@ -18,18 +18,17 @@ #include #include "mc_base.h" #include "mc_forward.hpp" -#include "AddressSpace.hpp" +#include "mc/AddressSpace.hpp" +#include "mc/DwarfExpression.hpp" namespace simgrid { namespace mc { -typedef std::vector DwarfExpression; - /** \brief A DWARF expression with optional validity contraints */ class LocationListEntry { public: - DwarfExpression expression; + simgrid::dwarf::DwarfExpression expression; void* lowpc, *highpc; LocationListEntry() : lowpc(nullptr), highpc(nullptr) {} @@ -90,11 +89,22 @@ enum mc_location_type mc_get_location_type(mc_location_t location) { } } -XBT_PRIVATE void mc_dwarf_resolve_location( - mc_location_t location, simgrid::mc::DwarfExpression* expression, +SG_END_DECL() + +namespace simgrid { +namespace dwarf { + +XBT_PRIVATE void resolve_location( + mc_location_t location, simgrid::dwarf::DwarfExpression const& expression, simgrid::mc::ObjectInformation* object_info, unw_cursor_t* c, void* frame_pointer_address, simgrid::mc::AddressSpace* address_space, int process_index); + +} +} + +SG_BEGIN_DECL() + void mc_dwarf_resolve_locations( mc_location_t location, simgrid::mc::LocationList* locations, simgrid::mc::ObjectInformation* object_info, unw_cursor_t* c, @@ -105,45 +115,9 @@ XBT_PRIVATE void mc_dwarf_location_list_init( simgrid::mc::LocationList*, simgrid::mc::ObjectInformation* info, Dwarf_Die* die, Dwarf_Attribute* attr); -#define MC_EXPRESSION_STACK_SIZE 64 - -#define MC_EXPRESSION_OK 0 -#define MC_EXPRESSION_E_UNSUPPORTED_OPERATION 1 -#define MC_EXPRESSION_E_STACK_OVERFLOW 2 -#define MC_EXPRESSION_E_STACK_UNDERFLOW 3 -#define MC_EXPRESSION_E_MISSING_STACK_CONTEXT 4 -#define MC_EXPRESSION_E_MISSING_FRAME_BASE 5 -#define MC_EXPRESSION_E_NO_BASE_ADDRESS 6 - -typedef struct s_mc_expression_state { - uintptr_t stack[MC_EXPRESSION_STACK_SIZE]; - size_t stack_size; - - unw_cursor_t* cursor; - void* frame_base; - simgrid::mc::AddressSpace* address_space; - simgrid::mc::ObjectInformation* object_info; - int process_index; -} s_mc_expression_state_t, *mc_expression_state_t; - -XBT_PUBLIC(int) mc_dwarf_execute_expression( - size_t n, const Dwarf_Op* ops, mc_expression_state_t state); void* mc_find_frame_base( simgrid::mc::Frame* frame, simgrid::mc::ObjectInformation* object_info, unw_cursor_t* unw_cursor); SG_END_DECL() -namespace simgrid { -namespace mc { - -static inline -int execute(DwarfExpression const& expression, mc_expression_state_t state) -{ - return mc_dwarf_execute_expression( - expression.size(), expression.data(), state); -} - -} -} - #endif diff --git a/src/mc/mc_member.cpp b/src/mc/mc_member.cpp index c69ef5159a..d7003c411e 100644 --- a/src/mc/mc_member.cpp +++ b/src/mc/mc_member.cpp @@ -29,22 +29,16 @@ void *resolve_member( if (!member->has_offset_location()) return ((char *) base) + member->offset(); - s_mc_expression_state_t state; - memset(&state, 0, sizeof(s_mc_expression_state_t)); + ExpressionContext state; state.frame_base = NULL; state.cursor = NULL; state.address_space = address_space; - state.stack_size = 1; - state.stack[0] = (uintptr_t) base; state.process_index = process_index; - if (simgrid::mc::execute( - member->location_expression, &state)) - xbt_die("Error evaluating DWARF expression"); - if (state.stack_size == 0) - xbt_die("No value on the stack"); - else - return (void *) state.stack[state.stack_size - 1]; + ExpressionStack stack; + stack.push((ExpressionStack::value_type) base); + simgrid::dwarf::execute(member->location_expression, state, stack); + return (void*) stack.top(); } } diff --git a/teshsuite/mc/dwarf_expression/dwarf_expression.cpp b/teshsuite/mc/dwarf_expression/dwarf_expression.cpp index 98ce2076ce..fa42b88066 100644 --- a/teshsuite/mc/dwarf_expression/dwarf_expression.cpp +++ b/teshsuite/mc/dwarf_expression/dwarf_expression.cpp @@ -23,8 +23,8 @@ static simgrid::mc::Process* process; static -uintptr_t eval_binary_operation(mc_expression_state_t state, int op, uintptr_t a, uintptr_t b) { - state->stack_size = 0; +uintptr_t eval_binary_operation( + simgrid::dwarf::ExpressionContext& state, int op, uintptr_t a, uintptr_t b) { Dwarf_Op ops[15]; ops[0].atom = DW_OP_const8u; @@ -33,126 +33,155 @@ uintptr_t eval_binary_operation(mc_expression_state_t state, int op, uintptr_t a ops[1].number = b; ops[2].atom = op; - assert(mc_dwarf_execute_expression(3, ops, state) == MC_EXPRESSION_OK); - assert(state->stack_size==1); - return state->stack[state->stack_size - 1]; + simgrid::dwarf::ExpressionStack stack; + + try { + simgrid::dwarf::execute(ops, 3, state, stack); + } + catch(std::runtime_error& e) { + assert(("Expression evaluation error", false)); + } + + assert(stack.size() == 1); + return stack.top(); } static -void basic_test(mc_expression_state_t state) { +void basic_test(simgrid::dwarf::ExpressionContext const& state) { + try { + Dwarf_Op ops[60]; uintptr_t a = rand(); uintptr_t b = rand(); - ops[0].atom = DW_OP_drop; - assert(mc_dwarf_execute_expression(1, ops, state) == MC_EXPRESSION_E_STACK_UNDERFLOW); + simgrid::dwarf::ExpressionStack stack; + + try { + ops[0].atom = DW_OP_drop; + simgrid::dwarf::execute(ops, 1, state, stack); + assert(("Exception expected", false)); + } + catch(simgrid::dwarf::evaluation_error& e) {} ops[0].atom = DW_OP_lit21; - assert(mc_dwarf_execute_expression(1, ops, state) == MC_EXPRESSION_OK); - assert(state->stack_size==1); - assert(state->stack[state->stack_size-1]==21); + simgrid::dwarf::execute(ops, 1, state, stack); + assert(stack.size() == 1); + assert(stack.top() == 21); ops[0].atom = DW_OP_const8u; ops[0].number = a; - assert(mc_dwarf_execute_expression(1, ops, state) == MC_EXPRESSION_OK); - assert(state->stack_size==2); - assert(state->stack[state->stack_size-1] == a); + simgrid::dwarf::execute(ops, 1, state, stack); + assert(stack.size() == 2); + assert(stack.top() == a); ops[0].atom = DW_OP_drop; ops[1].atom = DW_OP_drop; - assert(mc_dwarf_execute_expression(2, ops, state) == MC_EXPRESSION_OK); - assert(state->stack_size==0); + simgrid::dwarf::execute(ops, 2, state, stack); + assert(stack.empty()); + stack.clear(); ops[0].atom = DW_OP_lit21; ops[1].atom = DW_OP_plus_uconst; ops[1].number = a; - assert(mc_dwarf_execute_expression(2, ops, state) == MC_EXPRESSION_OK); - assert(state->stack_size==1); - assert(state->stack[state->stack_size-1]== a + 21); + simgrid::dwarf::execute(ops, 2, state, stack); + assert(stack.size() == 1); + assert(stack.top() == a + 21); - state->stack_size = 0; + stack.clear(); ops[0].atom = DW_OP_const8u; ops[0].number = a; ops[1].atom = DW_OP_dup; ops[2].atom = DW_OP_plus; - assert(mc_dwarf_execute_expression(3, ops, state) == MC_EXPRESSION_OK); - assert(state->stack_size==1); - assert(state->stack[state->stack_size-1]== a + a); + simgrid::dwarf::execute(ops, 3, state, stack); + assert(stack.size() == 1); + assert(stack.top() == a + a); - state->stack_size = 0; + stack.clear(); ops[0].atom = DW_OP_const8u; ops[0].number = a; ops[1].atom = DW_OP_const8u; ops[1].number = b; ops[2].atom = DW_OP_over; - assert(mc_dwarf_execute_expression(3, ops, state) == MC_EXPRESSION_OK); - assert(state->stack_size==3); - assert(state->stack[state->stack_size-1]== a); - assert(state->stack[state->stack_size-2]== b); - assert(state->stack[state->stack_size-3]== a); + simgrid::dwarf::execute(ops, 3, state, stack); + assert(stack.size() == 3); + assert(stack.top() == a); + assert(stack.top(1) == b); + assert(stack.top(2) == a); - state->stack_size = 0; + stack.clear(); ops[0].atom = DW_OP_const8u; ops[0].number = a; ops[1].atom = DW_OP_const8u; ops[1].number = b; ops[2].atom = DW_OP_swap; - assert(mc_dwarf_execute_expression(3, ops, state) == MC_EXPRESSION_OK); - assert(state->stack_size=2); - assert(state->stack[state->stack_size-1]== a); - assert(state->stack[state->stack_size-2]== b); + simgrid::dwarf::execute(ops, 3, state, stack); + assert(stack.size() == 2); + assert(stack.top() == a); + assert(stack.top(1) == b); + + } + catch(std::runtime_error& e) { + assert(("Expression evaluation error", false)); + } } static -void test_deref(mc_expression_state_t state) { +void test_deref(simgrid::dwarf::ExpressionContext const& state) { + try { + uintptr_t foo = 42; Dwarf_Op ops[60]; ops[0].atom = DW_OP_const8u; ops[0].number = (uintptr_t) &foo; ops[1].atom = DW_OP_deref; - state->stack_size = 0; - assert(mc_dwarf_execute_expression(2, ops, state) == MC_EXPRESSION_OK); - assert(state->stack_size==1); - assert(state->stack[state->stack_size-1] == foo); + simgrid::dwarf::ExpressionStack stack; + + simgrid::dwarf::execute(ops, 2, state, stack); + assert(stack.size() == 1); + assert(stack.top() == foo); + + } + catch(std::runtime_error& e) { + assert(("Expression evaluation error", false)); + } } int main(int argc, char** argv) { process = new simgrid::mc::Process(getpid(), -1); - s_mc_expression_state_t state; - memset(&state, 0, sizeof(s_mc_expression_state_t)); + simgrid::dwarf::ExpressionContext state; state.address_space = (simgrid::mc::AddressSpace*) process; - basic_test(&state); + basic_test(state); for(int i=0; i!=100; ++i) { uintptr_t a = rand(); uintptr_t b = rand(); - assert(eval_binary_operation(&state, DW_OP_plus, a, b) == (a + b)); + assert(eval_binary_operation(state, DW_OP_plus, a, b) == (a + b)); } for(int i=0; i!=100; ++i) { uintptr_t a = rand(); uintptr_t b = rand(); - assert(eval_binary_operation(&state, DW_OP_or, a, b) == (a | b)); + assert(eval_binary_operation(state, DW_OP_or, a, b) == (a | b)); } for(int i=0; i!=100; ++i) { uintptr_t a = rand(); uintptr_t b = rand(); - assert(eval_binary_operation(&state, DW_OP_and, a, b) == (a & b)); + assert(eval_binary_operation(state, DW_OP_and, a, b) == (a & b)); } for(int i=0; i!=100; ++i) { uintptr_t a = rand(); uintptr_t b = rand(); - assert(eval_binary_operation(&state, DW_OP_xor, a, b) == (a ^ b)); + assert(eval_binary_operation(state, DW_OP_xor, a, b) == (a ^ b)); } - test_deref(&state); + test_deref(state); return 0; } diff --git a/tools/cmake/DefinePackages.cmake b/tools/cmake/DefinePackages.cmake index 3c33fd9ab8..32ab76fc0b 100644 --- a/tools/cmake/DefinePackages.cmake +++ b/tools/cmake/DefinePackages.cmake @@ -646,7 +646,8 @@ set(MC_SRC src/mc/mc_dwarf.hpp src/mc/mc_dwarf.cpp src/mc/mc_dwarf_attrnames.cpp - src/mc/mc_dwarf_expression.cpp + src/mc/DwarfExpression.hpp + src/mc/DwarfExpression.cpp src/mc/mc_dwarf_tagnames.cpp src/mc/mc_hash.hpp src/mc/mc_hash.cpp -- 2.20.1