Skip to content

Commit

Permalink
llvm 13 support (#577)
Browse files Browse the repository at this point in the history
* llvm 13 support

* Add llvm 13

* Update build script

* Update build script

* Modify remill-lift docker entrypoint
  • Loading branch information
pgoodman authored Feb 17, 2022
1 parent 161e035 commit d5928a0
Show file tree
Hide file tree
Showing 12 changed files with 173 additions and 112 deletions.
14 changes: 4 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ jobs:
image:
- { name: 'ubuntu', tag: '18.04' }
- { name: 'ubuntu', tag: '20.04' }
llvm: [
'12'
]
llvm: ['12', '13']

runs-on: ubuntu-20.04
container:
Expand Down Expand Up @@ -94,12 +92,8 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [
'macos-11'
]
llvm: [
'12'
]
os: ['macos-11']
llvm: ['12', '13']

runs-on: ${{ matrix.os }}

Expand Down Expand Up @@ -235,7 +229,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
llvm: ["12"]
llvm: ["12", "13"]
ubuntu: ["18.04"]
steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Choose your LLVM version
ARG LLVM_VERSION=12
ARG LLVM_VERSION=13
ARG ARCH=amd64
ARG UBUNTU_VERSION=18.04
ARG DISTRO_BASE=ubuntu${UBUNTU_VERSION}
Expand Down
2 changes: 1 addition & 1 deletion bin/lift/Lift.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ int main(int argc, char *argv[]) {

auto reg_ptr = reg->AddressOf(state_ptr, entry);
ir.SetInsertPoint(entry);
ir.CreateStore(ir.CreateLoad(reg_ptr), &arg);
ir.CreateStore(ir.CreateLoad(reg->type, reg_ptr), &arg);
}

// Return the memory pointer, so that all memory accesses are
Expand Down
42 changes: 24 additions & 18 deletions include/remill/BC/IntrinsicTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
namespace llvm {
class ConstantArray;
class Function;
class FunctionType;
class IntegerType;
class Module;
class PointerType;
class Value;
} // namespace llvm
namespace remill {
Expand Down Expand Up @@ -79,26 +82,29 @@ class IntrinsicTable {
llvm::Function *const delay_slot_end;

// Optimization enabling.
llvm::Function *undefined_8;
llvm::Function *undefined_16;
llvm::Function *undefined_32;
llvm::Function *undefined_64;
llvm::Function *undefined_f32;
llvm::Function *undefined_f64;
llvm::Function *undefined_f80;

llvm::Function *const undefined_8;
llvm::Function *const undefined_16;
llvm::Function *const undefined_32;
llvm::Function *const undefined_64;
llvm::Function *const undefined_f32;
llvm::Function *const undefined_f64;
llvm::Function *const undefined_f80;

// Flag markers
llvm::Function *flag_computation_zero;
llvm::Function *flag_computation_sign;
llvm::Function *flag_computation_overflow;
llvm::Function *flag_computation_carry;

llvm::Function *compare_sle;
llvm::Function *compare_sgt;
llvm::Function *compare_eq;
llvm::Function *compare_neq;

llvm::Function *const flag_computation_zero;
llvm::Function *const flag_computation_sign;
llvm::Function *const flag_computation_overflow;
llvm::Function *const flag_computation_carry;

llvm::Function *const compare_sle;
llvm::Function *const compare_sgt;
llvm::Function *const compare_eq;
llvm::Function *const compare_neq;

llvm::FunctionType *const lifted_function_type;
llvm::PointerType *const state_ptr_type;
llvm::IntegerType *const pc_type;
llvm::PointerType *const mem_ptr_type;

private:
IntrinsicTable(void) = delete;
Expand Down
23 changes: 15 additions & 8 deletions include/remill/BC/Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,17 @@ class IntrinsicTable;
void InitFunctionAttributes(llvm::Function *F);

// Create a call from one lifted function to another.
llvm::CallInst *AddCall(llvm::BasicBlock *source_block, llvm::Value *dest_func);
llvm::CallInst *AddCall(llvm::BasicBlock *source_block, llvm::Value *dest_func,
const IntrinsicTable &intrinsics);

// Create a tail-call from one lifted function to another.
llvm::CallInst *AddTerminatingTailCall(llvm::Function *source_func,
llvm::Value *dest_func);
llvm::Value *dest_func,
const IntrinsicTable &intrinsics);

llvm::CallInst *AddTerminatingTailCall(llvm::BasicBlock *source_block,
llvm::Value *dest_func);
llvm::Value *dest_func,
const IntrinsicTable &intrinsics);

// Find a local variable defined in the entry block of the function. We use
// this to find register variables.
Expand All @@ -92,10 +95,12 @@ llvm::Value *LoadStatePointer(llvm::Function *function);
llvm::Value *LoadStatePointer(llvm::BasicBlock *block);

// Return the current program counter.
llvm::Value *LoadProgramCounter(llvm::BasicBlock *block);
llvm::Value *LoadProgramCounter(llvm::BasicBlock *block,
const IntrinsicTable &intrinsics);

// Return the next program counter.
llvm::Value *LoadNextProgramCounter(llvm::BasicBlock *block);
llvm::Value *LoadNextProgramCounter(llvm::BasicBlock *block,
const IntrinsicTable &intrinsics);

// Return a reference to the current program counter.
llvm::Value *LoadProgramCounterRef(llvm::BasicBlock *block);
Expand All @@ -107,7 +112,8 @@ llvm::Value *LoadNextProgramCounterRef(llvm::BasicBlock *block);
llvm::Value *LoadReturnProgramCounterRef(llvm::BasicBlock *block);

// Update the program counter in the state struct with a hard-coded value.
void StoreProgramCounter(llvm::BasicBlock *block, uint64_t pc);
void StoreProgramCounter(llvm::BasicBlock *block, uint64_t pc,
const IntrinsicTable &intrinsics);

// Update the program counter in the state struct with a new value.
void StoreProgramCounter(llvm::BasicBlock *block, llvm::Value *pc);
Expand All @@ -122,7 +128,8 @@ llvm::Value *LoadMemoryPointerArg(llvm::Function *func);
llvm::Value *LoadProgramCounterArg(llvm::Function *function);

// Return the current memory pointer.
llvm::Value *LoadMemoryPointer(llvm::BasicBlock *block);
llvm::Value *LoadMemoryPointer(llvm::BasicBlock *block,
const IntrinsicTable &intrinsics);

// Return a reference to the memory pointer.
llvm::Value *LoadMemoryPointerRef(llvm::BasicBlock *block);
Expand Down Expand Up @@ -180,7 +187,7 @@ llvm::Argument *NthArgument(llvm::Function *func, size_t index);
// Return a vector of arguments to pass to a lifted function, where the
// arguments are derived from `block`.
std::array<llvm::Value *, kNumBlockArgs>
LiftedFunctionArgs(llvm::BasicBlock *block);
LiftedFunctionArgs(llvm::BasicBlock *block, const IntrinsicTable &intrinsics);

// Serialize an LLVM object into a string.
std::string LLVMThingToString(llvm::Value *thing);
Expand Down
26 changes: 17 additions & 9 deletions lib/BC/InstructionLifter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,13 @@ llvm::Function *GetInstructionFunction(llvm::Module *module,
InstructionLifter::Impl::Impl(const Arch *arch_,
const IntrinsicTable *intrinsics_)
: arch(arch_),
word_type(llvm::Type::getIntNTy(
intrinsics_->async_hyper_call->getContext(), arch->address_size)),
intrinsics(intrinsics_),
word_type(
remill::NthArgument(intrinsics->async_hyper_call,
remill::kPCArgNum)->getType()),
memory_ptr_type(
remill::NthArgument(intrinsics->async_hyper_call,
remill::kMemoryPointerArgNum)->getType()),
module(intrinsics->async_hyper_call->getParent()),
invalid_instruction(
GetInstructionFunction(module, kInvalidInstructionISelName)),
Expand Down Expand Up @@ -119,7 +123,7 @@ LiftStatus InstructionLifter::LiftIntoBlock(Instruction &arch_inst,
const auto pc_ref = LoadRegAddress(block, state_ptr, kPCVariableName);
const auto next_pc_ref =
LoadRegAddress(block, state_ptr, kNextPCVariableName);
const auto next_pc = ir.CreateLoad(next_pc_ref);
const auto next_pc = ir.CreateLoad(impl->word_type, next_pc_ref);

// If this instruction appears within a delay slot, then we're going to assume
// that the prior instruction updated `PC` to the target of the CTI, and that
Expand All @@ -129,7 +133,8 @@ LiftStatus InstructionLifter::LiftIntoBlock(Instruction &arch_inst,
// TODO(pag): An alternate approach may be to call some kind of `DELAY_SLOT`
// semantics function.
if (is_delayed) {
llvm::Value *temp_args[] = {ir.CreateLoad(mem_ptr_ref)};
llvm::Value *temp_args[] = {
ir.CreateLoad(impl->memory_ptr_type, mem_ptr_ref)};
ir.CreateStore(ir.CreateCall(impl->intrinsics->delay_slot_begin, temp_args),
mem_ptr_ref);

Expand All @@ -149,7 +154,8 @@ LiftStatus InstructionLifter::LiftIntoBlock(Instruction &arch_inst,

// Begin an atomic block.
if (arch_inst.is_atomic_read_modify_write) {
llvm::Value *temp_args[] = {ir.CreateLoad(mem_ptr_ref)};
llvm::Value *temp_args[] = {
ir.CreateLoad(impl->memory_ptr_type, mem_ptr_ref)};
ir.CreateStore(ir.CreateCall(impl->intrinsics->atomic_begin, temp_args),
mem_ptr_ref);
}
Expand Down Expand Up @@ -185,14 +191,15 @@ LiftStatus InstructionLifter::LiftIntoBlock(Instruction &arch_inst,
}

// Pass in current value of the memory pointer.
args[0] = ir.CreateLoad(mem_ptr_ref);
args[0] = ir.CreateLoad(impl->memory_ptr_type, mem_ptr_ref);

// Call the function that implements the instruction semantics.
ir.CreateStore(ir.CreateCall(isel_func, args), mem_ptr_ref);

// End an atomic block.
if (arch_inst.is_atomic_read_modify_write) {
llvm::Value *temp_args[] = {ir.CreateLoad(mem_ptr_ref)};
llvm::Value *temp_args[] = {
ir.CreateLoad(impl->memory_ptr_type, mem_ptr_ref)};
ir.CreateStore(ir.CreateCall(impl->intrinsics->atomic_end, temp_args),
mem_ptr_ref);
}
Expand All @@ -209,7 +216,8 @@ LiftStatus InstructionLifter::LiftIntoBlock(Instruction &arch_inst,
// are lifted, we do the `PC = NEXT_PC + size`, so this is fine.
ir.CreateStore(next_pc, next_pc_ref);

llvm::Value *temp_args[] = {ir.CreateLoad(mem_ptr_ref)};
llvm::Value *temp_args[] = {
ir.CreateLoad(impl->memory_ptr_type, mem_ptr_ref)};
ir.CreateStore(ir.CreateCall(impl->intrinsics->delay_slot_end, temp_args),
mem_ptr_ref);
}
Expand Down Expand Up @@ -770,7 +778,7 @@ llvm::Value *InstructionLifter::LiftAddressOperand(Instruction &inst,
llvm::Argument *,
Operand &op) {
auto &arch_addr = op.addr;
const auto word_type = impl->word_type;
const auto word_type = llvm::dyn_cast<llvm::IntegerType>(impl->word_type);
const auto zero = llvm::ConstantInt::get(word_type, 0, false);
const auto word_size = impl->arch->address_size;

Expand Down
9 changes: 6 additions & 3 deletions lib/BC/InstructionLifter.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,15 @@ class InstructionLifter::Impl {
// Architecture being used for lifting.
const Arch *const arch;

// Machine word type for this architecture.
llvm::IntegerType *const word_type;

// Set of intrinsics.
const IntrinsicTable *const intrinsics;

// Machine word type for this architecture.
llvm::Type *const word_type;

// Type of the memory pointer.
llvm::Type *const memory_ptr_type;

// Cache of looked up registers inside of `last_func`.
std::unordered_map<std::string, llvm::Value *> reg_ptr_cache;

Expand Down
10 changes: 9 additions & 1 deletion lib/BC/IntrinsicTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,15 @@ IntrinsicTable::IntrinsicTable(llvm::Module *module)
compare_sle(FindPureIntrinsic(module, "__remill_compare_sle")),
compare_sgt(FindPureIntrinsic(module, "__remill_compare_sgt")),
compare_eq(FindPureIntrinsic(module, "__remill_compare_eq")),
compare_neq(FindPureIntrinsic(module, "__remill_compare_neq")) {
compare_neq(FindPureIntrinsic(module, "__remill_compare_neq")),

lifted_function_type(error->getFunctionType()),
state_ptr_type(llvm::dyn_cast<llvm::PointerType>(
lifted_function_type->getParamType(kStatePointerArgNum))),
pc_type(llvm::dyn_cast<llvm::IntegerType>(
lifted_function_type->getParamType(kPCArgNum))),
mem_ptr_type(llvm::dyn_cast<llvm::PointerType>(
lifted_function_type->getParamType(kMemoryPointerArgNum))) {


// Make sure to set the correct attributes on this to make sure that
Expand Down
Loading

0 comments on commit d5928a0

Please sign in to comment.