summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2011-06-26 18:58:10 +0000
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2011-06-26 18:58:10 +0000
commit0bc9421b147f6f54d6fde72e320466d2db61ae8c (patch)
tree9ee79e555edd0c8a58d6dcd08042938a37237572
parent8e4b3d32a8baedd7e39d4e82b4e8458e217e7f6e (diff)
downloadedk2-platforms-0bc9421b147f6f54d6fde72e320466d2db61ae8c.tar.xz
InOsEmuPkg/Unix: Auto-load symbols files in gdb
Images that can't be loaded with dlopen are added to SecMain.gdb. Whenever gdb stops, the hook-stop macro will automatically load the symbol files. Signed-off-by: jljusten git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11888 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--InOsEmuPkg/Unix/GdbRun37
-rw-r--r--InOsEmuPkg/Unix/Sec/SecMain.c288
2 files changed, 191 insertions, 134 deletions
diff --git a/InOsEmuPkg/Unix/GdbRun b/InOsEmuPkg/Unix/GdbRun
index cf4ca7fe5a..c374cb8ca5 100644
--- a/InOsEmuPkg/Unix/GdbRun
+++ b/InOsEmuPkg/Unix/GdbRun
@@ -27,6 +27,43 @@ set $_exitcode = 42
define hook-stop
if $_exitcode != 42
quit
+ else
+ source SecMain.gdb
+ end
+end
+
+#
+# We keep track of the number of symbol files we have loaded via gdb
+# scripts in the $SymbolFilesAdded variable
+#
+set $SymbolFileChangesCount = 0
+
+#
+# This macro adds a symbols file for gdb
+#
+# @param $arg0 - Symbol file changes number
+# @param $arg1 - Symbol file name
+# @param $arg2 - Image address
+#
+define AddFirmwareSymbolFile
+ if $SymbolFileChangesCount < $arg0
+ add-symbol-file $arg1 $arg2
+ set $SymbolFileChangesCount = $arg0
+ end
+end
+
+#
+# This macro removes a symbols file for gdb
+#
+# @param $arg0 - Symbol file changes number
+# @param $arg1 - Symbol file name
+#
+define RemoveFirmwareSymbolFile
+ if $SymbolFileChangesCount < $arg0
+ #
+ # Currently there is not a method to remove a single symbol file
+ #
+ set $SymbolFileChangesCount = $arg0
end
end
diff --git a/InOsEmuPkg/Unix/Sec/SecMain.c b/InOsEmuPkg/Unix/Sec/SecMain.c
index bcf4104b1b..61847b5348 100644
--- a/InOsEmuPkg/Unix/Sec/SecMain.c
+++ b/InOsEmuPkg/Unix/Sec/SecMain.c
@@ -16,7 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifdef __APPLE__
#define MAP_ANONYMOUS MAP_ANON
-char *gGdbWorkingFileName = NULL;
#endif
@@ -30,7 +29,8 @@ EMU_THUNK_PPI mSecEmuThunkPpi = {
GasketSecEmuThunkAddress
};
-
+char *gGdbWorkingFileName = NULL;
+UINTN mScriptSymbolChangesCount = 0;
//
@@ -95,6 +95,7 @@ main (
CHAR16 *MemorySizeStr;
CHAR16 *FirmwareVolumesStr;
UINTN *StackPointer;
+ FILE *GdbTempFile;
setbuf (stdout, 0);
setbuf (stderr, 0);
@@ -128,19 +129,22 @@ main (
gPpiList = GetThunkPpiList ();
-
-#ifdef __APPLE__
//
- // We can't use dlopen on OS X, so we need a scheme to get symboles into gdb
- // We need to create a temp file that contains gdb commands so we can load
- // symbols when we load every PE/COFF image.
+ // If dlopen doesn't work, then we build a gdb script to allow the
+ // symbols to be loaded.
//
Index = strlen (*Argv);
gGdbWorkingFileName = AllocatePool (Index + strlen(".gdb") + 1);
strcpy (gGdbWorkingFileName, *Argv);
strcat (gGdbWorkingFileName, ".gdb");
-#endif
+ //
+ // Empty out the gdb symbols script file.
+ //
+ GdbTempFile = fopen (gGdbWorkingFileName, "w");
+ if (GdbTempFile != NULL) {
+ fclose (GdbTempFile);
+ }
//
// Allocate space for gSystemMemory Array
@@ -1050,89 +1054,25 @@ PrintLoadAddress (
}
-VOID
-EFIAPI
-SecPeCoffRelocateImageExtraAction (
+/**
+ Loads the image using dlopen so symbols will be automatically
+ loaded by gdb.
+
+ @param ImageContext The PE/COFF image context
+
+ @retval TRUE - The image was successfully loaded
+ @retval FALSE - The image was successfully loaded
+
+**/
+BOOLEAN
+DlLoadImage (
IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
{
#ifdef __APPLE__
- BOOLEAN EnabledOnEntry;
-
- //
- // Make sure writting of the file is an atomic operation
- //
- if (SecInterruptEanbled ()) {
- SecDisableInterrupt ();
- EnabledOnEntry = TRUE;
- } else {
- EnabledOnEntry = FALSE;
- }
-
- PrintLoadAddress (ImageContext);
-
- //
- // In mach-o (OS X executable) dlopen() can only load files in the MH_DYLIB of MH_BUNDLE format.
- // To convert to PE/COFF we need to construct a mach-o with the MH_PRELOAD format. We create
- // .dSYM files for the PE/COFF images that can be used by gdb for source level debugging.
- //
- FILE *GdbTempFile;
-
- //
- // In the Mach-O to PE/COFF conversion the size of the PE/COFF headers is not accounted for.
- // Thus we need to skip over the PE/COFF header when giving load addresses for our symbol table.
- //
- if (ImageContext->PdbPointer != NULL && !IsPdbFile (ImageContext->PdbPointer)) {
- //
- // Now we have a database of the images that are currently loaded
- //
-
- //
- // 'symbol-file' will clear out currnet symbol mappings in gdb.
- // you can do a 'add-symbol-file filename address' for every image we loaded to get source
- // level debug in gdb. Note Sec, being a true application will work differently.
- //
- // We add the PE/COFF header size into the image as the mach-O does not have a header in
- // loaded into system memory.
- //
- // This gives us a data base of gdb commands and after something is unloaded that entry will be
- // removed. We don't yet have the scheme of how to comunicate with gdb, but we have the
- // data base of info ready to roll.
- //
- // We could use qXfer:libraries:read, but OS X GDB does not currently support it.
- // <library-list>
- // <library name="/lib/libc.so.6"> // ImageContext->PdbPointer
- // <segment address="0x10000000"/> // ImageContext->ImageAddress + ImageContext->SizeOfHeaders
- // </library>
- // </library-list>
- //
-
- //
- // Write the file we need for the gdb script
- //
- GdbTempFile = fopen (gGdbWorkingFileName, "w");
- if (GdbTempFile != NULL) {
- fprintf (GdbTempFile, "add-symbol-file %s 0x%08lx\n", ImageContext->PdbPointer, (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders));
- fclose (GdbTempFile);
-
- //
- // Target for gdb breakpoint in a script that uses gGdbWorkingFileName to set a breakpoint.
- // Hey what can you say scripting in gdb is not that great....
- //
- SecGdbScriptBreak ();
- } else {
- ASSERT (FALSE);
- }
-
- AddHandle (ImageContext, ImageContext->PdbPointer);
- if (EnabledOnEntry) {
- SecEnableInterrupt ();
- }
-
-
- }
+ return FALSE;
#else
@@ -1140,11 +1080,11 @@ SecPeCoffRelocateImageExtraAction (
void *Entry = NULL;
if (ImageContext->PdbPointer == NULL) {
- return;
+ return FALSE;
}
if (!IsPdbFile (ImageContext->PdbPointer)) {
- return;
+ return FALSE;
}
fprintf (
@@ -1166,75 +1106,155 @@ SecPeCoffRelocateImageExtraAction (
if (Entry != NULL) {
ImageContext->EntryPoint = (UINTN)Entry;
printf ("Change %s Entrypoint to :0x%08lx\n", ImageContext->PdbPointer, (unsigned long)Entry);
+ return TRUE;
+ } else {
+ return FALSE;
}
- SecUnixLoaderBreak ();
-
#endif
+}
+
+
+/**
+ Adds the image to a gdb script so it's symbols can be loaded.
+ The AddFirmwareSymbolFile helper macro is used.
+
+ @param ImageContext The PE/COFF image context
+
+**/
+VOID
+GdbScriptAddImage (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+{
+ BOOLEAN InterruptsWereEnabled;
- return;
+ //
+ // Disable interrupts to make sure writing of the .gdb file
+ // is an atomic operation.
+ //
+ if (SecInterruptEanbled ()) {
+ SecDisableInterrupt ();
+ InterruptsWereEnabled = TRUE;
+ } else {
+ InterruptsWereEnabled = FALSE;
+ }
+
+ PrintLoadAddress (ImageContext);
+
+ if (ImageContext->PdbPointer != NULL && !IsPdbFile (ImageContext->PdbPointer)) {
+ FILE *GdbTempFile;
+ GdbTempFile = fopen (gGdbWorkingFileName, "a");
+ if (GdbTempFile != NULL) {
+ long unsigned int SymbolsAddr = (long unsigned int)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders);
+ mScriptSymbolChangesCount++;
+ fprintf (
+ GdbTempFile,
+ "AddFirmwareSymbolFile 0x%x %s 0x%08lx\n",
+ mScriptSymbolChangesCount,
+ ImageContext->PdbPointer,
+ SymbolsAddr
+ );
+ fclose (GdbTempFile);
+ } else {
+ ASSERT (FALSE);
+ }
+
+ AddHandle (ImageContext, ImageContext->PdbPointer);
+
+ if (InterruptsWereEnabled) {
+ SecEnableInterrupt ();
+ }
+
+ }
}
VOID
EFIAPI
-SecPeCoffUnloadImageExtraAction (
- IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+SecPeCoffRelocateImageExtraAction (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
)
{
- VOID *Handle;
+ if (!DlLoadImage (ImageContext)) {
+ GdbScriptAddImage (ImageContext);
+ }
+}
- Handle = RemoveHandle (ImageContext);
-#ifdef __APPLE__
+/**
+ Adds the image to a gdb script so it's symbols can be unloaded.
+ The RemoveFirmwareSymbolFile helper macro is used.
+
+ @param ImageContext The PE/COFF image context
+
+**/
+VOID
+GdbScriptRemoveImage (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+{
FILE *GdbTempFile;
- BOOLEAN EnabledOnEntry;
+ BOOLEAN InterruptsWereEnabled;
- if (Handle != NULL) {
- //
- // Need to skip .PDB files created from VC++
- //
- if (!IsPdbFile (ImageContext->PdbPointer)) {
- if (SecInterruptEanbled ()) {
- SecDisableInterrupt ();
- EnabledOnEntry = TRUE;
- } else {
- EnabledOnEntry = FALSE;
- }
-
- //
- // Write the file we need for the gdb script
- //
- GdbTempFile = fopen (gGdbWorkingFileName, "w");
- if (GdbTempFile != NULL) {
- fprintf (GdbTempFile, "remove-symbol-file %s\n", ImageContext->PdbPointer);
- fclose (GdbTempFile);
-
- //
- // Target for gdb breakpoint in a script that uses gGdbWorkingFileName to set a breakpoint.
- // Hey what can you say scripting in gdb is not that great....
- //
- SecGdbScriptBreak ();
- } else {
- ASSERT (FALSE);
- }
-
- if (EnabledOnEntry) {
- SecEnableInterrupt ();
- }
- }
+ //
+ // Need to skip .PDB files created from VC++
+ //
+ if (IsPdbFile (ImageContext->PdbPointer)) {
+ return;
+ }
+
+ if (SecInterruptEanbled ()) {
+ SecDisableInterrupt ();
+ InterruptsWereEnabled = TRUE;
+ } else {
+ InterruptsWereEnabled = FALSE;
}
-#else
//
- // Don't want to confuse gdb with symbols for something that got unloaded
+ // Write the file we need for the gdb script
//
- if (Handle != NULL) {
- dlclose (Handle);
+ GdbTempFile = fopen (gGdbWorkingFileName, "a");
+ if (GdbTempFile != NULL) {
+ mScriptSymbolChangesCount++;
+ fprintf (
+ GdbTempFile,
+ "RemoveFirmwareSymbolFile 0x%x %s\n",
+ mScriptSymbolChangesCount,
+ ImageContext->PdbPointer
+ );
+ fclose (GdbTempFile);
+ } else {
+ ASSERT (FALSE);
+ }
+
+ if (InterruptsWereEnabled) {
+ SecEnableInterrupt ();
}
+}
+
+VOID
+EFIAPI
+SecPeCoffUnloadImageExtraAction (
+ IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+{
+ VOID *Handle;
+
+ //
+ // Check to see if the image symbols were loaded with gdb script, or dlopen
+ //
+ Handle = RemoveHandle (ImageContext);
+
+ if (Handle == NULL) {
+#ifndef __APPLE__
+ dlclose (Handle);
#endif
- return;
+ return;
+ }
+
+ GdbScriptRemoveImage (ImageContext);
}