Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[compiler-rt] Simple crtbegin.o and crtend.o implementation
Clang relies on existence of certain symbols that are normally provided by crtbegin.o/crtend.o. However, LLVM does not currently provide implementation of these files, instead relying on either libgcc or implementations provided as part of the system. This change provides an initial implementation of crtbegin.o/crtend.o that can be used on system that don't provide crtbegin.o/crtend.o as part of their C library. Differential Revision: https://reviews.llvm.org/D28791 llvm-svn: 359576
- Loading branch information
Showing
12 changed files
with
420 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
add_compiler_rt_component(crt) | ||
|
||
function(check_cxx_section_exists section output) | ||
cmake_parse_arguments(ARG "" "" "SOURCE;FLAGS" ${ARGN}) | ||
if(NOT ARG_SOURCE) | ||
set(ARG_SOURCE "int main() { return 0; }\n") | ||
endif() | ||
|
||
string(RANDOM TARGET_NAME) | ||
set(TARGET_NAME "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cmTC_${TARGET_NAME}.dir") | ||
file(MAKE_DIRECTORY ${TARGET_NAME}) | ||
|
||
file(WRITE "${TARGET_NAME}/CheckSectionExists.c" "${ARG_SOURCE}\n") | ||
|
||
string(REGEX MATCHALL "<[A-Za-z0-9_]*>" substitutions | ||
${CMAKE_C_COMPILE_OBJECT}) | ||
|
||
set(try_compile_flags "${ARG_FLAGS}") | ||
if(CMAKE_C_COMPILER_ID MATCHES Clang AND CMAKE_C_COMPILER_TARGET) | ||
list(APPEND try_compile_flags "-target ${CMAKE_C_COMPILER_TARGET}") | ||
endif() | ||
|
||
string(REPLACE ";" " " extra_flags "${try_compile_flags}") | ||
|
||
set(test_compile_command "${CMAKE_C_COMPILE_OBJECT}") | ||
foreach(substitution ${substitutions}) | ||
if(substitution STREQUAL "<CMAKE_C_COMPILER>") | ||
string(REPLACE "<CMAKE_C_COMPILER>" | ||
"${CMAKE_C_COMPILER}" test_compile_command ${test_compile_command}) | ||
elseif(substitution STREQUAL "<OBJECT>") | ||
string(REPLACE "<OBJECT>" "${TARGET_NAME}/CheckSectionExists.o" | ||
test_compile_command ${test_compile_command}) | ||
elseif(substitution STREQUAL "<SOURCE>") | ||
string(REPLACE "<SOURCE>" "${TARGET_NAME}/CheckSectionExists.c" | ||
test_compile_command ${test_compile_command}) | ||
elseif(substitution STREQUAL "<FLAGS>") | ||
string(REPLACE "<FLAGS>" "${CMAKE_C_FLAGS} ${extra_flags}" | ||
test_compile_command ${test_compile_command}) | ||
else() | ||
string(REPLACE "${substitution}" "" test_compile_command | ||
${test_compile_command}) | ||
endif() | ||
endforeach() | ||
|
||
string(REPLACE " " ";" test_compile_command "${test_compile_command}") | ||
|
||
execute_process( | ||
COMMAND ${test_compile_command} | ||
RESULT_VARIABLE TEST_RESULT | ||
OUTPUT_VARIABLE TEST_OUTPUT | ||
ERROR_VARIABLE TEST_ERROR | ||
) | ||
|
||
execute_process( | ||
COMMAND ${CMAKE_OBJDUMP} -h "${TARGET_NAME}/CheckSectionExists.o" | ||
RESULT_VARIABLE CHECK_RESULT | ||
OUTPUT_VARIABLE CHECK_OUTPUT | ||
ERROR_VARIABLE CHECK_ERROR | ||
) | ||
string(FIND "${CHECK_OUTPUT}" "${section}" SECTION_FOUND) | ||
|
||
if(NOT SECTION_FOUND EQUAL -1) | ||
set(${output} TRUE PARENT_SCOPE) | ||
else() | ||
set(${output} FALSE PARENT_SCOPE) | ||
endif() | ||
|
||
file(REMOVE_RECURSE ${TARGET_NAME}) | ||
endfunction() | ||
|
||
check_cxx_section_exists(".init_array" COMPILER_RT_HAS_INITFINI_ARRAY | ||
SOURCE "__attribute__((constructor)) void f() {}\nint main() { return 0; }\n") | ||
|
||
append_list_if(COMPILER_RT_HAS_INITFINI_ARRAY -DCRT_HAS_INITFINI_ARRAY CRT_CFLAGS) | ||
append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC CRT_CFLAGS) | ||
|
||
foreach(arch ${CRT_SUPPORTED_ARCH}) | ||
add_compiler_rt_runtime(clang_rt.crtbegin | ||
OBJECT | ||
ARCHS ${arch} | ||
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/crtbegin.c | ||
CFLAGS ${CRT_CFLAGS} | ||
PARENT_TARGET crt) | ||
add_compiler_rt_runtime(clang_rt.crtend | ||
OBJECT | ||
ARCHS ${arch} | ||
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/crtend.c | ||
CFLAGS ${CRT_CFLAGS} | ||
PARENT_TARGET crt) | ||
endforeach() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
//===-- crtbegin.c - Start of constructors and destructors ----------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include <stddef.h> | ||
|
||
__attribute__((visibility("hidden"))) void *__dso_handle = &__dso_handle; | ||
|
||
static void *__EH_FRAME_LIST__[] | ||
__attribute__((section(".eh_frame"), aligned(sizeof(void *)))) = {}; | ||
|
||
extern void __register_frame_info(const void *, void *) __attribute__((weak)); | ||
extern void *__deregister_frame_info(const void *) __attribute__((weak)); | ||
|
||
#ifndef CRT_HAS_INITFINI_ARRAY | ||
typedef void (*fp)(void); | ||
|
||
static fp __CTOR_LIST__[] | ||
__attribute__((section(".ctors"), aligned(sizeof(fp)))) = {(fp)-1}; | ||
extern fp __CTOR_LIST_END__[]; | ||
#endif | ||
|
||
extern void __cxa_finalize(void *) __attribute__((weak)); | ||
|
||
static void __attribute__((used)) __do_init() { | ||
static _Bool __initialized; | ||
if (__builtin_expect(__initialized, 0)) | ||
return; | ||
__initialized = 1; | ||
|
||
static struct { void *p[8]; } __object; | ||
if (__register_frame_info) | ||
__register_frame_info(__EH_FRAME_LIST__, &__object); | ||
|
||
#ifndef CRT_HAS_INITFINI_ARRAY | ||
const size_t n = __CTOR_LIST_END__ - __CTOR_LIST__ - 1; | ||
for (size_t i = n; i >= 1; i--) __CTOR_LIST__[i](); | ||
#endif | ||
} | ||
|
||
#ifdef CRT_HAS_INITFINI_ARRAY | ||
__attribute__((section(".init_array"), | ||
used)) static void (*__init)(void) = __do_init; | ||
#else // CRT_HAS_INITFINI_ARRAY | ||
#if defined(__i386__) || defined(__x86_64__) | ||
asm(".pushsection .init,\"ax\",@progbits\n\t" | ||
"call " __USER_LABEL_PREFIX__ "__do_init\n\t" | ||
".popsection"); | ||
#elif defined(__arm__) | ||
asm(".pushsection .init,\"ax\",%progbits\n\t" | ||
"bl " __USER_LABEL_PREFIX__ "__do_init\n\t" | ||
".popsection"); | ||
#endif // CRT_HAS_INITFINI_ARRAY | ||
#endif | ||
|
||
#ifndef CRT_HAS_INITFINI_ARRAY | ||
static fp __DTOR_LIST__[] | ||
__attribute__((section(".dtors"), aligned(sizeof(fp)))) = {(fp)-1}; | ||
extern fp __DTOR_LIST_END__[]; | ||
#endif | ||
|
||
static void __attribute__((used)) __do_fini() { | ||
static _Bool __finalized; | ||
if (__builtin_expect(__finalized, 0)) | ||
return; | ||
__finalized = 1; | ||
|
||
if (__cxa_finalize) | ||
__cxa_finalize(__dso_handle); | ||
|
||
#ifndef CRT_HAS_INITFINI_ARRAY | ||
if (__deregister_frame_info) | ||
__deregister_frame_info(__EH_FRAME_LIST__); | ||
|
||
const size_t n = __DTOR_LIST_END__ - __DTOR_LIST__ - 1; | ||
for (size_t i = 1; i < n; i++) __DTOR_LIST__[i](); | ||
#endif | ||
} | ||
|
||
#ifdef CRT_HAS_INITFINI_ARRAY | ||
__attribute__((section(".fini_array"), | ||
used)) static void (*__fini)(void) = __do_fini; | ||
#else // CRT_HAS_INITFINI_ARRAY | ||
#if defined(__i386__) || defined(__x86_64__) | ||
asm(".pushsection .fini,\"ax\",@progbits\n\t" | ||
"call " __USER_LABEL_PREFIX__ "__do_fini\n\t" | ||
".popsection"); | ||
#elif defined(__arm__) | ||
asm(".pushsection .fini,\"ax\",%progbits\n\t" | ||
"bl " __USER_LABEL_PREFIX__ "__do_fini\n\t" | ||
".popsection"); | ||
#endif | ||
#endif // CRT_HAS_INIT_FINI_ARRAY |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//===-- crtend.c - End of constructors and destructors --------------------===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include <stdint.h> | ||
|
||
// Put 4-byte zero which is the length field in FDE at the end as a terminator. | ||
const int32_t __EH_FRAME_LIST_END__[] | ||
__attribute__((section(".eh_frame"), aligned(sizeof(int32_t)), | ||
visibility("hidden"), used)) = {0}; | ||
|
||
#ifndef CRT_HAS_INITFINI_ARRAY | ||
typedef void (*fp)(void); | ||
fp __CTOR_LIST_END__[] | ||
__attribute__((section(".ctors"), visibility("hidden"), used)) = {0}; | ||
fp __DTOR_LIST_END__[] | ||
__attribute__((section(".dtors"), visibility("hidden"), used)) = {0}; | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
set(CRT_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) | ||
|
||
set(CRT_TESTSUITES) | ||
|
||
set(CRT_TEST_DEPS) | ||
if(NOT COMPILER_RT_STANDALONE_BUILD) | ||
list(APPEND CRT_TEST_DEPS crt) | ||
endif() | ||
if(NOT COMPILER_RT_STANDALONE_BUILD AND NOT RUNTIMES_BUILD) | ||
# Use LLVM utils and Clang from the same build tree. | ||
list(APPEND CRT_TEST_DEPS | ||
clang clang-resource-headers FileCheck not llvm-config) | ||
endif() | ||
|
||
set(CRT_TEST_ARCH ${CRT_SUPPORTED_ARCH}) | ||
if (COMPILER_RT_BUILD_CRT AND COMPILER_RT_HAS_CRT) | ||
foreach(arch ${CRT_TEST_ARCH}) | ||
set(CRT_TEST_TARGET_ARCH ${arch}) | ||
string(TOLOWER "-${arch}-${OS_NAME}" CRT_TEST_CONFIG_SUFFIX) | ||
get_test_cc_for_arch(${arch} CRT_TEST_TARGET_CC CRT_TEST_TARGET_CFLAGS) | ||
string(TOUPPER ${arch} ARCH_UPPER_CASE) | ||
set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config) | ||
|
||
configure_lit_site_cfg( | ||
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in | ||
${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg) | ||
list(APPEND CRT_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}) | ||
endforeach() | ||
endif() | ||
|
||
add_lit_testsuite(check-crt "Running the CRT tests" | ||
${CRT_TESTSUITES} | ||
DEPENDS ${CRT_TEST_DEPS}) | ||
set_target_properties(check-crt PROPERTIES FOLDER "Compiler-RT Misc") |
Oops, something went wrong.