]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/GenVtf/GenVtf.c
BaseTools/GenVtf: silence false "stringop-overflow" warning with memcpy()
[mirror_edk2.git] / BaseTools / Source / C / GenVtf / GenVtf.c
index e633b7ccf83a0d61d6d5fee4525c6b95ec9b0a95..fc7ae02203ff9716133f65c46bab7401eb086dec 100644 (file)
@@ -1,23 +1,15 @@
-/**\r
+/** @file\r
+This file contains functions required to generate a boot strap file (BSF) also \r
+known as the Volume Top File (VTF)\r
 \r
-Copyright (c)  1999 - 2008, Intel Corporation. All rights reserved\r
-This software and associated documentation (if any) is furnished\r
-under a license and may only be used or copied in accordance\r
-with the terms of the license. Except as permitted by such\r
-license, no part of this software or documentation may be\r
-reproduced, stored in a retrieval system, or transmitted in any\r
-form or by any means without the express written consent of\r
-Intel Corporation.\r
+Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed and made available \r
+under the terms and conditions of the BSD License which accompanies this \r
+distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
 \r
-\r
-Module Name:\r
-\r
-  GenVtf.c\r
-\r
-Abstract:\r
-\r
-  This file contains functions required to generate a boot strap file (BSF)\r
-  also known as the Volume Top File (VTF)\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
 \r
@@ -105,44 +97,51 @@ ConvertVersionInfo (
 /*++\r
 Routine Description:\r
 \r
-  This function converts GUID string to GUID\r
+  This function split version to major version and minor version\r
 \r
 Arguments:\r
 \r
   Str      - String representing in form XX.XX\r
-  MajorVer - The major vertion\r
-  MinorVer - The minor vertion\r
+  MajorVer - The major version\r
+  MinorVer - The minor version\r
 \r
 Returns:\r
 \r
-  EFI_SUCCESS  - The fuction completed successfully.\r
+  EFI_SUCCESS  - The function completed successfully.\r
 \r
 --*/\r
 {\r
-  CHAR8  StrPtr[40];\r
-  CHAR8  *Token;\r
-  UINTN  Length;\r
-  UINT32 Major;\r
-  UINT32 Minor;\r
+  CHAR8  TemStr[5] = "0000";\r
+  int    Major;\r
+  int    Minor;\r
+  UINTN Length;\r
 \r
   Major = 0;\r
   Minor = 0;\r
-  memset (StrPtr, 0, 40);\r
-  Token = strtok (Str, ".");\r
 \r
-  while (Token != NULL) {\r
-    strcat (StrPtr, Token);\r
-    Token = strtok (NULL, ".");\r
+  if (strstr (Str, ".") != NULL) {\r
+    sscanf (\r
+      Str,\r
+      "%02x.%02x",\r
+      &Major,\r
+      &Minor\r
+      );\r
+  } else {\r
+    Length = strlen(Str);\r
+    if (Length < 4) {\r
+      memcpy (TemStr + 4 - Length, Str, Length);\r
+    } else {\r
+      memcpy (TemStr, Str + Length - 4, 4);\r
+    }\r
+  \r
+    sscanf (\r
+      TemStr,\r
+      "%02x%02x",\r
+      &Major,\r
+      &Minor\r
+      );\r
   }\r
 \r
-  Length = strlen (StrPtr);\r
-  sscanf (\r
-    StrPtr,\r
-    "%01x%02x",\r
-    &Major,\r
-    &Minor\r
-    );\r
-\r
   *MajorVer = (UINT8) Major;\r
   *MinorVer = (UINT8) Minor;\r
   return EFI_SUCCESS;\r
@@ -278,7 +277,7 @@ InitializeComps (
 \r
 Routine Description:\r
 \r
-  This function intializes the relevant global variable which is being\r
+  This function initializes the relevant global variable which is being\r
   used to store the information retrieved from INF file.  This also initializes\r
   the VTF symbol file.\r
 \r
@@ -316,7 +315,7 @@ ParseAndUpdateComponents (
 \r
 Routine Description:\r
 \r
-  This function intializes the relevant global variable which is being\r
+  This function initializes the relevant global variable which is being\r
   used to store the information retrieved from INF file.\r
 \r
 Arguments:\r
@@ -342,12 +341,11 @@ Returns:
         VtfInfo->LocationType = SECOND_VTF;\r
       } else {\r
         VtfInfo->LocationType = NONE;\r
-        Warning(UTILITY_NAME, 0, 0001, "Unknown location for component.", VtfInfo->CompName);\r
       }\r
     } else if (strnicmp (*TokenStr, "COMP_TYPE", 9) == 0) {\r
       TokenStr++;\r
       if (AsciiStringToUint64 (*TokenStr, FALSE, &StringValue) != EFI_SUCCESS) {\r
-        Error (NULL, 0, 5001, "Cannot get: \"0x%x\".", *TokenStr);\r
+        Error (NULL, 0, 5001, "Cannot get: \"0x%s\".", *TokenStr);\r
         return ;\r
       }\r
 \r
@@ -364,10 +362,20 @@ Returns:
       }\r
     } else if (strnicmp (*TokenStr, "COMP_BIN", 8) == 0) {\r
       TokenStr++;\r
-      strcpy (VtfInfo->CompBinName, *TokenStr);\r
+      if (strlen (*TokenStr) >= FILE_NAME_SIZE) {\r
+        Error (NULL, 0, 3000, "Invalid", "The 'COMP_BIN' name is too long.");\r
+        return ;\r
+      }\r
+      strncpy (VtfInfo->CompBinName, *TokenStr, FILE_NAME_SIZE - 1);\r
+      VtfInfo->CompBinName[FILE_NAME_SIZE - 1] = 0;\r
     } else if (strnicmp (*TokenStr, "COMP_SYM", 8) == 0) {\r
       TokenStr++;\r
-      strcpy (VtfInfo->CompSymName, *TokenStr);\r
+      if (strlen (*TokenStr) >= FILE_NAME_SIZE) {\r
+        Error (NULL, 0, 3000, "Invalid", "The 'COMP_SYM' name is too long.");\r
+        return ;\r
+      }\r
+      strncpy (VtfInfo->CompSymName, *TokenStr, FILE_NAME_SIZE - 1);\r
+      VtfInfo->CompSymName[FILE_NAME_SIZE - 1] = 0;\r
     } else if (strnicmp (*TokenStr, "COMP_SIZE", 9) == 0) {\r
       TokenStr++;\r
       if (strnicmp (*TokenStr, "-", 1) == 0) {\r
@@ -446,14 +454,24 @@ Returns:
     if (SectionOptionFlag) {\r
       if (stricmp (*TokenStr, "IA32_RST_BIN") == 0) {\r
         TokenStr++;\r
-        strcpy (IA32BinFile, *TokenStr);\r
+        if (strlen (*TokenStr) >= FILE_NAME_SIZE) {\r
+          Error (NULL, 0, 3000, "Invalid", "The 'IA32_RST_BIN' name is too long.");\r
+          break;\r
+        }\r
+        strncpy (IA32BinFile, *TokenStr, FILE_NAME_SIZE - 1);\r
+        IA32BinFile[FILE_NAME_SIZE - 1] = 0;\r
       }\r
     }\r
 \r
     if (SectionCompFlag) {\r
       if (stricmp (*TokenStr, "COMP_NAME") == 0) {\r
         TokenStr++;\r
-        strcpy (FileListPtr->CompName, *TokenStr);\r
+        if (strlen (*TokenStr) >= COMPONENT_NAME_SIZE) {\r
+          Error (NULL, 0, 3000, "Invalid", "The 'COMP_NAME' name is too long.");\r
+          break;\r
+        }\r
+        strncpy (FileListPtr->CompName, *TokenStr, COMPONENT_NAME_SIZE - 1);\r
+        FileListPtr->CompName[COMPONENT_NAME_SIZE - 1] = 0;\r
         TokenStr++;\r
         ParseAndUpdateComponents (FileListPtr);\r
       }\r
@@ -798,6 +816,7 @@ Returns:
 \r
   TmpFitPtr         = (FIT_TABLE *) RelativeAddress;\r
   NumFitComponents  = TmpFitPtr->CompSize;\r
+  *FitPtr           = NULL;\r
 \r
   for (Index = 0; Index < NumFitComponents; Index++) {\r
     if ((TmpFitPtr->CvAndType & FIT_TYPE_MASK) == COMP_TYPE_FIT_UNUSED) {\r
@@ -1063,18 +1082,34 @@ Returns:
   CHAR8   Buff4[10];\r
   CHAR8   Buff5[10];\r
   CHAR8   Token[50];\r
+  CHAR8   FormatString[MAX_LINE_LEN];\r
 \r
-  Fp = fopen (VtfInfo->CompSymName, "rb");\r
+  Fp = fopen (LongFilePath (VtfInfo->CompSymName), "rb");\r
 \r
   if (Fp == NULL) {\r
     Error (NULL, 0, 0001, "Error opening file", VtfInfo->CompSymName);\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
+  //\r
+  // Generate the format string for fscanf\r
+  //\r
+  sprintf (\r
+    FormatString,\r
+    "%%%us %%%us %%%us %%%us %%%us %%%us %%%us",\r
+    (unsigned) sizeof (Buff1) - 1,\r
+    (unsigned) sizeof (Buff2) - 1,\r
+    (unsigned) sizeof (OffsetStr) - 1,\r
+    (unsigned) sizeof (Buff3) - 1,\r
+    (unsigned) sizeof (Buff4) - 1,\r
+    (unsigned) sizeof (Buff5) - 1,\r
+    (unsigned) sizeof (Token) - 1\r
+    );\r
+\r
   while (fgets (Buff, sizeof (Buff), Fp) != NULL) {\r
     fscanf (\r
       Fp,\r
-      "%s %s %s %s %s %s %s",\r
+      FormatString,\r
       Buff1,\r
       Buff2,\r
       OffsetStr,\r
@@ -1126,6 +1161,7 @@ Returns:
   EFI_ABORTED      - Aborted due to one of the many reasons like:\r
                       (a) Component Size greater than the specified size.\r
                       (b) Error opening files.\r
+                      (c) Fail to get the FIT table address.\r
 \r
   EFI_INVALID_PARAMETER     Value returned from call to UpdateEntryPoint()\r
   EFI_OUT_OF_RESOURCES      Memory allocation failure.\r
@@ -1135,7 +1171,6 @@ Returns:
   EFI_STATUS  Status;\r
   UINT64      CompStartAddress;\r
   UINT64      FileSize;\r
-  UINT64      NumByteRead;\r
   UINT64      NumAdjustByte;\r
   UINT8       *Buffer;\r
   FILE        *Fp;\r
@@ -1147,7 +1182,7 @@ Returns:
     return EFI_SUCCESS;\r
   }\r
 \r
-  Fp = fopen (VtfInfo->CompBinName, "rb");\r
+  Fp = fopen (LongFilePath (VtfInfo->CompBinName), "rb");\r
 \r
   if (Fp == NULL) {\r
     Error (NULL, 0, 0001, "Error opening file", VtfInfo->CompBinName);\r
@@ -1165,6 +1200,7 @@ Returns:
 \r
   if (VtfInfo->PreferredSize) {\r
     if (FileSize > VtfInfo->CompSize) {\r
+      fclose (Fp);\r
       Error (NULL, 0, 2000, "Invalid parameter", "The component size is more than specified size.");\r
       return EFI_ABORTED;\r
     }\r
@@ -1174,6 +1210,7 @@ Returns:
 \r
   Buffer = malloc ((UINTN) FileSize);\r
   if (Buffer == NULL) {\r
+    fclose (Fp);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
   memset (Buffer, 0, (UINTN) FileSize);\r
@@ -1183,7 +1220,7 @@ Returns:
     //\r
     // Read first 64 bytes of PAL header and use it to find version info\r
     //\r
-    NumByteRead = fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);\r
+    fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);\r
 \r
     //\r
     // PAL header contains the version info. Currently, we will use the header\r
@@ -1194,7 +1231,7 @@ Returns:
     }\r
   }\r
 \r
-  NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);\r
+  fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);\r
   fclose (Fp);\r
 \r
   //\r
@@ -1233,18 +1270,25 @@ Returns:
     Vtf1TotalSize += (UINT32) (FileSize + NumAdjustByte);\r
     Status = UpdateVtfBuffer (CompStartAddress, Buffer, FileSize, FIRST_VTF);\r
   } else {\r
+    free (Buffer);\r
     Error (NULL, 0, 2000,"Invalid Parameter", "There's component in second VTF so second BaseAddress and Size must be specified!");\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
   if (EFI_ERROR (Status)) {\r
+    free (Buffer);\r
     return EFI_ABORTED;\r
   }\r
 \r
   GetNextAvailableFitPtr (&CompFitPtr);\r
+  if (CompFitPtr == NULL) {\r
+    free (Buffer);\r
+    return EFI_ABORTED;\r
+  }\r
 \r
   CompFitPtr->CompAddress = CompStartAddress | IPF_CACHE_BIT;\r
   if ((FileSize % 16) != 0) {\r
+    free (Buffer);\r
     Error (NULL, 0, 2000, "Invalid parameter", "Binary FileSize must be a multiple of 16.");\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -1267,7 +1311,7 @@ Returns:
   //\r
   // Update the SYM file for this component based on it's start address.\r
   //\r
-  Status = UpdateSymFile (CompStartAddress, SymFileName, VtfInfo->CompSymName);\r
+  Status = UpdateSymFile (CompStartAddress, SymFileName, VtfInfo->CompSymName, FileSize);\r
   if (EFI_ERROR (Status)) {\r
 \r
     //\r
@@ -1323,12 +1367,11 @@ Returns:
   UINT64      AbsAddress;\r
   UINTN       RelativeAddress;\r
   UINT64      FileSize;\r
-  UINT64      NumByteRead;\r
   UINT8       *Buffer;\r
   FILE        *Fp;\r
   FIT_TABLE   *PalFitPtr;\r
 \r
-  Fp = fopen (VtfInfo->CompBinName, "rb");\r
+  Fp = fopen (LongFilePath (VtfInfo->CompBinName), "rb");\r
 \r
   if (Fp == NULL) {\r
     Error (NULL, 0, 0001, "Error opening file", VtfInfo->CompBinName);\r
@@ -1337,6 +1380,7 @@ Returns:
 \r
   FileSize = _filelength (fileno (Fp));\r
   if (FileSize < 64) {\r
+    fclose (Fp);\r
     Error (NULL, 0, 2000, "Invalid parameter", "PAL_A bin header is 64 bytes, so the Bin size must be larger than 64 bytes!");\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -1345,6 +1389,7 @@ Returns:
 \r
   if (VtfInfo->PreferredSize) {\r
     if (FileSize > VtfInfo->CompSize) {\r
+      fclose (Fp);\r
       Error (NULL, 0, 2000, "Invalid parameter", "The PAL_A Size is more than the specified size.");\r
       return EFI_ABORTED;\r
     }\r
@@ -1354,6 +1399,7 @@ Returns:
 \r
   Buffer = malloc ((UINTN) FileSize);\r
   if (Buffer == NULL) {\r
+    fclose (Fp);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
   memset (Buffer, 0, (UINTN) FileSize);\r
@@ -1361,7 +1407,7 @@ Returns:
   //\r
   // Read, Get version Info and discard the PAL header.\r
   //\r
-  NumByteRead = fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);\r
+  fread (Buffer, sizeof (UINT8), SIZE_OF_PAL_HEADER, Fp);\r
 \r
   //\r
   // Extract the version info from header of PAL_A. Once done, discrad this buffer\r
@@ -1373,7 +1419,7 @@ Returns:
   //\r
   // Read PAL_A file in a buffer\r
   //\r
-  NumByteRead = fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);\r
+  fread (Buffer, sizeof (UINT8), (UINTN) FileSize, Fp);\r
   fclose (Fp);\r
 \r
   PalStartAddress       = Fv1EndAddress - (SIZE_TO_OFFSET_PAL_A_END + FileSize);\r
@@ -1387,6 +1433,7 @@ Returns:
   PalFitPtr->CompAddress  = PalStartAddress | IPF_CACHE_BIT;\r
   //assert ((FileSize % 16) == 0);\r
   if ((FileSize % 16) != 0) {\r
+    free (Buffer);\r
     Error (NULL, 0, 2000, "Invalid parameter", "Binary FileSize must be a multiple of 16.");\r
     return EFI_INVALID_PARAMETER;\r
   }\r
@@ -1406,7 +1453,7 @@ Returns:
   //\r
   // Update the SYM file for this component based on it's start address.\r
   //\r
-  Status = UpdateSymFile (PalStartAddress, SymFileName, VtfInfo->CompSymName);\r
+  Status = UpdateSymFile (PalStartAddress, SymFileName, VtfInfo->CompSymName, FileSize);\r
   if (EFI_ERROR (Status)) {\r
 \r
     //\r
@@ -1547,7 +1594,7 @@ Returns:
     VtfBuffer = (VOID *) RelativeAddress;\r
   }\r
 \r
-  Fp = fopen (FileName, "wb");\r
+  Fp = fopen (LongFilePath (FileName), "wb");\r
   if (Fp == NULL) {\r
     Error (NULL, 0, 0001, "Error opening file", FileName);\r
     return EFI_ABORTED;\r
@@ -1688,7 +1735,7 @@ Returns:
   FileHeader->IntegrityCheck.Checksum.File    = 0;\r
   FileHeader->State                           = 0;\r
   FileHeader->IntegrityCheck.Checksum.Header  = CalculateChecksum8 ((UINT8 *) FileHeader, sizeof (EFI_FFS_FILE_HEADER));\r
-  FileHeader->IntegrityCheck.Checksum.File    = CalculateChecksum8 ((UINT8 *) FileHeader, TotalVtfSize);\r
+  FileHeader->IntegrityCheck.Checksum.File    = CalculateChecksum8 ((UINT8 *) (FileHeader + 1), TotalVtfSize - sizeof (EFI_FFS_FILE_HEADER));\r
   FileHeader->State                           = EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID | EFI_FILE_DATA_VALID;\r
 \r
   return EFI_SUCCESS;\r
@@ -1718,7 +1765,7 @@ Returns:
 \r
 --*/\r
 {\r
-  if ((BaseAddress >= 0) && (FwVolSize > 0x40) && ((BaseAddress + FwVolSize) % 8 == 0)) {\r
+  if ((FwVolSize > 0x40) && ((BaseAddress + FwVolSize) % 8 == 0)) {\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -1753,14 +1800,13 @@ Returns:
   UINT8 *Buffer;\r
   UINT8 *LocalVtfBuffer;\r
   UINTN FileSize;\r
-  UINTN NumByteRead;\r
   FILE  *Fp;\r
 \r
   if (!strcmp (FileName, "")) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
-  Fp = fopen (FileName, "rb");\r
+  Fp = fopen (LongFilePath (FileName), "rb");\r
 \r
   if (Fp == NULL) {\r
     Error (NULL, 0, 0001, "Error opening file", FileName);\r
@@ -1770,15 +1816,17 @@ Returns:
   FileSize = _filelength (fileno (Fp));\r
 \r
   if (FileSize > 16) {\r
+    fclose (Fp);\r
     return EFI_ABORTED;\r
   }\r
 \r
   Buffer = malloc (FileSize);\r
   if (Buffer == NULL) {\r
+    fclose (Fp);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
-  NumByteRead     = fread (Buffer, sizeof (UINT8), FileSize, Fp);\r
+  fread (Buffer, sizeof (UINT8), FileSize, Fp);\r
 \r
   LocalVtfBuffer  = (UINT8 *) Vtf1EndBuffer - SIZE_IA32_RESET_VECT;\r
   memcpy (LocalVtfBuffer, Buffer, FileSize);\r
@@ -1970,7 +2018,7 @@ Returns:
 \r
   Fv1BaseAddress        = StartAddress1;\r
   Fv1EndAddress         = Fv1BaseAddress + Size1;\r
-  if (Fv1EndAddress != 0x100000000 || Size1 < 0x100000) {\r
+  if (Fv1EndAddress != 0x100000000ULL || Size1 < 0x100000) {\r
     Error (NULL, 0, 2000, "Invalid parameter", "Error BaseAddress and Size parameters!");\r
     if (Size1 < 0x100000) {\r
       Error (NULL, 0, 2000, "Invalid parameter", "The FwVolumeSize must be larger than 1M!");\r
@@ -2115,7 +2163,6 @@ Returns:
   FILE        *Fp;\r
   UINT64      *StartAddressPtr;\r
   UINTN       FirstFwVSize;\r
-  UINTN       NumByte;\r
 \r
   StartAddressPtr   = malloc (sizeof (UINT64));\r
   if (StartAddressPtr == NULL) {\r
@@ -2123,7 +2170,7 @@ Returns:
   }\r
   *StartAddressPtr = StartAddress;\r
 \r
-  Fp = fopen (OutFileName1, "rb");\r
+  Fp = fopen (LongFilePath (OutFileName1), "rb");\r
 \r
   if (Fp == NULL) {\r
     Error (NULL, 0, 0001, "Error opening file", OutFileName1);\r
@@ -2135,7 +2182,7 @@ Returns:
 \r
   FirstFwVSize = _filelength (fileno (Fp));\r
   fseek (Fp, (long) (FirstFwVSize - (UINTN) (SIZE_IA32_RESET_VECT + SIZE_SALE_ENTRY_POINT)), SEEK_SET);\r
-  NumByte = fwrite ((VOID *) StartAddressPtr, sizeof (UINT64), 1, Fp);\r
+  fwrite ((VOID *) StartAddressPtr, sizeof (UINT64), 1, Fp);\r
 \r
   if (Fp) {\r
     fclose (Fp);\r
@@ -2153,7 +2200,9 @@ EFI_STATUS
 UpdateSymFile (\r
   IN UINT64 BaseAddress,\r
   IN CHAR8  *DestFileName,\r
-  IN CHAR8  *SourceFileName\r
+  IN CHAR8  *SourceFileName,\r
+  IN UINT64 FileSize\r
+\r
   )\r
 /*++\r
 \r
@@ -2167,6 +2216,7 @@ Arguments:
   BaseAddress    - The base address for the new SYM tokens.\r
   DestFileName   - The destination file.\r
   SourceFileName - The source file.\r
+  FileSize       - Size of bin file.\r
 \r
 Returns:\r
 \r
@@ -2178,14 +2228,15 @@ Returns:
 {\r
   FILE    *SourceFile;\r
   FILE    *DestFile;\r
-  CHAR8   Buffer[_MAX_PATH];\r
-  CHAR8   Type[_MAX_PATH];\r
-  CHAR8   Address[_MAX_PATH];\r
-  CHAR8   Section[_MAX_PATH];\r
-  CHAR8   Token[_MAX_PATH];\r
-  CHAR8   BaseToken[_MAX_PATH];\r
+  CHAR8   Buffer[MAX_LONG_FILE_PATH];\r
+  CHAR8   Type[MAX_LONG_FILE_PATH];\r
+  CHAR8   Address[MAX_LONG_FILE_PATH];\r
+  CHAR8   Section[MAX_LONG_FILE_PATH];\r
+  CHAR8   Token[MAX_LONG_FILE_PATH];\r
+  CHAR8   BaseToken[MAX_LONG_FILE_PATH];\r
+  CHAR8   FormatString[MAX_LINE_LEN];\r
   UINT64  TokenAddress;\r
-  long      StartLocation;\r
+  long    StartLocation;\r
 \r
   //\r
   // Verify input parameters.\r
@@ -2197,7 +2248,7 @@ Returns:
   //\r
   // Open the source file\r
   //\r
-  SourceFile = fopen (SourceFileName, "r");\r
+  SourceFile = fopen (LongFilePath (SourceFileName), "r");\r
   if (SourceFile == NULL) {\r
 \r
     //\r
@@ -2209,14 +2260,25 @@ Returns:
   //\r
   // Use the file name minus extension as the base for tokens\r
   //\r
-  strcpy (BaseToken, SourceFileName);\r
+  if (strlen (SourceFileName) >= MAX_LONG_FILE_PATH) {\r
+    fclose (SourceFile);\r
+    Error (NULL, 0, 2000, "Invalid parameter", "The source file name is too long.");\r
+    return EFI_ABORTED;\r
+  }\r
+  strncpy (BaseToken, SourceFileName, MAX_LONG_FILE_PATH - 1);\r
+  BaseToken[MAX_LONG_FILE_PATH - 1] = 0;\r
   strtok (BaseToken, ". \t\n");\r
-  strcat (BaseToken, "__");\r
+  if (strlen (BaseToken) + strlen ("__") >= MAX_LONG_FILE_PATH) {\r
+    fclose (SourceFile);\r
+    Error (NULL, 0, 2000, "Invalid parameter", "The source file name is too long.");\r
+    return EFI_ABORTED;\r
+  }\r
+  strncat (BaseToken, "__", MAX_LONG_FILE_PATH - strlen (BaseToken) - 1);\r
 \r
   //\r
   // Open the destination file\r
   //\r
-  DestFile = fopen (DestFileName, "a+");\r
+  DestFile = fopen (LongFilePath (DestFileName), "a+");\r
   if (DestFile == NULL) {\r
     fclose (SourceFile);\r
     Error (NULL, 0, 0001, "Error opening file", DestFileName);\r
@@ -2247,7 +2309,7 @@ Returns:
   //\r
   // Read the first line\r
   //\r
-  if (fgets (Buffer, _MAX_PATH, SourceFile) == NULL) {\r
+  if (fgets (Buffer, MAX_LONG_FILE_PATH, SourceFile) == NULL) {\r
     Buffer[0] = 0;\r
   }\r
 \r
@@ -2261,6 +2323,18 @@ Returns:
     return EFI_ABORTED;\r
   }\r
 \r
+  //\r
+  // Generate the format string for fscanf\r
+  //\r
+  sprintf (\r
+    FormatString,\r
+    "%%%us | %%%us | %%%us | %%%us\n",\r
+    (unsigned) sizeof (Type) - 1,\r
+    (unsigned) sizeof (Address) - 1,\r
+    (unsigned) sizeof (Section) - 1,\r
+    (unsigned) sizeof (Token) - 1\r
+    );\r
+\r
   //\r
   // Read in the file\r
   //\r
@@ -2269,23 +2343,26 @@ Returns:
     //\r
     // Read a line\r
     //\r
-    if (fscanf (SourceFile, "%s | %s | %s | %s\n", Type, Address, Section, Token) == 4) {\r
+    if (fscanf (SourceFile, FormatString, Type, Address, Section, Token) == 4) {\r
 \r
       //\r
       // Get the token address\r
       //\r
       AsciiStringToUint64 (Address, TRUE, &TokenAddress);\r
+      if (TokenAddress > FileSize) {\r
+        //\r
+        // Symbol offset larger than FileSize. This Symbol can't be in Bin file. Don't print them.\r
+        //\r
+        break;\r
+      }\r
 \r
       //\r
       // Add the base address, the size of the FFS file header and the size of the peim header.\r
       //\r
       TokenAddress += BaseAddress &~IPF_CACHE_BIT;\r
 \r
-#ifdef __GNUC__\r
-      fprintf (DestFile, "%s | %016lX | %s | %s%s\n", Type, TokenAddress, Section, BaseToken, Token);\r
-#else\r
-       fprintf (DestFile, "%s | %016I64X | %s | %s%s\n", Type, TokenAddress, Section, BaseToken, Token);\r
-#endif\r
+      fprintf (DestFile, "%s | %016llX | ", Type, (unsigned long long) TokenAddress);\r
+      fprintf (DestFile, "%s | %s\n    %s\n", Section, Token, BaseToken); \r
     }\r
   }\r
 \r
@@ -2371,7 +2448,7 @@ Returns:
 \r
 --*/\r
 {\r
-  fprintf (stdout, "%s Version %d.%d\n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION);\r
+  fprintf (stdout, "%s Version %d.%d %s \n", UTILITY_NAME, UTILITY_MAJOR_VERSION, UTILITY_MINOR_VERSION, __BUILD_VERSION);\r
 }\r
 \r
 VOID\r
@@ -2402,7 +2479,7 @@ Returns:
   //\r
   // Copyright declaration\r
   //\r
-  fprintf (stdout, "Copyright (c) 2007 - 2009, Intel Corporation. All rights reserved.\n\n");\r
+  fprintf (stdout, "Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.\n\n");\r
   //\r
   // Details Option\r
   //\r
@@ -2538,7 +2615,13 @@ Returns:
       // Get the input VTF file name\r
       //\r
       VtfFileName = argv[Index+1];\r
-      VtfFP = fopen(VtfFileName, "rb");\r
+      if (VtfFP != NULL) {\r
+        //\r
+        // VTF file name has been given previously, override with the new value\r
+        //\r
+        fclose (VtfFP);\r
+      }\r
+      VtfFP = fopen (LongFilePath (VtfFileName), "rb");\r
       if (VtfFP == NULL) {\r
         Error (NULL, 0, 0001, "Error opening file", VtfFileName);\r
         goto ERROR;\r
@@ -2651,21 +2734,28 @@ Returns:
     }\r
     SymFileName = VTF_SYM_FILE;\r
   } else {\r
-    INTN OutFileNameLen = strlen(OutFileName1);\r
-    INTN Index;\r
+    INTN OutFileNameLen;\r
+    INTN NewIndex;\r
 \r
-    for (Index = OutFileNameLen; Index > 0; --Index) {\r
-      if (OutFileName1[Index] == '/' || OutFileName1[Index] == '\\') {\r
+    assert (OutFileName1);\r
+    OutFileNameLen = strlen(OutFileName1);\r
+\r
+    for (NewIndex = OutFileNameLen; NewIndex > 0; --NewIndex) {\r
+      if (OutFileName1[NewIndex] == '/' || OutFileName1[NewIndex] == '\\') {\r
         break;\r
       }\r
     }\r
-    if (Index == 0) {\r
+    if (NewIndex == 0) {\r
       SymFileName = VTF_SYM_FILE;\r
     } else {\r
-      INTN SymFileNameLen = Index + 1 + strlen(VTF_SYM_FILE);\r
+      INTN SymFileNameLen = NewIndex + 1 + strlen(VTF_SYM_FILE);\r
       SymFileName = malloc(SymFileNameLen + 1);\r
-      memcpy(SymFileName, OutFileName1, Index + 1);\r
-      memcpy(SymFileName + Index + 1, VTF_SYM_FILE, strlen(VTF_SYM_FILE));\r
+      if (SymFileName == NULL) {\r
+        Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");\r
+        goto ERROR;\r
+      }\r
+      memcpy(SymFileName, OutFileName1, NewIndex + 1);\r
+      memcpy(SymFileName + NewIndex + 1, VTF_SYM_FILE, strlen(VTF_SYM_FILE));\r
       SymFileName[SymFileNameLen] = '\0';\r
     }\r
     if (DebugMode) {\r
@@ -2689,7 +2779,7 @@ Returns:
       break;\r
 \r
     case EFI_ABORTED:\r
-      Error (NULL, 0, 3000, "Invaild", "Error detected while creating the file image.");\r
+      Error (NULL, 0, 3000, "Invalid", "Error detected while creating the file image.");\r
       break;\r
 \r
     case EFI_OUT_OF_RESOURCES:\r
@@ -2697,11 +2787,11 @@ Returns:
       break;\r
 \r
     case EFI_VOLUME_CORRUPTED:\r
-      Error (NULL, 0, 3000, "Invaild", "No base address was specified.");\r
+      Error (NULL, 0, 3000, "Invalid", "No base address was specified.");\r
       break;\r
 \r
     default:\r
-      Error (NULL, 0, 3000, "Invaild", "GenVtfImage function returned unknown status %x.",Status );\r
+      Error (NULL, 0, 3000, "Invalid", "GenVtfImage function returned unknown status %x.", (int) Status );\r
       break;\r
     }\r
   }\r