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