#define SE_TIME_ZONE_NAME TEXT("SeTimeZonePrivilege")\r
#endif\r
\r
+//\r
+// The growth size for array of module handle entries\r
+//\r
+#define MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE 0x100\r
+\r
+//\r
+// Module handle entry structure\r
+//\r
+typedef struct {\r
+ CHAR8 *PdbPointer;\r
+ VOID *ModHandle;\r
+} PDB_NAME_TO_MOD_HANDLE;\r
+\r
+//\r
+// An Array to hold the module handles\r
+//\r
+PDB_NAME_TO_MOD_HANDLE *mPdbNameModHandleArray = NULL;\r
+UINTN mPdbNameModHandleArraySize = 0;\r
+\r
//\r
// Default information about where the FD is located.\r
// This array gets filled in with information from PcdWinNtFirmwareVolume\r
return Count;\r
}\r
\r
+/**\r
+ Store the ModHandle in an array indexed by the Pdb File name.\r
+ The ModHandle is needed to unload the image.\r
+ @param ImageContext - Input data returned from PE Laoder Library. Used to find the\r
+ .PDB file name of the PE Image.\r
+ @param ModHandle - Returned from LoadLibraryEx() and stored for call to\r
+ FreeLibrary().\r
+ @return return EFI_SUCCESS when ModHandle was stored.\r
+--*/\r
+EFI_STATUS\r
+AddModHandle (\r
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,\r
+ IN VOID *ModHandle\r
+ )\r
+\r
+{\r
+ UINTN Index;\r
+ PDB_NAME_TO_MOD_HANDLE *Array;\r
+ UINTN PreviousSize;\r
+ PDB_NAME_TO_MOD_HANDLE *TempArray;\r
+ HANDLE Handle;\r
+ UINTN Size;\r
+\r
+ //\r
+ // Return EFI_ALREADY_STARTED if this DLL has already been loaded\r
+ //\r
+ Array = mPdbNameModHandleArray;\r
+ for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) {\r
+ if (Array->PdbPointer != NULL && Array->ModHandle == ModHandle) {\r
+ return EFI_ALREADY_STARTED;\r
+ }\r
+ }\r
+\r
+ Array = mPdbNameModHandleArray;\r
+ for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) {\r
+ if (Array->PdbPointer == NULL) {\r
+ //\r
+ // Make a copy of the stirng and store the ModHandle\r
+ //\r
+ Handle = GetProcessHeap ();\r
+ Size = AsciiStrLen (ImageContext->PdbPointer) + 1;\r
+ Array->PdbPointer = HeapAlloc ( Handle, HEAP_ZERO_MEMORY, Size);\r
+ ASSERT (Array->PdbPointer != NULL);\r
+\r
+ AsciiStrCpyS (Array->PdbPointer, Size, ImageContext->PdbPointer);\r
+ Array->ModHandle = ModHandle;\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
+ //\r
+ // No free space in mPdbNameModHandleArray so grow it by\r
+ // MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE entires.\r
+ //\r
+ PreviousSize = mPdbNameModHandleArraySize * sizeof (PDB_NAME_TO_MOD_HANDLE);\r
+ mPdbNameModHandleArraySize += MAX_PDB_NAME_TO_MOD_HANDLE_ARRAY_SIZE;\r
+ //\r
+ // re-allocate a new buffer and copy the old values to the new locaiton.\r
+ //\r
+ TempArray = HeapAlloc (GetProcessHeap (),\r
+ HEAP_ZERO_MEMORY,\r
+ mPdbNameModHandleArraySize * sizeof (PDB_NAME_TO_MOD_HANDLE)\r
+ );\r
+\r
+ CopyMem ((VOID *) (UINTN) TempArray, (VOID *) (UINTN)mPdbNameModHandleArray, PreviousSize);\r
+\r
+ HeapFree (GetProcessHeap (), 0, mPdbNameModHandleArray);\r
+\r
+ mPdbNameModHandleArray = TempArray;\r
+ if (mPdbNameModHandleArray == NULL) {\r
+ ASSERT (FALSE);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ return AddModHandle (ImageContext, ModHandle);\r
+}\r
+\r
+/**\r
+ Return the ModHandle and delete the entry in the array.\r
+ @param ImageContext - Input data returned from PE Laoder Library. Used to find the\r
+ .PDB file name of the PE Image.\r
+ @return\r
+ ModHandle - ModHandle assoicated with ImageContext is returned\r
+ NULL - No ModHandle associated with ImageContext\r
+**/\r
+VOID *\r
+RemoveModHandle (\r
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
+ )\r
+{\r
+ UINTN Index;\r
+ PDB_NAME_TO_MOD_HANDLE *Array;\r
+\r
+ if (ImageContext->PdbPointer == NULL) {\r
+ //\r
+ // If no PDB pointer there is no ModHandle so return NULL\r
+ //\r
+ return NULL;\r
+ }\r
+\r
+ Array = mPdbNameModHandleArray;\r
+ for (Index = 0; Index < mPdbNameModHandleArraySize; Index++, Array++) {\r
+ if ((Array->PdbPointer != NULL) && (AsciiStrCmp(Array->PdbPointer, ImageContext->PdbPointer) == 0)) {\r
+ //\r
+ // If you find a match return it and delete the entry\r
+ //\r
+ HeapFree (GetProcessHeap (), 0, Array->PdbPointer);\r
+ Array->PdbPointer = NULL;\r
+ return Array->ModHandle;\r
+ }\r
+ }\r
+\r
+ return NULL;\r
+}\r
\r
VOID\r
EFIAPI\r
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
)\r
{\r
+ EFI_STATUS Status;\r
VOID *DllEntryPoint;\r
CHAR16 *DllFileName;\r
HMODULE Library;\r
ASSERT (ImageContext != NULL);\r
//\r
// If we load our own PE COFF images the Windows debugger can not source\r
- // level debug our code. If a valid PDB pointer exists usw it to load\r
+ // level debug our code. If a valid PDB pointer exists use it to load\r
// the *.dll file as a library using Windows* APIs. This allows\r
// source level debug. The image is still loaded and relocated\r
// in the Framework memory space like on a real system (by the code above),\r
}\r
\r
if ((Library != NULL) && (DllEntryPoint != NULL)) {\r
- ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) DllEntryPoint;\r
- SecPrint ("LoadLibraryEx (%S,\n NULL, DONT_RESOLVE_DLL_REFERENCES)\n", DllFileName);\r
+ Status = AddModHandle (ImageContext, Library);\r
+ if (Status == EFI_ALREADY_STARTED) {\r
+ //\r
+ // If the DLL has already been loaded before, then this instance of the DLL can not be debugged.\r
+ //\r
+ ImageContext->PdbPointer = NULL;\r
+ SecPrint ("WARNING: DLL already loaded. No source level debug %S.\n\r", DllFileName);\r
+ } else {\r
+ //\r
+ // This DLL is not already loaded, so source level debugging is supported.\r
+ //\r
+ ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) DllEntryPoint;\r
+ SecPrint ("LoadLibraryEx (\n\r %S,\n\r NULL, DONT_RESOLVE_DLL_REFERENCES)\n\r", DllFileName);\r
+ }\r
} else {\r
- SecPrint ("WARNING: No source level debug %S. \n", DllFileName);\r
+ SecPrint ("WARNING: No source level debug %S. \n\r", DllFileName);\r
}\r
\r
free (DllFileName);\r
VOID\r
EFIAPI\r
PeCoffLoaderUnloadImageExtraAction (\r
- IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext\r
)\r
{\r
+ VOID *ModHandle;\r
+\r
ASSERT (ImageContext != NULL);\r
-}\r
\r
+ ModHandle = RemoveModHandle (ImageContext);\r
+ if (ModHandle != NULL) {\r
+ FreeLibrary (ModHandle);\r
+ SecPrint ("FreeLibrary (\n\r %s)\n\r", ImageContext->PdbPointer);\r
+ } else {\r
+ SecPrint ("WARNING: Unload image without source level debug\n\r");\r
+ }\r
+}\r
\r
VOID\r
_ModuleEntryPoint (\r