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