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 / js.c
6.1 kB 169 lines
1#include "js.h" 2 3#include "str.h" 4 5static void comma(tobi_sb *sb, int *first) { 6 if (*first) { 7 *first = 0; 8 } else { 9 tobi_sb_ch(sb, ','); 10 } 11} 12 13static void node(tobi_sb *sb, const tobi_ir *n) { 14 int first = 1; 15 tobi_sb_ch(sb, '{'); 16 comma(sb, &first); 17 tobi_sb_add(sb, "\"kind\":"); 18 tobi_json_string(sb, tobi_ir_kind_name(n->kind)); 19 comma(sb, &first); 20 tobi_sb_printf(sb, "\"id\":%zu", n->id); 21 if (n->parent_id != 0) { 22 comma(sb, &first); 23 tobi_sb_printf(sb, "\"parent_id\":%zu", n->parent_id); 24 comma(sb, &first); 25 tobi_sb_printf(sb, "\"parent_index\":%zu", n->parent_index); 26 } 27 comma(sb, &first); 28 tobi_sb_printf(sb, "\"offset\":%zu", n->off); 29 comma(sb, &first); 30 tobi_sb_printf(sb, "\"length\":%zu", n->len); 31 if (n->name) { 32 comma(sb, &first); 33 tobi_sb_add(sb, "\"name\":"); 34 tobi_json_string(sb, n->name); 35 } 36 if (n->path) { 37 comma(sb, &first); 38 tobi_sb_add(sb, "\"path\":"); 39 tobi_json_string(sb, n->path); 40 } 41 if (n->scope) { 42 comma(sb, &first); 43 tobi_sb_add(sb, "\"scope\":"); 44 tobi_json_string(sb, n->scope); 45 } 46 if (n->str) { 47 comma(sb, &first); 48 tobi_sb_add(sb, "\"string\":"); 49 tobi_json_string(sb, n->str); 50 } 51 if (n->target) { 52 comma(sb, &first); 53 tobi_sb_add(sb, "\"target\":"); 54 tobi_json_string(sb, n->target); 55 } 56 if (n->kind == TOBI_IR_INTEGER || n->kind == TOBI_IR_PACKAGE || n->kind == TOBI_IR_FIELD || 57 n->kind == TOBI_IR_FIELD_ELEM || n->kind == TOBI_IR_CALL || n->kind == TOBI_IR_OPREGION || 58 n->kind == TOBI_IR_RESOURCE) { 59 comma(sb, &first); 60 tobi_sb_printf(sb, "\"value\":%llu", (unsigned long long)n->value); 61 } 62 if (n->raw_op) { 63 comma(sb, &first); 64 tobi_sb_printf(sb, "\"raw_opcode\":%u", n->raw_op); 65 } 66 if (n->kind == TOBI_IR_METHOD) { 67 comma(sb, &first); 68 tobi_sb_printf(sb, "\"args\":%u", n->method_args); 69 comma(sb, &first); 70 tobi_sb_printf(sb, "\"serialized\":%s", n->method_serialized ? "true" : "false"); 71 comma(sb, &first); 72 tobi_sb_printf(sb, "\"sync\":%u", n->method_sync); 73 } 74 if (n->bit_len || n->access_type || n->lock_rule || n->update_rule) { 75 comma(sb, &first); 76 tobi_sb_printf(sb, "\"bit_offset\":%llu", (unsigned long long)n->bit_off); 77 comma(sb, &first); 78 tobi_sb_printf(sb, "\"bit_length\":%llu", (unsigned long long)n->bit_len); 79 comma(sb, &first); 80 tobi_sb_printf(sb, "\"access_type\":%u", n->access_type); 81 comma(sb, &first); 82 tobi_sb_printf(sb, "\"lock_rule\":%u", n->lock_rule); 83 comma(sb, &first); 84 tobi_sb_printf(sb, "\"update_rule\":%u", n->update_rule); 85 } 86 comma(sb, &first); 87 tobi_sb_add(sb, "\"children\":["); 88 for (size_t i = 0; i < n->child_len; i++) { 89 if (i) { 90 tobi_sb_ch(sb, ','); 91 } 92 node(sb, n->child[i]); 93 } 94 tobi_sb_add(sb, "]}"); 95} 96 97static void namespace_emit(tobi_sb *sb, const tobi_parse_result *res) { 98 tobi_sb_add(sb, "\"namespace\":["); 99 for (size_t i = 0; i < res->ns.len; i++) { 100 const tobi_ns_ent *e = &res->ns.items[i]; 101 if (i) { 102 tobi_sb_ch(sb, ','); 103 } 104 tobi_sb_add(sb, "{\"kind\":"); 105 tobi_json_string(sb, tobi_ns_kind_name(e->kind)); 106 tobi_sb_add(sb, ",\"path\":"); 107 tobi_json_string(sb, e->path); 108 tobi_sb_add(sb, ",\"name\":"); 109 tobi_json_string(sb, e->name); 110 tobi_sb_add(sb, ",\"owner\":"); 111 tobi_json_string(sb, e->owner); 112 tobi_sb_printf(sb, ",\"offset\":%zu,\"args\":%u,\"flags\":%u,\"external\":%s", 113 e->off, e->args, e->flags, e->external ? "true" : "false"); 114 if (e->target) { 115 tobi_sb_add(sb, ",\"target\":"); 116 tobi_json_string(sb, e->target); 117 } 118 tobi_sb_ch(sb, '}'); 119 } 120 tobi_sb_ch(sb, ']'); 121} 122 123char *tobi_js_emit(const tobi_parse_result *res) { 124 tobi_sb sb; 125 tobi_sb_init(&sb); 126 tobi_sb_add(&sb, "{\"meta\":{"); 127 tobi_sb_printf(&sb, "\"is_table\":%s,", res->meta.is_table ? "true" : "false"); 128 tobi_sb_add(&sb, "\"source\":"); 129 tobi_json_string(&sb, res->meta.source); 130 tobi_sb_add(&sb, ","); 131 tobi_sb_add(&sb, "\"signature\":"); 132 tobi_json_string(&sb, res->meta.signature); 133 tobi_sb_printf(&sb, ",\"table_length\":%zu,\"aml_offset\":%zu,\"aml_length\":%zu," 134 "\"revision\":%u,\"checksum_byte\":%u,\"checksum_sum\":%u," 135 "\"checksum_valid\":%s,\"header_hash\":%u,\"aml_hash\":%u,", 136 res->meta.table_len, res->meta.aml_off, res->meta.aml_len, 137 (unsigned)res->meta.revision, (unsigned)res->meta.checksum_byte, 138 (unsigned)res->meta.checksum_sum, res->meta.checksum_valid ? "true" : "false", 139 res->meta.header_hash, res->meta.aml_hash); 140 tobi_sb_add(&sb, "\"oem_id\":"); 141 tobi_json_string(&sb, res->meta.oem_id); 142 tobi_sb_add(&sb, ",\"oem_table_id\":"); 143 tobi_json_string(&sb, res->meta.oem_table_id); 144 tobi_sb_printf(&sb, ",\"oem_revision\":%u,", res->meta.oem_revision); 145 tobi_sb_add(&sb, "\"creator_id\":"); 146 tobi_json_string(&sb, res->meta.creator_id); 147 tobi_sb_printf(&sb, ",\"creator_revision\":%u},", res->meta.creator_revision); 148 tobi_sb_add(&sb, "\"diagnostics\":["); 149 for (size_t i = 0; i < res->diag.len; i++) { 150 if (i) { 151 tobi_sb_ch(&sb, ','); 152 } 153 tobi_sb_printf(&sb, "{\"level\":"); 154 tobi_json_string(&sb, tobi_diag_level_name(res->diag.items[i].level)); 155 tobi_sb_printf(&sb, ",\"offset\":%zu,\"message\":", res->diag.items[i].off); 156 tobi_json_string(&sb, res->diag.items[i].msg); 157 tobi_sb_ch(&sb, '}'); 158 } 159 tobi_sb_add(&sb, "],"); 160 namespace_emit(&sb, res); 161 tobi_sb_add(&sb, ",\"ir\":"); 162 if (res->root) { 163 node(&sb, res->root); 164 } else { 165 tobi_sb_add(&sb, "null"); 166 } 167 tobi_sb_add(&sb, "}\n"); 168 return tobi_sb_take(&sb); 169}