fix control-flow decoding and restore smoketests

Handle the synthetic fallthrough sentinel in Sleigh control-flow analysis without indexing past the end of the pcode ops vector. Also fix the aarch32 smoketest flag spelling in CI and keep Nix checks enabled on Darwin so the smoketests run consistently across environments.
This commit is contained in:
William Tan
2026-03-31 10:12:41 -04:00
parent 70ec62035c
commit 56eee94851
3 changed files with 26 additions and 14 deletions
+2 -6
View File
@@ -80,7 +80,7 @@ jobs:
run: |
install/bin/remill-lift-${{ matrix.llvm }} --arch amd64 --ir_out /dev/stdout --bytes c704ba01000000
install/bin/remill-lift-${{ matrix.llvm }} --arch aarch64 --ir_out /dev/stdout --address 0x400544 --bytes FD7BBFA90000009000601891FD030091B7FFFF97E0031F2AFD7BC1A8C0035FD6
install/bin/remill-lift-${{ matrix.llvm }} --arch aarch32 -ir_out /dev/stderr --bytes 0cd04de208008de504108de500208de508309de504009de500109de5903122e0c20fa0e110109fe5001091e5002081e5040081e50cd08de21eff2fe14000000000000000
install/bin/remill-lift-${{ matrix.llvm }} --arch aarch32 --ir_out /dev/stderr --bytes 0cd04de208008de504108de500208de508309de504009de500109de5903122e0c20fa0e110109fe5001091e5002081e5040081e50cd08de21eff2fe14000000000000000
- name: Test remill
run: |
@@ -117,11 +117,7 @@ jobs:
run: |
./result/bin/remill-lift-${{ matrix.llvm }} --arch amd64 --ir_out /dev/stdout --bytes c704ba01000000
./result/bin/remill-lift-${{ matrix.llvm }} --arch aarch64 --ir_out /dev/stdout --address 0x400544 --bytes FD7BBFA90000009000601891FD030091B7FFFF97E0031F2AFD7BC1A8C0035FD6
- name: Smoketests (aarch32)
if: ${{ runner.os != 'macOS' }}
run: |
./result/bin/remill-lift-${{ matrix.llvm }} --arch aarch32 -ir_out /dev/stderr --bytes 0cd04de208008de504108de500208de508309de504009de500109de5903122e0c20fa0e110109fe5001091e5002081e5040081e50cd08de21eff2fe14000000000000000
./result/bin/remill-lift-${{ matrix.llvm }} --arch aarch32 --ir_out /dev/stderr --bytes 0cd04de208008de504108de500208de508309de504009de500109de5903122e0c20fa0e110109fe5001091e5002081e5040081e50cd08de21eff2fe14000000000000000
macos:
# Skip building pull requests from the same repository
+1 -1
View File
@@ -136,7 +136,7 @@
"-DGIT_FAIL_IF_NONZERO_EXIT=FALSE"
];
doCheck = !pkgs.stdenv.hostPlatform.isDarwin;
doCheck = true;
checkPhase = ''
runHook preCheck
+23 -7
View File
@@ -255,13 +255,22 @@ static ControlFlowStructureAnalysis::SleighDecodingResult
ExtractNonConditionalCategory(
const std::vector<Flow> &flows, const std::vector<RemillPcodeOp> &ops,
std::function<std::optional<Instruction::InstructionFlowCategory>(
const Flow &, const RemillPcodeOp &)>
const Flow &,
std::optional<std::reference_wrapper<const RemillPcodeOp>>)>
compute_single_flow_category) {
// So here the requirement to make this cateogry work is that all flows target the same abnormal (or are all returns), and all decoding contexts are equal
std::vector<Instruction::InstructionFlowCategory> cats;
for (auto flow : flows) {
if (auto cat = compute_single_flow_category(flow, ops[flow.pcode_index])) {
for (const auto &flow : flows) {
std::optional<std::reference_wrapper<const RemillPcodeOp>> op;
if (flow.pcode_index < ops.size()) {
op = std::cref(ops[flow.pcode_index]);
} else if (flow.pcode_index != ops.size()) {
DLOG(ERROR) << "Flow index out of range";
return std::nullopt;
}
if (auto cat = compute_single_flow_category(flow, op)) {
cats.push_back(*cat);
} else {
DLOG(ERROR) << "Missing flow cat";
@@ -291,11 +300,12 @@ ExtractNonConditionalCategory(
static ControlFlowStructureAnalysis::SleighDecodingResult
ExtractNormal(const std::vector<Flow> &flows,
const std::vector<RemillPcodeOp> &ops) {
// So we already know the op fallsthrough
return ExtractNonConditionalCategory(
flows, ops,
[](const Flow &flow, const RemillPcodeOp &op)
[](const Flow &flow,
std::optional<std::reference_wrapper<const RemillPcodeOp>> op)
-> std::optional<Instruction::InstructionFlowCategory> {
(void) op;
if (flow.context) {
Instruction::NormalInsn norm(
Instruction::FallthroughFlow(*flow.context));
@@ -312,9 +322,15 @@ ExtractAbnormal(const std::vector<Flow> &flows,
const std::vector<RemillPcodeOp> &ops) {
return ExtractNonConditionalCategory(
flows, ops,
[](const Flow &flow, const RemillPcodeOp &op)
[](const Flow &flow,
std::optional<std::reference_wrapper<const RemillPcodeOp>> op)
-> std::optional<Instruction::InstructionFlowCategory> {
auto res = AbnormalCategoryOfFlow(flow, op);
if (!op) {
DLOG(ERROR) << "Abnormal flow requires backing pcode op";
return std::nullopt;
}
auto res = AbnormalCategoryOfFlow(flow, op->get());
if (res) {
return variant_cast(*res);
}