Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/Arch/Arch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 6 additions & 4 deletions lib/BC/InstructionLifter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -251,18 +250,21 @@ 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};
if (var_ptr && reg) {
reg_ptr_it->second = {var_ptr, reg->type};
return reg_ptr_it->second;
}

// It's a register known to this architecture, so go and build a GEP to it
// 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.
Expand Down
22 changes: 22 additions & 0 deletions tests/Thumb/TestLifting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}