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:
parent
e58fab841f
commit
b8fc8b324d
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue