ACPI AML decompiler w/ CFG recovery and structured pseudocode
29

Configure Feed

Select the types of activity you want to include in your feed.

Materialise ACPI resource descriptor templates as typed decoded IR nodes

+124 -3
+1
src/ir.c
··· 67 67 case TOBI_IR_FIELD_ELEM: return "field_elem"; 68 68 case TOBI_IR_MUTEX: return "mutex"; 69 69 case TOBI_IR_EVENT: return "event"; 70 + case TOBI_IR_RESOURCE: return "resource"; 70 71 case TOBI_IR_BUFFER: return "buffer"; 71 72 case TOBI_IR_PACKAGE: return "package"; 72 73 case TOBI_IR_INTEGER: return "integer";
+1
src/ir.h
··· 18 18 TOBI_IR_FIELD_ELEM, 19 19 TOBI_IR_MUTEX, 20 20 TOBI_IR_EVENT, 21 + TOBI_IR_RESOURCE, 21 22 TOBI_IR_BUFFER, 22 23 TOBI_IR_PACKAGE, 23 24 TOBI_IR_INTEGER,
+2 -1
src/js.c
··· 36 36 tobi_json_string(sb, n->str); 37 37 } 38 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) { 39 + n->kind == TOBI_IR_FIELD_ELEM || n->kind == TOBI_IR_CALL || n->kind == TOBI_IR_OPREGION || 40 + n->kind == TOBI_IR_RESOURCE) { 40 41 comma(sb, &first); 41 42 tobi_sb_printf(sb, "\"value\":%llu", (unsigned long long)n->value); 42 43 }
+95 -2
src/p.c
··· 904 904 } 905 905 } 906 906 907 - static char *decode_resource_template(const uint8_t *data, size_t len) { 907 + static uint16_t res_u16(const uint8_t *p) { 908 + return (uint16_t)p[0] | ((uint16_t)p[1] << 8); 909 + } 910 + 911 + static uint32_t res_u32(const uint8_t *p) { 912 + return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24); 913 + } 914 + 915 + static uint64_t res_u64(const uint8_t *p) { 916 + return (uint64_t)res_u32(p) | ((uint64_t)res_u32(p + 4) << 32); 917 + } 918 + 919 + static void add_res_node(tobi_ir *parent, const char *label, size_t off, size_t len, 920 + uint32_t tag, size_t payload_len, const char *detail) { 921 + tobi_ir *r = tobi_ir_new(TOBI_IR_RESOURCE, off, len); 922 + r->raw_op = tag; 923 + r->value = payload_len; 924 + tobi_ir_set_name(r, label); 925 + if (detail) { 926 + tobi_ir_set_str(r, detail); 927 + } 928 + tobi_ir_add(parent, r); 929 + } 930 + 931 + static char *small_res_detail(unsigned name, const uint8_t *p, size_t len) { 932 + tobi_sb sb; 933 + tobi_sb_init(&sb); 934 + if (name == 0x04 && len >= 2) { 935 + tobi_sb_printf(&sb, "irq_mask=0x%x", (unsigned)res_u16(p)); 936 + if (len >= 3) { 937 + tobi_sb_printf(&sb, " flags=0x%x", (unsigned)p[2]); 938 + } 939 + } else if (name == 0x05 && len >= 2) { 940 + tobi_sb_printf(&sb, "dma_mask=0x%x flags=0x%x", (unsigned)p[0], (unsigned)p[1]); 941 + } else if (name == 0x08 && len >= 7) { 942 + tobi_sb_printf(&sb, "decode=0x%x min=0x%x max=0x%x align=%u length=%u", 943 + (unsigned)p[0], (unsigned)res_u16(p + 1), (unsigned)res_u16(p + 3), 944 + (unsigned)p[5], (unsigned)p[6]); 945 + } else if (name == 0x09 && len >= 3) { 946 + tobi_sb_printf(&sb, "base=0x%x length=%u", (unsigned)res_u16(p), (unsigned)p[2]); 947 + } else if (name == 0x0f && len >= 1) { 948 + tobi_sb_printf(&sb, "checksum=0x%x", (unsigned)p[0]); 949 + } else { 950 + tobi_sb_printf(&sb, "bytes=%zu", len); 951 + } 952 + return tobi_sb_take(&sb); 953 + } 954 + 955 + static char *large_res_detail(unsigned name, const uint8_t *p, size_t len) { 956 + tobi_sb sb; 957 + tobi_sb_init(&sb); 958 + if (name == 0x02 && len >= 12) { 959 + tobi_sb_printf(&sb, "space=0x%x width=%u offset=%u access=%u address=0x%x", 960 + (unsigned)p[0], (unsigned)p[1], (unsigned)p[2], (unsigned)p[3], 961 + (unsigned)res_u64(p + 4)); 962 + } else if ((name == 0x05 || name == 0x06) && len >= 9) { 963 + tobi_sb_printf(&sb, "write=0x%x min=0x%x max=0x%x align=0x%x length=0x%x", 964 + (unsigned)p[0], (unsigned)res_u32(p + 1), (unsigned)res_u32(p + 5), 965 + len >= 13 ? (unsigned)res_u32(p + 9) : 0u, 966 + len >= 17 ? (unsigned)res_u32(p + 13) : 0u); 967 + } else if (name == 0x07 && len >= 23) { 968 + tobi_sb_printf(&sb, "rtype=0x%x flags=0x%x gran=0x%x min=0x%x max=0x%x trans=0x%x length=0x%x", 969 + (unsigned)p[0], (unsigned)p[1], (unsigned)res_u32(p + 3), 970 + (unsigned)res_u32(p + 7), (unsigned)res_u32(p + 11), 971 + (unsigned)res_u32(p + 15), (unsigned)res_u32(p + 19)); 972 + } else if (name == 0x08 && len >= 13) { 973 + tobi_sb_printf(&sb, "rtype=0x%x flags=0x%x gran=0x%x min=0x%x max=0x%x", 974 + (unsigned)p[0], (unsigned)p[1], (unsigned)res_u16(p + 3), 975 + (unsigned)res_u16(p + 5), (unsigned)res_u16(p + 7)); 976 + } else if (name == 0x09 && len >= 2) { 977 + unsigned count = len >= 2 ? (unsigned)p[1] : 0u; 978 + tobi_sb_printf(&sb, "flags=0x%x interrupts=%u", (unsigned)p[0], count); 979 + } else if (name == 0x0a && len >= 43) { 980 + tobi_sb_printf(&sb, "rtype=0x%x flags=0x%x gran=0x%llx min=0x%llx max=0x%llx length=0x%llx", 981 + (unsigned)p[0], (unsigned)p[1], (unsigned long long)res_u64(p + 3), 982 + (unsigned long long)res_u64(p + 11), (unsigned long long)res_u64(p + 19), 983 + (unsigned long long)res_u64(p + 35)); 984 + } else if (name == 0x0c && len >= 2) { 985 + tobi_sb_printf(&sb, "revision=%u type=0x%x", (unsigned)p[0], (unsigned)p[1]); 986 + } else if (name == 0x0e && len >= 2) { 987 + tobi_sb_printf(&sb, "revision=%u type=0x%x", (unsigned)p[0], (unsigned)p[1]); 988 + } else { 989 + tobi_sb_printf(&sb, "bytes=%zu", len); 990 + } 991 + return tobi_sb_take(&sb); 992 + } 993 + 994 + static char *decode_resource_template(tobi_ir *parent, const uint8_t *data, size_t len, size_t base) { 908 995 if (!data || len == 0) { 909 996 return NULL; 910 997 } ··· 929 1016 if (!label) { 930 1017 label = "LargeItem"; 931 1018 } 1019 + char *detail = large_res_detail(name, data + pos, item_len); 1020 + add_res_node(parent, label, base + pos - 3u, item_len + 3u, tag, item_len, detail); 1021 + free(detail); 932 1022 if (any) { 933 1023 tobi_sb_add(&sb, "; "); 934 1024 } ··· 945 1035 if (!label) { 946 1036 label = "SmallItem"; 947 1037 } 1038 + char *detail = small_res_detail(name, data + pos, item_len); 1039 + add_res_node(parent, label, base + pos - 1u, item_len + 1u, tag, item_len, detail); 1040 + free(detail); 948 1041 if (any) { 949 1042 tobi_sb_add(&sb, "; "); 950 1043 } ··· 983 1076 const uint8_t *bytes = body.data + body.pos; 984 1077 size_t byte_len = tobi_rd_left(&body); 985 1078 tobi_hex(&hex, bytes, byte_len); 986 - char *res = decode_resource_template(bytes, byte_len); 1079 + char *res = decode_resource_template(n, bytes, byte_len, body.base + body.pos); 987 1080 if (res) { 988 1081 tobi_sb_add(&hex, " resources="); 989 1082 tobi_sb_add(&hex, res);
+11
test/t_js.c
··· 20 20 T_CHECK(strstr(s, ",]") == NULL); 21 21 free(s); 22 22 tobi_parse_result_free(&r); 23 + 24 + uint8_t res[] = {0x11,0x05,0x0a,0x02,0x79,0x00}; 25 + T_CHECK(tobi_parse(res, sizeof(res), 0, &r)); 26 + s = tobi_js_emit(&r); 27 + T_STR(s, "\"kind\":\"resource\""); 28 + T_STR(s, "\"name\":\"EndTag\""); 29 + T_STR(s, "\"string\":\"checksum=0x0\""); 30 + T_CHECK(strstr(s, ",}") == NULL); 31 + T_CHECK(strstr(s, ",]") == NULL); 32 + free(s); 33 + tobi_parse_result_free(&r); 23 34 return 0; 24 35 }
+14
test/t_p.c
··· 63 63 T_CHECK(r.root->child_len == 1); 64 64 T_CHECK(r.root->child[0]->child[0]->kind == TOBI_IR_BUFFER); 65 65 T_STR(r.root->child[0]->child[0]->str, "EndTag"); 66 + T_CHECK(r.root->child[0]->child[0]->child_len == 2); 67 + T_CHECK(r.root->child[0]->child[0]->child[1]->kind == TOBI_IR_RESOURCE); 68 + T_CHECK(strcmp(r.root->child[0]->child[0]->child[1]->name, "EndTag") == 0); 69 + T_STR(r.root->child[0]->child[0]->child[1]->str, "checksum=0x0"); 70 + tobi_parse_result_free(&r); 71 + 72 + uint8_t io_res[] = {0x11,0x0d,0x0a,0x09,0x47,0x01,0x00,0x10,0xff,0x10,0x01,0x08,0x79,0x00}; 73 + T_CHECK(parse_ok(io_res, sizeof(io_res), &r)); 74 + T_CHECK(r.root->child_len == 1); 75 + T_CHECK(r.root->child[0]->kind == TOBI_IR_BUFFER); 76 + T_CHECK(r.root->child[0]->child_len == 3); 77 + T_CHECK(r.root->child[0]->child[1]->kind == TOBI_IR_RESOURCE); 78 + T_CHECK(strcmp(r.root->child[0]->child[1]->name, "IO") == 0); 79 + T_STR(r.root->child[0]->child[1]->str, "min=0x1000"); 66 80 tobi_parse_result_free(&r); 67 81 68 82 uint8_t fld[] = {0x5b,0x80,'R','E','G','0',0x01,0x0a,0x10,0x0a,0x04,0x5b,0x81,0x0b,'R','E','G','0',0x00,'F','L','D','0',0x08};