mirror of
https://github.com/lifting-bits/remill
synced 2026-06-21 13:56:07 +00:00
Fix Type Info for Register Variable GEPs (#620)
* add test * direct type of found variable by reg info * weaker requirement on variable types
This commit is contained in:
@@ -311,6 +311,7 @@ void ArchBase::ForEachRegister(std::function<void(const Register *)> cb) const {
|
||||
// Return information about a register, given its name.
|
||||
const Register *ArchBase::RegisterByName(std::string_view name_) const {
|
||||
std::string name(name_.data(), name_.size());
|
||||
|
||||
auto [curr_val_it, added] = reg_by_name.emplace(std::move(name), nullptr);
|
||||
if (added) {
|
||||
return nullptr;
|
||||
|
||||
@@ -87,7 +87,6 @@ LiftStatus InstructionLifter::LiftIntoBlock(Instruction &arch_inst,
|
||||
llvm::BasicBlock *block,
|
||||
llvm::Value *state_ptr,
|
||||
bool is_delayed) {
|
||||
LOG(INFO) << "In instructionlifter";
|
||||
llvm::Function *const func = block->getParent();
|
||||
llvm::Module *const module = func->getParent();
|
||||
llvm::Function *isel_func = nullptr;
|
||||
@@ -251,10 +250,18 @@ InstructionLifter::LoadRegAddress(llvm::BasicBlock *block,
|
||||
return reg_ptr_it->second;
|
||||
}
|
||||
|
||||
|
||||
auto reg = impl->arch->RegisterByName(reg_name_);
|
||||
|
||||
// It's already a variable in the function.
|
||||
const auto [var_ptr, var_ptr_type] = FindVarInFunction(func, reg_name_, true);
|
||||
if (var_ptr) {
|
||||
reg_ptr_it->second = {var_ptr, var_ptr_type};
|
||||
auto ty = var_ptr_type;
|
||||
//NOTE(Ian) for stuff like NEXT_PC existing in the block we arent going to have reg type info, im not sure i like pulling it from var_ptr_type regardles. Not sure what to do about it
|
||||
if (reg) {
|
||||
ty = reg->type;
|
||||
}
|
||||
reg_ptr_it->second = {var_ptr, ty};
|
||||
return reg_ptr_it->second;
|
||||
}
|
||||
|
||||
@@ -262,7 +269,7 @@ InstructionLifter::LoadRegAddress(llvm::BasicBlock *block,
|
||||
// right now. We'll try to be careful about the placement of the actual
|
||||
// indexing instructions so that they always follow the definition of the
|
||||
// state pointer, and thus are most likely to dominate all future uses.
|
||||
if (auto reg = impl->arch->RegisterByName(reg_name_)) {
|
||||
if (reg) {
|
||||
llvm::Value *reg_ptr = nullptr;
|
||||
|
||||
// The state pointer is an argument.
|
||||
|
||||
@@ -232,3 +232,25 @@ TEST(ThumbRandomizedLifts, RelPcTest) {
|
||||
TestSpecRunner runner(context);
|
||||
runner.RunTestSpec(spec);
|
||||
}
|
||||
|
||||
TEST(RegressionTests, AARCH64RegSize) {
|
||||
llvm::LLVMContext context;
|
||||
context.enableOpaquePointers();
|
||||
auto arch = remill::Arch::Build(&context, remill::OSName::kOSLinux,
|
||||
remill::ArchName::kArchAArch64LittleEndian);
|
||||
auto sems = remill::LoadArchSemantics(arch.get());
|
||||
remill::IntrinsicTable instrinsics(sems.get());
|
||||
auto op_lifter = arch->DefaultLifter(instrinsics);
|
||||
auto target_lift = arch->DefineLiftedFunction("test_lift", sems.get());
|
||||
auto st_ptr = remill::LoadStatePointer(target_lift);
|
||||
CHECK_NOTNULL(st_ptr);
|
||||
auto lifted =
|
||||
op_lifter->LoadRegValue(&target_lift->getEntryBlock(), st_ptr, "W0");
|
||||
|
||||
CHECK_EQ(lifted->getType()->getIntegerBitWidth(), 32);
|
||||
op_lifter->ClearCache();
|
||||
auto lifted2 =
|
||||
op_lifter->LoadRegValue(&target_lift->getEntryBlock(), st_ptr, "W0");
|
||||
|
||||
CHECK_EQ(lifted2->getType()->getIntegerBitWidth(), 32);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user