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 | 24 |
25 def FinalizeAndTranslatePso(dest, opt_result): | 25 def FinalizePso(dest, opt_result): |
26 # Finalize to strip debugging info and to emit PNaCl bitcode. | 26 # Finalize to strip debugging info and to emit PNaCl bitcode. |
27 finalized_result = env.Command( | 27 return env.Command(dest + '.so', [opt_result], |
28 dest + '.final.pso', [opt_result], | 28 '${PNACLFINALIZE} ${SOURCES} -o ${TARGET}') |
29 '${PNACLFINALIZE} ${SOURCES} -o ${TARGET}') | 29 |
| 30 |
| 31 def TranslatePso(dest, finalized_result): |
30 # Translate to an ELF loadable object. | 32 # Translate to an ELF loadable object. |
31 return env.Command(dest + '.so', [finalized_result], | 33 return env.Command(dest + '.so.translated', [finalized_result], |
32 '${TRANSLATE} -pso ${SOURCES} -o ${TARGET}') | 34 '${TRANSLATE} -pso ${SOURCES} -o ${TARGET}') |
33 | 35 |
34 | 36 |
35 def MakeAndTranslatePso(dest, bitcode_file, llvm_passes): | 37 def MakeAndTranslatePso(dest, bitcode_file, llvm_passes): |
36 # Run opt to optionally apply PNaCl ABI simplifications to the IR and to | 38 # 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 | 39 # 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 | 40 # its invocation of Gold internalizes __pnacl_pso_root, which we want to |
39 # keep externally-visible. | 41 # keep externally-visible. |
40 opt_result = env.Command( | 42 opt_result = env.Command( |
41 dest + '.nonfinal.pso', [bitcode_file], | 43 dest + '.nonfinal.pso', [bitcode_file], |
42 '${PNACLOPT} ' + llvm_passes + ' ' | 44 '${PNACLOPT} ' + llvm_passes + ' ' |
43 '-verify-pnaclabi-module -verify-pnaclabi-functions ' | 45 '-verify-pnaclabi-module -verify-pnaclabi-functions ' |
44 '-pnaclabi-allow-debug-metadata ' | 46 '-pnaclabi-allow-debug-metadata ' |
45 '${SOURCES} -o ${TARGET}') | 47 '${SOURCES} -o ${TARGET}') |
46 return FinalizeAndTranslatePso(dest, opt_result) | 48 finalized_result = FinalizePso(dest, opt_result) |
| 49 return TranslatePso(dest, finalized_result) |
47 | 50 |
48 def PsoFromLLVMAssembly(base_name): | 51 def PsoFromLLVMAssembly(base_name): |
49 bitcode_file = env.Command( | 52 bitcode_file = env.Command( |
50 '%s.bc' % base_name, ['%s.ll' % base_name], | 53 '%s.bc' % base_name, ['%s.ll' % base_name], |
51 [Action('${ASCOM}', '${ASCOMSTR}')]) | 54 [Action('${ASCOM}', '${ASCOMSTR}')]) |
52 return MakeAndTranslatePso(base_name, [bitcode_file], | 55 return MakeAndTranslatePso(base_name, [bitcode_file], |
53 # Skip PNaCl passes because they add TLS functions. | 56 # Skip PNaCl passes because they add TLS functions. |
54 llvm_passes='') | 57 llvm_passes='') |
55 | 58 |
56 | 59 |
57 def MakeAndTranslatePll(dest, source_file): | 60 def MakePll(dest, source_file, dependencies): |
| 61 deps = '' |
| 62 if len(dependencies) != 0: |
| 63 deps += ' -L' + Dir('.').abspath |
| 64 for d in dependencies: |
| 65 deps += ' -l:' + d[0].name |
| 66 pll_object = env.ComponentObject(dest + '.po', [source_file]) |
58 nonfinal_pll = env.Command( | 67 nonfinal_pll = env.Command( |
59 dest + '.nonfinal.pll', [source_file], | 68 dest + '.nonfinal.pll', [pll_object], |
60 '${CC} -shared ${SOURCES} -o ${TARGET}') | 69 '${LD} -shared ${SOURCES} -o ${TARGET}' + deps) |
61 return FinalizeAndTranslatePso(dest, nonfinal_pll) | 70 # Linking the nonfinal_pll depends on the untranslated, finalized PLL (.so) |
| 71 # dependencies existing. |
| 72 Depends(nonfinal_pll, dependencies) |
| 73 return FinalizePso(dest, nonfinal_pll) |
| 74 |
| 75 def MakeAndTranslatePll(dest, source_file, dependencies): |
| 76 finalized_pll = MakePll(dest, source_file, dependencies) |
| 77 return TranslatePso(dest, finalized_pll) |
62 | 78 |
63 # Under SFI NaCl, the loader currently depends on the allocate_code_data() | 79 # Under SFI NaCl, the loader currently depends on the allocate_code_data() |
64 # interface provided by the IRT. | 80 # interface provided by the IRT. |
65 is_broken = not env.Bit('tests_use_irt') and not env.Bit('nonsfi_nacl') | 81 is_broken = not env.Bit('tests_use_irt') and not env.Bit('nonsfi_nacl') |
66 | 82 |
67 dso1 = MakeAndTranslatePso( | 83 dso1 = MakeAndTranslatePso( |
68 'test_pso', [env.ComponentObject('test_pso.c')], | 84 'test_pso', [env.ComponentObject('test_pso.c')], |
69 llvm_passes='-pnacl-abi-simplify-preopt -pnacl-abi-simplify-postopt') | 85 llvm_passes='-pnacl-abi-simplify-preopt -pnacl-abi-simplify-postopt') |
70 dso2 = PsoFromLLVMAssembly('data_only_pso') | 86 dso2 = PsoFromLLVMAssembly('data_only_pso') |
71 dso3 = PsoFromLLVMAssembly('data_only_pso_largebss') | 87 dso3 = PsoFromLLVMAssembly('data_only_pso_largebss') |
72 | 88 |
73 dynloader_test = env.ComponentProgram( | 89 dynloader_test = env.ComponentProgram( |
74 'dynloader_test', ['dynloader_test.c'], | 90 'dynloader_test', ['dynloader_test.c'], |
75 EXTRA_LIBS=['${NONIRT_LIBS}', 'pnacl_dynloader']) | 91 EXTRA_LIBS=['${NONIRT_LIBS}', 'pnacl_dynloader']) |
76 | 92 |
77 node = env.CommandSelLdrTestNacl( | 93 node = env.CommandSelLdrTestNacl( |
78 'dynloader_test.out', dynloader_test, [dso1, dso2, dso3], | 94 'dynloader_test.out', dynloader_test, [dso1, dso2, dso3], |
79 # Add '-a' to enable filesystem access for opening DSOs. | 95 # Add '-a' to enable filesystem access for opening DSOs. |
80 sel_ldr_flags=['-a']) | 96 sel_ldr_flags=['-a']) |
81 env.AddNodeToTestSuite( | 97 env.AddNodeToTestSuite( |
82 node, ['small_tests', 'toolchain_tests'], | 98 node, ['small_tests', 'toolchain_tests'], |
83 'run_pnacl_dynamic_loading_test', is_broken=is_broken) | 99 'run_pnacl_dynamic_loading_test', is_broken=is_broken) |
84 | 100 |
85 | 101 |
86 # Use of the ConvertToPSO pass requires this toolchain version. | 102 # Use of the ConvertToPSO pass requires this toolchain version. |
87 if env['TOOLCHAIN_FEATURE_VERSION'] < 24: | 103 if env['TOOLCHAIN_FEATURE_VERSION'] < 25: |
88 Return() | 104 Return() |
89 | 105 |
90 # TODO(smklein): These LLVM passes should be automatically applied by the | 106 test_pll_a_finalized = MakePll('test_pll_a', 'test_pll_a.c', []) |
91 # drivers. Once support for dependencies has been plumbed through the drivers, | 107 test_pll_a = TranslatePso('test_pll_a', test_pll_a_finalized) |
92 # use the "-l" linker flags and don't explicitly declare any LLVM passes. | 108 test_pll_b_finalized = MakePll('test_pll_b', 'test_pll_b.c', |
93 test_pll = MakeAndTranslatePso( | 109 [test_pll_a_finalized]) |
94 'test_pll', [env.ComponentObject('test_pll.c')], | 110 test_pll_b = TranslatePso('test_pll_b', test_pll_b_finalized) |
95 llvm_passes='-nacl-global-cleanup -expand-varargs ' | |
96 '-rewrite-pnacl-library-calls -rewrite-llvm-intrinsic-calls ' | |
97 '-convert-to-pso -convert-to-pso-deps=libfoo.so,libbar.so ' | |
98 '-pnacl-abi-simplify-postopt') | |
99 | 111 |
100 test_pll_tls = MakeAndTranslatePll('test_pll_tls', 'test_pll_tls.c') | 112 test_pll = MakeAndTranslatePll( |
| 113 'test_pll', 'test_pll.c', |
| 114 [test_pll_a_finalized, test_pll_b_finalized]) |
| 115 test_pll_tls = MakeAndTranslatePll('test_pll_tls', 'test_pll_tls.c', []) |
101 | 116 |
102 pll_symbols_test = env.ComponentProgram( | 117 pll_symbols_test = env.ComponentProgram( |
103 'pll_symbols_test', ['pll_symbols_test.cc'], | 118 'pll_symbols_test', ['pll_symbols_test.cc'], |
104 EXTRA_LIBS=['${NONIRT_LIBS}', 'pnacl_dynloader', 'pll_loader_lib']) | 119 EXTRA_LIBS=['${NONIRT_LIBS}', 'pnacl_dynloader', 'pll_loader_lib']) |
105 | 120 |
106 node = env.CommandSelLdrTestNacl( | 121 node = env.CommandSelLdrTestNacl( |
107 'pll_symbols_test.out', pll_symbols_test, [test_pll, test_pll_tls], | 122 'pll_symbols_test.out', pll_symbols_test, [test_pll, test_pll_tls], |
108 # Add '-a' to enable filesystem access for opening DSOs. | 123 # Add '-a' to enable filesystem access for opening DSOs. |
109 sel_ldr_flags=['-a']) | 124 sel_ldr_flags=['-a']) |
110 env.AddNodeToTestSuite( | 125 env.AddNodeToTestSuite( |
111 node, ['small_tests', 'toolchain_tests'], | 126 node, ['small_tests', 'toolchain_tests'], |
112 'run_pll_symbols_test', is_broken=is_broken) | 127 'run_pll_symbols_test', is_broken=is_broken) |
113 | 128 |
114 | 129 |
115 test_pll_a = MakeAndTranslatePll('test_pll_a', 'test_pll_a.c') | |
116 test_pll_b = MakeAndTranslatePll('test_pll_b', 'test_pll_b.c') | |
117 | |
118 pll_loader_test = env.ComponentProgram( | 130 pll_loader_test = env.ComponentProgram( |
119 'pll_loader_test', ['pll_loader_test.cc'], | 131 'pll_loader_test', ['pll_loader_test.cc'], |
120 EXTRA_LIBS=['${NONIRT_LIBS}', 'pll_loader_lib']) | 132 EXTRA_LIBS=['${NONIRT_LIBS}', 'pll_loader_lib']) |
121 | 133 |
122 node = env.CommandSelLdrTestNacl( | 134 node = env.CommandSelLdrTestNacl( |
123 'pll_loader_test.out', pll_loader_test, | 135 'pll_loader_test.out', pll_loader_test, |
124 [Dir('.').abspath, 'test_pll_a.so', 'test_pll_b.so', 'test_pll_tls.so'], | 136 [Dir('.').abspath, 'test_pll_a.so', 'test_pll_b.so', 'test_pll_tls.so'], |
125 # Add '-a' to enable filesystem access for opening DSOs. | 137 # Add '-a' to enable filesystem access for opening DSOs. |
126 sel_ldr_flags=['-a'], | 138 sel_ldr_flags=['-a'], |
127 extra_deps=[test_pll_a, test_pll_b, test_pll_tls]) | 139 extra_deps=[test_pll_a, test_pll_b, test_pll_tls]) |
128 env.AddNodeToTestSuite( | 140 env.AddNodeToTestSuite( |
129 node, ['small_tests', 'toolchain_tests'], | 141 node, ['small_tests', 'toolchain_tests'], |
130 'run_pll_loader_test', is_broken=is_broken) | 142 'run_pll_loader_test', is_broken=is_broken) |
131 | 143 |
132 | 144 |
133 pll_libc = env.Command( | 145 pll_libc_nonfinal = env.Command( |
134 'libc${OBJSUFFIX}', | 146 'libc${OBJSUFFIX}', |
135 # libnacl should come first so that it can override definitions in libc. | 147 # libnacl should come first so that it can override definitions in libc. |
136 [env.File('${LIB_DIR}/libnacl.a'), | 148 [env.File('${LIB_DIR}/libnacl.a'), |
137 env.File('${NACL_SDK_LIB}/libc.a'), | 149 env.File('${NACL_SDK_LIB}/libc.a'), |
138 env.ComponentObject('libc_entry.c')], | 150 env.ComponentObject('libc_entry.c')], |
139 '${CC} -shared -Wl,--whole-archive ${SOURCES} -o ${TARGET}') | 151 '${CC} -shared -Wl,--whole-archive ${SOURCES} -o ${TARGET}') |
140 | 152 |
141 translated_pll_libc = FinalizeAndTranslatePso('translated_pll_libc', pll_libc) | 153 pll_libc_finalized = FinalizePso('pll_libc', pll_libc_nonfinal) |
142 translated_pll_hello_world = MakeAndTranslatePll( | 154 pll_libc = TranslatePso('pll_libc', pll_libc_finalized) |
143 'translated_pll_hello_world', | 155 |
144 '../hello_world/hello_world.c') | 156 pll_hello_world = MakeAndTranslatePll( |
| 157 'pll_hello_world', |
| 158 '../hello_world/hello_world.c', |
| 159 [pll_libc_finalized]) |
145 | 160 |
146 # Ideally we would have this ComponentProgram() definition in | 161 # Ideally we would have this ComponentProgram() definition in |
147 # src/untrusted/pll_loader/nacl.scons instead; see the comment there for | 162 # src/untrusted/pll_loader/nacl.scons instead; see the comment there for |
148 # why we don't. | 163 # why we don't. |
149 pll_loader = env.ComponentProgram( | 164 pll_loader = env.ComponentProgram( |
150 'pll_loader', [], | 165 'pll_loader', [], |
151 EXTRA_LIBS=['${NONIRT_LIBS}', 'pll_loader_main', 'pll_loader_lib']) | 166 EXTRA_LIBS=['${NONIRT_LIBS}', 'pll_loader_main', 'pll_loader_lib']) |
152 | 167 |
153 node = env.CommandSelLdrTestNacl( | 168 node = env.CommandSelLdrTestNacl( |
154 'pll_hello_world_test.out', pll_loader, | 169 'pll_hello_world_test.out', pll_loader, |
155 [translated_pll_libc, translated_pll_hello_world], | 170 [Dir('.').abspath, pll_hello_world], |
156 # Add '-a' to enable filesystem access for opening DSOs. | 171 # Add '-a' to enable filesystem access for opening DSOs. |
157 sel_ldr_flags=['-a'], | 172 sel_ldr_flags=['-a'], |
158 stdout_golden=env.File('../hello_world/hello_world.stdout')) | 173 stdout_golden=env.File('../hello_world/hello_world.stdout'), |
| 174 extra_deps=[pll_libc, pll_hello_world]) |
159 env.AddNodeToTestSuite( | 175 env.AddNodeToTestSuite( |
160 node, ['small_tests', 'toolchain_tests'], | 176 node, ['small_tests', 'toolchain_tests'], |
161 'run_pll_hello_world_test', is_broken=is_broken) | 177 'run_pll_hello_world_test', is_broken=is_broken) |
| 178 |
| 179 |
| 180 test_pll_c_finalized = MakePll( |
| 181 'test_pll_c', 'test_pll_c.c', [test_pll_a_finalized, test_pll_b_finalized]) |
| 182 test_pll_c = TranslatePso('test_pll_c', test_pll_c_finalized) |
| 183 |
| 184 pll_dependencies_test = MakeAndTranslatePll( |
| 185 'pll_dependencies_test', 'dependencies_test.c', |
| 186 [pll_libc_finalized, test_pll_c_finalized]) |
| 187 |
| 188 node = env.CommandSelLdrTestNacl( |
| 189 'pll_dependencies_test.out', pll_loader, |
| 190 [Dir('.').abspath, pll_dependencies_test], |
| 191 # Add '-a' to enable filesystem access for opening DSOs. |
| 192 sel_ldr_flags=['-a'], stdout_golden=env.File('dependencies_test.stdout'), |
| 193 extra_deps=[pll_libc, test_pll_a, test_pll_b, test_pll_c, |
| 194 pll_dependencies_test]) |
| 195 env.AddNodeToTestSuite( |
| 196 node, ['small_tests', 'toolchain_tests'], 'run_pll_dependencies_test', |
| 197 is_broken=is_broken) |
OLD | NEW |