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