Skip to content

Commit 3bff79c

Browse files
committed
decomp: update switch handling and remove fallback code entirely and add new tests
1 parent 644966d commit 3bff79c

File tree

5 files changed

+53
-27
lines changed

5 files changed

+53
-27
lines changed

lib/patchestry/AST/OperationStmt.cpp

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -808,27 +808,6 @@ namespace patchestry::ast {
808808
input_expr = cast_expr;
809809
}
810810

811-
// Build a fallback statement for after the switch:
812-
// - goto fallback_block when a bounds-check out-of-range target is known,
813-
// - __builtin_unreachable() otherwise (all enumerated cases are covered).
814-
// Placed after the switch as a flat statement rather than inside a default:
815-
// arm, so the switch only contains explicit case labels.
816-
auto make_fallback_stmt = [&]() -> clang::Stmt * {
817-
if (op.fallback_block.has_value()
818-
&& function_builder().labels_declaration.contains(*op.fallback_block))
819-
{
820-
auto target_loc = SourceLocation(ctx.getSourceManager(), *op.fallback_block);
821-
return new (ctx) clang::GotoStmt(
822-
function_builder().labels_declaration.at(*op.fallback_block), loc,
823-
target_loc
824-
);
825-
}
826-
std::vector< clang::Expr * > no_args;
827-
return create_builtin_call(
828-
ctx, sema(), clang::Builtin::BI__builtin_unreachable, no_args, loc
829-
);
830-
};
831-
832811
// Priority 1: switch_cases present — proper integer switch using per-case
833812
// integer values recovered by Ghidra. Prefer inputs[0] when it is a named
834813
// local variable (the most direct discriminant); otherwise fall back to
@@ -955,16 +934,27 @@ namespace patchestry::ast {
955934
sw_body.push_back(create_case(sc));
956935
}
957936
}
937+
938+
// Emit a default: arm for the guard branch's out-of-bounds target.
939+
// When Ghidra folds a bounds-check CBRANCH, the "else" edge becomes
940+
// fallback_block — the path taken when no case matches.
941+
if (op.fallback_block.has_value()
942+
&& function_builder().labels_declaration.contains(*op.fallback_block))
943+
{
944+
auto *default_stmt = new (ctx) clang::DefaultStmt(loc, loc, nullptr);
945+
auto target_loc = SourceLocation(ctx.getSourceManager(), *op.fallback_block);
946+
auto *goto_stmt = new (ctx) clang::GotoStmt(
947+
function_builder().labels_declaration.at(*op.fallback_block), loc,
948+
target_loc
949+
);
950+
default_stmt->setSubStmt(goto_stmt);
951+
sw_body.push_back(default_stmt);
952+
}
953+
958954
switch_stmt->setBody(
959955
clang::CompoundStmt::Create(ctx, sw_body, clang::FPOptionsOverride(), loc, loc)
960956
);
961-
(void) make_fallback_stmt();
962957
return { switch_stmt, false };
963-
// auto *fallback = make_fallback_stmt();
964-
// std::vector< clang::Stmt * > result_stmts = { switch_stmt, fallback };
965-
// return { clang::CompoundStmt::Create(
966-
// ctx, result_stmts, clang::FPOptionsOverride(), loc, loc
967-
//), false };
968958
}
969959

