Compare 920d2f4 ... +4 ... d5ff9ca

Coverage Reach
arch/x86/x86Semantics.cpp arch/x86/x8664Cpu.cpp arch/x86/x86Cpu.cpp arch/x86/x86Specifications.cpp arch/arm/aarch64/aarch64Semantics.cpp arch/arm/aarch64/aarch64Cpu.cpp arch/arm/aarch64/aarch64Specifications.cpp arch/arm/arm32/arm32Semantics.cpp arch/arm/arm32/arm32Cpu.cpp arch/arm/arm32/arm32Specifications.cpp arch/arm/armOperandProperties.cpp arch/instruction.cpp arch/architecture.cpp arch/memoryAccess.cpp arch/irBuilder.cpp arch/operandWrapper.cpp arch/immediate.cpp arch/register.cpp arch/bitsVector.cpp bindings/python/objects/pyTritonContext.cpp bindings/python/objects/pyAstContext.cpp bindings/python/objects/pyAstNode.cpp bindings/python/objects/pyInstruction.cpp bindings/python/objects/pyMemoryAccess.cpp bindings/python/objects/pyRegister.cpp bindings/python/objects/pySymbolicExpression.cpp bindings/python/objects/pySymbolicVariable.cpp bindings/python/objects/pyImmediate.cpp bindings/python/objects/pyPathConstraint.cpp bindings/python/objects/pyBitsVector.cpp bindings/python/objects/pySolverModel.cpp bindings/python/namespaces/initOpcodesNamespace.cpp bindings/python/namespaces/initAstNodeNamespace.cpp bindings/python/namespaces/initConditionsNamespace.cpp bindings/python/namespaces/initShiftsNamespace.cpp bindings/python/namespaces/initCpuSizeNamespace.cpp bindings/python/namespaces/initRegNamespace.cpp bindings/python/namespaces/initExtendNamespace.cpp bindings/python/namespaces/initModeNamespace.cpp bindings/python/namespaces/initPrefixesNamespace.cpp bindings/python/namespaces/initSyscallNamespace.cpp bindings/python/namespaces/initSymbolicNamespace.cpp bindings/python/namespaces/initCallbackNamespace.cpp bindings/python/namespaces/initArchNamespace.cpp bindings/python/namespaces/initOperandNamespace.cpp bindings/python/namespaces/initVersionNamespace.cpp bindings/python/namespaces/initAstRepresentationNamespace.cpp bindings/python/utils.cpp bindings/python/init.cpp bindings/python/modules/tritonCallbacks.cpp bindings/python/pyXFunctions.cpp ast/ast.cpp ast/astContext.cpp ast/representations/astPythonRepresentation.cpp ast/representations/astSmtRepresentation.cpp ast/representations/astRepresentation.cpp ast/z3/z3ToTritonAst.cpp ast/z3/tritonToZ3Ast.cpp engines/symbolic/symbolicEngine.cpp engines/symbolic/symbolicExpression.cpp engines/symbolic/pathManager.cpp engines/symbolic/symbolicVariable.cpp engines/symbolic/symbolicSimplification.cpp engines/symbolic/pathConstraint.cpp engines/taint/taintEngine.cpp engines/solver/z3/z3Solver.cpp engines/solver/solverEngine.cpp engines/solver/solverModel.cpp api/api.cpp includes/triton/ast.hpp includes/triton/exceptions.hpp includes/triton/astContext.hpp includes/triton/shortcutRegister.hpp includes/triton/comparableFunctor.hpp includes/triton/semanticsInterface.hpp includes/triton/astRepresentationInterface.hpp includes/triton/solverInterface.hpp includes/triton/cpuInterface.hpp includes/triton/arm32Specifications.hpp includes/triton/x86Semantics.hpp includes/triton/symbolicExpression.hpp includes/triton/archEnums.hpp includes/triton/astRepresentation.hpp includes/triton/operandWrapper.hpp includes/triton/symbolicVariable.hpp includes/triton/pathManager.hpp includes/triton/x86Specifications.hpp includes/triton/astSmtRepresentation.hpp includes/triton/arm32Semantics.hpp includes/triton/taintEngine.hpp includes/triton/memoryAccess.hpp includes/triton/z3Solver.hpp includes/triton/callbacks.hpp includes/triton/solverEngine.hpp includes/triton/aarch64Specifications.hpp includes/triton/modes.hpp includes/triton/aarch64Semantics.hpp includes/triton/solverModel.hpp includes/triton/register.hpp includes/triton/z3ToTritonAst.hpp includes/triton/astPythonRepresentation.hpp includes/triton/architecture.hpp includes/triton/modesEnums.hpp callbacks/callbacks.cpp utils/coreUtils.cpp modes/modes.cpp os/unix/syscallNumberToString.cpp

No flags found

Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.

e.g., #unittest #integration

#production #enterprise

#frontend #backend

Learn more about Codecov Flags here.


@@ -320,6 +320,10 @@
Loading
320 320
321 321
        //! Prints the given node with this context representation
322 322
        TRITON_EXPORT std::ostream& print(std::ostream& stream, AbstractNode* node);
323 +
324 +
      private:
325 +
        //! Return simplified extraction.
326 +
        SharedAbstractNode simplify_extract(triton::uint32 high, triton::uint32 low, const SharedAbstractNode& expr);
323 327
    };
324 328
325 329
    //! Shared AST context

@@ -789,6 +789,13 @@
Loading
789 789
      if (low == 0 && (high + 1) == expr->getBitvectorSize())
790 790
        return expr;
791 791
792 +
      if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS)) {
793 +
        auto n = this->simplify_extract(high, low, expr);
794 +
        if (n) {
795 +
          return n;
796 +
        }
797 +
      }
