Skip to content

Commit d5928a0

Browse files
authored
llvm 13 support (#577)
* llvm 13 support * Add llvm 13 * Update build script * Update build script * Modify remill-lift docker entrypoint
1 parent 161e035 commit d5928a0

File tree

12 files changed

+173
-112
lines changed

12 files changed

+173
-112
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ jobs:
2424
image:
2525
- { name: 'ubuntu', tag: '18.04' }
2626
- { name: 'ubuntu', tag: '20.04' }
27-
llvm: [
28-
'12'
29-
]
27+
llvm: ['12', '13']
3028

3129
runs-on: ubuntu-20.04
3230
container:
@@ -94,12 +92,8 @@ jobs:
9492
strategy:
9593
fail-fast: false
9694
matrix:
97-
os: [
98-
'macos-11'
99-
]
100-
llvm: [
101-
'12'
102-
]
95+
os: ['macos-11']
96+
llvm: ['12', '13']
10397

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

@@ -235,7 +229,7 @@ jobs:
235229
runs-on: ubuntu-latest
236230
strategy:
237231
matrix:
238-
llvm: ["12"]
232+
llvm: ["12", "13"]
239233
ubuntu: ["18.04"]
240234
steps:
241235
- uses: actions/checkout@v2

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Choose your LLVM version
2-
ARG LLVM_VERSION=12
2+
ARG LLVM_VERSION=13
33
ARG ARCH=amd64
44
ARG UBUNTU_VERSION=18.04
55
ARG DISTRO_BASE=ubuntu${UBUNTU_VERSION}

bin/lift/Lift.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ int main(int argc, char *argv[]) {
403403

404404
auto reg_ptr = reg->AddressOf(state_ptr, entry);
405405
ir.SetInsertPoint(entry);
406-
ir.CreateStore(ir.CreateLoad(reg_ptr), &arg);
406+
ir.CreateStore(ir.CreateLoad(reg->type, reg_ptr), &arg);
407407
}
408408

409409
// Return the memory pointer, so that all memory accesses are

include/remill/BC/IntrinsicTable.h

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@
2121
namespace llvm {
2222
class ConstantArray;
2323
class Function;
24+
class FunctionType;
25+
class IntegerType;
2426
class Module;
27+
class PointerType;
2528
class Value;
2629
} // namespace llvm
2730
namespace remill {
@@ -79,26 +82,29 @@ class IntrinsicTable {
7982
llvm::Function *const delay_slot_end;
8083

8184
// Optimization enabling.
82-
llvm::Function *undefined_8;
83-
llvm::Function *undefined_16;
84-
llvm::Function *undefined_32;
85-
llvm::Function *undefined_64;
86-
llvm::Function *undefined_f32;
87-
llvm::Function *undefined_f64;
88-
llvm::Function *undefined_f80;
89-
85+
llvm::Function *const undefined_8;
86+
llvm::Function *const undefined_16;
87+
llvm::Function *const undefined_32;
88+
llvm::Function *const undefined_64;
89+
llvm::Function *const undefined_f32;
90+
llvm::Function *const undefined_f64;
91+
llvm::Function *const undefined_f80;
9092

9193
// Flag markers
92-
llvm::Function *flag_computation_zero;
93-
llvm::Function *flag_computation_sign;
94-
llvm::Function *flag_computation_overflow;
95-
llvm::Function *flag_computation_carry;
96-
97-
llvm::Function *compare_sle;
98-
llvm::Function *compare_sgt;
99-
llvm::Function *compare_eq;
100-
llvm::Function *compare_neq;
101-
94+
llvm::Function *const flag_computation_zero;
95+
llvm::Function *const flag_computation_sign;
96+
llvm::Function *const flag_computation_overflow;
97+
llvm::Function *const flag_computation_carry;
98+
99+
llvm::Function *const compare_sle;
100+
llvm::Function *const compare_sgt;
101+
llvm::Function *const compare_eq;
102+
llvm::Function *const compare_neq;
103+
104+
llvm::FunctionType *const lifted_function_type;
105+
llvm::PointerType *const state_ptr_type;
106+
llvm::IntegerType *const pc_type;
107+
llvm::PointerType *const mem_ptr_type;
102108

103109
private:
104110
IntrinsicTable(void) = delete;

include/remill/BC/Util.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,17 @@ class IntrinsicTable;
6767
void InitFunctionAttributes(llvm::Function *F);
6868

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

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

7678
llvm::CallInst *AddTerminatingTailCall(llvm::BasicBlock *source_block,
77-
llvm::Value *dest_func);
79+
llvm::Value *dest_func,
80+
const IntrinsicTable &intrinsics);
7881

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

9497
// Return the current program counter.
95-
llvm::Value *LoadProgramCounter(llvm::BasicBlock *block);
98+
llvm::Value *LoadProgramCounter(llvm::BasicBlock *block,
99+
const IntrinsicTable &intrinsics);
96100

97101
// Return the next program counter.
98-
llvm::Value *LoadNextProgramCounter(llvm::BasicBlock *block);
102+
llvm::Value *LoadNextProgramCounter(llvm::BasicBlock *block,
103+
const IntrinsicTable &intrinsics);
99104

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

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

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

124130
// Return the current memory pointer.
125-
llvm::Value *LoadMemoryPointer(llvm::BasicBlock *block);
131+
llvm::Value *LoadMemoryPointer(llvm::BasicBlock *block,
132+
const IntrinsicTable &intrinsics);
126133

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

185192
// Serialize an LLVM object into a string.
186193
std::string LLVMThingToString(llvm::Value *thing);

lib/BC/InstructionLifter.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,13 @@ llvm::Function *GetInstructionFunction(llvm::Module *module,
4646
InstructionLifter::Impl::Impl(const Arch *arch_,
4747
const IntrinsicTable *intrinsics_)
4848
: arch(arch_),
49-
word_type(llvm::Type::getIntNTy(
50-
intrinsics_->async_hyper_call->getContext(), arch->address_size)),
5149
intrinsics(intrinsics_),
50+
word_type(
51+
remill::NthArgument(intrinsics->async_hyper_call,
52+
remill::kPCArgNum)->getType()),
53+
memory_ptr_type(
54+
remill::NthArgument(intrinsics->async_hyper_call,
55+
remill::kMemoryPointerArgNum)->getType()),
5256
module(intrinsics->async_hyper_call->getParent()),
5357
invalid_instruction(
5458
GetInstructionFunction(module, kInvalidInstructionISelName)),
@@ -119,7 +123,7 @@ LiftStatus InstructionLifter::LiftIntoBlock(Instruction &arch_inst,
119123
const auto pc_ref = LoadRegAddress(block, state_ptr, kPCVariableName);
120124
const auto next_pc_ref =
121125
LoadRegAddress(block, state_ptr, kNextPCVariableName);
122-
const auto next_pc = ir.CreateLoad(next_pc_ref);
126+
const auto next_pc = ir.CreateLoad(impl->word_type, next_pc_ref);
123127

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

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

150155
// Begin an atomic block.
151156
if (arch_inst.is_atomic_read_modify_write) {
152-
llvm::Value *temp_args[] = {ir.CreateLoad(mem_ptr_ref)};
157+
llvm::Value *temp_args[] = {
158+
ir.CreateLoad(impl->memory_ptr_type, mem_ptr_ref)};
153159
ir.CreateStore(ir.CreateCall(impl->intrinsics->atomic_begin, temp_args),
154160
mem_ptr_ref);
155161
}
@@ -185,14 +191,15 @@ LiftStatus InstructionLifter::LiftIntoBlock(Instruction &arch_inst,
185191
}
186192

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

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

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

212-
llvm::Value *temp_args[] = {ir.CreateLoad(mem_ptr_ref)};
219+
llvm::Value *temp_args[] = {
220+
ir.CreateLoad(impl->memory_ptr_type, mem_ptr_ref)};
213221
ir.CreateStore(ir.CreateCall(impl->intrinsics->delay_slot_end, temp_args),
214222
mem_ptr_ref);
215223
}
@@ -770,7 +778,7 @@ llvm::Value *InstructionLifter::LiftAddressOperand(Instruction &inst,
770778
llvm::Argument *,
771779
Operand &op) {
772780
auto &arch_addr = op.addr;
773-
const auto word_type = impl->word_type;
781+
const auto word_type = llvm::dyn_cast<llvm::IntegerType>(impl->word_type);
774782
const auto zero = llvm::ConstantInt::get(word_type, 0, false);
775783
const auto word_size = impl->arch->address_size;
776784

lib/BC/InstructionLifter.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,15 @@ class InstructionLifter::Impl {
6161
// Architecture being used for lifting.
6262
const Arch *const arch;
6363

64-
// Machine word type for this architecture.
65-
llvm::IntegerType *const word_type;
66-
6764
// Set of intrinsics.
6865
const IntrinsicTable *const intrinsics;
6966

67+
// Machine word type for this architecture.
68+
llvm::Type *const word_type;
69+
70+
// Type of the memory pointer.
71+
llvm::Type *const memory_ptr_type;
72+
7073
// Cache of looked up registers inside of `last_func`.
7174
std::unordered_map<std::string, llvm::Value *> reg_ptr_cache;
7275

lib/BC/IntrinsicTable.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,15 @@ IntrinsicTable::IntrinsicTable(llvm::Module *module)
145145
compare_sle(FindPureIntrinsic(module, "__remill_compare_sle")),
146146
compare_sgt(FindPureIntrinsic(module, "__remill_compare_sgt")),
147147
compare_eq(FindPureIntrinsic(module, "__remill_compare_eq")),
148-
compare_neq(FindPureIntrinsic(module, "__remill_compare_neq")) {
148+
compare_neq(FindPureIntrinsic(module, "__remill_compare_neq")),
149+
150+
lifted_function_type(error->getFunctionType()),
151+
state_ptr_type(llvm::dyn_cast<llvm::PointerType>(
152+
lifted_function_type->getParamType(kStatePointerArgNum))),
153+
pc_type(llvm::dyn_cast<llvm::IntegerType>(
154+
lifted_function_type->getParamType(kPCArgNum))),
155+
mem_ptr_type(llvm::dyn_cast<llvm::PointerType>(
156+
lifted_function_type->getParamType(kMemoryPointerArgNum))) {
149157

150158

151159
// Make sure to set the correct attributes on this to make sure that

0 commit comments

Comments
 (0)