nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1Get crtbegin and crtend without compiler GCC! PR is at https://reviews.llvm.org/D28791
2
3Index: compiler-rt/CMakeLists.txt
4===================================================================
5--- compiler-rt/CMakeLists.txt
6+++ compiler-rt/CMakeLists.txt
7@@ -29,6 +29,8 @@
8
9 option(COMPILER_RT_BUILD_BUILTINS "Build builtins" ON)
10 mark_as_advanced(COMPILER_RT_BUILD_BUILTINS)
11+option(COMPILER_RT_BUILD_CRT "Build crtbegin.o/crtend.o" ON)
12+mark_as_advanced(COMPILER_RT_BUILD_CRT)
13 option(COMPILER_RT_BUILD_SANITIZERS "Build sanitizers" ON)
14 mark_as_advanced(COMPILER_RT_BUILD_SANITIZERS)
15 option(COMPILER_RT_BUILD_XRAY "Build xray" ON)
16Index: compiler-rt/cmake/Modules/AddCompilerRT.cmake
17===================================================================
18--- compiler-rt/cmake/Modules/AddCompilerRT.cmake
19+++ compiler-rt/cmake/Modules/AddCompilerRT.cmake
20@@ -132,7 +132,7 @@
21 # Adds static or shared runtime for a list of architectures and operating
22 # systems and puts it in the proper directory in the build and install trees.
23 # add_compiler_rt_runtime(<name>
24-# {STATIC|SHARED}
25+# {OBJECT|STATIC|SHARED}
26 # ARCHS <architectures>
27 # OS <os list>
28 # SOURCES <source files>
29@@ -144,8 +144,8 @@
30 # PARENT_TARGET <convenience parent target>
31 # ADDITIONAL_HEADERS <header files>)
32 function(add_compiler_rt_runtime name type)
33- if(NOT type MATCHES "^(STATIC|SHARED)$")
34- message(FATAL_ERROR "type argument must be STATIC or SHARED")
35+ if(NOT type MATCHES "^(OBJECT|STATIC|SHARED)$")
36+ message(FATAL_ERROR "type argument must be OBJECT, STATIC or SHARED")
37 return()
38 endif()
39 cmake_parse_arguments(LIB
40@@ -204,7 +204,10 @@
41 message(FATAL_ERROR "Architecture ${arch} can't be targeted")
42 return()
43 endif()
44- if(type STREQUAL "STATIC")
45+ if(type STREQUAL "OBJECT")
46+ set(libname "${name}-${arch}")
47+ set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX})
48+ elseif(type STREQUAL "STATIC")
49 set(libname "${name}-${arch}")
50 set_output_name(output_name_${libname} ${name} ${arch})
51 else()
52@@ -270,12 +273,34 @@
53 set(COMPONENT_OPTION COMPONENT ${libname})
54 endif()
55
56- add_library(${libname} ${type} ${sources_${libname}})
57- set_target_compile_flags(${libname} ${extra_cflags_${libname}})
58- set_target_link_flags(${libname} ${extra_link_flags_${libname}})
59- set_property(TARGET ${libname} APPEND PROPERTY
60- COMPILE_DEFINITIONS ${LIB_DEFS})
61- set_target_output_directories(${libname} ${output_dir_${libname}})
62+ if(type STREQUAL "OBJECT")
63+ string(TOUPPER ${CMAKE_BUILD_TYPE} config)
64+ get_property(cflags SOURCE ${sources_${libname}} PROPERTY COMPILE_FLAGS)
65+ separate_arguments(cflags)
66+ add_custom_command(
67+ OUTPUT ${output_dir_${libname}}/${libname}.o
68+ COMMAND ${CMAKE_C_COMPILER} ${sources_${libname}} ${cflags} ${extra_cflags_${libname}} -c -o ${output_dir_${libname}}/${libname}.o
69+ DEPENDS ${sources_${libname}}
70+ COMMENT "Building C object ${libname}.o")
71+ add_custom_target(${libname} DEPENDS ${output_dir_${libname}}/${libname}.o)
72+ install(FILES ${output_dir_${libname}}/${libname}.o
73+ DESTINATION ${install_dir_${libname}}
74+ ${COMPONENT_OPTION})
75+ else()
76+ add_library(${libname} ${type} ${sources_${libname}})
77+ set_target_compile_flags(${libname} ${extra_cflags_${libname}})
78+ set_target_link_flags(${libname} ${extra_link_flags_${libname}})
79+ set_property(TARGET ${libname} APPEND PROPERTY
80+ COMPILE_DEFINITIONS ${LIB_DEFS})
81+ set_target_output_directories(${libname} ${output_dir_${libname}})
82+ install(TARGETS ${libname}
83+ ARCHIVE DESTINATION ${install_dir_${libname}}
84+ ${COMPONENT_OPTION}
85+ LIBRARY DESTINATION ${install_dir_${libname}}
86+ ${COMPONENT_OPTION}
87+ RUNTIME DESTINATION ${install_dir_${libname}}
88+ ${COMPONENT_OPTION})
89+ endif()
90 set_target_properties(${libname} PROPERTIES
91 OUTPUT_NAME ${output_name_${libname}})
92 set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Runtime")
93@@ -299,13 +324,6 @@
94 )
95 endif()
96 endif()
97- install(TARGETS ${libname}
98- ARCHIVE DESTINATION ${install_dir_${libname}}
99- ${COMPONENT_OPTION}
100- LIBRARY DESTINATION ${install_dir_${libname}}
101- ${COMPONENT_OPTION}
102- RUNTIME DESTINATION ${install_dir_${libname}}
103- ${COMPONENT_OPTION})
104
105 # We only want to generate per-library install targets if you aren't using
106 # an IDE because the extra targets get cluttered in IDEs.
107Index: compiler-rt/cmake/config-ix.cmake
108===================================================================
109--- compiler-rt/cmake/config-ix.cmake
110+++ compiler-rt/cmake/config-ix.cmake
111@@ -227,6 +227,7 @@
112 ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${S390X})
113 set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64}
114 ${MIPS32} ${MIPS64} ${PPC64} ${S390X})
115+set(ALL_CRT_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64})
116 set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})
117 set(ALL_FUZZER_SUPPORTED_ARCH ${X86_64} ${ARM64})
118
119@@ -474,6 +475,7 @@
120 SANITIZER_COMMON_SUPPORTED_ARCH)
121
122 else()
123+ filter_available_targets(CRT_SUPPORTED_ARCH ${ALL_CRT_SUPPORTED_ARCH})
124 # Architectures supported by compiler-rt libraries.
125 filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH
126 ${ALL_SANITIZER_COMMON_SUPPORTED_ARCH})
127@@ -563,6 +565,12 @@
128
129 # TODO: Add builtins support.
130
131+if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux")
132+ set(COMPILER_RT_HAS_CRT TRUE)
133+else()
134+ set(COMPILER_RT_HAS_CRT FALSE)
135+endif()
136+
137 if (COMPILER_RT_HAS_SANITIZER_COMMON AND DFSAN_SUPPORTED_ARCH AND
138 OS_NAME MATCHES "Linux")
139 set(COMPILER_RT_HAS_DFSAN TRUE)
140Index: compiler-rt/lib/CMakeLists.txt
141===================================================================
142--- compiler-rt/lib/CMakeLists.txt
143+++ compiler-rt/lib/CMakeLists.txt
144@@ -17,6 +17,10 @@
145 add_subdirectory(builtins)
146 endif()
147
148+if(COMPILER_RT_BUILD_CRT)
149+ add_subdirectory(crt)
150+endif()
151+
152 function(compiler_rt_build_runtime runtime)
153 string(TOUPPER ${runtime} runtime_uppercase)
154 if(COMPILER_RT_HAS_${runtime_uppercase})
155Index: compiler-rt/lib/crt/CMakeLists.txt
156===================================================================
157--- /dev/null
158+++ compiler-rt/lib/crt/CMakeLists.txt
159@@ -0,0 +1,102 @@
160+add_compiler_rt_component(crt)
161+
162+function(check_cxx_section_exists section output)
163+ cmake_parse_arguments(ARG "" "" "SOURCE;FLAGS" ${ARGN})
164+ if(NOT ARG_SOURCE)
165+ set(ARG_SOURCE "int main() { return 0; }\n")
166+ endif()
167+
168+ string(RANDOM TARGET_NAME)
169+ set(TARGET_NAME "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cmTC_${TARGET_NAME}.dir")
170+ file(MAKE_DIRECTORY ${TARGET_NAME})
171+
172+ file(WRITE "${TARGET_NAME}/CheckSectionExists.c" "${ARG_SOURCE}\n")
173+
174+ string(REGEX MATCHALL "<[A-Za-z0-9_]*>" substitutions
175+ ${CMAKE_C_COMPILE_OBJECT})
176+
177+ set(try_compile_flags "${ARG_FLAGS}")
178+ if(CMAKE_C_COMPILER_ID MATCHES Clang AND CMAKE_C_COMPILER_TARGET)
179+ list(APPEND try_compile_flags "-target ${CMAKE_C_COMPILER_TARGET}")
180+ endif()
181+
182+ string(REPLACE ";" " " extra_flags "${try_compile_flags}")
183+
184+ set(test_compile_command "${CMAKE_C_COMPILE_OBJECT}")
185+ foreach(substitution ${substitutions})
186+ if(substitution STREQUAL "<CMAKE_C_COMPILER>")
187+ string(REPLACE "<CMAKE_C_COMPILER>"
188+ "${CMAKE_C_COMPILER}" test_compile_command ${test_compile_command})
189+ elseif(substitution STREQUAL "<OBJECT>")
190+ string(REPLACE "<OBJECT>" "${TARGET_NAME}/CheckSectionExists.o"
191+ test_compile_command ${test_compile_command})
192+ elseif(substitution STREQUAL "<SOURCE>")
193+ string(REPLACE "<SOURCE>" "${TARGET_NAME}/CheckSectionExists.c"
194+ test_compile_command ${test_compile_command})
195+ elseif(substitution STREQUAL "<FLAGS>")
196+ string(REPLACE "<FLAGS>" "${CMAKE_C_FLAGS} ${extra_flags}"
197+ test_compile_command ${test_compile_command})
198+ else()
199+ string(REPLACE "${substitution}" "" test_compile_command
200+ ${test_compile_command})
201+ endif()
202+ endforeach()
203+
204+ string(REPLACE " " ";" test_compile_command "${test_compile_command}")
205+
206+ execute_process(
207+ COMMAND ${test_compile_command}
208+ RESULT_VARIABLE TEST_RESULT
209+ OUTPUT_VARIABLE TEST_OUTPUT
210+ ERROR_VARIABLE TEST_ERROR
211+ )
212+
213+ execute_process(
214+ COMMAND ${CMAKE_OBJDUMP} -h "${TARGET_NAME}/CheckSectionExists.o"
215+ RESULT_VARIABLE CHECK_RESULT
216+ OUTPUT_VARIABLE CHECK_OUTPUT
217+ ERROR_VARIABLE CHECK_ERROR
218+ )
219+ string(FIND "${CHECK_OUTPUT}" "${section}" SECTION_FOUND)
220+
221+ if(NOT SECTION_FOUND EQUAL -1)
222+ set(${output} TRUE PARENT_SCOPE)
223+ else()
224+ set(${output} FALSE PARENT_SCOPE)
225+ endif()
226+
227+ file(REMOVE_RECURSE ${TARGET_NAME})
228+endfunction()
229+
230+check_cxx_section_exists(".init_array" COMPILER_RT_HAS_INITFINI_ARRAY
231+ SOURCE "__attribute__((constructor)) void f() {}\nint main() { return 0; }\n")
232+
233+append_list_if(COMPILER_RT_HAS_INITFINI_ARRAY -DCRT_HAS_INITFINI_ARRAY CRT_CFLAGS)
234+append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC CRT_CFLAGS)
235+
236+foreach(arch ${CRT_SUPPORTED_ARCH})
237+ add_compiler_rt_runtime(clang_rt.crtbegin
238+ OBJECT
239+ ARCHS ${arch}
240+ SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/crtbegin.c
241+ CFLAGS ${CRT_CFLAGS}
242+ PARENT_TARGET crt)
243+ add_compiler_rt_runtime(clang_rt.crtbegin_shared
244+ OBJECT
245+ ARCHS ${arch}
246+ SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/crtbegin.c
247+ CFLAGS ${CRT_CFLAGS} -DCRT_SHARED
248+ PARENT_TARGET crt)
249+ add_compiler_rt_runtime(clang_rt.crtend
250+ OBJECT
251+ ARCHS ${arch}
252+ SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/crtend.c
253+ CFLAGS ${CRT_CFLAGS}
254+ PARENT_TARGET crt)
255+ add_compiler_rt_runtime(clang_rt.crtend_shared
256+ OBJECT
257+ ARCHS ${arch}
258+ SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/crtend.c
259+ CFLAGS ${CRT_CFLAGS} -DCRT_SHARED
260+ PARENT_TARGET crt)
261+endforeach()
262Index: compiler-rt/lib/crt/crtbegin.c
263===================================================================
264--- /dev/null
265+++ compiler-rt/lib/crt/crtbegin.c
266@@ -0,0 +1,108 @@
267+/* ===-- crtbegin.c - Start of constructors and destructors ----------------===
268+ *
269+ * The LLVM Compiler Infrastructure
270+ *
271+ * This file is dual licensed under the MIT and the University of Illinois Open
272+ * Source Licenses. See LICENSE.TXT for details.
273+ *
274+ * ===----------------------------------------------------------------------===
275+ */
276+
277+#include <stddef.h>
278+
279+__attribute__((visibility("hidden")))
280+#ifdef CRT_SHARED
281+void *__dso_handle = &__dso_handle;
282+#else
283+void *__dso_handle = (void *)0;
284+#endif
285+
286+static long __EH_FRAME_LIST__[]
287+ __attribute__((section(".eh_frame"), aligned(sizeof(void *)))) = {};
288+
289+extern void __register_frame_info(const void *, void *) __attribute__((weak));
290+extern void *__deregister_frame_info(const void *) __attribute__((weak));
291+
292+#ifndef CRT_HAS_INITFINI_ARRAY
293+typedef void (*fp)(void);
294+
295+static fp __CTOR_LIST__[]
296+ __attribute__((section(".ctors"), aligned(sizeof(fp)), used)) = {(fp)-1};
297+extern fp __CTOR_LIST_END__[];
298+#endif
299+
300+#ifdef CRT_SHARED
301+extern void __cxa_finalize(void *) __attribute__((weak));
302+#endif
303+
304+static void __attribute__((used)) __do_init() {
305+ static _Bool __initialized;
306+ if (__builtin_expect(__initialized, 0))
307+ return;
308+ __initialized = 1;
309+
310+ static struct { void *p[8]; } __object;
311+ if (__register_frame_info)
312+ __register_frame_info(__EH_FRAME_LIST__, &__object);
313+
314+#ifndef CRT_HAS_INITFINI_ARRAY
315+ const size_t n = __CTOR_LIST_END__ - __CTOR_LIST__ - 1;
316+ for (size_t i = n; i >= 1; i--) __CTOR_LIST__[i]();
317+#endif
318+}
319+
320+#ifdef CRT_HAS_INITFINI_ARRAY
321+__attribute__((section(".init_array"),
322+ used)) static void (*__init)(void) = __do_init;
323+#else // CRT_HAS_INITFINI_ARRAY
324+#if defined(__i386__) || defined(__x86_64__)
325+asm(".pushsection .init,\"ax\",@progbits\n\t"
326+ "call " __USER_LABEL_PREFIX__ "__do_init\n\t"
327+ ".popsection");
328+#elif defined(__arm__)
329+asm(".pushsection .init,\"ax\",%progbits\n\t"
330+ "bl " __USER_LABEL_PREFIX__ "__do_init\n\t"
331+ ".popsection");
332+#endif // CRT_HAS_INITFINI_ARRAY
333+#endif
334+
335+#ifndef CRT_HAS_INITFINI_ARRAY
336+static fp __DTOR_LIST__[]
337+ __attribute__((section(".dtors"), aligned(sizeof(fp)), used)) = {(fp)-1};
338+extern fp __DTOR_LIST_END__[];
339+#endif
340+
341+static void __attribute__((used)) __do_fini() {
342+ static _Bool __finalized;
343+ if (__builtin_expect(__finalized, 0))
344+ return;
345+ __finalized = 1;
346+
347+#ifdef CRT_SHARED
348+ if (__cxa_finalize)
349+ __cxa_finalize(__dso_handle);
350+#endif
351+
352+#ifndef CRT_HAS_INITFINI_ARRAY
353+ if (__deregister_frame_info)
354+ __deregister_frame_info(__EH_FRAME_LIST__);
355+
356+ const size_t n = __DTOR_LIST_END__ - __DTOR_LIST__ - 1;
357+ for (size_t i = 1; i < n; i++) __DTOR_LIST__[i]();
358+#endif
359+}
360+
361+#ifdef CRT_HAS_INITFINI_ARRAY
362+__attribute__((section(".fini_array"),
363+ used)) static void (*__fini)(void) = __do_fini;
364+#else // CRT_HAS_INITFINI_ARRAY
365+#if defined(__i386__) || defined(__x86_64__)
366+asm(".pushsection .fini,\"ax\",@progbits\n\t"
367+ "call " __USER_LABEL_PREFIX__ "__do_fini\n\t"
368+ ".popsection");
369+#elif defined(__arm__)
370+asm(".pushsection .fini,\"ax\",%progbits\n\t"
371+ "bl " __USER_LABEL_PREFIX__ "__do_fini\n\t"
372+ ".popsection");
373+#endif
374+#endif // CRT_HAS_INIT_FINI_ARRAY
375Index: compiler-rt/lib/crt/crtend.c
376===================================================================
377--- /dev/null
378+++ compiler-rt/lib/crt/crtend.c
379@@ -0,0 +1,24 @@
380+/* ===-- crtend.c - End of constructors and destructors --------------------===
381+ *
382+ * The LLVM Compiler Infrastructure
383+ *
384+ * This file is dual licensed under the MIT and the University of Illinois Open
385+ * Source Licenses. See LICENSE.TXT for details.
386+ *
387+ * ===----------------------------------------------------------------------===
388+ */
389+
390+#include <stdint.h>
391+
392+// Put 4-byte zero which is the length field in FDE at the end as a terminator.
393+const int32_t __EH_FRAME_LIST_END__[]
394+ __attribute__((section(".eh_frame"), aligned(sizeof(int32_t)),
395+ visibility("hidden"), used)) = {0};
396+
397+#ifndef CRT_HAS_INITFINI_ARRAY
398+typedef void (*fp)(void);
399+fp __CTOR_LIST_END__[]
400+ __attribute__((section(".ctors"), visibility("hidden"), used)) = {0};
401+fp __DTOR_LIST_END__[]
402+ __attribute__((section(".dtors"), visibility("hidden"), used)) = {0};
403+#endif
404Index: compiler-rt/test/CMakeLists.txt
405===================================================================
406--- compiler-rt/test/CMakeLists.txt
407+++ compiler-rt/test/CMakeLists.txt
408@@ -73,6 +73,9 @@
409 if(COMPILER_RT_BUILD_XRAY)
410 compiler_rt_test_runtime(xray)
411 endif()
412+ if(COMPILER_RT_HAS_CRT)
413+ add_subdirectory(crt)
414+ endif()
415 # ShadowCallStack does not yet provide a runtime with compiler-rt, the tests
416 # include their own minimal runtime
417 add_subdirectory(shadowcallstack)
418Index: compiler-rt/test/crt/CMakeLists.txt
419===================================================================
420--- /dev/null
421+++ compiler-rt/test/crt/CMakeLists.txt
422@@ -0,0 +1,31 @@
423+set(CRT_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
424+
425+set(CRT_TESTSUITES)
426+
427+set(CRT_TEST_DEPS "")
428+
429+if(NOT COMPILER_RT_STANDALONE_BUILD AND COMPILER_RT_BUILD_CRT AND
430+ COMPILER_RT_HAS_CRT)
431+ list(APPEND CRT_TEST_DEPS crt)
432+endif()
433+
434+set(CRT_TEST_ARCH ${CRT_SUPPORTED_ARCH})
435+if (COMPILER_RT_BUILD_CRT AND COMPILER_RT_HAS_CRT)
436+ foreach(arch ${CRT_TEST_ARCH})
437+ set(CRT_TEST_TARGET_ARCH ${arch})
438+ string(TOLOWER "-${arch}-${OS_NAME}" CRT_TEST_CONFIG_SUFFIX)
439+ get_test_cc_for_arch(${arch} CRT_TEST_TARGET_CC CRT_TEST_TARGET_CFLAGS)
440+ string(TOUPPER ${arch} ARCH_UPPER_CASE)
441+ set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config)
442+
443+ configure_lit_site_cfg(
444+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
445+ ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg)
446+ list(APPEND CRT_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME})
447+ endforeach()
448+endif()
449+
450+add_lit_testsuite(check-crt "Running the CRT tests"
451+ ${CRT_TESTSUITES}
452+ DEPENDS ${CRT_TEST_DEPS})
453+set_target_properties(check-crt PROPERTIES FOLDER "Compiler-RT Misc")
454Index: compiler-rt/test/crt/dso_handle.cpp
455===================================================================
456--- /dev/null
457+++ compiler-rt/test/crt/dso_handle.cpp
458@@ -0,0 +1,33 @@
459+// RUN: %clangxx -g -DCRT_SHARED -c %s -fPIC -o %tshared.o
460+// RUN: %clangxx -g -c %s -fPIC -o %t.o
461+// RUN: %clangxx -g -shared -o %t.so -nostdlib %crti %shared_crtbegin %tshared.o %libstdcxx -lc -lm -lgcc_s %shared_crtend %crtn
462+// RUN: %clangxx -g -o %t -nostdlib %crt1 %crti %crtbegin %t.o %libstdcxx -lc -lm %libgcc %t.so %crtend %crtn
463+// RUN: %run %t 2>&1 | FileCheck %s
464+
465+#include <stdio.h>
466+
467+// CHECK: 1
468+// CHECK-NEXT: ~A()
469+
470+#ifdef CRT_SHARED
471+bool G;
472+void C() {
473+ printf("%d\n", G);
474+}
475+
476+struct A {
477+ A() { G = true; }
478+ ~A() {
479+ printf("~A()\n");
480+ }
481+};
482+
483+A a;
484+#else
485+void C();
486+
487+int main() {
488+ C();
489+ return 0;
490+}
491+#endif
492Index: compiler-rt/test/crt/lit.cfg
493===================================================================
494--- /dev/null
495+++ compiler-rt/test/crt/lit.cfg
496@@ -0,0 +1,80 @@
497+# -*- Python -*-
498+
499+import os
500+import subprocess
501+
502+# Setup config name.
503+config.name = 'CRT' + config.name_suffix
504+
505+# Setup source root.
506+config.test_source_root = os.path.dirname(__file__)
507+
508+
509+def get_library_path(file):
510+ cmd = subprocess.Popen([config.clang.strip(),
511+ config.target_cflags.strip(),
512+ '-print-file-name=%s' % file],
513+ stdout=subprocess.PIPE,
514+ env=config.environment)
515+ if not cmd.stdout:
516+ lit_config.fatal("Couldn't find the library path for '%s'" % file)
517+ dir = cmd.stdout.read().strip()
518+ if sys.platform in ['win32'] and execute_external:
519+ # Don't pass dosish path separator to msys bash.exe.
520+ dir = dir.replace('\\', '/')
521+ # Ensure the result is an ascii string, across Python2.5+ - Python3.
522+ return str(dir.decode('ascii'))
523+
524+
525+def get_libgcc_file_name():
526+ cmd = subprocess.Popen([config.clang.strip(),
527+ config.target_cflags.strip(),
528+ '-print-libgcc-file-name'],
529+ stdout=subprocess.PIPE,
530+ env=config.environment)
531+ if not cmd.stdout:
532+ lit_config.fatal("Couldn't find the library path for '%s'" % file)
533+ dir = cmd.stdout.read().strip()
534+ if sys.platform in ['win32'] and execute_external:
535+ # Don't pass dosish path separator to msys bash.exe.
536+ dir = dir.replace('\\', '/')
537+ # Ensure the result is an ascii string, across Python2.5+ - Python3.
538+ return str(dir.decode('ascii'))
539+
540+
541+def build_invocation(compile_flags):
542+ return ' ' + ' '.join([config.clang] + compile_flags) + ' '
543+
544+
545+# Setup substitutions.
546+config.substitutions.append(
547+ ('%clang ', build_invocation([config.target_cflags])))
548+config.substitutions.append(
549+ ('%clangxx ',
550+ build_invocation(config.cxx_mode_flags + [config.target_cflags])))
551+
552+base_lib = os.path.join(
553+ config.compiler_rt_libdir, "clang_rt.%%s-%s.o" % config.target_arch)
554+config.substitutions.append(('%crtbegin', base_lib % "crtbegin"))
555+config.substitutions.append(('%shared_crtbegin', base_lib % "crtbegin_shared"))
556+config.substitutions.append(('%crtend', base_lib % "crtend"))
557+config.substitutions.append(('%shared_crtend', base_lib % "crtend_shared"))
558+
559+config.substitutions.append(
560+ ('%crt1', get_library_path('crt1.o')))
561+config.substitutions.append(
562+ ('%crti', get_library_path('crti.o')))
563+config.substitutions.append(
564+ ('%crtn', get_library_path('crtn.o')))
565+
566+config.substitutions.append(
567+ ('%libgcc', get_libgcc_file_name()))
568+
569+config.substitutions.append(
570+ ('%libstdcxx', '-l' + config.sanitizer_cxx_lib.lstrip('lib')))
571+
572+# Default test suffixes.
573+config.suffixes = ['.c', '.cc', '.cpp']
574+
575+if config.host_os not in ['Linux']:
576+ config.unsupported = True
577Index: compiler-rt/test/crt/lit.site.cfg.in
578===================================================================
579--- /dev/null
580+++ compiler-rt/test/crt/lit.site.cfg.in
581@@ -0,0 +1,14 @@
582+@LIT_SITE_CFG_IN_HEADER@
583+
584+# Tool-specific config options.
585+config.name_suffix = "@CRT_TEST_CONFIG_SUFFIX@"
586+config.crt_lit_source_dir = "@CRT_LIT_SOURCE_DIR@"
587+config.target_cflags = "@CRT_TEST_TARGET_CFLAGS@"
588+config.target_arch = "@CRT_TEST_TARGET_ARCH@"
589+config.sanitizer_cxx_lib = "@SANITIZER_TEST_CXX_LIBNAME@"
590+
591+# Load common config for all compiler-rt lit tests
592+lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
593+
594+# Load tool-specific config that would do the real work.
595+lit_config.load_config(config, "@CRT_LIT_SOURCE_DIR@/lit.cfg")