From b8fc8b324d2e1b892d0b41cf3581226c210131d0 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 7 Aug 2008 09:09:45 -0400 Subject: 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 | 20 ++++++++++---------- 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, 57 insertions(+), 40 deletions(-) diff --git a/Modules/CMakeCCompilerABI.c b/Modules/CMakeCCompilerABI.c index f73e7fc..e6a07f4 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() +#ifdef __CLASSIC_C__ +int main(argc, argv) int argc; char *argv[]; +#else +int main(int argc, char *argv[]) +#endif { - 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/CMakeCCompilerId.c.in b/Modules/CMakeCCompilerId.c.in index ecbe431..35d7df7 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 7fb3618..c9b0440 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 060c7e9..fa2178c 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 c25b69d..8bcf1a0 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 68094d4..c924f78 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; } -- cgit v0.12