ProgramCounterHandler: add dissectJumpablePC

The new method `dissectJumpablePC` provides information about the
PC CSVs and allows not to make architecture-specific assumptions.
This commit is contained in:
Antonio Frighetto
2021-02-24 22:50:28 +01:00
parent ec629a20b1
commit ab597dc52f
2 changed files with 51 additions and 16 deletions
+46 -16
View File
@@ -51,6 +51,19 @@ public:
return Builder.CreateLoad(AddressCSV);
}
std::array<Value *, 4> 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();
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.
Value *ThumbValue = Store->getValueOperand();
B.CreateStore(computeMetaAddressType(B, ThumbValue), TypeCSV);
return true;
}
@@ -142,6 +142,21 @@ private:
AddressType));
}
std::array<Value *, 4> 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 = computeMetaAddressType(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 *computeMetaAddressType(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 {