Files
chipsec-chipsec/chipsec_tools/edk2/PythonEFI/build/compilePythonEDK2.py
T
2019-08-15 14:11:20 -07:00

216 lines
8.9 KiB
Python

#CHIPSEC: Platform Security Assessment Framework
#Copyright (c) 2010-2016, Intel Corporation
#
#This program is free software; you can redistribute it and/or
#modify it under the terms of the GNU General Public License
#as published by the Free Software Foundation; Version 2.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#Contact information:
#chipsec@intel.com
#
import sys
import os
import shutil
import fnmatch
from distutils import dir_util
import subprocess
import platform
TARGET_X64 = 'X64'
TARGET_IA32 = 'IA32'
TARGET_I586 = 'i586'
TARGETS= [TARGET_X64 ,TARGET_IA32, TARGET_I586 ]
asmFiles = {TARGET_X64: 'cpu.asm',
TARGET_IA32: 'cpu_ia32.asm',
TARGET_I586: 'cpu_ia32_gcc.s'}
class PythonEDk2:
def __init__(self):
self.edk2_path = ''
self.target = TARGET_X64
self.is_linux = ("linux" == platform.system().lower())
def usage(self):
print "\nUSAGE: {:.65} --edk2 <edk2-path> [--target <target>]".format(sys.argv[0])
print "OPTIONS:"
print " -e, --edk2 specify path where edk2 exist in the local filesystem"
print " -t, --target one of X64, IA32, i586. if none is specified X64 is used"
print " "
print "NOTES:"
print " By default the tool chanins used are GCC46 for Linux and VS2012x86 for windows"
print " if you need to use a different toolchain please modify manually the EDKII file Conf/target.txt "
print " This script will not change the value unless the current value is MYTOOLS, in that case it will "
print " modify it to be the default values mentioned above."
def parse_args(self, argv):
import getopt
try:
opts, args = getopt.getopt(argv, "e:ht:",
["edk2=","help","target="])
except getopt.GetoptError as err:
print str(err)
self.usage()
return 1
for o, a in opts:
if o in ("-e", "--edk2"):
self.edk2_path = a
elif o in ("-h", "--help"):
self.usage()
return 0
elif o in ("-t", "--target"):
self.target = a
if len(self.edk2_path) <=0:
self.usage()
return 1
if self.target not in TARGETS:
print "\n\nERROR: Invalid target \"{}\". Valid targets are: {}".format(self.target, TARGETS)
return 1
if self.target == TARGET_I586 and not self.is_linux:
print"\n\nERROR: Target \"{}\" can only be compiled in linux".format(self.target)
return 1
return 0
def setupTarget(self):
efi_path = os.path.join(self.edk2_path,"AppPkg","Applications","Python","Efi")
for file in os.listdir('..'):
if fnmatch.fnmatch(file, '*.asm') or fnmatch.fnmatch(file, '*.s') or fnmatch.fnmatch(file, '*.c'):
print "copying {:60} to {}".format(file , efi_path)
shutil.copy(os.path.join(os.pardir,file) , efi_path)
print
py_mod = os.path.join(self.edk2_path,"AppPkg","Applications","Python","PyMod-2.7.2")
py_dir = os.path.join(self.edk2_path,"AppPkg","Applications","Python","Python-2.7.2")
print py_dir
#for dir in os.listdir(py_mod):
print "copying {:80} to {}".format(py_mod , py_dir)
reserve_mode=1
preserve_times=1,
preserve_symlinks=0
update=0
verbose=5
dry_run=0
dir_util.copy_tree(py_mod , py_dir, reserve_mode, preserve_times,
preserve_symlinks, update, verbose, dry_run)
print
import fileinput
# un-comment the line in AppPkg.dsc to compile python
AppPkg_dsc = os.path.join(self.edk2_path,"AppPkg","AppPkg.dsc")
for line in fileinput.input(AppPkg_dsc, inplace=True):
if line.strip().startswith('#') and 'PythonCore.inf' in line:
sys.stdout.write( line.replace('#','',1) )
else:
sys.stdout.write( line )
# add the assembly file to the sources for compilation
PythonCore_inf = os.path.join(self.edk2_path,"AppPkg","Applications","Python","PythonCore.inf")
in_sources= False
wrote_asm = False
for line in fileinput.input(PythonCore_inf, inplace=True):
if not in_sources:
if "[Sources]" in line:
in_sources = True
sys.stdout.write( line )
else:
if "cpu" in line:
sys.stdout.write ( " Efi/{}\n".format(asmFiles[self.target]))
wrote_asm = True
elif len(line.strip()) <= 1:
in_sources = False
if not wrote_asm:
sys.stdout.write ( " Efi/{}\n".format(asmFiles[self.target]))
sys.stdout.write( line )
else:
sys.stdout.write( line )
target_txt = os.path.join(self.edk2_path,"Conf","target.txt")
if self.is_linux: tool_chain_tag = "GCC46"
else: tool_chain_tag = "VS2012x86"
for line in fileinput.input(target_txt, inplace=True):
if "MYTOOLS" in line:
sys.stdout.write(line.replace("MYTOOLS",tool_chain_tag))
elif "MAX_CONCURRENT_THREAD_NUMBER" in line and "#" not in line:
sys.stdout.write("MAX_CONCURRENT_THREAD_NUMBER = 12\n")
elif line.startswith("TARGET"):
sys.stdout.write(line.replace("RELEASE", "DEBUG"))
else:
sys.stdout.write(line)
# un-comment pyexpath from config.c
config_c = os.path.join(self.edk2_path,"AppPkg","Applications","Python","Efi","config.c" )
for line in fileinput.input(config_c, inplace=True):
if line.strip().startswith('/') and ('pyexpat' in line or
'_md5' in line or
'_sha' in line or
'_sha256' in line or
'_sha512' in line):
sys.stdout.write( line.replace('/','',2) )
else:
sys.stdout.write( line )
march ='-march=i586'
tools_def = os.path.join(self.edk2_path,"Conf","tools_def.txt")
for line in fileinput.input(tools_def, inplace=True):
if line.strip().startswith("DEFINE GCC46_IA32_CC_FLAGS"):
if self.target == TARGET_I586:
if not march in line:
sys.stdout.write( "{} {}\n".format(line.strip(), march) )
else:
sys.stdout.write( line )
else:
if march in line:
sys.stdout.write( line.replace(march, '') )
else:
sys.stdout.write( line )
else:
sys.stdout.write( line )
def compile(self):
env = os.environ.copy()
print self.edk2_path
if self.is_linux:
ec = subprocess.call(['pwd' ], shell=True, stderr=subprocess.STDOUT, env = env, cwd = self.edk2_path)
ec = subprocess.call(['bash','-c','source edksetup.sh' ], stderr=subprocess.STDOUT, env = env, cwd = self.edk2_path)
else:
ec = subprocess.call(["edk2setup" ], shell=True, stderr=subprocess.STDOUT, env = env, cwd = self.edk2_path)
if ec == 0:
self.setupTarget()
env = os.environ.copy()
if self.is_linux:
ec = subprocess.call(["pwd"], shell=True, stderr=subprocess.STDOUT, env = env)
ec = subprocess.call(['bash', '-c',"chmod 775 build_edk2_python.sh",self.edk2_path, self.target ],stderr=subprocess.STDOUT, env = env)
ec = subprocess.call(["./build_edk2_python.sh",self.edk2_path, self.target ],stderr=subprocess.STDOUT, env = env)
else:
ec = subprocess.call(["build_edk2_python",self.edk2_path, self.target ], shell=True, stderr=subprocess.STDOUT, env = env)
print ec
return ec
if __name__ == "__main__":
pythonEDk2 = PythonEDk2()
ec = pythonEDk2.parse_args(sys.argv[1:])
if ec == 0:
ec = pythonEDk2.compile()
sys.exit(ec)