Linux: Depend on liberation-fonts package for RPMs.
[chromium-blink-merge.git] / native_client_sdk / src / tools / sel_ldr.py
blob54617571e5f7d6a3ff35366707b71be876531a87
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.
6 """Wrapper script for launching application within the sel_ldr.
7 """
9 import argparse
10 import os
11 import subprocess
12 import sys
14 import create_nmf
15 import getos
17 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
18 NACL_SDK_ROOT = os.path.dirname(SCRIPT_DIR)
20 if sys.version_info < (2, 7, 0):
21 sys.stderr.write("python 2.7 or later is required run this script\n")
22 sys.exit(1)
25 class Error(Exception):
26 pass
29 def Log(msg):
30 if Log.verbose:
31 sys.stderr.write(str(msg) + '\n')
32 Log.verbose = False
35 def FindQemu():
36 path = os.environ.get('PATH', '').split(os.pathsep)
37 qemu_locations = [os.path.join(SCRIPT_DIR, 'qemu_arm'),
38 os.path.join(SCRIPT_DIR, 'qemu-arm')]
39 qemu_locations += [os.path.join(p, 'qemu_arm') for p in path]
40 qemu_locations += [os.path.join(p, 'qemu-arm') for p in path]
41 # See if qemu is in any of these locations.
42 qemu_bin = None
43 for loc in qemu_locations:
44 if os.path.isfile(loc) and os.access(loc, os.X_OK):
45 qemu_bin = loc
46 break
47 return qemu_bin
50 def main(argv):
51 epilog = 'Example: sel_ldr.py my_nexe.nexe'
52 parser = argparse.ArgumentParser(description=__doc__, epilog=epilog)
53 parser.add_argument('-v', '--verbose', action='store_true',
54 help='Verbose output')
55 parser.add_argument('-d', '--debug', action='store_true',
56 help='Enable debug stub')
57 parser.add_argument('-e', '--exceptions', action='store_true',
58 help='Enable exception handling interface')
59 parser.add_argument('-p', '--passthrough-environment', action='store_true',
60 help='Pass environment of host through to nexe')
61 parser.add_argument('--debug-libs', action='store_true',
62 help='Legacy option, do not use')
63 parser.add_argument('--config', default='Release',
64 help='Use a particular library configuration (normally '
65 'Debug or Release)')
66 parser.add_argument('executable', help='executable (.nexe) to run')
67 parser.add_argument('args', nargs='*', help='argument to pass to exectuable')
68 parser.add_argument('--library-path',
69 help='Pass extra library paths')
71 # To enable bash completion for this command first install optcomplete
72 # and then add this line to your .bashrc:
73 # complete -F _optcomplete sel_ldr.py
74 try:
75 import optcomplete
76 optcomplete.autocomplete(parser)
77 except ImportError:
78 pass
80 options = parser.parse_args(argv)
82 if options.verbose:
83 Log.verbose = True
85 osname = getos.GetPlatform()
86 if not os.path.exists(options.executable):
87 raise Error('executable not found: %s' % options.executable)
88 if not os.path.isfile(options.executable):
89 raise Error('not a file: %s' % options.executable)
91 elf_arch, dynamic = create_nmf.ParseElfHeader(options.executable)
93 if elf_arch == 'arm' and osname != 'linux':
94 raise Error('Cannot run ARM executables under sel_ldr on ' + osname)
96 arch_suffix = elf_arch.replace('-', '_')
98 sel_ldr = os.path.join(SCRIPT_DIR, 'sel_ldr_%s' % arch_suffix)
99 irt = os.path.join(SCRIPT_DIR, 'irt_core_%s.nexe' % arch_suffix)
100 if osname == 'win':
101 sel_ldr += '.exe'
102 Log('ROOT = %s' % NACL_SDK_ROOT)
103 Log('SEL_LDR = %s' % sel_ldr)
104 Log('IRT = %s' % irt)
105 cmd = [sel_ldr]
107 if osname == 'linux':
108 # Run sel_ldr under nacl_helper_bootstrap
109 helper = os.path.join(SCRIPT_DIR, 'nacl_helper_bootstrap_%s' % arch_suffix)
110 Log('HELPER = %s' % helper)
111 cmd.insert(0, helper)
112 cmd.append('--r_debug=0xXXXXXXXXXXXXXXXX')
113 cmd.append('--reserved_at_zero=0xXXXXXXXXXXXXXXXX')
115 # This script is provided mostly as way to run binaries during testing, not
116 # to run untrusted code in a production environment. As such we want it be
117 # as invisible as possible. So we pass -q (quiet) to disable most of output
118 # of sel_ldr itself, and -a (disable ACL) to enable local filesystem access.
119 cmd += ['-q', '-a', '-B', irt]
121 # Set the default NACLVERBOSITY level LOG_ERROR (-3). This can still be
122 # overridden in the environment if debug information is desired. However
123 # in most cases we don't want the application stdout/stderr polluted with
124 # sel_ldr logging.
125 if 'NACLVERBOSITY' not in os.environ and not options.verbose:
126 os.environ['NACLVERBOSITY'] = "-3"
128 if options.debug:
129 cmd.append('-g')
131 if options.exceptions:
132 cmd.append('-e')
134 if options.passthrough_environment:
135 cmd.append('-p')
137 if elf_arch == 'arm':
138 # Use the QEMU arm emulator if available.
139 qemu_bin = FindQemu()
140 if not qemu_bin:
141 raise Error('Cannot run ARM executables under sel_ldr without an emulator'
142 '. Try installing QEMU (http://wiki.qemu.org/).')
144 arm_libpath = os.path.join(NACL_SDK_ROOT, 'tools', 'lib', 'arm_trusted')
145 if not os.path.isdir(arm_libpath):
146 raise Error('Could not find ARM library path: %s' % arm_libpath)
147 qemu = [qemu_bin, '-cpu', 'cortex-a8', '-L', arm_libpath]
148 # '-Q' disables platform qualification, allowing arm binaries to run.
149 cmd = qemu + cmd + ['-Q']
151 if dynamic:
152 if options.debug_libs:
153 sys.stderr.write('warning: --debug-libs is deprecated (use --config).\n')
154 options.config = 'Debug'
156 sdk_lib_dir = os.path.join(NACL_SDK_ROOT, 'lib',
157 'glibc_%s' % arch_suffix, options.config)
159 if elf_arch == 'x86-64':
160 lib_subdir = 'lib'
161 tcarch = 'x86'
162 tcsubarch = 'x86_64'
163 usr_arch = 'x86_64'
164 elif elf_arch == 'arm':
165 lib_subdir = 'lib'
166 tcarch = 'arm'
167 tcsubarch = 'arm'
168 usr_arch = 'arm'
169 elif elf_arch == 'x86-32':
170 lib_subdir = 'lib32'
171 tcarch = 'x86'
172 tcsubarch = 'x86_64'
173 usr_arch = 'i686'
174 else:
175 raise Error("Unknown arch: %s" % elf_arch)
177 toolchain = '%s_%s_glibc' % (osname, tcarch)
178 toolchain_dir = os.path.join(NACL_SDK_ROOT, 'toolchain', toolchain)
179 interp_prefix = os.path.join(toolchain_dir, tcsubarch + '-nacl')
180 lib_dir = os.path.join(interp_prefix, lib_subdir)
181 usr_lib_dir = os.path.join(toolchain_dir, usr_arch + '-nacl', 'usr', 'lib')
183 libpath = [usr_lib_dir, sdk_lib_dir, lib_dir]
185 if options.config not in ['Debug', 'Release']:
186 config_fallback = 'Release'
187 if 'Debug' in options.config:
188 config_fallback = 'Debug'
189 libpath.append(os.path.join(NACL_SDK_ROOT, 'lib',
190 'glibc_%s' % arch_suffix, config_fallback))
192 if options.library_path:
193 libpath.extend([os.path.abspath(p) for p
194 in options.library_path.split(':')])
195 libpath = ':'.join(libpath)
196 if elf_arch == 'arm':
197 ldso = os.path.join(SCRIPT_DIR, 'elf_loader_arm.nexe')
198 cmd.append('-E')
199 cmd.append('LD_LIBRARY_PATH=%s' % libpath)
200 cmd.append(ldso)
201 cmd.append('--interp-prefix')
202 cmd.append(interp_prefix)
203 else:
204 ldso = os.path.join(lib_dir, 'runnable-ld.so')
205 cmd.append(ldso)
206 cmd.append('--library-path')
207 cmd.append(libpath)
208 Log('dynamic loader = %s' % ldso)
211 # Append arguments for the executable itself.
212 cmd.append(options.executable)
213 cmd += options.args
215 Log(cmd)
216 return subprocess.call(cmd)
219 if __name__ == '__main__':
220 try:
221 sys.exit(main(sys.argv[1:]))
222 except Error as e:
223 sys.stderr.write(str(e) + '\n')
224 sys.exit(1)