Skip to content

Commit 3b2f44f

Browse files
committed
More aarch64 fixes
1 parent 590c9b8 commit 3b2f44f

File tree

3 files changed

+56
-22
lines changed

3 files changed

+56
-22
lines changed

remill/Arch/AArch64/Arch.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,6 +1220,17 @@ bool AArch64Arch::DecodeInstruction(uint64_t address,
12201220
return false;
12211221
}
12221222

1223+
// Control flow operands update the next program counter.
1224+
if (inst.IsControlFlow()) {
1225+
inst.operands.emplace_back();
1226+
auto &dst_ret_pc = inst.operands.back();
1227+
dst_ret_pc.type = Operand::kTypeRegister;
1228+
dst_ret_pc.action = Operand::kActionWrite;
1229+
dst_ret_pc.size = address_size;
1230+
dst_ret_pc.reg.name = "NEXT_PC";
1231+
dst_ret_pc.reg.size = address_size;
1232+
}
1233+
12231234
// The semantics will store the return address in `RETURN_PC`. This is to
12241235
// help synchronize program counters when lifting instructions on an ISA
12251236
// with delay slots.
@@ -1228,9 +1239,9 @@ bool AArch64Arch::DecodeInstruction(uint64_t address,
12281239
auto &dst_ret_pc = inst.operands.back();
12291240
dst_ret_pc.type = Operand::kTypeRegister;
12301241
dst_ret_pc.action = Operand::kActionWrite;
1231-
dst_ret_pc.size = 64;
1242+
dst_ret_pc.size = address_size;
12321243
dst_ret_pc.reg.name = "RETURN_PC";
1233-
dst_ret_pc.reg.size = 64;
1244+
dst_ret_pc.reg.size = address_size;
12341245
}
12351246

12361247
return true;

remill/Arch/AArch64/Semantics/BRANCH.cpp

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -117,71 +117,90 @@ DEF_COND(AL) = CondAL;
117117

