1 /**@file
2 
3 Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
4 Portions copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
5 Portions copyright (c) 2011 - 2012, ARM Ltd. All rights reserved.<BR>
6 
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8 
9 **/
10 
11 #include <PiDxe.h>
12 #include <Library/PeCoffLib.h>
13 
14 #include <Library/BaseLib.h>
15 #include <Library/DebugLib.h>
16 #include <Library/BaseMemoryLib.h>
17 #include <Library/PeCoffExtraActionLib.h>
18 #include <Library/SemihostLib.h>
19 #include <Library/PrintLib.h>
20 
21 /**
22   Append string to debugger script file, create file if needed.
23 
24   This library can show up in multiple places so we need to append the file every time we write to it.
25   For example Sec can use this to load the DXE core, and the DXE core would use this to load all the
26   other modules. So we have two instances of the library in the system.
27 
28   @param  Buffer  Buffer to write to file.
29   @param  Length  Length of Buffer in bytes.
30 **/
31 VOID
32 WriteStringToFile (
33   IN  VOID    *Buffer,
34   IN  UINT32  Length
35   )
36 {
37   // Working around and issue with the code that is commented out. For now send it to the console.
38   // You can copy the console into a file and source the file as a script and you get symbols.
39   // This gets you all the symbols except for SEC. To get SEC symbols you need to copy the
40   // debug print in the SEC into the debugger manually
41   SemihostWriteString (Buffer);
42 /*
43   I'm currently having issues with this code crashing the debugger. Seems like it should work.
44 
45   UINT32        SemihostHandle;
46   UINT32        SemihostMode = SEMIHOST_FILE_MODE_WRITE | SEMIHOST_FILE_MODE_BINARY | SEMIHOST_FILE_MODE_UPDATE;
47 
48   SemihostFileOpen ("c:\rvi_symbols.inc", SemihostMode, &SemihostHandle);
49   SemihostFileWrite (SemihostHandle, &Length, Buffer);
50   SemihostFileClose (SemihostHandle);
51  */
52 }
53 
54 
55 /**
56   If the build is done on cygwin the paths are cygpaths.
57   /cygdrive/c/tmp.txt vs c:\tmp.txt so we need to convert
58   them to work with RVD commands
59 
60   @param  Name  Path to convert if needed
61 
62 **/
63 CHAR8 *
64 DeCygwinPathIfNeeded (
65   IN  CHAR8   *Name
66   )
67 {
68   CHAR8   *Ptr;
69   UINTN   Index;
70   UINTN   Len;
71 
72   Ptr = AsciiStrStr (Name, "/cygdrive/");
73   if (Ptr == NULL) {
74     return Name;
75   }
76 
77   Len = AsciiStrLen (Ptr);
78 
79   // convert "/cygdrive" to spaces
80   for (Index = 0; Index < 9; Index++) {
81     Ptr[Index] = ' ';
82   }
83 
84   // convert /c to c:
85   Ptr[9]  = Ptr[10];
86   Ptr[10] = ':';
87 
88   // switch path separators
89   for (Index = 11; Index < Len; Index++) {
90     if (Ptr[Index] == '/') {
91       Ptr[Index] = '\\' ;
92     }
93   }
94 
95   return Name;
96 }
97 
98 
99 /**
100   Performs additional actions after a PE/COFF image has been loaded and relocated.
101 
102   If ImageContext is NULL, then ASSERT().
103 
104   @param  ImageContext  Pointer to the image context structure that describes the
105                         PE/COFF image that has already been loaded and relocated.
106 
107 **/
108 VOID
109 EFIAPI
110 PeCoffLoaderRelocateImageExtraAction (
111   IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
112   )
113 {
114   CHAR8 Buffer[256];
115 
116 #if (__ARMCC_VERSION < 500000)
117   AsciiSPrint (Buffer, sizeof(Buffer), "load /a /ni /np \"%a\" &0x%08x\n", ImageContext->PdbPointer, (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders));
118 #else
119   AsciiSPrint (Buffer, sizeof(Buffer), "add-symbol-file %a 0x%08x\n", ImageContext->PdbPointer, (UINTN)(ImageContext->ImageAddress + ImageContext->SizeOfHeaders));
120 #endif
121   DeCygwinPathIfNeeded (&Buffer[16]);
122 
123   WriteStringToFile (Buffer, AsciiStrSize (Buffer));
124 }
125 
126 
127 
128 /**
129   Performs additional actions just before a PE/COFF image is unloaded.  Any resources
130   that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.
131 
132   If ImageContext is NULL, then ASSERT().
133 
134   @param  ImageContext  Pointer to the image context structure that describes the
135                         PE/COFF image that is being unloaded.
136 
137 **/
138 VOID
139 EFIAPI
140 PeCoffLoaderUnloadImageExtraAction (
141   IN OUT PE_COFF_LOADER_IMAGE_CONTEXT  *ImageContext
142   )
143 {
144   CHAR8 Buffer[256];
145 
146   AsciiSPrint (Buffer, sizeof(Buffer), "unload symbols_only \"%a\"\n", ImageContext->PdbPointer);
147   DeCygwinPathIfNeeded (Buffer);
148 
149   WriteStringToFile (Buffer, AsciiStrSize (Buffer));
150 }
151