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
4.2 kB 125 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->kind == TOBI_IR_INTEGER || n->kind == TOBI_IR_PACKAGE || n->kind == TOBI_IR_FIELD || 39 n->kind == TOBI_IR_FIELD_ELEM || n->kind == TOBI_IR_CALL || n->kind == TOBI_IR_OPREGION || 40 n->kind == TOBI_IR_RESOURCE) { 41 comma(sb, &first); 42 tobi_sb_printf(sb, "\"value\":%llu", (unsigned long long)n->value); 43 } 44 if (n->raw_op) { 45 comma(sb, &first); 46 tobi_sb_printf(sb, "\"raw_opcode\":%u", n->raw_op); 47 } 48 if (n->kind == TOBI_IR_METHOD) { 49 comma(sb, &first); 50 tobi_sb_printf(sb, "\"args\":%u", n->method_args); 51 comma(sb, &first); 52 tobi_sb_printf(sb, "\"serialized\":%s", n->method_serialized ? "true" : "false"); 53 comma(sb, &first); 54 tobi_sb_printf(sb, "\"sync\":%u", n->method_sync); 55 } 56 comma(sb, &first); 57 tobi_sb_add(sb, "\"children\":["); 58 for (size_t i = 0; i < n->child_len; i++) { 59 if (i) { 60 tobi_sb_ch(sb, ','); 61 } 62 node(sb, n->child[i]); 63 } 64 tobi_sb_add(sb, "]}"); 65} 66 67static void namespace_emit(tobi_sb *sb, const tobi_parse_result *res) { 68 tobi_sb_add(sb, "\"namespace\":["); 69 for (size_t i = 0; i < res->ns.len; i++) { 70 const tobi_ns_ent *e = &res->ns.items[i]; 71 if (i) { 72 tobi_sb_ch(sb, ','); 73 } 74 tobi_sb_add(sb, "{\"kind\":"); 75 tobi_json_string(sb, tobi_ns_kind_name(e->kind)); 76 tobi_sb_add(sb, ",\"path\":"); 77 tobi_json_string(sb, e->path); 78 tobi_sb_add(sb, ",\"name\":"); 79 tobi_json_string(sb, e->name); 80 tobi_sb_add(sb, ",\"owner\":"); 81 tobi_json_string(sb, e->owner); 82 tobi_sb_printf(sb, ",\"offset\":%zu,\"args\":%u,\"flags\":%u,\"external\":%s", 83 e->off, e->args, e->flags, e->external ? "true" : "false"); 84 if (e->target) { 85 tobi_sb_add(sb, ",\"target\":"); 86 tobi_json_string(sb, e->target); 87 } 88 tobi_sb_ch(sb, '}'); 89 } 90 tobi_sb_ch(sb, ']'); 91} 92 93char *tobi_js_emit(const tobi_parse_result *res) { 94 tobi_sb sb; 95 tobi_sb_init(&sb); 96 tobi_sb_add(&sb, "{\"meta\":{"); 97 tobi_sb_printf(&sb, "\"is_table\":%s,", res->meta.is_table ? "true" : "false"); 98 tobi_sb_add(&sb, "\"signature\":"); 99 tobi_json_string(&sb, res->meta.signature); 100 tobi_sb_printf(&sb, ",\"table_length\":%zu,\"aml_offset\":%zu,\"aml_length\":%zu," 101 "\"checksum_sum\":%u,\"checksum_valid\":%s},", 102 res->meta.table_len, res->meta.aml_off, res->meta.aml_len, 103 (unsigned)res->meta.checksum_sum, res->meta.checksum_valid ? "true" : "false"); 104 tobi_sb_add(&sb, "\"diagnostics\":["); 105 for (size_t i = 0; i < res->diag.len; i++) { 106 if (i) { 107 tobi_sb_ch(&sb, ','); 108 } 109 tobi_sb_printf(&sb, "{\"level\":"); 110 tobi_json_string(&sb, tobi_diag_level_name(res->diag.items[i].level)); 111 tobi_sb_printf(&sb, ",\"offset\":%zu,\"message\":", res->diag.items[i].off); 112 tobi_json_string(&sb, res->diag.items[i].msg); 113 tobi_sb_ch(&sb, '}'); 114 } 115 tobi_sb_add(&sb, "],"); 116 namespace_emit(&sb, res); 117 tobi_sb_add(&sb, ",\"ir\":"); 118 if (res->root) { 119 node(&sb, res->root); 120 } else { 121 tobi_sb_add(&sb, "null"); 122 } 123 tobi_sb_add(&sb, "}\n"); 124 return tobi_sb_take(&sb); 125}