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 |