3 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
4 Portions copyright (c) 2008 - 2011, Apple Inc. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #define MAP_ANONYMOUS MAP_ANON
19 char *gGdbWorkingFileName
= NULL
;
27 EMU_THUNK_PPI mSecEmuThunkPpi
= {
28 GasketSecUnixPeiAutoScan
,
29 GasketSecUnixFdAddress
,
30 GasketSecEmuThunkAddress
37 // Default information about where the FD is located.
38 // This array gets filled in with information from EFI_FIRMWARE_VOLUMES
39 // EFI_FIRMWARE_VOLUMES is a host environment variable set by system.cmd.
40 // The number of array elements is allocated base on parsing
41 // EFI_FIRMWARE_VOLUMES and the memory is never freed.
43 UINTN gFdInfoCount
= 0;
47 // Array that supports seperate memory rantes.
48 // The memory ranges are set in system.cmd via the EFI_MEMORY_SIZE variable.
49 // The number of array elements is allocated base on parsing
50 // EFI_MEMORY_SIZE and the memory is never freed.
52 UINTN gSystemMemoryCount
= 0;
53 EMU_SYSTEM_MEMORY
*gSystemMemory
;
57 UINTN mImageContextModHandleArraySize
= 0;
58 IMAGE_CONTEXT_TO_MOD_HANDLE
*mImageContextModHandleArray
= NULL
;
65 Main entry point to SEC for Unix. This is a unix program
68 Argc - Number of command line arguments
69 Argv - Array of command line argument strings
70 Envp - Array of environmemt variable strings
85 EFI_PHYSICAL_ADDRESS InitialStackMemory
;
86 UINT64 InitialStackMemorySize
;
93 EFI_PEI_FILE_HANDLE FileHandle
;
95 CHAR16
*MemorySizeStr
;
96 CHAR16
*FirmwareVolumesStr
;
102 MemorySizeStr
= (CHAR16
*) PcdGetPtr (PcdEmuMemorySize
);
103 FirmwareVolumesStr
= (CHAR16
*) PcdGetPtr (PcdEmuFirmwareVolume
);
105 printf ("\nEDK II UNIX Emulation Environment from edk2.sourceforge.net\n");
108 // PPIs pased into PEI_CORE
110 AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI
, &gEmuThunkPpiGuid
, &mSecEmuThunkPpi
);
112 SecInitThunkProtocol ();
115 // Emulator Bus Driver Thunks
117 AddThunkProtocol (&gX11ThunkIo
, (CHAR16
*)PcdGetPtr (PcdEmuGop
), TRUE
);
118 AddThunkProtocol (&gPosixFileSystemThunkIo
, (CHAR16
*)PcdGetPtr (PcdEmuFileSystem
), TRUE
);
121 // Emulator other Thunks
123 AddThunkProtocol (&gPthreadThunkIo
, (CHAR16
*)PcdGetPtr (PcdEmuApCount
), FALSE
);
125 // EmuSecLibConstructor ();
128 gPpiList
= GetThunkPpiList ();
133 // We can't use dlopen on OS X, so we need a scheme to get symboles into gdb
134 // We need to create a temp file that contains gdb commands so we can load
135 // symbols when we load every PE/COFF image.
137 Index
= strlen (*Argv
);
138 gGdbWorkingFileName
= malloc (Index
+ strlen(".gdb") + 1);
139 strcpy (gGdbWorkingFileName
, *Argv
);
140 strcat (gGdbWorkingFileName
, ".gdb");
145 // Allocate space for gSystemMemory Array
147 gSystemMemoryCount
= CountSeperatorsInString (MemorySizeStr
, '!') + 1;
148 gSystemMemory
= calloc (gSystemMemoryCount
, sizeof (EMU_SYSTEM_MEMORY
));
149 if (gSystemMemory
== NULL
) {
150 printf ("ERROR : Can not allocate memory for system. Exiting.\n");
154 // Allocate space for gSystemMemory Array
156 gFdInfoCount
= CountSeperatorsInString (FirmwareVolumesStr
, '!') + 1;
157 gFdInfo
= calloc (gFdInfoCount
, sizeof (EMU_FD_INFO
));
158 if (gFdInfo
== NULL
) {
159 printf ("ERROR : Can not allocate memory for fd info. Exiting.\n");
163 printf (" BootMode 0x%02x\n", (unsigned int)PcdGet32 (PcdEmuBootMode
));
166 // Open up a 128K file to emulate temp memory for SEC.
167 // on a real platform this would be SRAM, or using the cache as RAM.
168 // Set InitialStackMemory to zero so UnixOpenFile will allocate a new mapping
170 InitialStackMemorySize
= STACK_SIZE
;
171 InitialStackMemory
= (UINTN
)MapMemory (
172 0, (UINT32
) InitialStackMemorySize
,
173 PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_ANONYMOUS
| MAP_PRIVATE
175 if (InitialStackMemory
== 0) {
176 printf ("ERROR : Can not open SecStack Exiting\n");
180 printf (" OS Emulator passing in %u KB of temp RAM at 0x%08lx to SEC\n",
181 (unsigned int)(InitialStackMemorySize
/ 1024),
182 (unsigned long)InitialStackMemory
185 for (StackPointer
= (UINTN
*) (UINTN
) InitialStackMemory
;
186 StackPointer
< (UINTN
*)(UINTN
)((UINTN
) InitialStackMemory
+ (UINT64
) InitialStackMemorySize
);
188 *StackPointer
= 0x5AA55AA5;
192 // Open All the firmware volumes and remember the info in the gFdInfo global
194 FileName
= (CHAR8
*)malloc (StrLen (FirmwareVolumesStr
) + 1);
195 if (FileName
== NULL
) {
196 printf ("ERROR : Can not allocate memory for firmware volume string\n");
201 for (Done
= FALSE
, Index
= 0, PeiIndex
= 0, SecFile
= NULL
;
202 FirmwareVolumesStr
[Index2
] != 0;
204 for (Index1
= 0; (FirmwareVolumesStr
[Index2
] != '!') && (FirmwareVolumesStr
[Index2
] != 0); Index2
++) {
205 FileName
[Index1
++] = FirmwareVolumesStr
[Index2
];
207 if (FirmwareVolumesStr
[Index2
] == '!') {
210 FileName
[Index1
] = '\0';
213 // Open the FD and remmeber where it got mapped into our processes address space
217 &gFdInfo
[Index
].Address
,
220 if (EFI_ERROR (Status
)) {
221 printf ("ERROR : Can not open Firmware Device File %s (%x). Exiting.\n", FileName
, (unsigned int)Status
);
225 printf (" FD loaded from %s at 0x%08lx",FileName
, (unsigned long)gFdInfo
[Index
].Address
);
227 if (SecFile
== NULL
) {
229 // Assume the beginning of the FD is an FV and look for the SEC Core.
230 // Load the first one we find.
233 Status
= PeiServicesFfsFindNextFile (
234 EFI_FV_FILETYPE_SECURITY_CORE
,
235 (EFI_PEI_FV_HANDLE
)(UINTN
)gFdInfo
[Index
].Address
,
238 if (!EFI_ERROR (Status
)) {
239 Status
= PeiServicesFfsFindSectionData (EFI_SECTION_PE32
, FileHandle
, &SecFile
);
240 if (!EFI_ERROR (Status
)) {
242 printf (" contains SEC Core");
250 // Calculate memory regions and store the information in the gSystemMemory
251 // global for later use. The autosizing code will use this data to
252 // map this memory into the SEC process memory space.
259 // Save the size of the memory.
261 while (MemorySizeStr
[Index1
] >= '0' && MemorySizeStr
[Index1
] <= '9') {
262 val
= val
* 10 + MemorySizeStr
[Index1
] - '0';
265 gSystemMemory
[Index
++].Size
= val
* 0x100000;
266 if (MemorySizeStr
[Index1
] == 0) {
277 SecLoadFromCore ((UINTN
) InitialStackMemory
, (UINTN
) InitialStackMemorySize
, (UINTN
) gFdInfo
[0].Address
, SecFile
);
280 // If we get here, then the SEC Core returned. This is an error as SEC should
281 // always hand off to PEI Core and then on to DXE Core.
283 printf ("ERROR : SEC returned\n");
288 EFI_PHYSICAL_ADDRESS
*
295 STATIC UINTN base
= 0x40000000;
296 CONST UINTN align
= (1 << 24);
298 BOOLEAN isAligned
= 0;
301 // Try to get an aligned block somewhere in the address space of this
304 while((!isAligned
) && (base
!= 0)) {
305 res
= mmap ((void *)base
, length
, prot
, flags
, fd
, 0);
306 if (res
== MAP_FAILED
) {
309 if ((((UINTN
)res
) & ~(align
-1)) == (UINTN
)res
) {
323 Opens and memory maps a file using Unix services. If BaseAddress is non zero
324 the process will try and allocate the memory starting at BaseAddress.
327 FileName - The name of the file to open and map
328 MapSize - The amount of the file to map in bytes
329 CreationDisposition - The flags to pass to CreateFile(). Use to create new files for
330 memory emulation, and exiting files for firmware volume emulation
331 BaseAddress - The base address of the mapped file in the user address space.
332 If passed in as NULL the a new memory region is used.
333 If passed in as non NULL the request memory region is used for
334 the mapping of the file into the process space.
335 Length - The size of the mapped region in bytes
338 EFI_SUCCESS - The file was opened and mapped.
339 EFI_NOT_FOUND - FileName was not found in the current directory
340 EFI_DEVICE_ERROR - An error occured attempting to map the opened file
346 IN OUT EFI_PHYSICAL_ADDRESS
*BaseAddress
,
354 fd
= open (FileName
, O_RDONLY
);
356 return EFI_NOT_FOUND
;
358 FileSize
= lseek (fd
, 0, SEEK_END
);
361 res
= MapMemory (fd
, FileSize
, PROT_READ
| PROT_WRITE
| PROT_EXEC
, MAP_PRIVATE
);
365 if (res
== MAP_FAILED
) {
366 return EFI_DEVICE_ERROR
;
369 *Length
= (UINT64
) FileSize
;
370 *BaseAddress
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) res
;
380 This is the service to load the SEC Core from the Firmware Volume
383 LargestRegion - Memory to use for SEC.
384 LargestRegionSize - Size of Memory to use for PEI
385 BootFirmwareVolumeBase - Start of the Boot FV
386 PeiCorePe32File - SEC PE32
389 Success means control is transfered and thus we should never return
394 IN UINTN LargestRegion
,
395 IN UINTN LargestRegionSize
,
396 IN UINTN BootFirmwareVolumeBase
,
397 IN VOID
*PeiCorePe32File
401 EFI_PHYSICAL_ADDRESS TopOfMemory
;
403 EFI_PHYSICAL_ADDRESS PeiCoreEntryPoint
;
404 EFI_SEC_PEI_HAND_OFF
*SecCoreData
;
408 // Compute Top Of Memory for Stack and PEI Core Allocations
410 TopOfMemory
= LargestRegion
+ LargestRegionSize
;
411 PeiStackSize
= (UINTN
)RShiftU64((UINT64
)STACK_SIZE
,1);
414 // |-----------| <---- TemporaryRamBase + TemporaryRamSize
417 // |-----------| <---- StackBase / PeiTemporaryMemoryBase
420 // |-----------| <---- TemporaryRamBase
422 TopOfStack
= (VOID
*)(LargestRegion
+ PeiStackSize
);
423 TopOfMemory
= LargestRegion
+ PeiStackSize
;
426 // Reservet space for storing PeiCore's parament in stack.
428 TopOfStack
= (VOID
*)((UINTN
)TopOfStack
- sizeof (EFI_SEC_PEI_HAND_OFF
) - CPU_STACK_ALIGNMENT
);
429 TopOfStack
= ALIGN_POINTER (TopOfStack
, CPU_STACK_ALIGNMENT
);
433 // Bind this information into the SEC hand-off state
435 SecCoreData
= (EFI_SEC_PEI_HAND_OFF
*)(UINTN
) TopOfStack
;
436 SecCoreData
->DataSize
= sizeof(EFI_SEC_PEI_HAND_OFF
);
437 SecCoreData
->BootFirmwareVolumeBase
= (VOID
*)BootFirmwareVolumeBase
;
438 SecCoreData
->BootFirmwareVolumeSize
= PcdGet32 (PcdEmuFirmwareFdSize
);
439 SecCoreData
->TemporaryRamBase
= (VOID
*)(UINTN
)LargestRegion
;
440 SecCoreData
->TemporaryRamSize
= STACK_SIZE
;
441 SecCoreData
->StackBase
= SecCoreData
->TemporaryRamBase
;
442 SecCoreData
->StackSize
= PeiStackSize
;
443 SecCoreData
->PeiTemporaryRamBase
= (VOID
*) ((UINTN
) SecCoreData
->TemporaryRamBase
+ PeiStackSize
);
444 SecCoreData
->PeiTemporaryRamSize
= STACK_SIZE
- PeiStackSize
;
447 // Find the SEC Core Entry Point
449 Status
= SecPeCoffGetEntryPoint (PeiCorePe32File
, (VOID
**)&PeiCoreEntryPoint
);
450 if (EFI_ERROR (Status
)) {
455 // Transfer control to the SEC Core
458 (SWITCH_STACK_ENTRY_POINT
) (UINTN
) PeiCoreEntryPoint
,
465 // If we get here, then the SEC Core returned. This is an error
474 This service is called from Index == 0 until it returns EFI_UNSUPPORTED.
475 It allows discontiguous memory regions to be supported by the emulator.
476 It uses gSystemMemory[] and gSystemMemoryCount that were created by
477 parsing the host environment variable EFI_MEMORY_SIZE.
478 The size comes from the varaible and the address comes from the call to
482 Index - Which memory region to use
483 MemoryBase - Return Base address of memory region
484 MemorySize - Return size in bytes of the memory region
487 EFI_SUCCESS - If memory region was mapped
488 EFI_UNSUPPORTED - If Index is not supported
495 OUT EFI_PHYSICAL_ADDRESS
*MemoryBase
,
496 OUT UINT64
*MemorySize
501 if (Index
>= gSystemMemoryCount
) {
502 return EFI_UNSUPPORTED
;
507 0, gSystemMemory
[Index
].Size
,
508 PROT_READ
| PROT_WRITE
| PROT_EXEC
,
509 MAP_PRIVATE
| MAP_ANONYMOUS
511 if (res
== MAP_FAILED
) {
512 return EFI_DEVICE_ERROR
;
514 *MemorySize
= gSystemMemory
[Index
].Size
;
515 *MemoryBase
= (UINTN
)res
;
516 gSystemMemory
[Index
].Memory
= *MemoryBase
;
525 Since the SEC is the only Unix program in stack it must export
526 an interface to do POSIX calls. gUnix is initailized in UnixThunk.c.
529 InterfaceSize - sizeof (EFI_WIN_NT_THUNK_PROTOCOL);
530 InterfaceBase - Address of the gUnix global
533 EFI_SUCCESS - Data returned
542 return &gEmuThunkProtocol
;
549 SecPeCoffGetEntryPoint (
551 IN OUT VOID
**EntryPoint
555 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
557 ImageContext
.ImageAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Pe32Data
;
558 ImageContext
.SizeOfHeaders
= PeCoffGetSizeOfHeaders (Pe32Data
);
559 ImageContext
.PdbPointer
= PeCoffLoaderGetPdbPointer (Pe32Data
);
560 Status
= PeCoffLoaderGetEntryPoint (Pe32Data
, EntryPoint
);
561 if (!EFI_ERROR (Status
)) {
565 ImageContext
.EntryPoint
= (UINTN
)EntryPoint
;
567 // On Unix a dlopen is done that will change the entry point
568 SecPeCoffRelocateImageExtraAction (&ImageContext
);
569 *EntryPoint
= (VOID
*)(UINTN
)ImageContext
.EntryPoint
;
579 Return the FD Size and base address. Since the FD is loaded from a
580 file into host memory only the SEC will know it's address.
583 Index - Which FD, starts at zero.
584 FdSize - Size of the FD in bytes
585 FdBase - Start address of the FD. Assume it points to an FV Header
586 FixUp - Difference between actual FD address and build address
589 EFI_SUCCESS - Return the Base address and size of the FV
590 EFI_UNSUPPORTED - Index does nto map to an FD in the system
597 IN OUT EFI_PHYSICAL_ADDRESS
*FdBase
,
598 IN OUT UINT64
*FdSize
,
599 IN OUT EFI_PHYSICAL_ADDRESS
*FixUp
602 if (Index
>= gFdInfoCount
) {
603 return EFI_UNSUPPORTED
;
606 *FdBase
= gFdInfo
[Index
].Address
;
607 *FdSize
= gFdInfo
[Index
].Size
;
610 if (*FdBase
== 0 && *FdSize
== 0) {
611 return EFI_UNSUPPORTED
;
616 // FD 0 has XIP code and well known PCD values
617 // If the memory buffer could not be allocated at the FD build address
618 // the Fixup is the difference.
620 *FixUp
= *FdBase
- PcdGet64 (PcdEmuFdBaseAddress
);
630 Count the number of seperators in String
633 String - String to process
634 Seperator - Item to count
637 Number of Seperator in String
641 CountSeperatorsInString (
642 IN
const CHAR16
*String
,
648 for (Count
= 0; *String
!= '\0'; String
++) {
649 if (*String
== Seperator
) {
661 Store the ModHandle in an array indexed by the Pdb File name.
662 The ModHandle is needed to unload the image.
665 ImageContext - Input data returned from PE Laoder Library. Used to find the
666 .PDB file name of the PE Image.
667 ModHandle - Returned from LoadLibraryEx() and stored for call to
671 EFI_SUCCESS - ModHandle was stored.
676 IN PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
,
681 IMAGE_CONTEXT_TO_MOD_HANDLE
*Array
;
685 Array
= mImageContextModHandleArray
;
686 for (Index
= 0; Index
< mImageContextModHandleArraySize
; Index
++, Array
++) {
687 if (Array
->ImageContext
== NULL
) {
689 // Make a copy of the stirng and store the ModHandle
691 Array
->ImageContext
= ImageContext
;
692 Array
->ModHandle
= ModHandle
;
698 // No free space in mImageContextModHandleArray so grow it by
699 // IMAGE_CONTEXT_TO_MOD_HANDLE entires. realloc will
700 // copy the old values to the new locaiton. But it does
701 // not zero the new memory area.
703 PreviousSize
= mImageContextModHandleArraySize
* sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE
);
704 mImageContextModHandleArraySize
+= MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE
;
706 mImageContextModHandleArray
= realloc (mImageContextModHandleArray
, mImageContextModHandleArraySize
* sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE
));
707 if (mImageContextModHandleArray
== NULL
) {
709 return EFI_OUT_OF_RESOURCES
;
712 memset (mImageContextModHandleArray
+ PreviousSize
, 0, MAX_IMAGE_CONTEXT_TO_MOD_HANDLE_ARRAY_SIZE
* sizeof (IMAGE_CONTEXT_TO_MOD_HANDLE
));
714 return AddHandle (ImageContext
, ModHandle
);
721 Return the ModHandle and delete the entry in the array.
724 ImageContext - Input data returned from PE Laoder Library. Used to find the
725 .PDB file name of the PE Image.
728 ModHandle - ModHandle assoicated with ImageContext is returned
729 NULL - No ModHandle associated with ImageContext
734 IN PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
738 IMAGE_CONTEXT_TO_MOD_HANDLE
*Array
;
740 if (ImageContext
->PdbPointer
== NULL
) {
742 // If no PDB pointer there is no ModHandle so return NULL
747 Array
= mImageContextModHandleArray
;
748 for (Index
= 0; Index
< mImageContextModHandleArraySize
; Index
++, Array
++) {
749 if (Array
->ImageContext
== ImageContext
) {
751 // If you find a match return it and delete the entry
753 Array
->ImageContext
= NULL
;
754 return Array
->ModHandle
;
764 // Target for gdb breakpoint in a script that uses gGdbWorkingFileName to source a
765 // add-symbol-file command. Hey what can you say scripting in gdb is not that great....
767 // Put .gdbinit in the CWD where you do gdb SecMain.dll for source level debug
770 // b SecGdbScriptBreak
773 // source SecMain.gdb
793 IN CHAR8
*PdbFileName
798 if (PdbFileName
== NULL
) {
802 Len
= strlen (PdbFileName
);
803 if ((Len
< 5)|| (PdbFileName
[Len
- 4] != '.')) {
807 if ((PdbFileName
[Len
- 3] == 'P' || PdbFileName
[Len
- 3] == 'p') &&
808 (PdbFileName
[Len
- 2] == 'D' || PdbFileName
[Len
- 2] == 'd') &&
809 (PdbFileName
[Len
- 1] == 'B' || PdbFileName
[Len
- 1] == 'b')) {
817 #define MAX_SPRINT_BUFFER_SIZE 0x200
821 IN PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
824 if (ImageContext
->PdbPointer
== NULL
) {
826 "0x%08lx Loading NO DEBUG with entry point 0x%08lx\n",
827 (unsigned long)(ImageContext
->ImageAddress
),
828 (unsigned long)ImageContext
->EntryPoint
832 "0x%08lx Loading %s with entry point 0x%08lx\n",
833 (unsigned long)(ImageContext
->ImageAddress
+ ImageContext
->SizeOfHeaders
),
834 ImageContext
->PdbPointer
,
835 (unsigned long)ImageContext
->EntryPoint
838 // Keep output synced up
845 SecPeCoffRelocateImageExtraAction (
846 IN OUT PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
851 BOOLEAN EnabledOnEntry
;
854 // Make sure writting of the file is an atomic operation
856 if (SecInterruptEanbled ()) {
857 SecDisableInterrupt ();
858 EnabledOnEntry
= TRUE
;
860 EnabledOnEntry
= FALSE
;
863 PrintLoadAddress (ImageContext
);
866 // In mach-o (OS X executable) dlopen() can only load files in the MH_DYLIB of MH_BUNDLE format.
867 // To convert to PE/COFF we need to construct a mach-o with the MH_PRELOAD format. We create
868 // .dSYM files for the PE/COFF images that can be used by gdb for source level debugging.
873 // In the Mach-O to PE/COFF conversion the size of the PE/COFF headers is not accounted for.
874 // Thus we need to skip over the PE/COFF header when giving load addresses for our symbol table.
876 if (ImageContext
->PdbPointer
!= NULL
&& !IsPdbFile (ImageContext
->PdbPointer
)) {
878 // Now we have a database of the images that are currently loaded
882 // 'symbol-file' will clear out currnet symbol mappings in gdb.
883 // you can do a 'add-symbol-file filename address' for every image we loaded to get source
884 // level debug in gdb. Note Sec, being a true application will work differently.
886 // We add the PE/COFF header size into the image as the mach-O does not have a header in
887 // loaded into system memory.
889 // This gives us a data base of gdb commands and after something is unloaded that entry will be
890 // removed. We don't yet have the scheme of how to comunicate with gdb, but we have the
891 // data base of info ready to roll.
893 // We could use qXfer:libraries:read, but OS X GDB does not currently support it.
895 // <library name="/lib/libc.so.6"> // ImageContext->PdbPointer
896 // <segment address="0x10000000"/> // ImageContext->ImageAddress + ImageContext->SizeOfHeaders
902 // Write the file we need for the gdb script
904 GdbTempFile
= fopen (gGdbWorkingFileName
, "w");
905 if (GdbTempFile
!= NULL
) {
906 fprintf (GdbTempFile
, "add-symbol-file %s 0x%08lx\n", ImageContext
->PdbPointer
, (long unsigned int)(ImageContext
->ImageAddress
+ ImageContext
->SizeOfHeaders
));
907 fclose (GdbTempFile
);
910 // Target for gdb breakpoint in a script that uses gGdbWorkingFileName to set a breakpoint.
911 // Hey what can you say scripting in gdb is not that great....
913 SecGdbScriptBreak ();
918 AddHandle (ImageContext
, ImageContext
->PdbPointer
);
920 if (EnabledOnEntry
) {
921 SecEnableInterrupt ();
932 if (ImageContext
->PdbPointer
== NULL
) {
936 if (!IsPdbFile (ImageContext
->PdbPointer
)) {
942 "Loading %s 0x%08lx - entry point 0x%08lx\n",
943 ImageContext
->PdbPointer
,
944 (unsigned long)ImageContext
->ImageAddress
,
945 (unsigned long)ImageContext
->EntryPoint
948 Handle
= dlopen (ImageContext
->PdbPointer
, RTLD_NOW
);
951 Entry
= dlsym (Handle
, "_ModuleEntryPoint");
953 printf("%s\n", dlerror());
957 ImageContext
->EntryPoint
= (UINTN
)Entry
;
958 printf ("Change %s Entrypoint to :0x%08lx\n", ImageContext
->PdbPointer
, (unsigned long)Entry
);
961 SecUnixLoaderBreak ();
971 SecPeCoffUnloadImageExtraAction (
972 IN PE_COFF_LOADER_IMAGE_CONTEXT
*ImageContext
977 Handle
= RemoveHandle (ImageContext
);
981 BOOLEAN EnabledOnEntry
;
983 if (Handle
!= NULL
) {
985 // Need to skip .PDB files created from VC++
987 if (!IsPdbFile (ImageContext
->PdbPointer
)) {
988 if (SecInterruptEanbled ()) {
989 SecDisableInterrupt ();
990 EnabledOnEntry
= TRUE
;
992 EnabledOnEntry
= FALSE
;
996 // Write the file we need for the gdb script
998 GdbTempFile
= fopen (gGdbWorkingFileName
, "w");
999 if (GdbTempFile
!= NULL
) {
1000 fprintf (GdbTempFile
, "remove-symbol-file %s\n", ImageContext
->PdbPointer
);
1001 fclose (GdbTempFile
);
1004 // Target for gdb breakpoint in a script that uses gGdbWorkingFileName to set a breakpoint.
1005 // Hey what can you say scripting in gdb is not that great....
1007 SecGdbScriptBreak ();
1012 if (EnabledOnEntry
) {
1013 SecEnableInterrupt ();
1020 // Don't want to confuse gdb with symbols for something that got unloaded
1022 if (Handle
!= NULL
) {