1## @file 2# process rule section generation 3# 4# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> 5# 6# SPDX-License-Identifier: BSD-2-Clause-Patent 7# 8 9## 10# Import Modules 11# 12from __future__ import absolute_import 13from struct import * 14from . import Section 15from .GenFdsGlobalVariable import GenFdsGlobalVariable 16import subprocess 17from .Ffs import SectionSuffix 18import Common.LongFilePathOs as os 19from CommonDataClass.FdfClass import EfiSectionClassObject 20from Common import EdkLogger 21from Common.BuildToolError import * 22from Common.Misc import PeImageClass 23from Common.LongFilePathSupport import OpenLongFilePath as open 24from Common.LongFilePathSupport import CopyLongFilePath 25from Common.DataType import * 26 27## generate rule section 28# 29# 30class EfiSection (EfiSectionClassObject): 31 32 ## The constructor 33 # 34 # @param self The object pointer 35 # 36 def __init__(self): 37 EfiSectionClassObject.__init__(self) 38 39 ## GenSection() method 40 # 41 # Generate rule section 42 # 43 # @param self The object pointer 44 # @param OutputPath Where to place output file 45 # @param ModuleName Which module this section belongs to 46 # @param SecNum Index of section 47 # @param KeyStringList Filter for inputs of section generation 48 # @param FfsInf FfsInfStatement object that contains this section data 49 # @param Dict dictionary contains macro and its value 50 # @retval tuple (Generated file name list, section alignment) 51 # 52 def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = None, IsMakefile = False) : 53 54 if self.FileName is not None and self.FileName.startswith('PCD('): 55 self.FileName = GenFdsGlobalVariable.GetPcdValue(self.FileName) 56 """Prepare the parameter of GenSection""" 57 if FfsInf is not None : 58 InfFileName = FfsInf.InfFileName 59 SectionType = FfsInf.__ExtendMacro__(self.SectionType) 60 Filename = FfsInf.__ExtendMacro__(self.FileName) 61 BuildNum = FfsInf.__ExtendMacro__(self.BuildNum) 62 StringData = FfsInf.__ExtendMacro__(self.StringData) 63 ModuleNameStr = FfsInf.__ExtendMacro__('$(MODULE_NAME)') 64 NoStrip = True 65 if FfsInf.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE) and SectionType in (BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32): 66 if FfsInf.KeepReloc is not None: 67 NoStrip = FfsInf.KeepReloc 68 elif FfsInf.KeepRelocFromRule is not None: 69 NoStrip = FfsInf.KeepRelocFromRule 70 elif self.KeepReloc is not None: 71 NoStrip = self.KeepReloc 72 elif FfsInf.ShadowFromInfFile is not None: 73 NoStrip = FfsInf.ShadowFromInfFile 74 else: 75 EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s apply rule for None!" %ModuleName) 76 77 """If the file name was pointed out, add it in FileList""" 78 FileList = [] 79 if Dict is None: 80 Dict = {} 81 if Filename is not None: 82 Filename = GenFdsGlobalVariable.MacroExtend(Filename, Dict) 83 # check if the path is absolute or relative 84 if os.path.isabs(Filename): 85 Filename = os.path.normpath(Filename) 86 else: 87 Filename = os.path.normpath(os.path.join(FfsInf.EfiOutputPath, Filename)) 88 89 if not self.Optional: 90 FileList.append(Filename) 91 elif os.path.exists(Filename): 92 FileList.append(Filename) 93 elif IsMakefile: 94 SuffixMap = FfsInf.GetFinalTargetSuffixMap() 95 if '.depex' in SuffixMap: 96 FileList.append(Filename) 97 else: 98 FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FileType, self.FileExtension, Dict, IsMakefile=IsMakefile, SectionType=SectionType) 99 if IsSect : 100 return FileList, self.Alignment 101 102 Index = 0 103 Align = self.Alignment 104 105 """ If Section type is 'VERSION'""" 106 OutputFileList = [] 107 if SectionType == 'VERSION': 108 109 InfOverrideVerString = False 110 if FfsInf.Version is not None: 111 #StringData = FfsInf.Version 112 BuildNum = FfsInf.Version 113 InfOverrideVerString = True 114 115 if InfOverrideVerString: 116 #VerTuple = ('-n', '"' + StringData + '"') 117 if BuildNum is not None and BuildNum != '': 118 BuildNumTuple = ('-j', BuildNum) 119 else: 120 BuildNumTuple = tuple() 121 122 Num = SecNum 123 OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType)) 124 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', 125 #Ui=StringData, 126 Ver=BuildNum, 127 IsMakefile=IsMakefile) 128 OutputFileList.append(OutputFile) 129 130 elif FileList != []: 131 for File in FileList: 132 Index = Index + 1 133 Num = '%s.%d' %(SecNum, Index) 134 OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType)) 135 f = open(File, 'r') 136 VerString = f.read() 137 f.close() 138 BuildNum = VerString 139 if BuildNum is not None and BuildNum != '': 140 BuildNumTuple = ('-j', BuildNum) 141 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', 142 #Ui=VerString, 143 Ver=BuildNum, 144 IsMakefile=IsMakefile) 145 OutputFileList.append(OutputFile) 146 147 else: 148 BuildNum = StringData 149 if BuildNum is not None and BuildNum != '': 150 BuildNumTuple = ('-j', BuildNum) 151 else: 152 BuildNumTuple = tuple() 153 BuildNumString = ' ' + ' '.join(BuildNumTuple) 154 155 #if VerString == '' and 156 if BuildNumString == '': 157 if self.Optional == True : 158 GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!") 159 return [], None 160 else: 161 EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss Version Section value" %InfFileName) 162 Num = SecNum 163 OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType)) 164 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', 165 #Ui=VerString, 166 Ver=BuildNum, 167 IsMakefile=IsMakefile) 168 OutputFileList.append(OutputFile) 169 170 # 171 # If Section Type is BINARY_FILE_TYPE_UI 172 # 173 elif SectionType == BINARY_FILE_TYPE_UI: 174 175 InfOverrideUiString = False 176 if FfsInf.Ui is not None: 177 StringData = FfsInf.Ui 178 InfOverrideUiString = True 179 180 if InfOverrideUiString: 181 Num = SecNum 182 if IsMakefile and StringData == ModuleNameStr: 183 StringData = "$(MODULE_NAME)" 184 OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType)) 185 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', 186 Ui=StringData, IsMakefile=IsMakefile) 187 OutputFileList.append(OutputFile) 188 189 elif FileList != []: 190 for File in FileList: 191 Index = Index + 1 192 Num = '%s.%d' %(SecNum, Index) 193 OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType)) 194 f = open(File, 'r') 195 UiString = f.read() 196 f.close() 197 if IsMakefile and UiString == ModuleNameStr: 198 UiString = "$(MODULE_NAME)" 199 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', 200 Ui=UiString, IsMakefile=IsMakefile) 201 OutputFileList.append(OutputFile) 202 else: 203 if StringData is not None and len(StringData) > 0: 204 UiTuple = ('-n', '"' + StringData + '"') 205 else: 206 UiTuple = tuple() 207 208 if self.Optional == True : 209 GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!") 210 return '', None 211 else: 212 EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss UI Section value" %InfFileName) 213 214 Num = SecNum 215 if IsMakefile and StringData == ModuleNameStr: 216 StringData = "$(MODULE_NAME)" 217 OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType)) 218 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', 219 Ui=StringData, IsMakefile=IsMakefile) 220 OutputFileList.append(OutputFile) 221 222 # 223 # If Section Type is BINARY_FILE_TYPE_RAW 224 # 225 elif SectionType == BINARY_FILE_TYPE_RAW: 226 """If File List is empty""" 227 if FileList == []: 228 if self.Optional == True: 229 GenFdsGlobalVariable.VerboseLogger("Optional Section don't exist!") 230 return [], None 231 else: 232 EdkLogger.error("GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName)) 233 234 elif len(FileList) > 1: 235 EdkLogger.error("GenFds", GENFDS_ERROR, 236 "Files suffixed with %s are not allowed to have more than one file in %s[Binaries] section" % ( 237 self.FileExtension, InfFileName)) 238 else: 239 for File in FileList: 240 File = GenFdsGlobalVariable.MacroExtend(File, Dict) 241 OutputFileList.append(File) 242 243 else: 244 """If File List is empty""" 245 if FileList == [] : 246 if self.Optional == True: 247 GenFdsGlobalVariable.VerboseLogger("Optional Section don't exist!") 248 return [], None 249 else: 250 EdkLogger.error("GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName)) 251 252 else: 253 """Convert the File to Section file one by one """ 254 for File in FileList: 255 """ Copy Map file to FFS output path """ 256 Index = Index + 1 257 Num = '%s.%d' %(SecNum, Index) 258 OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType)) 259 File = GenFdsGlobalVariable.MacroExtend(File, Dict) 260 261 #Get PE Section alignment when align is set to AUTO 262 if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_TE): 263 ImageObj = PeImageClass (File) 264 if ImageObj.SectionAlignment < 0x400: 265 Align = str (ImageObj.SectionAlignment) 266 elif ImageObj.SectionAlignment < 0x100000: 267 Align = str (ImageObj.SectionAlignment // 0x400) + 'K' 268 else: 269 Align = str (ImageObj.SectionAlignment // 0x100000) + 'M' 270 271 if File[(len(File)-4):] == '.efi' and FfsInf.InfModule.BaseName == os.path.basename(File)[:-4]: 272 MapFile = File.replace('.efi', '.map') 273 CopyMapFile = os.path.join(OutputPath, ModuleName + '.map') 274 if IsMakefile: 275 if GenFdsGlobalVariable.CopyList == []: 276 GenFdsGlobalVariable.CopyList = [(MapFile, CopyMapFile)] 277 else: 278 GenFdsGlobalVariable.CopyList.append((MapFile, CopyMapFile)) 279 else: 280 if os.path.exists(MapFile): 281 if not os.path.exists(CopyMapFile) or \ 282 (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)): 283 CopyLongFilePath(MapFile, CopyMapFile) 284 285 if not NoStrip: 286 FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi') 287 if IsMakefile: 288 if GenFdsGlobalVariable.CopyList == []: 289 GenFdsGlobalVariable.CopyList = [(File, FileBeforeStrip)] 290 else: 291 GenFdsGlobalVariable.CopyList.append((File, FileBeforeStrip)) 292 else: 293 if not os.path.exists(FileBeforeStrip) or \ 294 (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)): 295 CopyLongFilePath(File, FileBeforeStrip) 296 StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped') 297 GenFdsGlobalVariable.GenerateFirmwareImage( 298 StrippedFile, 299 [File], 300 Strip=True, 301 IsMakefile = IsMakefile 302 ) 303 File = StrippedFile 304 305 """For TE Section call GenFw to generate TE image""" 306 307 if SectionType == BINARY_FILE_TYPE_TE: 308 TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw') 309 GenFdsGlobalVariable.GenerateFirmwareImage( 310 TeFile, 311 [File], 312 Type='te', 313 IsMakefile = IsMakefile 314 ) 315 File = TeFile 316 317 """Call GenSection""" 318 GenFdsGlobalVariable.GenerateSection(OutputFile, 319 [File], 320 Section.Section.SectionType.get (SectionType), 321 IsMakefile=IsMakefile 322 ) 323 OutputFileList.append(OutputFile) 324 325 return OutputFileList, Align 326