From b8fc8b324d2e1b892d0b41cf3581226c210131d0 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 7 Aug 2008 09:09:45 -0400 Subject: [PATCH] ENH: Improve robustness of compiler INFO strings Compiler INFO strings built at preprocessing time encode information that must appear as a string literal in the resulting binary. We must make sure the strings appear in the final binary no matter what compiler and flags are used. The previous implementation worked in most places but failed with the GNU linker's --gc-sections option which managed to discard the string. Instead we make the program return value depend on an element of the string indexed by a runtime program parameter, which absolutely requires the string to be present. --- Modules/CMakeCCompilerABI.c | 24 ++++++++++++------------ Modules/CMakeCCompilerId.c.in | 21 +++++++++++++++------ Modules/CMakeCXXCompilerABI.cpp | 16 ++++++---------- Modules/CMakeCXXCompilerId.cpp.in | 14 +++++++++++--- Modules/CheckTypeSizeC.c.in | 13 +++++++------ Modules/TestEndianess.c.in | 13 ++++++++----- 6 files changed, 59 insertions(+), 42 deletions(-) diff --git a/Modules/CMakeCCompilerABI.c b/Modules/CMakeCCompilerABI.c index f73e7fcc3..e6a07f4c4 100644 --- a/Modules/CMakeCCompilerABI.c +++ b/Modules/CMakeCCompilerABI.c @@ -12,17 +12,17 @@ /*--------------------------------------------------------------------------*/ -/* Make sure the information strings are referenced. */ -#define REQUIRE(x) (&x[0] != &require) - -int main() -{ - const char require = 0; - return - ( - REQUIRE(info_sizeof_dptr) -#if defined(ABI_ID) - && REQUIRE(info_abi) +#ifdef __CLASSIC_C__ +int main(argc, argv) int argc; char *argv[]; +#else +int main(int argc, char *argv[]) #endif - ); +{ + int require = 0; + require += info_sizeof_dptr[argc]; +#if defined(ABI_ID) + require += info_abi[argc]; +#endif + (void)argv; + return require; } diff --git a/Modules/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in index ecbe431b7..35d7df77a 100644 --- a/Modules/CMakeCCompilerId.c.in +++ b/Modules/CMakeCCompilerId.c.in @@ -2,15 +2,9 @@ # error "A C++ compiler has been selected for C." #endif -/* Provide main() so the program can link. */ #if defined(__18CXX) # define ID_VOID_MAIN #endif -#ifdef ID_VOID_MAIN -void main() {} -#else -int main() { return 0; } -#endif #if defined(__INTEL_COMPILER) || defined(__ICC) # define COMPILER_ID "Intel" @@ -82,3 +76,18 @@ int main() { return 0; } char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; @CMAKE_C_COMPILER_ID_PLATFORM_CONTENT@ + +/*--------------------------------------------------------------------------*/ + +#ifdef ID_VOID_MAIN +void main() {} +#else +int main(int argc, char* argv[]) +{ + int require = 0; + require += info_compiler[argc]; + require += info_platform[argc]; + (void)argv; + return require; +} +#endif diff --git a/Modules/CMakeCXXCompilerABI.cpp b/Modules/CMakeCXXCompilerABI.cpp index 7fb361887..c9b0440b8 100644 --- a/Modules/CMakeCXXCompilerABI.cpp +++ b/Modules/CMakeCXXCompilerABI.cpp @@ -8,17 +8,13 @@ /*--------------------------------------------------------------------------*/ -/* Make sure the information strings are referenced. */ -#define REQUIRE(x) (&x[0] != &require) - -int main() +int main(int argc, char* argv[]) { - const char require = 0; - return - ( - REQUIRE(info_sizeof_dptr) + int require = 0; + require += info_sizeof_dptr[argc]; #if defined(ABI_ID) - && REQUIRE(info_abi) + require += info_abi[argc]; #endif - ); + (void)argv; + return require; } diff --git a/Modules/CMakeCXXCompilerId.cpp.in b/Modules/CMakeCXXCompilerId.cpp.in index 060c7e9c1..fa2178c0b 100644 --- a/Modules/CMakeCXXCompilerId.cpp.in +++ b/Modules/CMakeCXXCompilerId.cpp.in @@ -5,9 +5,6 @@ # error "A C compiler has been selected for C++." #endif -/* Provide main() so the program can link. */ -int main() { return 0; } - #if defined(__COMO__) # define COMPILER_ID "Comeau" @@ -70,3 +67,14 @@ int main() { return 0; } char* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]"; @CMAKE_CXX_COMPILER_ID_PLATFORM_CONTENT@ + +/*--------------------------------------------------------------------------*/ + +int main(int argc, char* argv[]) +{ + int require = 0; + require += info_compiler[argc]; + require += info_platform[argc]; + (void)argv; + return require; +} diff --git a/Modules/CheckTypeSizeC.c.in b/Modules/CheckTypeSizeC.c.in index c25b69dcb..8bcf1a0cc 100644 --- a/Modules/CheckTypeSizeC.c.in +++ b/Modules/CheckTypeSizeC.c.in @@ -29,15 +29,16 @@ const char info_sizeof[] = {'I', 'N', 'F', 'O', ':', 's','i','z','e','o','f','[ ('0' + (SIZE % 10)), ']','\0'}; - #ifdef __CLASSIC_C__ -int main(){ - int ac; - char*av[]; +int main(argc, argv) int argc; char *argv[]; #else -int main(int ac, char*av[]){ +int main(int argc, char *argv[]) #endif - return (&info_sizeof[0] != &info_sizeof[0]); +{ + int require = 0; + require += info_sizeof[argc]; + (void)argv; + return require; } #else /* CHECK_TYPE_SIZE_TYPE */ diff --git a/Modules/TestEndianess.c.in b/Modules/TestEndianess.c.in index 68094d4ac..c924f7858 100644 --- a/Modules/TestEndianess.c.in +++ b/Modules/TestEndianess.c.in @@ -10,11 +10,14 @@ const cmakeint16 info_little[] = {0x4854, 0x5349, 0x4920, 0x2053, 0x494c, 0x545 const cmakeint16 info_big[] = {0x5448, 0x4953, 0x2049, 0x5320, 0x4249, 0x4720, 0x454e, 0x4449, 0x414e, 0x2e2e, 0x0000}; #ifdef __CLASSIC_C__ -int main(){ - int ac; - char*av[]; +int main(argc, argv) int argc; char *argv[]; #else -int main(int ac, char*av[]){ +int main(int argc, char *argv[]) #endif - return (&info_little[0] != &info_big[0]); +{ + int require = 0; + require += info_little[argc]; + require += info_big[argc]; + (void)argv; + return require; }