2 UEFI PropertiesTable support
4 Copyright (c) 2015, Intel Corporation. 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.
16 #include <Library/BaseLib.h>
17 #include <Library/BaseMemoryLib.h>
18 #include <Library/MemoryAllocationLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/DxeServicesTableLib.h>
21 #include <Library/DebugLib.h>
22 #include <Library/UefiLib.h>
23 #include <Library/PcdLib.h>
25 #include <Guid/EventGroup.h>
26 #include <Protocol/DxeSmmReadyToLock.h>
28 #include <Library/PeCoffLib.h>
29 #include <Library/PeCoffGetEntryPointLib.h>
30 #include <Protocol/Runtime.h>
32 #include <Guid/PropertiesTable.h>
36 #define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \
37 ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size)))
39 #define IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE SIGNATURE_32 ('I','P','R','C')
44 EFI_PHYSICAL_ADDRESS CodeSegmentBase
;
45 UINT64 CodeSegmentSize
;
46 } IMAGE_PROPERTIES_RECORD_CODE_SECTION
;
48 #define IMAGE_PROPERTIES_RECORD_SIGNATURE SIGNATURE_32 ('I','P','R','D')
53 EFI_PHYSICAL_ADDRESS ImageBase
;
55 UINTN CodeSegmentCount
;
56 LIST_ENTRY CodeSegmentList
;
57 } IMAGE_PROPERTIES_RECORD
;
59 #define IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('I','P','P','D')
63 UINTN ImageRecordCount
;
64 UINTN CodeSegmentCountMax
;
65 LIST_ENTRY ImageRecordList
;
66 } IMAGE_PROPERTIES_PRIVATE_DATA
;
68 IMAGE_PROPERTIES_PRIVATE_DATA mImagePropertiesPrivateData
= {
69 IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE
,
72 INITIALIZE_LIST_HEAD_VARIABLE (mImagePropertiesPrivateData
.ImageRecordList
)
75 EFI_PROPERTIES_TABLE mPropertiesTable
= {
76 EFI_PROPERTIES_TABLE_VERSION
,
77 sizeof(EFI_PROPERTIES_TABLE
),
78 EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA
81 EFI_LOCK mPropertiesTableLock
= EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY
);
84 // Below functions are for MemoryMap
88 Converts a number of EFI_PAGEs to a size in bytes.
90 NOTE: Do not use EFI_PAGES_TO_SIZE because it handles UINTN only.
92 @param Pages The number of EFI_PAGES.
94 @return The number of bytes associated with the number of EFI_PAGEs specified
103 return LShiftU64 (Pages
, EFI_PAGE_SHIFT
);
107 Converts a size, in bytes, to a number of EFI_PAGESs.
109 NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only.
111 @param Size A size in bytes.
113 @return The number of EFI_PAGESs associated with the number of bytes specified
123 return RShiftU64 (Size
, EFI_PAGE_SHIFT
) + ((((UINTN
)Size
) & EFI_PAGE_MASK
) ? 1 : 0);
127 Acquire memory lock on mPropertiesTableLock.
131 CoreAcquirePropertiesTableLock (
135 CoreAcquireLock (&mPropertiesTableLock
);
139 Release memory lock on mPropertiesTableLock.
143 CoreReleasePropertiesTableLock (
147 CoreReleaseLock (&mPropertiesTableLock
);
151 Sort memory map entries based upon PhysicalStart, from low to high.
153 @param MemoryMap A pointer to the buffer in which firmware places
154 the current memory map.
155 @param MemoryMapSize Size, in bytes, of the MemoryMap buffer.
156 @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
161 IN OUT EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
162 IN UINTN MemoryMapSize
,
163 IN UINTN DescriptorSize
166 EFI_MEMORY_DESCRIPTOR
*MemoryMapEntry
;
167 EFI_MEMORY_DESCRIPTOR
*NextMemoryMapEntry
;
168 EFI_MEMORY_DESCRIPTOR
*MemoryMapEnd
;
169 EFI_MEMORY_DESCRIPTOR TempMemoryMap
;
171 MemoryMapEntry
= MemoryMap
;
172 NextMemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry
, DescriptorSize
);
173 MemoryMapEnd
= (EFI_MEMORY_DESCRIPTOR
*) ((UINT8
*) MemoryMap
+ MemoryMapSize
);
174 while (MemoryMapEntry
< MemoryMapEnd
) {
175 while (NextMemoryMapEntry
< MemoryMapEnd
) {
176 if (MemoryMapEntry
->PhysicalStart
> NextMemoryMapEntry
->PhysicalStart
) {
177 CopyMem (&TempMemoryMap
, MemoryMapEntry
, sizeof(EFI_MEMORY_DESCRIPTOR
));
178 CopyMem (MemoryMapEntry
, NextMemoryMapEntry
, sizeof(EFI_MEMORY_DESCRIPTOR
));
179 CopyMem (NextMemoryMapEntry
, &TempMemoryMap
, sizeof(EFI_MEMORY_DESCRIPTOR
));
182 NextMemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry
, DescriptorSize
);
185 MemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry
, DescriptorSize
);
186 NextMemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry
, DescriptorSize
);
193 Merge continous memory map entries whose have same attributes.
195 @param MemoryMap A pointer to the buffer in which firmware places
196 the current memory map.
197 @param MemoryMapSize A pointer to the size, in bytes, of the
198 MemoryMap buffer. On input, this is the size of
199 the current memory map. On output,
200 it is the size of new memory map after merge.
201 @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
206 IN OUT EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
207 IN OUT UINTN
*MemoryMapSize
,
208 IN UINTN DescriptorSize
211 EFI_MEMORY_DESCRIPTOR
*MemoryMapEntry
;
212 EFI_MEMORY_DESCRIPTOR
*MemoryMapEnd
;
213 UINT64 MemoryBlockLength
;
214 EFI_MEMORY_DESCRIPTOR
*NewMemoryMapEntry
;
215 EFI_MEMORY_DESCRIPTOR
*NextMemoryMapEntry
;
217 MemoryMapEntry
= MemoryMap
;
218 NewMemoryMapEntry
= MemoryMap
;
219 MemoryMapEnd
= (EFI_MEMORY_DESCRIPTOR
*) ((UINT8
*) MemoryMap
+ *MemoryMapSize
);
220 while ((UINTN
)MemoryMapEntry
< (UINTN
)MemoryMapEnd
) {
221 CopyMem (NewMemoryMapEntry
, MemoryMapEntry
, sizeof(EFI_MEMORY_DESCRIPTOR
));
222 NextMemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry
, DescriptorSize
);
224 MemoryBlockLength
= (UINT64
) (EfiPagesToSize (MemoryMapEntry
->NumberOfPages
));
225 if (((UINTN
)NextMemoryMapEntry
< (UINTN
)MemoryMapEnd
) &&
226 (MemoryMapEntry
->Type
== NextMemoryMapEntry
->Type
) &&
227 (MemoryMapEntry
->Attribute
== NextMemoryMapEntry
->Attribute
) &&
228 ((MemoryMapEntry
->PhysicalStart
+ MemoryBlockLength
) == NextMemoryMapEntry
->PhysicalStart
)) {
229 NewMemoryMapEntry
->NumberOfPages
+= NextMemoryMapEntry
->NumberOfPages
;
230 MemoryMapEntry
= NextMemoryMapEntry
;
233 MemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry
, DescriptorSize
);
234 NewMemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry
, DescriptorSize
);
237 *MemoryMapSize
= (UINTN
)NewMemoryMapEntry
- (UINTN
)MemoryMap
;
243 Enforce memory map attributes.
244 This function will set EfiRuntimeServicesData/EfiMemoryMappedIO/EfiMemoryMappedIOPortSpace to be EFI_MEMORY_XP.
246 @param MemoryMap A pointer to the buffer in which firmware places
247 the current memory map.
248 @param MemoryMapSize Size, in bytes, of the MemoryMap buffer.
249 @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
253 EnforceMemoryMapAttribute (
254 IN OUT EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
255 IN UINTN MemoryMapSize
,
256 IN UINTN DescriptorSize
259 EFI_MEMORY_DESCRIPTOR
*MemoryMapEntry
;
260 EFI_MEMORY_DESCRIPTOR
*MemoryMapEnd
;
262 MemoryMapEntry
= MemoryMap
;
263 MemoryMapEnd
= (EFI_MEMORY_DESCRIPTOR
*) ((UINT8
*) MemoryMap
+ MemoryMapSize
);
264 while ((UINTN
)MemoryMapEntry
< (UINTN
)MemoryMapEnd
) {
265 switch (MemoryMapEntry
->Type
) {
266 case EfiRuntimeServicesCode
:
269 case EfiRuntimeServicesData
:
270 case EfiMemoryMappedIO
:
271 case EfiMemoryMappedIOPortSpace
:
272 MemoryMapEntry
->Attribute
|= EFI_MEMORY_XP
;
274 case EfiReservedMemoryType
:
275 case EfiACPIMemoryNVS
:
279 MemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry
, DescriptorSize
);
286 Return the first image record, whose [ImageBase, ImageSize] covered by [Buffer, Length].
288 @param Buffer Start Address
289 @param Length Address length
291 @return first image record covered by [buffer, length]
294 IMAGE_PROPERTIES_RECORD
*
295 GetImageRecordByAddress (
296 IN EFI_PHYSICAL_ADDRESS Buffer
,
300 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
301 LIST_ENTRY
*ImageRecordLink
;
302 LIST_ENTRY
*ImageRecordList
;
304 ImageRecordList
= &mImagePropertiesPrivateData
.ImageRecordList
;
306 for (ImageRecordLink
= ImageRecordList
->ForwardLink
;
307 ImageRecordLink
!= ImageRecordList
;
308 ImageRecordLink
= ImageRecordLink
->ForwardLink
) {
311 IMAGE_PROPERTIES_RECORD
,
313 IMAGE_PROPERTIES_RECORD_SIGNATURE
316 if ((Buffer
<= ImageRecord
->ImageBase
) &&
317 (Buffer
+ Length
>= ImageRecord
->ImageBase
+ ImageRecord
->ImageSize
)) {
326 Set the memory map to new entries, according to one old entry,
327 based upon PE code section and data section in image record
329 @param ImageRecord An image record whose [ImageBase, ImageSize] covered
330 by old memory map entry.
331 @param NewRecord A pointer to several new memory map entries.
332 The caller gurantee the buffer size be 1 +
333 (SplitRecordCount * DescriptorSize) calculated
335 @param OldRecord A pointer to one old memory map entry.
336 @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
341 IN IMAGE_PROPERTIES_RECORD
*ImageRecord
,
342 IN OUT EFI_MEMORY_DESCRIPTOR
*NewRecord
,
343 IN EFI_MEMORY_DESCRIPTOR
*OldRecord
,
344 IN UINTN DescriptorSize
347 EFI_MEMORY_DESCRIPTOR TempRecord
;
348 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*ImageRecordCodeSection
;
349 LIST_ENTRY
*ImageRecordCodeSectionLink
;
350 LIST_ENTRY
*ImageRecordCodeSectionEndLink
;
351 LIST_ENTRY
*ImageRecordCodeSectionList
;
352 UINTN NewRecordCount
;
356 CopyMem (&TempRecord
, OldRecord
, sizeof(EFI_MEMORY_DESCRIPTOR
));
357 PhysicalEnd
= TempRecord
.PhysicalStart
+ EfiPagesToSize(TempRecord
.NumberOfPages
);
360 ImageRecordCodeSectionList
= &ImageRecord
->CodeSegmentList
;
362 ImageRecordCodeSectionLink
= ImageRecordCodeSectionList
->ForwardLink
;
363 ImageRecordCodeSectionEndLink
= ImageRecordCodeSectionList
;
364 while (ImageRecordCodeSectionLink
!= ImageRecordCodeSectionEndLink
) {
365 ImageRecordCodeSection
= CR (
366 ImageRecordCodeSectionLink
,
367 IMAGE_PROPERTIES_RECORD_CODE_SECTION
,
369 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
371 ImageRecordCodeSectionLink
= ImageRecordCodeSectionLink
->ForwardLink
;
373 if (TempRecord
.PhysicalStart
<= ImageRecordCodeSection
->CodeSegmentBase
) {
377 NewRecord
->Type
= EfiRuntimeServicesData
;
378 NewRecord
->PhysicalStart
= TempRecord
.PhysicalStart
;
379 NewRecord
->VirtualStart
= 0;
380 NewRecord
->NumberOfPages
= EfiSizeToPages(ImageRecordCodeSection
->CodeSegmentBase
- NewRecord
->PhysicalStart
);
381 NewRecord
->Attribute
= TempRecord
.Attribute
| EFI_MEMORY_XP
;
382 if (NewRecord
->NumberOfPages
!= 0) {
383 NewRecord
= NEXT_MEMORY_DESCRIPTOR (NewRecord
, DescriptorSize
);
390 NewRecord
->Type
= EfiRuntimeServicesCode
;
391 NewRecord
->PhysicalStart
= ImageRecordCodeSection
->CodeSegmentBase
;
392 NewRecord
->VirtualStart
= 0;
393 NewRecord
->NumberOfPages
= EfiSizeToPages(ImageRecordCodeSection
->CodeSegmentSize
);
394 NewRecord
->Attribute
= (TempRecord
.Attribute
& (~EFI_MEMORY_XP
)) | EFI_MEMORY_RO
;
395 if (NewRecord
->NumberOfPages
!= 0) {
396 NewRecord
= NEXT_MEMORY_DESCRIPTOR (NewRecord
, DescriptorSize
);
400 TempRecord
.PhysicalStart
= ImageRecordCodeSection
->CodeSegmentBase
+ EfiPagesToSize (EfiSizeToPages(ImageRecordCodeSection
->CodeSegmentSize
));
401 TempRecord
.NumberOfPages
= EfiSizeToPages(PhysicalEnd
- TempRecord
.PhysicalStart
);
402 if (TempRecord
.NumberOfPages
== 0) {
408 ImageEnd
= ImageRecord
->ImageBase
+ ImageRecord
->ImageSize
;
413 if (TempRecord
.PhysicalStart
< ImageEnd
) {
414 NewRecord
->Type
= EfiRuntimeServicesData
;
415 NewRecord
->PhysicalStart
= TempRecord
.PhysicalStart
;
416 NewRecord
->VirtualStart
= 0;
417 NewRecord
->NumberOfPages
= EfiSizeToPages (ImageEnd
- TempRecord
.PhysicalStart
);
418 NewRecord
->Attribute
= TempRecord
.Attribute
| EFI_MEMORY_XP
;
422 return NewRecordCount
;
426 Return the max number of new splitted entries, according to one old entry,
427 based upon PE code section and data section.
429 @param OldRecord A pointer to one old memory map entry.
431 @retval 0 no entry need to be splitted.
432 @return the max number of new splitted entries
436 GetMaxSplitRecordCount (
437 IN EFI_MEMORY_DESCRIPTOR
*OldRecord
440 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
441 UINTN SplitRecordCount
;
442 UINT64 PhysicalStart
;
445 SplitRecordCount
= 0;
446 PhysicalStart
= OldRecord
->PhysicalStart
;
447 PhysicalEnd
= OldRecord
->PhysicalStart
+ EfiPagesToSize(OldRecord
->NumberOfPages
);
450 ImageRecord
= GetImageRecordByAddress (PhysicalStart
, PhysicalEnd
- PhysicalStart
);
451 if (ImageRecord
== NULL
) {
454 SplitRecordCount
+= (2 * ImageRecord
->CodeSegmentCount
+ 1);
455 PhysicalStart
= ImageRecord
->ImageBase
+ ImageRecord
->ImageSize
;
456 } while ((ImageRecord
!= NULL
) && (PhysicalStart
< PhysicalEnd
));
458 if (SplitRecordCount
!= 0) {
462 return SplitRecordCount
;
466 Split the memory map to new entries, according to one old entry,
467 based upon PE code section and data section.
469 @param OldRecord A pointer to one old memory map entry.
470 @param NewRecord A pointer to several new memory map entries.
471 The caller gurantee the buffer size be 1 +
472 (SplitRecordCount * DescriptorSize) calculated
474 @param MaxSplitRecordCount The max number of splitted entries
475 @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
477 @retval 0 no entry is splitted.
478 @return the real number of splitted record.
483 IN EFI_MEMORY_DESCRIPTOR
*OldRecord
,
484 IN OUT EFI_MEMORY_DESCRIPTOR
*NewRecord
,
485 IN UINTN MaxSplitRecordCount
,
486 IN UINTN DescriptorSize
489 EFI_MEMORY_DESCRIPTOR TempRecord
;
490 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
491 IMAGE_PROPERTIES_RECORD
*NewImageRecord
;
492 UINT64 PhysicalStart
;
494 UINTN NewRecordCount
;
495 UINTN TotalNewRecordCount
;
497 if (MaxSplitRecordCount
== 0) {
498 CopyMem (NewRecord
, OldRecord
, DescriptorSize
);
502 TotalNewRecordCount
= 0;
505 // Override previous record
507 CopyMem (&TempRecord
, OldRecord
, sizeof(EFI_MEMORY_DESCRIPTOR
));
508 PhysicalStart
= TempRecord
.PhysicalStart
;
509 PhysicalEnd
= TempRecord
.PhysicalStart
+ EfiPagesToSize(TempRecord
.NumberOfPages
);
513 NewImageRecord
= GetImageRecordByAddress (PhysicalStart
, PhysicalEnd
- PhysicalStart
);
514 if (NewImageRecord
== NULL
) {
516 // No more image covered by this range, stop
518 if ((PhysicalEnd
> PhysicalStart
) && (ImageRecord
!= NULL
)) {
520 // If this is still address in this record, need record.
522 NewRecord
= PREVIOUS_MEMORY_DESCRIPTOR (NewRecord
, DescriptorSize
);
523 if (NewRecord
->Type
== EfiRuntimeServicesData
) {
525 // Last record is DATA, just merge it.
527 NewRecord
->NumberOfPages
= EfiSizeToPages(PhysicalEnd
- NewRecord
->PhysicalStart
);
530 // Last record is CODE, create a new DATA entry.
532 NewRecord
= NEXT_MEMORY_DESCRIPTOR (NewRecord
, DescriptorSize
);
533 NewRecord
->Type
= EfiRuntimeServicesData
;
534 NewRecord
->PhysicalStart
= TempRecord
.PhysicalStart
;
535 NewRecord
->VirtualStart
= 0;
536 NewRecord
->NumberOfPages
= TempRecord
.NumberOfPages
;
537 NewRecord
->Attribute
= TempRecord
.Attribute
| EFI_MEMORY_XP
;
538 TotalNewRecordCount
++;
543 ImageRecord
= NewImageRecord
;
548 NewRecordCount
= SetNewRecord (ImageRecord
, NewRecord
, &TempRecord
, DescriptorSize
);
549 TotalNewRecordCount
+= NewRecordCount
;
550 NewRecord
= (EFI_MEMORY_DESCRIPTOR
*)((UINT8
*)NewRecord
+ NewRecordCount
* DescriptorSize
);
553 // Update PhysicalStart, in order to exclude the image buffer already splitted.
555 PhysicalStart
= ImageRecord
->ImageBase
+ ImageRecord
->ImageSize
;
556 TempRecord
.PhysicalStart
= PhysicalStart
;
557 TempRecord
.NumberOfPages
= EfiSizeToPages (PhysicalEnd
- PhysicalStart
);
558 } while ((ImageRecord
!= NULL
) && (PhysicalStart
< PhysicalEnd
));
560 return TotalNewRecordCount
- 1;
564 Split the original memory map, and add more entries to describe PE code section and data section.
565 This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP.
566 This function will merge entries with same attributes finally.
568 NOTE: It assumes PE code/data section are page aligned.
569 NOTE: It assumes enough entry is prepared for new memory map.
582 +---------------+ ----
585 | Record RtCode | |-> PE/COFF1
588 +---------------+ ----
591 | Record RtCode | |-> PE/COFF2
594 +---------------+ ----
598 @param MemoryMapSize A pointer to the size, in bytes, of the
599 MemoryMap buffer. On input, this is the size of
600 old MemoryMap before split. The actual buffer
601 size of MemoryMap is MemoryMapSize +
602 (AdditionalRecordCount * DescriptorSize) calculated
603 below. On output, it is the size of new MemoryMap
605 @param MemoryMap A pointer to the buffer in which firmware places
606 the current memory map.
607 @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
612 IN OUT UINTN
*MemoryMapSize
,
613 IN OUT EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
614 IN UINTN DescriptorSize
619 UINTN MaxSplitRecordCount
;
620 UINTN RealSplitRecordCount
;
621 UINTN TotalSplitRecordCount
;
622 UINTN AdditionalRecordCount
;
624 AdditionalRecordCount
= (2 * mImagePropertiesPrivateData
.CodeSegmentCountMax
+ 1) * mImagePropertiesPrivateData
.ImageRecordCount
;
626 TotalSplitRecordCount
= 0;
628 // Let old record point to end of valid MemoryMap buffer.
630 IndexOld
= ((*MemoryMapSize
) / DescriptorSize
) - 1;
632 // Let new record point to end of full MemoryMap buffer.
634 IndexNew
= ((*MemoryMapSize
) / DescriptorSize
) - 1 + AdditionalRecordCount
;
635 for (; IndexOld
>= 0; IndexOld
--) {
636 MaxSplitRecordCount
= GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR
*)((UINT8
*)MemoryMap
+ IndexOld
* DescriptorSize
));
638 // Split this MemoryMap record
640 IndexNew
-= MaxSplitRecordCount
;
641 RealSplitRecordCount
= SplitRecord (
642 (EFI_MEMORY_DESCRIPTOR
*)((UINT8
*)MemoryMap
+ IndexOld
* DescriptorSize
),
643 (EFI_MEMORY_DESCRIPTOR
*)((UINT8
*)MemoryMap
+ IndexNew
* DescriptorSize
),
648 // Adjust IndexNew according to real split.
651 ((UINT8
*)MemoryMap
+ (IndexNew
+ MaxSplitRecordCount
- RealSplitRecordCount
) * DescriptorSize
),
652 ((UINT8
*)MemoryMap
+ IndexNew
* DescriptorSize
),
653 RealSplitRecordCount
* DescriptorSize
655 IndexNew
= IndexNew
+ MaxSplitRecordCount
- RealSplitRecordCount
;
656 TotalSplitRecordCount
+= RealSplitRecordCount
;
660 // Move all records to the beginning.
664 (UINT8
*)MemoryMap
+ (AdditionalRecordCount
- TotalSplitRecordCount
) * DescriptorSize
,
665 (*MemoryMapSize
) + TotalSplitRecordCount
* DescriptorSize
668 *MemoryMapSize
= (*MemoryMapSize
) + DescriptorSize
* TotalSplitRecordCount
;
671 // Sort from low to high (Just in case)
673 SortMemoryMap (MemoryMap
, *MemoryMapSize
, DescriptorSize
);
676 // Set RuntimeData to XP
678 EnforceMemoryMapAttribute (MemoryMap
, *MemoryMapSize
, DescriptorSize
);
681 // Merge same type to save entry size
683 MergeMemoryMap (MemoryMap
, MemoryMapSize
, DescriptorSize
);
689 This function for GetMemoryMap() with properties table.
691 It calls original GetMemoryMap() to get the original memory map information. Then
692 plus the additional memory map entries for PE Code/Data seperation.
694 @param MemoryMapSize A pointer to the size, in bytes, of the
695 MemoryMap buffer. On input, this is the size of
696 the buffer allocated by the caller. On output,
697 it is the size of the buffer returned by the
698 firmware if the buffer was large enough, or the
699 size of the buffer needed to contain the map if
700 the buffer was too small.
701 @param MemoryMap A pointer to the buffer in which firmware places
702 the current memory map.
703 @param MapKey A pointer to the location in which firmware
704 returns the key for the current memory map.
705 @param DescriptorSize A pointer to the location in which firmware
706 returns the size, in bytes, of an individual
707 EFI_MEMORY_DESCRIPTOR.
708 @param DescriptorVersion A pointer to the location in which firmware
709 returns the version number associated with the
710 EFI_MEMORY_DESCRIPTOR.
712 @retval EFI_SUCCESS The memory map was returned in the MemoryMap
714 @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current
715 buffer size needed to hold the memory map is
716 returned in MemoryMapSize.
717 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
723 CoreGetMemoryMapPropertiesTable (
724 IN OUT UINTN
*MemoryMapSize
,
725 IN OUT EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
727 OUT UINTN
*DescriptorSize
,
728 OUT UINT32
*DescriptorVersion
732 UINTN OldMemoryMapSize
;
733 UINTN AdditionalRecordCount
;
736 // If PE code/data is not aligned, just return.
738 if ((mPropertiesTable
.MemoryProtectionAttribute
& EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA
) == 0) {
739 return CoreGetMemoryMap (MemoryMapSize
, MemoryMap
, MapKey
, DescriptorSize
, DescriptorVersion
);
742 if (MemoryMapSize
== NULL
) {
743 return EFI_INVALID_PARAMETER
;
746 CoreAcquirePropertiesTableLock ();
748 AdditionalRecordCount
= (2 * mImagePropertiesPrivateData
.CodeSegmentCountMax
+ 1) * mImagePropertiesPrivateData
.ImageRecordCount
;
750 OldMemoryMapSize
= *MemoryMapSize
;
751 Status
= CoreGetMemoryMap (MemoryMapSize
, MemoryMap
, MapKey
, DescriptorSize
, DescriptorVersion
);
752 if (Status
== EFI_BUFFER_TOO_SMALL
) {
753 *MemoryMapSize
= *MemoryMapSize
+ (*DescriptorSize
) * AdditionalRecordCount
;
754 } else if (Status
== EFI_SUCCESS
) {
755 if (OldMemoryMapSize
- *MemoryMapSize
< (*DescriptorSize
) * AdditionalRecordCount
) {
756 *MemoryMapSize
= *MemoryMapSize
+ (*DescriptorSize
) * AdditionalRecordCount
;
758 // Need update status to buffer too small
760 Status
= EFI_BUFFER_TOO_SMALL
;
763 // Split PE code/data
765 SplitTable (MemoryMapSize
, MemoryMap
, *DescriptorSize
);
769 CoreReleasePropertiesTableLock ();
774 // Below functions are for ImageRecord
778 Set PropertiesTable according to PE/COFF image section alignment.
780 @param SectionAlignment PE/COFF section alignment
784 SetPropertiesTableSectionAlignment (
785 IN UINT32 SectionAlignment
788 if (((SectionAlignment
& (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT
- 1)) != 0) &&
789 ((mPropertiesTable
.MemoryProtectionAttribute
& EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA
) != 0)) {
790 DEBUG ((EFI_D_VERBOSE
, "SetPropertiesTableSectionAlignment - Clear\n"));
791 mPropertiesTable
.MemoryProtectionAttribute
&= ~((UINT64
)EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA
);
792 gBS
->GetMemoryMap
= CoreGetMemoryMap
;
794 gBS
->CalculateCrc32 ((UINT8
*)gBS
, gBS
->Hdr
.HeaderSize
, &gBS
->Hdr
.CRC32
);
799 Swap two code sections in image record.
801 @param FirstImageRecordCodeSection first code section in image record
802 @param SecondImageRecordCodeSection second code section in image record
806 SwapImageRecordCodeSection (
807 IN IMAGE_PROPERTIES_RECORD_CODE_SECTION
*FirstImageRecordCodeSection
,
808 IN IMAGE_PROPERTIES_RECORD_CODE_SECTION
*SecondImageRecordCodeSection
811 IMAGE_PROPERTIES_RECORD_CODE_SECTION TempImageRecordCodeSection
;
813 TempImageRecordCodeSection
.CodeSegmentBase
= FirstImageRecordCodeSection
->CodeSegmentBase
;
814 TempImageRecordCodeSection
.CodeSegmentSize
= FirstImageRecordCodeSection
->CodeSegmentSize
;
816 FirstImageRecordCodeSection
->CodeSegmentBase
= SecondImageRecordCodeSection
->CodeSegmentBase
;
817 FirstImageRecordCodeSection
->CodeSegmentSize
= SecondImageRecordCodeSection
->CodeSegmentSize
;
819 SecondImageRecordCodeSection
->CodeSegmentBase
= TempImageRecordCodeSection
.CodeSegmentBase
;
820 SecondImageRecordCodeSection
->CodeSegmentSize
= TempImageRecordCodeSection
.CodeSegmentSize
;
824 Sort code section in image record, based upon CodeSegmentBase from low to high.
826 @param ImageRecord image record to be sorted
830 SortImageRecordCodeSection (
831 IN IMAGE_PROPERTIES_RECORD
*ImageRecord
834 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*ImageRecordCodeSection
;
835 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*NextImageRecordCodeSection
;
836 LIST_ENTRY
*ImageRecordCodeSectionLink
;
837 LIST_ENTRY
*NextImageRecordCodeSectionLink
;
838 LIST_ENTRY
*ImageRecordCodeSectionEndLink
;
839 LIST_ENTRY
*ImageRecordCodeSectionList
;
841 ImageRecordCodeSectionList
= &ImageRecord
->CodeSegmentList
;
843 ImageRecordCodeSectionLink
= ImageRecordCodeSectionList
->ForwardLink
;
844 NextImageRecordCodeSectionLink
= ImageRecordCodeSectionLink
->ForwardLink
;
845 ImageRecordCodeSectionEndLink
= ImageRecordCodeSectionList
;
846 while (ImageRecordCodeSectionLink
!= ImageRecordCodeSectionEndLink
) {
847 ImageRecordCodeSection
= CR (
848 ImageRecordCodeSectionLink
,
849 IMAGE_PROPERTIES_RECORD_CODE_SECTION
,
851 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
853 while (NextImageRecordCodeSectionLink
!= ImageRecordCodeSectionEndLink
) {
854 NextImageRecordCodeSection
= CR (
855 NextImageRecordCodeSectionLink
,
856 IMAGE_PROPERTIES_RECORD_CODE_SECTION
,
858 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
860 if (ImageRecordCodeSection
->CodeSegmentBase
> NextImageRecordCodeSection
->CodeSegmentBase
) {
861 SwapImageRecordCodeSection (ImageRecordCodeSection
, NextImageRecordCodeSection
);
863 NextImageRecordCodeSectionLink
= NextImageRecordCodeSectionLink
->ForwardLink
;
866 ImageRecordCodeSectionLink
= ImageRecordCodeSectionLink
->ForwardLink
;
867 NextImageRecordCodeSectionLink
= ImageRecordCodeSectionLink
->ForwardLink
;
872 Check if code section in image record is valid.
874 @param ImageRecord image record to be checked
876 @retval TRUE image record is valid
877 @retval FALSE image record is invalid
881 IsImageRecordCodeSectionValid (
882 IN IMAGE_PROPERTIES_RECORD
*ImageRecord
885 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*ImageRecordCodeSection
;
886 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*LastImageRecordCodeSection
;
887 LIST_ENTRY
*ImageRecordCodeSectionLink
;
888 LIST_ENTRY
*ImageRecordCodeSectionEndLink
;
889 LIST_ENTRY
*ImageRecordCodeSectionList
;
891 DEBUG ((EFI_D_VERBOSE
, "ImageCode SegmentCount - 0x%x\n", ImageRecord
->CodeSegmentCount
));
893 ImageRecordCodeSectionList
= &ImageRecord
->CodeSegmentList
;
895 ImageRecordCodeSectionLink
= ImageRecordCodeSectionList
->ForwardLink
;
896 ImageRecordCodeSectionEndLink
= ImageRecordCodeSectionList
;
897 LastImageRecordCodeSection
= NULL
;
898 while (ImageRecordCodeSectionLink
!= ImageRecordCodeSectionEndLink
) {
899 ImageRecordCodeSection
= CR (
900 ImageRecordCodeSectionLink
,
901 IMAGE_PROPERTIES_RECORD_CODE_SECTION
,
903 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
905 if (ImageRecordCodeSection
->CodeSegmentSize
== 0) {
908 if (ImageRecordCodeSection
->CodeSegmentBase
< ImageRecord
->ImageBase
) {
911 if (ImageRecordCodeSection
->CodeSegmentBase
>= MAX_ADDRESS
- ImageRecordCodeSection
->CodeSegmentSize
) {
914 if ((ImageRecordCodeSection
->CodeSegmentBase
+ ImageRecordCodeSection
->CodeSegmentSize
) > (ImageRecord
->ImageBase
+ ImageRecord
->ImageSize
)) {
917 if (LastImageRecordCodeSection
!= NULL
) {
918 if ((LastImageRecordCodeSection
->CodeSegmentBase
+ LastImageRecordCodeSection
->CodeSegmentSize
) > ImageRecordCodeSection
->CodeSegmentBase
) {
923 LastImageRecordCodeSection
= ImageRecordCodeSection
;
924 ImageRecordCodeSectionLink
= ImageRecordCodeSectionLink
->ForwardLink
;
931 Swap two image records.
933 @param FirstImageRecord first image record.
934 @param SecondImageRecord second image record.
939 IN IMAGE_PROPERTIES_RECORD
*FirstImageRecord
,
940 IN IMAGE_PROPERTIES_RECORD
*SecondImageRecord
943 IMAGE_PROPERTIES_RECORD TempImageRecord
;
945 TempImageRecord
.ImageBase
= FirstImageRecord
->ImageBase
;
946 TempImageRecord
.ImageSize
= FirstImageRecord
->ImageSize
;
947 TempImageRecord
.CodeSegmentCount
= FirstImageRecord
->CodeSegmentCount
;
949 FirstImageRecord
->ImageBase
= SecondImageRecord
->ImageBase
;
950 FirstImageRecord
->ImageSize
= SecondImageRecord
->ImageSize
;
951 FirstImageRecord
->CodeSegmentCount
= SecondImageRecord
->CodeSegmentCount
;
953 SecondImageRecord
->ImageBase
= TempImageRecord
.ImageBase
;
954 SecondImageRecord
->ImageSize
= TempImageRecord
.ImageSize
;
955 SecondImageRecord
->CodeSegmentCount
= TempImageRecord
.CodeSegmentCount
;
957 SwapListEntries (&FirstImageRecord
->CodeSegmentList
, &SecondImageRecord
->CodeSegmentList
);
961 Sort image record based upon the ImageBase from low to high.
969 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
970 IMAGE_PROPERTIES_RECORD
*NextImageRecord
;
971 LIST_ENTRY
*ImageRecordLink
;
972 LIST_ENTRY
*NextImageRecordLink
;
973 LIST_ENTRY
*ImageRecordEndLink
;
974 LIST_ENTRY
*ImageRecordList
;
976 ImageRecordList
= &mImagePropertiesPrivateData
.ImageRecordList
;
978 ImageRecordLink
= ImageRecordList
->ForwardLink
;
979 NextImageRecordLink
= ImageRecordLink
->ForwardLink
;
980 ImageRecordEndLink
= ImageRecordList
;
981 while (ImageRecordLink
!= ImageRecordEndLink
) {
984 IMAGE_PROPERTIES_RECORD
,
986 IMAGE_PROPERTIES_RECORD_SIGNATURE
988 while (NextImageRecordLink
!= ImageRecordEndLink
) {
989 NextImageRecord
= CR (
991 IMAGE_PROPERTIES_RECORD
,
993 IMAGE_PROPERTIES_RECORD_SIGNATURE
995 if (ImageRecord
->ImageBase
> NextImageRecord
->ImageBase
) {
996 SwapImageRecord (ImageRecord
, NextImageRecord
);
998 NextImageRecordLink
= NextImageRecordLink
->ForwardLink
;
1001 ImageRecordLink
= ImageRecordLink
->ForwardLink
;
1002 NextImageRecordLink
= ImageRecordLink
->ForwardLink
;
1015 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
1016 LIST_ENTRY
*ImageRecordLink
;
1017 LIST_ENTRY
*ImageRecordList
;
1020 ImageRecordList
= &mImagePropertiesPrivateData
.ImageRecordList
;
1022 for (ImageRecordLink
= ImageRecordList
->ForwardLink
, Index
= 0;
1023 ImageRecordLink
!= ImageRecordList
;
1024 ImageRecordLink
= ImageRecordLink
->ForwardLink
, Index
++) {
1027 IMAGE_PROPERTIES_RECORD
,
1029 IMAGE_PROPERTIES_RECORD_SIGNATURE
1031 DEBUG ((EFI_D_VERBOSE
, " Image[%d]: 0x%016lx - 0x%016lx\n", Index
, ImageRecord
->ImageBase
, ImageRecord
->ImageSize
));
1036 Insert image record.
1038 @param RuntimeImage Runtime image information
1042 IN EFI_RUNTIME_IMAGE_ENTRY
*RuntimeImage
1046 EFI_IMAGE_DOS_HEADER
*DosHdr
;
1047 UINT32 PeCoffHeaderOffset
;
1048 UINT32 SectionAlignment
;
1049 EFI_IMAGE_SECTION_HEADER
*Section
;
1050 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
1053 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
1055 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*ImageRecordCodeSection
;
1058 DEBUG ((EFI_D_VERBOSE
, "InsertImageRecord - 0x%x\n", RuntimeImage
));
1059 DEBUG ((EFI_D_VERBOSE
, "InsertImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS
)(UINTN
)RuntimeImage
->ImageBase
, RuntimeImage
->ImageSize
));
1061 ImageRecord
= AllocatePool (sizeof(*ImageRecord
));
1062 if (ImageRecord
== NULL
) {
1065 ImageRecord
->Signature
= IMAGE_PROPERTIES_RECORD_SIGNATURE
;
1067 DEBUG ((EFI_D_VERBOSE
, "ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData
.ImageRecordCount
));
1070 // Step 1: record whole region
1072 ImageRecord
->ImageBase
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)RuntimeImage
->ImageBase
;
1073 ImageRecord
->ImageSize
= RuntimeImage
->ImageSize
;
1075 ImageAddress
= RuntimeImage
->ImageBase
;
1077 PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageAddress
);
1078 if (PdbPointer
!= NULL
) {
1079 DEBUG ((EFI_D_VERBOSE
, " Image - %a\n", PdbPointer
));
1083 // Check PE/COFF image
1085 DosHdr
= (EFI_IMAGE_DOS_HEADER
*) (UINTN
) ImageAddress
;
1086 PeCoffHeaderOffset
= 0;
1087 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
1088 PeCoffHeaderOffset
= DosHdr
->e_lfanew
;
1091 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*)((UINT8
*) (UINTN
) ImageAddress
+ PeCoffHeaderOffset
);
1092 if (Hdr
.Pe32
->Signature
!= EFI_IMAGE_NT_SIGNATURE
) {
1093 DEBUG ((EFI_D_VERBOSE
, "Hdr.Pe32->Signature invalid - 0x%x\n", Hdr
.Pe32
->Signature
));
1094 // It might be image in SMM.
1099 // Get SectionAlignment
1101 if (Hdr
.Pe32
->FileHeader
.Machine
== IMAGE_FILE_MACHINE_IA64
&& Hdr
.Pe32
->OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1103 // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value
1104 // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the
1105 // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
1106 // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
1108 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
1111 // Get the magic value from the PE/COFF Optional Header
1113 Magic
= Hdr
.Pe32
->OptionalHeader
.Magic
;
1115 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1116 SectionAlignment
= Hdr
.Pe32
->OptionalHeader
.SectionAlignment
;
1118 SectionAlignment
= Hdr
.Pe32Plus
->OptionalHeader
.SectionAlignment
;
1121 SetPropertiesTableSectionAlignment (SectionAlignment
);
1122 if ((SectionAlignment
& (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT
- 1)) != 0) {
1123 DEBUG ((EFI_D_WARN
, "!!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not %dK !!!!!!!!\n",
1124 SectionAlignment
, EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT
>> 10));
1125 PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageAddress
);
1126 if (PdbPointer
!= NULL
) {
1127 DEBUG ((EFI_D_WARN
, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer
));
1132 Section
= (EFI_IMAGE_SECTION_HEADER
*) (
1133 (UINT8
*) (UINTN
) ImageAddress
+
1134 PeCoffHeaderOffset
+
1136 sizeof(EFI_IMAGE_FILE_HEADER
) +
1137 Hdr
.Pe32
->FileHeader
.SizeOfOptionalHeader
1139 ImageRecord
->CodeSegmentCount
= 0;
1140 InitializeListHead (&ImageRecord
->CodeSegmentList
);
1141 for (Index
= 0; Index
< Hdr
.Pe32
->FileHeader
.NumberOfSections
; Index
++) {
1142 Name
= Section
[Index
].Name
;
1145 " Section - '%c%c%c%c%c%c%c%c'\n",
1156 if ((Section
[Index
].Characteristics
& EFI_IMAGE_SCN_CNT_CODE
) != 0) {
1157 DEBUG ((EFI_D_VERBOSE
, " VirtualSize - 0x%08x\n", Section
[Index
].Misc
.VirtualSize
));
1158 DEBUG ((EFI_D_VERBOSE
, " VirtualAddress - 0x%08x\n", Section
[Index
].VirtualAddress
));
1159 DEBUG ((EFI_D_VERBOSE
, " SizeOfRawData - 0x%08x\n", Section
[Index
].SizeOfRawData
));
1160 DEBUG ((EFI_D_VERBOSE
, " PointerToRawData - 0x%08x\n", Section
[Index
].PointerToRawData
));
1161 DEBUG ((EFI_D_VERBOSE
, " PointerToRelocations - 0x%08x\n", Section
[Index
].PointerToRelocations
));
1162 DEBUG ((EFI_D_VERBOSE
, " PointerToLinenumbers - 0x%08x\n", Section
[Index
].PointerToLinenumbers
));
1163 DEBUG ((EFI_D_VERBOSE
, " NumberOfRelocations - 0x%08x\n", Section
[Index
].NumberOfRelocations
));
1164 DEBUG ((EFI_D_VERBOSE
, " NumberOfLinenumbers - 0x%08x\n", Section
[Index
].NumberOfLinenumbers
));
1165 DEBUG ((EFI_D_VERBOSE
, " Characteristics - 0x%08x\n", Section
[Index
].Characteristics
));
1168 // Step 2: record code section
1170 ImageRecordCodeSection
= AllocatePool (sizeof(*ImageRecordCodeSection
));
1171 if (ImageRecordCodeSection
== NULL
) {
1174 ImageRecordCodeSection
->Signature
= IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
;
1176 ImageRecordCodeSection
->CodeSegmentBase
= (UINTN
)ImageAddress
+ Section
[Index
].VirtualAddress
;
1177 ImageRecordCodeSection
->CodeSegmentSize
= Section
[Index
].SizeOfRawData
;
1179 DEBUG ((EFI_D_VERBOSE
, "ImageCode: 0x%016lx - 0x%016lx\n", ImageRecordCodeSection
->CodeSegmentBase
, ImageRecordCodeSection
->CodeSegmentSize
));
1181 InsertTailList (&ImageRecord
->CodeSegmentList
, &ImageRecordCodeSection
->Link
);
1182 ImageRecord
->CodeSegmentCount
++;
1186 if (ImageRecord
->CodeSegmentCount
== 0) {
1187 SetPropertiesTableSectionAlignment (1);
1188 DEBUG ((EFI_D_ERROR
, "!!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n"));
1189 PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageAddress
);
1190 if (PdbPointer
!= NULL
) {
1191 DEBUG ((EFI_D_ERROR
, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer
));
1199 SortImageRecordCodeSection (ImageRecord
);
1201 // Check overlap all section in ImageBase/Size
1203 if (!IsImageRecordCodeSectionValid (ImageRecord
)) {
1204 DEBUG ((EFI_D_ERROR
, "IsImageRecordCodeSectionValid - FAIL\n"));
1208 InsertTailList (&mImagePropertiesPrivateData
.ImageRecordList
, &ImageRecord
->Link
);
1209 mImagePropertiesPrivateData
.ImageRecordCount
++;
1213 if (mImagePropertiesPrivateData
.CodeSegmentCountMax
< ImageRecord
->CodeSegmentCount
) {
1214 mImagePropertiesPrivateData
.CodeSegmentCountMax
= ImageRecord
->CodeSegmentCount
;
1222 Find image record according to image base and size.
1224 @param ImageBase Base of PE image
1225 @param ImageSize Size of PE image
1227 @return image record
1230 IMAGE_PROPERTIES_RECORD
*
1232 IN EFI_PHYSICAL_ADDRESS ImageBase
,
1236 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
1237 LIST_ENTRY
*ImageRecordLink
;
1238 LIST_ENTRY
*ImageRecordList
;
1240 ImageRecordList
= &mImagePropertiesPrivateData
.ImageRecordList
;
1242 for (ImageRecordLink
= ImageRecordList
->ForwardLink
;
1243 ImageRecordLink
!= ImageRecordList
;
1244 ImageRecordLink
= ImageRecordLink
->ForwardLink
) {
1247 IMAGE_PROPERTIES_RECORD
,
1249 IMAGE_PROPERTIES_RECORD_SIGNATURE
1252 if ((ImageBase
== ImageRecord
->ImageBase
) &&
1253 (ImageSize
== ImageRecord
->ImageSize
)) {
1262 Remove Image record.
1264 @param RuntimeImage Runtime image information
1268 IN EFI_RUNTIME_IMAGE_ENTRY
*RuntimeImage
1271 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
1272 LIST_ENTRY
*CodeSegmentListHead
;
1273 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*ImageRecordCodeSection
;
1275 DEBUG ((EFI_D_VERBOSE
, "RemoveImageRecord - 0x%x\n", RuntimeImage
));
1276 DEBUG ((EFI_D_VERBOSE
, "RemoveImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS
)(UINTN
)RuntimeImage
->ImageBase
, RuntimeImage
->ImageSize
));
1278 ImageRecord
= FindImageRecord ((EFI_PHYSICAL_ADDRESS
)(UINTN
)RuntimeImage
->ImageBase
, RuntimeImage
->ImageSize
);
1279 if (ImageRecord
== NULL
) {
1280 DEBUG ((EFI_D_ERROR
, "!!!!!!!! ImageRecord not found !!!!!!!!\n"));
1284 CodeSegmentListHead
= &ImageRecord
->CodeSegmentList
;
1285 while (!IsListEmpty (CodeSegmentListHead
)) {
1286 ImageRecordCodeSection
= CR (
1287 CodeSegmentListHead
->ForwardLink
,
1288 IMAGE_PROPERTIES_RECORD_CODE_SECTION
,
1290 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
1292 RemoveEntryList (&ImageRecordCodeSection
->Link
);
1293 FreePool (ImageRecordCodeSection
);
1296 RemoveEntryList (&ImageRecord
->Link
);
1297 FreePool (ImageRecord
);
1298 mImagePropertiesPrivateData
.ImageRecordCount
--;
1303 Install PropertiesTable.
1305 @param[in] Event The Event this notify function registered to.
1306 @param[in] Context Pointer to the context data registered to the Event.
1310 InstallPropertiesTable (
1315 if (PcdGetBool (PcdPropertiesTableEnable
)) {
1318 Status
= gBS
->InstallConfigurationTable (&gEfiPropertiesTableGuid
, &mPropertiesTable
);
1319 ASSERT_EFI_ERROR (Status
);
1321 DEBUG ((EFI_D_INFO
, "MemoryProtectionAttribute - 0x%016lx\n", mPropertiesTable
.MemoryProtectionAttribute
));
1322 if ((mPropertiesTable
.MemoryProtectionAttribute
& EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA
) == 0) {
1323 DEBUG ((EFI_D_ERROR
, "MemoryProtectionAttribute NON_EXECUTABLE_PE_DATA is not set, "));
1324 DEBUG ((EFI_D_ERROR
, "because Runtime Driver Section Alignment is not %dK.\n", EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT
>> 10));
1328 gBS
->GetMemoryMap
= CoreGetMemoryMapPropertiesTable
;
1330 gBS
->CalculateCrc32 ((UINT8
*)gBS
, gBS
->Hdr
.HeaderSize
, &gBS
->Hdr
.CRC32
);
1332 DEBUG ((EFI_D_VERBOSE
, "Total Image Count - 0x%x\n", mImagePropertiesPrivateData
.ImageRecordCount
));
1333 DEBUG ((EFI_D_VERBOSE
, "Dump ImageRecord:\n"));
1339 Initialize PropertiesTable support.
1343 CoreInitializePropertiesTable (
1348 EFI_EVENT EndOfDxeEvent
;
1350 Status
= gBS
->CreateEventEx (
1353 InstallPropertiesTable
,
1355 &gEfiEndOfDxeEventGroupGuid
,
1358 ASSERT_EFI_ERROR (Status
);