17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#!/usr/bin/env python 27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Copyright 2013 The Chromium Authors. All rights reserved. 37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# Use of this source code is governed by a BSD-style license that can be 47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch# found in the LICENSE file. 57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch"""Wrapper script for launching application within the sel_ldr. 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch""" 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport optparse 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport os 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport subprocess 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport sys 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport create_nmf 157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochimport getos 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochSCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochNACL_SDK_ROOT = os.path.dirname(SCRIPT_DIR) 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochif sys.version_info < (2, 6, 0): 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sys.stderr.write("python 2.6 or later is required run this script\n") 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sys.exit(1) 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochclass Error(Exception): 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch pass 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochdef Log(msg): 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if Log.verbose: 317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sys.stderr.write(str(msg) + '\n') 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochLog.verbose = False 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)def FindQemu(): 36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) qemu_locations = [os.path.join(SCRIPT_DIR, 'qemu_arm'), 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) os.path.join(SCRIPT_DIR, 'qemu-arm')] 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) qemu_locations += [os.path.join(path, 'qemu_arm') 39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for path in os.environ["PATH"].split(os.pathsep)] 40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) qemu_locations += [os.path.join(path, 'qemu-arm') 41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for path in os.environ["PATH"].split(os.pathsep)] 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) # See if qemu is in any of these locations. 43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) qemu_bin = None 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for loc in qemu_locations: 45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if os.path.isfile(loc) and os.access(loc, os.X_OK): 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) qemu_bin = loc 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return qemu_bin 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochdef main(argv): 527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch usage = 'Usage: %prog [options] <.nexe>' 537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch epilog = 'Example: sel_ldr.py my_nexe.nexe' 540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) parser = optparse.OptionParser(usage, description=__doc__, epilog=epilog) 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch parser.add_option('-v', '--verbose', action='store_true', 567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch help='Verbose output') 577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch parser.add_option('-d', '--debug', action='store_true', 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch help='Enable debug stub') 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch parser.add_option('--debug-libs', action='store_true', 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch help='For dynamic executables, reference debug ' 617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 'libraries rather then release') 620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # To enable bash completion for this command first install optcomplete 640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # and then add this line to your .bashrc: 650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) # complete -F _optcomplete sel_ldr.py 660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) try: 670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) import optcomplete 680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) optcomplete.autocomplete(parser) 690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) except ImportError: 700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) pass 710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch options, args = parser.parse_args(argv) 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if not args: 747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch parser.error('No executable file specified') 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch nexe = args[0] 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if options.verbose: 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Log.verbose = True 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch osname = getos.GetPlatform() 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if not os.path.exists(nexe): 827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch raise Error('executable not found: %s' % nexe) 837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if not os.path.isfile(nexe): 847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch raise Error('not a file: %s' % nexe) 857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch arch, dynamic = create_nmf.ParseElfHeader(nexe) 877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if arch == 'arm' and osname != 'linux': 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise Error('Cannot run ARM executables under sel_ldr on ' + osname) 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch arch_suffix = arch.replace('-', '_') 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sel_ldr = os.path.join(SCRIPT_DIR, 'sel_ldr_%s' % arch_suffix) 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch irt = os.path.join(SCRIPT_DIR, 'irt_core_%s.nexe' % arch_suffix) 957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if osname == 'win': 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sel_ldr += '.exe' 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Log('ROOT = %s' % NACL_SDK_ROOT) 987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Log('SEL_LDR = %s' % sel_ldr) 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Log('IRT = %s' % irt) 100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cmd = [sel_ldr] 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if osname == 'linux': 103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # Run sel_ldr under nacl_helper_bootstrap 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch helper = os.path.join(SCRIPT_DIR, 'nacl_helper_bootstrap_%s' % arch_suffix) 1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Log('HELPER = %s' % helper) 1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cmd.insert(0, helper) 107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cmd.append('--r_debug=0xXXXXXXXXXXXXXXXX') 108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cmd.append('--reserved_at_zero=0xXXXXXXXXXXXXXXXX') 109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cmd += ['-a', '-B', irt] 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if options.debug: 113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cmd.append('-g') 114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if not options.verbose: 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cmd += ['-l', os.devnull] 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if arch == 'arm': 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) # Use the QEMU arm emulator if available. 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) qemu_bin = FindQemu() 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if qemu_bin: 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) qemu = [qemu_bin, '-cpu', 'cortex-a8', '-L', 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) os.path.abspath(os.path.join(NACL_SDK_ROOT, 'toolchain', 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 'linux_arm_trusted'))] 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) # '-Q' disables platform qualification, allowing arm binaries to run. 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) cmd = qemu + cmd + ['-Q'] 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) else: 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) raise Error('Cannot run ARM executables under sel_ldr without an emulator' 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) '. Try installing QEMU (http://wiki.qemu.org/).') 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if dynamic: 1323240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if options.debug_libs: 1333240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch libpath = os.path.join(NACL_SDK_ROOT, 'lib', 1343240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 'glibc_%s' % arch_suffix, 'Debug') 1353240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch else: 1363240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch libpath = os.path.join(NACL_SDK_ROOT, 'lib', 1373240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch 'glibc_%s' % arch_suffix, 'Release') 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch toolchain = '%s_x86_glibc' % osname 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sdk_lib_dir = os.path.join(NACL_SDK_ROOT, 'toolchain', 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch toolchain, 'x86_64-nacl') 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if arch == 'x86-64': 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sdk_lib_dir = os.path.join(sdk_lib_dir, 'lib') 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else: 1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sdk_lib_dir = os.path.join(sdk_lib_dir, 'lib32') 1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ldso = os.path.join(sdk_lib_dir, 'runnable-ld.so') 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cmd.append(ldso) 147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Log('LD.SO = %s' % ldso) 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch libpath += ':' + sdk_lib_dir 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cmd.append('--library-path') 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch cmd.append(libpath) 1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if args: 154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) # Append arguments for the executable itself. 155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cmd += args 156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Log(cmd) 1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch rtn = subprocess.call(cmd) 1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return rtn 1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochif __name__ == '__main__': 1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch try: 1647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sys.exit(main(sys.argv[1:])) 1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch except Error as e: 1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sys.stderr.write(str(e) + '\n') 1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sys.exit(1) 168