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->target);
27 free(node);
28}
29
30void tobi_ir_add(tobi_ir *parent, tobi_ir *child) {
31 if (!parent || !child) {
32 return;
33 }
34 if (parent->child_len == parent->child_cap) {
35 parent->child_cap = parent->child_cap ? parent->child_cap * 2 : 4;
36 parent->child = tobi_xrealloc(parent->child, parent->child_cap * sizeof(parent->child[0]));
37 }
38 parent->child[parent->child_len++] = child;
39}
40
41void tobi_ir_set_name(tobi_ir *node, const char *s) {
42 free(node->name);
43 node->name = tobi_xstrdup(s ? s : "");
44}
45
46void tobi_ir_set_path(tobi_ir *node, const char *s) {
47 free(node->path);
48 node->path = tobi_xstrdup(s ? s : "");
49}
50
51void tobi_ir_set_str(tobi_ir *node, const char *s) {
52 free(node->str);
53 node->str = tobi_xstrdup(s ? s : "");
54}
55
56void tobi_ir_set_target(tobi_ir *node, const char *s) {
57 free(node->target);
58 node->target = tobi_xstrdup(s ? s : "");
59}
60
61const char *tobi_ir_kind_name(tobi_ir_kind kind) {
62 switch (kind) {
63 case TOBI_IR_ROOT: return "root";
64 case TOBI_IR_BLOCK: return "block";
65 case TOBI_IR_SCOPE: return "scope";
66 case TOBI_IR_DEVICE: return "device";
67 case TOBI_IR_METHOD: return "method";
68 case TOBI_IR_PROCESSOR: return "processor";
69 case TOBI_IR_NAME: return "name";
70 case TOBI_IR_ALIAS: return "alias";
71 case TOBI_IR_OPREGION: return "opregion";
72 case TOBI_IR_FIELD: return "field";
73 case TOBI_IR_FIELD_ELEM: return "field_elem";
74 case TOBI_IR_MUTEX: return "mutex";
75 case TOBI_IR_EVENT: return "event";
76 case TOBI_IR_RESOURCE: return "resource";
77 case TOBI_IR_BUFFER: return "buffer";
78 case TOBI_IR_PACKAGE: return "package";
79 case TOBI_IR_INTEGER: return "integer";
80 case TOBI_IR_STRING: return "string";
81 case TOBI_IR_REF: return "ref";
82 case TOBI_IR_CALL: return "call";
83 case TOBI_IR_EXPR: return "expr";
84 case TOBI_IR_STORE: return "store";
85 case TOBI_IR_RETURN: return "return";
86 case TOBI_IR_IF: return "if";
87 case TOBI_IR_WHILE: return "while";
88 case TOBI_IR_BREAK: return "break";
89 case TOBI_IR_CONTINUE: return "continue";
90 case TOBI_IR_UNKNOWN: return "unknown";
91 case TOBI_IR_DIAG: return "diag";
92 }
93 return "invalid";
94}
95
96tobi_ir *tobi_ir_find_child(tobi_ir *node, tobi_ir_kind kind) {
97 if (!node) {
98 return NULL;
99 }
100 for (size_t i = 0; i < node->child_len; i++) {
101 if (node->child[i]->kind == kind) {
102 return node->child[i];
103 }
104 }
105 return NULL;
106}
107
108size_t tobi_ir_count_kind(const tobi_ir *node, tobi_ir_kind kind) {
109 size_t n = 0;
110 if (!node) {
111 return 0;
112 }
113 for (size_t i = 0; i < node->child_len; i++) {
114 if (node->child[i]->kind == kind) {
115 n++;
116 }
117 }
118 return n;
119}