ACPI AML decompiler w/ CFG recovery and structured pseudocode
1#include "t.h"
2
3#include "cf.h"
4#include "p.h"
5
6int t_cf(void) {
7 uint8_t ifelse[] = {0x14,0x15,'I','F','E','0',0x01,0xa0,0x06,0x68,0x70,0x0a,0x01,0x60,0xa1,0x05,0x70,0x0a,0x02,0x60,0xa4,0x60};
8 tobi_parse_result r;
9 T_CHECK(tobi_parse(ifelse, sizeof(ifelse), 0, &r));
10 T_CHECK(tobi_cf_recover(r.root, &r.diag));
11 tobi_ir *ifn = r.root->child[0]->child[0]->child[0];
12 T_CHECK(ifn->kind == TOBI_IR_IF && ifn->child_len == 3);
13 char *dot = tobi_cf_dot(r.root);
14 T_STR(dot, "digraph tobi_cfg");
15 T_STR(dot, "then");
16 T_STR(dot, "else");
17 free(dot);
18 tobi_parse_result_free(&r);
19
20 uint8_t wh[] = {0x14,0x20,'W','L','O','0',0x01,0x70,0x0a,0x03,0x60,0xa2,0x13,0x60,0xa0,0x06,0x68,0x70,0x0a,0x01,0x61,0xa1,0x05,0x70,0x0a,0x02,0x61,0x74,0x60,0x01,0x60,0xa4,0x61};
21 T_CHECK(tobi_parse(wh, sizeof(wh), 0, &r));
22 T_CHECK(tobi_cf_recover(r.root, &r.diag));
23 tobi_ir *while_n = r.root->child[0]->child[0]->child[1];
24 T_CHECK(while_n->kind == TOBI_IR_WHILE);
25 T_CHECK(while_n->child[1]->child[0]->kind == TOBI_IR_IF);
26 tobi_parse_result_free(&r);
27
28 uint8_t ll[] = {
29 0x14,0x24,'L','L','0','0',0x01,
30 0x70,0x00,0x60,
31 0x70,0x0a,0x03,0x61,
32 0xa2,0x14,0x61,
33 0xa0,0x06,0x68,0x72,0x60,0x01,0x60,
34 0xa1,0x06,0x72,0x60,0x0a,0x02,0x60,
35 0x74,0x61,0x01,0x61,
36 0xa4,0x60
37 };
38 T_CHECK(tobi_parse(ll, sizeof(ll), 0, &r));
39 T_CHECK(tobi_cf_recover(r.root, &r.diag));
40 tobi_ir *ll_method = r.root->child[0];
41 T_CHECK(ll_method->kind == TOBI_IR_METHOD);
42 T_CHECK(strcmp(ll_method->name, "LL00") == 0);
43 tobi_ir *ll_block = ll_method->child[0];
44 T_CHECK(ll_block->child_len == 4);
45 T_CHECK(ll_block->child[2]->kind == TOBI_IR_WHILE);
46 T_CHECK(ll_block->child[2]->child[1]->child[0]->kind == TOBI_IR_IF);
47 dot = tobi_cf_dot(r.root);
48 T_STR(dot, "LL00");
49 T_STR(dot, "while");
50 T_STR(dot, "back");
51 free(dot);
52 dot = tobi_graph_dot(r.root, &r.ns, TOBI_GRAPH_AST);
53 T_STR(dot, "digraph tobi_ast");
54 T_STR(dot, "LL00");
55 T_STR(dot, "expr");
56 free(dot);
57 dot = tobi_graph_dot(r.root, &r.ns, TOBI_GRAPH_NAMESPACE);
58 T_STR(dot, "digraph tobi_namespace");
59 T_STR(dot, "LL00");
60 T_STR(dot, "method");
61 free(dot);
62 tobi_parse_result_free(&r);
63
64 uint8_t amb[] = {0xa0,0x03,0x01,0xa1};
65 T_CHECK(tobi_parse(amb, sizeof(amb), 0, &r));
66 T_CHECK(r.root->child_len == 1);
67 T_CHECK(r.root->child[0]->kind == TOBI_IR_IF);
68 T_CHECK(tobi_ir_find_child(r.root->child[0]->child[1], TOBI_IR_UNKNOWN) != NULL);
69 T_CHECK(tobi_cf_recover(r.root, &r.diag));
70 T_CHECK(tobi_ir_find_child(r.root->child[0]->child[1], TOBI_IR_DIAG) != NULL);
71 tobi_parse_result_free(&r);
72 return 0;
73}