From 9583456b329abe8bfbaaedd0aca76fc3eb31e0b8 Mon Sep 17 00:00:00 2001 From: Alain Mosnier Date: Sat, 28 Jul 2018 19:16:41 +0200 Subject: [PATCH] Implemented workaround for ld issue with large BSS The large arrays are now allocated on heap instead of in BSS. This actually feels like a pretty stupid linker limitation, and the workaround leads to code that is less readable. But it only impacts the test program. The issue was reported with GCC 7.3.0 and compiling for 64-bit arch on MSYS2's MinGW compiler. GCC 7.3.0 for 64-bit on Linux (my own machine and Travis) seems perfectly OK with a large BSS segment (around 3 GB is what the test program uses for test data). Reported issue: $ make cc -Wall -Wextra -Wpedantic -c -o test.o test.c cc -Wall -Wextra -Wpedantic -c -o sha-256.o sha-256.c cc test.o sha-256.o -o test C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o: in function `__tmainCRTStartup': C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:251:(.text+0x1cd): relocation truncated to fit: R_X86_64_PC32 against symbol `__imp_Sleep' defined in .idata$5 section in C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/lib/../lib/libkernel32.a(dkhchs01360.o) C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:278:(.text+0x255): relocation truncated to fit: R_X86_64_PC32 against symbol `__imp_SetUnhandledExceptionFilter' defined in .idata$5 section in C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/lib/../lib/libkernel32.a(dkhchs01346.o) C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:286:(.text+0x283): relocation truncated to fit: R_X86_64_PC32 against symbol `__mingw_winmain_hInstance' defined in COMMON section in C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:312:(.text+0x2f3): relocation truncated to fit: R_X86_64_PC32 against symbol `__mingw_winmain_lpCmdLine' defined in COMMON section in C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/crtexe.c:238:(.text+0x475): relocation truncated to fit: R_X86_64_PC32 against symbol `__imp_GetStartupInfoA' defined in .idata$5 section in C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/lib/../lib/libkernel32.a(dkhchs00721.o) C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-gccmain.o): in function `__main': C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/gccmain.c:74:(.text+0xb2): relocation truncated to fit: R_X86_64_PC32 against `.bss' C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/gccmain.c:76:(.text+0xc2): relocation truncated to fit: R_X86_64_PC32 against `.bss' C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-charmax.o): in function `my_lconv_init': C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/charmax.c:19:(.text+0x3): relocation truncated to fit: R_X86_64_PC32 against symbol `__imp___lconv_init' defined in .idata$5 section in C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/lib/../lib/libmsvcrt.a(dkxcbs00090.o) C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-gs_support.o): in function `__security_init_cookie': C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/gs_support.c:62:(.text+0x47): relocation truncated to fit: R_X86_64_PC32 against symbol `__imp_GetSystemTimeAsFileTime' defined in .idata$5 section in C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/lib/../lib/libkernel32.a(dkhchs00746.o) C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/gs_support.c:70:(.text+0x52): relocation truncated to fit: R_X86_64_PC32 against symbol `__imp_GetCurrentProcessId' defined in .idata$5 section in C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/lib/../lib/libkernel32.a(dkhchs00536.o) C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/repo/mingw-w64-crt-git/src/mingw-w64/mingw-w64-crt/crt/gs_support.c:71:(.text+0x5b): additional relocation overflows omitted from the output collect2.exe: error: ld returned 1 exit status make: *** [: test] Error 1``` --- test.c | 88 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 32 deletions(-) diff --git a/test.c b/test.c index feae6be..14b8b96 100644 --- a/test.c +++ b/test.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "sha-256.h" @@ -49,37 +50,21 @@ static uint8_t data7[1000]; static uint8_t data8[1000]; static uint8_t data9[1005]; #if LARGE_MESSAGES -static uint8_t data11[536870912]; -static uint8_t data12[1090519040]; -static uint8_t data13[1610612798]; +#define SIZEOF_DATA11 536870912 +#define SIZEOF_DATA12 1090519040 +#define SIZEOF_DATA13 1610612798 +static uint8_t * data11; +static uint8_t * data12; +static uint8_t * data13; #endif -static void construct_binary_messages(void) -{ - size_t i; - for (i = 0; i < sizeof data7; i++) - data7[i] = 0; - for (i = 0; i < sizeof data8; i++) - data8[i] = 0x41; - for (i = 0; i < sizeof data9; i++) - data9[i] = 0x55; -#if LARGE_MESSAGES - for (i = 0; i < sizeof data11; i++) - data11[i] = 0x5a; - for (i = 0; i < sizeof data12; i++) - data12[i] = 0; - for (i = 0; i < sizeof data13; i++) - data13[i] = 0x42; -#endif -} - struct vector { const uint8_t *input; size_t input_len; const char *output; }; -static const struct vector VECTORS[] = { +static struct vector vectors[] = { { data1, sizeof data1, @@ -128,28 +113,63 @@ static const struct vector VECTORS[] = { #if LARGE_MESSAGES , { - data12, + NULL, 1000000, "d29751f2649b32ff572b5e0a9f541ea660a50f94ff0beedfb0b692b924cc8025" }, { - data11, - sizeof data11, + NULL, + SIZEOF_DATA11, "15a1868c12cc53951e182344277447cd0979536badcc512ad24c67e9b2d4f3dd" }, { - data12, - sizeof data12, + NULL, + SIZEOF_DATA12, "461c19a93bd4344f9215f5ec64357090342bc66b15a148317d276e31cbc20b53" }, { - data13, - sizeof data13, + NULL, + SIZEOF_DATA13, "c23ce8a7895f4b21ec0daf37920ac0a262a220045a03eb2dfed48ef9b05aabea" } #endif }; +static void construct_binary_messages(void) +{ + size_t i; + for (i = 0; i < sizeof data7; i++) + data7[i] = 0; + for (i = 0; i < sizeof data8; i++) + data8[i] = 0x41; + for (i = 0; i < sizeof data9; i++) + data9[i] = 0x55; +#if LARGE_MESSAGES + data11 = malloc(SIZEOF_DATA11); + data12 = malloc(SIZEOF_DATA12); + data13 = malloc(SIZEOF_DATA13); + for (i = 0; i < SIZEOF_DATA11; i++) + data11[i] = 0x5a; + for (i = 0; i < SIZEOF_DATA12; i++) + data12[i] = 0; + for (i = 0; i < SIZEOF_DATA13; i++) + data13[i] = 0x42; + vectors[9].input = data12; + vectors[10].input = data11; + vectors[11].input = data12; + vectors[12].input = data13; +#endif +} + +static void destruct_binary_messages(void) +{ +#if LARGE_MESSAGES + free(data11); + free(data12); + free(data13); +#endif +} + static void hash_to_string(char string[65], const uint8_t hash[32]) { size_t i; @@ -208,10 +228,14 @@ int main(void) return 1; } construct_binary_messages(); - for (i = 0; i < (sizeof VECTORS / sizeof (struct vector)); i++) { - const struct vector *vector = &VECTORS[i]; + for (i = 0; i < (sizeof vectors / sizeof (struct vector)); i++) { + const struct vector *vector = &vectors[i]; if (test(vector->input, vector->input_len, vector->output)) + { + destruct_binary_messages(); return 1; + } } + destruct_binary_messages(); return 0; }