Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[mc] OOify DWARF stack/evaluation expression
authorGabriel Corona <gabriel.corona@loria.fr>
Mon, 12 Oct 2015 13:56:36 +0000 (15:56 +0200)
committerGabriel Corona <gabriel.corona@loria.fr>
Thu, 15 Oct 2015 09:18:31 +0000 (11:18 +0200)
src/mc/DwarfExpression.cpp [moved from src/mc/mc_dwarf_expression.cpp with 57% similarity]
src/mc/DwarfExpression.hpp [new file with mode: 0644]
src/mc/Type.hpp
src/mc/mc_dwarf.cpp
src/mc/mc_location.h
src/mc/mc_member.cpp
teshsuite/mc/dwarf_expression/dwarf_expression.cpp
tools/cmake/DefinePackages.cmake

similarity index 57%
rename from src/mc/mc_dwarf_expression.cpp
rename to src/mc/DwarfExpression.cpp
index cc9b6a6..924b5f2 100644 (file)
 #include "mc/AddressSpace.hpp"
 #include "mc/Frame.hpp"
 #include "mc/ObjectInformation.hpp"
 #include "mc/AddressSpace.hpp"
 #include "mc/Frame.hpp"
 #include "mc/ObjectInformation.hpp"
+#include "mc/DwarfExpression.hpp"
 
 using simgrid::mc::remote;
 
 
 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
  *
 
 /** Convert a DWARF register into a libunwind register
  *
@@ -101,11 +101,16 @@ static int mc_dwarf_register_to_libunwind(int dwarf_register)
 #endif
 }
 
 #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) {
 {
   for (size_t i = 0; i != n; ++i) {
-    int error = 0;
     const Dwarf_Op *op = ops + i;
     std::uint8_t atom = op->atom;
 
     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;
         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;
       }
 
         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:
 
         // (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:
 
         // 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);
         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:
         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:
 
 
       // ***** 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:
     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: {
       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)
       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;
     }
 
       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:
     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:
       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:
       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:
       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:
       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:
       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:
       // (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:
       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:
       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:
       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:
       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:
       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:
       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:
       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:
       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:
       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:
       // ***** Deference (memory fetch)
 
     case DW_OP_deref_size:
-      return MC_EXPRESSION_E_UNSUPPORTED_OPERATION;
+      throw evaluation_error("Unsupported operation");
 
     case DW_OP_deref:
 
     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:
       break;
 
       // Not handled:
     default:
-      return MC_EXPRESSION_E_UNSUPPORTED_OPERATION;
+      throw evaluation_error("Unsupported operation");
     }
 
     }
 
-    if (error)
-      return error;
   }
   }
-  return 0;
 }
 
 // ***** Location
 }
 
 // ***** 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
  */
 /** \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);
     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;
   }
 
     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
 }
 
 // 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)
     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;
 }
 
   return nullptr;
 }
 
+extern "C" {
+
 void mc_dwarf_resolve_locations(mc_location_t location,
                                 simgrid::mc::LocationList* locations,
                                 simgrid::mc::ObjectInformation* object_info,
 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");
   }
 
       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) {
   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");
                               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;
       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:
 
     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 (file)
index 0000000..7a64654
--- /dev/null
@@ -0,0 +1,93 @@
+#ifndef SIMGRID_MC_DWARF_EXPRESSION_HPP
+#define SIMGRID_MC_DWARF_EXPRESSION_HPP
+
+#include <cstdint>
+
+#include <stdexcept>
+
+#include <mc/AddressSpace.hpp>
+
+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<Dwarf_Op> 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
index 540bf4c..42978af 100644 (file)
@@ -25,7 +25,7 @@ public:
 
   bool inheritance;
   std::string name;
 
   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;
   std::size_t byte_size; // Do we really need this?
   unsigned type_id;
   simgrid::mc::Type* type;
index 90fd3d6..9d30fcf 100644 (file)
@@ -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());
             ("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:
       break;
     }
   case simgrid::dwarf::FormClass::Constant:
index 1f82a16..06be71b 100644 (file)
 #include <simgrid_config.h>
 #include "mc_base.h"
 #include "mc_forward.hpp"
 #include <simgrid_config.h>
 #include "mc_base.h"
 #include "mc_forward.hpp"
-#include "AddressSpace.hpp"
+#include "mc/AddressSpace.hpp"
+#include "mc/DwarfExpression.hpp"
 
 namespace simgrid {
 namespace mc {
 
 
 namespace simgrid {
 namespace mc {
 
-typedef std::vector<Dwarf_Op> DwarfExpression;
-
 
 /** \brief A DWARF expression with optional validity contraints */
 class LocationListEntry {
 public:
 
 /** \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) {}
   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);
   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,
 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);
 
   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()
 
 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
 #endif
index c69ef51..d7003c4 100644 (file)
@@ -29,22 +29,16 @@ void *resolve_member(
   if (!member->has_offset_location())
     return ((char *) base) + member->offset();
 
   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.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;
 
   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();
 }
 
 }
 }
 
 }
index 98ce207..fa42b88 100644 (file)
@@ -23,8 +23,8 @@
 static simgrid::mc::Process* process;
 
 static
 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;
 
   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;
 
   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
 }
 
 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();
 
   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;
 
   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;
 
   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;
 
   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;
   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;
   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;
   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;
   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
 }
 
 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;
   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);
 
 }
 
 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;
 
   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();
 
   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();
   }
 
   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();
   }
 
   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();
   }
 
   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;
 }
 
   return 0;
 }
index 3c33fd9..32ab76f 100644 (file)
@@ -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.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
   src/mc/mc_dwarf_tagnames.cpp
   src/mc/mc_hash.hpp
   src/mc/mc_hash.cpp