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.
This commit is contained in:
Brad King 2008-08-07 09:09:45 -04:00
parent e58fab841f
commit b8fc8b324d
6 changed files with 59 additions and 42 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}