TianoCore EDK2 master
Loading...
Searching...
No Matches
DebugAgentSymbolsBaseLib.c
Go to the documentation of this file.
1
10#include <Uefi.h>
11#include <Library/BaseLib.h>
13#include <Library/DebugLib.h>
15#include <Library/PcdLib.h>
17#include <Library/PeCoffLib.h>
18
19#include <Pi/PiFirmwareFile.h>
20#include <Pi/PiFirmwareVolume.h>
21
22#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
23 (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
24
25// Vector Table for Sec Phase
26VOID
27DebugAgentVectorTable (
28 VOID
29 );
30
43EFI_FFS_FILE_STATE
45 IN UINT8 ErasePolarity,
46 IN EFI_FFS_FILE_HEADER *FfsHeader
47 )
48{
49 EFI_FFS_FILE_STATE FileState;
50 EFI_FFS_FILE_STATE HighestBit;
51
52 FileState = FfsHeader->State;
53
54 if (ErasePolarity != 0) {
55 FileState = (EFI_FFS_FILE_STATE) ~FileState;
56 }
57
58 HighestBit = 0x80;
59 while (HighestBit != 0 && (HighestBit & FileState) == 0) {
60 HighestBit >>= 1;
61 }
62
63 return HighestBit;
64}
65
76UINT8
78 IN EFI_FFS_FILE_HEADER *FileHeader
79 )
80{
81 UINT8 Sum;
82
83 // Calculate the sum of the header
84 Sum = CalculateSum8 ((CONST VOID *)FileHeader, sizeof (EFI_FFS_FILE_HEADER));
85
86 // State field (since this indicates the different state of file).
87 Sum = (UINT8)(Sum - FileHeader->State);
88
89 // Checksum field of the file is not part of the header checksum.
90 Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);
91
92 return Sum;
93}
94
96GetFfsFile (
97 IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
98 IN EFI_FV_FILETYPE FileType,
99 OUT EFI_FFS_FILE_HEADER **FileHeader
100 )
101{
102 UINT64 FvLength;
103 UINTN FileOffset;
104 EFI_FFS_FILE_HEADER *FfsFileHeader;
105 UINT8 ErasePolarity;
106 UINT8 FileState;
107 UINT32 FileLength;
108 UINT32 FileOccupiedSize;
109
110 ASSERT (FwVolHeader->Signature == EFI_FVH_SIGNATURE);
111
112 FvLength = FwVolHeader->FvLength;
113 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
114 FileOffset = FwVolHeader->HeaderLength;
115
116 if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
117 ErasePolarity = 1;
118 } else {
119 ErasePolarity = 0;
120 }
121
122 while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
123 // Get FileState which is the highest bit of the State
124 FileState = GetFileState (ErasePolarity, FfsFileHeader);
125
126 switch (FileState) {
127 case EFI_FILE_HEADER_INVALID:
128 FileOffset += sizeof (EFI_FFS_FILE_HEADER);
129 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof (EFI_FFS_FILE_HEADER));
130 break;
131
132 case EFI_FILE_DATA_VALID:
133 case EFI_FILE_MARKED_FOR_UPDATE:
134 if (CalculateHeaderChecksum (FfsFileHeader) != 0) {
135 ASSERT (FALSE);
136 return EFI_NOT_FOUND;
137 }
138
139 if (FfsFileHeader->Type == FileType) {
140 *FileHeader = FfsFileHeader;
141 return EFI_SUCCESS;
142 }
143
144 FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
145 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
146
147 FileOffset += FileOccupiedSize;
148 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
149 break;
150
151 case EFI_FILE_DELETED:
152 FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
153 FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
154 FileOffset += FileOccupiedSize;
155 FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
156 break;
157
158 default:
159 return EFI_NOT_FOUND;
160 }
161 }
162
163 return EFI_NOT_FOUND;
164}
165
167GetImageContext (
168 IN EFI_FFS_FILE_HEADER *FfsHeader,
170 )
171{
172 EFI_STATUS Status;
173 UINTN ParsedLength;
174 UINTN SectionSize;
175 UINTN SectionLength;
177 VOID *EfiImage;
178 UINTN ImageAddress;
180 VOID *CodeViewEntryPointer;
181
182 Section = (EFI_COMMON_SECTION_HEADER *)(FfsHeader + 1);
183 SectionSize = *(UINT32 *)(FfsHeader->Size) & 0x00FFFFFF;
184 SectionSize -= sizeof (EFI_FFS_FILE_HEADER);
185 ParsedLength = 0;
186 EfiImage = NULL;
187
188 while (ParsedLength < SectionSize) {
189 if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) {
190 EfiImage = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(Section + 1);
191 break;
192 }
193
194 //
195 // Size is 24 bits wide so mask upper 8 bits.
196 // SectionLength is adjusted it is 4 byte aligned.
197 // Go to the next section
198 //
199 SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
200 SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
201 ASSERT (SectionLength != 0);
202 ParsedLength += SectionLength;
203 Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
204 }
205
206 if (EfiImage == NULL) {
207 return EFI_NOT_FOUND;
208 }
209
210 // Initialize the Image Context
211 ZeroMem (ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
212 ImageContext->Handle = EfiImage;
213 ImageContext->ImageRead = PeCoffLoaderImageReadFromMemory;
214
215 Status = PeCoffLoaderGetImageInfo (ImageContext);
216 if (!EFI_ERROR (Status) && ((VOID *)(UINTN)ImageContext->DebugDirectoryEntryRva != NULL)) {
217 ImageAddress = ImageContext->ImageAddress;
218 if (ImageContext->IsTeImage) {
219 ImageAddress += sizeof (EFI_TE_IMAGE_HEADER) - ((EFI_TE_IMAGE_HEADER *)EfiImage)->StrippedSize;
220 }
221
222 DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(ImageAddress + ImageContext->DebugDirectoryEntryRva);
223 if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
224 CodeViewEntryPointer = (VOID *)(ImageAddress + (UINTN)DebugEntry->RVA);
225 switch (*(UINT32 *)CodeViewEntryPointer) {
227 ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
228 break;
230 ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
231 break;
233 ImageContext->PdbPointer = (CHAR8 *)CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY);
234 break;
235 default:
236 break;
237 }
238 }
239 }
240
241 return Status;
242}
243
266VOID
267EFIAPI
269 IN UINT32 InitFlag,
270 IN VOID *Context OPTIONAL,
271 IN DEBUG_AGENT_CONTINUE Function OPTIONAL
272 )
273{
274 EFI_STATUS Status;
275 EFI_FFS_FILE_HEADER *FfsHeader;
276 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
277
278 // We use InitFlag to know if DebugAgent has been initialized from
279 // Sec (DEBUG_AGENT_INIT_PREMEM_SEC) or PrePi (DEBUG_AGENT_INIT_POSTMEM_SEC)
280 // modules
281 if (InitFlag == DEBUG_AGENT_INIT_PREMEM_SEC) {
282 //
283 // Get the Sec or PrePeiCore module (defined as SEC type module)
284 //
285 Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet64 (PcdSecureFvBaseAddress), EFI_FV_FILETYPE_SECURITY_CORE, &FfsHeader);
286 if (!EFI_ERROR (Status)) {
287 Status = GetImageContext (FfsHeader, &ImageContext);
288 if (!EFI_ERROR (Status)) {
290 }
291 }
292 } else if (InitFlag == DEBUG_AGENT_INIT_POSTMEM_SEC) {
293 //
294 // Get the PrePi or PrePeiCore module (defined as SEC type module)
295 //
296 Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet64 (PcdFvBaseAddress), EFI_FV_FILETYPE_SECURITY_CORE, &FfsHeader);
297 if (!EFI_ERROR (Status)) {
298 Status = GetImageContext (FfsHeader, &ImageContext);
299 if (!EFI_ERROR (Status)) {
301 }
302 }
303
304 //
305 // Get the PeiCore module (defined as PEI_CORE type module)
306 //
307 Status = GetFfsFile ((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet64 (PcdFvBaseAddress), EFI_FV_FILETYPE_PEI_CORE, &FfsHeader);
308 if (!EFI_ERROR (Status)) {
309 Status = GetImageContext (FfsHeader, &ImageContext);
310 if (!EFI_ERROR (Status)) {
312 }
313 }
314 }
315}
316
329BOOLEAN
330EFIAPI
332 IN BOOLEAN EnableStatus
333 )
334{
335 return FALSE;
336}
UINT64 UINTN
UINT8 EFIAPI CalculateSum8(IN CONST UINT8 *Buffer, IN UINTN Length)
Definition: CheckSum.c:33
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID(EFIAPI * DEBUG_AGENT_CONTINUE)(IN VOID *Context)
Definition: DebugAgentLib.h:43
STATIC EFI_FFS_FILE_STATE GetFileState(IN UINT8 ErasePolarity, IN EFI_FFS_FILE_HEADER *FfsHeader)
BOOLEAN EFIAPI SaveAndSetDebugTimerInterrupt(IN BOOLEAN EnableStatus)
VOID EFIAPI InitializeDebugAgent(IN UINT32 InitFlag, IN VOID *Context OPTIONAL, IN DEBUG_AGENT_CONTINUE Function OPTIONAL)
STATIC UINT8 CalculateHeaderChecksum(IN EFI_FFS_FILE_HEADER *FileHeader)
VOID EFIAPI PeCoffLoaderRelocateImageExtraAction(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
RETURN_STATUS EFIAPI PeCoffLoaderGetImageInfo(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
Definition: BasePeCoff.c:577
RETURN_STATUS EFIAPI PeCoffLoaderImageReadFromMemory(IN VOID *FileHandle, IN UINTN FileOffset, IN OUT UINTN *ReadSize, OUT VOID *Buffer)
Definition: BasePeCoff.c:1992
#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 CODEVIEW_SIGNATURE_MTOC
Definition: PeImage.h:687
#define EFI_SECTION_PE32
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_FV_FILETYPE Type
UINT32 RVA
The address of the debug data when loaded, relative to the image base.
Definition: PeImage.h:647