1## @file 2# process GUIDed section generation 3# 4# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR> 5# 6# This program and the accompanying materials 7# are licensed and made available under the terms and conditions of the BSD License 8# which accompanies this distribution. The full text of the license may be found at 9# http://opensource.org/licenses/bsd-license.php 10# 11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13# 14 15## 16# Import Modules 17# 18import Section 19import subprocess 20from Ffs import Ffs 21import Common.LongFilePathOs as os 22from GenFdsGlobalVariable import GenFdsGlobalVariable 23from CommonDataClass.FdfClass import GuidSectionClassObject 24from Common import ToolDefClassObject 25import sys 26from Common import EdkLogger 27from Common.BuildToolError import * 28from FvImageSection import FvImageSection 29from Common.LongFilePathSupport import OpenLongFilePath as open 30from GenFds import FindExtendTool 31 32## generate GUIDed section 33# 34# 35class GuidSection(GuidSectionClassObject) : 36 37 ## The constructor 38 # 39 # @param self The object pointer 40 # 41 def __init__(self): 42 GuidSectionClassObject.__init__(self) 43 44 ## GenSection() method 45 # 46 # Generate GUIDed section 47 # 48 # @param self The object pointer 49 # @param OutputPath Where to place output file 50 # @param ModuleName Which module this section belongs to 51 # @param SecNum Index of section 52 # @param KeyStringList Filter for inputs of section generation 53 # @param FfsInf FfsInfStatement object that contains this section data 54 # @param Dict dictionary contains macro and its value 55 # @retval tuple (Generated file name, section alignment) 56 # 57 def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}): 58 # 59 # Generate all section 60 # 61 self.KeyStringList = KeyStringList 62 self.CurrentArchList = GenFdsGlobalVariable.ArchList 63 if FfsInf != None: 64 self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) 65 self.NameGuid = FfsInf.__ExtendMacro__(self.NameGuid) 66 self.SectionType = FfsInf.__ExtendMacro__(self.SectionType) 67 self.CurrentArchList = [FfsInf.CurrentArch] 68 69 SectFile = tuple() 70 SectAlign = [] 71 Index = 0 72 MaxAlign = None 73 if self.FvAddr != []: 74 FvAddrIsSet = True 75 else: 76 FvAddrIsSet = False 77 78 if self.ProcessRequired in ("TRUE", "1"): 79 if self.FvAddr != []: 80 #no use FvAddr when the image is processed. 81 self.FvAddr = [] 82 if self.FvParentAddr != None: 83 #no use Parent Addr when the image is processed. 84 self.FvParentAddr = None 85 86 for Sect in self.SectionList: 87 Index = Index + 1 88 SecIndex = '%s.%d' % (SecNum, Index) 89 # set base address for inside FvImage 90 if isinstance(Sect, FvImageSection): 91 if self.FvAddr != []: 92 Sect.FvAddr = self.FvAddr.pop(0) 93 self.IncludeFvSection = True 94 elif isinstance(Sect, GuidSection): 95 Sect.FvAddr = self.FvAddr 96 Sect.FvParentAddr = self.FvParentAddr 97 ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict) 98 if isinstance(Sect, GuidSection): 99 if Sect.IncludeFvSection: 100 self.IncludeFvSection = Sect.IncludeFvSection 101 102 if align != None: 103 if MaxAlign == None: 104 MaxAlign = align 105 if GenFdsGlobalVariable.GetAlignment (align) > GenFdsGlobalVariable.GetAlignment (MaxAlign): 106 MaxAlign = align 107 if ReturnSectList != []: 108 if align == None: 109 align = "1" 110 for file in ReturnSectList: 111 SectFile += (file,) 112 SectAlign.append(align) 113 114 if MaxAlign != None: 115 if self.Alignment == None: 116 self.Alignment = MaxAlign 117 else: 118 if GenFdsGlobalVariable.GetAlignment (MaxAlign) > GenFdsGlobalVariable.GetAlignment (self.Alignment): 119 self.Alignment = MaxAlign 120 121 OutputFile = OutputPath + \ 122 os.sep + \ 123 ModuleName + \ 124 'SEC' + \ 125 SecNum + \ 126 Ffs.SectionSuffix['GUIDED'] 127 OutputFile = os.path.normpath(OutputFile) 128 129 ExternalTool = None 130 ExternalOption = None 131 if self.NameGuid != None: 132 ExternalTool, ExternalOption = FindExtendTool(self.KeyStringList, self.CurrentArchList, self.NameGuid) 133 134 # 135 # If not have GUID , call default 136 # GENCRC32 section 137 # 138 if self.NameGuid == None : 139 GenFdsGlobalVariable.VerboseLogger("Use GenSection function Generate CRC32 Section") 140 GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign) 141 OutputFileList = [] 142 OutputFileList.append(OutputFile) 143 return OutputFileList, self.Alignment 144 #or GUID not in External Tool List 145 elif ExternalTool == None: 146 EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % self.NameGuid) 147 else: 148 DummyFile = OutputFile + ".dummy" 149 # 150 # Call GenSection with DUMMY section type. 151 # 152 GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign) 153 # 154 # Use external tool process the Output 155 # 156 TempFile = OutputPath + \ 157 os.sep + \ 158 ModuleName + \ 159 'SEC' + \ 160 SecNum + \ 161 '.tmp' 162 TempFile = os.path.normpath(TempFile) 163 # 164 # Remove temp file if its time stamp is older than dummy file 165 # Just in case the external tool fails at this time but succeeded before 166 # Error should be reported if the external tool does not generate a new output based on new input 167 # 168 if os.path.exists(TempFile) and os.path.exists(DummyFile) and os.path.getmtime(TempFile) < os.path.getmtime(DummyFile): 169 os.remove(TempFile) 170 171 FirstCall = False 172 CmdOption = '-e' 173 if ExternalOption != None: 174 CmdOption = CmdOption + ' ' + ExternalOption 175 if self.ProcessRequired not in ("TRUE", "1") and self.IncludeFvSection and not FvAddrIsSet and self.FvParentAddr != None: 176 #FirstCall is only set for the encapsulated flash FV image without process required attribute. 177 FirstCall = True 178 # 179 # Call external tool 180 # 181 ReturnValue = [1] 182 if FirstCall: 183 #first try to call the guided tool with -z option and CmdOption for the no process required guided tool. 184 GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, '-z' + ' ' + CmdOption, ReturnValue) 185 186 # 187 # when no call or first call failed, ReturnValue are not 1. 188 # Call the guided tool with CmdOption 189 # 190 if ReturnValue[0] != 0: 191 FirstCall = False 192 ReturnValue[0] = 0 193 GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption) 194 # 195 # There is external tool which does not follow standard rule which return nonzero if tool fails 196 # The output file has to be checked 197 # 198 if not os.path.exists(TempFile): 199 EdkLogger.error("GenFds", COMMAND_FAILURE, 'Fail to call %s, no output file was generated' % ExternalTool) 200 201 FileHandleIn = open(DummyFile, 'rb') 202 FileHandleIn.seek(0, 2) 203 InputFileSize = FileHandleIn.tell() 204 205 FileHandleOut = open(TempFile, 'rb') 206 FileHandleOut.seek(0, 2) 207 TempFileSize = FileHandleOut.tell() 208 209 Attribute = [] 210 HeaderLength = None 211 if self.ExtraHeaderSize != -1: 212 HeaderLength = str(self.ExtraHeaderSize) 213 214 if self.ProcessRequired == "NONE" and HeaderLength == None: 215 if TempFileSize > InputFileSize: 216 FileHandleIn.seek(0) 217 BufferIn = FileHandleIn.read() 218 FileHandleOut.seek(0) 219 BufferOut = FileHandleOut.read() 220 if BufferIn == BufferOut[TempFileSize - InputFileSize:]: 221 HeaderLength = str(TempFileSize - InputFileSize) 222 #auto sec guided attribute with process required 223 if HeaderLength == None: 224 Attribute.append('PROCESSING_REQUIRED') 225 226 FileHandleIn.close() 227 FileHandleOut.close() 228 229 if FirstCall and 'PROCESSING_REQUIRED' in Attribute: 230 # Guided data by -z option on first call is the process required data. Call the guided tool with the real option. 231 GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption) 232 233 # 234 # Call Gensection Add Section Header 235 # 236 if self.ProcessRequired in ("TRUE", "1"): 237 if 'PROCESSING_REQUIRED' not in Attribute: 238 Attribute.append('PROCESSING_REQUIRED') 239 240 if self.AuthStatusValid in ("TRUE", "1"): 241 Attribute.append('AUTH_STATUS_VALID') 242 GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'], 243 Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength) 244 OutputFileList = [] 245 OutputFileList.append(OutputFile) 246 if 'PROCESSING_REQUIRED' in Attribute: 247 # reset guided section alignment to none for the processed required guided data 248 self.Alignment = None 249 self.IncludeFvSection = False 250 self.ProcessRequired = "TRUE" 251 return OutputFileList, self.Alignment 252 253 254 255