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.
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")
25 class Error(Exception):
31 sys
.stderr
.write(str(msg
) + '\n')
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.
44 for loc
in qemu_locations
:
45 if os
.path
.isfile(loc
) and os
.access(loc
, os
.X_OK
):
52 epilog
= 'Example: sel_ldr.py my_nexe.nexe'
53 parser
= argparse
.ArgumentParser(description
=__doc__
, epilog
=epilog
)
54 parser
.add_argument('-v', '--verbose', action
='store_true',
55 help='Verbose output')
56 parser
.add_argument('-d', '--debug', action
='store_true',
57 help='Enable debug stub')
58 parser
.add_argument('-e', '--exceptions', action
='store_true',
59 help='Enable exception handling interface')
60 parser
.add_argument('-p', '--passthrough-environment', action
='store_true',
61 help='Pass environment of host through to nexe')
62 parser
.add_argument('--debug-libs', action
='store_true',
63 help='Legacy option, do not use')
64 parser
.add_argument('--config', default
='Release',
65 help='Use a particular library configuration (normally '
67 parser
.add_argument('executable', help='executable (.nexe) to run')
68 parser
.add_argument('args', nargs
='*', help='argument to pass to exectuable')
69 parser
.add_argument('--library-path',
70 help='Pass extra library paths')
72 # To enable bash completion for this command first install optcomplete
73 # and then add this line to your .bashrc:
74 # complete -F _optcomplete sel_ldr.py
77 optcomplete
.autocomplete(parser
)
81 options
= parser
.parse_args(argv
)
86 osname
= getos
.GetPlatform()
87 if not os
.path
.exists(options
.executable
):
88 raise Error('executable not found: %s' % options
.executable
)
89 if not os
.path
.isfile(options
.executable
):
90 raise Error('not a file: %s' % options
.executable
)
92 elf_arch
, dynamic
= create_nmf
.ParseElfHeader(options
.executable
)
94 if elf_arch
== 'arm' and osname
!= 'linux':
95 raise Error('Cannot run ARM executables under sel_ldr on ' + osname
)
97 arch_suffix
= elf_arch
.replace('-', '_')
99 sel_ldr
= os
.path
.join(SCRIPT_DIR
, 'sel_ldr_%s' % arch_suffix
)
100 irt
= os
.path
.join(SCRIPT_DIR
, 'irt_core_%s.nexe' % arch_suffix
)
103 Log('ROOT = %s' % NACL_SDK_ROOT
)
104 Log('SEL_LDR = %s' % sel_ldr
)
105 Log('IRT = %s' % irt
)
108 if osname
== 'linux':
109 # Run sel_ldr under nacl_helper_bootstrap
110 helper
= os
.path
.join(SCRIPT_DIR
, 'nacl_helper_bootstrap_%s' % arch_suffix
)
111 Log('HELPER = %s' % helper
)
112 cmd
.insert(0, helper
)
113 cmd
.append('--r_debug=0xXXXXXXXXXXXXXXXX')
114 cmd
.append('--reserved_at_zero=0xXXXXXXXXXXXXXXXX')
116 # This script is provided mostly as way to run binaries during testing, not
117 # to run untrusted code in a production environment. As such we want it be
118 # as invisible as possible. So we pass -q (quiet) to disable most of output
119 # of sel_ldr itself, and -a (disable ACL) to enable local filesystem access.
120 cmd
+= ['-q', '-a', '-B', irt
]
122 # Set the default NACLVERBOSITY level LOG_ERROR (-3). This can still be
123 # overridden in the environment if debug information is desired. However
124 # in most cases we don't want the application stdout/stderr polluted with
126 if 'NACLVERBOSITY' not in os
.environ
and not options
.verbose
:
127 os
.environ
['NACLVERBOSITY'] = "-3"
132 if options
.exceptions
:
135 if options
.passthrough_environment
:
138 if elf_arch
== 'arm':
139 # Use the QEMU arm emulator if available.
140 qemu_bin
= FindQemu()
142 raise Error('Cannot run ARM executables under sel_ldr without an emulator'
143 '. Try installing QEMU (http://wiki.qemu.org/).')
145 arm_libpath
= os
.path
.join(NACL_SDK_ROOT
, 'tools', 'lib', 'arm_trusted')
146 if not os
.path
.isdir(arm_libpath
):
147 raise Error('Could not find ARM library path: %s' % arm_libpath
)
148 qemu
= [qemu_bin
, '-cpu', 'cortex-a8', '-L', arm_libpath
]
149 # '-Q' disables platform qualification, allowing arm binaries to run.
150 cmd
= qemu
+ cmd
+ ['-Q']
153 if options
.debug_libs
:
154 sys
.stderr
.write('warning: --debug-libs is deprecated (use --config).\n')
155 options
.config
= 'Debug'
157 sdk_lib_dir
= os
.path
.join(NACL_SDK_ROOT
, 'lib',
158 'glibc_%s' % arch_suffix
, options
.config
)
160 if elf_arch
== 'x86-64':
165 elif elf_arch
== 'arm':
170 elif elf_arch
== 'x86-32':
176 raise Error("Unknown arch: %s" % elf_arch
)
178 toolchain
= '%s_%s_glibc' % (osname
, tcarch
)
179 toolchain_dir
= os
.path
.join(NACL_SDK_ROOT
, 'toolchain', toolchain
)
180 interp_prefix
= os
.path
.join(toolchain_dir
, tcsubarch
+ '-nacl')
181 lib_dir
= os
.path
.join(interp_prefix
, lib_subdir
)
182 usr_lib_dir
= os
.path
.join(toolchain_dir
, usr_arch
+ '-nacl', 'usr', 'lib')
184 libpath
= [usr_lib_dir
, sdk_lib_dir
, lib_dir
]
186 if options
.config
not in ['Debug', 'Release']:
187 config_fallback
= 'Release'
188 if 'Debug' in options
.config
:
189 config_fallback
= 'Debug'
190 libpath
.append(os
.path
.join(NACL_SDK_ROOT
, 'lib',
191 'glibc_%s' % arch_suffix
, config_fallback
))
193 if options
.library_path
:
194 libpath
.extend([os
.path
.abspath(p
) for p
195 in options
.library_path
.split(':')])
196 libpath
= ':'.join(libpath
)
197 if elf_arch
== 'arm':
198 ldso
= os
.path
.join(SCRIPT_DIR
, 'elf_loader_arm.nexe')
200 cmd
.append('LD_LIBRARY_PATH=%s' % libpath
)
202 cmd
.append('--interp-prefix')
203 cmd
.append(interp_prefix
)
205 ldso
= os
.path
.join(lib_dir
, 'runnable-ld.so')
207 cmd
.append('--library-path')
209 Log('dynamic loader = %s' % ldso
)
212 # Append arguments for the executable itself.
213 cmd
.append(options
.executable
)
217 return subprocess
.call(cmd
)
220 if __name__
== '__main__':
222 sys
.exit(main(sys
.argv
[1:]))
224 sys
.stderr
.write(str(e
) + '\n')