TianoCore EDK2 master
Loading...
Searching...
No Matches
EdbSymbol.c
Go to the documentation of this file.
1
9#include "Edb.h"
10
27 IN CHAR8 *Name,
28 IN CHAR8 *ObjName,
29 IN UINTN Address,
30 IN EFI_DEBUGGER_SYMBOL_TYPE Type
31 )
32{
34
35 //
36 // Check Count VS MaxCount
37 //
38 if (Object->EntryCount >= Object->MaxEntryCount) {
39 //
40 // reallocate (for codebuffer too)
41 // TBD
42 //
43 return EFI_OUT_OF_RESOURCES;
44 }
45
46 Entry = &Object->Entry[Object->EntryCount];
47
48 //
49 // Print Debug info
50 //
51 if (sizeof (UINTN) == sizeof (UINT64)) {
52 DEBUG ((DEBUG_ERROR, " Symbol: %a, Address: 0x%016lx (%d)\n", Name, (UINT64)Address, (UINTN)Type));
53 } else {
54 DEBUG ((DEBUG_ERROR, " Symbol: %a, Address: 0x%08x (%d)\n", Name, Address, (UINTN)Type));
55 }
56
57 //
58 // Fill the entry - name, RVA, type
59 //
60 AsciiStrnCpyS (Entry->Name, sizeof (Entry->Name), Name, sizeof (Entry->Name) - 1);
61 if (ObjName != NULL) {
62 AsciiStrnCpyS (Entry->ObjName, sizeof (Entry->ObjName), ObjName, sizeof (Entry->ObjName) - 1);
63 }
64
65 Entry->Rva = Address % EFI_DEBUGGER_DEFAULT_LINK_IMAGEBASE;
66 Entry->Type = Type;
67
68 //
69 // Increase Count
70 //
71 Object->EntryCount++;
72
73 //
74 // Done
75 //
76 return EFI_SUCCESS;
77}
78
79typedef enum {
80 EdbEbcMapParseStateUninitialized,
81 EdbEbcMapParseStateSymbolStart,
82 EdbEbcMapParseStateSeHandlerSymbol,
83 EdbEbcMapParseStateFunctionSymbol,
84 EdbEbcMapParseStateVarbssInitSymbol,
85 EdbEbcMapParseStateCrtSymbol,
86 EdbEbcMapParseStateVariableSymbol,
87 EdbEbcMapParseStateStaticFunctionSymbol,
88 EdbEbcMapParseStateMax,
89} EDB_EBC_MAP_PARSE_STATE;
90
91typedef enum {
92 EdbEbcSymbolParseStateUninitialized,
93 EdbEbcSymbolParseStateReadyForName,
94 EdbEbcSymbolParseStateReadyForRVA,
95 EdbEbcSymbolParseStateReadyForType,
96 EdbEbcSymbolParseStateReadyForObject,
97 EdbEbcSymbolParseStateMax,
98} EDB_EBC_SYMBOL_PARSE_STATE;
99
167 IN UINTN BufferSize,
168 IN VOID *Buffer
169 )
170{
171 CHAR8 *LineBuffer;
172 CHAR8 *FieldBuffer;
173 EDB_EBC_MAP_PARSE_STATE MapParseState;
174 EDB_EBC_SYMBOL_PARSE_STATE SymbolParseState;
175 CHAR8 *Name;
176 CHAR8 *ObjName;
177 UINTN Address;
178 EFI_DEBUGGER_SYMBOL_TYPE Type;
179
180 //
181 // Begin to parse the Buffer
182 //
183 LineBuffer = AsciiStrGetNewTokenLine (Buffer, "\n\r");
184 MapParseState = EdbEbcMapParseStateUninitialized;
185 //
186 // Check each line
187 //
188 while (LineBuffer != NULL) {
189 FieldBuffer = AsciiStrGetNewTokenField (LineBuffer, " ");
190 SymbolParseState = EdbEbcSymbolParseStateUninitialized;
191 //
192 // Init entry value
193 //
194 Name = NULL;
195 ObjName = NULL;
196 Address = 0;
197 Type = EfiDebuggerSymbolTypeMax;
198 //
199 // Check each field
200 //
201 while (FieldBuffer != NULL) {
202 if (AsciiStrCmp (FieldBuffer, "") == 0) {
203 FieldBuffer = AsciiStrGetNextTokenField (" ");
204 continue;
205 }
206
207 //
208 // check "Address"
209 //
210 if (AsciiStrCmp (FieldBuffer, "Address") == 0) {
211 MapParseState = EdbEbcMapParseStateSymbolStart;
212 break;
213 }
214
215 //
216 // check "Static"
217 //
218 if (AsciiStrCmp (FieldBuffer, "Static") == 0) {
219 MapParseState = EdbEbcMapParseStateStaticFunctionSymbol;
220 break;
221 }
222
223 if (MapParseState == EdbEbcMapParseStateUninitialized) {
224 //
225 // Do not parse anything until get "Address" or "Static"
226 //
227 break;
228 }
229
230 if (AsciiStrCmp (FieldBuffer, "entry") == 0) {
231 //
232 // Skip entry point
233 //
234 break;
235 }
236
237 //
238 // Now we start to parse this line for Name, Address, and Object
239 //
240 switch (SymbolParseState) {
241 case EdbEbcSymbolParseStateUninitialized:
242 //
243 // Get the Address
244 //
245 SymbolParseState = EdbEbcSymbolParseStateReadyForName;
246 break;
247 case EdbEbcSymbolParseStateReadyForName:
248 //
249 // Get the Name
250 //
251 if (AsciiStrnCmp (FieldBuffer, "___safe_se_handler", AsciiStrLen ("___safe_se_handler")) == 0) {
252 //
253 // skip SeHandler
254 //
255 MapParseState = EdbEbcMapParseStateSeHandlerSymbol;
256 goto ExitFieldParse;
257 } else if (AsciiStrnCmp (FieldBuffer, "varbss_init", AsciiStrLen ("varbss_init")) == 0) {
258 //
259 // check VarbssInit
260 //
261 MapParseState = EdbEbcMapParseStateVarbssInitSymbol;
262 // goto ExitFieldParse;
263 Name = FieldBuffer;
264 SymbolParseState = EdbEbcSymbolParseStateReadyForRVA;
265 } else if (AsciiStrnCmp (FieldBuffer, "Crt", AsciiStrLen ("Crt")) == 0) {
266 //
267 // check Crt
268 //
269 MapParseState = EdbEbcMapParseStateCrtSymbol;
270 // goto ExitFieldParse;
271 Name = FieldBuffer;
272 SymbolParseState = EdbEbcSymbolParseStateReadyForRVA;
273 } else {
274 //
275 // Now, it is normal function
276 //
277 switch (MapParseState) {
278 case EdbEbcMapParseStateSeHandlerSymbol:
279 MapParseState = EdbEbcMapParseStateFunctionSymbol;
280 break;
281 case EdbEbcMapParseStateCrtSymbol:
282 MapParseState = EdbEbcMapParseStateVariableSymbol;
283 break;
284 case EdbEbcMapParseStateFunctionSymbol:
285 case EdbEbcMapParseStateVariableSymbol:
286 case EdbEbcMapParseStateStaticFunctionSymbol:
287 break;
288 default:
289 ASSERT (FALSE);
290 break;
291 }
292
293 Name = FieldBuffer;
294 SymbolParseState = EdbEbcSymbolParseStateReadyForRVA;
295 }
296
297 break;
298 case EdbEbcSymbolParseStateReadyForRVA:
299 //
300 // Get the RVA
301 //
302 Address = AsciiXtoi (FieldBuffer);
303 SymbolParseState = EdbEbcSymbolParseStateReadyForType;
304 break;
305 case EdbEbcSymbolParseStateReadyForType:
306 //
307 // Get the Type. This is optional, only for "f".
308 //
309 if (AsciiStrCmp (FieldBuffer, "f") == 0) {
310 SymbolParseState = EdbEbcSymbolParseStateReadyForObject;
311 switch (MapParseState) {
312 case EdbEbcMapParseStateFunctionSymbol:
313 case EdbEbcMapParseStateVarbssInitSymbol:
314 Type = EfiDebuggerSymbolFunction;
315 break;
316 case EdbEbcMapParseStateStaticFunctionSymbol:
317 Type = EfiDebuggerSymbolStaticFunction;
318 break;
319 default:
320 ASSERT (FALSE);
321 break;
322 }
323
324 break;
325 }
326
327 //
328 // Else it should be Object.
329 // let it bypass here
330 //
331 case EdbEbcSymbolParseStateReadyForObject:
332 switch (Type) {
333 case EfiDebuggerSymbolTypeMax:
334 switch (MapParseState) {
335 case EdbEbcMapParseStateVariableSymbol:
336 case EdbEbcMapParseStateCrtSymbol:
337 Type = EfiDebuggerSymbolGlobalVariable;
338 break;
339 case EdbEbcMapParseStateSeHandlerSymbol:
340 //
341 // do nothing here
342 //
343 break;
344 default:
345 ASSERT (FALSE);
346 break;
347 }
348
349 break;
350 case EfiDebuggerSymbolFunction:
351 case EfiDebuggerSymbolStaticFunction:
352 break;
353 default:
354 ASSERT (FALSE);
355 break;
356 }
357
358 //
359 // Get the Object
360 //
361 ObjName = FieldBuffer;
362 SymbolParseState = EdbEbcSymbolParseStateUninitialized;
363 break;
364 default:
365 ASSERT (FALSE);
366 break;
367 }
368
369 //
370 // Get the next field
371 //
372 FieldBuffer = AsciiStrGetNextTokenField (" ");
373 }
374
375 //
376 // Add the entry if we get everything.
377 //
378 if ((Name != NULL) && (Type != EfiDebuggerSymbolTypeMax)) {
379 EdbLoadSymbolSingleEntry (Object, Name, ObjName, Address, Type);
380 }
381
382ExitFieldParse:
383 //
384 // Get the next line
385 //
386 LineBuffer = AsciiStrGetNextTokenLine ("\n\r");
387 }
388
389 //
390 // Done
391 //
392 return EFI_SUCCESS;
393}
394
409 IN UINTN BufferSize,
410 IN VOID *Buffer
411 )
412{
413 //
414 // MAP file format depends on the compiler (actually linker).
415 //
416 // It is possible to check the different MAP file format in this routine.
417 // Now only IEC is supported.
418 //
419 return EdbLoadSymbolEntryByIec (Object, BufferSize, Buffer);
420}
421
435 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
436 IN CHAR16 *FileName,
437 IN OUT UINTN *Index OPTIONAL
438 )
439{
440 UINTN ObjectIndex;
441
442 //
443 // Check each Object
444 //
445 for (ObjectIndex = 0; ObjectIndex < DebuggerPrivate->DebuggerSymbolContext.ObjectCount; ObjectIndex++) {
446 if (StrCmp (FileName, DebuggerPrivate->DebuggerSymbolContext.Object[ObjectIndex].Name) == 0) {
447 //
448 // Name match, found it
449 //
450 if (Index != NULL) {
451 *Index = ObjectIndex;
452 }
453
454 return &DebuggerPrivate->DebuggerSymbolContext.Object[ObjectIndex];
455 }
456 }
457
458 //
459 // Not found
460 //
461 return NULL;
462}
463
476UINTN
478 IN UINTN Address,
479 IN EDB_MATCH_SYMBOL_TYPE Type,
482 )
483{
484 UINTN Index;
485 UINTN SubIndex;
486 UINTN CandidateLowerAddress;
487 UINTN CandidateUpperAddress;
491 EFI_DEBUGGER_SYMBOL_ENTRY *UpperEntry;
493 EFI_DEBUGGER_SYMBOL_OBJECT *UpperObject;
494
495 if ((Type < 0) || (Type >= EdbMatchSymbolTypeMax)) {
496 return 0;
497 }
498
499 //
500 // Init
501 //
502 CandidateLowerAddress = 0;
503 CandidateUpperAddress = (UINTN)-1;
504 LowEntry = NULL;
505 UpperEntry = NULL;
506 LowObject = NULL;
507 UpperObject = NULL;
508
509 //
510 // Go through each object
511 //
512 Object = mDebuggerPrivate.DebuggerSymbolContext.Object;
513 for (Index = 0; Index < mDebuggerPrivate.DebuggerSymbolContext.ObjectCount; Index++, Object++) {
514 if (Object->EntryCount == 0) {
515 continue;
516 }
517
518 //
519 // Go through each entry
520 //
521 Entry = Object->Entry;
522 for (SubIndex = 0; SubIndex < Object->EntryCount; SubIndex++, Entry++) {
523 if (Address != Entry->Rva + Object->BaseAddress) {
524 //
525 // Check for nearest address
526 //
527 if (Address > Entry->Rva + Object->BaseAddress) {
528 //
529 // Record it if Current RVA < Address
530 //
531 if (CandidateLowerAddress < Entry->Rva + Object->BaseAddress) {
532 CandidateLowerAddress = Entry->Rva + Object->BaseAddress;
533 LowEntry = Entry;
534 LowObject = Object;
535 }
536 } else {
537 //
538 // Record it if Current RVA > Address
539 //
540 if (CandidateUpperAddress > Entry->Rva + Object->BaseAddress) {
541 CandidateUpperAddress = Entry->Rva + Object->BaseAddress;
542 UpperEntry = Entry;
543 UpperObject = Object;
544 }
545 }
546
547 continue;
548 }
549
550 //
551 // address match, return directly
552 //
553 *RetEntry = Entry;
554 *RetObject = Object;
555 return Address;
556 }
557 }
558
559 //
560 // No Match, provide latest symbol
561 //
562
563 if ((Address - CandidateLowerAddress) < EFI_DEBUGGER_MAX_SYMBOL_ADDRESS_DELTA_VALUE) {
564 //
565 // Check for lower address
566 //
567 if (((Type == EdbMatchSymbolTypeNearestAddress) &&
568 ((CandidateUpperAddress - Address) > (Address - CandidateLowerAddress))) ||
569 (Type == EdbMatchSymbolTypeLowerAddress))
570 {
571 //
572 // return nearest lower address
573 //
574 *RetEntry = LowEntry;
575 *RetObject = LowObject;
576 return CandidateLowerAddress;
577 }
578 }
579
580 if ((CandidateUpperAddress - Address) < EFI_DEBUGGER_MAX_SYMBOL_ADDRESS_DELTA_VALUE) {
581 //
582 // Check for upper address
583 //
584 if (((Type == EdbMatchSymbolTypeNearestAddress) &&
585 ((CandidateUpperAddress - Address) < (Address - CandidateLowerAddress))) ||
586 (Type == EdbMatchSymbolTypeUpperAddress))
587 {
588 //
589 // return nearest upper address
590 //
591 *RetEntry = UpperEntry;
592 *RetObject = UpperObject;
593 return CandidateUpperAddress;
594 }
595 }
596
597 //
598 // No match and nearest one, return NULL
599 //
600 return 0;
601}
602
615 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
616 IN CHAR16 *FileName
617 )
618{
620 UINTN ObjectIndex;
621 UINTN Index;
623 UINTN OldEntryCount;
624 UINTN MaxEntryCount;
625 VOID **OldSourceBuffer;
626
627 //
628 // Find Symbol
629 //
630 Object = EdbFindSymbolFile (DebuggerPrivate, FileName, &ObjectIndex);
631 if (Object == NULL) {
632 EDBPrint (L"SymbolFile is not loaded!\n");
633 return EFI_DEBUG_CONTINUE;
634 }
635
636 //
637 // Record old data
638 //
639 Object = DebuggerPrivate->DebuggerSymbolContext.Object;
640 OldEntry = Object->Entry;
641 OldSourceBuffer = Object->SourceBuffer;
642 MaxEntryCount = Object->MaxEntryCount;
643 OldEntryCount = Object->EntryCount;
644
645 //
646 // Remove the matched Object
647 //
648 for (Index = ObjectIndex; Index < DebuggerPrivate->DebuggerSymbolContext.ObjectCount - 1; Index++) {
649 CopyMem (&Object[Index], &Object[Index + 1], sizeof (EFI_DEBUGGER_SYMBOL_OBJECT));
650 }
651
652 ZeroMem (&Object[Index], sizeof (Object[Index]));
653
654 //
655 // Move old data to new place
656 //
657 Object[Index].Entry = OldEntry;
658 Object[Index].SourceBuffer = OldSourceBuffer;
659 Object[Index].MaxEntryCount = MaxEntryCount;
660 DebuggerPrivate->DebuggerSymbolContext.ObjectCount--;
661
662 //
663 // Clean old entry data
664 //
665 for (Index = 0; Index < OldEntryCount; Index++) {
666 ZeroMem (&OldEntry[Index], sizeof (OldEntry[Index]));
667 }
668
669 //
670 // Free OldSourceBuffer
671 //
672 for (Index = 0; OldSourceBuffer[Index] != NULL; Index++) {
673 gBS->FreePool (OldSourceBuffer[Index]);
674 OldSourceBuffer[Index] = NULL;
675 }
676
677 return EFI_SUCCESS;
678}
679
694 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
695 IN CHAR16 *FileName,
696 IN UINTN BufferSize,
697 IN VOID *Buffer
698 )
699{
701 EFI_STATUS Status;
702
703 //
704 // Check duplicated File
705 //
706 Object = EdbFindSymbolFile (DebuggerPrivate, FileName, NULL);
707 if (Object != NULL) {
708 Status = EdbUnloadSymbol (DebuggerPrivate, FileName);
709 if (EFI_ERROR (Status)) {
710 DEBUG ((DEBUG_ERROR, "Unload Duplicated Symbol File Error!\n"));
711 return Status;
712 }
713 }
714
715 //
716 // Check Count VS MaxCount
717 //
718 if (DebuggerPrivate->DebuggerSymbolContext.ObjectCount >= DebuggerPrivate->DebuggerSymbolContext.MaxObjectCount) {
719 //
720 // reallocate
721 // TBD
722 //
723 return EFI_OUT_OF_RESOURCES;
724 }
725
726 Object = &DebuggerPrivate->DebuggerSymbolContext.Object[DebuggerPrivate->DebuggerSymbolContext.ObjectCount];
727
728 //
729 // Init Object
730 //
731 Object->EntryCount = 0;
732 Object->MaxEntryCount = EFI_DEBUGGER_SYMBOL_ENTRY_MAX;
733
734 //
735 // Load SymbolEntry
736 //
737 DEBUG ((DEBUG_ERROR, "Symbol File: %s\n", FileName));
738 Status = EdbLoadSymbolEntry (Object, BufferSize, Buffer);
739 if (EFI_ERROR (Status)) {
740 return Status;
741 }
742
743 //
744 // Fill Object value
745 //
746 StrnCpyS (
747 Object->Name,
748 sizeof (Object->Name) / sizeof (CHAR16),
749 FileName,
750 (sizeof (Object->Name) / sizeof (CHAR16)) - 1
751 );
752 Object->BaseAddress = 0;
753
754 //
755 // Increase the object count
756 //
757 DebuggerPrivate->DebuggerSymbolContext.ObjectCount++;
758
759 return EFI_SUCCESS;
760}
761
772CHAR8 *
774 VOID *ImageBase
775 )
776{
777 CHAR8 *PdbPath;
778 UINT32 DirCount;
779 EFI_IMAGE_DOS_HEADER *DosHdr;
781 EFI_IMAGE_OPTIONAL_HEADER32 *OptionalHdr32;
782 EFI_IMAGE_OPTIONAL_HEADER64 *OptionalHdr64;
783 EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
785 VOID *CodeViewEntryPointer;
786
787 //
788 // Init value
789 //
790 CodeViewEntryPointer = NULL;
791 PdbPath = NULL;
792 DosHdr = ImageBase;
793
794 //
795 // Check magic
796 //
797 if (DosHdr->e_magic != EFI_IMAGE_DOS_SIGNATURE) {
798 return NULL;
799 }
800
801 NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((UINT8 *)DosHdr + DosHdr->e_lfanew);
802 //
803 // Check Machine, filter for EBC
804 //
805 if (NtHdr->Pe32.FileHeader.Machine != EFI_IMAGE_MACHINE_EBC) {
806 //
807 // If not EBC, return NULL
808 //
809 return NULL;
810 }
811
812 //
813 // Get DirectoryEntry
814 // EBC spec says PE32+, but implementation uses PE32. So check dynamically here.
815 //
816 if (NtHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
817 OptionalHdr32 = (VOID *)&NtHdr->Pe32.OptionalHeader;
818 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(OptionalHdr32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
819 } else if (NtHdr->Pe32Plus.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
820 OptionalHdr64 = (VOID *)&NtHdr->Pe32Plus.OptionalHeader;
821 DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(OptionalHdr64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
822 } else {
823 return NULL;
824 }
825
826 if (DirectoryEntry->VirtualAddress == 0) {
827 return NULL;
828 }
829
830 //
831 // Go through DirectoryEntry
832 //
833 for (DirCount = 0;
834 (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && CodeViewEntryPointer == NULL;
835 DirCount++
836 )
837 {
838 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(DirectoryEntry->VirtualAddress + (UINTN)ImageBase + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
839 if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
840 //
841 // Match DebugEntry, only CODEVIEW_SIGNATURE_NB10 and CODEVIEW_SIGNATURE_RSDS are supported.
842 //
843 CodeViewEntryPointer = (VOID *)((UINTN)DebugEntry->RVA + (UINTN)ImageBase);
844 switch (*(UINT32 *)CodeViewEntryPointer) {
846 PdbPath = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
847 break;
849 PdbPath = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
850 break;
851 default:
852 break;
853 }
854 }
855 }
856
857 //
858 // Done successfully
859 //
860 return PdbPath;
861}
862
874BOOLEAN
876 IN CHAR8 *PdbFileName,
877 IN CHAR16 *MapFileName
878 )
879{
880 UINTN PdbNameSize;
881 UINTN MapNameSize;
882 CHAR8 *PurePdbFileName;
883 UINTN Index;
884
885 //
886 // remove dir name
887 //
888 PurePdbFileName = PdbFileName;
889 for (Index = 0; PdbFileName[Index] != 0; Index++) {
890 if (PdbFileName[Index] == '\\') {
891 PurePdbFileName = &PdbFileName[Index + 1];
892 }
893 }
894
895 PdbFileName = PurePdbFileName;
896
897 //
898 // get size
899 //
900 PdbNameSize = AsciiStrLen (PdbFileName);
901 MapNameSize = StrLen (MapFileName);
902
903 if (PdbNameSize != MapNameSize) {
904 return FALSE;
905 }
906
907 //
908 // check the name
909 //
910 for (Index = 0; Index < MapNameSize - 4; Index++) {
911 if ((PdbFileName[Index] | 0x20) != (MapFileName[Index] | 0x20)) {
912 return FALSE;
913 }
914 }
915
916 return TRUE;
917}
918
919//
920// BUGBUG: work-around start
921//
922typedef struct {
923 EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable;
924 volatile UINT32 UpdateStatus;
925 UINT32 TableSize;
927
928EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugImageInfoTableHeader;
929
958VOID
960 IN OUT EFI_DEBUG_IMAGE_INFO_TABLE_HEADER **DebugImageInfoTableHeader
961 )
962{
963 mDebugImageInfoTableHeader.EfiDebugImageInfoTable = ((EFI_DEBUG_IMAGE_INFO_TABLE_HEADER_OLD *)(*DebugImageInfoTableHeader))->EfiDebugImageInfoTable;
964 mDebugImageInfoTableHeader.UpdateStatus = ((EFI_DEBUG_IMAGE_INFO_TABLE_HEADER_OLD *)(*DebugImageInfoTableHeader))->UpdateStatus;
965 mDebugImageInfoTableHeader.TableSize = ((EFI_DEBUG_IMAGE_INFO_TABLE_HEADER_OLD *)(*DebugImageInfoTableHeader))->TableSize;
966
967 if ((*DebugImageInfoTableHeader)->UpdateStatus > 3) {
968 *DebugImageInfoTableHeader = &mDebugImageInfoTableHeader;
969 return;
970 }
971
972 if ((*DebugImageInfoTableHeader)->TableSize % (EFI_PAGE_SIZE / (sizeof (VOID *))) != 0) {
973 *DebugImageInfoTableHeader = &mDebugImageInfoTableHeader;
974 return;
975 }
976
977 return;
978}
979
980//
981// BUGBUG: work-around end
982//
983
998 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
999 IN CHAR16 *FileName,
1000 IN EDB_EBC_IMAGE_RVA_SEARCH_TYPE SearchType
1001 )
1002{
1003 EFI_STATUS Status;
1004 UINTN ImageNumber;
1005 EFI_DEBUG_IMAGE_INFO *ImageTable;
1006 CHAR8 *PdbPath;
1007 VOID *ImageBase;
1008 VOID *CandidateImageBase;
1010
1011 if ((SearchType < 0) || (SearchType >= EdbEbcImageRvaSearchTypeMax)) {
1012 return EFI_INVALID_PARAMETER;
1013 }
1014
1015 //
1016 // Get the related object
1017 //
1018 Object = EdbFindSymbolFile (DebuggerPrivate, FileName, NULL);
1019 if (Object == NULL) {
1020 return EFI_NOT_FOUND;
1021 }
1022
1023 //
1024 // Try again to get DebugImageInfoTable
1025 //
1026 if (mDebuggerPrivate.DebugImageInfoTableHeader == NULL) {
1028 &gEfiDebugImageInfoTableGuid,
1029 (VOID **)&mDebuggerPrivate.DebugImageInfoTableHeader
1030 );
1031 if (EFI_ERROR (Status)) {
1032 EDBPrint (L"DebugImageInfoTable not found!\n");
1033 return Status;
1034 }
1035 }
1036
1037 DEBUG ((DEBUG_ERROR, "DebugImageInfoTableHeader: %x\n", mDebuggerPrivate.DebugImageInfoTableHeader));
1038
1039 //
1040 // BUGBUG: work-around start
1041 //
1042 EdbFixDebugImageInfoTable (&mDebuggerPrivate.DebugImageInfoTableHeader);
1043 //
1044 // BUGBUG: work-around end
1045 //
1046
1047 //
1048 // Go through DebugImageInfoTable for each Image
1049 //
1050 CandidateImageBase = NULL;
1051 ImageTable = mDebuggerPrivate.DebugImageInfoTableHeader->EfiDebugImageInfoTable;
1052 for (ImageNumber = 0; ImageNumber < mDebuggerPrivate.DebugImageInfoTableHeader->TableSize; ImageNumber++) {
1053 if (ImageTable[ImageNumber].NormalImage == NULL) {
1054 continue;
1055 }
1056
1057 ImageBase = ImageTable[ImageNumber].NormalImage->LoadedImageProtocolInstance->ImageBase;
1058 //
1059 // Get PDB path
1060 //
1061 PdbPath = GetPdbPath (ImageBase);
1062 if (PdbPath == NULL) {
1063 continue;
1064 }
1065
1066 //
1067 // Check PDB name
1068 //
1069 if (!MatchPdbAndMap (PdbPath, FileName)) {
1070 continue;
1071 }
1072
1073 DEBUG ((DEBUG_ERROR, "ImageBase: %x\n", ImageBase));
1074
1075 //
1076 // Check SearchType
1077 //
1078 if ((SearchType == EdbEbcImageRvaSearchTypeAny) || (SearchType == EdbEbcImageRvaSearchTypeFirst)) {
1079 //
1080 // Assign base address and return
1081 //
1082 Object->BaseAddress = (UINTN)ImageBase;
1083 return EFI_SUCCESS;
1084 }
1085
1086 //
1087 // Get CandidateImageBase for EdbEbcImageRvaSearchTypeLast
1088 //
1089 CandidateImageBase = ImageBase;
1090 }
1091
1092 //
1093 // Check EdbEbcImageRvaSearchTypeLast
1094 //
1095 if (SearchType == EdbEbcImageRvaSearchTypeLast) {
1096 if (CandidateImageBase == NULL) {
1097 return EFI_NOT_FOUND;
1098 }
1099
1100 //
1101 // Assign base address and return
1102 //
1103 Object->BaseAddress = (UINTN)CandidateImageBase;
1104 return EFI_SUCCESS;
1105 }
1106
1107 //
1108 // No match
1109 //
1110 return EFI_NOT_FOUND;
1111}
1112
1124BOOLEAN
1126 IN CHAR8 *ObjFileName,
1127 IN CHAR16 *CodFileName
1128 )
1129{
1130 UINTN ObjNameSize;
1131 UINTN CodNameSize;
1132 CHAR8 *PureObjFileName;
1133 UINTN Index;
1134
1135 //
1136 // remove library name
1137 //
1138 PureObjFileName = ObjFileName;
1139 for (Index = 0; ObjFileName[Index] != 0; Index++) {
1140 if (ObjFileName[Index] == ':') {
1141 PureObjFileName = &ObjFileName[Index + 1];
1142 break;
1143 }
1144 }
1145
1146 ObjFileName = PureObjFileName;
1147
1148 //
1149 // get size
1150 //
1151 ObjNameSize = AsciiStrLen (ObjFileName);
1152 CodNameSize = StrLen (CodFileName);
1153
1154 if (ObjNameSize != CodNameSize) {
1155 return FALSE;
1156 }
1157
1158 //
1159 // check the name
1160 //
1161 for (Index = 0; Index < CodNameSize - 4; Index++) {
1162 if ((ObjFileName[Index] | 0x20) != (CodFileName[Index] | 0x20)) {
1163 return FALSE;
1164 }
1165 }
1166
1167 return TRUE;
1168}
1169
1170typedef enum {
1171 EdbEbcCodParseStateUninitialized,
1172 EdbEbcCodParseStateSymbolInitialized,
1173 EdbEbcCodParseStateSymbolStart,
1174 EdbEbcCodParseStateSymbolEnd,
1175 EdbEbcCodParseStateMax,
1176} EDB_EBC_COD_PARSE_STATE;
1177
1197CHAR8 *
1199 IN CHAR8 *Name,
1200 IN VOID *Buffer,
1201 IN UINTN BufferSize,
1202 OUT UINTN *CodeBufferSize,
1203 OUT UINTN *FuncOffset
1204 )
1205{
1206 CHAR8 *LineBuffer;
1207 CHAR8 *FieldBuffer;
1208 VOID *BufferStart;
1209 VOID *BufferEnd;
1210 UINTN Offset;
1211 EDB_EBC_COD_PARSE_STATE CodParseState;
1212 CHAR8 Char[2];
1213
1214 //
1215 // Init
1216 //
1217 Char[0] = 9;
1218 Char[1] = 0;
1219 LineBuffer = AsciiStrGetNewTokenLine (Buffer, "\n\r");
1220 Offset = (UINTN)-1;
1221 BufferStart = NULL;
1222 BufferEnd = NULL;
1223 CodParseState = EdbEbcCodParseStateUninitialized;
1224
1225 //
1226 // Check each line
1227 //
1228 while (LineBuffer != NULL) {
1229 switch (CodParseState) {
1230 case EdbEbcCodParseStateUninitialized:
1231 //
1232 // check mark_begin, begin to check line after this match
1233 //
1234 if (AsciiStrCmp (LineBuffer, "; mark_begin;") == 0) {
1235 CodParseState = EdbEbcCodParseStateSymbolInitialized;
1236 }
1237
1238 LineBuffer = AsciiStrGetNextTokenLine ("\n\r");
1239 PatchForAsciiStrTokenBefore (LineBuffer, '\n');
1240 break;
1241
1242 case EdbEbcCodParseStateSymbolInitialized:
1243 //
1244 // check mark_end, not check line after this match
1245 //
1246 if (AsciiStrCmp (LineBuffer, "; mark_end;") == 0) {
1247 CodParseState = EdbEbcCodParseStateUninitialized;
1248 LineBuffer = AsciiStrGetNextTokenLine ("\n\r");
1249 PatchForAsciiStrTokenBefore (LineBuffer, '\n');
1250 break;
1251 }
1252
1253 //
1254 // not check this line if the first char is as follows
1255 //
1256 if ((*LineBuffer == 0) ||
1257 (*LineBuffer == '$') ||
1258 (*LineBuffer == ';') ||
1259 (*LineBuffer == '_') ||
1260 (*LineBuffer == ' '))
1261 {
1262 LineBuffer = AsciiStrGetNextTokenLine ("\n\r");
1263 PatchForAsciiStrTokenBefore (LineBuffer, '\n');
1264 break;
1265 }
1266
1267 //
1268 // get function name, function name is followed by char 0x09.
1269 //
1270 FieldBuffer = AsciiStrGetNewTokenField (LineBuffer, Char);
1271 ASSERT (FieldBuffer != NULL);
1272 if (AsciiStriCmp (FieldBuffer, Name) == 0) {
1273 BufferStart = FieldBuffer;
1274 CodParseState = EdbEbcCodParseStateSymbolStart;
1275 }
1276
1277 PatchForAsciiStrTokenAfter (FieldBuffer, 0x9);
1278
1279 //
1280 // Get next line
1281 //
1282 LineBuffer = AsciiStrGetNextTokenLine ("\n\r");
1283 PatchForAsciiStrTokenBefore (LineBuffer, '\n');
1284 break;
1285
1286 case EdbEbcCodParseStateSymbolStart:
1287 //
1288 // check mark_end, if this match, means the function is found successfully.
1289 //
1290 if (AsciiStrCmp (LineBuffer, "; mark_end;") == 0) {
1291 CodParseState = EdbEbcCodParseStateSymbolEnd;
1292 //
1293 // prepare CodeBufferSize, FuncOffset, and FuncStart to return
1294 //
1295 BufferEnd = LineBuffer + sizeof ("; mark_end;") - 1;
1296 *CodeBufferSize = (UINTN)BufferEnd - (UINTN)BufferStart;
1297 *FuncOffset = Offset;
1298 PatchForAsciiStrTokenAfter (LineBuffer, '\n');
1299 return BufferStart;
1300 }
1301
1302 //
1303 // Get function offset
1304 //
1305 if ((Offset == (UINTN)-1) &&
1306 (*LineBuffer == ' '))
1307 {
1308 FieldBuffer = AsciiStrGetNewTokenField (LineBuffer + 2, " ");
1309 Offset = AsciiXtoi (FieldBuffer);
1310 PatchForAsciiStrTokenAfter (FieldBuffer, ' ');
1311 }
1312
1313 //
1314 // Get next line
1315 //
1316 LineBuffer = AsciiStrGetNextTokenLine ("\n\r");
1317 PatchForAsciiStrTokenBefore (LineBuffer, '\n');
1318 break;
1319
1320 case EdbEbcCodParseStateSymbolEnd:
1321 break;
1322
1323 default:
1324 break;
1325 }
1326 }
1327
1328 //
1329 // no function found
1330 //
1331 return NULL;
1332}
1333
1347CHAR8 *
1349 IN CHAR8 *Name,
1350 IN VOID *Buffer,
1351 IN UINTN BufferSize,
1352 OUT UINTN *CodeBufferSize,
1353 OUT UINTN *FuncOffset
1354 )
1355{
1356 //
1357 // COD file format depends on the compiler.
1358 //
1359 // It is possible to check the different COD file format in this routine.
1360 // Now only IEC is supported.
1361 //
1362 return EdbLoadCodBySymbolByIec (Name, Buffer, BufferSize, CodeBufferSize, FuncOffset);
1363}
1364
1374VOID *
1376 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
1378 IN CHAR16 *FileName
1379 )
1380{
1381 UINTN EntryIndex;
1382
1383 //
1384 // Go througn each Entry in this Object
1385 //
1386 for (EntryIndex = 0; EntryIndex < Object->EntryCount; EntryIndex++) {
1387 //
1388 // This check is for Function only
1389 //
1390 if ((Object->Entry[EntryIndex].Type != EfiDebuggerSymbolFunction) &&
1391 (Object->Entry[EntryIndex].Type != EfiDebuggerSymbolStaticFunction))
1392 {
1393 continue;
1394 }
1395
1396 //
1397 // Skip match varbss_init function, because they has no source code
1398 //
1399 if (AsciiStrnCmp (Object->Entry[EntryIndex].Name, "varbss_init", sizeof ("varbss_init") - 1) == 0) {
1400 continue;
1401 }
1402
1403 //
1404 // check the name
1405 //
1406 if (!MatchObjAndCod (Object->Entry[EntryIndex].ObjName, FileName)) {
1407 continue;
1408 }
1409
1410 //
1411 // found it, return source buffer
1412 //
1413 if (Object->Entry[EntryIndex].CodBuffer != NULL) {
1414 return Object->Entry[EntryIndex].SourceBuffer;
1415 }
1416 }
1417
1418 //
1419 // not found
1420 //
1421 return NULL;
1422}
1423
1439 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
1440 IN CHAR16 *MapFileName,
1441 IN CHAR16 *FileName,
1442 IN UINTN BufferSize,
1443 IN VOID *Buffer
1444 )
1445{
1447 UINTN ObjectIndex;
1448 UINTN EntryIndex;
1449 VOID *SourceBuffer;
1450 EFI_STATUS Status;
1451
1452 //
1453 // Find Symbol
1454 //
1455 Object = EdbFindSymbolFile (DebuggerPrivate, MapFileName, &ObjectIndex);
1456 if (Object == NULL) {
1457 EDBPrint (L"SymbolFile is not loaded!\n");
1458 return EFI_NOT_FOUND;
1459 } else {
1460 //
1461 // Check duplicated File
1462 //
1463 SourceBuffer = EdbFindCodeFromObject (DebuggerPrivate, Object, FileName);
1464 if (SourceBuffer != NULL) {
1465 //
1466 // unnload duplicated code
1467 //
1468 Status = EdbUnloadCode (DebuggerPrivate, MapFileName, FileName, &SourceBuffer);
1469 if (EFI_ERROR (Status)) {
1470 DEBUG ((DEBUG_ERROR, "Unload Duplicated Code File Error!\n"));
1471 return Status;
1472 }
1473
1474 Status = EdbDeleteCodeBuffer (DebuggerPrivate, MapFileName, FileName, SourceBuffer);
1475 if (EFI_ERROR (Status)) {
1476 DEBUG ((DEBUG_ERROR, "Delete Duplicated Code File Error!\n"));
1477 return Status;
1478 }
1479 }
1480 }
1481
1482 //
1483 // Go through each SymbolEntry
1484 //
1485 for (EntryIndex = 0; EntryIndex < Object->EntryCount; EntryIndex++) {
1486 //
1487 // load symbol for function only
1488 //
1489 if ((Object->Entry[EntryIndex].Type != EfiDebuggerSymbolFunction) &&
1490 (Object->Entry[EntryIndex].Type != EfiDebuggerSymbolStaticFunction))
1491 {
1492 continue;
1493 }
1494
1495 //
1496 // skip varbss_init
1497 //
1498 if (AsciiStrnCmp (Object->Entry[EntryIndex].Name, "varbss_init", sizeof ("varbss_init") - 1) == 0) {
1499 continue;
1500 }
1501
1502 //
1503 // Check the name
1504 //
1505 if (!MatchObjAndCod (Object->Entry[EntryIndex].ObjName, FileName)) {
1506 continue;
1507 }
1508
1509 //
1510 // load code for this symbol
1511 //
1512 Object->Entry[EntryIndex].CodBuffer = EdbLoadCodBySymbol (
1513 Object->Entry[EntryIndex].Name,
1514 Buffer,
1515 BufferSize,
1516 &Object->Entry[EntryIndex].CodBufferSize,
1517 &Object->Entry[EntryIndex].FuncOffsetBase
1518 );
1519 if (Object->Entry[EntryIndex].CodBuffer != NULL) {
1520 Object->Entry[EntryIndex].SourceBuffer = Buffer;
1521 }
1522 }
1523
1524 //
1525 // patch end '\0' for each code buffer
1526 //
1527 for (EntryIndex = 0; EntryIndex < Object->EntryCount; EntryIndex++) {
1528 if (Object->Entry[EntryIndex].CodBuffer != NULL) {
1529 *((UINT8 *)Object->Entry[EntryIndex].CodBuffer + Object->Entry[EntryIndex].CodBufferSize) = 0;
1530 DEBUG ((DEBUG_ERROR, " CodeSymbol: %a, FuncOffset: 0x05%x\n", Object->Entry[EntryIndex].Name, Object->Entry[EntryIndex].FuncOffsetBase));
1531 // DEBUG ((DEBUG_ERROR, " [CODE]:\n%a\n", Object->Entry[EntryIndex].CodBuffer));
1532 }
1533 }
1534
1535 //
1536 // Done
1537 //
1538 return EFI_SUCCESS;
1539}
1540
1555 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
1556 IN CHAR16 *MapFileName,
1557 IN CHAR16 *FileName,
1558 OUT VOID **Buffer
1559 )
1560{
1562 UINTN ObjectIndex;
1563 UINTN EntryIndex;
1564
1565 //
1566 // Find Symbol
1567 //
1568 Object = EdbFindSymbolFile (DebuggerPrivate, MapFileName, &ObjectIndex);
1569 if (Object == NULL) {
1570 EDBPrint (L"SymbolFile is not loaded!\n");
1571 return EFI_NOT_FOUND;
1572 }
1573
1574 //
1575 // Find code
1576 //
1577 *Buffer = EdbFindCodeFromObject (DebuggerPrivate, Object, FileName);
1578 if (*Buffer == NULL) {
1579 EDBPrint (L"CodeFile is not loaded!\n");
1580 return EFI_NOT_FOUND;
1581 }
1582
1583 //
1584 // go through each entry
1585 //
1586 for (EntryIndex = 0; EntryIndex < Object->EntryCount; EntryIndex++) {
1587 if ((Object->Entry[EntryIndex].Type != EfiDebuggerSymbolFunction) &&
1588 (Object->Entry[EntryIndex].Type != EfiDebuggerSymbolStaticFunction))
1589 {
1590 continue;
1591 }
1592
1593 if (AsciiStrnCmp (Object->Entry[EntryIndex].Name, "varbss_init", sizeof ("varbss_init") - 1) == 0) {
1594 continue;
1595 }
1596
1597 if (!MatchObjAndCod (Object->Entry[EntryIndex].ObjName, FileName)) {
1598 continue;
1599 }
1600
1601 //
1602 // clean up the buffer
1603 //
1604 Object->Entry[EntryIndex].CodBuffer = NULL;
1605 Object->Entry[EntryIndex].CodBufferSize = 0;
1606 Object->Entry[EntryIndex].FuncOffsetBase = 0;
1607 Object->Entry[EntryIndex].SourceBuffer = NULL;
1608 }
1609
1610 //
1611 // Done
1612 //
1613 return EFI_SUCCESS;
1614}
1615
1631 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
1632 IN CHAR16 *MapFileName,
1633 IN CHAR16 *CodeFileName,
1634 IN UINTN SourceBufferSize,
1635 IN VOID *SourceBuffer
1636 )
1637{
1638 UINTN Index;
1640
1641 //
1642 // Find Symbol
1643 //
1644 Object = EdbFindSymbolFile (DebuggerPrivate, MapFileName, NULL);
1645 if (Object == NULL) {
1646 EDBPrint (L"SymbolFile is not loaded!\n");
1647 return EFI_NOT_FOUND;
1648 }
1649
1650 //
1651 // Add it to last entry
1652 //
1653 for (Index = 0; Object->SourceBuffer[Index] != NULL; Index++) {
1654 }
1655
1656 Object->SourceBuffer[Index] = SourceBuffer;
1657
1658 return EFI_SUCCESS;
1659}
1660
1675 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
1676 IN CHAR16 *MapFileName,
1677 IN CHAR16 *CodeFileName,
1678 IN VOID *SourceBuffer
1679 )
1680{
1681 UINTN Index;
1683
1684 //
1685 // Find Symbol
1686 //
1687 Object = EdbFindSymbolFile (DebuggerPrivate, MapFileName, NULL);
1688 if (Object == NULL) {
1689 EDBPrint (L"SymbolFile is not loaded!\n");
1690 return EFI_NOT_FOUND;
1691 }
1692
1693 for (Index = 0; Object->SourceBuffer[Index] != NULL; Index++) {
1694 //
1695 // free the buffer if match
1696 //
1697 if (Object->SourceBuffer[Index] == SourceBuffer) {
1698 gBS->FreePool (SourceBuffer);
1699 break;
1700 }
1701 }
1702
1703 if (Object->SourceBuffer[Index] == NULL) {
1704 //
1705 // not return NOT_FOUND
1706 //
1707 return EFI_SUCCESS;
1708 }
1709
1710 //
1711 // remove the entry
1712 //
1713 Object->SourceBuffer[Index] = NULL;
1714 for (Index = Index + 1; Object->SourceBuffer[Index] != NULL; Index++) {
1715 Object->SourceBuffer[Index - 1] = Object->SourceBuffer[Index];
1716 }
1717
1718 Object->SourceBuffer[Index - 1] = NULL;
1719
1720 return EFI_SUCCESS;
1721}
1722
1732CHAR8 *
1734 IN UINTN Address
1735 )
1736{
1737 UINTN ObjectIndex;
1739 UINTN EntryIndex;
1741
1742 //
1743 // need we display symbol
1744 //
1745 if (!mDebuggerPrivate.DebuggerSymbolContext.DisplaySymbol) {
1746 return NULL;
1747 }
1748
1749 //
1750 // Go through each object and entry
1751 //
1752 Object = mDebuggerPrivate.DebuggerSymbolContext.Object;
1753 for (ObjectIndex = 0; ObjectIndex < mDebuggerPrivate.DebuggerSymbolContext.ObjectCount; ObjectIndex++) {
1754 Entry = Object[ObjectIndex].Entry;
1755 for (EntryIndex = 0; EntryIndex < Object[ObjectIndex].EntryCount; EntryIndex++) {
1756 //
1757 // if Address match, return Name
1758 //
1759 if (Address == (Entry[EntryIndex].Rva + Object[ObjectIndex].BaseAddress)) {
1760 return Entry[EntryIndex].Name;
1761 }
1762 }
1763 }
1764
1765 //
1766 // not found
1767 //
1768 return NULL;
1769}
1770
1781UINTN
1783 IN VOID *Line,
1784 OUT UINTN *Offset
1785 )
1786{
1787 UINTN LineNumber;
1788 CHAR8 *LineBuffer;
1789 CHAR8 *FieldBuffer;
1790
1791 LineNumber = (UINTN)-1;
1792 LineBuffer = Line;
1793 *Offset = (UINTN)-1;
1794
1795 while (LineBuffer != NULL) {
1796 //
1797 // Check candidate
1798 //
1799 if (*LineBuffer != ' ') {
1800 return (UINTN)-1;
1801 }
1802
1803 //
1804 // Get Offset
1805 //
1806 if (*(LineBuffer + 2) != ' ') {
1807 if (*Offset == (UINTN)-1) {
1808 FieldBuffer = AsciiStrGetNewTokenField (LineBuffer + 2, " ");
1809 *Offset = AsciiXtoi (FieldBuffer);
1810 PatchForAsciiStrTokenAfter (FieldBuffer, ' ');
1811 }
1812 }
1813
1814 //
1815 // 1. assembly instruction
1816 //
1817 FieldBuffer = AsciiStrGetNewTokenField (LineBuffer, ":");
1818 //
1819 // 2. file path
1820 //
1821 FieldBuffer = AsciiStrGetNextTokenField (":");
1822 PatchForAsciiStrTokenBefore (FieldBuffer, ':');
1823 if (FieldBuffer == NULL) {
1824 //
1825 // candidate found
1826 //
1827 LineNumber = 0;
1828 LineBuffer = AsciiStrGetNextTokenLine ("\n");
1829 PatchForAsciiStrTokenBefore (LineBuffer, '\n');
1830 continue;
1831 }
1832
1833 //
1834 // 3. line number
1835 //
1836 FieldBuffer = AsciiStrGetNextTokenField (":");
1837 PatchForAsciiStrTokenBefore (FieldBuffer, ':');
1838 if (FieldBuffer == NULL) {
1839 //
1840 // impossible, TBD?
1841 //
1842 LineBuffer = AsciiStrGetNextTokenLine ("\n");
1843 PatchForAsciiStrTokenBefore (LineBuffer, '\n');
1844 continue;
1845 }
1846
1847 LineNumber = AsciiAtoi (FieldBuffer);
1848 //
1849 // Not patch after
1850 //
1851
1852 return LineNumber;
1853 }
1854
1855 return (UINTN)-1;
1856}
1857
1858typedef enum {
1859 EdbEbcLineSearchTypeAny,
1860 EdbEbcLineSearchTypeFirst,
1861 EdbEbcLineSearchTypeLast,
1862 EdbEbcLineSearchTypeMax,
1863} EDB_EBC_LINE_SEARCH_TYPE;
1864
1876UINTN
1879 IN UINTN FuncOffset,
1880 IN EDB_EBC_LINE_SEARCH_TYPE SearchType
1881 )
1882{
1883 CHAR8 *LineBuffer;
1884 UINTN LineNumber;
1885 UINTN Offset;
1886 UINTN CandidateLineNumber;
1887 UINTN CandidateOffset;
1888
1889 if ((SearchType < 0) || (SearchType >= EdbEbcLineSearchTypeMax)) {
1890 return (UINTN)-1;
1891 }
1892
1893 LineNumber = (UINTN)-1;
1894 CandidateLineNumber = (UINTN)-1;
1895 CandidateOffset = (UINTN)-1;
1896 LineBuffer = AsciiStrGetNewTokenLine (Entry->CodBuffer, "\n");
1897 while (LineBuffer != NULL) {
1898 if (*LineBuffer != ' ') {
1899 LineBuffer = AsciiStrGetNextTokenLine ("\n");
1900 PatchForAsciiStrTokenBefore (LineBuffer, '\n');
1901 continue;
1902 }
1903
1904 //
1905 // Get Info
1906 //
1907 LineNumber = EdbGetLineNumberAndOffsetFromThisLine (LineBuffer, &Offset);
1908
1909 //
1910 // Check offset
1911 //
1912 if (Offset != FuncOffset) {
1913 //
1914 // Check last offset match
1915 //
1916 if (CandidateOffset == FuncOffset) {
1917 if (SearchType == EdbEbcLineSearchTypeLast) {
1918 PatchForAsciiStrTokenAfter (LineBuffer, '\n');
1919 if (CandidateLineNumber != LineNumber) {
1920 return CandidateLineNumber;
1921 } else {
1922 return (UINTN)-1;
1923 }
1924 } else {
1925 //
1926 // impossible, TBD?
1927 //
1928 }
1929 }
1930
1931 LineBuffer = AsciiStrGetNextTokenLine ("\n");
1932 PatchForAsciiStrTokenBefore (LineBuffer, '\n');
1933 CandidateLineNumber = LineNumber;
1934 continue;
1935 }
1936
1937 //
1938 // Offset match, more check
1939 //
1940 if (SearchType == EdbEbcLineSearchTypeAny) {
1941 PatchForAsciiStrTokenAfter (LineBuffer, '\n');
1942 return LineNumber;
1943 }
1944
1945 if (SearchType == EdbEbcLineSearchTypeFirst) {
1946 //
1947 // Check last line
1948 //
1949 PatchForAsciiStrTokenAfter (LineBuffer, '\n');
1950 if (CandidateLineNumber != LineNumber) {
1951 return LineNumber;
1952 } else {
1953 return (UINTN)-1;
1954 }
1955 }
1956
1957 CandidateLineNumber = LineNumber;
1958 CandidateOffset = Offset;
1959
1960 LineBuffer = AsciiStrGetNextTokenLine ("\n");
1961 PatchForAsciiStrTokenBefore (LineBuffer, '\n');
1962 }
1963
1964 //
1965 // Check last offset match
1966 //
1967 if (CandidateOffset == FuncOffset) {
1968 if (SearchType == EdbEbcLineSearchTypeLast) {
1969 return CandidateLineNumber;
1970 }
1971 }
1972
1973 return (UINTN)-1;
1974}
1975
1987VOID *
1990 IN UINTN LineNumber,
1991 IN VOID **FuncEnd
1992 )
1993{
1994 CHAR8 *LineBuffer;
1995 CHAR8 *FieldBuffer;
1996 VOID *FuncStart;
1997 UINTN Number;
1998
1999 FuncStart = NULL;
2000 LineBuffer = AsciiStrGetNewTokenLine (Entry->CodBuffer, "\n");
2001 while (LineBuffer != NULL) {
2002 if (*LineBuffer != ';') {
2003 if (FuncStart != NULL) {
2004 //
2005 // Over
2006 //
2007 *FuncEnd = LineBuffer - 1;
2008 PatchForAsciiStrTokenAfter (LineBuffer, '\n');
2009 return FuncStart;
2010 }
2011
2012 LineBuffer = AsciiStrGetNextTokenLine ("\n");
2013 PatchForAsciiStrTokenBefore (LineBuffer, '\n');
2014 continue;
2015 }
2016
2017 //
2018 // Check LineNumber
2019 //
2020 FieldBuffer = AsciiStrGetNewTokenField (LineBuffer + 1, " ");
2021 Number = AsciiAtoi (FieldBuffer);
2022 PatchForAsciiStrTokenAfter (FieldBuffer, ' ');
2023 if (Number != LineNumber) {
2024 LineBuffer = AsciiStrGetNextTokenLine ("\n");
2025 PatchForAsciiStrTokenBefore (LineBuffer, '\n');
2026 continue;
2027 }
2028
2029 //
2030 // Line match, get line number
2031 //
2032 if (FuncStart == NULL) {
2033 FuncStart = LineBuffer;
2034 }
2035
2036 LineBuffer = AsciiStrGetNextTokenLine ("\n");
2037 PatchForAsciiStrTokenBefore (LineBuffer, '\n');
2038 }
2039
2040 return NULL;
2041}
2042
2054VOID *
2057 IN UINTN FuncOffset,
2058 IN VOID **FuncEnd
2059 )
2060{
2061 UINTN LineNumber;
2062
2063 //
2064 // Only search the last line, then display
2065 //
2066 LineNumber = EdbGetLineNumberFromCode (Entry, FuncOffset, EdbEbcLineSearchTypeLast);
2067 if (LineNumber == (UINTN)-1) {
2068 return NULL;
2069 }
2070
2071 return EdbGetSourceStrFromCodeByLine (Entry, LineNumber, FuncEnd);
2072}
2073
2085UINTN
2087 IN UINTN Address,
2088 IN BOOLEAN IsPrint
2089 )
2090{
2091 UINTN SymbolAddress;
2092 EFI_DEBUGGER_SYMBOL_OBJECT *RetObject;
2093 EFI_DEBUGGER_SYMBOL_ENTRY *RetEntry;
2094 UINTN FuncOffset;
2095 UINT8 *FuncStart;
2096 UINT8 *FuncEnd;
2097 UINT8 *FuncIndex;
2098 CHAR8 Buffer[EFI_DEBUG_MAX_PRINT_BUFFER];
2099 UINTN BufferSize;
2100
2101 //
2102 // need we display symbol
2103 //
2104 if (!mDebuggerPrivate.DebuggerSymbolContext.DisplaySymbol) {
2105 return 0;
2106 }
2107
2108 //
2109 // find the symbol address
2110 //
2111 SymbolAddress = EbdFindSymbolAddress (
2112 Address,
2113 EdbMatchSymbolTypeLowerAddress,
2114 &RetObject,
2115 &RetEntry
2116 );
2117 if ((SymbolAddress == 0) || (RetEntry == NULL)) {
2118 return 0;
2119 }
2120
2121 FuncOffset = Address - SymbolAddress + RetEntry->FuncOffsetBase;
2122
2123 //
2124 // Get Func String
2125 //
2126 FuncStart = EdbGetSourceStrFromCode (RetEntry, FuncOffset, (VOID **)&FuncEnd);
2127 if (FuncStart == NULL) {
2128 return 0;
2129 }
2130
2131 //
2132 // check whether need to real print
2133 //
2134 if (!IsPrint) {
2135 return 1;
2136 }
2137
2138 *(UINT8 *)FuncEnd = 0;
2139
2140 //
2141 // seperate buffer by \n, so that \r can be added.
2142 //
2143 FuncIndex = FuncStart;
2144 while (*FuncIndex != 0) {
2145 if (*FuncIndex == '\n') {
2146 if ((FuncIndex - FuncStart) < (EFI_DEBUG_MAX_PRINT_BUFFER - 3)) {
2147 BufferSize = FuncIndex - FuncStart;
2148 } else {
2149 BufferSize = EFI_DEBUG_MAX_PRINT_BUFFER - 3;
2150 }
2151
2152 if (BufferSize != 0) {
2153 CopyMem (Buffer, FuncStart, BufferSize);
2154 }
2155
2156 Buffer[BufferSize] = 0;
2157 EDBPrint (L"%a\n", Buffer);
2158 FuncStart = FuncIndex + 1;
2159 FuncIndex = FuncStart;
2160 } else {
2161 FuncIndex++;
2162 }
2163 }
2164
2165 //
2166 // Patch the end
2167 //
2168 *(UINT8 *)FuncEnd = '\n';
2169
2170 return 1;
2171}
2172
2182VOID
2184 IN CHAR16 *Symbol,
2185 OUT CHAR16 **MapfileName,
2186 OUT CHAR16 **SymbolName
2187 )
2188{
2189 CHAR16 *Ch;
2190
2191 *MapfileName = NULL;
2192 *SymbolName = Symbol;
2193
2194 for (Ch = Symbol; *Ch != 0; Ch++) {
2195 //
2196 // Find split char
2197 //
2198 if (*Ch == L':') {
2199 *MapfileName = Symbol;
2200 *Ch = 0;
2201 *SymbolName = Ch + 1;
2202 break;
2203 }
2204 }
2205
2206 return;
2207}
2208
2223 IN CHAR16 *Symbol,
2224 OUT UINTN *Address
2225 )
2226{
2227 UINTN ObjectIndex;
2229 UINTN EntryIndex;
2231 CHAR16 *SymbolName;
2232 CHAR16 *MapfileName;
2233
2234 //
2235 // Split one symbol to mapfile name and symbol name
2236 //
2237 GetMapfileAndSymbol (Symbol, &MapfileName, &SymbolName);
2238
2239 *Address = 0;
2240 //
2241 // Go through each object
2242 //
2243 Object = mDebuggerPrivate.DebuggerSymbolContext.Object;
2244 for (ObjectIndex = 0; ObjectIndex < mDebuggerPrivate.DebuggerSymbolContext.ObjectCount; ObjectIndex++) {
2245 //
2246 // Check MapfileName
2247 //
2248 if ((MapfileName != NULL) && (StriCmp (Object[ObjectIndex].Name, MapfileName) != 0)) {
2249 continue;
2250 }
2251
2252 //
2253 // Go through each entry
2254 //
2255 Entry = Object[ObjectIndex].Entry;
2256 for (EntryIndex = 0; EntryIndex < Object[ObjectIndex].EntryCount; EntryIndex++) {
2257 //
2258 // Check SymbolName (case sensitive)
2259 //
2260 if (StrCmpUnicodeAndAscii (SymbolName, Entry[EntryIndex].Name) == 0) {
2261 if ((*Address != 0) && (MapfileName == NULL)) {
2262 //
2263 // Find the duplicated symbol
2264 //
2265 EDBPrint (L"Duplicated Symbol found!\n");
2266 return EFI_NO_MAPPING;
2267 } else {
2268 //
2269 // record Address
2270 //
2271 *Address = (Entry[EntryIndex].Rva + Object[ObjectIndex].BaseAddress);
2272 }
2273 }
2274 }
2275 }
2276
2277 if (*Address == 0) {
2278 //
2279 // Not found
2280 //
2281 return EFI_NOT_FOUND;
2282 }
2283
2284 return EFI_SUCCESS;
2285}
UINT64 UINTN
INTN EFIAPI AsciiStriCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
Definition: String.c:814
RETURN_STATUS EFIAPI AsciiStrnCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source, IN UINTN Length)
Definition: SafeString.c:1875
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
INTN EFIAPI AsciiStrCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString)
Definition: String.c:716
INTN EFIAPI AsciiStrnCmp(IN CONST CHAR8 *FirstString, IN CONST CHAR8 *SecondString, IN UINTN Length)
Definition: String.c:872
RETURN_STATUS EFIAPI StrnCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source, IN UINTN Length)
Definition: SafeString.c:310
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI PatchForAsciiStrTokenAfter(IN CHAR8 *Buffer, IN CHAR8 Patch)
CHAR8 *EFIAPI AsciiStrGetNewTokenLine(IN CHAR8 *String, IN CHAR8 *CharSet)
UINTN EFIAPI AsciiAtoi(CHAR8 *Str)
VOID EFIAPI PatchForAsciiStrTokenBefore(IN CHAR8 *Buffer, IN CHAR8 Patch)
UINTN EFIAPI EDBPrint(IN CONST CHAR16 *Format,...)
Definition: EdbSupportUI.c:683
UINTN EFIAPI AsciiXtoi(CHAR8 *Str)
INTN EFIAPI StrCmpUnicodeAndAscii(IN CHAR16 *String, IN CHAR8 *String2)
CHAR8 *EFIAPI AsciiStrGetNextTokenLine(IN CHAR8 *CharSet)
CHAR8 *EFIAPI AsciiStrGetNextTokenField(IN CHAR8 *CharSet)
CHAR8 *EFIAPI AsciiStrGetNewTokenField(IN CHAR8 *String, IN CHAR8 *CharSet)
INTN EFIAPI StriCmp(IN CHAR16 *String, IN CHAR16 *String2)
EFI_STATUS EdbLoadSymbol(IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, IN CHAR16 *FileName, IN UINTN BufferSize, IN VOID *Buffer)
Definition: EdbSymbol.c:693
VOID * EdbFindCodeFromObject(IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, IN EFI_DEBUGGER_SYMBOL_OBJECT *Object, IN CHAR16 *FileName)
Definition: EdbSymbol.c:1375
VOID EdbFixDebugImageInfoTable(IN OUT EFI_DEBUG_IMAGE_INFO_TABLE_HEADER **DebugImageInfoTableHeader)
Definition: EdbSymbol.c:959
EFI_STATUS EdbLoadCode(IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, IN CHAR16 *MapFileName, IN CHAR16 *FileName, IN UINTN BufferSize, IN VOID *Buffer)
Definition: EdbSymbol.c:1438
EFI_STATUS EdbLoadSymbolEntry(IN EFI_DEBUGGER_SYMBOL_OBJECT *Object, IN UINTN BufferSize, IN VOID *Buffer)
Definition: EdbSymbol.c:407
EFI_STATUS EdbUnloadSymbol(IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, IN CHAR16 *FileName)
Definition: EdbSymbol.c:614
VOID * EdbGetSourceStrFromCodeByLine(IN EFI_DEBUGGER_SYMBOL_ENTRY *Entry, IN UINTN LineNumber, IN VOID **FuncEnd)
Definition: EdbSymbol.c:1988
EFI_STATUS EdbLoadSymbolEntryByIec(IN EFI_DEBUGGER_SYMBOL_OBJECT *Object, IN UINTN BufferSize, IN VOID *Buffer)
Definition: EdbSymbol.c:165
UINTN EdbGetLineNumberFromCode(IN EFI_DEBUGGER_SYMBOL_ENTRY *Entry, IN UINTN FuncOffset, IN EDB_EBC_LINE_SEARCH_TYPE SearchType)
Definition: EdbSymbol.c:1877
CHAR8 * EdbLoadCodBySymbol(IN CHAR8 *Name, IN VOID *Buffer, IN UINTN BufferSize, OUT UINTN *CodeBufferSize, OUT UINTN *FuncOffset)
Definition: EdbSymbol.c:1348
BOOLEAN MatchPdbAndMap(IN CHAR8 *PdbFileName, IN CHAR16 *MapFileName)
Definition: EdbSymbol.c:875
CHAR8 * EdbLoadCodBySymbolByIec(IN CHAR8 *Name, IN VOID *Buffer, IN UINTN BufferSize, OUT UINTN *CodeBufferSize, OUT UINTN *FuncOffset)
Definition: EdbSymbol.c:1198
UINTN EdbPrintSource(IN UINTN Address, IN BOOLEAN IsPrint)
Definition: EdbSymbol.c:2086
VOID * EdbGetSourceStrFromCode(IN EFI_DEBUGGER_SYMBOL_ENTRY *Entry, IN UINTN FuncOffset, IN VOID **FuncEnd)
Definition: EdbSymbol.c:2055
CHAR8 * GetPdbPath(VOID *ImageBase)
Definition: EdbSymbol.c:773
EFI_STATUS EdbAddCodeBuffer(IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, IN CHAR16 *MapFileName, IN CHAR16 *CodeFileName, IN UINTN SourceBufferSize, IN VOID *SourceBuffer)
Definition: EdbSymbol.c:1630
EFI_STATUS EdbLoadSymbolSingleEntry(IN EFI_DEBUGGER_SYMBOL_OBJECT *Object, IN CHAR8 *Name, IN CHAR8 *ObjName, IN UINTN Address, IN EFI_DEBUGGER_SYMBOL_TYPE Type)
Definition: EdbSymbol.c:25
UINTN EdbGetLineNumberAndOffsetFromThisLine(IN VOID *Line, OUT UINTN *Offset)
Definition: EdbSymbol.c:1782
EFI_STATUS EdbUnloadCode(IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, IN CHAR16 *MapFileName, IN CHAR16 *FileName, OUT VOID **Buffer)
Definition: EdbSymbol.c:1554
EFI_STATUS Symboltoi(IN CHAR16 *Symbol, OUT UINTN *Address)
Definition: EdbSymbol.c:2222
EFI_STATUS EdbPatchSymbolRVA(IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, IN CHAR16 *FileName, IN EDB_EBC_IMAGE_RVA_SEARCH_TYPE SearchType)
Definition: EdbSymbol.c:997
BOOLEAN MatchObjAndCod(IN CHAR8 *ObjFileName, IN CHAR16 *CodFileName)
Definition: EdbSymbol.c:1125
UINTN EbdFindSymbolAddress(IN UINTN Address, IN EDB_MATCH_SYMBOL_TYPE Type, OUT EFI_DEBUGGER_SYMBOL_OBJECT **RetObject, OUT EFI_DEBUGGER_SYMBOL_ENTRY **RetEntry)
Definition: EdbSymbol.c:477
VOID GetMapfileAndSymbol(IN CHAR16 *Symbol, OUT CHAR16 **MapfileName, OUT CHAR16 **SymbolName)
Definition: EdbSymbol.c:2183
CHAR8 * FindSymbolStr(IN UINTN Address)
Definition: EdbSymbol.c:1733
EFI_DEBUGGER_SYMBOL_OBJECT * EdbFindSymbolFile(IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, IN CHAR16 *FileName, IN OUT UINTN *Index OPTIONAL)
Definition: EdbSymbol.c:434
EFI_STATUS EdbDeleteCodeBuffer(IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate, IN CHAR16 *MapFileName, IN CHAR16 *CodeFileName, IN VOID *SourceBuffer)
Definition: EdbSymbol.c:1674
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define CODEVIEW_SIGNATURE_NB10
Definition: PeImage.h:657
#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW
The Visual C++ debug information.
Definition: PeImage.h:651
#define CODEVIEW_SIGNATURE_RSDS
Definition: PeImage.h:671
#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
Definition: PeImage.h:143
#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: PeImage.h:194
#define EFI_IMAGE_MACHINE_EBC
Definition: UefiBaseType.h:228
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiGetSystemConfigurationTable(IN EFI_GUID *TableGuid, OUT VOID **Table)
Definition: UefiLib.c:82
EFI_LOADED_IMAGE_PROTOCOL * LoadedImageProtocolInstance
EFI_DEBUG_IMAGE_INFO * EfiDebugImageInfoTable
UINT32 RVA
The address of the debug data when loaded, relative to the image base.
Definition: PeImage.h:647
UINT32 e_lfanew
File address of new exe header.
Definition: PeImage.h:76
UINT16 e_magic
Magic number.
Definition: PeImage.h:58
VOID * ImageBase
The base address at which the image was loaded.
Definition: LoadedImage.h:67