2 # Copyright (c) 2012 The Native Client 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.
11 env.Append(CPPPATH=['${TARGET_ROOT}/gen'])
13 # normally comment out -- uncomment out to test the pedantic removal
15 #if env.Bit('linux') or env.Bit('mac'):
16 # env.FilterOut(CCFLAGS=['-pedantic'])
17 # env.FilterOut(CCFLAGS=['-Wall'])
19 if env.Bit('windows'):
20 syscall_impl = 'win/nacl_syscall_impl.c'
22 syscall_impl = 'posix/nacl_syscall_impl.c'
26 GENERATED='${TARGET_ROOT}/gen/native_client/src/trusted/service_runtime'
27 env.Command(target=env.File(GENERATED + '/nacl_syscall_handlers.c'),
28 source=[syscall_impl, 'nacl_syscall_handlers_gen.py'],
29 action=[Action('${PYTHON} ${SOURCES[1]} ${SYSCALL_GEN_FLAGS}'
30 ' -i ${SOURCE} -o ${TARGET}'),
35 # ----------------------------------------------------------
36 # TODO(robertm): this library is too big and needs to be split up
37 # for easier unit testing
44 'nacl_bootstrap_channel_error_reporter.c',
46 'nacl_desc_effector_ldr.c',
47 'nacl_desc_postmessage.c',
49 'nacl_error_log_hook.c',
51 'nacl_kernel_service.c',
53 'nacl_reverse_host_interface.c',
54 'nacl_reverse_quota_interface.c',
55 'nacl_runtime_host_interface.c',
56 'nacl_secure_service.c',
57 'nacl_signal_common.c',
58 'nacl_stack_safety.c',
59 'nacl_syscall_common.c',
60 GENERATED + '/nacl_syscall_handlers.c',
61 'nacl_syscall_hook.c',
63 'nacl_valgrind_hooks.c',
64 'name_service/default_name_service.c',
65 'name_service/name_service.c',
69 'sel_ldr_thread_interface.c',
72 'sel_validate_image.c',
78 'sys_list_mappings.c',
81 'thread_suspension_common.c',
82 'thread_suspension_unwind.c',
85 if env.Bit('build_x86_32'):
87 'arch/x86/nacl_ldt_x86.c',
88 'arch/x86_32/nacl_app_32.c',
89 'arch/x86_32/nacl_switch_32.S',
90 'arch/x86_32/nacl_switch_all_regs_32.c',
91 'arch/x86_32/nacl_switch_all_regs_asm_32.S',
92 'arch/x86_32/nacl_switch_to_app_32.c',
93 'arch/x86_32/nacl_syscall_32.S',
94 'arch/x86_32/nacl_tls_32.c',
95 'arch/x86_32/sel_addrspace_x86_32.c',
96 'arch/x86_32/sel_ldr_x86_32.c',
97 'arch/x86_32/sel_rt_32.c',
98 'arch/x86_32/springboard.S',
99 'arch/x86_32/tramp_32.S',
101 elif env.Bit('build_x86_64'):
103 'arch/x86/nacl_ldt_x86.c',
104 'arch/x86_64/nacl_app_64.c',
105 'arch/x86_64/nacl_switch_64.S',
106 'arch/x86_64/nacl_switch_to_app_64.c',
107 'arch/x86_64/nacl_syscall_64.S',
108 'arch/x86_64/nacl_tls_64.c',
109 'arch/x86_64/sel_ldr_x86_64.c',
110 'arch/x86_64/sel_rt_64.c',
111 'arch/x86_64/tramp_64.S',
113 if env.Bit('windows'):
114 # We assemble the .asm assembly file with the Microsoft assembler
115 # because we need to generate x86-64 Windows unwind info, which
116 # the GNU assembler we use elsewhere does not support.
117 win64_asm_env = env.Clone(ASCOM='ml64 $ASFLAGS /c /Fo$TARGET $SOURCES')
119 'arch/x86_64/sel_addrspace_win_x86_64.c',
120 'arch/x86_64/fnstcw.S',
121 'arch/x86_64/fxsaverstor.S',
122 win64_asm_env.ComponentObject('arch/x86_64/nacl_switch_unwind_win.asm')]
124 ldr_inputs += ['arch/x86_64/sel_addrspace_posix_x86_64.c']
125 if env.Bit('x86_64_zero_based_sandbox'):
126 env.Append(CPPDEFINES=['-DNACL_X86_64_ZERO_BASED_SANDBOX=1'])
128 env.Append(CPPDEFINES=['-DNACL_X86_64_ZERO_BASED_SANDBOX=0'])
129 elif env.Bit('build_arm'):
131 'arch/arm/nacl_app.c',
132 'arch/arm/nacl_switch_to_app_arm.c',
134 'arch/arm/nacl_tls.c',
135 'arch/arm/sel_ldr_arm.c',
136 'arch/arm/sel_addrspace_arm.c',
137 'arch/arm/nacl_switch.S',
138 'arch/arm/nacl_syscall.S',
139 'arch/arm/tramp_arm.S',
141 elif env.Bit('build_mips32'):
143 'arch/mips/nacl_app.c',
144 'arch/mips/nacl_switch_to_app_mips.c',
145 'arch/mips/sel_rt.c',
146 'arch/mips/nacl_tls.c',
147 'arch/mips/sel_ldr_mips.c',
148 'arch/mips/sel_addrspace_mips.c',
149 'arch/mips/nacl_switch.S',
150 'arch/mips/nacl_syscall.S',
151 'arch/mips/tramp_mips.S',
154 if env.Bit('windows'):
156 'win/addrspace_teardown.c',
158 'win/nacl_thread_nice.c',
160 'win/sel_segments.c',
163 # Rely on the c preprocessor to discover where the mach interface definitions
166 [GENERATED + '/exc.defs'], [],
167 "echo '#include <mach/exc.defs>' | ${CC} ${CFLAGS} -E - > ${TARGET}")
169 [GENERATED + '/nacl_exc.h', GENERATED + '/nacl_exc_server.c'],
170 ['osx/run_mig.py', GENERATED + '/exc.defs'],
171 '${PYTHON} ${SOURCES} ${TARGETS}')
173 GENERATED + '/nacl_exc_server.c',
174 'osx/crash_filter.c',
175 'osx/mach_exception_handler.c',
176 'osx/mach_thread_map.c',
178 'osx/nacl_thread_nice.c',
179 'osx/outer_sandbox.c',
180 'posix/addrspace_teardown.c',
181 'posix/sel_memory.c',
182 'posix/x86/sel_segments.c',
184 elif env.Bit('linux'):
186 'linux/nacl_bootstrap_args.c',
187 'linux/nacl_thread_nice.c',
189 'linux/reserved_at_zero.c',
190 'posix/addrspace_teardown.c',
191 'posix/sel_memory.c',
193 if env.Bit('build_x86'):
195 'linux/x86/nacl_ldt.c',
196 'posix/x86/sel_segments.c',
198 elif env.Bit('build_arm'):
200 'linux/arm/sel_segments.c',
202 elif env.Bit('build_mips32'):
204 'linux/mips/sel_segments.c',
208 # -------------------------------------------------------------
209 # Add OS and architecture specific signal handling files.
211 if env.Bit('windows'):
213 'win/debug_exception_handler.c',
214 'win/debug_exception_handler_standalone.c',
215 'win/nacl_signal_stack.c',
216 'win/thread_handle_map.c',
217 'win/thread_suspension.c',
218 'win/sel_addrspace_win.c',
220 if env.Bit('target_x86_32'):
222 'win/nacl_signal_32.c',
224 elif env.Bit('target_x86_64'):
226 'win/exception_patch/exit_fast.S',
227 'win/exception_patch/intercept.S',
228 'win/exception_patch/ntdll_patch.c',
229 'win/nacl_signal_64.c',
232 raise Exception("Unsupported target")
236 'linux/thread_suspension.c',
237 'posix/nacl_signal_stack.c',
238 'posix/sel_addrspace_posix.c'
240 if env.Bit('target_arm'):
241 ldr_inputs += ['linux/nacl_signal_arm.c']
242 elif env.Bit('target_mips32'):
243 ldr_inputs += ['linux/nacl_signal_mips.c']
244 elif env.Bit('target_x86_32'):
245 ldr_inputs += ['linux/nacl_signal_32.c']
246 elif env.Bit('target_x86_64'):
247 ldr_inputs += ['linux/nacl_signal_64.c']
249 raise Exception("Unsupported target")
251 nacl_signal_env = env.Clone()
252 if env.Bit('target_x86_32'):
253 # nacl_signal.c needs to be compiled without the stack protector
255 # See https://code.google.com/p/nativeclient/issues/detail?id=3581.
256 nacl_signal_env.FilterOut(CCFLAGS=['-fstack-protector',
257 '-fstack-protector-all'])
258 nacl_signal_env.Append(CCFLAGS=['-fno-stack-protector'])
259 ldr_inputs += [nacl_signal_env.ComponentObject('linux/nacl_signal.c')]
263 'osx/thread_suspension.c',
264 'posix/nacl_signal_stack.c',
265 'posix/sel_addrspace_posix.c'
267 if env.Bit('target_x86_32'):
268 ldr_inputs += ['osx/nacl_signal_32.c']
269 elif env.Bit('target_x86_64'):
270 ldr_inputs += ['osx/nacl_signal_64.c']
272 raise Exception("Unsupported target")
274 if env.Bit('windows'):
275 ldr_inputs += ['win/vm_hole.c']
277 ldr_inputs += ['generic/vm_hole.c']
280 syscall_gen_flags = '-a ${TARGET_ARCHITECTURE} -s ${TARGET_SUBARCH}'
282 env.Append(SYSCALL_GEN_FLAGS=syscall_gen_flags)
284 env.DualLibrary('sel', ldr_inputs)
286 env.DualLibrary('sel_main_chrome', ['sel_main_chrome.c'])
288 env.DualLibrary('sel_main', ['sel_main.c'])
290 env.DualLibrary('env_cleanser', ['env_cleanser.c'])
292 env.DualLibrary('nacl_error_code',
293 ['nacl_error_code.c',
296 if env.Bit('windows'):
297 env.ComponentLibrary('sel_test', 'win/mmap_test_check.cc')
299 env.ComponentLibrary('sel_test', 'osx/mmap_test_check.cc')
300 elif env.Bit('linux'):
301 env.ComponentLibrary('sel_test', 'linux/mmap_test_check.cc')
303 raise AssertionError('Unsupported host OS')
306 # NOTE(robertm): these extra libs were orignially only added to the
308 # TODO(robertm): see who really needs them and remove
309 if env.Bit('windows'):
316 # TODO(gregoryd): ntdll.lib is required for sem_get_value implementation but
317 # it is available in Windows DDK only. The DDK is not
318 # in third_party, but we might need to add it if we want to use it.
323 sel_ldr_libs = ['sel',
344 if not env.Bit('coverage_enabled') or not env.Bit('windows'):
345 sel_main_objs = [env.ComponentObject('nacl_test_injection_main.c')]
346 SEL_LDR_NODE = env.ComponentProgram('sel_ldr', sel_main_objs,
347 EXTRA_LIBS=['sel_main'])
349 # This target exists only to check that the service_runtime code
350 # can successfully be linked into a Mac OS X dynamic library. Our
351 # assembly code needs to be PIC-friendly and linkable in this
352 # context, because it is linked into a dynamic library inside
353 # Chromium, and OS X is strict about TEXTRELs. Without this, the
354 # standalone build won't catch some mistakes that can break the
355 # Chromium build. Linking a dylib here works because -fPIC is the
356 # default for all C code on OS X.
357 dylib_env = env.Clone()
358 dylib_env.Append(LINKFLAGS=['-bundle'])
359 dylib_env.ComponentProgram('dummy_sel_ldr.dylib', sel_main_objs,
360 EXTRA_LIBS=['sel_main'])
362 # NOTE: we do not have segments on ARM
363 if env.Bit('build_x86'):
364 env.ComponentProgram('nacl_ldt_unittest',
365 'nacl_ldt_unittest.c',
374 env.SDKInstallBin('sel_ldr', SEL_LDR_NODE)
376 if env.Bit('linux') and env.Bit('target_x86_64'):
377 sel_ldr_seccomp_node = env.ComponentProgram('sel_ldr_seccomp',
378 ['sel_ldr_seccomp_main.c'],
379 EXTRA_LIBS=['sel_main',
381 env.SDKInstallBin('sel_ldr_seccomp', sel_ldr_seccomp_node)
383 env.EnsureRequiredBuildWarnings()
385 # Bootstrap loader used on Linux.
386 if (env.Bit('linux') and not env.Bit('built_elsewhere')):
387 bootstrap_env = env.Clone()
388 bootstrap_env.Replace(CLANG_OPTS='')
389 bootstrap_env.FilterOut(CCFLAGS=['-fstack-protector', '-fPIC', '-fPIE',
390 '-pedantic', '$COVERAGE_CCFLAGS'],
391 CFLAGS=['-Wdeclaration-after-statement'])
392 bootstrap_env.Append(CCFLAGS=['-fno-pic', '-fno-PIC', '-fno-pie', '-fno-pie',
393 '-fno-stack-protector'])
395 # TODO(bbudge) Remove -Qunused-arguments when Clang supports -fno-pic.
397 bootstrap_env.Append(CCFLAGS=['-ffreestanding',
399 '-D__STDC_HOSTED__=1',
400 '-Qunused-arguments'])
402 if env.Bit('target_x86_64'):
403 ld_emul = 'elf_x86_64'
404 if env.Bit('x86_64_zero_based_sandbox'):
405 # For the zero-based 64-bit sandbox, we want to reserve 44GB of address
406 # space: 4GB for the program plus 40GB of guard pages. Due to a binutils
407 # bug (see http://sourceware.org/bugzilla/show_bug.cgi?id=13400), the
408 # amount of address space that the linker can pre-reserve is capped
409 # at 4GB. For proper reservation, GNU ld version 2.22 or higher
412 # Without the bug fix, trying to reserve 44GB will result in
413 # pre-reserving the entire capped space of 4GB. This tricks the run-time
414 # into thinking that we can mmap up to 44GB. This is unsafe as it can
415 # overwrite the run-time program itself and/or other programs. Because
416 # of this, we only reserve 4GB.
418 # TODO(arbenson): remove these comments and reserve 44GB once the
419 # necessary ld version becomes standard.
420 reserve_top = '0x100000000'
421 # The reserve_top value gets interpreted as a pointer in
422 # linux/nacl_bootstrap.c. By default, mcmodel is set to small,
423 # which restricts code and data to the first 2GB. With
424 # mcmodel set to small or medium, the reserve_top value is
425 # truncated, which produces an error. With mcmodel set to large,
426 # there is no restriction on the code and data, so we can
427 # safely set reserve_top to 0x100000000.
428 bootstrap_env.Append(CCFLAGS=['-mcmodel=large'])
431 elif env.Bit('target_x86_32'):
433 reserve_top = '0x40000000'
434 elif env.Bit('target_arm'):
435 ld_emul = 'armelf_linux_eabi'
436 reserve_top = '0x40002000'
437 elif env.Bit('target_mips32'):
438 ld_emul = 'elf32ltsmip'
439 reserve_top = '0x40008000'
441 bootstrap_obj = bootstrap_env.ComponentObject('linux/nacl_bootstrap.c')
442 bootstrap_raw = bootstrap_env.Command(
443 'nacl_bootstrap_raw',
445 ("env CXX='${CXX}' ${PYTHON} %s " +
446 '-m %s --build-id -static -z max-page-size=0x1000 ' +
447 '--defsym RESERVE_TOP=%s --script %s -o ${TARGET} ${SOURCES}') %
448 (bootstrap_env.File('linux/ld_bfd.py'), ld_emul, reserve_top,
449 bootstrap_env.File('linux/nacl_bootstrap.x')),
452 # The bootstrap program is used as an intermediate program so it
453 # must be built in the current build environment.
454 munge_env = env['BUILD_ENV']
455 bootstrap_munge = munge_env.Program(
456 'nacl_bootstrap_munge_phdr',
457 ['linux/nacl_bootstrap_munge_phdr.c'],
460 bootstrap_prog = bootstrap_env.Command(
461 'nacl_helper_bootstrap',
462 [bootstrap_env.File('linux/nacl_bootstrap_munge_phdr.py'),
463 bootstrap_munge, bootstrap_raw],
464 '${PYTHON} ${SOURCES} ${TARGET}'
466 bootstrap_out = bootstrap_env.Install('${STAGING_DIR}', bootstrap_prog)
468 bootstrap_env.Alias('nacl_helper_bootstrap', bootstrap_out)
469 bootstrap_env.Requires(SEL_LDR_NODE, bootstrap_out)
470 env.SDKInstallBin('nacl_helper_bootstrap', bootstrap_prog)
472 # ----------------------------------------------------------
474 # ----------------------------------------------------------
476 # NOTE: uses validator
477 # TODO(robertm): break this test up in smaller pieces with more managable
479 gtest_env = env.MakeGTestEnv()
484 'sel_memory_unittest.cc',
485 # nacl_sync_unittest.cc was testing the wrong (i.e., too low level) API
486 # re-enable it when it has been converted to the C API.
487 #'nacl_sync_unittest.cc',
490 'thread_suspension_test.cc',
493 if not env.Bit('coverage_enabled') or not env.Bit('windows'):
494 unit_tests_exe = gtest_env.ComponentProgram(
495 'service_runtime_tests',
514 node = gtest_env.CommandTest(
515 'gtest_output.xml.out',
516 size='large', # This test suite is fairly slow on Windows XP.
517 command=[unit_tests_exe, '--gtest_output=xml:${TARGET}'])
518 gtest_env.AddNodeToTestSuite(node, ['small_tests'],
519 'run_service_runtime_tests')
522 if not env.Bit('coverage_enabled') or not env.Bit('windows'):
523 format_string_test_exe = env.ComponentProgram(
524 'format_string_test',
525 ['format_string_test.c'],
531 node = env.CommandTest(
532 'format_string_test.out',
533 command=[format_string_test_exe])
534 env.AddNodeToTestSuite(node, ['small_tests'], 'run_format_string_test')
537 if env.Bit('target_x86_32'):
538 arch_testdata_dir = 'testdata/x86_32'
539 elif env.Bit('target_x86_64'):
540 arch_testdata_dir = 'testdata/x86_64'
542 arch_testdata_dir = 'testdata/' + env['TARGET_ARCHITECTURE']
544 untrusted_env = env.MakeUntrustedNativeEnv()
545 hello_world_nexe = untrusted_env.File('$STAGING_DIR/hello_world.nexe')
547 # Doesn't work on windows under coverage.
548 # TODO(bradnelson): fix this to work on windows under coverage.
549 if ((not env.Bit('windows') or not env.Bit('coverage_enabled')) and
550 env.Bit('nacl_static_link')):
551 # NOTE: uses validator
552 mmap_test_objs = [env.ComponentObject('mmap_test.c')]
553 mmap_test_exe = env.ComponentProgram(
573 mmap_test_command = env.AddBootstrap(mmap_test_exe, [hello_world_nexe])
575 # TODO(robertm): This test emits lots of messages to stderr
576 node = env.CommandTest (
578 command=mmap_test_command,
579 # TODO(mseaborn): Extend this test to cover the case where the
580 # dynamic code segment is present.
581 osenv='NACL_DISABLE_DYNAMIC_LOADING=1')
582 env.AddNodeToTestSuite(node, ['medium_tests'], 'run_trusted_mmap_test')
586 nacl_bootstrap_prereservation_test_exe = env.ComponentProgram(
587 'nacl_bootstrap_prereservation_test',
588 ['linux/nacl_bootstrap_prereservation_test.c'],
591 bootstrap, bootstrap_arg = env.GetBootstrap()
592 node = env.CommandTest(
593 'nacl_bootstrap_prereservation_test.out',
594 command=env.AddBootstrap(nacl_bootstrap_prereservation_test_exe, []))
595 env.AddNodeToTestSuite(node, ['small_tests'],
596 'run_nacl_bootstrap_prereservation_test')
599 # also seems to have issues with windows coverage or VMs
600 # NOTE: uses validator
601 is_broken = env.Bit('coverage_enabled') or env.Bit('running_on_vm')
602 nacl_sync_cond_test_exe = env.ComponentProgram(
603 'nacl_sync_cond_test',
604 ['nacl_sync_cond_test.c'],
620 node = env.CommandTest(
621 'nacl_sync_cond_test.out',
622 command=[nacl_sync_cond_test_exe])
623 env.AddNodeToTestSuite(node,
625 'run_nacl_sync_cond_test',
629 env_cleanser_test_exe = env.ComponentProgram('env_cleanser_test',
630 ['env_cleanser_test.c'],
631 EXTRA_LIBS=['env_cleanser',
634 node = env.CommandTest(
635 'env_cleanser_test.out',
636 command=[env_cleanser_test_exe])
637 env.AddNodeToTestSuite(node, ['small_tests'], 'run_env_cleanser_test')
641 nacl_resource_test_exe = env.ComponentProgram('nacl_resource_test',
642 ['nacl_resource_test.c'],
644 node = env.CommandTest(
645 'nacl_resource_test.out',
646 command=[nacl_resource_test_exe])
647 env.AddNodeToTestSuite(node, ['small_tests'], 'run_nacl_resource_test')
651 if (not env.Bit('coverage_enabled') and
652 not env.Bit('target_arm') and
653 not env.Bit('target_mips32') and
654 not env.IsRunningUnderValgrind()):
655 nacl_signal_exe = env.ComponentProgram(
656 'nacl_signal_unittest', 'nacl_signal_unittest.c',
658 node = env.CommandTest('nacl_signal_unittest.out',
659 command=[nacl_signal_exe])
661 env.AddNodeToTestSuite(node, ['small_tests'], 'run_nacl_signal_test')
663 test_prog = env.ComponentProgram('nacl_signal_frame_test',
664 'nacl_signal_frame_test.c',
666 node = env.CommandTest('nacl_signal_frame_test.out',
668 declares_exit_status=True,
669 using_nacl_signal_handler=True)
670 env.AddNodeToTestSuite(node, ['small_tests'], 'run_signal_frame_test')
672 if env.Bit('windows') and env.Bit('target_x86_64'):
673 test_prog = env.ComponentProgram('patch_ntdll_test',
674 'win/exception_patch/ntdll_test.c',
680 node = env.CommandTest('patch_ntdll_test.out',
681 command=[test_prog], declares_exit_status=True)
682 env.AddNodeToTestSuite(node, ['small_tests'], 'run_patch_ntdll_test')
684 intercept_test_prog = env.ComponentProgram(
685 'ntdll_intercept_test', 'win/exception_patch/intercept_test.c',
686 EXTRA_LIBS=sel_ldr_libs)
687 node = env.CommandTest(
688 'ntdll_intercept_test.out',
689 command=[intercept_test_prog, 'test_intercept'],
690 exit_status='untrusted_segfault',
691 stdout_golden=env.File('win/exception_patch/intercept_test.stdout'))
692 env.AddNodeToTestSuite(node, ['small_tests'], 'run_ntdll_intercept_test')
693 node = env.CommandTest(
694 'ntdll_fallback_test.out',
695 command=[intercept_test_prog, 'test_fallback'],
696 exit_status='untrusted_segfault',
697 stdout_golden=env.File('win/exception_patch/fallback_test.stdout'))
698 env.AddNodeToTestSuite(node, ['small_tests'], 'run_ntdll_fallback_test')
701 check_test_exe = env.ComponentProgram('nacl_check_test',
702 ['nacl_check_test.c'],
711 node = env.CommandTest(
713 command=[check_test_exe, '-C'])
714 env.AddNodeToTestSuite(node, ['small_tests'], 'run_check_test')
717 ABORT_EXIT = '17' # magic, see nacl_check_test.c
720 node = env.CommandTest(
721 'check_test_death.out',
722 command=[check_test_exe, '-c'],
723 exit_status=ABORT_EXIT) # abort()
724 env.AddNodeToTestSuite(node, ['small_tests'], 'run_check_test_death')
728 node = env.CommandTest(
729 'dcheck_test_death.out',
730 command=[check_test_exe, '-d'],
731 exit_status=ABORT_EXIT) # abort()
733 node = env.CommandTest(
734 'dcheck_test_death.out',
735 command=[check_test_exe, '-d']) # no abort()
736 env.AddNodeToTestSuite(node, ['small_tests'], 'run_dcheck_test_death')
739 node = env.CommandTest(
740 'check_test_always_death.out',
741 command=[check_test_exe, '-s', '0', '-C']) # no abort
742 env.AddNodeToTestSuite(node, ['small_tests'], 'run_check_test_always_death')
745 node = env.CommandTest(
746 'check_test_always_death_abort.out',
747 command=[check_test_exe, '-s', '0', '-c'],
748 exit_status=ABORT_EXIT) # abort
749 env.AddNodeToTestSuite(
752 'run_check_test_always_death_abort')
755 node = env.CommandTest(
756 'dcheck_test_never_death.out',
757 command=[check_test_exe, '-s', '0', '-d']) # no abort
758 env.AddNodeToTestSuite(node, ['small_tests'], 'run_dcheck_test_never_death')
761 node = env.CommandTest(
762 'dcheck_test_always_death.out',
763 command=[check_test_exe, '-s', '1', '-d'],
764 exit_status=ABORT_EXIT) # abort()
765 env.AddNodeToTestSuite(
768 'run_dcheck_test_always_death')
771 # Mac does not support thread local storage via "__thread" so do not run this
773 # This test is thread-unsafe by design. Don't run it under Valgrind.
774 if not env.Bit('mac') and not env.IsRunningUnderValgrind():
775 nacl_tls_unittest = env.ComponentProgram('nacl_tls_unittest',
776 ['nacl_tls_unittest.c'],
777 EXTRA_LIBS=['platform'])
778 node = env.CommandTest('nacl_tls_unittest.out',
779 command=[nacl_tls_unittest])
781 env.AddNodeToTestSuite(node, ['small_tests'], 'run_nacl_tls_unittest')
783 # Test that sel_ldr does not crash if the executable file cannot be opened.
784 node = env.CommandSelLdrTestNacl(
785 'sel_ldr_exe_not_found.out',
786 'name_of_file_that_does_not_exist.nexe',
788 env.AddNodeToTestSuite(node, ['small_tests'], 'run_sel_ldr_exe_not_found_test')
790 # Check that "-F" makes sel_ldr stop after loading the nexe but before running
792 nullptr_nexe = untrusted_env.GetTranslatedNexe(
793 untrusted_env.File('$STAGING_DIR/nullptr$PROGSUFFIX'))
795 node = env.CommandSelLdrTestNacl(
796 'fuzz_nullptr_test.out',
798 sel_ldr_flags=['-F'])
799 env.AddNodeToTestSuite(node, ['small_tests'], 'run_fuzz_nullptr_test')
801 # Test hello_world binary with obsolete, non-ragel based validator.
802 if (not env.Bit('validator_ragel') and env.Bit('target_x86')
803 and env.Bit('nacl_static_link')):
804 node = env.CommandSelLdrTestNacl(
807 stdout_golden = env.File('testdata/hello_world.stdout'),
808 stderr_golden = env.File('testdata/non_dfa_validator_hello.stderr'),
809 filter_regex = '"^(Hello, World!)$' + '|' +
810 '^[[][^]]*[]] (USING OBSOLETE NON-DFA-BASED VALIDATOR!)$"',
811 filter_group_only = 'true',
813 env.AddNodeToTestSuite(node, ['medium_tests', 'validator_tests'],
814 'run_dfa_validator_hello_world_test')
816 if env.Bit('target_mips32'):
817 text_region_start = 0x00020000
818 # Use arbitrary non-page-aligned addresses for data and rodata.
819 rodata_region_start = 0x10020094
820 data_region_start = 0x10030098
821 untrusted_env.Append(CPPFLAGS=['--pnacl-allow-native', '-arch', 'mips32'])
822 unaligned_data_objs = untrusted_env.ComponentObject(
823 'arch/mips/unaligned_data_test.S')
824 unaligned_data_nexe = untrusted_env.ComponentProgram(
825 'unaligned_data.nexe',
827 LINKFLAGS=['-nostdlib',
828 '--pnacl-allow-native', '-arch', 'mips32',
829 '-Wn,--section-start=.text=0x%x' % (text_region_start),
830 '-Wn,--section-start=.rodata=0x%x' % (rodata_region_start),
831 '-Wn,--section-start=.data=0x%x' % (data_region_start)],
832 ASFLAGS=['--pnacl-allow-native', '-arch', 'mips32'])
834 rodata_region_start_irt = 0x3eef0000
835 text_region_start_irt = 0x0fc00000
836 unaligned_data_irt_nexe = untrusted_env.ComponentProgram(
837 'unaligned_data_irt.nexe',
839 LINKFLAGS=['-nostdlib',
840 '--pnacl-allow-native', '-arch', 'mips32',
841 '-Wl,-Ttext-segment=0x%x' % text_region_start_irt,
842 '-Wl,-Trodata-segment=0x%x' % rodata_region_start_irt],
843 ASFLAGS=['--pnacl-allow-native', '-arch', 'mips32'])
845 unaligned_data_nexe = env.File(os.path.join(arch_testdata_dir,
846 'unaligned_data.nexe'))
847 unaligned_data_irt_nexe = env.File(os.path.join(arch_testdata_dir,
848 'unaligned_data_irt.nexe'))
850 node = env.CommandSelLdrTestNacl('unaligned_data.out', unaligned_data_nexe)
851 env.AddNodeToTestSuite(node, ['small_tests'], 'run_unaligned_data_test')
853 node = env.CommandSelLdrTestNacl(
854 'unaligned_data_irt.out',
856 sel_ldr_flags=['-B', unaligned_data_irt_nexe]
858 env.AddNodeToTestSuite(node, ['small_tests'], 'run_unaligned_data_irt_test')
860 # ----------------------------------------------------------
861 # Small tests with canned binaries
862 # ----------------------------------------------------------
864 if env.Bit('target_x86_64'):
865 node = env.CommandSelLdrTestNacl(
867 env.File(os.path.join(arch_testdata_dir, 'hello_x32.nexe')),
868 stdout_golden=env.File(os.path.join('${MAIN_DIR}',
870 'hello_world.stdout'))
872 env.AddNodeToTestSuite(node, ['small_tests'], 'run_hello_x32_test')
874 # ----------------------------------------------------------
875 # Integration Tests With Canned x86 Binaries
876 # ----------------------------------------------------------
877 # To update the canned tests run:
878 # ./scons platform=x86-64
879 # cp scons-out/nacl-x86-64/staging/{mandel.nexe,fib_*} \
880 # src/trusted/service_runtime/testdata/x86_64/
881 # ./scons platform=x86-32
882 # cp scons-out/nacl-x86-32/staging/{mandel.nexe,fib_*} \
883 # src/trusted/service_runtime/testdata/x86_32/
885 # TODO: Create integration test nexes for arm.
886 INTEGRATION_TESTS_X86 = [ 'mandel',
889 INTEGRATION_TESTS_X86_STDIN_OUT = ['$SCONSTRUCT_DIR/tests/mandel/test',
890 '$SCONSTRUCT_DIR/tests/fib/fib_scalar_test',
891 '$SCONSTRUCT_DIR/tests/fib/fib_array_test' ]
893 def AddIntegrationTest(test, location):
894 if not test or not location:
897 node = env.SelUniversalTest(
898 test + '_canned.out',
899 env.File(arch_testdata_dir + '/' + test + '.nexe'),
900 stdin = location + '.stdin',
901 stdout_golden = location + '.stdout',
903 env.AddNodeToTestSuite(node,
905 'run_%s_integration_test' % test)
907 if env.Bit('target_x86') and env.Bit('nacl_static_link'):
908 RE_HELLO = '^(Hello, World!)$'
909 RE_IDENT = '^\[[0-9,:.]*\] (e_ident\+1 = ELF)$'
911 node = env.CommandSelLdrTestNacl(
914 log_golden = env.File('testdata/hello_world.log'),
915 stdout_golden = env.File('testdata/hello_world.stdout'),
916 filter_regex = '"' + RE_HELLO + '|' + RE_IDENT + '"',
917 filter_group_only = 'true',
919 env.AddNodeToTestSuite(node, ['medium_tests'],
920 'run_service_runtime_hello_world_test')
922 assert len(INTEGRATION_TESTS_X86) == len(INTEGRATION_TESTS_X86_STDIN_OUT)
923 map(AddIntegrationTest,
924 INTEGRATION_TESTS_X86,
925 INTEGRATION_TESTS_X86_STDIN_OUT)
927 # ----------------------------------------------------------
928 # Death Tests With Canned x86 Binaries
929 # ----------------------------------------------------------
930 ERROR_WHILE_LOADING = '"^(Error while loading).*' + '(:[^:]*)"'
932 # TODO: Create death test nexes for arm.
933 DEATH_TESTS_X86 = [ 'old_abi', # hello_world.nexe with an old ABI version
934 'integer_overflow_while_madvising',
936 'rodata_data_overlap',
938 'text_overlaps_rodata',
939 'text_overlaps_data',
942 NOT_AVAIL_X86_32 = [ ]
944 NOT_AVAIL_X86_64 = [ 'text_overlaps_rodata',
945 'text_overlaps_data' ]
947 def AddDeathTest(test, skip):
952 print 'SKIPPING test ', test
955 # Use an arch-specific golden file if there is one.
956 # We can't use the SCons File .exists() method because that will
957 # look for the file in a scons-out directory.
958 stderr_file = env.File(os.path.join(arch_testdata_dir, test + '.stderr'))
959 if not os.path.exists(str(stderr_file)):
960 stderr_file = env.File(os.path.join('testdata', test + '.stderr'))
962 node = env.CommandSelLdrTestNacl(
964 env.File(arch_testdata_dir + '/' + test + '.nexe'),
965 stderr_golden = stderr_file,
966 filter_regex = ERROR_WHILE_LOADING,
967 filter_group_only = 'true',
969 env.AddNodeToTestSuite(node, ['medium_tests'],
970 'run_' + test + '_death_test')
973 if env.Bit('target_x86'):
974 if env.Bit('build_x86_32'):
975 skip = NOT_AVAIL_X86_32
977 skip = NOT_AVAIL_X86_64
979 for death_test in DEATH_TESTS_X86:
980 AddDeathTest(death_test, skip)
982 # ----------------------------------------------------------
984 # ----------------------------------------------------------
985 if not env.Bit('coverage_enabled') or not env.Bit('windows'):
986 # NOTE: uses validator
987 sel_ldr_thread_death_test_exe = env.ComponentProgram(
988 'sel_ldr_thread_death_test',
989 ['sel_ldr_thread_death_test.c'],
1001 'nacl_fault_inject',
1006 # NaClAbort() behaves differently when code coverage is enabled: it
1007 # calls exit() rather than abort().
1008 if env.Bit('coverage_enabled'):
1009 expected_exit_status = 'naclabort_coverage'
1011 expected_exit_status = 'trusted_sigabrt'
1012 node = env.CommandTest(
1013 'sel_ldr_thread_death_test.out',
1014 command=[sel_ldr_thread_death_test_exe],
1015 exit_status=expected_exit_status)
1017 # TODO(tuduce): Make it work on windows.
1018 env.AddNodeToTestSuite(node, ['medium_tests'],
1019 'run_sel_ldr_thread_death_test',
1020 is_broken=env.Bit('windows'))
1023 exe = env.ComponentProgram('nacl_error_gio_test',
1024 ['nacl_error_gio_test.c'],
1025 EXTRA_LIBS=sel_ldr_libs)
1027 node = env.CommandTest('nacl_error_gio_test.out',
1028 command=[exe, '-n', '1000'])
1030 env.AddNodeToTestSuite(node, ['small_tests'],
1031 'run_nacl_error_gio_test')
1033 exe = env.ComponentProgram('nacl_error_log_test',
1034 ['nacl_error_log_test.c'],
1035 EXTRA_LIBS=sel_ldr_libs)
1037 if env.Bit('coverage_enabled'):
1038 expected_exit = 'naclabort_coverage'
1040 expected_exit = 'trusted_sigabrt'
1042 node = env.CommandTest(
1043 'nacl_error_log_test.out',
1045 exit_status=expected_exit,
1046 filter_regex='"(NaClCrashLogWriter.*)|(This is a test of the emergency.*)"',
1047 filter_group_only='true',
1048 stdout_golden=env.File('nacl_error_log_test.stdout'))
1050 is_broken = env.Bit('host_windows') and env.Bit('coverage_enabled')
1051 env.AddNodeToTestSuite(node, ['small_tests'],
1052 'run_nacl_error_log_test',
1053 is_broken=is_broken)
1055 dyn_array_test_exe = env.ComponentProgram('dyn_array_test',
1056 ['dyn_array_test.c'],
1057 EXTRA_LIBS=sel_ldr_libs)
1059 node = env.CommandTest('dyn_array_test.out',
1060 command=[dyn_array_test_exe])
1062 env.AddNodeToTestSuite(node, ['small_tests'], 'run_dyn_array_test')