X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/8f327dfbe1524884e5a1bccaf90a0454c17567dc..debe4e5871c0c3d1c714bbb1bd28ba7147454aa5:/src/mc/DwarfExpression.cpp diff --git a/src/mc/DwarfExpression.cpp b/src/mc/DwarfExpression.cpp index 07b5f0d7cd..31852a6719 100644 --- a/src/mc/DwarfExpression.cpp +++ b/src/mc/DwarfExpression.cpp @@ -1,31 +1,24 @@ -/* Copyright (c) 2014-2015. The SimGrid Team. - * All rights reserved. */ +/* Copyright (c) 2014-2019. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include #include -#include -#include -#include - -#include "mc_object_info.h" -#include "mc_private.h" -#include "mc/LocationList.hpp" -#include "mc/AddressSpace.hpp" -#include "mc/Frame.hpp" -#include "mc/ObjectInformation.hpp" -#include "mc/DwarfExpression.hpp" -#include "mc_dwarf.hpp" +#include "src/mc/AddressSpace.hpp" +#include "src/mc/DwarfExpression.hpp" +#include "src/mc/Frame.hpp" +#include "src/mc/LocationList.hpp" +#include "src/mc/ObjectInformation.hpp" +#include "src/mc/mc_dwarf.hpp" +#include "src/mc/mc_private.hpp" using simgrid::mc::remote; namespace simgrid { namespace dwarf { -evaluation_error::~evaluation_error() noexcept(true) {} - void execute( const Dwarf_Op* ops, std::size_t n, const ExpressionContext& context, ExpressionStack& stack) @@ -33,6 +26,8 @@ void execute( for (size_t i = 0; i != n; ++i) { const Dwarf_Op *op = ops + i; std::uint8_t atom = op->atom; + intptr_t first; + intptr_t second; switch (atom) { @@ -70,24 +65,33 @@ void execute( case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31:{ + // Push register + constant: int register_id = simgrid::dwarf::dwarf_register_to_libunwind( op->atom - DW_OP_breg0); unw_word_t res; - if (!context.cursor) - throw evaluation_error("Missin stack context"); + if (not context.cursor) + throw evaluation_error("Missing stack context"); unw_get_reg(context.cursor, register_id, &res); stack.push(res + op->number); break; } - // Push the CFA (Canonical Frame Addresse): + // Push the CFA (Canonical Frame Address): case DW_OP_call_frame_cfa: { - // UNW_X86_64_CFA does not return the CFA DWARF expects - // (it is a synonym for UNW_X86_64_RSP) so copy the cursor, - // unwind it once in order to find the parent SP: - - if (!context.cursor) + /* See 6.4 of DWARF4 (http://dwarfstd.org/doc/DWARF4.pdf#page=140): + * + * > Typically, the CFA is defined to be the value of the stack + * > pointer at the call site in the previous frame (which may be + * > different from its value on entry to the current frame). + * + * We need to unwind the frame in order to get the SP of the parent + * frame. + * + * Warning: the CFA returned by libunwind (UNW_X86_64_RSP, etc.) + * is the SP of the *current* frame. */ + + if (not context.cursor) throw evaluation_error("Missint cursor"); // Get frame: @@ -109,7 +113,6 @@ void execute( // ***** Constants: // Short constant literals: - // DW_OP_lit15 pushed the 15 on the stack. case DW_OP_lit0: case DW_OP_lit1: case DW_OP_lit2: @@ -142,13 +145,14 @@ void execute( case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: + // Push a literal/constant on the stack: 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 (!context.object_info) + if (not context.object_info) throw evaluation_error("No base address"); Dwarf_Off addr = (Dwarf_Off) (std::uintptr_t) context.object_info->base_address() + op->number; @@ -183,9 +187,8 @@ void execute( stack.pop(); break; - // Swap the two top-most value of the stack: case DW_OP_swap: - std::swap(stack.top(), stack.top(1)); + stack.swap(); break; // Duplicate the value under the top of the stack: @@ -199,11 +202,15 @@ void execute( // (stack.top() += stack.before_top()). case DW_OP_plus: - stack.push(stack.pop() + stack.pop()); + first = stack.pop(); + second = stack.pop(); + stack.push(first + second); break; case DW_OP_mul: - stack.push(stack.pop() * stack.pop()); + first = stack.pop(); + second = stack.pop(); + stack.push(first * second); break; case DW_OP_plus_uconst: @@ -219,19 +226,27 @@ void execute( break; case DW_OP_minus: - stack.push(stack.pop() - stack.pop()); + first = stack.pop(); + second = stack.pop(); + stack.push(second - first); break; case DW_OP_and: - stack.push(stack.pop() & stack.pop()); + first = stack.pop(); + second = stack.pop(); + stack.push(first & second); break; case DW_OP_or: - stack.push(stack.pop() | stack.pop()); + first = stack.pop(); + second = stack.pop(); + stack.push(first | second); break; case DW_OP_xor: - stack.push(stack.pop() ^ stack.pop()); + first = stack.pop(); + second = stack.pop(); + stack.push(first ^ second); break; case DW_OP_nop: @@ -244,7 +259,7 @@ void execute( case DW_OP_deref: // Computed address: - if (!context.address_space) + if (not context.address_space) throw evaluation_error("Missing address space"); context.address_space->read_bytes( &stack.top(), sizeof(uintptr_t), remote(stack.top()),