mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user