ACPI AML decompiler w/ CFG recovery and structured pseudocode
1#include "op.h"
2
3#include <stddef.h>
4#include <string.h>
5
6static const tobi_op ops[] = {
7 {0x00, "ZeroOp", TOBI_OP_SIMPLE, 0},
8 {0x01, "OneOp", TOBI_OP_SIMPLE, 0},
9 {0x06, "AliasOp", TOBI_OP_NAMED, 0},
10 {0x08, "NameOp", TOBI_OP_NAMED, 0},
11 {0x0a, "ByteConst", TOBI_OP_SIMPLE, 0},
12 {0x0b, "WordConst", TOBI_OP_SIMPLE, 0},
13 {0x0c, "DWordConst", TOBI_OP_SIMPLE, 0},
14 {0x0d, "StringConst", TOBI_OP_SIMPLE, 0},
15 {0x0e, "QWordConst", TOBI_OP_SIMPLE, 0},
16 {0x10, "ScopeOp", TOBI_OP_PKG, 1},
17 {0x11, "BufferOp", TOBI_OP_PKG, 1},
18 {0x12, "PackageOp", TOBI_OP_PKG, 1},
19 {0x13, "VarPackageOp", TOBI_OP_PKG, 1},
20 {0x14, "MethodOp", TOBI_OP_PKG, 1},
21 {0x15, "ExternalOp", TOBI_OP_NAMED, 0},
22 {0x2e, "DualNamePrefix", TOBI_OP_NAMED, 0},
23 {0x2f, "MultiNamePrefix", TOBI_OP_NAMED, 0},
24 {0x5b, "ExtOpPrefix", TOBI_OP_EXT, 0},
25 {0x60, "Local0", TOBI_OP_SIMPLE, 0},
26 {0x61, "Local1", TOBI_OP_SIMPLE, 0},
27 {0x62, "Local2", TOBI_OP_SIMPLE, 0},
28 {0x63, "Local3", TOBI_OP_SIMPLE, 0},
29 {0x64, "Local4", TOBI_OP_SIMPLE, 0},
30 {0x65, "Local5", TOBI_OP_SIMPLE, 0},
31 {0x66, "Local6", TOBI_OP_SIMPLE, 0},
32 {0x67, "Local7", TOBI_OP_SIMPLE, 0},
33 {0x68, "Arg0", TOBI_OP_SIMPLE, 0},
34 {0x69, "Arg1", TOBI_OP_SIMPLE, 0},
35 {0x6a, "Arg2", TOBI_OP_SIMPLE, 0},
36 {0x6b, "Arg3", TOBI_OP_SIMPLE, 0},
37 {0x6c, "Arg4", TOBI_OP_SIMPLE, 0},
38 {0x6d, "Arg5", TOBI_OP_SIMPLE, 0},
39 {0x6e, "Arg6", TOBI_OP_SIMPLE, 0},
40 {0x70, "StoreOp", TOBI_OP_EXPR, 0},
41 {0x71, "RefOfOp", TOBI_OP_EXPR, 0},
42 {0x72, "AddOp", TOBI_OP_EXPR, 0},
43 {0x73, "ConcatOp", TOBI_OP_EXPR, 0},
44 {0x74, "SubtractOp", TOBI_OP_EXPR, 0},
45 {0x75, "IncrementOp", TOBI_OP_EXPR, 0},
46 {0x76, "DecrementOp", TOBI_OP_EXPR, 0},
47 {0x77, "MultiplyOp", TOBI_OP_EXPR, 0},
48 {0x78, "DivideOp", TOBI_OP_EXPR, 0},
49 {0x79, "ShiftLeftOp", TOBI_OP_EXPR, 0},
50 {0x7a, "ShiftRightOp", TOBI_OP_EXPR, 0},
51 {0x7b, "AndOp", TOBI_OP_EXPR, 0},
52 {0x7c, "NAndOp", TOBI_OP_EXPR, 0},
53 {0x7d, "OrOp", TOBI_OP_EXPR, 0},
54 {0x7e, "NOrOp", TOBI_OP_EXPR, 0},
55 {0x7f, "XorOp", TOBI_OP_EXPR, 0},
56 {0x80, "NotOp", TOBI_OP_EXPR, 0},
57 {0x81, "FindSetLeftBitOp", TOBI_OP_EXPR, 0},
58 {0x82, "FindSetRightBitOp", TOBI_OP_EXPR, 0},
59 {0x83, "DerefOfOp", TOBI_OP_EXPR, 0},
60 {0x84, "ConcatResOp", TOBI_OP_EXPR, 0},
61 {0x85, "ModOp", TOBI_OP_EXPR, 0},
62 {0x86, "NotifyOp", TOBI_OP_EXPR, 0},
63 {0x87, "SizeOfOp", TOBI_OP_EXPR, 0},
64 {0x88, "IndexOp", TOBI_OP_EXPR, 0},
65 {0x89, "MatchOp", TOBI_OP_EXPR, 0},
66 {0x8a, "CreateDWordFieldOp", TOBI_OP_EXPR, 0},
67 {0x8b, "CreateWordFieldOp", TOBI_OP_EXPR, 0},
68 {0x8c, "CreateByteFieldOp", TOBI_OP_EXPR, 0},
69 {0x8d, "CreateBitFieldOp", TOBI_OP_EXPR, 0},
70 {0x8e, "ObjectTypeOp", TOBI_OP_EXPR, 0},
71 {0x8f, "CreateQWordFieldOp", TOBI_OP_EXPR, 0},
72 {0x90, "LAndOp", TOBI_OP_EXPR, 0},
73 {0x91, "LOrOp", TOBI_OP_EXPR, 0},
74 {0x92, "LNotOp", TOBI_OP_EXPR, 0},
75 {0x93, "LEqualOp", TOBI_OP_EXPR, 0},
76 {0x94, "LGreaterOp", TOBI_OP_EXPR, 0},
77 {0x95, "LLessOp", TOBI_OP_EXPR, 0},
78 {0x96, "ToBufferOp", TOBI_OP_EXPR, 0},
79 {0x97, "ToDecimalStringOp", TOBI_OP_EXPR, 0},
80 {0x98, "ToHexStringOp", TOBI_OP_EXPR, 0},
81 {0x99, "ToIntegerOp", TOBI_OP_EXPR, 0},
82 {0x9c, "ToStringOp", TOBI_OP_EXPR, 0},
83 {0x9d, "CopyObjectOp", TOBI_OP_EXPR, 0},
84 {0x9e, "MidOp", TOBI_OP_EXPR, 0},
85 {0x9f, "ContinueOp", TOBI_OP_CONTROL, 0},
86 {0xa0, "IfOp", TOBI_OP_CONTROL, 1},
87 {0xa1, "ElseOp", TOBI_OP_CONTROL, 1},
88 {0xa2, "WhileOp", TOBI_OP_CONTROL, 1},
89 {0xa3, "NoopOp", TOBI_OP_CONTROL, 0},
90 {0xa4, "ReturnOp", TOBI_OP_CONTROL, 0},
91 {0xa5, "BreakOp", TOBI_OP_CONTROL, 0},
92 {0xcc, "BreakPointOp", TOBI_OP_CONTROL, 0},
93 {0xff, "OnesOp", TOBI_OP_SIMPLE, 0},
94};
95
96static const tobi_op ext_ops[] = {
97 {0x5b01, "MutexOp", TOBI_OP_EXT, 0},
98 {0x5b02, "EventOp", TOBI_OP_EXT, 0},
99 {0x5b12, "CondRefOfOp", TOBI_OP_EXT, 0},
100 {0x5b13, "CreateFieldOp", TOBI_OP_EXT, 0},
101 {0x5b1f, "LoadTableOp", TOBI_OP_EXT, 0},
102 {0x5b20, "LoadOp", TOBI_OP_EXT, 0},
103 {0x5b21, "StallOp", TOBI_OP_EXT, 0},
104 {0x5b22, "SleepOp", TOBI_OP_EXT, 0},
105 {0x5b23, "AcquireOp", TOBI_OP_EXT, 0},
106 {0x5b24, "SignalOp", TOBI_OP_EXT, 0},
107 {0x5b25, "WaitOp", TOBI_OP_EXT, 0},
108 {0x5b26, "ResetOp", TOBI_OP_EXT, 0},
109 {0x5b27, "ReleaseOp", TOBI_OP_EXT, 0},
110 {0x5b28, "FromBCDOp", TOBI_OP_EXT, 0},
111 {0x5b29, "ToBCDOp", TOBI_OP_EXT, 0},
112 {0x5b2a, "UnloadOp", TOBI_OP_EXT, 0},
113 {0x5b30, "RevisionOp", TOBI_OP_EXT, 0},
114 {0x5b31, "DebugOp", TOBI_OP_EXT, 0},
115 {0x5b32, "FatalOp", TOBI_OP_EXT, 0},
116 {0x5b33, "TimerOp", TOBI_OP_EXT, 0},
117 {0x5b80, "OpRegionOp", TOBI_OP_EXT, 0},
118 {0x5b81, "FieldOp", TOBI_OP_EXT, 1},
119 {0x5b82, "DeviceOp", TOBI_OP_EXT, 1},
120 {0x5b83, "ProcessorOp", TOBI_OP_EXT, 1},
121 {0x5b84, "PowerResOp", TOBI_OP_EXT, 1},
122 {0x5b85, "ThermalZoneOp", TOBI_OP_EXT, 1},
123 {0x5b86, "IndexFieldOp", TOBI_OP_EXT, 1},
124 {0x5b87, "BankFieldOp", TOBI_OP_EXT, 1},
125 {0x5b88, "DataRegionOp", TOBI_OP_EXT, 0},
126};
127
128static const tobi_op_desc descs[] = {
129 {0x06, "NameString NameString"},
130 {0x08, "NameString DataRef"},
131 {0x0a, "ByteData"},
132 {0x0b, "WordData"},
133 {0x0c, "DWordData"},
134 {0x0d, "StringData"},
135 {0x0e, "QWordData"},
136 {0x10, "PkgLength NameString TermList"},
137 {0x11, "PkgLength BufferSize ByteList"},
138 {0x12, "PkgLength NumElements PackageElements"},
139 {0x13, "PkgLength VarNumElements PackageElements"},
140 {0x14, "PkgLength NameString MethodFlags TermList"},
141 {0x15, "NameString ObjectType ArgumentCount"},
142 {0x70, "TermArg SuperName"},
143 {0x71, "SuperName"},
144 {0x72, "TermArg TermArg Target"},
145 {0x73, "Data TermArg Target"},
146 {0x74, "TermArg TermArg Target"},
147 {0x75, "SuperName"},
148 {0x76, "SuperName"},
149 {0x77, "TermArg TermArg Target"},
150 {0x78, "TermArg TermArg Target RemainderTarget"},
151 {0x79, "TermArg TermArg Target"},
152 {0x7a, "TermArg TermArg Target"},
153 {0x7b, "TermArg TermArg Target"},
154 {0x7c, "TermArg TermArg Target"},
155 {0x7d, "TermArg TermArg Target"},
156 {0x7e, "TermArg TermArg Target"},
157 {0x7f, "TermArg TermArg Target"},
158 {0x80, "TermArg Target"},
159 {0x81, "TermArg Target"},
160 {0x82, "TermArg Target"},
161 {0x83, "TermArg"},
162 {0x84, "Data Buffer Target"},
163 {0x85, "TermArg TermArg Target"},
164 {0x86, "SuperName TermArg"},
165 {0x87, "SuperName"},
166 {0x88, "SuperName TermArg Target"},
167 {0x89, "SearchPkg MatchOp1 MatchObj1 MatchOp2 MatchObj2 StartIndex"},
168 {0x8a, "SourceBuff BitIndex NameString"},
169 {0x8b, "SourceBuff BitIndex NameString"},
170 {0x8c, "SourceBuff ByteIndex NameString"},
171 {0x8d, "SourceBuff BitIndex NameString"},
172 {0x8e, "SuperName"},
173 {0x8f, "SourceBuff BitIndex NameString"},
174 {0x90, "TermArg TermArg"},
175 {0x91, "TermArg TermArg"},
176 {0x92, "TermArg"},
177 {0x93, "TermArg TermArg"},
178 {0x94, "TermArg TermArg"},
179 {0x95, "TermArg TermArg"},
180 {0x96, "TermArg Target"},
181 {0x97, "TermArg Target"},
182 {0x98, "TermArg Target"},
183 {0x99, "TermArg Target"},
184 {0x9c, "TermArg LengthArg Target"},
185 {0x9d, "SimpleName Target"},
186 {0x9e, "TermArg TermArg TermArg Target"},
187 {0x9f, ""},
188 {0xa0, "PkgLength Predicate TermList"},
189 {0xa1, "PkgLength TermList"},
190 {0xa2, "PkgLength Predicate TermList"},
191 {0xa4, "TermArg"},
192 {0xa5, ""},
193 {0x5b01, "NameString SyncFlags"},
194 {0x5b02, "NameString"},
195 {0x5b12, "SuperName Target"},
196 {0x5b13, "SourceBuff BitIndex NumBits NameString"},
197 {0x5b1f, "Signature OemId OemTableId RootPath ParameterPath Target"},
198 {0x5b20, "NameString Target"},
199 {0x5b21, "TermArg"},
200 {0x5b22, "TermArg"},
201 {0x5b23, "MutexObject Timeout"},
202 {0x5b24, "EventObject"},
203 {0x5b25, "EventObject Timeout"},
204 {0x5b26, "EventObject"},
205 {0x5b27, "MutexObject"},
206 {0x5b28, "TermArg Target"},
207 {0x5b29, "TermArg Target"},
208 {0x5b2a, "Handle"},
209 {0x5b30, ""},
210 {0x5b31, ""},
211 {0x5b32, "FatalType FatalCode FatalArg"},
212 {0x5b33, ""},
213 {0x5b80, "NameString RegionSpace RegionOffset RegionLen"},
214 {0x5b81, "PkgLength NameString FieldFlags FieldList"},
215 {0x5b82, "PkgLength NameString TermList"},
216 {0x5b83, "PkgLength NameString ProcId PblkAddr PblkLen TermList"},
217 {0x5b84, "PkgLength NameString SystemLevel ResourceOrder TermList"},
218 {0x5b85, "PkgLength NameString TermList"},
219 {0x5b86, "PkgLength IndexName DataName FieldFlags FieldList"},
220 {0x5b87, "PkgLength RegionName BankName BankValue FieldFlags FieldList"},
221 {0x5b88, "NameString SignatureString OemIdString OemTableIdString"},
222};
223
224static const tobi_op_expr exprs[] = {
225 {0x71, "ref_of", 1, 0, 0},
226 {0x72, "add", 2, 1, 0},
227 {0x73, "concat", 2, 1, 0},
228 {0x74, "sub", 2, 1, 0},
229 {0x75, "inc", 1, 0, 0},
230 {0x76, "dec", 1, 0, 0},
231 {0x77, "mul", 2, 1, 0},
232 {0x78, "div", 2, 2, 0},
233 {0x79, "shl", 2, 1, 0},
234 {0x7a, "shr", 2, 1, 0},
235 {0x7b, "and", 2, 1, 0},
236 {0x7c, "nand", 2, 1, 0},
237 {0x7d, "or", 2, 1, 0},
238 {0x7e, "nor", 2, 1, 0},
239 {0x7f, "xor", 2, 1, 0},
240 {0x80, "not", 1, 1, 0},
241 {0x81, "find_set_left_bit", 1, 1, 0},
242 {0x82, "find_set_right_bit", 1, 1, 0},
243 {0x83, "deref_of", 1, 0, 0},
244 {0x84, "concat_res", 2, 1, 0},
245 {0x85, "mod", 2, 1, 0},
246 {0x86, "notify", 2, 0, 0},
247 {0x87, "size_of", 1, 0, 0},
248 {0x88, "index", 2, 1, 0},
249 {0x89, "match", 6, 0, 0},
250 {0x8a, "create_dword_field", 2, 0, 1},
251 {0x8b, "create_word_field", 2, 0, 1},
252 {0x8c, "create_byte_field", 2, 0, 1},
253 {0x8d, "create_bit_field", 2, 0, 1},
254 {0x8e, "object_type", 1, 0, 0},
255 {0x8f, "create_qword_field", 2, 0, 1},
256 {0x90, "land", 2, 0, 0},
257 {0x91, "lor", 2, 0, 0},
258 {0x92, "lnot", 1, 0, 0},
259 {0x93, "eq", 2, 0, 0},
260 {0x94, "gt", 2, 0, 0},
261 {0x95, "lt", 2, 0, 0},
262 {0x96, "to_buffer", 1, 1, 0},
263 {0x97, "to_decimal_string", 1, 1, 0},
264 {0x98, "to_hex_string", 1, 1, 0},
265 {0x99, "to_integer", 1, 1, 0},
266 {0x9c, "to_string", 2, 1, 0},
267 {0x9d, "copy_object", 1, 1, 0},
268 {0x9e, "mid", 3, 1, 0},
269 {0x5b12, "cond_ref_of", 1, 1, 0},
270 {0x5b13, "create_field", 3, 0, 1},
271 {0x5b1f, "load_table", 5, 1, 0},
272 {0x5b20, "load", 1, 1, 0},
273 {0x5b21, "stall", 1, 0, 0},
274 {0x5b22, "sleep", 1, 0, 0},
275 {0x5b23, "acquire", 2, 0, 0},
276 {0x5b24, "signal", 1, 0, 0},
277 {0x5b25, "wait", 2, 0, 0},
278 {0x5b26, "reset", 1, 0, 0},
279 {0x5b27, "release", 1, 0, 0},
280 {0x5b28, "from_bcd", 1, 1, 0},
281 {0x5b29, "to_bcd", 1, 1, 0},
282 {0x5b2a, "unload", 1, 0, 0},
283 {0x5b32, "fatal", 3, 0, 0},
284};
285
286const tobi_op *tobi_op_find(uint8_t op) {
287 for (size_t i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) {
288 if (ops[i].code == op) {
289 return &ops[i];
290 }
291 }
292 return NULL;
293}
294
295const tobi_op *tobi_op_find_ext(uint8_t ext) {
296 uint16_t code = (uint16_t)(0x5b00u | ext);
297 return tobi_op_find_code(code);
298}
299
300const tobi_op *tobi_op_find_code(uint16_t code) {
301 if ((code & 0xff00u) == 0x5b00u) {
302 for (size_t i = 0; i < sizeof(ext_ops) / sizeof(ext_ops[0]); i++) {
303 if (ext_ops[i].code == code) {
304 return &ext_ops[i];
305 }
306 }
307 return NULL;
308 }
309 return tobi_op_find((uint8_t)code);
310}
311
312const char *tobi_op_operands(uint16_t code) {
313 for (size_t i = 0; i < sizeof(descs) / sizeof(descs[0]); i++) {
314 if (descs[i].code == code) {
315 return descs[i].operands;
316 }
317 }
318 return NULL;
319}
320
321const tobi_op_expr *tobi_op_expr_find(uint16_t code) {
322 for (size_t i = 0; i < sizeof(exprs) / sizeof(exprs[0]); i++) {
323 if (exprs[i].code == code) {
324 return &exprs[i];
325 }
326 }
327 return NULL;
328}
329
330const tobi_op_expr *tobi_op_expr_find_name(const char *name) {
331 if (!name) {
332 return NULL;
333 }
334 for (size_t i = 0; i < sizeof(exprs) / sizeof(exprs[0]); i++) {
335 if (strcmp(exprs[i].ir_name, name) == 0) {
336 return &exprs[i];
337 }
338 }
339 return NULL;
340}