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