| Index: tests/translation_service/bc2nexe.py
|
| ===================================================================
|
| --- tests/translation_service/bc2nexe.py (revision 0)
|
| +++ tests/translation_service/bc2nexe.py (revision 0)
|
| @@ -0,0 +1,178 @@
|
| +import sys
|
| +import getopt
|
| +import subprocess
|
| +import tempfile
|
| +import time
|
| +def printUsage():
|
| + """Print usage string."""
|
| + print 'Usage: python bc2nexe.py --arch [x86-32,x86-64,arm] '\
|
| + '--output [out-file] in-file'
|
| +
|
| +def parseOpts():
|
| + """Parse program options and print usage string if necessary."""
|
| + try:
|
| + opts, args = getopt.getopt(sys.argv[1:], '', ['arch=', 'output='])
|
| + except getopt.GetoptError, e:
|
| + print e
|
| + printUsage()
|
| + sys.exit(0)
|
| + output = None
|
| + arch = None
|
| + for opt, arg in opts:
|
| + if opt == '--arch':
|
| + arch = arg
|
| + elif opt == '--output':
|
| + output = arg
|
| + if output is None:
|
| + print '--output parameter is not found'
|
| + printUsage()
|
| + sys.exit(1)
|
| + if arch is None:
|
| + print '--arch parameter is not found'
|
| + printUsage()
|
| + sys.exit(1)
|
| + return (output, arch, args)
|
| +
|
| +class Compiler(object):
|
| + """Compiles bitcode to nexe.'"""
|
| + def __init__(self, nacl):
|
| + """Compiler constructor.
|
| +
|
| + Args:
|
| + nacl: Path to the root of NaCl directory.
|
| + """
|
| + self._NaCl = nacl
|
| +
|
| + def _llc(self, files, arch, output):
|
| + """Convert bitcode files to assembler files.
|
| +
|
| + Args:
|
| + files: List of bitcode files.
|
| + arch: Cpu architecture. One of 'x86-32', 'x86-64', 'arm'.
|
| + output: Assembler file name.
|
| + """
|
| + if arch == 'x86-32':
|
| + params = ['-march=x86', '-mcpu=pentium4']
|
| + elif arch == 'x86-64':
|
| + params = ['-march=x86-64', '-mcpu=core2']
|
| + else:
|
| + params = [
|
| + '-march=arm',
|
| + '-mcpu=cortex-a8',
|
| + '-mattr=-neon',
|
| + '-mattr=+vfp3',
|
| + '-arm-reserve-r9',
|
| + '-sfi-cp-fudge',
|
| + '-sfi-cp-fudge-percent=75',
|
| + '-sfi-store',
|
| + '-sfi-stack',
|
| + '-sfi-branch',
|
| + '-sfi-data',
|
| + '-sfi-cp-disable-verify',
|
| + '-no-inline-jumptables']
|
| + return subprocess.call(
|
| + [self._toolchainBin + '/llc'] + params +
|
| + ['-o', output] + files)
|
| +
|
| + def _assemble(self, files, arch, output):
|
| + """Compile assembler code.
|
| +
|
| + Args:
|
| + files: List of assembler files.
|
| + arch: Cpu architecture. One of 'x86-32', 'x86-64', 'arm'.
|
| + output: Object file name.
|
| + """
|
| + if arch == 'x86-32':
|
| + bin = self._toolchainGcc + '/bin/nacl64-as'
|
| + params = ['--32', '--nacl-align', '5', '-n', '-mtune=i386']
|
| + elif arch == 'x86-64':
|
| + bin = self._toolchainGcc + '/bin/nacl64-as'
|
| + params = ['--64', '--nacl-align', '5', '-n', '-mtune=core2']
|
| + else:
|
| + bin = self._toolchainBin + '/arm-none-linux-gnueabi-as'
|
| + params = ['-mfpu=vfp3', '-march=armv7-a']
|
| + return subprocess.call(
|
| + [bin] + params + ['-o', output] + files)
|
| +
|
| + def _linkNEXE(self, files, output):
|
| + """Link object files and create *.nexe.
|
| +
|
| + Args:
|
| + files: List of object files.
|
| + output: *.nexe file name.
|
| + """
|
| + return subprocess.call(
|
| + [self._toolchainBin + '/arm-none-linux-gnueabi-ld',
|
| + '--native-client',
|
| + '-nostdlib',
|
| + '-T',
|
| + self._NaCl + '/native_client/tools/llvm/ld_script_x8664_untrusted',
|
| + '-static',
|
| + self._libPath + '/crt1.o',
|
| + self._libPath + '/crti.o',
|
| + self._libPath + '/crtbegin.o'] +
|
| + files +
|
| + [self._libPathBC + '/libc.a',
|
| + self._libPathBC + '/libnacl.a',
|
| + self._libPath + '/libcrt_platform.a',
|
| + self._libPath + '/crtn.o',
|
| + '-lgcc',
|
| + '-L' + self._libPath,
|
| + '-o',
|
| + output])
|
| +
|
| + def _initPaths(self, arch):
|
| + """Initialize paths to important directories.
|
| +
|
| + Args:
|
| + arch: Cpu architecture. One of 'x86-32', 'x86-64', 'arm'.
|
| + """
|
| + self._toolchain = self._NaCl + \
|
| + '/native_client/toolchain/linux_arm-untrusted'
|
| + self._toolchainBin = self._toolchain + '/arm-none-linux-gnueabi/bin'
|
| + if arch == 'x86-32':
|
| + self._libPath = self._toolchain + '/libs-x8632'
|
| + elif arch == 'x86-64':
|
| + self._libPath = self._toolchain + '/libs-x8664'
|
| + else:
|
| + self._libPath = self._toolchain + '/libs-arm'
|
| + self._libPathBC = self._libPath + '-bc'
|
| + self._toolchainGcc = self._NaCl + '/native_client/toolchain/linux_x86'
|
| +
|
| + def generateNEXE(self, files, arch, output):
|
| + """Generate *.nexe from bitcode files.
|
| +
|
| + Args:
|
| + files: List of bitcode files
|
| + arch: Cpu architecture. One of 'x86-32', 'x86-64', 'arm'.
|
| + output: *.nexe file name.
|
| + """
|
| + self._initPaths(arch)
|
| + tmpASfile = tempfile.NamedTemporaryFile()
|
| + try:
|
| + t0 = time.time()
|
| + if self._llc(files, arch, tmpASfile.name) != 0:
|
| + raise TranslateError('error while code generating')
|
| + print "llc", "%.3f" % (time.time() - t0)
|
| + tmpOfile = tempfile.NamedTemporaryFile()
|
| + try:
|
| + t0 = time.time()
|
| + if self._assemble([tmpASfile.name], arch, tmpOfile.name) != 0:
|
| + raise TranslateError('error while assembling')
|
| + print "asm", "%.3f" % (time.time() - t0)
|
| + t0 = time.time()
|
| + if self._linkNEXE([tmpOfile.name], output) != 0:
|
| + raise TranslateError('error while linking nexe')
|
| + print "link", "%.3f" % (time.time() - t0)
|
| + finally:
|
| + tmpOfile.close()
|
| + finally:
|
| + tmpASfile.close()
|
| +
|
| +class TranslateError(Exception):
|
| + """Exception when one of the compile stages returns non-zero."""
|
| + pass
|
| +
|
| +if __name__ == '__main__':
|
| + output, arch, args = parseOpts()
|
| + Compiler('../../../').generateNEXE(args, arch, output)
|
|
|
| Property changes on: tests/translation_service/bc2nexe.py
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|