970960
// Priority 2: successor_blocks only — address-based switch (existing logic).
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// CIR-only: MLIR/LL lowering crashes on function pointer types in structs
2+
// (CIR ABI limitation: "Missing default ABI-specific type for !cir.func")
3+
// RUN: bash %strip-json-comments %s > %t.json
4+
// RUN: %patchir-decomp -input %t.json -use-rellic-transform=false -emit-cir -print-tu -output %t >> /dev/null 2>&1
5+
// RUN: test -e %t.c
6+
// RUN: %patchir-decomp -input %t.json -emit-cir -print-tu -output %t >> /dev/null 2>&1
7+
// RUN: test -e %t.c
8+
// RUN: %file-check -vv -check-prefix=CIR %s --input-file %t.cir
9+
// CIR: cir.func @dma2_channel2_isr
10+
// RUN: %gen-call-checks %t.json > %t.call.checks
11+
// RUN: %file-check -check-prefix=CALL-CHECK %t.call.checks --input-file %t.cir
12+
{"architecture":"ARM","id":"ARM:LE:32:Cortex","format":"Executable and Linking Format (ELF)","functions":{"ram:0800180c":{"name":"dma2_channel2_isr","is_intrinsic":false,"type":{"return_type":"t0","is_variadic":false,"is_noreturn":false,"calling_convention":"unknown","parameter_types":[]},"basic_blocks":{"ram:0800180c:0:basic":{"operations":{"ram:0800180c:250:0":{"mnemonic":"COPY","type":"t1","output":{"kind":"local","operation":"unique:001c2400:0:0"},"inputs":[{"type":"t1","kind":"global","global":"ram:2000818c"}]},"ram:08001818:24:2":{"mnemonic":"CALL","type":"t2","output":{"kind":"local","operation":"unique:001c2401:1:0"},"has_return_value":true,"target":{"kind":"function","function":"ram:08001f86","is_variadic":false,"is_noreturn":false},"inputs":[{"type":"t3","kind":"constant","value":1073873920},{"type":"t4","kind":"constant","value":2},{"type":"t3","kind":"constant","value":4}]},"ram:08001820:34:3":{"mnemonic":"CBRANCH","taken_block":"ram:08001822:2:basic","not_taken_block":"ram:0800183a:1:basic","condition":{"type":"t2","kind":"local","operation":"unique:001c2401:1:0"}}},"ordered_operations":["ram:0800180c:250:0","ram:08001818:24:2","ram:08001820:34:3"]},"ram:0800183a:1:basic":{"operations":{"ram:0800183a:243:0":{"mnemonic":"PTRSUB","type":"t5","inputs":[{"type":"t1","kind":"local","operation":"unique:001c2400:0:0"},{"type":"t6","kind":"constant","value":36}]},"ram:0800183a:72:1":{"mnemonic":"LOAD","type":"t7","inputs":[{"type":"t5","kind":"temporary","operation":"ram:0800183a:243:0"}]},"ram:0800183c:244:2":{"mnemonic":"PTRSUB","type":"t8","inputs":[{"type":"t1","kind":"local","operation":"unique:001c2400:0:0"},{"type":"t6","kind":"constant","value":8232}]},"ram:0800183c:74:3":{"mnemonic":"LOAD","type":"t9","inputs":[{"type":"t8","kind":"temporary","operation":"ram:0800183c:244:2"}]},"ram:08001840:247:4":{"mnemonic":"PTRSUB","type":"ta","inputs":[{"type":"t1","kind":"local","operation":"unique:001c2400:0:0"},{"type":"t6","kind":"constant","value":40}]},"ram:08001840:249:5":{"mnemonic":"PTRADD","type":"ta","inputs":[{"type":"ta","kind":"temporary","operation":"ram:08001840:247:4"},{"type":"t7","kind":"temporary","operation":"ram:0800183a:72:1"},{"type":"t6","kind":"constant","value":2}]},"ram:08001846:102:7":{"mnemonic":"CALLIND","has_return_value":false,"target":{"type":"t9","kind":"temporary","operation":"ram:0800183c:74:3"},"inputs":[{"type":"t1","kind":"local","operation":"unique:001c2400:0:0"},{"type":"ta","kind":"temporary","operation":"ram:08001840:249:5"}]},"ram:08001848:103:8":{"mnemonic":"COPY","type":"t3","output":{"kind":"local","operation":"unique:001c2402:2:0"},"inputs":[{"type":"t3","kind":"constant","value":2}]},"ram:0800184a:108:9":{"mnemonic":"BRANCH","target_block":"ram:0800182e:3:basic"}},"ordered_operations":["ram:0800183a:243:0","ram:0800183a:72:1","ram:0800183c:244:2","ram:0800183c:74:3","ram:08001840:247:4","ram:08001840:249:5","ram:08001846:102:7","ram:08001848:103:8","ram:0800184a:108:9"]},"ram:08001822:2:basic":{"operations":{"ram:08001822:241:0":{"mnemonic":"PTRSUB","type":"t8","inputs":[{"type":"t1","kind":"local","operation":"unique:001c2400:0:0"},{"type":"t6","kind":"constant","value":8232}]},"ram:08001822:36:1":{"mnemonic":"LOAD","type":"t9","inputs":[{"type":"t8","kind":"temporary","operation":"ram:08001822:241:0"}]},"ram:08001824:242:2":{"mnemonic":"PTRSUB","type":"ta","inputs":[{"type":"t1","kind":"local","operation":"unique:001c2400:0:0"},{"type":"t6","kind":"constant","value":40}]},"ram:0800182a:51:4":{"mnemonic":"CALLIND","has_return_value":false,"target":{"type":"t9","kind":"temporary","operation":"ram:08001822:36:1"},"inputs":[{"type":"t1","kind":"local","operation":"unique:001c2400:0:0"},{"type":"ta","kind":"temporary","operation":"ram:08001824:242:2"}]},"ram:0800182c:52:5":{"mnemonic":"COPY","type":"t3","output":{"kind":"local","operation":"unique:001c2402:2:0"},"inputs":[{"type":"t3","kind":"constant","value":4}]},"ram:08001822:2:basic.exit":{"mnemonic":"BRANCH","target_block":"ram:0800182e:3:basic"}},"ordered_operations":["ram:08001822:241:0","ram:08001822:36:1","ram:08001824:242:2","ram:0800182a:51:4","ram:0800182c:52:5","ram:08001822:2:basic.exit"]},"ram:0800182e:3:basic":{"operations":{"ram:08001836:69:3":{"mnemonic":"CALL","has_return_value":true,"target":{"kind":"function","function":"ram:08001f7a","is_variadic":false,"is_noreturn":false},"inputs":[{"type":"t3","kind":"constant","value":1073873920},{"type":"t4","kind":"constant","value":2},{"type":"t3","kind":"local","operation":"unique:001c2402:2:0"}]},"ram:08001836:70:5":{"mnemonic":"RETURN","inputs":[]}},"ordered_operations":["ram:08001836:69:3","ram:08001836:70:5"]},"ram:0800180c:entry":{"operations":{"unique:001c2400:0:0":{"mnemonic":"DECLARE_LOCAL","kind":"local","name":"pbVar1","type":"t1"},"unique:001c2401:1:0":{"mnemonic":"DECLARE_LOCAL","kind":"local","name":"_Var2","type":"t2"},"unique:001c2402:2:0":{"mnemonic":"DECLARE_LOCAL","kind":"local","name":"interrupts","type":"t3"},"entry.exit":{"mnemonic":"BRANCH","target_block":"ram:0800180c:0:basic"}},"ordered_operations":["unique:001c2400:0:0","unique:001c2401:1:0","unique:001c2402:2:0","entry.exit"]}},"entry_block":"ram:0800180c:entry"},"ram:08001f86":{"name":"dma_get_interrupt_flag","is_intrinsic":false,"type":{"return_type":"t2","is_variadic":false,"is_noreturn":false,"calling_convention":"__stdcall","parameter_types":["t3","t4","t3"]}},"ram:08001f7a":{"name":"dma_clear_interrupt_flags","is_intrinsic":false,"type":{"return_type":"t0","is_variadic":false,"is_noreturn":false,"calling_convention":"__stdcall","parameter_types":["t3","t4","t3"]}}},"globals":{"ram:2000818c":{"name":"bl_acq_adc4","size":"4","type":"t1"}},"types":{"t0":{"name":"void","size":0,"kind":"void"},"t1":{"kind":"pointer","size":4,"element_type":"tb"},"t2":{"name":"_Bool","kind":"typedef","size":1,"base_type":"tc"},"t3":{"name":"uint32_t","kind":"typedef","size":4,"base_type":"td"},"t4":{"name":"uint8_t","kind":"typedef","size":1,"base_type":"te"},"t5":{"kind":"pointer","size":4,"element_type":"t7"},"t6":{"is_signed":true,"name":"int","size":4,"kind":"integer"},"t7":{"is_signed":false,"name":"unsigned int","size":4,"kind":"integer"},"t8":{"kind":"pointer","size":4,"element_type":"t9"},"t9":{"kind":"pointer","size":4,"element_type":"tf"},"ta":{"kind":"pointer","size":4,"element_type":"t10"},"tb":{"name":"bl_acq_adc_t","kind":"typedef","size":8268,"base_type":"t11"},"tc":{"is_signed":false,"name":"bool","size":1,"kind":"boolean"},"td":{"is_signed":false,"name":"unsigned int","size":4,"kind":"integer"},"te":{"is_signed":false,"name":"unsigned char","size":1,"kind":"integer"},"tf":{"kind":"function","return_type":"t0","is_variadic":false,"is_noreturn":false,"calling_convention":"unknown","parameter_types":["t1","ta"]},"t10":{"name":"uint16_t","kind":"typedef","size":2,"base_type":"t12"},"t11":{"name":"bl_acq_adc_s","kind":"struct","size":8268,"fields":[{"type":"t13","offset":0,"name":"group"},{"type":"t3","offset":4,"name":"base"},{"type":"t14","offset":8,"name":"timer"},{"type":"t3","offset":12,"name":"extsel"},{"type":"t15","offset":16,"name":"dma"},{"type":"t4","offset":20,"name":"dma_channel"},{"type":"t4","offset":21,"name":"dmamux_req"},{"type":"t10","offset":22,"name":"irq"},{"type":"t7","offset":24,"name":"enable"},{"type":"t2","offset":28,"name":"flash_enable"},{"type":"t2","offset":29,"name":"flash_master"},{"type":"t4","offset":30,"name":"flash_index"},{"type":"t2","offset":31,"name":"calibrated"},{"type":"t3","offset":32,"name":"calfact"},{"type":"t7","offset":36,"name":"samples_per_dma"},{"type":"t16","offset":40,"name":"dma_buffer"},{"type":"t9","offset":8232,"name":"isr"},{"type":"t17","offset":8236,"name":"config"}]},"t12":{"is_signed":false,"name":"unsigned short","size":2,"kind":"integer"},"t13":{"kind":"pointer","size":4,"element_type":"t18"},"t14":{"kind":"pointer","size":4,"element_type":"t19"},"t15":{"kind":"pointer","size":4,"element_type":"t1a"},"t16":{"kind":"array","size":8192,"num_elements":4096,"element_type":"t10"},"t17":{"name":"bl_acq_adc_config_t","kind":"struct","size":32,"fields":[{"type":"t7","offset":0,"name":"channel_count"},{"type":"t1b","offset":4,"name":"src_mask"},{"type":"t1b","offset":11,"name":"channel_adc"},{"type":"t1b","offset":18,"name":"channel_source"},{"type":"t1b","offset":25,"name":"smp"}]},"t18":{"name":"bl_acq_adc_group_t","kind":"typedef","size":28,"base_type":"t1c"},"t19":{"kind":"pointer","size":4,"element_type":"t1d"},"t1a":{"kind":"pointer","size":4,"element_type":"t1e"},"t1b":{"kind":"array","size":7,"num_elements":7,"element_type":"t4"},"t1c":{"name":"bl_acq_adc_group_s","kind":"struct","size":28,"fields":[{"type":"t3","offset":0,"name":"rcc_unit"},{"type":"t3","offset":4,"name":"master"},{"type":"t4","offset":8,"name":"presc_shift"},{"type":"t7","offset":12,"name":"enable"},{"type":"t1f","offset":16,"name":"config"}]},"t1d":{"name":"bl_acq_timer_t","kind":"typedef","size":24,"base_type":"t20"},"t1e":{"name":"bl_acq_dma_t","kind":"typedef","size":12,"base_type":"t21"},"t1f":{"name":"bl_acq_adc_group_config_t","kind":"struct","size":12,"fields":[{"type":"t3","offset":0,"name":"ckmode"},{"type":"t3","offset":4,"name":"presc"},{"type":"t3","offset":8,"name":"frequency"}]},"t20":{"name":"bl_acq_timer_s","kind":"struct","size":24,"fields":[{"type":"t3","offset":0,"name":"rcc_unit"},{"type":"t3","offset":4,"name":"base"},{"type":"t3","offset":8,"name":"frequency"},{"type":"t7","offset":12,"name":"enable"},{"type":"t22","offset":16,"name":"config"}]},"t21":{"name":"bl_acq_dma_s","kind":"struct","size":12,"fields":[{"type":"t3","offset":0,"name":"rcc_unit"},{"type":"t3","offset":4,"name":"base"},{"type":"t2","offset":8,"name":"enable"},{"type":"t4","offset":9,"name":"channel_mask"}]},"t22":{"name":"bl_acq_timer_config_t","kind":"struct","size":8,"fields":[{"type":"t3","offset":0,"name":"prescale"},{"type":"t3","offset":4,"name":"period"}]}}}

0 commit comments

Comments
 (0)