OLD | NEW |
1 # -*- python -*- | 1 # -*- python -*- |
2 # Copyright (c) 2014 The Native Client Authors. All rights reserved. | 2 # Copyright (c) 2014 The Native Client Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 Import('env') | 6 Import('env') |
7 | 7 |
8 if not env.Bit('bitcode'): | 8 if not env.Bit('bitcode'): |
9 Return() | 9 Return() |
10 # Translating the PSO to an ELF DSO doesn't work on x86-64 yet. The | 10 # Translating the PSO to an ELF DSO doesn't work on x86-64 yet. The |
11 # Gold linker complains that the input "requires dynamic R_X86_64_32 | 11 # Gold linker complains that the input "requires dynamic R_X86_64_32 |
12 # reloc against <blah> which may overflow at runtime". (In contrast, | 12 # reloc against <blah> which may overflow at runtime". (In contrast, |
13 # the BFD linker in the glibc toolchain does handle this relocation.) | 13 # the BFD linker in the glibc toolchain does handle this relocation.) |
14 # TODO(mseaborn): Fix this and enable the test for x86-64. | 14 # TODO(mseaborn): Fix this and enable the test for x86-64. |
15 if env.Bit('build_x86_64'): | 15 if env.Bit('build_x86_64'): |
16 Return() | 16 Return() |
17 # TODO(sbc): Enable this test for mips. | 17 # TODO(sbc): Enable this test for mips. |
18 if env.Bit('build_mips32'): | 18 if env.Bit('build_mips32'): |
19 Return() | 19 Return() |
20 # The sandboxed translator does not support translating PSOs yet. | 20 # The sandboxed translator does not support translating PSOs yet. |
21 if env.Bit('use_sandboxed_translator'): | 21 if env.Bit('use_sandboxed_translator'): |
22 Return() | 22 Return() |
23 | 23 |
| 24 def FinalizePso(dest, opt_result): |
| 25 # Finalize to strip debugging info and to emit PNaCl bitcode. |
| 26 return env.Command(dest + '.so', [opt_result], |
| 27 '${PNACLFINALIZE} ${SOURCES} -o ${TARGET}') |
24 | 28 |
25 def FinalizeAndTranslatePso(dest, opt_result): | 29 def TranslatePso(dest, finalized_result): |
26 # Finalize to strip debugging info and to emit PNaCl bitcode. | |
27 finalized_result = env.Command( | |
28 dest + '.final.pso', [opt_result], | |
29 '${PNACLFINALIZE} ${SOURCES} -o ${TARGET}') | |
30 # Translate to an ELF loadable object. | 30 # Translate to an ELF loadable object. |
31 return env.Command(dest + '.so', [finalized_result], | 31 return env.Command(dest + '.so.translated', [finalized_result], |
32 '${TRANSLATE} -pso ${SOURCES} -o ${TARGET}') | 32 '${TRANSLATE} -pso ${SOURCES} -o ${TARGET}') |
33 | 33 |
34 | 34 |
35 def MakeAndTranslatePso(dest, bitcode_file, llvm_passes): | 35 def MakeAndTranslatePso(dest, bitcode_file, llvm_passes): |
36 # Run opt to optionally apply PNaCl ABI simplifications to the IR and to | 36 # Run opt to optionally apply PNaCl ABI simplifications to the IR and to |
37 # run the PNaCl ABI checker. We are bypassing pnacl-ld for now because | 37 # run the PNaCl ABI checker. We are bypassing pnacl-ld for now because |
38 # its invocation of Gold internalizes __pnacl_pso_root, which we want to | 38 # its invocation of Gold internalizes __pnacl_pso_root, which we want to |
39 # keep externally-visible. | 39 # keep externally-visible. |
40 opt_result = env.Command( | 40 opt_result = env.Command( |
41 dest + '.nonfinal.pso', [bitcode_file], | 41 dest + '.nonfinal.pso', [bitcode_file], |
42 '${PNACLOPT} ' + llvm_passes + ' ' | 42 '${PNACLOPT} ' + llvm_passes + ' ' |
43 '-verify-pnaclabi-module -verify-pnaclabi-functions ' | 43 '-verify-pnaclabi-module -verify-pnaclabi-functions ' |
44 '-pnaclabi-allow-debug-metadata ' | 44 '-pnaclabi-allow-debug-metadata ' |
45 '${SOURCES} -o ${TARGET}') | 45 '${SOURCES} -o ${TARGET}') |
46 return FinalizeAndTranslatePso(dest, opt_result) | 46 finalized_result = FinalizePso(dest, opt_result) |
| 47 return TranslatePso(dest, finalized_result) |
47 | 48 |
48 def PsoFromLLVMAssembly(base_name): | 49 def PsoFromLLVMAssembly(base_name): |
49 bitcode_file = env.Command( | 50 bitcode_file = env.Command( |
50 '%s.bc' % base_name, ['%s.ll' % base_name], | 51 '%s.bc' % base_name, ['%s.ll' % base_name], |
51 [Action('${ASCOM}', '${ASCOMSTR}')]) | 52 [Action('${ASCOM}', '${ASCOMSTR}')]) |
52 return MakeAndTranslatePso(base_name, [bitcode_file], | 53 return MakeAndTranslatePso(base_name, [bitcode_file], |
53 # Skip PNaCl passes because they add TLS functions. | 54 # Skip PNaCl passes because they add TLS functions. |
54 llvm_passes='') | 55 llvm_passes='') |
55 | 56 |
56 | 57 |
57 def MakeAndTranslatePll(dest, source_file): | 58 def MakePll(dest, source_file, dependencies): |
| 59 deps = '' |
| 60 if dependencies != []: |
| 61 deps += ' -L' + Dir('.').abspath |
| 62 for d in dependencies: |
| 63 deps += ' -l:' + d[0].name |
58 nonfinal_pll = env.Command( | 64 nonfinal_pll = env.Command( |
59 dest + '.nonfinal.pll', [source_file], | 65 dest + '.nonfinal.pll', [source_file], |
60 '${CC} -shared ${SOURCES} -o ${TARGET}') | 66 '${CC} -shared ${SOURCES} -o ${TARGET}' + deps) |
61 return FinalizeAndTranslatePso(dest, nonfinal_pll) | 67 for d in dependencies: |
| 68 # Linking the nonfinal_pll depends on the untranslated, finalized PLL (.so) |
| 69 # dependencies existing. |
| 70 Depends(nonfinal_pll, d) |
| 71 return FinalizePso(dest, nonfinal_pll) |
| 72 |
| 73 def MakeAndTranslatePll(dest, source_file, dependencies): |
| 74 finalized_pll = MakePll(dest, source_file, dependencies) |
| 75 return TranslatePso(dest, finalized_pll) |
62 | 76 |
63 # Under SFI NaCl, the loader currently depends on the allocate_code_data() | 77 # Under SFI NaCl, the loader currently depends on the allocate_code_data() |
64 # interface provided by the IRT. | 78 # interface provided by the IRT. |
65 is_broken = not env.Bit('tests_use_irt') and not env.Bit('nonsfi_nacl') | 79 is_broken = not env.Bit('tests_use_irt') and not env.Bit('nonsfi_nacl') |
66 | 80 |
67 dso1 = MakeAndTranslatePso( | 81 dso1 = MakeAndTranslatePso( |
68 'test_pso', [env.ComponentObject('test_pso.c')], | 82 'test_pso', [env.ComponentObject('test_pso.c')], |
69 llvm_passes='-pnacl-abi-simplify-preopt -pnacl-abi-simplify-postopt') | 83 llvm_passes='-pnacl-abi-simplify-preopt -pnacl-abi-simplify-postopt') |
70 dso2 = PsoFromLLVMAssembly('data_only_pso') | 84 dso2 = PsoFromLLVMAssembly('data_only_pso') |
71 dso3 = PsoFromLLVMAssembly('data_only_pso_largebss') | 85 dso3 = PsoFromLLVMAssembly('data_only_pso_largebss') |
72 | 86 |
73 dynloader_test = env.ComponentProgram( | 87 dynloader_test = env.ComponentProgram( |
74 'dynloader_test', ['dynloader_test.c'], | 88 'dynloader_test', ['dynloader_test.c'], |
75 EXTRA_LIBS=['${NONIRT_LIBS}', 'pnacl_dynloader']) | 89 EXTRA_LIBS=['${NONIRT_LIBS}', 'pnacl_dynloader']) |
76 | 90 |
77 node = env.CommandSelLdrTestNacl( | 91 node = env.CommandSelLdrTestNacl( |
78 'dynloader_test.out', dynloader_test, [dso1, dso2, dso3], | 92 'dynloader_test.out', dynloader_test, [dso1, dso2, dso3], |
79 # Add '-a' to enable filesystem access for opening DSOs. | 93 # Add '-a' to enable filesystem access for opening DSOs. |
80 sel_ldr_flags=['-a']) | 94 sel_ldr_flags=['-a']) |
81 env.AddNodeToTestSuite( | 95 env.AddNodeToTestSuite( |
82 node, ['small_tests', 'toolchain_tests'], | 96 node, ['small_tests', 'toolchain_tests'], |
83 'run_pnacl_dynamic_loading_test', is_broken=is_broken) | 97 'run_pnacl_dynamic_loading_test', is_broken=is_broken) |
84 | 98 |
85 | 99 |
86 # Use of the ConvertToPSO pass requires this toolchain version. | 100 # Use of the ConvertToPSO pass requires this toolchain version. |
87 if env['TOOLCHAIN_FEATURE_VERSION'] < 23: | 101 if env['TOOLCHAIN_FEATURE_VERSION'] < 24: |
88 Return() | 102 Return() |
89 | 103 |
90 test_pll = MakeAndTranslatePll('test_pll', 'test_pll.c') | 104 test_pll = MakeAndTranslatePll('test_pll', 'test_pll.c', []) |
91 test_pll_tls = MakeAndTranslatePll('test_pll_tls', 'test_pll_tls.c') | 105 test_pll_tls = MakeAndTranslatePll('test_pll_tls', 'test_pll_tls.c', []) |
92 | 106 |
93 pll_symbols_test = env.ComponentProgram( | 107 pll_symbols_test = env.ComponentProgram( |
94 'pll_symbols_test', ['pll_symbols_test.cc'], | 108 'pll_symbols_test', ['pll_symbols_test.cc'], |
95 EXTRA_LIBS=['${NONIRT_LIBS}', 'pnacl_dynloader', 'pll_loader_lib']) | 109 EXTRA_LIBS=['${NONIRT_LIBS}', 'pnacl_dynloader', 'pll_loader_lib']) |
96 | 110 |
97 node = env.CommandSelLdrTestNacl( | 111 node = env.CommandSelLdrTestNacl( |
98 'pll_symbols_test.out', pll_symbols_test, [test_pll, test_pll_tls], | 112 'pll_symbols_test.out', pll_symbols_test, [test_pll, test_pll_tls], |
99 # Add '-a' to enable filesystem access for opening DSOs. | 113 # Add '-a' to enable filesystem access for opening DSOs. |
100 sel_ldr_flags=['-a']) | 114 sel_ldr_flags=['-a']) |
101 env.AddNodeToTestSuite( | 115 env.AddNodeToTestSuite( |
102 node, ['small_tests', 'toolchain_tests'], | 116 node, ['small_tests', 'toolchain_tests'], |
103 'run_pll_symbols_test', is_broken=is_broken) | 117 'run_pll_symbols_test', is_broken=is_broken) |
104 | 118 |
105 | 119 |
106 test_pll_a = MakeAndTranslatePll('test_pll_a', 'test_pll_a.c') | 120 test_pll_a_finalized = MakePll('test_pll_a', 'test_pll_a.c', []) |
107 test_pll_b = MakeAndTranslatePll('test_pll_b', 'test_pll_b.c') | 121 test_pll_a = TranslatePso('test_pll_a', test_pll_a_finalized) |
| 122 test_pll_b_finalized = MakePll('test_pll_b', 'test_pll_b.c', |
| 123 [test_pll_a_finalized]) |
| 124 test_pll_b = TranslatePso('test_pll_b', test_pll_b_finalized) |
108 | 125 |
109 pll_loader_test = env.ComponentProgram( | 126 pll_loader_test = env.ComponentProgram( |
110 'pll_loader_test', ['pll_loader_test.cc'], | 127 'pll_loader_test', ['pll_loader_test.cc'], |
111 EXTRA_LIBS=['${NONIRT_LIBS}', 'pll_loader_lib']) | 128 EXTRA_LIBS=['${NONIRT_LIBS}', 'pll_loader_lib']) |
112 | 129 |
113 node = env.CommandSelLdrTestNacl( | 130 node = env.CommandSelLdrTestNacl( |
114 'pll_loader_test.out', pll_loader_test, | 131 'pll_loader_test.out', pll_loader_test, |
115 [Dir('.').abspath, 'test_pll_a.so', 'test_pll_b.so', 'test_pll_tls.so'], | 132 [Dir('.').abspath, 'test_pll_a.so', 'test_pll_b.so', 'test_pll_tls.so'], |
116 # Add '-a' to enable filesystem access for opening DSOs. | 133 # Add '-a' to enable filesystem access for opening DSOs. |
117 sel_ldr_flags=['-a'], | 134 sel_ldr_flags=['-a'], |
118 extra_deps=[test_pll_a, test_pll_b, test_pll_tls]) | 135 extra_deps=[test_pll_a, test_pll_b, test_pll_tls]) |
119 env.AddNodeToTestSuite( | 136 env.AddNodeToTestSuite( |
120 node, ['small_tests', 'toolchain_tests'], | 137 node, ['small_tests', 'toolchain_tests'], |
121 'run_pll_loader_test', is_broken=is_broken) | 138 'run_pll_loader_test', is_broken=is_broken) |
122 | 139 |
123 | 140 |
124 pll_libc = env.Command( | 141 pll_libc_nonfinal = env.Command( |
125 'libc${OBJSUFFIX}', | 142 'libc${OBJSUFFIX}', |
126 # libnacl should come first so that it can override definitions in libc. | 143 # libnacl should come first so that it can override definitions in libc. |
127 [env.File('${LIB_DIR}/libnacl.a'), | 144 [env.File('${LIB_DIR}/libnacl.a'), |
128 env.File('${NACL_SDK_LIB}/libc.a'), | 145 env.File('${NACL_SDK_LIB}/libc.a'), |
129 env.ComponentObject('libc_entry.c')], | 146 env.ComponentObject('libc_entry.c')], |
130 '${CC} -shared -Wl,--whole-archive ${SOURCES} -o ${TARGET}') | 147 '${CC} -shared -Wl,--whole-archive ${SOURCES} -o ${TARGET}') |
131 | 148 |
132 translated_pll_libc = FinalizeAndTranslatePso('translated_pll_libc', pll_libc) | 149 pll_libc_finalized = FinalizePso('pll_libc', pll_libc_nonfinal) |
| 150 pll_libc = TranslatePso('pll_libc', pll_libc_finalized) |
| 151 |
133 translated_pll_hello_world = MakeAndTranslatePll( | 152 translated_pll_hello_world = MakeAndTranslatePll( |
134 'translated_pll_hello_world', | 153 'translated_pll_hello_world', |
135 '../hello_world/hello_world.c') | 154 '../hello_world/hello_world.c', |
| 155 [pll_libc_finalized]) |
136 | 156 |
137 # Ideally we would have this ComponentProgram() definition in | 157 # Ideally we would have this ComponentProgram() definition in |
138 # src/untrusted/pll_loader/nacl.scons instead; see the comment there for | 158 # src/untrusted/pll_loader/nacl.scons instead; see the comment there for |
139 # why we don't. | 159 # why we don't. |
140 pll_loader = env.ComponentProgram( | 160 pll_loader = env.ComponentProgram( |
141 'pll_loader', [], | 161 'pll_loader', [], |
142 EXTRA_LIBS=['${NONIRT_LIBS}', 'pll_loader_main', 'pll_loader_lib']) | 162 EXTRA_LIBS=['${NONIRT_LIBS}', 'pll_loader_main', 'pll_loader_lib']) |
143 | 163 |
144 node = env.CommandSelLdrTestNacl( | 164 node = env.CommandSelLdrTestNacl( |
145 'pll_hello_world_test.out', pll_loader, | 165 'pll_hello_world_test.out', pll_loader, |
146 [translated_pll_libc, translated_pll_hello_world], | 166 [translated_pll_hello_world], |
147 # Add '-a' to enable filesystem access for opening DSOs. | 167 # Add '-a' to enable filesystem access for opening DSOs. |
148 sel_ldr_flags=['-a'], | 168 sel_ldr_flags=['-a'], |
149 stdout_golden=env.File('../hello_world/hello_world.stdout')) | 169 stdout_golden=env.File('../hello_world/hello_world.stdout'), |
| 170 extra_deps=[pll_libc]) |
150 env.AddNodeToTestSuite( | 171 env.AddNodeToTestSuite( |
151 node, ['small_tests', 'toolchain_tests'], | 172 node, ['small_tests', 'toolchain_tests'], |
152 'run_pll_hello_world_test', is_broken=is_broken) | 173 'run_pll_hello_world_test', is_broken=is_broken) |
| 174 |
| 175 |
| 176 test_pll_c_finalized = MakePll( |
| 177 'test_pll_c', 'test_pll_c.c', [test_pll_a_finalized, test_pll_b_finalized]) |
| 178 test_pll_c = TranslatePso('test_pll_c', test_pll_c_finalized) |
| 179 |
| 180 translated_pll_dependencies_test = MakeAndTranslatePll( |
| 181 'translated_pll_dependencies_test', 'dependencies_test.c', |
| 182 [pll_libc_finalized, test_pll_c_finalized]) |
| 183 |
| 184 node = env.CommandSelLdrTestNacl( |
| 185 'pll_dependencies_test.out', pll_loader, |
| 186 [translated_pll_dependencies_test], |
| 187 # Add '-a' to enable filesystem access for opening DSOs. |
| 188 sel_ldr_flags=['-a'], stdout_golden=env.File('dependencies_test.stdout'), |
| 189 extra_deps=[pll_libc, test_pll_a, test_pll_b, test_pll_c]) |
| 190 env.AddNodeToTestSuite( |
| 191 node, ['small_tests', 'toolchain_tests'], 'run_pll_dependencies_test', |
| 192 is_broken=is_broken) |
| 193 |
OLD | NEW |