From ad4586f401dead36742f7662bb018d35725c6dd3 Mon Sep 17 00:00:00 2001 From: Antonio Frighetto Date: Wed, 24 Feb 2021 22:50:28 +0100 Subject: [PATCH] ProgramCounterHandler: add `dissectJumpablePC` The new method `dissectJumpablePC` provides information about the PC CSVs and allows not to make architecture-specific assumptions. --- include/revng/Support/ProgramCounterHandler.h | 5 ++ lib/Support/ProgramCounterHandler.cpp | 62 ++++++++++++++----- 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/include/revng/Support/ProgramCounterHandler.h b/include/revng/Support/ProgramCounterHandler.h index 03c4521e1..486728604 100644 --- a/include/revng/Support/ProgramCounterHandler.h +++ b/include/revng/Support/ProgramCounterHandler.h @@ -165,6 +165,11 @@ public: virtual llvm::Value *loadJumpablePC(llvm::IRBuilder<> &Builder) const = 0; + virtual std::array + dissectJumpablePC(llvm::IRBuilder<> &Builder, + llvm::Value *ToDissect, + llvm::Triple::ArchType Arch) const = 0; + virtual void deserializePCFromSignalContext(llvm::IRBuilder<> &Builder, llvm::Value *PCAddress, diff --git a/lib/Support/ProgramCounterHandler.cpp b/lib/Support/ProgramCounterHandler.cpp index 838f7e1df..a76f583b6 100644 --- a/lib/Support/ProgramCounterHandler.cpp +++ b/lib/Support/ProgramCounterHandler.cpp @@ -51,6 +51,19 @@ public: return Builder.CreateLoad(AddressCSV); } + std::array dissectJumpablePC(IRBuilder<> &Builder, + Value *ToDissect, + Triple::ArchType Arch) const final { + IntegerType *Ty = getCSVType(TypeCSV); + + Value *Address = ToDissect; + Value *Epoch = ConstantInt::get(Ty, 0); + Value *AddressSpace = ConstantInt::get(Ty, 0); + Value *Type = ConstantInt::get(Ty, + MetaAddressType::defaultCodeFromArch(Arch)); + return { Address, Epoch, AddressSpace, Type }; + } + void deserializePCFromSignalContext(IRBuilder<> &Builder, Value *PCAddress, Value *SavedRegisters) const final { @@ -109,24 +122,11 @@ private: revng_assert(affectsPC(Store)); Value *Pointer = Store->getPointerOperand(); - Value *StoredValue = Store->getValueOperand(); + Value *ThumbValue = Store->getValueOperand(); if (Pointer == IsThumb) { - // Update Type - using CI = ConstantInt; - using namespace MetaAddressType; - - auto *TypeType = getCSVType(TypeCSV); - auto *ArmCode = CI::get(TypeType, Code_arm); - auto *ThumbCode = CI::get(TypeType, Code_arm_thumb); - // We don't use select here, SCEV can't handle it - // NewType = ARM + IsThumb * (Thumb - ARM) - auto *NewType = B.CreateAdd(ArmCode, - B.CreateMul(B.CreateTrunc(StoredValue, - TypeType), - B.CreateSub(ThumbCode, ArmCode))); - - B.CreateStore(NewType, TypeCSV); + // Compute Type and update it. + B.CreateStore(this->emitARMState(B, ThumbValue), TypeCSV); return true; } @@ -142,6 +142,21 @@ private: AddressType)); } + std::array dissectJumpablePC(IRBuilder<> &Builder, + Value *ToDissect, + Triple::ArchType Arch) const final { + constexpr uint32_t ThumbMask = 0x1; + constexpr uint32_t AddressMask = 0xFFFFFFFE; + IntegerType *Ty = getCSVType(TypeCSV); + + Value *IsThumb = Builder.CreateAnd(ToDissect, ThumbMask); + Value *Address = Builder.CreateAnd(ToDissect, AddressMask); + Value *Epoch = ConstantInt::get(Ty, 0); + Value *AddressSpace = ConstantInt::get(Ty, 0); + Value *Type = this->emitARMState(Builder, IsThumb); + return { Address, Epoch, AddressSpace, Type }; + } + void deserializePCFromSignalContext(IRBuilder<> &B, Value *PCAddress, Value *SavedRegisters) const final { @@ -170,6 +185,21 @@ private: B.CreateStore(PCAddress, AddressCSV); } + Value *emitARMState(IRBuilder<> &B, Value *IsThumb) const { + using CI = ConstantInt; + using namespace MetaAddressType; + + auto *TypeType = getCSVType(TypeCSV); + auto *ArmCode = CI::get(TypeType, Code_arm); + auto *ThumbCode = CI::get(TypeType, Code_arm_thumb); + // We don't use select here, SCEV can't handle it + // NewType = ARM + IsThumb * (Thumb - ARM) + auto *NewType = B.CreateAdd(ArmCode, + B.CreateMul(B.CreateTrunc(IsThumb, TypeType), + B.CreateSub(ThumbCode, ArmCode))); + return NewType; + } + protected: void initializePCInternal(IRBuilder<> &Builder, MetaAddress NewPC) const final {