ACPI AML decompiler w/ CFG recovery and structured pseudocode
29

Configure Feed

Select the types of activity you want to include in your feed.

tobi / src / ir.c
5.2 kB 184 lines
1#include "ir.h" 2 3#include "mem.h" 4 5#include <stdlib.h> 6#include <stdint.h> 7 8tobi_ir *tobi_ir_new(tobi_ir_kind kind, size_t off, size_t len) { 9 tobi_ir *n = tobi_xcalloc(1, sizeof(*n)); 10 n->kind = kind; 11 n->off = off; 12 n->len = len; 13 n->parent_index = SIZE_MAX; 14 return n; 15} 16 17void tobi_ir_free(tobi_ir *node) { 18 if (!node) { 19 return; 20 } 21 for (size_t i = 0; i < node->child_len; i++) { 22 tobi_ir_free(node->child[i]); 23 } 24 free(node->child); 25 free(node->name); 26 free(node->path); 27 free(node->scope); 28 free(node->str); 29 free(node->target); 30 free(node->source); 31 free(node); 32} 33 34void tobi_ir_add(tobi_ir *parent, tobi_ir *child) { 35 if (!parent || !child) { 36 return; 37 } 38 if (parent->child_len == parent->child_cap) { 39 parent->child_cap = tobi_xgrow_cap(parent->child_cap, parent->child_len + 1u, 4u); 40 parent->child = tobi_xrealloc(parent->child, 41 tobi_xmul_size(parent->child_cap, sizeof(parent->child[0]))); 42 } 43 if (parent->has_source && !child->has_source) { 44 tobi_ir_set_source_recursive(child, parent->source, parent->input_index); 45 } 46 child->parent_id = parent->id; 47 child->parent_index = parent->child_len; 48 parent->child[parent->child_len++] = child; 49} 50 51void tobi_ir_assign_ids(tobi_ir *root) { 52 if (!root) { 53 return; 54 } 55 typedef struct frame { 56 tobi_ir *node; 57 size_t parent_id; 58 size_t parent_index; 59 } frame; 60 size_t cap = 64; 61 size_t len = 0; 62 frame *stack = tobi_xcalloc(cap, sizeof(stack[0])); 63 stack[len++] = (frame){root, 0, SIZE_MAX}; 64 size_t next_id = 1; 65 while (len > 0) { 66 frame cur = stack[--len]; 67 cur.node->id = next_id++; 68 cur.node->parent_id = cur.parent_id; 69 cur.node->parent_index = cur.parent_index; 70 for (size_t i = cur.node->child_len; i > 0; i--) { 71 if (len == cap) { 72 cap = tobi_xgrow_cap(cap, len + 1u, 64u); 73 stack = tobi_xrealloc(stack, tobi_xmul_size(cap, sizeof(stack[0]))); 74 } 75 stack[len++] = (frame){cur.node->child[i - 1u], cur.node->id, i - 1u}; 76 } 77 } 78 free(stack); 79} 80 81void tobi_ir_set_name(tobi_ir *node, const char *s) { 82 free(node->name); 83 node->name = tobi_xstrdup(s ? s : ""); 84} 85 86void tobi_ir_set_path(tobi_ir *node, const char *s) { 87 free(node->path); 88 node->path = tobi_xstrdup(s ? s : ""); 89} 90 91void tobi_ir_set_scope(tobi_ir *node, const char *s) { 92 free(node->scope); 93 node->scope = tobi_xstrdup(s ? s : ""); 94} 95 96void tobi_ir_set_str(tobi_ir *node, const char *s) { 97 free(node->str); 98 node->str = tobi_xstrdup(s ? s : ""); 99} 100 101void tobi_ir_set_target(tobi_ir *node, const char *s) { 102 free(node->target); 103 node->target = tobi_xstrdup(s ? s : ""); 104} 105 106void tobi_ir_set_source(tobi_ir *node, const char *s, size_t input_index) { 107 if (!node || !s) { 108 return; 109 } 110 free(node->source); 111 node->source = tobi_xstrdup(s); 112 node->input_index = input_index; 113 node->has_source = 1; 114} 115 116void tobi_ir_set_source_recursive(tobi_ir *node, const char *s, size_t input_index) { 117 if (!node || !s) { 118 return; 119 } 120 tobi_ir_set_source(node, s, input_index); 121 for (size_t i = 0; i < node->child_len; i++) { 122 tobi_ir_set_source_recursive(node->child[i], s, input_index); 123 } 124} 125 126const char *tobi_ir_kind_name(tobi_ir_kind kind) { 127 switch (kind) { 128 case TOBI_IR_ROOT: return "root"; 129 case TOBI_IR_BLOCK: return "block"; 130 case TOBI_IR_SCOPE: return "scope"; 131 case TOBI_IR_DEVICE: return "device"; 132 case TOBI_IR_METHOD: return "method"; 133 case TOBI_IR_PROCESSOR: return "processor"; 134 case TOBI_IR_NAME: return "name"; 135 case TOBI_IR_ALIAS: return "alias"; 136 case TOBI_IR_OPREGION: return "opregion"; 137 case TOBI_IR_FIELD: return "field"; 138 case TOBI_IR_FIELD_ELEM: return "field_elem"; 139 case TOBI_IR_MUTEX: return "mutex"; 140 case TOBI_IR_EVENT: return "event"; 141 case TOBI_IR_RESOURCE: return "resource"; 142 case TOBI_IR_BUFFER: return "buffer"; 143 case TOBI_IR_PACKAGE: return "package"; 144 case TOBI_IR_INTEGER: return "integer"; 145 case TOBI_IR_STRING: return "string"; 146 case TOBI_IR_REF: return "ref"; 147 case TOBI_IR_CALL: return "call"; 148 case TOBI_IR_EXPR: return "expr"; 149 case TOBI_IR_STORE: return "store"; 150 case TOBI_IR_RETURN: return "return"; 151 case TOBI_IR_IF: return "if"; 152 case TOBI_IR_WHILE: return "while"; 153 case TOBI_IR_BREAK: return "break"; 154 case TOBI_IR_CONTINUE: return "continue"; 155 case TOBI_IR_UNKNOWN: return "unknown"; 156 case TOBI_IR_DIAG: return "diag"; 157 } 158 return "invalid"; 159} 160 161tobi_ir *tobi_ir_find_child(tobi_ir *node, tobi_ir_kind kind) { 162 if (!node) { 163 return NULL; 164 } 165 for (size_t i = 0; i < node->child_len; i++) { 166 if (node->child[i]->kind == kind) { 167 return node->child[i]; 168 } 169 } 170 return NULL; 171} 172 173size_t tobi_ir_count_kind(const tobi_ir *node, tobi_ir_kind kind) { 174 size_t n = 0; 175 if (!node) { 176 return 0; 177 } 178 for (size_t i = 0; i < node->child_len; i++) { 179 if (node->child[i]->kind == kind) { 180 n++; 181 } 182 } 183 return n; 184}