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 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.
43 for loc
in qemu_locations
:
44 if os
.path
.isfile(loc
) and os
.access(loc
, os
.X_OK
):
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 '
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
76 optcomplete
.autocomplete(parser
)
80 options
= parser
.parse_args(argv
)
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
)
102 Log('ROOT = %s' % NACL_SDK_ROOT
)
103 Log('SEL_LDR = %s' % sel_ldr
)
104 Log('IRT = %s' % irt
)
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
125 if 'NACLVERBOSITY' not in os
.environ
and not options
.verbose
:
126 os
.environ
['NACLVERBOSITY'] = "-3"
131 if options
.exceptions
:
134 if options
.passthrough_environment
:
137 if elf_arch
== 'arm':
138 # Use the QEMU arm emulator if available.
139 qemu_bin
= FindQemu()
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']
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':
164 elif elf_arch
== 'arm':
169 elif elf_arch
== 'x86-32':
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')
199 cmd
.append('LD_LIBRARY_PATH=%s' % libpath
)
201 cmd
.append('--interp-prefix')
202 cmd
.append(interp_prefix
)
204 ldso
= os
.path
.join(lib_dir
, 'runnable-ld.so')
206 cmd
.append('--library-path')
208 Log('dynamic loader = %s' % ldso
)
211 # Append arguments for the executable itself.
212 cmd
.append(options
.executable
)
216 return subprocess
.call(cmd
)
219 if __name__
== '__main__':
221 sys
.exit(main(sys
.argv
[1:]))
223 sys
.stderr
.write(str(e
) + '\n')