1#!/usr/bin/env python 2# Copyright 2013 The Chromium Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""Wrapper script for launching application within the sel_ldr. 7""" 8 9import optparse 10import os 11import subprocess 12import sys 13 14import create_nmf 15import getos 16 17SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) 18NACL_SDK_ROOT = os.path.dirname(SCRIPT_DIR) 19 20if sys.version_info < (2, 6, 0): 21 sys.stderr.write("python 2.6 or later is required run this script\n") 22 sys.exit(1) 23 24 25class Error(Exception): 26 pass 27 28 29def Log(msg): 30 if Log.verbose: 31 sys.stderr.write(str(msg) + '\n') 32Log.verbose = False 33 34 35def FindQemu(): 36 qemu_locations = [os.path.join(SCRIPT_DIR, 'qemu_arm'), 37 os.path.join(SCRIPT_DIR, 'qemu-arm')] 38 qemu_locations += [os.path.join(path, 'qemu_arm') 39 for path in os.environ["PATH"].split(os.pathsep)] 40 qemu_locations += [os.path.join(path, 'qemu-arm') 41 for path in os.environ["PATH"].split(os.pathsep)] 42 # See if qemu is in any of these locations. 43 qemu_bin = None 44 for loc in qemu_locations: 45 if os.path.isfile(loc) and os.access(loc, os.X_OK): 46 qemu_bin = loc 47 break 48 return qemu_bin 49 50 51def main(argv): 52 usage = 'Usage: %prog [options] <.nexe>' 53 epilog = 'Example: sel_ldr.py my_nexe.nexe' 54 parser = optparse.OptionParser(usage, description=__doc__, epilog=epilog) 55 parser.add_option('-v', '--verbose', action='store_true', 56 help='Verbose output') 57 parser.add_option('-d', '--debug', action='store_true', 58 help='Enable debug stub') 59 parser.add_option('--debug-libs', action='store_true', 60 help='For dynamic executables, reference debug ' 61 'libraries rather then release') 62 63 # To enable bash completion for this command first install optcomplete 64 # and then add this line to your .bashrc: 65 # complete -F _optcomplete sel_ldr.py 66 try: 67 import optcomplete 68 optcomplete.autocomplete(parser) 69 except ImportError: 70 pass 71 72 options, args = parser.parse_args(argv) 73 if not args: 74 parser.error('No executable file specified') 75 76 nexe = args[0] 77 if options.verbose: 78 Log.verbose = True 79 80 osname = getos.GetPlatform() 81 if not os.path.exists(nexe): 82 raise Error('executable not found: %s' % nexe) 83 if not os.path.isfile(nexe): 84 raise Error('not a file: %s' % nexe) 85 86 arch, dynamic = create_nmf.ParseElfHeader(nexe) 87 88 if arch == 'arm' and osname != 'linux': 89 raise Error('Cannot run ARM executables under sel_ldr on ' + osname) 90 91 arch_suffix = arch.replace('-', '_') 92 93 sel_ldr = os.path.join(SCRIPT_DIR, 'sel_ldr_%s' % arch_suffix) 94 irt = os.path.join(SCRIPT_DIR, 'irt_core_%s.nexe' % arch_suffix) 95 if osname == 'win': 96 sel_ldr += '.exe' 97 Log('ROOT = %s' % NACL_SDK_ROOT) 98 Log('SEL_LDR = %s' % sel_ldr) 99 Log('IRT = %s' % irt) 100 cmd = [sel_ldr] 101 102 if osname == 'linux': 103 # Run sel_ldr under nacl_helper_bootstrap 104 helper = os.path.join(SCRIPT_DIR, 'nacl_helper_bootstrap_%s' % arch_suffix) 105 Log('HELPER = %s' % helper) 106 cmd.insert(0, helper) 107 cmd.append('--r_debug=0xXXXXXXXXXXXXXXXX') 108 cmd.append('--reserved_at_zero=0xXXXXXXXXXXXXXXXX') 109 110 cmd += ['-a', '-B', irt] 111 112 if options.debug: 113 cmd.append('-g') 114 115 if not options.verbose: 116 cmd += ['-l', os.devnull] 117 118 if arch == 'arm': 119 # Use the QEMU arm emulator if available. 120 qemu_bin = FindQemu() 121 if qemu_bin: 122 qemu = [qemu_bin, '-cpu', 'cortex-a8', '-L', 123 os.path.abspath(os.path.join(NACL_SDK_ROOT, 'toolchain', 124 'linux_arm_trusted'))] 125 # '-Q' disables platform qualification, allowing arm binaries to run. 126 cmd = qemu + cmd + ['-Q'] 127 else: 128 raise Error('Cannot run ARM executables under sel_ldr without an emulator' 129 '. Try installing QEMU (http://wiki.qemu.org/).') 130 131 if dynamic: 132 if options.debug_libs: 133 libpath = os.path.join(NACL_SDK_ROOT, 'lib', 134 'glibc_%s' % arch_suffix, 'Debug') 135 else: 136 libpath = os.path.join(NACL_SDK_ROOT, 'lib', 137 'glibc_%s' % arch_suffix, 'Release') 138 toolchain = '%s_x86_glibc' % osname 139 sdk_lib_dir = os.path.join(NACL_SDK_ROOT, 'toolchain', 140 toolchain, 'x86_64-nacl') 141 if arch == 'x86-64': 142 sdk_lib_dir = os.path.join(sdk_lib_dir, 'lib') 143 else: 144 sdk_lib_dir = os.path.join(sdk_lib_dir, 'lib32') 145 ldso = os.path.join(sdk_lib_dir, 'runnable-ld.so') 146 cmd.append(ldso) 147 Log('LD.SO = %s' % ldso) 148 libpath += ':' + sdk_lib_dir 149 cmd.append('--library-path') 150 cmd.append(libpath) 151 152 153 if args: 154 # Append arguments for the executable itself. 155 cmd += args 156 157 Log(cmd) 158 rtn = subprocess.call(cmd) 159 return rtn 160 161 162if __name__ == '__main__': 163 try: 164 sys.exit(main(sys.argv[1:])) 165 except Error as e: 166 sys.stderr.write(str(e) + '\n') 167 sys.exit(1) 168