@@ -237,7 +237,7 @@ llvm::StructType *Arch::StateStructType(void) const {
237237llvm::PointerType *Arch::StatePointerType (void ) const {
238238 CHECK (impl)
239239 << " Have you not run `PrepareModule` on a loaded semantics module?" ;
240- return llvm::PointerType::get (impl-> state_type , 0 );
240+ return llvm::PointerType::get (*context , 0 );
241241}
242242
243243// Return the type of an address, i.e. `addr_t` in the semantics.
@@ -259,6 +259,12 @@ llvm::FunctionType *Arch::LiftedFunctionType(void) const {
259259 return impl->lifted_function_type ;
260260}
261261
262+ llvm::StructType *Arch::RegisterWindowType (void ) const {
263+ CHECK (impl)
264+ << " Have you not run `PrepareModule` on a loaded semantics module?" ;
265+ return impl->register_window_type ;
266+ }
267+
262268// Return information about the register at offset `offset` in the `State`
263269// structure.
264270const Register *Arch::RegisterAtStateOffset (uint64_t offset) const {
@@ -386,11 +392,11 @@ namespace {
386392
387393// These variables must always be defined within any lifted function.
388394static bool BlockHasSpecialVars (llvm::Function *basic_block) {
389- return FindVarInFunction (basic_block, kStateVariableName , true ) &&
390- FindVarInFunction (basic_block, kMemoryVariableName , true ) &&
391- FindVarInFunction (basic_block, kPCVariableName , true ) &&
392- FindVarInFunction (basic_block, kNextPCVariableName , true ) &&
393- FindVarInFunction (basic_block, kBranchTakenVariableName , true );
395+ return FindVarInFunction (basic_block, kStateVariableName , true ). first &&
396+ FindVarInFunction (basic_block, kMemoryVariableName , true ). first &&
397+ FindVarInFunction (basic_block, kPCVariableName , true ). first &&
398+ FindVarInFunction (basic_block, kNextPCVariableName , true ). first &&
399+ FindVarInFunction (basic_block, kBranchTakenVariableName , true ). first ;
394400}
395401
396402// Add attributes to llvm::Argument in a way portable across LLVMs
@@ -444,10 +450,9 @@ namespace {
444450
445451// Compute the total offset of a GEP chain.
446452static uint64_t TotalOffset (const llvm::DataLayout &dl, llvm::Value *base,
447- llvm::Type *state_ptr_type ) {
453+ llvm::StructType *state_type ) {
448454 uint64_t total_offset = 0 ;
449- const auto state_size =
450- dl.getTypeAllocSize (state_ptr_type->getPointerElementType ());
455+ const auto state_size = dl.getTypeAllocSize (state_type);
451456 while (base) {
452457 if (auto gep = llvm::dyn_cast<llvm::GEPOperator>(base); gep) {
453458 llvm::APInt accumulated_offset (dl.getPointerSizeInBits (0 ), 0 , false );
@@ -468,7 +473,7 @@ static uint64_t TotalOffset(const llvm::DataLayout &dl, llvm::Value *base,
468473 } else if (auto pti = llvm::dyn_cast<llvm::PtrToIntOperator>(base); pti) {
469474 base = pti->getOperand (0 );
470475
471- } else if (base->getType () == state_ptr_type ) {
476+ } else if (base->getType ()-> isPointerTy () ) {
472477 break ;
473478
474479 } else {
@@ -482,27 +487,21 @@ static uint64_t TotalOffset(const llvm::DataLayout &dl, llvm::Value *base,
482487
483488static llvm::Value *
484489FinishAddressOf (llvm::IRBuilder<> &ir, const llvm::DataLayout &dl,
485- llvm::Type *state_ptr_type, size_t state_size,
486- const Register *reg, unsigned addr_space,
487- llvm::Value *gep) {
490+ llvm::StructType *state_type, size_t state_size,
491+ const Register *reg, unsigned addr_space, llvm::Value *gep) {
488492
489493
490- auto gep_offset = TotalOffset (dl, gep, state_ptr_type);
491- auto gep_type_at_offset = gep->getType ()->getPointerElementType ();
494+ auto gep_offset = TotalOffset (dl, gep, state_type);
492495
493496 CHECK_LT (gep_offset, state_size);
494497
495498 const auto index_type = reg->gep_index_list [0 ]->getType ();
496- const auto goal_ptr_type = llvm::PointerType::get (reg-> type , addr_space);
499+ const auto goal_ptr_type = llvm::PointerType::get (ir. getContext () , addr_space);
497500
498501 // Best case: we've found a value field in the structure that
499502 // is located at the correct byte offset.
500503 if (gep_offset == reg->offset ) {
501- if (gep_type_at_offset == reg->type ) {
502- return gep;
503-
504- } else if (auto const_gep = llvm::dyn_cast<llvm::Constant>(gep);
505- const_gep) {
504+ if (auto const_gep = llvm::dyn_cast<llvm::Constant>(gep); const_gep) {
506505 return llvm::ConstantExpr::getBitCast (const_gep, goal_ptr_type);
507506
508507 } else {
@@ -539,22 +538,26 @@ FinishAddressOf(llvm::IRBuilder<> &ir, const llvm::DataLayout &dl,
539538
540539 if (auto const_gep = llvm::dyn_cast<llvm::Constant>(gep); const_gep) {
541540 const_gep = llvm::ConstantExpr::getBitCast (
542- const_gep, llvm::PointerType::get (byte_type , addr_space));
541+ const_gep, llvm::PointerType::get (ir. getContext () , addr_space));
543542 const_gep = llvm::ConstantExpr::getGetElementPtr (byte_type, const_gep,
544543 elem_indexes);
545544 return llvm::ConstantExpr::getBitCast (const_gep, goal_ptr_type);
546545
547546 } else {
548- gep = ir.CreateBitCast (gep, llvm::PointerType::get (byte_type , addr_space));
547+ gep = ir.CreateBitCast (gep, llvm::PointerType::get (ir. getContext () , addr_space));
549548 gep = ir.CreateGEP (byte_type, gep, elem_indexes);
550549 return ir.CreateBitCast (gep, goal_ptr_type);
551550 }
552551}
553552
554553} // namespace
555554
556- void Register::CompteGEPAccessors (const llvm::DataLayout &dl,
557- llvm::Type *state_type) {
555+ void Register::ComputeGEPAccessors (const llvm::DataLayout &dl,
556+ llvm::StructType *state_type) {
557+ if (!state_type) {
558+ state_type = arch->state_type ;
559+ }
560+
558561 if (gep_type_at_offset || !state_type) {
559562 return ;
560563 }
@@ -585,15 +588,13 @@ llvm::Value *Register::AddressOf(llvm::Value *state_ptr,
585588 CHECK_NOTNULL (state_ptr_type);
586589 const auto addr_space = state_ptr_type->getAddressSpace ();
587590
588- const auto state_type =
589- llvm::dyn_cast<llvm::StructType>(state_ptr_type->getPointerElementType ());
590- CHECK_NOTNULL (state_type);
591+ const auto state_type = arch->state_type ;
591592
592593 const auto module = ir.GetInsertBlock ()->getParent ()->getParent ();
593594 const auto &dl = module ->getDataLayout ();
594595
595596 if (!gep_type_at_offset) {
596- const_cast <Register *>(this )->CompteGEPAccessors (dl, state_type);
597+ const_cast <Register *>(this )->ComputeGEPAccessors (dl, state_type);
597598 }
598599
599600 llvm::Value *gep = nullptr ;
@@ -607,7 +608,7 @@ llvm::Value *Register::AddressOf(llvm::Value *state_ptr,
607608
608609 auto state_size = dl.getTypeAllocSize (state_type);
609610 auto ret = FinishAddressOf (
610- ir, dl, state_ptr_type , state_size, this , addr_space, gep);
611+ ir, dl, state_type , state_size, this , addr_space, gep);
611612
612613 // Add the metadata to `inst`.
613614 if (auto inst = llvm::dyn_cast<llvm::Instruction>(ret); inst) {
@@ -722,7 +723,7 @@ void Arch::InitializeEmptyLiftedFunction(llvm::Function *func) const {
722723 // `FinishLiftedFunctionInitialization`.
723724
724725 ir.CreateStore (state,
725- ir.CreateAlloca (llvm::PointerType::get (impl-> state_type , 0 ),
726+ ir.CreateAlloca (llvm::PointerType::get (context , 0 ),
726727 nullptr , " STATE" ));
727728 ir.CreateStore (memory,
728729 ir.CreateAlloca (impl->memory_type , nullptr , " MEMORY" ));
@@ -757,7 +758,7 @@ const Register *Arch::AddRegister(const char *reg_name_, llvm::Type *val_type,
757758 auto reg_impl = new Register (reg_name, offset, dl.getTypeAllocSize (val_type),
758759 val_type, parent_reg, impl.get ());
759760
760- reg_impl->CompteGEPAccessors (dl, impl->state_type );
761+ reg_impl->ComputeGEPAccessors (dl, impl->state_type );
761762
762763 reg = reg_impl;
763764 impl->registers .emplace_back (reg_impl);
@@ -803,10 +804,20 @@ void Arch::InitFromSemanticsModule(llvm::Module *module) const {
803804 const auto &dl = module ->getDataLayout ();
804805 const auto basic_block = module ->getFunction (" __remill_jump" );
805806 CHECK_NOTNULL (basic_block);
806- const auto state_ptr_type =
807- NthArgument (basic_block, kStatePointerArgNum )->getType ();
808- const auto state_type =
809- llvm::dyn_cast<llvm::StructType>(state_ptr_type->getPointerElementType ());
807+
808+ const auto *state_global = module ->getGlobalVariable (" __remill_state" );
809+ CHECK_NOTNULL (state_global);
810+ auto *state_type = llvm::dyn_cast<llvm::StructType>(state_global->getValueType ());
811+ CHECK_NOTNULL (state_type);
812+
813+ const auto *register_window_global =
814+ module ->getGlobalVariable (" __remill_register_window" );
815+ if (register_window_global) {
816+ auto *register_window_type = llvm::dyn_cast<llvm::StructType>(
817+ register_window_global->getValueType ());
818+ CHECK_NOTNULL (register_window_type);
819+ impl->register_window_type = register_window_type;
820+ }
810821
811822 impl->state_type = state_type;
812823 impl->reg_by_offset .resize (dl.getTypeAllocSize (state_type));
0 commit comments