ACPI AML decompiler w/ CFG recovery and structured pseudocode
1#include "ir.h"
2
3#include "mem.h"
4
5#include <stdlib.h>
6
7tobi_ir *tobi_ir_new(tobi_ir_kind kind, size_t off, size_t len) {
8 tobi_ir *n = tobi_xcalloc(1, sizeof(*n));
9 n->kind = kind;
10 n->off = off;
11 n->len = len;
12 return n;
13}
14
15void tobi_ir_free(tobi_ir *node) {
16 if (!node) {
17 return;
18 }
19 for (size_t i = 0; i < node->child_len; i++) {
20 tobi_ir_free(node->child[i]);
21 }
22 free(node->child);
23 free(node->name);
24 free(node->path);
25 free(node->str);
26 free(node);
27}
28
29void tobi_ir_add(tobi_ir *parent, tobi_ir *child) {
30 if (!parent || !child) {
31 return;
32 }
33 if (parent->child_len == parent->child_cap) {
34 parent->child_cap = parent->child_cap ? parent->child_cap * 2 : 4;
35 parent->child = tobi_xrealloc(parent->child, parent->child_cap * sizeof(parent->child[0]));
36 }
37 parent->child[parent->child_len++] = child;
38}
39
40void tobi_ir_set_name(tobi_ir *node, const char *s) {
41 free(node->name);
42 node->name = tobi_xstrdup(s ? s : "");
43}
44
45void tobi_ir_set_path(tobi_ir *node, const char *s) {
46 free(node->path);
47 node->path = tobi_xstrdup(s ? s : "");
48}
49
50void tobi_ir_set_str(tobi_ir *node, const char *s) {
51 free(node->str);
52 node->str = tobi_xstrdup(s ? s : "");
53}
54
55const char *tobi_ir_kind_name(tobi_ir_kind kind) {
56 switch (kind) {
57 case TOBI_IR_ROOT: return "root";
58 case TOBI_IR_BLOCK: return "block";
59 case TOBI_IR_SCOPE: return "scope";
60 case TOBI_IR_DEVICE: return "device";
61 case TOBI_IR_METHOD: return "method";
62 case TOBI_IR_PROCESSOR: return "processor";
63 case TOBI_IR_NAME: return "name";
64 case TOBI_IR_ALIAS: return "alias";
65 case TOBI_IR_OPREGION: return "opregion";
66 case TOBI_IR_FIELD: return "field";
67 case TOBI_IR_FIELD_ELEM: return "field_elem";
68 case TOBI_IR_MUTEX: return "mutex";
69 case TOBI_IR_EVENT: return "event";
70 case TOBI_IR_BUFFER: return "buffer";
71 case TOBI_IR_PACKAGE: return "package";
72 case TOBI_IR_INTEGER: return "integer";
73 case TOBI_IR_STRING: return "string";
74 case TOBI_IR_REF: return "ref";
75 case TOBI_IR_CALL: return "call";
76 case TOBI_IR_EXPR: return "expr";
77 case TOBI_IR_STORE: return "store";
78 case TOBI_IR_RETURN: return "return";
79 case TOBI_IR_IF: return "if";
80 case TOBI_IR_WHILE: return "while";
81 case TOBI_IR_BREAK: return "break";
82 case TOBI_IR_CONTINUE: return "continue";
83 case TOBI_IR_UNKNOWN: return "unknown";
84 case TOBI_IR_DIAG: return "diag";
85 }
86 return "invalid";
87}
88
89tobi_ir *tobi_ir_find_child(tobi_ir *node, tobi_ir_kind kind) {
90 if (!node) {
91 return NULL;
92 }
93 for (size_t i = 0; i < node->child_len; i++) {
94 if (node->child[i]->kind == kind) {
95 return node->child[i];
96 }
97 }
98 return NULL;
99}
100
101size_t tobi_ir_count_kind(const tobi_ir *node, tobi_ir_kind kind) {
102 size_t n = 0;
103 if (!node) {
104 return 0;
105 }
106 for (size_t i = 0; i < node->child_len; i++) {
107 if (node->child[i]->kind == kind) {
108 n++;
109 }
110 }
111 return n;
112}