1 /** @file
2
3 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
5
6
7 **/
8
9 #include "Edb.h"
10
11 //
12 // Debugger Disasm definition
13 //
14 #define EDB_DISASM_DEFINE(func) \
15 UINTN \
16 func ( \
17 IN EFI_PHYSICAL_ADDRESS InstructionAddress, \
18 IN EFI_SYSTEM_CONTEXT SystemContext, \
19 OUT CHAR16 **DisasmString \
20 )
21
22 EDB_DISASM_DEFINE (EdbDisasmBREAK);
23 EDB_DISASM_DEFINE (EdbDisasmJMP);
24 EDB_DISASM_DEFINE (EdbDisasmJMP8);
25 EDB_DISASM_DEFINE (EdbDisasmCALL);
26 EDB_DISASM_DEFINE (EdbDisasmRET);
27 EDB_DISASM_DEFINE (EdbDisasmCMP);
28 EDB_DISASM_DEFINE (EdbDisasmUnsignedDataManip);
29 EDB_DISASM_DEFINE (EdbDisasmSignedDataManip);
30 EDB_DISASM_DEFINE (EdbDisasmMOVxx);
31 EDB_DISASM_DEFINE (EdbDisasmMOVsnw);
32 EDB_DISASM_DEFINE (EdbDisasmMOVsnd);
33 EDB_DISASM_DEFINE (EdbDisasmLOADSP);
34 EDB_DISASM_DEFINE (EdbDisasmSTORESP);
35 EDB_DISASM_DEFINE (EdbDisasmPUSH);
36 EDB_DISASM_DEFINE (EdbDisasmPOP);
37 EDB_DISASM_DEFINE (EdbDisasmCMPI);
38 EDB_DISASM_DEFINE (EdbDisasmPUSHn);
39 EDB_DISASM_DEFINE (EdbDisasmPOPn);
40 EDB_DISASM_DEFINE (EdbDisasmMOVI);
41 EDB_DISASM_DEFINE (EdbDisasmMOVIn);
42 EDB_DISASM_DEFINE (EdbDisasmMOVREL);
43
44 //
45 // Debugger Disasm Table
46 //
47 EDB_DISASM_INSTRUCTION mEdbDisasmInstructionTable[] = {
48 EdbDisasmBREAK, // opcode 0x00 BREAK
49 EdbDisasmJMP, // opcode 0x01 JMP
50 EdbDisasmJMP8, // opcode 0x02 JMP8
51 EdbDisasmCALL, // opcode 0x03 CALL
52 EdbDisasmRET, // opcode 0x04 RET
53 EdbDisasmCMP, // opcode 0x05 CMPEQ
54 EdbDisasmCMP, // opcode 0x06 CMPLTE
55 EdbDisasmCMP, // opcode 0x07 CMPGTE
56 EdbDisasmCMP, // opcode 0x08 CMPULTE
57 EdbDisasmCMP, // opcode 0x09 CMPUGTE
58 EdbDisasmUnsignedDataManip, // opcode 0x0A NOT
59 EdbDisasmSignedDataManip, // opcode 0x0B NEG
60 EdbDisasmSignedDataManip, // opcode 0x0C ADD
61 EdbDisasmSignedDataManip, // opcode 0x0D SUB
62 EdbDisasmSignedDataManip, // opcode 0x0E MUL
63 EdbDisasmUnsignedDataManip, // opcode 0x0F MULU
64 EdbDisasmSignedDataManip, // opcode 0x10 DIV
65 EdbDisasmUnsignedDataManip, // opcode 0x11 DIVU
66 EdbDisasmSignedDataManip, // opcode 0x12 MOD
67 EdbDisasmUnsignedDataManip, // opcode 0x13 MODU
68 EdbDisasmUnsignedDataManip, // opcode 0x14 AND
69 EdbDisasmUnsignedDataManip, // opcode 0x15 OR
70 EdbDisasmUnsignedDataManip, // opcode 0x16 XOR
71 EdbDisasmUnsignedDataManip, // opcode 0x17 SHL
72 EdbDisasmUnsignedDataManip, // opcode 0x18 SHR
73 EdbDisasmSignedDataManip, // opcode 0x19 ASHR
74 EdbDisasmUnsignedDataManip, // opcode 0x1A EXTNDB
75 EdbDisasmUnsignedDataManip, // opcode 0x1B EXTNDW
76 EdbDisasmUnsignedDataManip, // opcode 0x1C EXTNDD
77 EdbDisasmMOVxx, // opcode 0x1D MOVBW
78 EdbDisasmMOVxx, // opcode 0x1E MOVWW
79 EdbDisasmMOVxx, // opcode 0x1F MOVDW
80 EdbDisasmMOVxx, // opcode 0x20 MOVQW
81 EdbDisasmMOVxx, // opcode 0x21 MOVBD
82 EdbDisasmMOVxx, // opcode 0x22 MOVWD
83 EdbDisasmMOVxx, // opcode 0x23 MOVDD
84 EdbDisasmMOVxx, // opcode 0x24 MOVQD
85 EdbDisasmMOVsnw, // opcode 0x25 MOVSNW
86 EdbDisasmMOVsnd, // opcode 0x26 MOVSND
87 NULL, // opcode 0x27
88 EdbDisasmMOVxx, // opcode 0x28 MOVQQ
89 EdbDisasmLOADSP, // opcode 0x29 LOADSP
90 EdbDisasmSTORESP, // opcode 0x2A STORESP
91 EdbDisasmPUSH, // opcode 0x2B PUSH
92 EdbDisasmPOP, // opcode 0x2C POP
93 EdbDisasmCMPI, // opcode 0x2D CMPIEQ
94 EdbDisasmCMPI, // opcode 0x2E CMPILTE
95 EdbDisasmCMPI, // opcode 0x2F CMPIGTE
96 EdbDisasmCMPI, // opcode 0x30 CMPIULTE
97 EdbDisasmCMPI, // opcode 0x31 CMPIUGTE
98 EdbDisasmMOVxx, // opcode 0x32 MOVNW
99 EdbDisasmMOVxx, // opcode 0x33 MOVND
100 NULL, // opcode 0x34
101 EdbDisasmPUSHn, // opcode 0x35 PUSHN
102 EdbDisasmPOPn, // opcode 0x36 POPN
103 EdbDisasmMOVI, // opcode 0x37 MOVI
104 EdbDisasmMOVIn, // opcode 0x38 MOVIN
105 EdbDisasmMOVREL, // opcode 0x39 MOVREL
106 };
107
108 /**
109
110 Disasm instruction - BREAK.
111
112 @param InstructionAddress - The instruction address
113 @param SystemContext - EBC system context.
114 @param DisasmString - The instruction string
115
116 @return Instruction length
117
118 **/
119 UINTN
EdbDisasmBREAK(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)120 EdbDisasmBREAK (
121 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
122 IN EFI_SYSTEM_CONTEXT SystemContext,
123 OUT CHAR16 **DisasmString
124 )
125 {
126 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_BREAK);
127
128 if (*(UINT8 *)(UINTN)(InstructionAddress + 1) > 6) {
129 return 0;
130 }
131
132 //
133 // Construct Disasm String
134 //
135 if (DisasmString != NULL) {
136 *DisasmString = EdbPreInstructionString ();
137
138 EdbPrintInstructionName (L"BREAK");
139 EdbPrintDatan (*(UINT8 *)(UINTN)(InstructionAddress + 1));
140
141 EdbPostInstructionString ();
142 }
143
144 return 2;
145 }
146
147 extern CONST UINT8 mJMPLen[];
148
149 /**
150
151 Disasm instruction - JMP.
152
153 @param InstructionAddress - The instruction address
154 @param SystemContext - EBC system context.
155 @param DisasmString - The instruction string
156
157 @return Instruction length
158
159 **/
160 UINTN
EdbDisasmJMP(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)161 EdbDisasmJMP (
162 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
163 IN EFI_SYSTEM_CONTEXT SystemContext,
164 OUT CHAR16 **DisasmString
165 )
166 {
167 UINT8 Modifiers;
168 UINT8 Operands;
169 UINTN Size;
170 UINT32 Data32;
171 UINT64 Data64;
172
173 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_JMP);
174
175 Modifiers = GET_MODIFIERS (InstructionAddress);
176 Operands = GET_OPERANDS (InstructionAddress);
177 Size = (UINTN)mJMPLen[(Modifiers >> 6) & 0x03];
178
179 //
180 // Construct Disasm String
181 //
182 if (DisasmString != NULL) {
183 *DisasmString = EdbPreInstructionString ();
184
185 EdbPrintInstructionName (L"JMP");
186 // if (Modifiers & OPCODE_M_IMMDATA64) {
187 // EdbPrintInstructionName (L"64");
188 // } else {
189 // EdbPrintInstructionName (L"32");
190 // }
191 if ((Modifiers & CONDITION_M_CONDITIONAL) != 0) {
192 if ((Modifiers & JMP_M_CS) != 0) {
193 EdbPrintInstructionName (L"cs");
194 } else {
195 EdbPrintInstructionName (L"cc");
196 }
197 }
198
199 InstructionAddress += 2;
200 if ((Modifiers & OPCODE_M_IMMDATA64) != 0) {
201 CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
202 if ((Modifiers & OPCODE_M_IMMDATA) != 0) {
203 EdbPrintData64 (Data64);
204 } else {
205 return 0;
206 }
207 } else {
208 CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
209 EdbPrintRegister1 (Operands);
210
211 if ((Operands & OPERAND_M_INDIRECT1) == 0) {
212 if ((Modifiers & OPCODE_M_IMMDATA) == 0) {
213 Data32 = 0;
214 }
215 EdbPrintImmDatan (Data32);
216 } else {
217 EdbPrintRawIndexData32 (Data32);
218 }
219 }
220
221 EdbPostInstructionString ();
222 }
223
224 return Size;
225 }
226
227 /**
228
229 Disasm instruction - JMP8.
230
231 @param InstructionAddress - The instruction address
232 @param SystemContext - EBC system context.
233 @param DisasmString - The instruction string
234
235 @return Instruction length
236
237 **/
238 UINTN
EdbDisasmJMP8(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)239 EdbDisasmJMP8 (
240 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
241 IN EFI_SYSTEM_CONTEXT SystemContext,
242 OUT CHAR16 **DisasmString
243 )
244 {
245 UINT8 Modifiers;
246
247 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_JMP8);
248 Modifiers = GET_MODIFIERS (InstructionAddress);
249
250 //
251 // Construct Disasm String
252 //
253 if (DisasmString != NULL) {
254 *DisasmString = EdbPreInstructionString ();
255
256 EdbPrintInstructionName (L"JMP8");
257 if ((Modifiers & CONDITION_M_CONDITIONAL) != 0) {
258 if ((Modifiers & JMP_M_CS) != 0) {
259 EdbPrintInstructionName (L"cs");
260 } else {
261 EdbPrintInstructionName (L"cc");
262 }
263 }
264
265 EdbPrintData8 (*(UINT8 *)(UINTN)(InstructionAddress + 1));
266
267 EdbPostInstructionString ();
268 }
269
270 return 2;
271 }
272
273 /**
274
275 Disasm instruction - CALL.
276
277 @param InstructionAddress - The instruction address
278 @param SystemContext - EBC system context.
279 @param DisasmString - The instruction string
280
281 @return Instruction length
282
283 **/
284 UINTN
EdbDisasmCALL(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)285 EdbDisasmCALL (
286 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
287 IN EFI_SYSTEM_CONTEXT SystemContext,
288 OUT CHAR16 **DisasmString
289 )
290 {
291 UINT8 Modifiers;
292 UINT8 Operands;
293 UINTN Size;
294 UINT32 Data32;
295 UINT64 Data64;
296 UINT64 Ip;
297 UINTN Result;
298 EFI_PHYSICAL_ADDRESS SavedInstructionAddress;
299
300 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_CALL);
301 SavedInstructionAddress = InstructionAddress;
302
303 Modifiers = GET_MODIFIERS (InstructionAddress);
304 Operands = GET_OPERANDS (InstructionAddress);
305 Size = (UINTN)mJMPLen[(Modifiers >> 6) & 0x03];
306
307 //
308 // Construct Disasm String
309 //
310 if (DisasmString != NULL) {
311 *DisasmString = EdbPreInstructionString ();
312
313 EdbPrintInstructionName (L"CALL");
314 // if (Modifiers & OPCODE_M_IMMDATA64) {
315 // EdbPrintInstructionName (L"64");
316 // } else {
317 // EdbPrintInstructionName (L"32");
318 // }
319 if ((Operands & OPERAND_M_NATIVE_CALL) != 0) {
320 EdbPrintInstructionName (L"EX");
321 }
322 // if ((Operands & OPERAND_M_RELATIVE_ADDR) == 0) {
323 // EdbPrintInstructionName (L"a");
324 // }
325
326 InstructionAddress += 2;
327 if ((Modifiers & OPCODE_M_IMMDATA64) != 0) {
328 CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
329 Ip = Data64;
330 if ((Modifiers & OPCODE_M_IMMDATA) != 0) {
331 Result = EdbFindAndPrintSymbol ((UINTN)Ip);
332 if (Result == 0) {
333 EdbPrintData64 (Data64);
334 }
335 } else {
336 return 0;
337 }
338 } else {
339 if ((Modifiers & OPCODE_M_IMMDATA) != 0) {
340 CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
341 } else {
342 Data32 = 0;
343 }
344
345 if ((Operands & OPERAND_M_OP1) == 0) {
346 Ip = (UINT64)Data32;
347 } else {
348 Ip = GetRegisterValue (SystemContext, (Operands & OPERAND_M_OP1));
349 }
350
351 if ((Operands & OPERAND_M_INDIRECT1) == 0) {
352 if ((Operands & OPERAND_M_RELATIVE_ADDR) != 0) {
353 Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Ip + Size));
354 } else {
355 Result = EdbFindAndPrintSymbol ((UINTN)Ip);
356 }
357 if (Result == 0) {
358 EdbPrintRegister1 (Operands);
359 if ((Modifiers & OPCODE_M_IMMDATA) != 0) {
360 EdbPrintImmData32 (Data32);
361 }
362 }
363 } else {
364 EdbPrintRegister1 (Operands);
365 if ((Modifiers & OPCODE_M_IMMDATA) != 0) {
366 EdbPrintRawIndexData32 (Data32);
367 }
368 }
369 }
370
371 EdbPostInstructionString ();
372 }
373
374 return Size;
375 }
376
377 /**
378
379 Disasm instruction - RET.
380
381 @param InstructionAddress - The instruction address
382 @param SystemContext - EBC system context.
383 @param DisasmString - The instruction string
384
385 @return Instruction length
386
387 **/
388 UINTN
EdbDisasmRET(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)389 EdbDisasmRET (
390 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
391 IN EFI_SYSTEM_CONTEXT SystemContext,
392 OUT CHAR16 **DisasmString
393 )
394 {
395 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_RET);
396
397 if (*(UINT8 *)(UINTN)(InstructionAddress + 1) != 0) {
398 return 0;
399 }
400
401 //
402 // Construct Disasm String
403 //
404 if (DisasmString != NULL) {
405 *DisasmString = EdbPreInstructionString ();
406
407 EdbPrintInstructionName (L"RET");
408
409 EdbPostInstructionString ();
410 }
411
412 return 2;
413 }
414
415 /**
416
417 Disasm instruction - CMP.
418
419 @param InstructionAddress - The instruction address
420 @param SystemContext - EBC system context.
421 @param DisasmString - The instruction string
422
423 @return Instruction length
424
425 **/
426 UINTN
EdbDisasmCMP(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)427 EdbDisasmCMP (
428 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
429 IN EFI_SYSTEM_CONTEXT SystemContext,
430 OUT CHAR16 **DisasmString
431 )
432 {
433 UINT8 Opcode;
434 UINT8 Modifiers;
435 UINT8 Operands;
436 UINT16 Data16;
437 UINTN Size;
438
439 ASSERT (
440 (GET_OPCODE(InstructionAddress) == OPCODE_CMPEQ) ||
441 (GET_OPCODE(InstructionAddress) == OPCODE_CMPLTE) ||
442 (GET_OPCODE(InstructionAddress) == OPCODE_CMPGTE) ||
443 (GET_OPCODE(InstructionAddress) == OPCODE_CMPULTE) ||
444 (GET_OPCODE(InstructionAddress) == OPCODE_CMPUGTE)
445 );
446
447 Opcode = GET_OPCODE (InstructionAddress);
448 Modifiers = GET_MODIFIERS (InstructionAddress);
449 Operands = GET_OPERANDS (InstructionAddress);
450 if ((Modifiers & OPCODE_M_IMMDATA) != 0) {
451 Size = 4;
452 } else {
453 Size = 2;
454 }
455
456 //
457 // Construct Disasm String
458 //
459 if (DisasmString != NULL) {
460 *DisasmString = EdbPreInstructionString ();
461
462 EdbPrintInstructionName (L"CMP");
463 // if (Modifiers & OPCODE_M_64BIT) {
464 // EdbPrintInstructionName (L"64");
465 // } else {
466 // EdbPrintInstructionName (L"32");
467 // }
468 switch (Opcode) {
469 case OPCODE_CMPEQ:
470 EdbPrintInstructionName (L"eq");
471 break;
472 case OPCODE_CMPLTE:
473 EdbPrintInstructionName (L"lte");
474 break;
475 case OPCODE_CMPGTE:
476 EdbPrintInstructionName (L"gte");
477 break;
478 case OPCODE_CMPULTE:
479 EdbPrintInstructionName (L"ulte");
480 break;
481 case OPCODE_CMPUGTE:
482 EdbPrintInstructionName (L"ugte");
483 break;
484 }
485
486 EdbPrintRegister1 (Operands);
487 InstructionAddress += 2;
488
489 EdbPrintComma ();
490 EdbPrintRegister2 (Operands);
491
492 if ((Modifiers & OPCODE_M_IMMDATA) != 0) {
493 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
494 if ((Operands & OPERAND_M_INDIRECT2) != 0) {
495 EdbPrintRawIndexData16 (Data16);
496 } else {
497 EdbPrintImmDatan (Data16);
498 }
499 }
500
501 EdbPostInstructionString ();
502 }
503
504 return Size;
505 }
506
507 /**
508
509 Disasm instruction - Unsigned Data Manipulate.
510
511 @param InstructionAddress - The instruction address
512 @param SystemContext - EBC system context.
513 @param DisasmString - The instruction string
514
515 @return Instruction length
516
517 **/
518 UINTN
EdbDisasmUnsignedDataManip(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)519 EdbDisasmUnsignedDataManip (
520 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
521 IN EFI_SYSTEM_CONTEXT SystemContext,
522 OUT CHAR16 **DisasmString
523 )
524 {
525 UINT8 Modifiers;
526 UINT8 Opcode;
527 UINT8 Operands;
528 UINTN Size;
529 UINT16 Data16;
530
531 ASSERT (
532 (GET_OPCODE(InstructionAddress) == OPCODE_NOT) ||
533 (GET_OPCODE(InstructionAddress) == OPCODE_MULU) ||
534 (GET_OPCODE(InstructionAddress) == OPCODE_DIVU) ||
535 (GET_OPCODE(InstructionAddress) == OPCODE_MODU) ||
536 (GET_OPCODE(InstructionAddress) == OPCODE_AND) ||
537 (GET_OPCODE(InstructionAddress) == OPCODE_OR) ||
538 (GET_OPCODE(InstructionAddress) == OPCODE_XOR) ||
539 (GET_OPCODE(InstructionAddress) == OPCODE_SHL) ||
540 (GET_OPCODE(InstructionAddress) == OPCODE_SHR) ||
541 (GET_OPCODE(InstructionAddress) == OPCODE_EXTNDB) ||
542 (GET_OPCODE(InstructionAddress) == OPCODE_EXTNDW) ||
543 (GET_OPCODE(InstructionAddress) == OPCODE_EXTNDD)
544 );
545
546 Opcode = GET_OPCODE (InstructionAddress);
547 Operands = GET_OPERANDS (InstructionAddress);
548 Modifiers = GET_MODIFIERS (InstructionAddress);
549 if ((Modifiers & DATAMANIP_M_IMMDATA) != 0) {
550 Size = 4;
551 } else {
552 Size = 2;
553 }
554
555 //
556 // Construct Disasm String
557 //
558 if (DisasmString != NULL) {
559 *DisasmString = EdbPreInstructionString ();
560
561 switch (Opcode) {
562 case OPCODE_NOT:
563 EdbPrintInstructionName (L"NOT");
564 break;
565 case OPCODE_MULU:
566 EdbPrintInstructionName (L"MULU");
567 break;
568 case OPCODE_DIVU:
569 EdbPrintInstructionName (L"DIVU");
570 break;
571 case OPCODE_MODU:
572 EdbPrintInstructionName (L"MODU");
573 break;
574 case OPCODE_AND:
575 EdbPrintInstructionName (L"AND");
576 break;
577 case OPCODE_OR:
578 EdbPrintInstructionName (L"OR");
579 break;
580 case OPCODE_XOR:
581 EdbPrintInstructionName (L"XOR");
582 break;
583 case OPCODE_SHL:
584 EdbPrintInstructionName (L"SHL");
585 break;
586 case OPCODE_SHR:
587 EdbPrintInstructionName (L"SHR");
588 break;
589 case OPCODE_EXTNDB:
590 EdbPrintInstructionName (L"EXTNDB");
591 break;
592 case OPCODE_EXTNDW:
593 EdbPrintInstructionName (L"EXTNDW");
594 break;
595 case OPCODE_EXTNDD:
596 EdbPrintInstructionName (L"EXTNDD");
597 break;
598 }
599 // if (Modifiers & DATAMANIP_M_64) {
600 // EdbPrintInstructionName (L"64");
601 // } else {
602 // EdbPrintInstructionName (L"32");
603 // }
604
605 EdbPrintRegister1 (Operands);
606 EdbPrintComma ();
607 EdbPrintRegister2 (Operands);
608
609 InstructionAddress += 2;
610 if ((Modifiers & DATAMANIP_M_IMMDATA) != 0) {
611 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
612 if ((Operands & OPERAND_M_INDIRECT2) != 0) {
613 EdbPrintRawIndexData16 (Data16);
614 } else {
615 EdbPrintImmDatan (Data16);
616 }
617 }
618
619 EdbPostInstructionString ();
620 }
621
622 return Size;
623 }
624
625 /**
626
627 Disasm instruction - Signed Data Manipulate,
628
629 @param InstructionAddress - The instruction address
630 @param SystemContext - EBC system context.
631 @param DisasmString - The instruction string
632
633 @return Instruction length
634
635 **/
636 UINTN
EdbDisasmSignedDataManip(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)637 EdbDisasmSignedDataManip (
638 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
639 IN EFI_SYSTEM_CONTEXT SystemContext,
640 OUT CHAR16 **DisasmString
641 )
642 {
643 UINT8 Modifiers;
644 UINT8 Opcode;
645 UINT8 Operands;
646 UINTN Size;
647 UINT16 Data16;
648
649 ASSERT (
650 (GET_OPCODE(InstructionAddress) == OPCODE_NEG) ||
651 (GET_OPCODE(InstructionAddress) == OPCODE_ADD) ||
652 (GET_OPCODE(InstructionAddress) == OPCODE_SUB) ||
653 (GET_OPCODE(InstructionAddress) == OPCODE_MUL) ||
654 (GET_OPCODE(InstructionAddress) == OPCODE_DIV) ||
655 (GET_OPCODE(InstructionAddress) == OPCODE_MOD) ||
656 (GET_OPCODE(InstructionAddress) == OPCODE_ASHR)
657 );
658
659 Opcode = GET_OPCODE (InstructionAddress);
660 Operands = GET_OPERANDS (InstructionAddress);
661 Modifiers = GET_MODIFIERS (InstructionAddress);
662 if ((Modifiers & DATAMANIP_M_IMMDATA) != 0) {
663 Size = 4;
664 } else {
665 Size = 2;
666 }
667
668 //
669 // Construct Disasm String
670 //
671 if (DisasmString != NULL) {
672 *DisasmString = EdbPreInstructionString ();
673
674 switch (Opcode) {
675 case OPCODE_NEG:
676 EdbPrintInstructionName (L"NEG");
677 break;
678 case OPCODE_ADD:
679 EdbPrintInstructionName (L"ADD");
680 break;
681 case OPCODE_SUB:
682 EdbPrintInstructionName (L"SUB");
683 break;
684 case OPCODE_MUL:
685 EdbPrintInstructionName (L"MUL");
686 break;
687 case OPCODE_DIV:
688 EdbPrintInstructionName (L"DIV");
689 break;
690 case OPCODE_MOD:
691 EdbPrintInstructionName (L"MOD");
692 break;
693 case OPCODE_ASHR:
694 EdbPrintInstructionName (L"ASHR");
695 break;
696 }
697 // if (Modifiers & DATAMANIP_M_64) {
698 // EdbPrintInstructionName (L"64");
699 // } else {
700 // EdbPrintInstructionName (L"32");
701 // }
702
703 EdbPrintRegister1 (Operands);
704 EdbPrintComma ();
705 EdbPrintRegister2 (Operands);
706
707 InstructionAddress += 2;
708 if ((Modifiers & DATAMANIP_M_IMMDATA) != 0) {
709 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
710 if ((Operands & OPERAND_M_INDIRECT2) != 0) {
711 EdbPrintRawIndexData16 (Data16);
712 } else {
713 EdbPrintImmDatan (Data16);
714 }
715 }
716
717 EdbPostInstructionString ();
718 }
719
720 return Size;
721 }
722
723 /**
724
725 Disasm instruction - MOVxx.
726
727 @param InstructionAddress - The instruction address
728 @param SystemContext - EBC system context.
729 @param DisasmString - The instruction string
730
731 @return Instruction length
732
733 **/
734 UINTN
EdbDisasmMOVxx(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)735 EdbDisasmMOVxx (
736 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
737 IN EFI_SYSTEM_CONTEXT SystemContext,
738 OUT CHAR16 **DisasmString
739 )
740 {
741 UINT8 Modifiers;
742 UINT8 Opcode;
743 UINT8 Operands;
744 UINTN Size;
745 UINT16 Data16;
746 UINT32 Data32;
747 UINT64 Data64;
748
749 ASSERT (
750 (GET_OPCODE(InstructionAddress) == OPCODE_MOVBW) ||
751 (GET_OPCODE(InstructionAddress) == OPCODE_MOVWW) ||
752 (GET_OPCODE(InstructionAddress) == OPCODE_MOVDW) ||
753 (GET_OPCODE(InstructionAddress) == OPCODE_MOVQW) ||
754 (GET_OPCODE(InstructionAddress) == OPCODE_MOVBD) ||
755 (GET_OPCODE(InstructionAddress) == OPCODE_MOVWD) ||
756 (GET_OPCODE(InstructionAddress) == OPCODE_MOVDD) ||
757 (GET_OPCODE(InstructionAddress) == OPCODE_MOVQD) ||
758 (GET_OPCODE(InstructionAddress) == OPCODE_MOVQQ) ||
759 (GET_OPCODE(InstructionAddress) == OPCODE_MOVNW) ||
760 (GET_OPCODE(InstructionAddress) == OPCODE_MOVND)
761 );
762
763 Opcode = GET_OPCODE (InstructionAddress);
764 Modifiers = GET_MODIFIERS (InstructionAddress);
765 Operands = GET_OPERANDS (InstructionAddress);
766 Size = 2;
767 if ((Modifiers & (OPCODE_M_IMMED_OP1 | OPCODE_M_IMMED_OP2)) != 0) {
768 if ((Opcode <= OPCODE_MOVQW) || (Opcode == OPCODE_MOVNW)) {
769 if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
770 Size += 2;
771 }
772 if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
773 Size += 2;
774 }
775 } else if (((Opcode <= OPCODE_MOVQD) || (Opcode == OPCODE_MOVND)) != 0) {
776 if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
777 Size += 4;
778 }
779 if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
780 Size += 4;
781 }
782 } else if (Opcode == OPCODE_MOVQQ) {
783 if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
784 Size += 8;
785 }
786 if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
787 Size += 8;
788 }
789 }
790 }
791
792 //
793 // Construct Disasm String
794 //
795 if (DisasmString != NULL) {
796 *DisasmString = EdbPreInstructionString ();
797
798 EdbPrintInstructionName (L"MOV");
799 switch (Opcode) {
800 case OPCODE_MOVBW:
801 EdbPrintInstructionName (L"bw");
802 break;
803 case OPCODE_MOVWW:
804 EdbPrintInstructionName (L"ww");
805 break;
806 case OPCODE_MOVDW:
807 EdbPrintInstructionName (L"dw");
808 break;
809 case OPCODE_MOVQW:
810 EdbPrintInstructionName (L"qw");
811 break;
812 case OPCODE_MOVBD:
813 EdbPrintInstructionName (L"bd");
814 break;
815 case OPCODE_MOVWD:
816 EdbPrintInstructionName (L"wd");
817 break;
818 case OPCODE_MOVDD:
819 EdbPrintInstructionName (L"dd");
820 break;
821 case OPCODE_MOVQD:
822 EdbPrintInstructionName (L"qd");
823 break;
824 case OPCODE_MOVQQ:
825 EdbPrintInstructionName (L"qq");
826 break;
827 case OPCODE_MOVNW:
828 EdbPrintInstructionName (L"nw");
829 break;
830 case OPCODE_MOVND:
831 EdbPrintInstructionName (L"nd");
832 break;
833 }
834
835 EdbPrintRegister1 (Operands);
836
837 InstructionAddress += 2;
838 if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
839 if ((Opcode <= OPCODE_MOVQW) || (Opcode == OPCODE_MOVNW)) {
840 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
841 InstructionAddress += 2;
842 EdbPrintRawIndexData16 (Data16);
843 } else if ((Opcode <= OPCODE_MOVQD) || (Opcode == OPCODE_MOVND)) {
844 CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
845 InstructionAddress += 4;
846 EdbPrintRawIndexData32 (Data32);
847 } else if (Opcode == OPCODE_MOVQQ) {
848 CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
849 InstructionAddress += 8;
850 EdbPrintRawIndexData64 (Data64);
851 }
852 }
853
854 EdbPrintComma ();
855 EdbPrintRegister2 (Operands);
856
857 if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
858 if ((Opcode <= OPCODE_MOVQW) || (Opcode == OPCODE_MOVNW)) {
859 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
860 EdbPrintRawIndexData16 (Data16);
861 } else if ((Opcode <= OPCODE_MOVQD) || (Opcode == OPCODE_MOVND)) {
862 CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
863 EdbPrintRawIndexData32 (Data32);
864 } else if (Opcode == OPCODE_MOVQQ) {
865 CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
866 EdbPrintRawIndexData64 (Data64);
867 }
868 }
869
870 EdbPostInstructionString ();
871 }
872
873 return Size;
874 }
875
876 /**
877
878 Disasm instruction - MOVsnw.
879
880 @param InstructionAddress - The instruction address
881 @param SystemContext - EBC system context.
882 @param DisasmString - The instruction string
883
884 @return Instruction length
885
886 **/
887 UINTN
EdbDisasmMOVsnw(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)888 EdbDisasmMOVsnw (
889 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
890 IN EFI_SYSTEM_CONTEXT SystemContext,
891 OUT CHAR16 **DisasmString
892 )
893 {
894 UINT8 Modifiers;
895 UINT8 Operands;
896 UINTN Size;
897 UINT16 Data16;
898
899 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVSNW);
900
901 Modifiers = GET_MODIFIERS (InstructionAddress);
902 Operands = GET_OPERANDS (InstructionAddress);
903 Size = 2;
904 if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
905 Size += 2;
906 }
907 if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
908 Size += 2;
909 }
910
911 //
912 // Construct Disasm String
913 //
914 if (DisasmString != NULL) {
915 *DisasmString = EdbPreInstructionString ();
916
917 EdbPrintInstructionName (L"MOVsnw");
918
919 EdbPrintRegister1 (Operands);
920
921 InstructionAddress += 2;
922 if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
923 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
924 InstructionAddress += 2;
925 EdbPrintRawIndexData16 (Data16);
926 }
927
928 EdbPrintComma ();
929 EdbPrintRegister2 (Operands);
930
931 if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
932 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
933 if ((Operands & OPERAND_M_INDIRECT2) != 0) {
934 EdbPrintRawIndexData16 (Data16);
935 } else {
936 EdbPrintImmDatan (Data16);
937 }
938 }
939
940 EdbPostInstructionString ();
941 }
942
943 return Size;
944 }
945
946 /**
947
948 Disasm instruction - MOVsnd.
949
950 @param InstructionAddress - The instruction address
951 @param SystemContext - EBC system context.
952 @param DisasmString - The instruction string
953
954 @return Instruction length
955
956 **/
957 UINTN
EdbDisasmMOVsnd(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)958 EdbDisasmMOVsnd (
959 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
960 IN EFI_SYSTEM_CONTEXT SystemContext,
961 OUT CHAR16 **DisasmString
962 )
963 {
964 UINT8 Modifiers;
965 UINT8 Operands;
966 UINTN Size;
967 UINT32 Data32;
968
969 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVSND);
970
971 Modifiers = GET_MODIFIERS (InstructionAddress);
972 Operands = GET_OPERANDS (InstructionAddress);
973 Size = 2;
974 if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
975 Size += 4;
976 }
977 if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
978 Size += 4;
979 }
980
981 //
982 // Construct Disasm String
983 //
984 if (DisasmString != NULL) {
985 *DisasmString = EdbPreInstructionString ();
986
987 EdbPrintInstructionName (L"MOVsnd");
988
989 EdbPrintRegister1 (Operands);
990
991 InstructionAddress += 2;
992 if ((Modifiers & OPCODE_M_IMMED_OP1) != 0) {
993 CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
994 InstructionAddress += 4;
995 EdbPrintRawIndexData32 (Data32);
996 }
997
998 EdbPrintComma ();
999 EdbPrintRegister2 (Operands);
1000
1001 if ((Modifiers & OPCODE_M_IMMED_OP2) != 0) {
1002 CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
1003 if ((Operands & OPERAND_M_INDIRECT2) != 0) {
1004 EdbPrintRawIndexData32 (Data32);
1005 } else {
1006 EdbPrintImmDatan (Data32);
1007 }
1008 }
1009
1010 EdbPostInstructionString ();
1011 }
1012
1013 return Size;
1014 }
1015
1016 /**
1017
1018 Disasm instruction - LOADSP.
1019
1020 @param InstructionAddress - The instruction address
1021 @param SystemContext - EBC system context.
1022 @param DisasmString - The instruction string
1023
1024 @return Instruction length
1025
1026 **/
1027 UINTN
EdbDisasmLOADSP(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)1028 EdbDisasmLOADSP (
1029 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
1030 IN EFI_SYSTEM_CONTEXT SystemContext,
1031 OUT CHAR16 **DisasmString
1032 )
1033 {
1034 UINT8 Operands;
1035
1036 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_LOADSP);
1037
1038 Operands = GET_OPERANDS (InstructionAddress);
1039
1040 //
1041 // Construct Disasm String
1042 //
1043 if (DisasmString != NULL) {
1044 *DisasmString = EdbPreInstructionString ();
1045
1046 EdbPrintInstructionName (L"LOADSP");
1047
1048 EdbPrintDedicatedRegister1 (Operands);
1049
1050 EdbPrintRegister2 (Operands);
1051
1052 EdbPostInstructionString ();
1053 }
1054
1055 return 2;
1056 }
1057
1058 /**
1059
1060 Disasm instruction - STORESP.
1061
1062 @param InstructionAddress - The instruction address
1063 @param SystemContext - EBC system context.
1064 @param DisasmString - The instruction string
1065
1066 @return Instruction length
1067
1068 **/
1069 UINTN
EdbDisasmSTORESP(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)1070 EdbDisasmSTORESP (
1071 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
1072 IN EFI_SYSTEM_CONTEXT SystemContext,
1073 OUT CHAR16 **DisasmString
1074 )
1075 {
1076 UINT8 Operands;
1077
1078 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_STORESP);
1079
1080 Operands = GET_OPERANDS (InstructionAddress);
1081
1082 //
1083 // Construct Disasm String
1084 //
1085 if (DisasmString != NULL) {
1086 *DisasmString = EdbPreInstructionString ();
1087
1088 EdbPrintInstructionName (L"STORESP");
1089
1090 EdbPrintRegister1 (Operands);
1091
1092 EdbPrintDedicatedRegister2 (Operands);
1093
1094 EdbPostInstructionString ();
1095 }
1096
1097 return 2;
1098 }
1099
1100
1101 /**
1102
1103 Disasm instruction - PUSH.
1104
1105 @param InstructionAddress - The instruction address
1106 @param SystemContext - EBC system context.
1107 @param DisasmString - The instruction string
1108
1109 @return Instruction length
1110
1111 **/
1112 UINTN
EdbDisasmPUSH(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)1113 EdbDisasmPUSH (
1114 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
1115 IN EFI_SYSTEM_CONTEXT SystemContext,
1116 OUT CHAR16 **DisasmString
1117 )
1118 {
1119 UINT8 Modifiers;
1120 UINT8 Operands;
1121 UINTN Size;
1122 UINT16 Data16;
1123
1124 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_PUSH);
1125
1126 Operands = GET_OPERANDS (InstructionAddress);
1127 Modifiers = GET_MODIFIERS (InstructionAddress);
1128 if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
1129 Size = 4;
1130 } else {
1131 Size = 2;
1132 }
1133
1134 //
1135 // Construct Disasm String
1136 //
1137 if (DisasmString != NULL) {
1138 *DisasmString = EdbPreInstructionString ();
1139
1140 EdbPrintInstructionName (L"PUSH");
1141 // if (Modifiers & PUSHPOP_M_64) {
1142 // EdbPrintInstructionName (L"64");
1143 // } else {
1144 // EdbPrintInstructionName (L"32");
1145 // }
1146
1147 EdbPrintRegister1 (Operands);
1148
1149 InstructionAddress += 2;
1150 if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
1151 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
1152 if ((Operands & OPERAND_M_INDIRECT1) != 0) {
1153 EdbPrintRawIndexData16 (Data16);
1154 } else {
1155 EdbPrintImmDatan (Data16);
1156 }
1157 }
1158
1159 EdbPostInstructionString ();
1160 }
1161
1162 return Size;
1163 }
1164
1165 /**
1166
1167 Disasm instruction - POP.
1168
1169 @param InstructionAddress - The instruction address
1170 @param SystemContext - EBC system context.
1171 @param DisasmString - The instruction string
1172
1173 @return Instruction length
1174
1175 **/
1176 UINTN
EdbDisasmPOP(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)1177 EdbDisasmPOP (
1178 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
1179 IN EFI_SYSTEM_CONTEXT SystemContext,
1180 OUT CHAR16 **DisasmString
1181 )
1182 {
1183 UINT8 Modifiers;
1184 UINT8 Operands;
1185 UINTN Size;
1186 UINT16 Data16;
1187
1188 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_POP);
1189
1190 Operands = GET_OPERANDS (InstructionAddress);
1191 Modifiers = GET_MODIFIERS (InstructionAddress);
1192 if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
1193 Size = 4;
1194 } else {
1195 Size = 2;
1196 }
1197
1198 //
1199 // Construct Disasm String
1200 //
1201 if (DisasmString != NULL) {
1202 *DisasmString = EdbPreInstructionString ();
1203
1204 EdbPrintInstructionName (L"POP");
1205 // if (Modifiers & PUSHPOP_M_64) {
1206 // EdbPrintInstructionName (L"64");
1207 // } else {
1208 // EdbPrintInstructionName (L"32");
1209 // }
1210
1211 EdbPrintRegister1 (Operands);
1212
1213 InstructionAddress += 2;
1214 if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
1215 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
1216 if ((Operands & OPERAND_M_INDIRECT1) != 0) {
1217 EdbPrintRawIndexData16 (Data16);
1218 } else {
1219 EdbPrintImmDatan (Data16);
1220 }
1221 }
1222
1223 EdbPostInstructionString ();
1224 }
1225
1226 return Size;
1227 }
1228
1229 /**
1230
1231 Disasm instruction - CMPI.
1232
1233 @param InstructionAddress - The instruction address
1234 @param SystemContext - EBC system context.
1235 @param DisasmString - The instruction string
1236
1237 @return Instruction length
1238
1239 **/
1240 UINTN
EdbDisasmCMPI(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)1241 EdbDisasmCMPI (
1242 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
1243 IN EFI_SYSTEM_CONTEXT SystemContext,
1244 OUT CHAR16 **DisasmString
1245 )
1246 {
1247 UINT8 Modifiers;
1248 UINT8 Opcode;
1249 UINT8 Operands;
1250 UINT16 Data16;
1251 UINT32 Data32;
1252 UINTN Size;
1253
1254 ASSERT (
1255 (GET_OPCODE(InstructionAddress) == OPCODE_CMPIEQ) ||
1256 (GET_OPCODE(InstructionAddress) == OPCODE_CMPILTE) ||
1257 (GET_OPCODE(InstructionAddress) == OPCODE_CMPIGTE) ||
1258 (GET_OPCODE(InstructionAddress) == OPCODE_CMPIULTE) ||
1259 (GET_OPCODE(InstructionAddress) == OPCODE_CMPIUGTE)
1260 );
1261
1262 Modifiers = GET_MODIFIERS (InstructionAddress);
1263 Opcode = GET_OPCODE (InstructionAddress);
1264 Operands = GET_OPERANDS (InstructionAddress);
1265
1266 if ((Operands & 0xE0) != 0) {
1267 return 0;
1268 }
1269
1270 Size = 2;
1271 if ((Operands & OPERAND_M_CMPI_INDEX) != 0) {
1272 Size += 2;
1273 }
1274 if ((Modifiers & OPCODE_M_CMPI32_DATA) != 0) {
1275 Size += 4;
1276 } else {
1277 Size += 2;
1278 }
1279
1280 //
1281 // Construct Disasm String
1282 //
1283 if (DisasmString != NULL) {
1284 *DisasmString = EdbPreInstructionString ();
1285
1286 EdbPrintInstructionName (L"CMPI");
1287 // if (Modifiers & OPCODE_M_CMPI64) {
1288 // EdbPrintInstructionName (L"64");
1289 // } else {
1290 // EdbPrintInstructionName (L"32");
1291 // }
1292 if ((Modifiers & OPCODE_M_CMPI32_DATA) != 0) {
1293 EdbPrintInstructionName (L"d");
1294 } else {
1295 EdbPrintInstructionName (L"w");
1296 }
1297 switch (Opcode) {
1298 case OPCODE_CMPIEQ:
1299 EdbPrintInstructionName (L"eq");
1300 break;
1301 case OPCODE_CMPILTE:
1302 EdbPrintInstructionName (L"lte");
1303 break;
1304 case OPCODE_CMPIGTE:
1305 EdbPrintInstructionName (L"gte");
1306 break;
1307 case OPCODE_CMPIULTE:
1308 EdbPrintInstructionName (L"ulte");
1309 break;
1310 case OPCODE_CMPIUGTE:
1311 EdbPrintInstructionName (L"ugte");
1312 break;
1313 }
1314
1315 EdbPrintRegister1 (Operands);
1316
1317 InstructionAddress += 2;
1318 if ((Operands & OPERAND_M_CMPI_INDEX) != 0) {
1319 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
1320 InstructionAddress += 2;
1321 EdbPrintRawIndexData16 (Data16);
1322 }
1323
1324 EdbPrintComma ();
1325
1326 if ((Modifiers & OPCODE_M_CMPI32_DATA) != 0) {
1327 CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
1328 EdbPrintDatan (Data32);
1329 } else {
1330 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
1331 EdbPrintDatan (Data16);
1332 }
1333
1334 EdbPostInstructionString ();
1335 }
1336
1337 return Size;
1338 }
1339
1340 /**
1341
1342 Disasm instruction - PUSHn.
1343
1344 @param InstructionAddress - The instruction address
1345 @param SystemContext - EBC system context.
1346 @param DisasmString - The instruction string
1347
1348 @return Instruction length
1349
1350 **/
1351 UINTN
EdbDisasmPUSHn(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)1352 EdbDisasmPUSHn (
1353 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
1354 IN EFI_SYSTEM_CONTEXT SystemContext,
1355 OUT CHAR16 **DisasmString
1356 )
1357 {
1358 UINT8 Modifiers;
1359 UINT8 Operands;
1360 UINTN Size;
1361 UINT16 Data16;
1362
1363 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_PUSHN);
1364
1365 Operands = GET_OPERANDS (InstructionAddress);
1366 Modifiers = GET_MODIFIERS (InstructionAddress);
1367 if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
1368 Size = 4;
1369 } else {
1370 Size = 2;
1371 }
1372
1373 //
1374 // Construct Disasm String
1375 //
1376 if (DisasmString != NULL) {
1377 *DisasmString = EdbPreInstructionString ();
1378
1379 EdbPrintInstructionName (L"PUSHn");
1380
1381 EdbPrintRegister1 (Operands);
1382
1383 InstructionAddress += 2;
1384 if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
1385 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
1386 if ((Operands & OPERAND_M_INDIRECT1) != 0) {
1387 EdbPrintRawIndexData16 (Data16);
1388 } else {
1389 EdbPrintImmDatan (Data16);
1390 }
1391 }
1392
1393 EdbPostInstructionString ();
1394 }
1395
1396 return Size;
1397 }
1398
1399 /**
1400
1401 Disasm instruction - POPn.
1402
1403 @param InstructionAddress - The instruction address
1404 @param SystemContext - EBC system context.
1405 @param DisasmString - The instruction string
1406
1407 @return Instruction length
1408
1409 **/
1410 UINTN
EdbDisasmPOPn(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)1411 EdbDisasmPOPn (
1412 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
1413 IN EFI_SYSTEM_CONTEXT SystemContext,
1414 OUT CHAR16 **DisasmString
1415 )
1416 {
1417 UINT8 Modifiers;
1418 UINT8 Operands;
1419 UINTN Size;
1420 UINT16 Data16;
1421
1422 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_POPN);
1423
1424 Operands = GET_OPERANDS (InstructionAddress);
1425 Modifiers = GET_MODIFIERS (InstructionAddress);
1426 if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
1427 Size = 4;
1428 } else {
1429 Size = 2;
1430 }
1431
1432 //
1433 // Construct Disasm String
1434 //
1435 if (DisasmString != NULL) {
1436 *DisasmString = EdbPreInstructionString ();
1437
1438 EdbPrintInstructionName (L"POPn");
1439
1440 EdbPrintRegister1 (Operands);
1441
1442 InstructionAddress += 2;
1443 if ((Modifiers & PUSHPOP_M_IMMDATA) != 0) {
1444 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
1445 if ((Operands & OPERAND_M_INDIRECT1) != 0) {
1446 EdbPrintRawIndexData16 (Data16);
1447 } else {
1448 EdbPrintImmDatan (Data16);
1449 }
1450 }
1451
1452 EdbPostInstructionString ();
1453 }
1454
1455 return Size;
1456 }
1457
1458 /**
1459
1460 Disasm instruction - MOVI.
1461
1462 @param InstructionAddress - The instruction address
1463 @param SystemContext - EBC system context.
1464 @param DisasmString - The instruction string
1465
1466 @return Instruction length
1467
1468 **/
1469 UINTN
EdbDisasmMOVI(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)1470 EdbDisasmMOVI (
1471 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
1472 IN EFI_SYSTEM_CONTEXT SystemContext,
1473 OUT CHAR16 **DisasmString
1474 )
1475 {
1476 UINT8 Modifiers;
1477 UINT8 Operands;
1478 UINTN Size;
1479 UINT16 Data16;
1480 UINT32 Data32;
1481 UINT64 Data64;
1482
1483 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVI);
1484
1485 Modifiers = GET_MODIFIERS (InstructionAddress);
1486 Operands = GET_OPERANDS (InstructionAddress);
1487
1488 if ((Operands & MOVI_M_IMMDATA) != 0) {
1489 Size = 4;
1490 } else {
1491 Size = 2;
1492 }
1493 if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {
1494 Size += 2;
1495 } else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {
1496 Size += 4;
1497 } else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {
1498 Size += 8;
1499 }
1500
1501 //
1502 // Construct Disasm String
1503 //
1504 if (DisasmString != NULL) {
1505 *DisasmString = EdbPreInstructionString ();
1506
1507 EdbPrintInstructionName (L"MOVI");
1508 switch (Operands & MOVI_M_MOVEWIDTH) {
1509 case MOVI_MOVEWIDTH8:
1510 EdbPrintInstructionName (L"b");
1511 break;
1512 case MOVI_MOVEWIDTH16:
1513 EdbPrintInstructionName (L"w");
1514 break;
1515 case MOVI_MOVEWIDTH32:
1516 EdbPrintInstructionName (L"d");
1517 break;
1518 case MOVI_MOVEWIDTH64:
1519 EdbPrintInstructionName (L"q");
1520 break;
1521 }
1522 switch (Modifiers & MOVI_M_DATAWIDTH) {
1523 case MOVI_DATAWIDTH16:
1524 EdbPrintInstructionName (L"w");
1525 break;
1526 case MOVI_DATAWIDTH32:
1527 EdbPrintInstructionName (L"d");
1528 break;
1529 case MOVI_DATAWIDTH64:
1530 EdbPrintInstructionName (L"q");
1531 break;
1532 }
1533
1534 EdbPrintRegister1 (Operands);
1535
1536 InstructionAddress += 2;
1537 if ((Operands & MOVI_M_IMMDATA) != 0) {
1538 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
1539 InstructionAddress += 2;
1540 EdbPrintRawIndexData16 (Data16);
1541 }
1542
1543 EdbPrintComma ();
1544
1545 switch (Modifiers & MOVI_M_DATAWIDTH) {
1546 case MOVI_DATAWIDTH16:
1547 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
1548 EdbPrintDatan (Data16);
1549 break;
1550 case MOVI_DATAWIDTH32:
1551 CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
1552 EdbPrintDatan (Data32);
1553 break;
1554 case MOVI_DATAWIDTH64:
1555 CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
1556 EdbPrintData64n (Data64);
1557 break;
1558 }
1559
1560 EdbPostInstructionString ();
1561 }
1562
1563 return Size;
1564 }
1565
1566 /**
1567
1568 Disasm instruction - MOVIn.
1569
1570 @param InstructionAddress - The instruction address
1571 @param SystemContext - EBC system context.
1572 @param DisasmString - The instruction string
1573
1574 @return Instruction length
1575
1576 **/
1577 UINTN
EdbDisasmMOVIn(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)1578 EdbDisasmMOVIn (
1579 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
1580 IN EFI_SYSTEM_CONTEXT SystemContext,
1581 OUT CHAR16 **DisasmString
1582 )
1583 {
1584 UINT8 Modifiers;
1585 UINT8 Operands;
1586 UINTN Size;
1587 UINT16 Data16;
1588 UINT32 Data32;
1589 UINT64 Data64;
1590
1591 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVIN);
1592
1593 Modifiers = GET_MODIFIERS (InstructionAddress);
1594 Operands = GET_OPERANDS (InstructionAddress);
1595
1596 if ((Operands & MOVI_M_IMMDATA) != 0) {
1597 Size = 4;
1598 } else {
1599 Size = 2;
1600 }
1601 if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {
1602 Size += 2;
1603 } else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {
1604 Size += 4;
1605 } else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {
1606 Size += 8;
1607 }
1608
1609 //
1610 // Construct Disasm String
1611 //
1612 if (DisasmString != NULL) {
1613 *DisasmString = EdbPreInstructionString ();
1614
1615 EdbPrintInstructionName (L"MOVIn");
1616 switch (Modifiers & MOVI_M_DATAWIDTH) {
1617 case MOVI_DATAWIDTH16:
1618 EdbPrintInstructionName (L"w");
1619 break;
1620 case MOVI_DATAWIDTH32:
1621 EdbPrintInstructionName (L"d");
1622 break;
1623 case MOVI_DATAWIDTH64:
1624 EdbPrintInstructionName (L"q");
1625 break;
1626 }
1627
1628 EdbPrintRegister1 (Operands);
1629
1630 InstructionAddress += 2;
1631 if ((Operands & MOVI_M_IMMDATA) != 0) {
1632 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
1633 InstructionAddress += 2;
1634 EdbPrintRawIndexData16 (Data16);
1635 }
1636
1637 EdbPrintComma ();
1638
1639 switch (Modifiers & MOVI_M_DATAWIDTH) {
1640 case MOVI_DATAWIDTH16:
1641 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
1642 EdbPrintRawIndexData16 (Data16);
1643 break;
1644 case MOVI_DATAWIDTH32:
1645 CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
1646 EdbPrintRawIndexData32 (Data32);
1647 break;
1648 case MOVI_DATAWIDTH64:
1649 CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
1650 EdbPrintRawIndexData64 (Data64);
1651 break;
1652 }
1653
1654 EdbPostInstructionString ();
1655 }
1656
1657 return Size;
1658 }
1659
1660 /**
1661
1662 Disasm instruction - MOVREL.
1663
1664 @param InstructionAddress - The instruction address
1665 @param SystemContext - EBC system context.
1666 @param DisasmString - The instruction string
1667
1668 @return Instruction length
1669
1670 **/
1671 UINTN
EdbDisasmMOVREL(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN EFI_SYSTEM_CONTEXT SystemContext,OUT CHAR16 ** DisasmString)1672 EdbDisasmMOVREL (
1673 IN EFI_PHYSICAL_ADDRESS InstructionAddress,
1674 IN EFI_SYSTEM_CONTEXT SystemContext,
1675 OUT CHAR16 **DisasmString
1676 )
1677 {
1678 UINT8 Modifiers;
1679 UINT8 Operands;
1680 UINTN Size;
1681 UINT16 Data16;
1682 UINT32 Data32;
1683 UINT64 Data64;
1684 UINTN Result;
1685 EFI_PHYSICAL_ADDRESS SavedInstructionAddress;
1686
1687 ASSERT (GET_OPCODE(InstructionAddress) == OPCODE_MOVREL);
1688 SavedInstructionAddress = InstructionAddress;
1689
1690 Modifiers = GET_MODIFIERS (InstructionAddress);
1691 Operands = GET_OPERANDS (InstructionAddress);
1692
1693 if ((Operands & MOVI_M_IMMDATA) != 0) {
1694 Size = 4;
1695 } else {
1696 Size = 2;
1697 }
1698 if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH16) {
1699 Size += 2;
1700 } else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH32) {
1701 Size += 4;
1702 } else if ((Modifiers & MOVI_M_DATAWIDTH) == MOVI_DATAWIDTH64) {
1703 Size += 8;
1704 } else {
1705 return 0;
1706 }
1707
1708 //
1709 // Construct Disasm String
1710 //
1711 if (DisasmString != NULL) {
1712 *DisasmString = EdbPreInstructionString ();
1713
1714 EdbPrintInstructionName (L"MOVrel");
1715 switch (Modifiers & MOVI_M_DATAWIDTH) {
1716 case MOVI_DATAWIDTH16:
1717 EdbPrintInstructionName (L"w");
1718 break;
1719 case MOVI_DATAWIDTH32:
1720 EdbPrintInstructionName (L"d");
1721 break;
1722 case MOVI_DATAWIDTH64:
1723 EdbPrintInstructionName (L"q");
1724 break;
1725 }
1726
1727 EdbPrintRegister1 (Operands);
1728
1729 InstructionAddress += 2;
1730 if ((Operands & MOVI_M_IMMDATA) != 0) {
1731 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
1732 InstructionAddress += 2;
1733 EdbPrintRawIndexData16 (Data16);
1734 }
1735
1736 EdbPrintComma ();
1737
1738 switch (Modifiers & MOVI_M_DATAWIDTH) {
1739 case MOVI_DATAWIDTH16:
1740 CopyMem (&Data16, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT16));
1741 Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Size + (INT16)Data16));
1742 if (Result == 0) {
1743 EdbPrintData16 (Data16);
1744 }
1745 break;
1746 case MOVI_DATAWIDTH32:
1747 CopyMem (&Data32, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT32));
1748 Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Size + (INT32)Data32));
1749 if (Result == 0) {
1750 EdbPrintData32 (Data32);
1751 }
1752 break;
1753 case MOVI_DATAWIDTH64:
1754 CopyMem (&Data64, (VOID *)(UINTN)(InstructionAddress), sizeof(UINT64));
1755 if (sizeof(UINTN) == sizeof(UINT64)) {
1756 Result = EdbFindAndPrintSymbol ((UINTN)(SavedInstructionAddress + Size + (INT64)Data64));
1757 } else {
1758 Result = 0;
1759 }
1760 if (Result == 0) {
1761 EdbPrintData64 (Data64);
1762 }
1763 break;
1764 }
1765
1766 EdbPostInstructionString ();
1767 }
1768
1769 return Size;
1770 }
1771