798 +
792 799
      SharedAbstractNode node = std::make_shared<ExtractNode>(high, low, expr);
793 800
      if (node == nullptr)
794 801
        throw triton::exceptions::Ast("AstContext::extract(): Not enough memory.");
@@ -1051,5 +1058,114 @@
Loading
1051 1058
      return this->astRepresentation.print(stream, node);
1052 1059
    }
1053 1060
1061 +
1062 +
    SharedAbstractNode AstContext::simplify_extract(triton::uint32 high, triton::uint32 low, const SharedAbstractNode& expr) {
1063 +
      auto size = expr->getBitvectorSize();
1064 +
1065 +
      if (high <= low || high >= size) {
1066 +
        return 0;
1067 +
      }
1068 +
1069 +
      auto node = expr;
1070 +
      while (true) {
1071 +
        /* Unroll references, n will contain unrolled node */
1072 +
        auto n = node;
1073 +
        while (n->getType() == REFERENCE_NODE) {
1074 +
          auto ref = reinterpret_cast<ReferenceNode*>(n.get());
1075 +
          n = ref->getSymbolicExpression()->getAst();
1076 +
        }
1077 +
1078 +
        if (n->getType() == CONCAT_NODE) {
1079 +
          /*
1080 +
           * Optimization: If we extract the full part of concatenation, just
1081 +
           * return the part. We are trying to find a part of concatenation
1082 +
           * that we can extract from. Thus, we can extract from only one part
1083 +
           * of concatenation.
1084 +
           *
1085 +
           * ((_ extract 11 9) (concat (_ bv1 8) (_ bv2 8) (_ bv3 8) (_ bv4 8))) =>
1086 +
           * ((_ extract 3 1) (_ bv3 8))
1087 +
           */
1088 +
          auto hi = n->getBitvectorSize() - 1;
1089 +
          bool found = false;
1090 +
          /* Search for part of concatenation we can extract from. Iterate
1091 +
           * from the left to the right. */
1092 +
          for (const auto& part : n->getChildren()) {
1093 +
            if (hi < high) {
1094 +
              /* Did not find a part we can extract from */
1095 +
              break;
1096 +
            }
1097 +
            auto sz = part->getBitvectorSize();
1098 +
            auto lo = hi + 1 - sz;
1099 +
            if (hi == high && lo == low) {
1100 +
              /* We are extracting the full part, just return it */
1101 +
              return part;
1102 +
            }
1103 +
            if (hi >= high && lo <= low) {
1104 +
              /* Extract from part: ((_ extract high-lo low-lo) part) */
1105 +
              node = part;
1106 +
              high -= lo;
1107 +
              low -= lo;
1108 +
              found = true;
1109 +
              break;
1110 +
            }
1111 +
            hi -= sz;
1112 +
          }
1113 +
          if (found) {
1114 +
            /* Optimize ((_ extract high low) node) one more time */
1115 +
            continue;
1116 +
          }
1117 +
        }
1118 +
        else if (n->getType() == ZX_NODE || n->getType() == SX_NODE) {
1119 +
          /*
1120 +
           * Optimization: If we extract from the node being extended, just
1121 +
           * return the node
1122 +
           *
1123 +
           * ((_ extract 31 0) ((_ zero_extend 32) (_ bv1 32))) => (_ bv1 32)
1124 +
           *
1125 +
           * ((_ extract 7 0) ((_ sign_extend 32) (_ bv1 32))) =>
1126 +
           * ((_ extract 7 0) (_ bv1 32))
1127 +
           **/
1128 +
          n = n->getChildren()[1];
1129 +
          auto sz = n->getBitvectorSize();
1130 +
          if (low == 0 && high + 1 == sz) {
1131 +
            /* Just return the node being extended */
1132 +
            return n;
1133 +
          }
1134 +
          if (high < sz) {
1135 +
            /* Optimize ((_ extract high low) n) one more time */
1136 +
            node = n;
1137 +
            continue;
1138 +
          }
1139 +
        }
1140 +
        break;
1141 +
      }
1142 +
1143 +
      /* Unroll references, n will contain unrolled node */
1144 +
      auto n = node;
1145 +
      while (n->getType() == REFERENCE_NODE) {
1146 +
        auto ref = reinterpret_cast<ReferenceNode*>(n.get());
1147 +
        n = ref->getSymbolicExpression()->getAst();
1148 +
      }
1149 +
1150 +
      /*
1151 +
       * Optimization: extract from extract is one extract
1152 +
       *
1153 +
       * ((_ extract high low) ((_ extract hi lo) a)) =>
1154 +
       * ((_ extract high+lo low+lo) a)
1155 +
       **/
1156 +
      if (n->getType() == EXTRACT_NODE) {
1157 +
        const auto& childs = n->getChildren();
1158 +
        auto hi = reinterpret_cast<IntegerNode*>(childs[0].get())->getInteger().convert_to<uint32>();
1159 +
        auto lo = reinterpret_cast<IntegerNode*>(childs[1].get())->getInteger().convert_to<uint32>();
1160 +
        if (lo + high <= hi) {
1161 +
          node = childs[2];
1162 +
          high += lo;
1163 +
          low += lo;
1164 +
        }
1165 +
      }
1166 +
1167 +
      return node == expr ? 0 : this->extract(high, low, node);
1168 +
    }
1169 +
1054 1170
  }; /* ast namespace */
1055 1171
}; /* triton namespace */

Everything is accounted for!

No changes detected that need to be reviewed.
What changes does Codecov check for?
Lines, not adjusted in diff, that have changed coverage data.
Files that introduced coverage data that had none before.
Files that have missing coverage data that once were tracked.
Files Coverage
src/libtriton 0.02% 86.14%
Project Totals (107 files) 86.14%
Loading