ACPI AML decompiler w/ CFG recovery and structured pseudocode
1#include "rd.h"
2
3#include <string.h>
4
5void tobi_rd_init(tobi_rd *rd, const uint8_t *data, size_t len, size_t base) {
6 rd->data = data;
7 rd->len = len;
8 rd->pos = 0;
9 rd->base = base;
10 rd->failed = 0;
11}
12
13size_t tobi_rd_off(const tobi_rd *rd) {
14 return rd->base + rd->pos;
15}
16
17size_t tobi_rd_left(const tobi_rd *rd) {
18 return rd->pos <= rd->len ? rd->len - rd->pos : 0;
19}
20
21int tobi_rd_u8(tobi_rd *rd, uint8_t *out) {
22 if (rd->pos >= rd->len) {
23 rd->failed = 1;
24 return 0;
25 }
26 *out = rd->data[rd->pos++];
27 return 1;
28}
29
30int tobi_rd_peek(const tobi_rd *rd, uint8_t *out) {
31 if (rd->pos >= rd->len) {
32 return 0;
33 }
34 *out = rd->data[rd->pos];
35 return 1;
36}
37
38int tobi_rd_u16(tobi_rd *rd, uint16_t *out) {
39 uint8_t b[2];
40 if (!tobi_rd_bytes(rd, b, sizeof(b))) {
41 return 0;
42 }
43 *out = (uint16_t)b[0] | ((uint16_t)b[1] << 8);
44 return 1;
45}
46
47int tobi_rd_u32(tobi_rd *rd, uint32_t *out) {
48 uint8_t b[4];
49 if (!tobi_rd_bytes(rd, b, sizeof(b))) {
50 return 0;
51 }
52 *out = (uint32_t)b[0] | ((uint32_t)b[1] << 8) | ((uint32_t)b[2] << 16) | ((uint32_t)b[3] << 24);
53 return 1;
54}
55
56int tobi_rd_u64(tobi_rd *rd, uint64_t *out) {
57 uint8_t b[8];
58 if (!tobi_rd_bytes(rd, b, sizeof(b))) {
59 return 0;
60 }
61 uint64_t v = 0;
62 for (size_t i = 0; i < 8; i++) {
63 v |= (uint64_t)b[i] << (i * 8);
64 }
65 *out = v;
66 return 1;
67}
68
69int tobi_rd_bytes(tobi_rd *rd, uint8_t *out, size_t n) {
70 if (n > tobi_rd_left(rd)) {
71 rd->failed = 1;
72 return 0;
73 }
74 if (n != 0) {
75 memcpy(out, rd->data + rd->pos, n);
76 }
77 rd->pos += n;
78 return 1;
79}
80
81int tobi_rd_skip(tobi_rd *rd, size_t n) {
82 if (n > tobi_rd_left(rd)) {
83 rd->failed = 1;
84 return 0;
85 }
86 rd->pos += n;
87 return 1;
88}
89
90int tobi_rd_sub(tobi_rd *rd, size_t n, tobi_rd *sub) {
91 if (n > tobi_rd_left(rd)) {
92 rd->failed = 1;
93 return 0;
94 }
95 tobi_rd_init(sub, rd->data + rd->pos, n, rd->base + rd->pos);
96 rd->pos += n;
97 return 1;
98}
99
100int tobi_rd_pkg_len(tobi_rd *rd, size_t *pkg_len, size_t *encoded_len) {
101 size_t start = rd->pos;
102 uint8_t lead = 0;
103 if (!tobi_rd_u8(rd, &lead)) {
104 return 0;
105 }
106 unsigned follow = lead >> 6;
107 size_t len = 0;
108 if (follow == 0) {
109 len = (size_t)(lead & 0x3f);
110 } else {
111 len = (size_t)(lead & 0x0f);
112 for (unsigned i = 0; i < follow; i++) {
113 uint8_t b = 0;
114 if (!tobi_rd_u8(rd, &b)) {
115 rd->pos = start;
116 rd->failed = 1;
117 return 0;
118 }
119 len |= (size_t)b << (4 + 8 * i);
120 }
121 }
122 *pkg_len = len;
123 *encoded_len = rd->pos - start;
124 return 1;
125}