118118
namespace {
119119

120-
DEF_SEM(DoDirectBranch, PC target_pc) {
121-
Write(REG_PC, Read(target_pc));
120+
DEF_SEM(DoDirectBranch, PC target_pc, R64W pc_dst) {
121+
const auto new_pc = Read(target_pc);
122+
Write(REG_PC, new_pc);
123+
Write(pc_dst, new_pc);
122124
return memory;
123125
}
124126

125127
template <typename S>
126-
DEF_SEM(DoIndirectBranch, S dst) {
127-
Write(REG_PC, Read(dst));
128+
DEF_SEM(DoIndirectBranch, S dst, R64W pc_dst) {
129+
const auto new_pc = Read(dst);
130+
Write(REG_PC, new_pc);
131+
Write(pc_dst, new_pc);
128132
return memory;
129133
}
130134

131135
template <bool (*check_cond)(const State &)>
132-
DEF_SEM(DirectCondBranch, R8W cond, PC taken, PC not_taken) {
136+
DEF_SEM(DirectCondBranch, R8W cond, PC taken, PC not_taken, R64W pc_dst) {
133137
addr_t taken_pc = Read(taken);
134138
addr_t not_taken_pc = Read(not_taken);
135139
uint8_t take_branch = check_cond(state);
136140
Write(cond, take_branch);
137-
Write(REG_PC, Select<addr_t>(take_branch, taken_pc, not_taken_pc));
141+
142+
const auto new_pc = Select<addr_t>(take_branch, taken_pc, not_taken_pc);
143+
Write(REG_PC, new_pc);
144+
Write(pc_dst, new_pc);
138145
return memory;
139146
}
140147

141148
template <typename S>
142-
DEF_SEM(CBZ, R8W cond, PC taken, PC not_taken, S src) {
149+
DEF_SEM(CBZ, R8W cond, PC taken, PC not_taken, S src, R64W pc_dst) {
143150
addr_t taken_pc = Read(taken);
144151
addr_t not_taken_pc = Read(not_taken);
145152
uint8_t take_branch = UCmpEq(Read(src), 0);
146153
Write(cond, take_branch);
147-
Write(REG_PC, Select<addr_t>(take_branch, taken_pc, not_taken_pc));
154+
155+
const auto new_pc = Select<addr_t>(take_branch, taken_pc, not_taken_pc);
156+
Write(REG_PC, new_pc);
157+
Write(pc_dst, new_pc);
148158
return memory;
149159
}
150160

151161
template <typename S>
152-
DEF_SEM(CBNZ, R8W cond, PC taken, PC not_taken, S src) {
162+
DEF_SEM(CBNZ, R8W cond, PC taken, PC not_taken, S src, R64W pc_dst) {
153163
addr_t taken_pc = Read(taken);
154164
addr_t not_taken_pc = Read(not_taken);
155165
uint8_t take_branch = UCmpNeq(Read(src), 0);
156166
Write(cond, take_branch);
157-
Write(REG_PC, Select<addr_t>(take_branch, taken_pc, not_taken_pc));
167+
168+
const auto new_pc = Select<addr_t>(take_branch, taken_pc, not_taken_pc);
169+
Write(REG_PC, new_pc);
170+
Write(pc_dst, new_pc);
158171
return memory;
159172
}
160173

161174

162175
template <typename S>
163-
DEF_SEM(TBZ, I8 bit_pos, R8W cond, PC taken, PC not_taken, S src) {
176+
DEF_SEM(TBZ, I8 bit_pos, R8W cond, PC taken, PC not_taken, S src, R64W pc_dst) {
164177
addr_t taken_pc = Read(taken);
165178
addr_t not_taken_pc = Read(not_taken);
166179
auto bit_n = ZExtTo<S>(Read(bit_pos));
167180
auto reg_val = ZExtTo<S>(Read(src));
168181
auto bit_set = UAnd(reg_val, UShl(ZExtTo<S>(1), bit_n));
169182
auto take_branch = UCmpEq(bit_set, 0);
170183
Write(cond, take_branch);
171-
Write(REG_PC, Select<addr_t>(take_branch, taken_pc, not_taken_pc));
184+
185+
const auto new_pc = Select<addr_t>(take_branch, taken_pc, not_taken_pc);
186+
Write(REG_PC, new_pc);
187+
Write(pc_dst, new_pc);
172188
return memory;
173189
}
174190

175191
template <typename S>
176-
DEF_SEM(TBNZ, I8 bit_pos, R8W cond, PC taken, PC not_taken, S src) {
192+
DEF_SEM(TBNZ, I8 bit_pos, R8W cond, PC taken, PC not_taken, S src, R64W pc_dst) {
177193
addr_t taken_pc = Read(taken);
178194
addr_t not_taken_pc = Read(not_taken);
179195
auto bit_n = ZExtTo<S>(Read(bit_pos));
180196
auto reg_val = ZExtTo<S>(Read(src));
181197
auto bit_set = UAnd(reg_val, UShl(ZExtTo<S>(1), bit_n));
182198
auto take_branch = UCmpNeq(bit_set, 0);
183199
Write(cond, take_branch);
184-
Write(REG_PC, Select<addr_t>(take_branch, taken_pc, not_taken_pc));
200+
201+
const auto new_pc = Select<addr_t>(take_branch, taken_pc, not_taken_pc);
202+
Write(REG_PC, new_pc);
203+
Write(pc_dst, new_pc);
185204
return memory;
186205
}
187206

remill/Arch/AArch64/Semantics/CALL_RET.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,20 @@
1717
namespace {
1818

1919
template <typename S>
20-
DEF_SEM(CALL, S target_addr, PC ret_addr, R64W return_pc_dst) {
21-
Write(REG_LP, Read(ret_addr));
22-
const auto return_pc = Read(target_addr);
23-
Write(REG_PC, return_pc);
20+
DEF_SEM(CALL, S target_addr, PC ret_addr, R64W dst_pc, R64W return_pc_dst) {
21+
const auto return_pc = Read(ret_addr);
22+
const auto new_pc = Read(target_addr);
23+
Write(REG_LP, return_pc);
24+
Write(REG_PC, new_pc);
25+
Write(dst_pc, new_pc);
2426
Write(return_pc_dst, return_pc);
2527
return memory;
2628
}
2729

28-
DEF_SEM(RET, R64 target_pc) {
29-
Write(REG_PC, Read(target_pc));
30+
DEF_SEM(RET, R64 target_pc, R64W dst_pc) {
31+
const auto new_pc = Read(target_pc);
32+
Write(REG_PC, new_pc);
33+
Write(dst_pc, new_pc);
3034
return memory;
3135
}
3236

0 commit comments

Comments
 (0)