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
7.3 kB 204 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->has_source && n->source) { 57 comma(sb, &first); 58 tobi_sb_add(sb, "\"source\":"); 59 tobi_json_string(sb, n->source); 60 comma(sb, &first); 61 tobi_sb_printf(sb, "\"input_index\":%zu", n->input_index); 62 } 63 if (n->kind == TOBI_IR_INTEGER || n->kind == TOBI_IR_PACKAGE || n->kind == TOBI_IR_FIELD || 64 n->kind == TOBI_IR_FIELD_ELEM || n->kind == TOBI_IR_CALL || n->kind == TOBI_IR_OPREGION || 65 n->kind == TOBI_IR_RESOURCE) { 66 comma(sb, &first); 67 tobi_sb_printf(sb, "\"value\":%llu", (unsigned long long)n->value); 68 } 69 if (n->raw_op) { 70 comma(sb, &first); 71 tobi_sb_printf(sb, "\"raw_opcode\":%u", n->raw_op); 72 } 73 if (n->kind == TOBI_IR_METHOD) { 74 comma(sb, &first); 75 tobi_sb_printf(sb, "\"args\":%u", n->method_args); 76 comma(sb, &first); 77 tobi_sb_printf(sb, "\"serialized\":%s", n->method_serialized ? "true" : "false"); 78 comma(sb, &first); 79 tobi_sb_printf(sb, "\"sync\":%u", n->method_sync); 80 } 81 if (n->bit_len || n->access_type || n->lock_rule || n->update_rule) { 82 comma(sb, &first); 83 tobi_sb_printf(sb, "\"bit_offset\":%llu", (unsigned long long)n->bit_off); 84 comma(sb, &first); 85 tobi_sb_printf(sb, "\"bit_length\":%llu", (unsigned long long)n->bit_len); 86 comma(sb, &first); 87 tobi_sb_printf(sb, "\"access_type\":%u", n->access_type); 88 comma(sb, &first); 89 tobi_sb_printf(sb, "\"lock_rule\":%u", n->lock_rule); 90 comma(sb, &first); 91 tobi_sb_printf(sb, "\"update_rule\":%u", n->update_rule); 92 } 93 comma(sb, &first); 94 tobi_sb_add(sb, "\"children\":["); 95 for (size_t i = 0; i < n->child_len; i++) { 96 if (i) { 97 tobi_sb_ch(sb, ','); 98 } 99 node(sb, n->child[i]); 100 } 101 tobi_sb_add(sb, "]}"); 102} 103 104static void namespace_emit(tobi_sb *sb, const tobi_parse_result *res) { 105 tobi_sb_add(sb, "\"namespace\":["); 106 for (size_t i = 0; i < res->ns.len; i++) { 107 const tobi_ns_ent *e = &res->ns.items[i]; 108 if (i) { 109 tobi_sb_ch(sb, ','); 110 } 111 tobi_sb_add(sb, "{\"kind\":"); 112 tobi_json_string(sb, tobi_ns_kind_name(e->kind)); 113 tobi_sb_add(sb, ",\"path\":"); 114 tobi_json_string(sb, e->path); 115 tobi_sb_add(sb, ",\"name\":"); 116 tobi_json_string(sb, e->name); 117 tobi_sb_add(sb, ",\"owner\":"); 118 tobi_json_string(sb, e->owner); 119 tobi_sb_printf(sb, ",\"offset\":%zu,\"args\":%u,\"flags\":%u,\"external\":%s", 120 e->off, e->args, e->flags, e->external ? "true" : "false"); 121 if (e->target) { 122 tobi_sb_add(sb, ",\"target\":"); 123 tobi_json_string(sb, e->target); 124 } 125 if (e->has_source && e->source) { 126 tobi_sb_add(sb, ",\"source\":"); 127 tobi_json_string(sb, e->source); 128 tobi_sb_printf(sb, ",\"input_index\":%zu", e->input_index); 129 } 130 tobi_sb_ch(sb, '}'); 131 } 132 tobi_sb_ch(sb, ']'); 133} 134 135static void meta_obj(tobi_sb *sb, const tobi_input_meta *meta) { 136 tobi_sb_ch(sb, '{'); 137 tobi_sb_printf(sb, "\"is_table\":%s,", meta->is_table ? "true" : "false"); 138 tobi_sb_add(sb, "\"source\":"); 139 tobi_json_string(sb, meta->source ? meta->source : "raw"); 140 tobi_sb_add(sb, ",\"signature\":"); 141 tobi_json_string(sb, meta->signature); 142 tobi_sb_printf(sb, ",\"table_length\":%zu,\"aml_offset\":%zu,\"aml_length\":%zu," 143 "\"revision\":%u,\"checksum_byte\":%u,\"checksum_sum\":%u," 144 "\"checksum_valid\":%s,\"header_hash\":%u,\"aml_hash\":%u,", 145 meta->table_len, meta->aml_off, meta->aml_len, 146 (unsigned)meta->revision, (unsigned)meta->checksum_byte, 147 (unsigned)meta->checksum_sum, meta->checksum_valid ? "true" : "false", 148 meta->header_hash, meta->aml_hash); 149 tobi_sb_add(sb, "\"oem_id\":"); 150 tobi_json_string(sb, meta->oem_id); 151 tobi_sb_add(sb, ",\"oem_table_id\":"); 152 tobi_json_string(sb, meta->oem_table_id); 153 tobi_sb_printf(sb, ",\"oem_revision\":%u,", meta->oem_revision); 154 tobi_sb_add(sb, "\"creator_id\":"); 155 tobi_json_string(sb, meta->creator_id); 156 tobi_sb_printf(sb, ",\"creator_revision\":%u}", meta->creator_revision); 157} 158 159static void inputs_emit(tobi_sb *sb, const tobi_parse_result *res) { 160 tobi_sb_add(sb, "\"inputs\":["); 161 for (size_t i = 0; i < res->input_len; i++) { 162 if (i) { 163 tobi_sb_ch(sb, ','); 164 } 165 meta_obj(sb, &res->inputs[i]); 166 } 167 tobi_sb_ch(sb, ']'); 168} 169 170char *tobi_js_emit(const tobi_parse_result *res) { 171 tobi_sb sb; 172 tobi_sb_init(&sb); 173 tobi_sb_add(&sb, "{\"meta\":"); 174 meta_obj(&sb, &res->meta); 175 tobi_sb_ch(&sb, ','); 176 inputs_emit(&sb, res); 177 tobi_sb_ch(&sb, ','); 178 tobi_sb_add(&sb, "\"diagnostics\":["); 179 for (size_t i = 0; i < res->diag.len; i++) { 180 if (i) { 181 tobi_sb_ch(&sb, ','); 182 } 183 tobi_sb_printf(&sb, "{\"level\":"); 184 tobi_json_string(&sb, tobi_diag_level_name(res->diag.items[i].level)); 185 tobi_sb_printf(&sb, ",\"offset\":%zu,\"message\":", res->diag.items[i].off); 186 tobi_json_string(&sb, res->diag.items[i].msg); 187 if (res->diag.items[i].has_source && res->diag.items[i].source) { 188 tobi_sb_add(&sb, ",\"source\":"); 189 tobi_json_string(&sb, res->diag.items[i].source); 190 tobi_sb_printf(&sb, ",\"input_index\":%zu", res->diag.items[i].input_index); 191 } 192 tobi_sb_ch(&sb, '}'); 193 } 194 tobi_sb_add(&sb, "],"); 195 namespace_emit(&sb, res); 196 tobi_sb_add(&sb, ",\"ir\":"); 197 if (res->root) { 198 node(&sb, res->root); 199 } else { 200 tobi_sb_add(&sb, "null"); 201 } 202 tobi_sb_add(&sb, "}\n"); 203 return tobi_sb_take(&sb); 204}