1#ifndef ROSE_BinaryAnalysis_InstructionSemantics_DispatcherCil_H
2#define ROSE_BinaryAnalysis_InstructionSemantics_DispatcherCil_H
4#include <featureTests.h>
5#ifdef ROSE_ENABLE_BINARY_ANALYSIS
7#include <Rose/BinaryAnalysis/BasicTypes.h>
8#include <Rose/BinaryAnalysis/Architecture/Base.h>
9#include <Rose/BinaryAnalysis/InstructionSemantics/BaseSemantics.h>
10#include <Rose/BinaryAnalysis/InstructionSemantics/BaseSemantics/Dispatcher.h>
11#include <Rose/BinaryAnalysis/InstructionEnumsCil.h>
13#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
14#include <boost/serialization/access.hpp>
15#include <boost/serialization/base_object.hpp>
16#include <boost/serialization/export.hpp>
17#include <boost/serialization/split_member.hpp>
28namespace BinaryAnalysis {
29namespace InstructionSemantics {
51 RegisterDescriptor REG_D[8], REG_A[8], REG_FP[8], REG_PC, REG_CCR, REG_CCR_C, REG_CCR_V, REG_CCR_Z, REG_CCR_N, REG_CCR_X;
52 RegisterDescriptor REG_MACSR_SU, REG_MACSR_FI, REG_MACSR_N, REG_MACSR_Z, REG_MACSR_V, REG_MACSR_C, REG_MAC_MASK;
53 RegisterDescriptor REG_MACEXT0, REG_MACEXT1, REG_MACEXT2, REG_MACEXT3, REG_SSP, REG_SR_S, REG_SR, REG_VBR;
57 RegisterDescriptor REG_EXC_BSUN, REG_EXC_OPERR, REG_EXC_OVFL, REG_EXC_UNFL, REG_EXC_DZ, REG_EXC_INAN;
60 RegisterDescriptor REG_AEXC_IOP, REG_AEXC_OVFL, REG_AEXC_UNFL, REG_AEXC_DZ, REG_AEXC_INEX;
67#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
69 friend class boost::serialization::access;
72 void save(S &s,
const unsigned )
const
74 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(
Super);
78 void load(S &s,
const unsigned )
80 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(
Super);
91 BOOST_SERIALIZATION_SPLIT_MEMBER();
182 using TypeToken = uint32_t;
183 using TypeSet = std::set<TypeToken>;
186 std::map<const void*, TypeSet> possibleTypes_;
198 enum CilBranchCompareKind
217 uint32_t metadataToken = 0;
219 bool isValueType =
false;
220 bool isReferenceType =
true;
221 bool isInterface =
false;
222 bool isArray =
false;
223 size_t valueBitWidth = 0;
229 TypeDescriptor(uint32_t token,
const std::string &name) : metadataToken(token), name(name) {}
233 return metadataToken != 0;
240 uint32_t metadataToken = 0;
244 bool metadataKnown =
false;
249 bool isValueType =
false;
250 bool isReferenceType =
false;
251 bool isInterface =
false;
252 bool isArray =
false;
258 bool baseTypeKnown =
false;
259 uint32_t baseTypeToken = 0;
260 bool interfaceTypesKnown =
false;
261 std::set<uint32_t> interfaceTypeTokens;
264 size_t valueBitWidth = 0;
270 : metadataToken(token), metadataKnown(
false)
275 : metadataToken(token), metadataKnown(
true), name(name)
281 return metadataToken != 0;
284 bool isResolved()
const
286 return metadataKnown;
289 bool isKnownReferenceType()
const
291 return metadataKnown && isReferenceType && !isValueType;
294 bool isKnownValueType()
const
296 return metadataKnown && isValueType;
299 bool hasKnownValueWidth()
const
301 return metadataKnown && valueBitWidth != 0;
304 bool hasKnownBaseType()
const
306 return metadataKnown && baseTypeKnown;
309 bool hasKnownInterfaceTypes()
const
311 return metadataKnown && interfaceTypesKnown;
325 uint32_t metadataToken = 0;
326 Kind kind = UnknownMetadata;
335 return metadataToken != 0;
341 uint32_t metadataToken = 0;
344 bool signatureKnown =
false;
348 bool explicitThis =
false;
349 bool isStatic =
false;
350 bool isVirtual =
false;
352 size_t parameterCount = 0;
353 bool hasThis =
false;
354 bool returnsVoid =
true;
355 size_t returnBits = 0;
361 std::string returnTypeDescriptor;
363 std::vector<size_t> parameterBitWidths;
364 std::vector<std::string> parameterTypeDescriptors;
372 return metadataToken != 0;
375 size_t stackArgumentCount()
const
377 return parameterCount + ((hasThis || explicitThis) ? 1 : 0);
383 uint32_t metadataToken = 0;
385 bool signatureKnown =
false;
387 bool hasThis =
false;
388 bool explicitThis =
false;
389 bool isStatic =
false;
390 bool isVirtual =
false;
392 size_t parameterCount = 0;
394 bool returnsVoid =
true;
395 size_t returnBitWidth = 0;
397 SValue::ValueKind returnKind = SValue::ValueKind::UNKNOWN;
398 std::string returnTypeDescriptor;
400 std::vector<SValue::ValueKind> parameterKinds;
401 std::vector<size_t> parameterBitWidths;
402 std::vector<std::string> parameterTypeDescriptors;
408 uint32_t signatureToken = 0;
410 bool signatureKnown =
false;
411 size_t parameterCount = 0;
412 bool hasThis =
false;
413 bool returnsVoid =
true;
414 size_t returnBits = 0;
418 size_t stackArgumentCount()
const
420 return parameterCount + (hasThis ? 1 : 0);
426 bool returnsVoid =
true;
427 size_t returnBits = 32;
429 std::string returnTypeDescriptor;
434 uint32_t metadataToken = 0;
437 bool metadataKnown =
false;
439 bool isStatic =
false;
442 bool offsetKnown =
false;
443 uint64_t offsetBytes = 0;
446 bool typeKnown =
false;
447 size_t fieldBits = 32;
453 bool isValid()
const {
return metadataToken != 0; }
458 uint32_t metadataToken = 0;
461 bool metadataKnown =
false;
463 bool isStatic =
false;
466 bool offsetKnown =
false;
467 uint64_t offsetBytes = 0;
470 bool typeKnown =
false;
471 size_t fieldBits = 32;
475 bool isReferenceType =
false;
476 bool isValueType =
false;
477 uint32_t fieldTypeToken = 0;
478 std::string typeDescriptor;
483 bool isValid()
const {
return metadataToken != 0; }
493 resolveMethod(uint32_t methodToken)
const = 0;
496 resolveCallSite(uint32_t standaloneSigToken)
const = 0;
499 resolveType(uint32_t typeToken)
const = 0;
508 resolveMethod(uint32_t methodToken)
const = 0;
526 if (dispatcher && dispatcher->cilMetadata())
527 return dispatcher->cilMetadata()->resolveField(token);
531 void setPossibleTypes(
const SValuePtr &v,
const TypeSet &types);
532 void addPossibleType(
const SValuePtr &v, TypeToken type);
533 TypeSet possibleDynamicTypes(
const SValuePtr &v)
const;
534 bool hasTypeInfo(
const SValuePtr &v)
const;
535 void rememberTypeDescriptor(
const TypeDescriptor &type);
536 const TypeDescriptor* typeDescriptorFor(TypeToken type)
const;
539 static const void* key(
const SValuePtr &v)
545 return static_cast<const void*
>(v.operator->());
549 std::map<const void*, Nullness> nullness_;
550 std::map<TypeToken, TypeDescriptor> knownTypes_;
553 void setNullness(
const SValuePtr &v, Nullness n);
554 Nullness nullness(
const SValuePtr &v)
const;
555 bool isDefinitelyNull(
const SValuePtr &v)
const;
556 bool isDefinitelyNonNull(
const SValuePtr &v)
const;
558 bool isAssignableTo(uint32_t sourceType,
const TypeDescriptor *targetType);
559 bool allAssignableTo(
const DispatcherCil::CilTypeAnalysis::TypeSet &possibleTypes,
const TypeDescriptor *targetType);
560 bool noneAssignableTo(
const DispatcherCil::CilTypeAnalysis::TypeSet &possibleTypes,
const TypeDescriptor *targetType);
563 Assignability isAssignableTo(uint32_t sourceType,
const TypeDescriptor *targetType);
564 bool allAssignableTo(
const DispatcherCil::CilTypeAnalysis::TypeSet &possibleTypes,
const TypeDescriptor *targetType);
565 bool noneAssignableTo(
const DispatcherCil::CilTypeAnalysis::TypeSet &possibleTypes,
const TypeDescriptor *targetType);
567 void copyFacts(
const SValuePtr &dst,
const SValuePtr &src);
574 bool hasUnaligned =
false;
575 uint8_t unalignedBytes = 0;
577 bool isVolatile =
false;
580 bool hasConstrained =
false;
581 uint32_t constrainedTypeToken = 0;
583 bool isReadonly =
false;
595 return typeAnalysis_;
598 const CilTypeAnalysis& typeAnalysis()
const
600 return typeAnalysis_;
604 CilPendingPrefixState pendingPrefix_;
607 CilPendingPrefixState& pendingPrefix() {
return pendingPrefix_; }
608 const CilPendingPrefixState& pendingPrefix()
const {
return pendingPrefix_; }
609 void clearPendingPrefix() { pendingPrefix_.clear(); }
613 const DispatcherCil::CilTypeAnalysis::CilMetadataProvider *cilMetadata_ =
nullptr;
616 void cilMetadata(
const DispatcherCil::CilTypeAnalysis::CilMetadataProvider *provider)
618 cilMetadata_ = provider;
621 const DispatcherCil::CilTypeAnalysis::CilMetadataProvider* cilMetadata()
const
627 CilTypeAnalysis::CurrentMethodDescriptor currentMethod_;
630 const CilTypeAnalysis::CurrentMethodDescriptor& currentMethod()
const
632 return currentMethod_;
635 void currentMethod(
const CilTypeAnalysis::CurrentMethodDescriptor &m)
642 size_t cilPointerBits_ = 32;
649 return cilPointerBits_;
653 bool allowByteOnlyExceptionFallback_ =
true;
656 bool allowByteOnlyExceptionFallback()
const
658 return allowByteOnlyExceptionFallback_;
661 void allowByteOnlyExceptionFallback(
bool b)
663 allowByteOnlyExceptionFallback_ = b;
672#ifdef ROSE_ENABLE_BOOST_SERIALIZATION
BaseConstPtr ConstPtr
Reference counting pointer to const object.
Dispatches instructions through the RISC layer.
Functor that knows how to dispatch a single kind of instruction.
Base class for most instruction semantics RISC operators.
SValuePtr Ptr
Shared-ownership pointer.
static DispatcherCilPtr instance(const Architecture::BaseConstPtr &, const BaseSemantics::RiscOperatorsPtr &)
Constructor.
void initializeMemoryState()
Make sure memory is set up correctly.
void updateFpsrExcUnfl(const BaseSemantics::SValuePtr &intermediate, SgAsmType *valueType, SgAsmType *rounding, SgAsmType *dstType)
Set or clear FPSR EXC UVFL bit.
void updateFpsrExcInan(const BaseSemantics::SValuePtr &a, SgAsmType *aType, const BaseSemantics::SValuePtr &b, SgAsmType *bType)
Set or clear FPSR EXC INAN bit.
virtual BaseSemantics::SValuePtr read(SgAsmExpression *, size_t value_nbits, size_t addr_nbits=0) override
Reads an R-value expression.
void updateFpsrExcIde(const BaseSemantics::SValuePtr &a, SgAsmType *aType, const BaseSemantics::SValuePtr &b, SgAsmType *bType)
Set or clear FPSR EXC IDE bit.
BaseSemantics::SValuePtr condition(CilInstructionKind, BaseSemantics::RiscOperators *)
Determines if an instruction should branch.
void updateFpsrExcInex()
Set or clear FPSR EXC INEX bit.
DispatcherCilPtr Ptr
Shared-ownership pointer.
void updateFpsrExcOvfl(const BaseSemantics::SValuePtr &intermediate, SgAsmType *valueType, SgAsmType *rounding, SgAsmType *dstType)
Set or clear FPSR EXC OVFL bit.
virtual RegisterDescriptor stackPointerRegister() const override
Returns the stack pointer register.
static DispatcherCilPtr instance(const Architecture::BaseConstPtr &)
Construct a prototypical dispatcher.
BaseSemantics::Dispatcher Super
Base type.
BaseSemantics::InsnProcessor * iprocLookup(SgAsmInstruction *insn) override
Lookup the processor for an instruction.
static DispatcherCilPtr promote(const BaseSemantics::DispatcherPtr &)
Dynamic cast to DispatcherCilPtr with assertion.
int iprocKey(SgAsmInstruction *insn_) const override
Given an instruction, return the InsnProcessor key that can be used as an index into the iproc_table.
virtual RegisterDescriptor instructionPointerRegister() const override
Returns the instruction pointer register.
void accumulateFpExceptions()
Update accrued floating-point exceptions.
virtual BaseSemantics::DispatcherPtr create(const BaseSemantics::RiscOperatorsPtr &) const override
Virtual constructor.
void initializeDispatchTable()
Loads the iproc table with instruction processing functors.
void adjustFpConditionCodes(const BaseSemantics::SValuePtr &result, SgAsmFloatType *)
Set floating point condition codes according to result.
Describes (part of) a physical CPU register.
Base class for expressions.
Base class for machine instructions.
Base class for binary types.
std::shared_ptr< const Base > BaseConstPtr
Reference counted pointer for Architecture::Base.
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
boost::shared_ptr< Dispatcher > DispatcherPtr
Shared-ownership pointer to a semantics instruction dispatcher.
ValueKind
Kind of an SValue for emulating JVM and CIL instructions.
boost::shared_ptr< class DispatcherCil > DispatcherCilPtr
Shared-ownership pointer to an CIL instruction dispatcher.