diff options
Diffstat (limited to 'BaseTools/Source/C/Common/FvLib.c')
-rw-r--r-- | BaseTools/Source/C/Common/FvLib.c | 131 |
1 files changed, 110 insertions, 21 deletions
diff --git a/BaseTools/Source/C/Common/FvLib.c b/BaseTools/Source/C/Common/FvLib.c index 1b289d83cd..4758749dc3 100644 --- a/BaseTools/Source/C/Common/FvLib.c +++ b/BaseTools/Source/C/Common/FvLib.c @@ -1,6 +1,6 @@ /** @file
-Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -181,7 +181,7 @@ Returns: //
// Verify file is in this FV.
//
- if ((UINTN) CurrentFile + GetLength (CurrentFile->Size) > (UINTN) mFvHeader + mFvLength) {
+ if ((UINTN) CurrentFile + GetFfsFileLength(CurrentFile) > (UINTN) mFvHeader + mFvLength) {
*NextFile = NULL;
return EFI_SUCCESS;
}
@@ -194,20 +194,20 @@ Returns: // Verify current file is in range
//
if (((UINTN) CurrentFile < (UINTN) mFvHeader + mFvHeader->HeaderLength) ||
- ((UINTN) CurrentFile + GetLength (CurrentFile->Size) > (UINTN) mFvHeader + mFvLength)
+ ((UINTN) CurrentFile + GetFfsFileLength(CurrentFile) > (UINTN) mFvHeader + mFvLength)
) {
return EFI_INVALID_PARAMETER;
}
//
// Get next file, compensate for 8 byte alignment if necessary.
//
- *NextFile = (EFI_FFS_FILE_HEADER *) ((((UINTN) CurrentFile - (UINTN) mFvHeader + GetLength (CurrentFile->Size) + 0x07) & (-1 << 3)) + (UINT8 *) mFvHeader);
+ *NextFile = (EFI_FFS_FILE_HEADER *) ((((UINTN) CurrentFile - (UINTN) mFvHeader + GetFfsFileLength(CurrentFile) + 0x07) & (-1 << 3)) + (UINT8 *) mFvHeader);
//
// Verify file is in this FV.
//
- if (((UINTN) *NextFile + sizeof (EFI_FFS_FILE_HEADER) >= (UINTN) mFvHeader + mFvLength) ||
- ((UINTN) *NextFile + GetLength ((*NextFile)->Size) > (UINTN) mFvHeader + mFvLength)
+ if (((UINTN) *NextFile + GetFfsHeaderLength(*NextFile) >= (UINTN) mFvHeader + mFvLength) ||
+ ((UINTN) *NextFile + GetFfsFileLength (*NextFile) > (UINTN) mFvHeader + mFvLength)
) {
*NextFile = NULL;
return EFI_SUCCESS;
@@ -434,7 +434,11 @@ Returns: EFI_FILE_SECTION_POINTER InnerSection;
EFI_STATUS Status;
UINTN SectionSize;
+ UINT16 GuidSecAttr;
+ UINT16 GuidDataOffset;
+ GuidSecAttr = 0;
+ GuidDataOffset = 0;
CurrentSection = FirstSection;
while ((UINTN) CurrentSection.CommonHeader < (UINTN) SearchEnd) {
@@ -452,14 +456,21 @@ Returns: // special processing, go ahead to search the requesting
// section inside the GUID-defined section.
//
+ if (CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED) {
+ if (GetLength(CurrentSection.CommonHeader->Size) == 0xffffff) {
+ GuidSecAttr = CurrentSection.GuidDefinedSection2->Attributes;
+ GuidDataOffset = CurrentSection.GuidDefinedSection2->DataOffset;
+ } else {
+ GuidSecAttr = CurrentSection.GuidDefinedSection->Attributes;
+ GuidDataOffset = CurrentSection.GuidDefinedSection->DataOffset;
+ }
+ }
if (SectionType != EFI_SECTION_GUID_DEFINED &&
CurrentSection.CommonHeader->Type == EFI_SECTION_GUID_DEFINED &&
- !(CurrentSection.GuidDefinedSection->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED)) {
+ !(GuidSecAttr & EFI_GUIDED_SECTION_PROCESSING_REQUIRED)) {
InnerSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *)
- ((UINTN) CurrentSection.CommonHeader + CurrentSection.GuidDefinedSection->DataOffset);
- SectionSize = CurrentSection.CommonHeader->Size[0] +
- (CurrentSection.CommonHeader->Size[1] << 8) +
- (CurrentSection.CommonHeader->Size[2] << 16);
+ ((UINTN) CurrentSection.CommonHeader + GuidDataOffset);
+ SectionSize = GetSectionFileLength(CurrentSection.CommonHeader);
Status = SearchSectionByType (
InnerSection,
(UINT8 *) ((UINTN) CurrentSection.CommonHeader + SectionSize),
@@ -475,7 +486,7 @@ Returns: //
// Find next section (including compensating for alignment issues.
//
- CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetLength (CurrentSection.CommonHeader->Size) + 0x03) & (-1 << 2));
+ CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((((UINTN) CurrentSection.CommonHeader) + GetSectionFileLength(CurrentSection.CommonHeader) + 0x03) & (-1 << 2));
}
return EFI_NOT_FOUND;
@@ -538,14 +549,14 @@ Returns: //
// Get the first section
//
- CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + sizeof (EFI_FFS_FILE_HEADER));
+ CurrentSection.CommonHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) File + GetFfsHeaderLength(File));
//
// Depth-first manner to find section file.
//
Status = SearchSectionByType (
CurrentSection,
- (UINT8 *) ((UINTN) File + GetLength (File->Size)),
+ (UINT8 *) ((UINTN) File + GetFfsFileLength (File)),
SectionType,
&SectionCount,
Instance,
@@ -639,12 +650,14 @@ Returns: {
BOOLEAN ErasePolarity;
EFI_STATUS Status;
- EFI_FFS_FILE_HEADER BlankHeader;
+ EFI_FFS_FILE_HEADER2 BlankHeader;
UINT8 Checksum;
UINT32 FileLength;
UINT8 SavedChecksum;
UINT8 SavedState;
UINT8 FileGuidString[80];
+ UINT32 FfsHeaderSize;
+
//
// Verify library has been initialized.
//
@@ -665,16 +678,18 @@ Returns: if (EFI_ERROR (Status)) {
return EFI_ABORTED;
}
+
+ FfsHeaderSize = GetFfsHeaderLength(FfsHeader);
//
// Check if we have free space
//
if (ErasePolarity) {
- memset (&BlankHeader, -1, sizeof (EFI_FFS_FILE_HEADER));
+ memset (&BlankHeader, -1, FfsHeaderSize);
} else {
- memset (&BlankHeader, 0, sizeof (EFI_FFS_FILE_HEADER));
+ memset (&BlankHeader, 0, FfsHeaderSize);
}
- if (memcmp (&BlankHeader, FfsHeader, sizeof (EFI_FFS_FILE_HEADER)) == 0) {
+ if (memcmp (&BlankHeader, FfsHeader, FfsHeaderSize) == 0) {
return EFI_NOT_FOUND;
}
//
@@ -689,7 +704,7 @@ Returns: FfsHeader->State = 0;
SavedChecksum = FfsHeader->IntegrityCheck.Checksum.File;
FfsHeader->IntegrityCheck.Checksum.File = 0;
- Checksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER));
+ Checksum = CalculateSum8 ((UINT8 *) FfsHeader, FfsHeaderSize);
FfsHeader->State = SavedState;
FfsHeader->IntegrityCheck.Checksum.File = SavedChecksum;
if (Checksum != 0) {
@@ -703,8 +718,8 @@ Returns: //
// Verify file data checksum
//
- FileLength = GetLength (FfsHeader->Size);
- Checksum = CalculateSum8 ((UINT8 *) (FfsHeader + 1), FileLength - sizeof (EFI_FFS_FILE_HEADER));
+ FileLength = GetFfsFileLength (FfsHeader);
+ Checksum = CalculateSum8 ((UINT8 *) ((UINT8 *)FfsHeader + FfsHeaderSize), FileLength - FfsHeaderSize);
Checksum = Checksum + FfsHeader->IntegrityCheck.Checksum.File;
if (Checksum != 0) {
Error (NULL, 0, 0006, "invalid FFS file checksum", "Ffs file with Guid %s", FileGuidString);
@@ -725,6 +740,80 @@ Returns: }
UINT32
+GetFfsHeaderLength(
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+{
+ if (FfsHeader == NULL) {
+ return 0;
+ }
+ if (FfsHeader->Attributes & FFS_ATTRIB_LARGE_FILE) {
+ return sizeof(EFI_FFS_FILE_HEADER2);
+ }
+ return sizeof(EFI_FFS_FILE_HEADER);
+}
+
+UINT32
+GetSectionHeaderLength(
+ IN EFI_COMMON_SECTION_HEADER *SectionHeader
+ )
+{
+ if (SectionHeader == NULL) {
+ return 0;
+ }
+ if (GetLength(SectionHeader->Size) == 0xffffff) {
+ return sizeof(EFI_COMMON_SECTION_HEADER2);
+ }
+ return sizeof(EFI_COMMON_SECTION_HEADER);
+}
+
+UINT32
+GetFfsFileLength (
+ EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+
+ Get FFS file length including FFS header.
+
+Arguments:
+
+ FfsHeader Pointer to EFI_FFS_FILE_HEADER.
+
+Returns:
+
+ UINT32 Length of FFS file header.
+
+--*/
+{
+ if (FfsHeader == NULL) {
+ return 0;
+ }
+ if (FfsHeader->Attributes & FFS_ATTRIB_LARGE_FILE) {
+ return ((EFI_FFS_FILE_HEADER2 *)FfsHeader)->ExtendedSize;
+ } else {
+ return GetLength(FfsHeader->Size);
+ }
+}
+
+UINT32
+GetSectionFileLength (
+ EFI_COMMON_SECTION_HEADER *SectionHeader
+ )
+{
+ UINT32 Length;
+ if (SectionHeader == NULL) {
+ return 0;
+ }
+ Length = GetLength(SectionHeader->Size);
+ if (Length == 0xffffff) {
+ Length = ((EFI_COMMON_SECTION_HEADER2 *)SectionHeader)->ExtendedSize;
+ }
+ return Length;
+}
+
+UINT32
GetLength (
UINT8 *ThreeByteLength
)
|