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
102 return LShiftU64 (Pages
, EFI_PAGE_SHIFT
);
106 Converts a size, in bytes, to a number of EFI_PAGESs.
108 NOTE: Do not use EFI_SIZE_TO_PAGES because it handles UINTN only.
110 @param Size A size in bytes.
112 @return The number of EFI_PAGESs associated with the number of bytes specified
121 return RShiftU64 (Size
, EFI_PAGE_SHIFT
) + ((((UINTN
)Size
) & EFI_PAGE_MASK
) ? 1 : 0);
125 Acquire memory lock on mPropertiesTableLock.
128 CoreAcquirePropertiesTableLock (
132 CoreAcquireLock (&mPropertiesTableLock
);
136 Release memory lock on mPropertiesTableLock.
139 CoreReleasePropertiesTableLock (
143 CoreReleaseLock (&mPropertiesTableLock
);
147 Sort memory map entries based upon PhysicalStart, from low to high.
149 @param MemoryMap A pointer to the buffer in which firmware places
150 the current memory map.
151 @param MemoryMapSize Size, in bytes, of the MemoryMap buffer.
152 @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
156 IN OUT EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
157 IN UINTN MemoryMapSize
,
158 IN UINTN DescriptorSize
161 EFI_MEMORY_DESCRIPTOR
*MemoryMapEntry
;
162 EFI_MEMORY_DESCRIPTOR
*NextMemoryMapEntry
;
163 EFI_MEMORY_DESCRIPTOR
*MemoryMapEnd
;
164 EFI_MEMORY_DESCRIPTOR TempMemoryMap
;
166 MemoryMapEntry
= MemoryMap
;
167 NextMemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry
, DescriptorSize
);
168 MemoryMapEnd
= (EFI_MEMORY_DESCRIPTOR
*) ((UINT8
*) MemoryMap
+ MemoryMapSize
);
169 while (MemoryMapEntry
< MemoryMapEnd
) {
170 while (NextMemoryMapEntry
< MemoryMapEnd
) {
171 if (MemoryMapEntry
->PhysicalStart
> NextMemoryMapEntry
->PhysicalStart
) {
172 CopyMem (&TempMemoryMap
, MemoryMapEntry
, sizeof(EFI_MEMORY_DESCRIPTOR
));
173 CopyMem (MemoryMapEntry
, NextMemoryMapEntry
, sizeof(EFI_MEMORY_DESCRIPTOR
));
174 CopyMem (NextMemoryMapEntry
, &TempMemoryMap
, sizeof(EFI_MEMORY_DESCRIPTOR
));
177 NextMemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry
, DescriptorSize
);
180 MemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry
, DescriptorSize
);
181 NextMemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry
, DescriptorSize
);
188 Merge continous memory map entries whose have same attributes.
190 @param MemoryMap A pointer to the buffer in which firmware places
191 the current memory map.
192 @param MemoryMapSize A pointer to the size, in bytes, of the
193 MemoryMap buffer. On input, this is the size of
194 the current memory map. On output,
195 it is the size of new memory map after merge.
196 @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
200 IN OUT EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
201 IN OUT UINTN
*MemoryMapSize
,
202 IN UINTN DescriptorSize
205 EFI_MEMORY_DESCRIPTOR
*MemoryMapEntry
;
206 EFI_MEMORY_DESCRIPTOR
*MemoryMapEnd
;
207 UINT64 MemoryBlockLength
;
208 EFI_MEMORY_DESCRIPTOR
*NewMemoryMapEntry
;
209 EFI_MEMORY_DESCRIPTOR
*NextMemoryMapEntry
;
211 MemoryMapEntry
= MemoryMap
;
212 NewMemoryMapEntry
= MemoryMap
;
213 MemoryMapEnd
= (EFI_MEMORY_DESCRIPTOR
*) ((UINT8
*) MemoryMap
+ *MemoryMapSize
);
214 while ((UINTN
)MemoryMapEntry
< (UINTN
)MemoryMapEnd
) {
215 CopyMem (NewMemoryMapEntry
, MemoryMapEntry
, sizeof(EFI_MEMORY_DESCRIPTOR
));
216 NextMemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry
, DescriptorSize
);
218 MemoryBlockLength
= (UINT64
) (EfiPagesToSize (MemoryMapEntry
->NumberOfPages
));
219 if (((UINTN
)NextMemoryMapEntry
< (UINTN
)MemoryMapEnd
) &&
220 (MemoryMapEntry
->Type
== NextMemoryMapEntry
->Type
) &&
221 (MemoryMapEntry
->Attribute
== NextMemoryMapEntry
->Attribute
) &&
222 ((MemoryMapEntry
->PhysicalStart
+ MemoryBlockLength
) == NextMemoryMapEntry
->PhysicalStart
)) {
223 NewMemoryMapEntry
->NumberOfPages
+= NextMemoryMapEntry
->NumberOfPages
;
224 MemoryMapEntry
= NextMemoryMapEntry
;
227 MemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry
, DescriptorSize
);
228 NewMemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry
, DescriptorSize
);
231 *MemoryMapSize
= (UINTN
)NewMemoryMapEntry
- (UINTN
)MemoryMap
;
237 Enforce memory map attributes.
238 This function will set EfiRuntimeServicesData/EfiMemoryMappedIO/EfiMemoryMappedIOPortSpace to be EFI_MEMORY_XP.
240 @param MemoryMap A pointer to the buffer in which firmware places
241 the current memory map.
242 @param MemoryMapSize Size, in bytes, of the MemoryMap buffer.
243 @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
246 EnforceMemoryMapAttribute (
247 IN OUT EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
248 IN UINTN MemoryMapSize
,
249 IN UINTN DescriptorSize
252 EFI_MEMORY_DESCRIPTOR
*MemoryMapEntry
;
253 EFI_MEMORY_DESCRIPTOR
*MemoryMapEnd
;
255 MemoryMapEntry
= MemoryMap
;
256 MemoryMapEnd
= (EFI_MEMORY_DESCRIPTOR
*) ((UINT8
*) MemoryMap
+ MemoryMapSize
);
257 while ((UINTN
)MemoryMapEntry
< (UINTN
)MemoryMapEnd
) {
258 switch (MemoryMapEntry
->Type
) {
259 case EfiRuntimeServicesCode
:
262 case EfiRuntimeServicesData
:
263 case EfiMemoryMappedIO
:
264 case EfiMemoryMappedIOPortSpace
:
265 MemoryMapEntry
->Attribute
|= EFI_MEMORY_XP
;
267 case EfiReservedMemoryType
:
268 case EfiACPIMemoryNVS
:
272 MemoryMapEntry
= NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry
, DescriptorSize
);
279 Return the first image record, whose [ImageBase, ImageSize] covered by [Buffer, Length].
281 @param Buffer Start Address
282 @param Length Address length
284 @return first image record covered by [buffer, length]
286 IMAGE_PROPERTIES_RECORD
*
287 GetImageRecordByAddress (
288 IN EFI_PHYSICAL_ADDRESS Buffer
,
292 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
293 LIST_ENTRY
*ImageRecordLink
;
294 LIST_ENTRY
*ImageRecordList
;
296 ImageRecordList
= &mImagePropertiesPrivateData
.ImageRecordList
;
298 for (ImageRecordLink
= ImageRecordList
->ForwardLink
;
299 ImageRecordLink
!= ImageRecordList
;
300 ImageRecordLink
= ImageRecordLink
->ForwardLink
) {
303 IMAGE_PROPERTIES_RECORD
,
305 IMAGE_PROPERTIES_RECORD_SIGNATURE
308 if ((Buffer
<= ImageRecord
->ImageBase
) &&
309 (Buffer
+ Length
>= ImageRecord
->ImageBase
+ ImageRecord
->ImageSize
)) {
318 Set the memory map to new entries, according to one old entry,
319 based upon PE code section and data section in image record
321 @param ImageRecord An image record whose [ImageBase, ImageSize] covered
322 by old memory map entry.
323 @param NewRecord A pointer to several new memory map entries.
324 The caller gurantee the buffer size be 1 +
325 (SplitRecordCount * DescriptorSize) calculated
327 @param OldRecord A pointer to one old memory map entry.
328 @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
332 IN IMAGE_PROPERTIES_RECORD
*ImageRecord
,
333 IN OUT EFI_MEMORY_DESCRIPTOR
*NewRecord
,
334 IN EFI_MEMORY_DESCRIPTOR
*OldRecord
,
335 IN UINTN DescriptorSize
338 EFI_MEMORY_DESCRIPTOR TempRecord
;
339 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*ImageRecordCodeSection
;
340 LIST_ENTRY
*ImageRecordCodeSectionLink
;
341 LIST_ENTRY
*ImageRecordCodeSectionEndLink
;
342 LIST_ENTRY
*ImageRecordCodeSectionList
;
343 UINTN NewRecordCount
;
347 CopyMem (&TempRecord
, OldRecord
, sizeof(EFI_MEMORY_DESCRIPTOR
));
348 PhysicalEnd
= TempRecord
.PhysicalStart
+ EfiPagesToSize(TempRecord
.NumberOfPages
);
351 ImageRecordCodeSectionList
= &ImageRecord
->CodeSegmentList
;
353 ImageRecordCodeSectionLink
= ImageRecordCodeSectionList
->ForwardLink
;
354 ImageRecordCodeSectionEndLink
= ImageRecordCodeSectionList
;
355 while (ImageRecordCodeSectionLink
!= ImageRecordCodeSectionEndLink
) {
356 ImageRecordCodeSection
= CR (
357 ImageRecordCodeSectionLink
,
358 IMAGE_PROPERTIES_RECORD_CODE_SECTION
,
360 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
362 ImageRecordCodeSectionLink
= ImageRecordCodeSectionLink
->ForwardLink
;
364 if (TempRecord
.PhysicalStart
<= ImageRecordCodeSection
->CodeSegmentBase
) {
368 NewRecord
->Type
= EfiRuntimeServicesData
;
369 NewRecord
->PhysicalStart
= TempRecord
.PhysicalStart
;
370 NewRecord
->VirtualStart
= 0;
371 NewRecord
->NumberOfPages
= EfiSizeToPages(ImageRecordCodeSection
->CodeSegmentBase
- NewRecord
->PhysicalStart
);
372 NewRecord
->Attribute
= TempRecord
.Attribute
| EFI_MEMORY_XP
;
373 if (NewRecord
->NumberOfPages
!= 0) {
374 NewRecord
= NEXT_MEMORY_DESCRIPTOR (NewRecord
, DescriptorSize
);
381 NewRecord
->Type
= EfiRuntimeServicesCode
;
382 NewRecord
->PhysicalStart
= ImageRecordCodeSection
->CodeSegmentBase
;
383 NewRecord
->VirtualStart
= 0;
384 NewRecord
->NumberOfPages
= EfiSizeToPages(ImageRecordCodeSection
->CodeSegmentSize
);
385 NewRecord
->Attribute
= (TempRecord
.Attribute
& (~EFI_MEMORY_XP
)) | EFI_MEMORY_RO
;
386 if (NewRecord
->NumberOfPages
!= 0) {
387 NewRecord
= NEXT_MEMORY_DESCRIPTOR (NewRecord
, DescriptorSize
);
391 TempRecord
.PhysicalStart
= ImageRecordCodeSection
->CodeSegmentBase
+ EfiPagesToSize (EfiSizeToPages(ImageRecordCodeSection
->CodeSegmentSize
));
392 TempRecord
.NumberOfPages
= EfiSizeToPages(PhysicalEnd
- TempRecord
.PhysicalStart
);
393 if (TempRecord
.NumberOfPages
== 0) {
399 ImageEnd
= ImageRecord
->ImageBase
+ ImageRecord
->ImageSize
;
404 if (TempRecord
.PhysicalStart
< ImageEnd
) {
405 NewRecord
->Type
= EfiRuntimeServicesData
;
406 NewRecord
->PhysicalStart
= TempRecord
.PhysicalStart
;
407 NewRecord
->VirtualStart
= 0;
408 NewRecord
->NumberOfPages
= EfiSizeToPages (ImageEnd
- TempRecord
.PhysicalStart
);
409 NewRecord
->Attribute
= TempRecord
.Attribute
| EFI_MEMORY_XP
;
413 return NewRecordCount
;
417 Return the max number of new splitted entries, according to one old entry,
418 based upon PE code section and data section.
420 @param OldRecord A pointer to one old memory map entry.
422 @retval 0 no entry need to be splitted.
423 @return the max number of new splitted entries
426 GetMaxSplitRecordCount (
427 IN EFI_MEMORY_DESCRIPTOR
*OldRecord
430 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
431 UINTN SplitRecordCount
;
432 UINT64 PhysicalStart
;
435 SplitRecordCount
= 0;
436 PhysicalStart
= OldRecord
->PhysicalStart
;
437 PhysicalEnd
= OldRecord
->PhysicalStart
+ EfiPagesToSize(OldRecord
->NumberOfPages
);
440 ImageRecord
= GetImageRecordByAddress (PhysicalStart
, PhysicalEnd
- PhysicalStart
);
441 if (ImageRecord
== NULL
) {
444 SplitRecordCount
+= (2 * ImageRecord
->CodeSegmentCount
+ 1);
445 PhysicalStart
= ImageRecord
->ImageBase
+ ImageRecord
->ImageSize
;
446 } while ((ImageRecord
!= NULL
) && (PhysicalStart
< PhysicalEnd
));
448 if (SplitRecordCount
!= 0) {
452 return SplitRecordCount
;
456 Split the memory map to new entries, according to one old entry,
457 based upon PE code section and data section.
459 @param OldRecord A pointer to one old memory map entry.
460 @param NewRecord A pointer to several new memory map entries.
461 The caller gurantee the buffer size be 1 +
462 (SplitRecordCount * DescriptorSize) calculated
464 @param MaxSplitRecordCount The max number of splitted entries
465 @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
467 @retval 0 no entry is splitted.
468 @return the real number of splitted record.
472 IN EFI_MEMORY_DESCRIPTOR
*OldRecord
,
473 IN OUT EFI_MEMORY_DESCRIPTOR
*NewRecord
,
474 IN UINTN MaxSplitRecordCount
,
475 IN UINTN DescriptorSize
478 EFI_MEMORY_DESCRIPTOR TempRecord
;
479 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
480 IMAGE_PROPERTIES_RECORD
*NewImageRecord
;
481 UINT64 PhysicalStart
;
483 UINTN NewRecordCount
;
484 UINTN TotalNewRecordCount
;
486 if (MaxSplitRecordCount
== 0) {
487 CopyMem (NewRecord
, OldRecord
, DescriptorSize
);
491 TotalNewRecordCount
= 0;
494 // Override previous record
496 CopyMem (&TempRecord
, OldRecord
, sizeof(EFI_MEMORY_DESCRIPTOR
));
497 PhysicalStart
= TempRecord
.PhysicalStart
;
498 PhysicalEnd
= TempRecord
.PhysicalStart
+ EfiPagesToSize(TempRecord
.NumberOfPages
);
502 NewImageRecord
= GetImageRecordByAddress (PhysicalStart
, PhysicalEnd
- PhysicalStart
);
503 if (NewImageRecord
== NULL
) {
505 // No more image covered by this range, stop
507 if ((PhysicalEnd
> PhysicalStart
) && (ImageRecord
!= NULL
)) {
509 // If this is still address in this record, need record.
511 NewRecord
= PREVIOUS_MEMORY_DESCRIPTOR (NewRecord
, DescriptorSize
);
512 if (NewRecord
->Type
== EfiRuntimeServicesData
) {
514 // Last record is DATA, just merge it.
516 NewRecord
->NumberOfPages
= EfiSizeToPages(PhysicalEnd
- NewRecord
->PhysicalStart
);
519 // Last record is CODE, create a new DATA entry.
521 NewRecord
= NEXT_MEMORY_DESCRIPTOR (NewRecord
, DescriptorSize
);
522 NewRecord
->Type
= EfiRuntimeServicesData
;
523 NewRecord
->PhysicalStart
= TempRecord
.PhysicalStart
;
524 NewRecord
->VirtualStart
= 0;
525 NewRecord
->NumberOfPages
= TempRecord
.NumberOfPages
;
526 NewRecord
->Attribute
= TempRecord
.Attribute
| EFI_MEMORY_XP
;
527 TotalNewRecordCount
++;
532 ImageRecord
= NewImageRecord
;
537 NewRecordCount
= SetNewRecord (ImageRecord
, NewRecord
, &TempRecord
, DescriptorSize
);
538 TotalNewRecordCount
+= NewRecordCount
;
539 NewRecord
= (EFI_MEMORY_DESCRIPTOR
*)((UINT8
*)NewRecord
+ NewRecordCount
* DescriptorSize
);
542 // Update PhysicalStart, in order to exclude the image buffer already splitted.
544 PhysicalStart
= ImageRecord
->ImageBase
+ ImageRecord
->ImageSize
;
545 TempRecord
.PhysicalStart
= PhysicalStart
;
546 TempRecord
.NumberOfPages
= EfiSizeToPages (PhysicalEnd
- PhysicalStart
);
547 } while ((ImageRecord
!= NULL
) && (PhysicalStart
< PhysicalEnd
));
549 return TotalNewRecordCount
- 1;
553 Split the original memory map, and add more entries to describe PE code section and data section.
554 This function will set EfiRuntimeServicesData to be EFI_MEMORY_XP.
555 This function will merge entries with same attributes finally.
557 NOTE: It assumes PE code/data section are page aligned.
558 NOTE: It assumes enough entry is prepared for new memory map.
571 +---------------+ ----
574 | Record RtCode | |-> PE/COFF1
577 +---------------+ ----
580 | Record RtCode | |-> PE/COFF2
583 +---------------+ ----
587 @param MemoryMapSize A pointer to the size, in bytes, of the
588 MemoryMap buffer. On input, this is the size of
589 old MemoryMap before split. The actual buffer
590 size of MemoryMap is MemoryMapSize +
591 (AdditionalRecordCount * DescriptorSize) calculated
592 below. On output, it is the size of new MemoryMap
594 @param MemoryMap A pointer to the buffer in which firmware places
595 the current memory map.
596 @param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
600 IN OUT UINTN
*MemoryMapSize
,
601 IN OUT EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
602 IN UINTN DescriptorSize
607 UINTN MaxSplitRecordCount
;
608 UINTN RealSplitRecordCount
;
609 UINTN TotalSplitRecordCount
;
610 UINTN AdditionalRecordCount
;
612 AdditionalRecordCount
= (2 * mImagePropertiesPrivateData
.CodeSegmentCountMax
+ 1) * mImagePropertiesPrivateData
.ImageRecordCount
;
614 TotalSplitRecordCount
= 0;
616 // Let old record point to end of valid MemoryMap buffer.
618 IndexOld
= ((*MemoryMapSize
) / DescriptorSize
) - 1;
620 // Let new record point to end of full MemoryMap buffer.
622 IndexNew
= ((*MemoryMapSize
) / DescriptorSize
) - 1 + AdditionalRecordCount
;
623 for (; IndexOld
>= 0; IndexOld
--) {
624 MaxSplitRecordCount
= GetMaxSplitRecordCount ((EFI_MEMORY_DESCRIPTOR
*)((UINT8
*)MemoryMap
+ IndexOld
* DescriptorSize
));
626 // Split this MemoryMap record
628 IndexNew
-= MaxSplitRecordCount
;
629 RealSplitRecordCount
= SplitRecord (
630 (EFI_MEMORY_DESCRIPTOR
*)((UINT8
*)MemoryMap
+ IndexOld
* DescriptorSize
),
631 (EFI_MEMORY_DESCRIPTOR
*)((UINT8
*)MemoryMap
+ IndexNew
* DescriptorSize
),
636 // Adjust IndexNew according to real split.
639 ((UINT8
*)MemoryMap
+ (IndexNew
+ MaxSplitRecordCount
- RealSplitRecordCount
) * DescriptorSize
),
640 ((UINT8
*)MemoryMap
+ IndexNew
* DescriptorSize
),
641 RealSplitRecordCount
* DescriptorSize
643 IndexNew
= IndexNew
+ MaxSplitRecordCount
- RealSplitRecordCount
;
644 TotalSplitRecordCount
+= RealSplitRecordCount
;
648 // Move all records to the beginning.
652 (UINT8
*)MemoryMap
+ (AdditionalRecordCount
- TotalSplitRecordCount
) * DescriptorSize
,
653 (*MemoryMapSize
) + TotalSplitRecordCount
* DescriptorSize
656 *MemoryMapSize
= (*MemoryMapSize
) + DescriptorSize
* TotalSplitRecordCount
;
659 // Sort from low to high (Just in case)
661 SortMemoryMap (MemoryMap
, *MemoryMapSize
, DescriptorSize
);
664 // Set RuntimeData to XP
666 EnforceMemoryMapAttribute (MemoryMap
, *MemoryMapSize
, DescriptorSize
);
669 // Merge same type to save entry size
671 MergeMemoryMap (MemoryMap
, MemoryMapSize
, DescriptorSize
);
677 This function for GetMemoryMap() with properties table.
679 It calls original GetMemoryMap() to get the original memory map information. Then
680 plus the additional memory map entries for PE Code/Data seperation.
682 @param MemoryMapSize A pointer to the size, in bytes, of the
683 MemoryMap buffer. On input, this is the size of
684 the buffer allocated by the caller. On output,
685 it is the size of the buffer returned by the
686 firmware if the buffer was large enough, or the
687 size of the buffer needed to contain the map if
688 the buffer was too small.
689 @param MemoryMap A pointer to the buffer in which firmware places
690 the current memory map.
691 @param MapKey A pointer to the location in which firmware
692 returns the key for the current memory map.
693 @param DescriptorSize A pointer to the location in which firmware
694 returns the size, in bytes, of an individual
695 EFI_MEMORY_DESCRIPTOR.
696 @param DescriptorVersion A pointer to the location in which firmware
697 returns the version number associated with the
698 EFI_MEMORY_DESCRIPTOR.
700 @retval EFI_SUCCESS The memory map was returned in the MemoryMap
702 @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current
703 buffer size needed to hold the memory map is
704 returned in MemoryMapSize.
705 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
710 CoreGetMemoryMapPropertiesTable (
711 IN OUT UINTN
*MemoryMapSize
,
712 IN OUT EFI_MEMORY_DESCRIPTOR
*MemoryMap
,
714 OUT UINTN
*DescriptorSize
,
715 OUT UINT32
*DescriptorVersion
719 UINTN OldMemoryMapSize
;
720 UINTN AdditionalRecordCount
;
723 // If PE code/data is not aligned, just return.
725 if ((mPropertiesTable
.MemoryProtectionAttribute
& EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA
) == 0) {
726 return CoreGetMemoryMap (MemoryMapSize
, MemoryMap
, MapKey
, DescriptorSize
, DescriptorVersion
);
729 if (MemoryMapSize
== NULL
) {
730 return EFI_INVALID_PARAMETER
;
733 CoreAcquirePropertiesTableLock ();
735 AdditionalRecordCount
= (2 * mImagePropertiesPrivateData
.CodeSegmentCountMax
+ 1) * mImagePropertiesPrivateData
.ImageRecordCount
;
737 OldMemoryMapSize
= *MemoryMapSize
;
738 Status
= CoreGetMemoryMap (MemoryMapSize
, MemoryMap
, MapKey
, DescriptorSize
, DescriptorVersion
);
739 if (Status
== EFI_BUFFER_TOO_SMALL
) {
740 *MemoryMapSize
= *MemoryMapSize
+ (*DescriptorSize
) * AdditionalRecordCount
;
741 } else if (Status
== EFI_SUCCESS
) {
742 if (OldMemoryMapSize
- *MemoryMapSize
< (*DescriptorSize
) * AdditionalRecordCount
) {
743 *MemoryMapSize
= *MemoryMapSize
+ (*DescriptorSize
) * AdditionalRecordCount
;
745 // Need update status to buffer too small
747 Status
= EFI_BUFFER_TOO_SMALL
;
750 // Split PE code/data
752 SplitTable (MemoryMapSize
, MemoryMap
, *DescriptorSize
);
756 CoreReleasePropertiesTableLock ();
761 // Below functions are for ImageRecord
765 Set PropertiesTable accroding to PE/COFF image section alignment.
767 @param SectionAlignment PE/COFF section alignment
770 SetPropertiesTableSectionAlignment (
771 IN UINT32 SectionAlignment
774 if (((SectionAlignment
& (SIZE_4KB
- 1)) != 0) &&
775 ((mPropertiesTable
.MemoryProtectionAttribute
& EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA
) != 0)) {
776 DEBUG ((EFI_D_VERBOSE
, "SetPropertiesTableSectionAlignment - Clear\n"));
777 mPropertiesTable
.MemoryProtectionAttribute
&= ~EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA
;
778 gBS
->GetMemoryMap
= CoreGetMemoryMap
;
780 gBS
->CalculateCrc32 ((UINT8
*)gBS
, gBS
->Hdr
.HeaderSize
, &gBS
->Hdr
.CRC32
);
785 Swap two code sections in image record.
787 @param FirstImageRecordCodeSection first code section in image record
788 @param SecondImageRecordCodeSection second code section in image record
791 SwapImageRecordCodeSection (
792 IN IMAGE_PROPERTIES_RECORD_CODE_SECTION
*FirstImageRecordCodeSection
,
793 IN IMAGE_PROPERTIES_RECORD_CODE_SECTION
*SecondImageRecordCodeSection
796 IMAGE_PROPERTIES_RECORD_CODE_SECTION TempImageRecordCodeSection
;
798 TempImageRecordCodeSection
.CodeSegmentBase
= FirstImageRecordCodeSection
->CodeSegmentBase
;
799 TempImageRecordCodeSection
.CodeSegmentSize
= FirstImageRecordCodeSection
->CodeSegmentSize
;
801 FirstImageRecordCodeSection
->CodeSegmentBase
= SecondImageRecordCodeSection
->CodeSegmentBase
;
802 FirstImageRecordCodeSection
->CodeSegmentSize
= SecondImageRecordCodeSection
->CodeSegmentSize
;
804 SecondImageRecordCodeSection
->CodeSegmentBase
= TempImageRecordCodeSection
.CodeSegmentBase
;
805 SecondImageRecordCodeSection
->CodeSegmentSize
= TempImageRecordCodeSection
.CodeSegmentSize
;
809 Sort code section in image record, based upon CodeSegmentBase from low to high.
811 @param ImageRecord image record to be sorted
814 SortImageRecordCodeSection (
815 IN IMAGE_PROPERTIES_RECORD
*ImageRecord
818 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*ImageRecordCodeSection
;
819 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*NextImageRecordCodeSection
;
820 LIST_ENTRY
*ImageRecordCodeSectionLink
;
821 LIST_ENTRY
*NextImageRecordCodeSectionLink
;
822 LIST_ENTRY
*ImageRecordCodeSectionEndLink
;
823 LIST_ENTRY
*ImageRecordCodeSectionList
;
825 ImageRecordCodeSectionList
= &ImageRecord
->CodeSegmentList
;
827 ImageRecordCodeSectionLink
= ImageRecordCodeSectionList
->ForwardLink
;
828 NextImageRecordCodeSectionLink
= ImageRecordCodeSectionLink
->ForwardLink
;
829 ImageRecordCodeSectionEndLink
= ImageRecordCodeSectionList
;
830 while (ImageRecordCodeSectionLink
!= ImageRecordCodeSectionEndLink
) {
831 ImageRecordCodeSection
= CR (
832 ImageRecordCodeSectionLink
,
833 IMAGE_PROPERTIES_RECORD_CODE_SECTION
,
835 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
837 while (NextImageRecordCodeSectionLink
!= ImageRecordCodeSectionEndLink
) {
838 NextImageRecordCodeSection
= CR (
839 NextImageRecordCodeSectionLink
,
840 IMAGE_PROPERTIES_RECORD_CODE_SECTION
,
842 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
844 if (ImageRecordCodeSection
->CodeSegmentBase
> NextImageRecordCodeSection
->CodeSegmentBase
) {
845 SwapImageRecordCodeSection (ImageRecordCodeSection
, NextImageRecordCodeSection
);
847 NextImageRecordCodeSectionLink
= NextImageRecordCodeSectionLink
->ForwardLink
;
850 ImageRecordCodeSectionLink
= ImageRecordCodeSectionLink
->ForwardLink
;
851 NextImageRecordCodeSectionLink
= ImageRecordCodeSectionLink
->ForwardLink
;
856 Check if code section in image record is valid.
858 @param ImageRecord image record to be checked
860 @retval TRUE image record is valid
861 @retval FALSE image record is invalid
864 IsImageRecordCodeSectionValid (
865 IN IMAGE_PROPERTIES_RECORD
*ImageRecord
868 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*ImageRecordCodeSection
;
869 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*LastImageRecordCodeSection
;
870 LIST_ENTRY
*ImageRecordCodeSectionLink
;
871 LIST_ENTRY
*ImageRecordCodeSectionEndLink
;
872 LIST_ENTRY
*ImageRecordCodeSectionList
;
874 DEBUG ((EFI_D_VERBOSE
, "ImageCode SegmentCount - 0x%x\n", ImageRecord
->CodeSegmentCount
));
876 ImageRecordCodeSectionList
= &ImageRecord
->CodeSegmentList
;
878 ImageRecordCodeSectionLink
= ImageRecordCodeSectionList
->ForwardLink
;
879 ImageRecordCodeSectionEndLink
= ImageRecordCodeSectionList
;
880 LastImageRecordCodeSection
= NULL
;
881 while (ImageRecordCodeSectionLink
!= ImageRecordCodeSectionEndLink
) {
882 ImageRecordCodeSection
= CR (
883 ImageRecordCodeSectionLink
,
884 IMAGE_PROPERTIES_RECORD_CODE_SECTION
,
886 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
888 if (ImageRecordCodeSection
->CodeSegmentSize
== 0) {
891 if (ImageRecordCodeSection
->CodeSegmentBase
< ImageRecord
->ImageBase
) {
894 if (ImageRecordCodeSection
->CodeSegmentBase
>= MAX_ADDRESS
- ImageRecordCodeSection
->CodeSegmentSize
) {
897 if ((ImageRecordCodeSection
->CodeSegmentBase
+ ImageRecordCodeSection
->CodeSegmentSize
) > (ImageRecord
->ImageBase
+ ImageRecord
->ImageSize
)) {
900 if (LastImageRecordCodeSection
!= NULL
) {
901 if ((LastImageRecordCodeSection
->CodeSegmentBase
+ LastImageRecordCodeSection
->CodeSegmentSize
) > ImageRecordCodeSection
->CodeSegmentBase
) {
906 LastImageRecordCodeSection
= ImageRecordCodeSection
;
907 ImageRecordCodeSectionLink
= ImageRecordCodeSectionLink
->ForwardLink
;
914 Swap two image records.
916 @param FirstImageRecord first image record.
917 @param SecondImageRecord second image record.
921 IN IMAGE_PROPERTIES_RECORD
*FirstImageRecord
,
922 IN IMAGE_PROPERTIES_RECORD
*SecondImageRecord
925 IMAGE_PROPERTIES_RECORD TempImageRecord
;
927 TempImageRecord
.ImageBase
= FirstImageRecord
->ImageBase
;
928 TempImageRecord
.ImageSize
= FirstImageRecord
->ImageSize
;
929 TempImageRecord
.CodeSegmentCount
= FirstImageRecord
->CodeSegmentCount
;
931 FirstImageRecord
->ImageBase
= SecondImageRecord
->ImageBase
;
932 FirstImageRecord
->ImageSize
= SecondImageRecord
->ImageSize
;
933 FirstImageRecord
->CodeSegmentCount
= SecondImageRecord
->CodeSegmentCount
;
935 SecondImageRecord
->ImageBase
= TempImageRecord
.ImageBase
;
936 SecondImageRecord
->ImageSize
= TempImageRecord
.ImageSize
;
937 SecondImageRecord
->CodeSegmentCount
= TempImageRecord
.CodeSegmentCount
;
939 SwapListEntries (&FirstImageRecord
->CodeSegmentList
, &SecondImageRecord
->CodeSegmentList
);
943 Sort image record based upon the ImageBase from low to high.
950 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
951 IMAGE_PROPERTIES_RECORD
*NextImageRecord
;
952 LIST_ENTRY
*ImageRecordLink
;
953 LIST_ENTRY
*NextImageRecordLink
;
954 LIST_ENTRY
*ImageRecordEndLink
;
955 LIST_ENTRY
*ImageRecordList
;
957 ImageRecordList
= &mImagePropertiesPrivateData
.ImageRecordList
;
959 ImageRecordLink
= ImageRecordList
->ForwardLink
;
960 NextImageRecordLink
= ImageRecordLink
->ForwardLink
;
961 ImageRecordEndLink
= ImageRecordList
;
962 while (ImageRecordLink
!= ImageRecordEndLink
) {
965 IMAGE_PROPERTIES_RECORD
,
967 IMAGE_PROPERTIES_RECORD_SIGNATURE
969 while (NextImageRecordLink
!= ImageRecordEndLink
) {
970 NextImageRecord
= CR (
972 IMAGE_PROPERTIES_RECORD
,
974 IMAGE_PROPERTIES_RECORD_SIGNATURE
976 if (ImageRecord
->ImageBase
> NextImageRecord
->ImageBase
) {
977 SwapImageRecord (ImageRecord
, NextImageRecord
);
979 NextImageRecordLink
= NextImageRecordLink
->ForwardLink
;
982 ImageRecordLink
= ImageRecordLink
->ForwardLink
;
983 NextImageRecordLink
= ImageRecordLink
->ForwardLink
;
995 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
996 LIST_ENTRY
*ImageRecordLink
;
997 LIST_ENTRY
*ImageRecordList
;
1000 ImageRecordList
= &mImagePropertiesPrivateData
.ImageRecordList
;
1002 for (ImageRecordLink
= ImageRecordList
->ForwardLink
, Index
= 0;
1003 ImageRecordLink
!= ImageRecordList
;
1004 ImageRecordLink
= ImageRecordLink
->ForwardLink
, Index
++) {
1007 IMAGE_PROPERTIES_RECORD
,
1009 IMAGE_PROPERTIES_RECORD_SIGNATURE
1011 DEBUG ((EFI_D_VERBOSE
, " Image[%d]: 0x%016lx - 0x%016lx\n", Index
, ImageRecord
->ImageBase
, ImageRecord
->ImageSize
));
1016 Insert image record.
1018 @param RuntimeImage Runtime image information
1022 IN EFI_RUNTIME_IMAGE_ENTRY
*RuntimeImage
1026 EFI_IMAGE_DOS_HEADER
*DosHdr
;
1027 UINT32 PeCoffHeaderOffset
;
1028 UINT32 SectionAlignment
;
1029 EFI_IMAGE_SECTION_HEADER
*Section
;
1030 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
;
1033 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
1035 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*ImageRecordCodeSection
;
1038 DEBUG ((EFI_D_VERBOSE
, "InsertImageRecord - 0x%x\n", RuntimeImage
));
1039 DEBUG ((EFI_D_VERBOSE
, "InsertImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS
)(UINTN
)RuntimeImage
->ImageBase
, RuntimeImage
->ImageSize
));
1041 ImageRecord
= AllocatePool (sizeof(*ImageRecord
));
1042 if (ImageRecord
== NULL
) {
1045 ImageRecord
->Signature
= IMAGE_PROPERTIES_RECORD_SIGNATURE
;
1047 DEBUG ((EFI_D_VERBOSE
, "ImageRecordCount - 0x%x\n", mImagePropertiesPrivateData
.ImageRecordCount
));
1050 // Step 1: record whole region
1052 ImageRecord
->ImageBase
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)RuntimeImage
->ImageBase
;
1053 ImageRecord
->ImageSize
= RuntimeImage
->ImageSize
;
1055 ImageAddress
= RuntimeImage
->ImageBase
;
1057 PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageAddress
);
1058 if (PdbPointer
!= NULL
) {
1059 DEBUG ((EFI_D_VERBOSE
, " Image - %a\n", PdbPointer
));
1063 // Check PE/COFF image
1065 DosHdr
= (EFI_IMAGE_DOS_HEADER
*) (UINTN
) ImageAddress
;
1066 PeCoffHeaderOffset
= 0;
1067 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
1068 PeCoffHeaderOffset
= DosHdr
->e_lfanew
;
1071 Hdr
.Pe32
= (EFI_IMAGE_NT_HEADERS32
*)((UINT8
*) (UINTN
) ImageAddress
+ PeCoffHeaderOffset
);
1072 if (Hdr
.Pe32
->Signature
!= EFI_IMAGE_NT_SIGNATURE
) {
1073 DEBUG ((EFI_D_VERBOSE
, "Hdr.Pe32->Signature invalid - 0x%x\n", Hdr
.Pe32
->Signature
));
1074 // It might be image in SMM.
1079 // Get SectionAlignment
1081 if (Hdr
.Pe32
->FileHeader
.Machine
== IMAGE_FILE_MACHINE_IA64
&& Hdr
.Pe32
->OptionalHeader
.Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1083 // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value
1084 // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the
1085 // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
1086 // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
1088 Magic
= EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
;
1091 // Get the magic value from the PE/COFF Optional Header
1093 Magic
= Hdr
.Pe32
->OptionalHeader
.Magic
;
1095 if (Magic
== EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
) {
1096 SectionAlignment
= Hdr
.Pe32
->OptionalHeader
.SectionAlignment
;
1098 SectionAlignment
= Hdr
.Pe32Plus
->OptionalHeader
.SectionAlignment
;
1101 SetPropertiesTableSectionAlignment (SectionAlignment
);
1102 if ((SectionAlignment
& (SIZE_4KB
- 1)) != 0) {
1103 DEBUG ((EFI_D_ERROR
, "!!!!!!!! InsertImageRecord - Section Alignment(0x%x) is not 4K !!!!!!!!\n", SectionAlignment
));
1104 PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageAddress
);
1105 if (PdbPointer
!= NULL
) {
1106 DEBUG ((EFI_D_ERROR
, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer
));
1111 Section
= (EFI_IMAGE_SECTION_HEADER
*) (
1112 (UINT8
*) (UINTN
) ImageAddress
+
1113 PeCoffHeaderOffset
+
1115 sizeof(EFI_IMAGE_FILE_HEADER
) +
1116 Hdr
.Pe32
->FileHeader
.SizeOfOptionalHeader
1118 ImageRecord
->CodeSegmentCount
= 0;
1119 InitializeListHead (&ImageRecord
->CodeSegmentList
);
1120 for (Index
= 0; Index
< Hdr
.Pe32
->FileHeader
.NumberOfSections
; Index
++) {
1121 Name
= Section
[Index
].Name
;
1124 " Section - '%c%c%c%c%c%c%c%c'\n",
1135 if ((Section
[Index
].Characteristics
& EFI_IMAGE_SCN_CNT_CODE
) != 0) {
1136 DEBUG ((EFI_D_VERBOSE
, " VirtualSize - 0x%08x\n", Section
[Index
].Misc
.VirtualSize
));
1137 DEBUG ((EFI_D_VERBOSE
, " VirtualAddress - 0x%08x\n", Section
[Index
].VirtualAddress
));
1138 DEBUG ((EFI_D_VERBOSE
, " SizeOfRawData - 0x%08x\n", Section
[Index
].SizeOfRawData
));
1139 DEBUG ((EFI_D_VERBOSE
, " PointerToRawData - 0x%08x\n", Section
[Index
].PointerToRawData
));
1140 DEBUG ((EFI_D_VERBOSE
, " PointerToRelocations - 0x%08x\n", Section
[Index
].PointerToRelocations
));
1141 DEBUG ((EFI_D_VERBOSE
, " PointerToLinenumbers - 0x%08x\n", Section
[Index
].PointerToLinenumbers
));
1142 DEBUG ((EFI_D_VERBOSE
, " NumberOfRelocations - 0x%08x\n", Section
[Index
].NumberOfRelocations
));
1143 DEBUG ((EFI_D_VERBOSE
, " NumberOfLinenumbers - 0x%08x\n", Section
[Index
].NumberOfLinenumbers
));
1144 DEBUG ((EFI_D_VERBOSE
, " Characteristics - 0x%08x\n", Section
[Index
].Characteristics
));
1147 // Step 2: record code section
1149 ImageRecordCodeSection
= AllocatePool (sizeof(*ImageRecordCodeSection
));
1150 if (ImageRecordCodeSection
== NULL
) {
1153 ImageRecordCodeSection
->Signature
= IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
;
1155 ImageRecordCodeSection
->CodeSegmentBase
= (UINTN
)ImageAddress
+ Section
[Index
].VirtualAddress
;
1156 ImageRecordCodeSection
->CodeSegmentSize
= Section
[Index
].SizeOfRawData
;
1158 DEBUG ((EFI_D_VERBOSE
, "ImageCode: 0x%016lx - 0x%016lx\n", ImageRecordCodeSection
->CodeSegmentBase
, ImageRecordCodeSection
->CodeSegmentSize
));
1160 InsertTailList (&ImageRecord
->CodeSegmentList
, &ImageRecordCodeSection
->Link
);
1161 ImageRecord
->CodeSegmentCount
++;
1165 if (ImageRecord
->CodeSegmentCount
== 0) {
1166 SetPropertiesTableSectionAlignment (1);
1167 DEBUG ((EFI_D_ERROR
, "!!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n"));
1168 PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageAddress
);
1169 if (PdbPointer
!= NULL
) {
1170 DEBUG ((EFI_D_ERROR
, "!!!!!!!! Image - %a !!!!!!!!\n", PdbPointer
));
1178 SortImageRecordCodeSection (ImageRecord
);
1180 // Check overlap all section in ImageBase/Size
1182 if (!IsImageRecordCodeSectionValid (ImageRecord
)) {
1183 DEBUG ((EFI_D_ERROR
, "IsImageRecordCodeSectionValid - FAIL\n"));
1187 InsertTailList (&mImagePropertiesPrivateData
.ImageRecordList
, &ImageRecord
->Link
);
1188 mImagePropertiesPrivateData
.ImageRecordCount
++;
1192 if (mImagePropertiesPrivateData
.CodeSegmentCountMax
< ImageRecord
->CodeSegmentCount
) {
1193 mImagePropertiesPrivateData
.CodeSegmentCountMax
= ImageRecord
->CodeSegmentCount
;
1201 Find image record accroding to image base and size.
1203 @param ImageBase Base of PE image
1204 @param ImageSize Size of PE image
1206 @return image record
1208 IMAGE_PROPERTIES_RECORD
*
1210 IN EFI_PHYSICAL_ADDRESS ImageBase
,
1214 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
1215 LIST_ENTRY
*ImageRecordLink
;
1216 LIST_ENTRY
*ImageRecordList
;
1218 ImageRecordList
= &mImagePropertiesPrivateData
.ImageRecordList
;
1220 for (ImageRecordLink
= ImageRecordList
->ForwardLink
;
1221 ImageRecordLink
!= ImageRecordList
;
1222 ImageRecordLink
= ImageRecordLink
->ForwardLink
) {
1225 IMAGE_PROPERTIES_RECORD
,
1227 IMAGE_PROPERTIES_RECORD_SIGNATURE
1230 if ((ImageBase
== ImageRecord
->ImageBase
) &&
1231 (ImageSize
== ImageRecord
->ImageSize
)) {
1240 Remove Image record.
1242 @param RuntimeImage Runtime image information
1246 IN EFI_RUNTIME_IMAGE_ENTRY
*RuntimeImage
1249 IMAGE_PROPERTIES_RECORD
*ImageRecord
;
1250 LIST_ENTRY
*CodeSegmentListHead
;
1251 IMAGE_PROPERTIES_RECORD_CODE_SECTION
*ImageRecordCodeSection
;
1253 DEBUG ((EFI_D_VERBOSE
, "RemoveImageRecord - 0x%x\n", RuntimeImage
));
1254 DEBUG ((EFI_D_VERBOSE
, "RemoveImageRecord - 0x%016lx - 0x%016lx\n", (EFI_PHYSICAL_ADDRESS
)(UINTN
)RuntimeImage
->ImageBase
, RuntimeImage
->ImageSize
));
1256 ImageRecord
= FindImageRecord ((EFI_PHYSICAL_ADDRESS
)(UINTN
)RuntimeImage
->ImageBase
, RuntimeImage
->ImageSize
);
1257 if (ImageRecord
== NULL
) {
1258 DEBUG ((EFI_D_ERROR
, "!!!!!!!! ImageRecord not found !!!!!!!!\n"));
1262 CodeSegmentListHead
= &ImageRecord
->CodeSegmentList
;
1263 while (!IsListEmpty (CodeSegmentListHead
)) {
1264 ImageRecordCodeSection
= CR (
1265 CodeSegmentListHead
->ForwardLink
,
1266 IMAGE_PROPERTIES_RECORD_CODE_SECTION
,
1268 IMAGE_PROPERTIES_RECORD_CODE_SECTION_SIGNATURE
1270 RemoveEntryList (&ImageRecordCodeSection
->Link
);
1271 FreePool (ImageRecordCodeSection
);
1274 RemoveEntryList (&ImageRecord
->Link
);
1275 FreePool (ImageRecord
);
1276 mImagePropertiesPrivateData
.ImageRecordCount
--;
1281 Install PropertiesTable.
1283 @param[in] Event The Event this notify function registered to.
1284 @param[in] Context Pointer to the context data registered to the Event.
1288 InstallPropertiesTable (
1293 if (PcdGetBool (PropertiesTableEnable
)) {
1296 Status
= gBS
->InstallConfigurationTable (&gEfiPropertiesTableGuid
, &mPropertiesTable
);
1297 ASSERT_EFI_ERROR (Status
);
1299 DEBUG ((EFI_D_INFO
, "MemoryProtectionAttribute - 0x%016lx\n", mPropertiesTable
.MemoryProtectionAttribute
));
1300 if ((mPropertiesTable
.MemoryProtectionAttribute
& EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA
) == 0) {
1304 gBS
->GetMemoryMap
= CoreGetMemoryMapPropertiesTable
;
1306 gBS
->CalculateCrc32 ((UINT8
*)gBS
, gBS
->Hdr
.HeaderSize
, &gBS
->Hdr
.CRC32
);
1308 DEBUG ((EFI_D_VERBOSE
, "Total Image Count - 0x%x\n", mImagePropertiesPrivateData
.ImageRecordCount
));
1309 DEBUG ((EFI_D_VERBOSE
, "Dump ImageRecord:\n"));
1315 Initialize PropertiesTable support.
1319 CoreInitializePropertiesTable (
1324 EFI_EVENT EndOfDxeEvent
;
1326 Status
= gBS
->CreateEventEx (
1329 InstallPropertiesTable
,
1331 &gEfiEndOfDxeEventGroupGuid
,
1334 ASSERT_EFI_ERROR (Status
);