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 extern EDB_DISASM_INSTRUCTION mEdbDisasmInstructionTable[];
12 
13 typedef struct {
14   CHAR16    Name[EDB_INSTRUCTION_NAME_MAX_LENGTH];
15   CHAR16    Content[EDB_INSTRUCTION_CONTENT_MAX_LENGTH];
16   CHAR16    Tail;
17 } EDB_INSTRUCTION_STRING;
18 
19 EDB_INSTRUCTION_STRING mInstructionString;
20 UINTN                  mInstructionNameOffset;
21 UINTN                  mInstructionContentOffset;
22 
23 /**
24 
25   Set offset for Instruction name and content.
26 
27   @param  InstructionNameOffset     - Instruction name offset
28   @param  InstructionContentOffset  - Instruction content offset
29 
30 **/
31 VOID
EdbSetOffset(IN UINTN InstructionNameOffset,IN UINTN InstructionContentOffset)32 EdbSetOffset (
33   IN UINTN InstructionNameOffset,
34   IN UINTN InstructionContentOffset
35   )
36 {
37   mInstructionNameOffset = InstructionNameOffset;
38   mInstructionContentOffset = InstructionContentOffset;
39 
40   return ;
41 }
42 
43 /**
44 
45   Pre instruction string construction.
46 
47   @return Instruction string
48 
49 **/
50 CHAR16 *
EdbPreInstructionString(VOID)51 EdbPreInstructionString (
52   VOID
53   )
54 {
55   ZeroMem (&mInstructionString, sizeof(mInstructionString));
56   mInstructionNameOffset    = 0;
57   mInstructionContentOffset = 0;
58 
59   return (CHAR16 *)&mInstructionString;
60 }
61 
62 /**
63 
64   Post instruction string construction.
65 
66   @return Instruction string
67 
68 **/
69 CHAR16 *
EdbPostInstructionString(VOID)70 EdbPostInstructionString (
71   VOID
72   )
73 {
74   CHAR16 *Char;
75 
76   for (Char = (CHAR16 *)&mInstructionString; Char < &mInstructionString.Tail; Char++) {
77     if (*Char == 0) {
78       *Char = L' ';
79     }
80   }
81   mInstructionString.Tail = 0;
82 
83   mInstructionNameOffset    = 0;
84   mInstructionContentOffset = 0;
85 
86   return (CHAR16 *)&mInstructionString;
87 }
88 
89 /**
90 
91   Get Sign, NaturalUnits, and ConstantUnits of the WORD data.
92 
93   @param  Data16        - WORD data
94   @param  NaturalUnits  - Natural Units of the WORD
95   @param  ConstantUnits - Constant Units of the WORD
96 
97   @return Sign value of WORD
98 
99 **/
100 BOOLEAN
EdbGetNaturalIndex16(IN UINT16 Data16,OUT UINTN * NaturalUnits,OUT UINTN * ConstantUnits)101 EdbGetNaturalIndex16 (
102   IN  UINT16  Data16,
103   OUT UINTN   *NaturalUnits,
104   OUT UINTN   *ConstantUnits
105   )
106 {
107   BOOLEAN Sign;
108   UINTN   NaturalUnitBit;
109 
110   Sign = (BOOLEAN)(Data16 >> 15);
111   NaturalUnitBit = (UINTN)((Data16 >> 12) & 0x7);
112   NaturalUnitBit *= 2;
113   Data16 = Data16 & 0xFFF;
114   *NaturalUnits = (UINTN)(Data16 & ((1 << NaturalUnitBit) - 1));
115   *ConstantUnits = (UINTN)((Data16 >> NaturalUnitBit) & ((1 << (12 - NaturalUnitBit)) - 1));
116 
117   return Sign;
118 }
119 
120 /**
121 
122   Get Sign, NaturalUnits, and ConstantUnits of the DWORD data.
123 
124   @param  Data32        - DWORD data
125   @param  NaturalUnits  - Natural Units of the DWORD
126   @param  ConstantUnits - Constant Units of the DWORD
127 
128   @return Sign value of DWORD
129 
130 **/
131 BOOLEAN
EdbGetNaturalIndex32(IN UINT32 Data32,OUT UINTN * NaturalUnits,OUT UINTN * ConstantUnits)132 EdbGetNaturalIndex32 (
133   IN  UINT32  Data32,
134   OUT UINTN   *NaturalUnits,
135   OUT UINTN   *ConstantUnits
136   )
137 {
138   BOOLEAN Sign;
139   UINTN   NaturalUnitBit;
140 
141   Sign = (BOOLEAN)(Data32 >> 31);
142   NaturalUnitBit = (UINTN)((Data32 >> 28) & 0x7);
143   NaturalUnitBit *= 4;
144   Data32 = Data32 & 0xFFFFFFF;
145   *NaturalUnits = (UINTN)(Data32 & ((1 << NaturalUnitBit) - 1));
146   *ConstantUnits = (UINTN)((Data32 >> NaturalUnitBit) & ((1 << (28 - NaturalUnitBit)) - 1));
147 
148   return Sign;
149 }
150 
151 /**
152 
153   Get Sign, NaturalUnits, and ConstantUnits of the QWORD data.
154 
155   @param  Data64        - QWORD data
156   @param  NaturalUnits  - Natural Units of the QWORD
157   @param  ConstantUnits - Constant Units of the QWORD
158 
159   @return Sign value of QWORD
160 
161 **/
162 BOOLEAN
EdbGetNaturalIndex64(IN UINT64 Data64,OUT UINT64 * NaturalUnits,OUT UINT64 * ConstantUnits)163 EdbGetNaturalIndex64 (
164   IN  UINT64  Data64,
165   OUT UINT64  *NaturalUnits,
166   OUT UINT64  *ConstantUnits
167   )
168 {
169   BOOLEAN Sign;
170   UINTN   NaturalUnitBit;
171 
172   Sign = (BOOLEAN)RShiftU64 (Data64, 63);
173   NaturalUnitBit = (UINTN)(RShiftU64 (Data64, 60) & 0x7);
174   NaturalUnitBit *= 8;
175   Data64 = RShiftU64 (LShiftU64 (Data64, 4), 4);
176   *NaturalUnits = (UINT64)(Data64 & (LShiftU64 (1, NaturalUnitBit) - 1));
177   *ConstantUnits = (UINT64)(RShiftU64 (Data64, NaturalUnitBit) & (LShiftU64 (1, (60 - NaturalUnitBit)) - 1));
178 
179   return Sign;
180 }
181 
182 /**
183 
184   Get Bit Width of the value.
185 
186   @param  Value - data
187 
188   @return Bit width
189 
190 **/
191 UINT8
EdbGetBitWidth(IN UINT64 Value)192 EdbGetBitWidth (
193   IN UINT64  Value
194   )
195 {
196   if (Value >= 10000000000000) {
197     return 14;
198   } else if (Value >= 1000000000000) {
199     return 13;
200   } else if (Value >= 100000000000) {
201     return 12;
202   } else if (Value >= 10000000000) {
203     return 11;
204   } else if (Value >= 1000000000) {
205     return 10;
206   } else if (Value >= 100000000) {
207     return 9;
208   } else if (Value >= 10000000) {
209     return 8;
210   } else if (Value >= 1000000) {
211     return 7;
212   } else if (Value >= 100000) {
213     return 6;
214   } else if (Value >= 10000) {
215     return 5;
216   } else if (Value >= 1000) {
217     return 4;
218   } else if (Value >= 100) {
219     return 3;
220   } else if (Value >= 10) {
221     return 2;
222   } else {
223     return 1;
224   }
225 }
226 
227 /**
228 
229   Print the instruction name.
230 
231   @param  Name - instruction name
232 
233   @return Instruction name offset
234 
235 **/
236 UINTN
EdbPrintInstructionName(IN CHAR16 * Name)237 EdbPrintInstructionName (
238   IN CHAR16                 *Name
239   )
240 {
241   EDBSPrintWithOffset (
242     mInstructionString.Name,
243     EDB_INSTRUCTION_NAME_MAX_SIZE,
244     mInstructionNameOffset,
245     L"%s",
246     Name
247     );
248   mInstructionNameOffset += StrLen (Name);
249 
250   return mInstructionNameOffset;
251 }
252 
253 /**
254 
255   Print register 1 in operands.
256 
257   @param  Operands - instruction operands
258 
259   @return Instruction content offset
260 
261 **/
262 UINTN
EdbPrintRegister1(IN UINT8 Operands)263 EdbPrintRegister1 (
264   IN UINT8                  Operands
265   )
266 {
267   if ((Operands & OPERAND_M_INDIRECT1) != 0) {
268     EDBSPrintWithOffset (
269       mInstructionString.Content,
270       EDB_INSTRUCTION_CONTENT_MAX_SIZE,
271       mInstructionContentOffset,
272       L"@"
273       );
274     mInstructionContentOffset += 1;
275   }
276   EDBSPrintWithOffset (
277     mInstructionString.Content,
278     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
279     mInstructionContentOffset,
280     L"R%d",
281     (UINTN)(Operands & OPERAND_M_OP1)
282     );
283   mInstructionContentOffset += 2;
284 
285   return mInstructionContentOffset;
286 }
287 
288 /**
289 
290   Print register 2 in operands.
291 
292   @param  Operands - instruction operands
293 
294   @return Instruction content offset
295 
296 **/
297 UINTN
EdbPrintRegister2(IN UINT8 Operands)298 EdbPrintRegister2 (
299   IN UINT8                  Operands
300   )
301 {
302   if ((Operands & OPERAND_M_INDIRECT2) != 0) {
303     EDBSPrintWithOffset (
304       mInstructionString.Content,
305       EDB_INSTRUCTION_CONTENT_MAX_SIZE,
306       mInstructionContentOffset,
307       L"@"
308       );
309     mInstructionContentOffset += 1;
310   }
311   EDBSPrintWithOffset (
312     mInstructionString.Content,
313     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
314     mInstructionContentOffset,
315     L"R%d",
316     (UINTN)((Operands & OPERAND_M_OP2) >> 4)
317     );
318   mInstructionContentOffset += 2;
319 
320   return mInstructionContentOffset;
321 }
322 
323 /**
324 
325   Print dedicated register 1 in operands.
326 
327   @param Operands - instruction operands
328 
329   @return Instruction content offset
330 
331 **/
332 UINTN
EdbPrintDedicatedRegister1(IN UINT8 Operands)333 EdbPrintDedicatedRegister1 (
334   IN UINT8                  Operands
335   )
336 {
337   switch (Operands & OPERAND_M_OP1) {
338   case 0:
339     EDBSPrintWithOffset (
340       mInstructionString.Content,
341       EDB_INSTRUCTION_CONTENT_MAX_SIZE,
342       mInstructionContentOffset,
343       L"[FLAGS]"
344       );
345     mInstructionContentOffset += 7;
346     break;
347   case 1:
348     EDBSPrintWithOffset (
349       mInstructionString.Content,
350       EDB_INSTRUCTION_CONTENT_MAX_SIZE,
351       mInstructionContentOffset,
352       L"[IP]"
353       );
354     mInstructionContentOffset += 4;
355     break;
356   }
357 
358   return mInstructionContentOffset;
359 }
360 
361 /**
362 
363   Print dedicated register 2 in operands.
364 
365   @param  Operands - instruction operands
366 
367   @return Instruction content offset
368 
369 **/
370 UINTN
EdbPrintDedicatedRegister2(IN UINT8 Operands)371 EdbPrintDedicatedRegister2 (
372   IN UINT8                  Operands
373   )
374 {
375   switch ((Operands & OPERAND_M_OP2) >> 4) {
376   case 0:
377     EDBSPrintWithOffset (
378       mInstructionString.Content,
379       EDB_INSTRUCTION_CONTENT_MAX_SIZE,
380       mInstructionContentOffset,
381       L"[FLAGS]"
382       );
383     mInstructionContentOffset += 7;
384     break;
385   case 1:
386     EDBSPrintWithOffset (
387       mInstructionString.Content,
388       EDB_INSTRUCTION_CONTENT_MAX_SIZE,
389       mInstructionContentOffset,
390       L"[IP]"
391       );
392     mInstructionContentOffset += 4;
393     break;
394   }
395 
396   return mInstructionContentOffset;
397 }
398 
399 /**
400 
401   Print the hexical UINTN index data to instruction content.
402 
403   @param  Sign          - Signed bit of UINTN data
404   @param  NaturalUnits  - natural units of UINTN data
405   @param  ConstantUnits - natural units of UINTN data
406 
407   @return Instruction content offset
408 
409 **/
410 UINTN
EdbPrintIndexData(IN BOOLEAN Sign,IN UINTN NaturalUnits,IN UINTN ConstantUnits)411 EdbPrintIndexData (
412   IN BOOLEAN                Sign,
413   IN UINTN                  NaturalUnits,
414   IN UINTN                  ConstantUnits
415   )
416 {
417   EDBSPrintWithOffset (
418     mInstructionString.Content,
419     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
420     mInstructionContentOffset,
421     L"(%s%d,%s%d)",
422     Sign ? L"-" : L"+",
423     NaturalUnits,
424     Sign ? L"-" : L"+",
425     ConstantUnits
426     );
427   mInstructionContentOffset  = mInstructionContentOffset + 5 + EdbGetBitWidth (NaturalUnits) + EdbGetBitWidth (ConstantUnits);
428 
429   return mInstructionContentOffset;
430 }
431 
432 /**
433 
434   Print the hexical QWORD index data to instruction content.
435 
436   @param  Sign          - Signed bit of QWORD data
437   @param  NaturalUnits  - natural units of QWORD data
438   @param  ConstantUnits - natural units of QWORD data
439 
440   @return Instruction content offset
441 
442 **/
443 UINTN
EdbPrintIndexData64(IN BOOLEAN Sign,IN UINT64 NaturalUnits,IN UINT64 ConstantUnits)444 EdbPrintIndexData64 (
445   IN BOOLEAN                Sign,
446   IN UINT64                 NaturalUnits,
447   IN UINT64                 ConstantUnits
448   )
449 {
450   EDBSPrintWithOffset (
451     mInstructionString.Content,
452     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
453     mInstructionContentOffset,
454     L"(%s%ld,%s%ld)",
455     Sign ? L"-" : L"+",
456     NaturalUnits,
457     Sign ? L"-" : L"+",
458     ConstantUnits
459     );
460   mInstructionContentOffset  = mInstructionContentOffset + 5 + EdbGetBitWidth (NaturalUnits) + EdbGetBitWidth (ConstantUnits);
461 
462   return mInstructionContentOffset;
463 }
464 
465 /**
466 
467   Print the hexical WORD raw index data to instruction content.
468 
469   @param  Data16 - WORD data
470 
471   @return Instruction content offset
472 
473 **/
474 UINTN
EdbPrintRawIndexData16(IN UINT16 Data16)475 EdbPrintRawIndexData16 (
476   IN UINT16                 Data16
477   )
478 {
479   BOOLEAN Sign;
480   UINTN   NaturalUnits;
481   UINTN   ConstantUnits;
482   UINTN   Offset;
483 
484   Sign = EdbGetNaturalIndex16 (Data16, &NaturalUnits, &ConstantUnits);
485   Offset = EdbPrintIndexData (Sign, NaturalUnits, ConstantUnits);
486 
487   return Offset;
488 }
489 
490 /**
491 
492   Print the hexical DWORD raw index data to instruction content.
493 
494   @param  Data32 - DWORD data
495 
496   @return Instruction content offset
497 
498 **/
499 UINTN
EdbPrintRawIndexData32(IN UINT32 Data32)500 EdbPrintRawIndexData32 (
501   IN UINT32                 Data32
502   )
503 {
504   BOOLEAN Sign;
505   UINTN   NaturalUnits;
506   UINTN   ConstantUnits;
507   UINTN   Offset;
508 
509   Sign = EdbGetNaturalIndex32 (Data32, &NaturalUnits, &ConstantUnits);
510   Offset = EdbPrintIndexData (Sign, NaturalUnits, ConstantUnits);
511 
512   return Offset;
513 }
514 
515 /**
516 
517   Print the hexical QWORD raw index data to instruction content.
518 
519   @param  Data64 - QWORD data
520 
521   @return Instruction content offset
522 
523 **/
524 UINTN
EdbPrintRawIndexData64(IN UINT64 Data64)525 EdbPrintRawIndexData64 (
526   IN UINT64                 Data64
527   )
528 {
529   BOOLEAN Sign;
530   UINT64  NaturalUnits;
531   UINT64  ConstantUnits;
532   UINTN   Offset;
533 
534   Sign = EdbGetNaturalIndex64 (Data64, &NaturalUnits, &ConstantUnits);
535   Offset = EdbPrintIndexData64 (Sign, NaturalUnits, ConstantUnits);
536 
537   return Offset;
538 }
539 
540 /**
541 
542   Print the hexical BYTE immediate data to instruction content.
543 
544   @param  Data - BYTE data
545 
546   @return Instruction content offset
547 
548 **/
549 UINTN
EdbPrintImmData8(IN UINT8 Data)550 EdbPrintImmData8 (
551   IN UINT8                  Data
552   )
553 {
554   EDBSPrintWithOffset (
555     mInstructionString.Content,
556     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
557     mInstructionContentOffset,
558     L"(0x%02x)",
559     (UINTN)Data
560     );
561   mInstructionContentOffset  += 6;
562 
563   return mInstructionContentOffset;
564 }
565 
566 /**
567 
568   Print the hexical WORD immediate data to instruction content.
569 
570   @param  Data - WORD data
571 
572   @return Instruction content offset
573 
574 **/
575 UINTN
EdbPrintImmData16(IN UINT16 Data)576 EdbPrintImmData16 (
577   IN UINT16                 Data
578   )
579 {
580   EDBSPrintWithOffset (
581     mInstructionString.Content,
582     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
583     mInstructionContentOffset,
584     L"(0x%04x)",
585     (UINTN)Data
586     );
587   mInstructionContentOffset  += 8;
588 
589   return mInstructionContentOffset;
590 }
591 
592 /**
593 
594   Print the hexical DWORD immediate data to instruction content.
595 
596   @param  Data - DWORD data
597 
598   @return Instruction content offset
599 
600 **/
601 UINTN
EdbPrintImmData32(IN UINT32 Data)602 EdbPrintImmData32 (
603   IN UINT32                 Data
604   )
605 {
606   EDBSPrintWithOffset (
607     mInstructionString.Content,
608     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
609     mInstructionContentOffset,
610     L"(0x%08x)",
611     (UINTN)Data
612     );
613   mInstructionContentOffset  += 12;
614 
615   return mInstructionContentOffset;
616 }
617 
618 /**
619 
620   Print the hexical QWORD immediate data to instruction content.
621 
622   @param  Data - QWORD data
623 
624   @return Instruction content offset
625 
626 **/
627 UINTN
EdbPrintImmData64(IN UINT64 Data)628 EdbPrintImmData64 (
629   IN UINT64                 Data
630   )
631 {
632   EDBSPrintWithOffset (
633     mInstructionString.Content,
634     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
635     mInstructionContentOffset,
636     L"(0x%016lx)",
637     Data
638     );
639   mInstructionContentOffset  += 20;
640 
641   return mInstructionContentOffset;
642 }
643 
644 /**
645 
646   Print the decimal UINTN immediate data to instruction content.
647 
648   @param  Data - UINTN data
649 
650   @return Instruction content offset
651 
652 **/
653 UINTN
EdbPrintImmDatan(IN UINTN Data)654 EdbPrintImmDatan (
655   IN UINTN                  Data
656   )
657 {
658   EDBSPrintWithOffset (
659     mInstructionString.Content,
660     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
661     mInstructionContentOffset,
662     L"(%d)",
663     (UINTN)Data
664     );
665   mInstructionContentOffset  = mInstructionContentOffset + 2 + EdbGetBitWidth (Data);
666 
667   return mInstructionContentOffset;
668 }
669 
670 /**
671 
672   Print the decimal QWORD immediate data to instruction content.
673 
674   @param  Data64 - QWORD data
675 
676   @return Instruction content offset
677 
678 **/
679 UINTN
EdbPrintImmData64n(IN UINT64 Data64)680 EdbPrintImmData64n (
681   IN UINT64                 Data64
682   )
683 {
684   EDBSPrintWithOffset (
685     mInstructionString.Content,
686     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
687     mInstructionContentOffset,
688     L"(%ld)",
689     Data64
690     );
691   mInstructionContentOffset  = mInstructionContentOffset + 2 + EdbGetBitWidth (Data64);
692 
693   return mInstructionContentOffset;
694 }
695 
696 /**
697 
698   Print the hexical BYTE to instruction content.
699 
700   @param  Data8 - BYTE data
701 
702   @return Instruction content offset
703 
704 **/
705 UINTN
EdbPrintData8(IN UINT8 Data8)706 EdbPrintData8 (
707   IN UINT8                  Data8
708   )
709 {
710   EDBSPrintWithOffset (
711     mInstructionString.Content,
712     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
713     mInstructionContentOffset,
714     L"0x%02x",
715     (UINTN)Data8
716     );
717   mInstructionContentOffset += 4;
718 
719   return mInstructionContentOffset;
720 }
721 
722 /**
723 
724   Print the hexical WORD to instruction content.
725 
726   @param  Data16 - WORD data
727 
728   @return Instruction content offset
729 
730 **/
731 UINTN
EdbPrintData16(IN UINT16 Data16)732 EdbPrintData16 (
733   IN UINT16                 Data16
734   )
735 {
736   EDBSPrintWithOffset (
737     mInstructionString.Content,
738     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
739     mInstructionContentOffset,
740     L"0x%04x",
741     (UINTN)Data16
742     );
743   mInstructionContentOffset += 6;
744 
745   return mInstructionContentOffset;
746 }
747 
748 /**
749 
750   Print the hexical DWORD to instruction content.
751 
752   @param  Data32 - DWORD data
753 
754   @return Instruction content offset
755 
756 **/
757 UINTN
EdbPrintData32(IN UINT32 Data32)758 EdbPrintData32 (
759   IN UINT32                 Data32
760   )
761 {
762   EDBSPrintWithOffset (
763     mInstructionString.Content,
764     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
765     mInstructionContentOffset,
766     L"0x%08x",
767     (UINTN)Data32
768     );
769   mInstructionContentOffset += 10;
770 
771   return mInstructionContentOffset;
772 }
773 
774 /**
775 
776   Print the hexical QWORD to instruction content.
777 
778   @param  Data64 - QWORD data
779 
780   @return Instruction content offset
781 
782 **/
783 UINTN
EdbPrintData64(IN UINT64 Data64)784 EdbPrintData64 (
785   IN UINT64                 Data64
786   )
787 {
788   EDBSPrintWithOffset (
789     mInstructionString.Content,
790     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
791     mInstructionContentOffset,
792     L"0x%016lx",
793     (UINT64)Data64
794     );
795   mInstructionContentOffset += 18;
796 
797   return mInstructionContentOffset;
798 }
799 
800 /**
801 
802   Print the decimal unsigned UINTN to instruction content.
803 
804   @param  Data - unsigned UINTN data
805 
806   @return Instruction content offset
807 
808 **/
809 UINTN
EdbPrintDatan(IN UINTN Data)810 EdbPrintDatan (
811   IN UINTN                  Data
812   )
813 {
814   EDBSPrintWithOffset (
815     mInstructionString.Content,
816     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
817     mInstructionContentOffset,
818     L"%d",
819     (UINTN)Data
820     );
821   mInstructionContentOffset = mInstructionContentOffset + EdbGetBitWidth (Data);
822 
823   return mInstructionContentOffset;
824 }
825 
826 /**
827 
828   Print the decimal unsigned QWORD to instruction content.
829 
830   @param  Data64 - unsigned QWORD data
831 
832   @return Instruction content offset
833 
834 **/
835 UINTN
EdbPrintData64n(IN UINT64 Data64)836 EdbPrintData64n (
837   IN UINT64                 Data64
838   )
839 {
840   EDBSPrintWithOffset (
841     mInstructionString.Content,
842     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
843     mInstructionContentOffset,
844     L"%ld",
845     Data64
846     );
847   mInstructionContentOffset = mInstructionContentOffset + EdbGetBitWidth (Data64);
848 
849   return mInstructionContentOffset;
850 }
851 
852 /**
853 
854   Print the decimal signed BYTE to instruction content.
855 
856   @param  Data8 - signed BYTE data
857 
858   @return Instruction content offset
859 
860 **/
861 UINTN
EdbPrintData8s(IN UINT8 Data8)862 EdbPrintData8s (
863   IN UINT8                  Data8
864   )
865 {
866   BOOLEAN Sign;
867 
868   Sign = (BOOLEAN)(Data8 >> 7);
869 
870   EDBSPrintWithOffset (
871     mInstructionString.Content,
872     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
873     mInstructionContentOffset,
874     L"%s%d",
875     Sign ? L"-" : L"+",
876     (UINTN)(Data8 & 0x7F)
877     );
878   mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data8 & 0x7F);
879 
880   return mInstructionContentOffset;
881 }
882 
883 /**
884 
885   Print the decimal signed WORD to instruction content.
886 
887   @param  Data16 - signed WORD data
888 
889   @return Instruction content offset
890 
891 **/
892 UINTN
EdbPrintData16s(IN UINT16 Data16)893 EdbPrintData16s (
894   IN UINT16                 Data16
895   )
896 {
897   BOOLEAN Sign;
898 
899   Sign = (BOOLEAN)(Data16 >> 15);
900 
901   EDBSPrintWithOffset (
902     mInstructionString.Content,
903     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
904     mInstructionContentOffset,
905     L"%s%d",
906     Sign ? L"-" : L"+",
907     (UINTN)(Data16 & 0x7FFF)
908     );
909   mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data16 & 0x7FFF);
910 
911   return mInstructionContentOffset;
912 }
913 
914 /**
915 
916   Print the decimal signed DWORD to instruction content.
917 
918   @param  Data32 - signed DWORD data
919 
920   @return Instruction content offset
921 
922 **/
923 UINTN
EdbPrintData32s(IN UINT32 Data32)924 EdbPrintData32s (
925   IN UINT32                 Data32
926   )
927 {
928   BOOLEAN Sign;
929 
930   Sign = (BOOLEAN)(Data32 >> 31);
931 
932   EDBSPrintWithOffset (
933     mInstructionString.Content,
934     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
935     mInstructionContentOffset,
936     L"%s%d",
937     Sign ? L"-" : L"+",
938     (UINTN)(Data32 & 0x7FFFFFFF)
939     );
940   mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data32 & 0x7FFFFFFF);
941 
942   return mInstructionContentOffset;
943 }
944 
945 /**
946 
947   Print the decimal signed QWORD to instruction content.
948 
949   @param  Data64 - signed QWORD data
950 
951   @return Instruction content offset
952 
953 **/
954 UINTN
EdbPrintData64s(IN UINT64 Data64)955 EdbPrintData64s (
956   IN UINT64                 Data64
957   )
958 {
959   BOOLEAN Sign;
960   INT64   Data64s;
961 
962   Sign = (BOOLEAN)RShiftU64 (Data64, 63);
963   Data64s = (INT64)RShiftU64 (LShiftU64 (Data64, 1), 1);
964 
965   EDBSPrintWithOffset (
966     mInstructionString.Content,
967     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
968     mInstructionContentOffset,
969     L"%s%ld",
970     Sign ? L"-" : L"+",
971     (UINT64)Data64s
972     );
973   mInstructionContentOffset = mInstructionContentOffset + 1 + EdbGetBitWidth (Data64s);
974 
975   return mInstructionContentOffset;
976 }
977 
978 /**
979 
980   Print the comma to instruction content.
981 
982   @return Instruction content offset
983 
984 **/
985 UINTN
EdbPrintComma(VOID)986 EdbPrintComma (
987   VOID
988   )
989 {
990   EDBSPrintWithOffset (
991     mInstructionString.Content,
992     EDB_INSTRUCTION_CONTENT_MAX_SIZE,
993     mInstructionContentOffset,
994     L", "
995     );
996   mInstructionContentOffset += 2;
997 
998   return mInstructionContentOffset;
999 }
1000 
1001 /**
1002 
1003   Find the symbol string according to address, then print it.
1004 
1005   @param  Address - instruction address
1006 
1007   @retval 1 - symbol string is found and printed
1008   @retval 0 - symbol string not found
1009 
1010 **/
1011 UINTN
EdbFindAndPrintSymbol(IN UINTN Address)1012 EdbFindAndPrintSymbol (
1013   IN UINTN                  Address
1014   )
1015 {
1016   CHAR8 *SymbolStr;
1017 
1018   SymbolStr = FindSymbolStr (Address);
1019   if (SymbolStr != NULL) {
1020     EDBSPrintWithOffset (
1021       mInstructionString.Content,
1022       EDB_INSTRUCTION_CONTENT_MAX_SIZE,
1023       mInstructionContentOffset,
1024       L"[%a]",
1025       SymbolStr
1026       );
1027     return 1;
1028   }
1029 
1030   return 0;
1031 }
1032 
1033 /**
1034 
1035   Print the EBC byte code.
1036 
1037   @param  InstructionAddress - instruction address
1038   @param  InstructionNumber  - instruction number
1039 
1040 **/
1041 VOID
EdbPrintRaw(IN EFI_PHYSICAL_ADDRESS InstructionAddress,IN UINTN InstructionNumber)1042 EdbPrintRaw (
1043   IN EFI_PHYSICAL_ADDRESS   InstructionAddress,
1044   IN UINTN                  InstructionNumber
1045   )
1046 {
1047   UINTN  LineNumber;
1048   UINTN  ByteNumber;
1049   UINTN  LineIndex;
1050   UINTN  ByteIndex;
1051   CHAR8  *SymbolStr;
1052 
1053   if (InstructionNumber == 0) {
1054     return ;
1055   }
1056 
1057   LineNumber = InstructionNumber / EDB_BYTECODE_NUMBER_IN_LINE;
1058   ByteNumber = InstructionNumber % EDB_BYTECODE_NUMBER_IN_LINE;
1059   if (ByteNumber == 0) {
1060     LineNumber -= 1;
1061     ByteNumber  = EDB_BYTECODE_NUMBER_IN_LINE;
1062   }
1063 
1064   //
1065   // Print Symbol
1066   //
1067   SymbolStr = FindSymbolStr ((UINTN)InstructionAddress);
1068   if (SymbolStr != NULL) {
1069     EDBPrint (L"[%a]:\n", SymbolStr);
1070   }
1071 
1072   for (LineIndex = 0; LineIndex < LineNumber; LineIndex++) {
1073     EDBPrint (EDB_PRINT_ADDRESS_FORMAT, (UINTN)InstructionAddress);
1074     for (ByteIndex = 0; ByteIndex < EDB_BYTECODE_NUMBER_IN_LINE; ByteIndex++) {
1075       EDBPrint (L"%02x ", *(UINT8 *)(UINTN)InstructionAddress);
1076       InstructionAddress += 1;
1077     }
1078     EDBPrint (L"\n");
1079   }
1080 
1081   EDBPrint (EDB_PRINT_ADDRESS_FORMAT, (UINTN)InstructionAddress);
1082   for (ByteIndex = 0; ByteIndex < ByteNumber; ByteIndex++) {
1083     EDBPrint (L"%02x ", *(UINT8 *)(UINTN)InstructionAddress);
1084     InstructionAddress += 1;
1085   }
1086   for (ByteIndex = 0; ByteIndex < EDB_BYTECODE_NUMBER_IN_LINE - ByteNumber; ByteIndex++) {
1087     EDBPrint (L"   ");
1088   }
1089 
1090   return ;
1091 }
1092 
1093 /**
1094 
1095   Print the EBC asm code.
1096 
1097   @param  DebuggerPrivate - EBC Debugger private data structure
1098   @param  SystemContext   - EBC system context.
1099 
1100   @retval EFI_SUCCESS - show disasm successfully
1101 
1102 **/
1103 EFI_STATUS
EdbShowDisasm(IN EFI_DEBUGGER_PRIVATE_DATA * DebuggerPrivate,IN EFI_SYSTEM_CONTEXT SystemContext)1104 EdbShowDisasm (
1105   IN     EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
1106   IN     EFI_SYSTEM_CONTEXT        SystemContext
1107   )
1108 {
1109   EFI_PHYSICAL_ADDRESS    InstructionAddress;
1110   UINTN                   InstructionNumber;
1111   UINTN                   InstructionLength;
1112   UINT8                   Opcode;
1113   CHAR16                  *InstructionString;
1114 //  UINTN                   Result;
1115 
1116   InstructionAddress = DebuggerPrivate->InstructionScope;
1117   for (InstructionNumber = 0; InstructionNumber < DebuggerPrivate->InstructionNumber; InstructionNumber++) {
1118 
1119     //
1120     // Break each 0x10 instruction
1121     //
1122     if (((InstructionNumber % EFI_DEBUGGER_LINE_NUMBER_IN_PAGE) == 0) &&
1123         (InstructionNumber != 0)) {
1124       if (SetPageBreak ()) {
1125         break;
1126       }
1127     }
1128 
1129     Opcode = GET_OPCODE(InstructionAddress);
1130     if ((Opcode < OPCODE_MAX) && (mEdbDisasmInstructionTable[Opcode] != NULL)) {
1131       InstructionLength = mEdbDisasmInstructionTable [Opcode] (InstructionAddress, SystemContext, &InstructionString);
1132       if (InstructionLength != 0) {
1133 
1134         //
1135         // Print Source
1136         //
1137 //        Result = EdbPrintSource ((UINTN)InstructionAddress, FALSE);
1138 
1139         if (!DebuggerPrivate->DebuggerSymbolContext.DisplayCodeOnly) {
1140 
1141           EdbPrintRaw (InstructionAddress, InstructionLength);
1142           if (InstructionString != NULL) {
1143             EDBPrint (L"%s\n", InstructionString);
1144           } else {
1145             EDBPrint (L"%s\n", L"<Unknown Instruction>");
1146           }
1147         }
1148 
1149         EdbPrintSource ((UINTN)InstructionAddress, TRUE);
1150 
1151         InstructionAddress += InstructionLength;
1152       } else {
1153         //
1154         // Something wrong with OPCODE
1155         //
1156         EdbPrintRaw (InstructionAddress, EDB_BYTECODE_NUMBER_IN_LINE);
1157         EDBPrint (L"%s\n", L"<Bad Instruction>");
1158         break;
1159       }
1160     } else {
1161       //
1162       // Something wrong with OPCODE
1163       //
1164       EdbPrintRaw (InstructionAddress, EDB_BYTECODE_NUMBER_IN_LINE);
1165       EDBPrint (L"%s\n", L"<Bad Instruction>");
1166       break;
1167     }
1168   }
1169 
1170   return EFI_SUCCESS;
1171 }
1172 
1173 /**
1174 
1175   Get register value according to the system context, and register index.
1176 
1177   @param  SystemContext   - EBC system context.
1178   @param  Index           - EBC register index
1179 
1180   @return register value
1181 
1182 **/
1183 UINT64
GetRegisterValue(IN EFI_SYSTEM_CONTEXT SystemContext,IN UINT8 Index)1184 GetRegisterValue (
1185   IN     EFI_SYSTEM_CONTEXT        SystemContext,
1186   IN     UINT8                     Index
1187   )
1188 {
1189   switch (Index) {
1190   case 0:
1191     return SystemContext.SystemContextEbc->R0;
1192   case 1:
1193     return SystemContext.SystemContextEbc->R1;
1194   case 2:
1195     return SystemContext.SystemContextEbc->R2;
1196   case 3:
1197     return SystemContext.SystemContextEbc->R3;
1198   case 4:
1199     return SystemContext.SystemContextEbc->R4;
1200   case 5:
1201     return SystemContext.SystemContextEbc->R5;
1202   case 6:
1203     return SystemContext.SystemContextEbc->R6;
1204   case 7:
1205     return SystemContext.SystemContextEbc->R7;
1206   default:
1207     ASSERT (FALSE);
1208     break;
1209   }
1210   return 0;
1211 }
1212