https://sourceware.org/bugzilla/show_bug.cgi?id=33187
Bug ID: 33187 Summary: LD --gc-sections discards .reloc and .edata for exe file Product: binutils Version: unspecified Status: UNCONFIRMED Severity: normal Priority: P2 Component: ld Assignee: unassigned at sourceware dot org Reporter: pali at kernel dot org Target Milestone: --- When trying to create simple Windows executable which exports symbols and has relocation section (so it can be loaded at non-base address) and links against some external DLL library then LD --gc-sections completely drops the export symbols and relocation section. Steps to reproduce: 1. Create import library lib.a for external DLL lib.dll $ cat lib.def LIBRARY lib.dll EXPORTS func3 $ i686-w64-mingw32-dlltool -d lib.def --output-lib lib.a 2. Compile source code of test application with -Os -ffunction-sections -fdata-sections $ cat start.c extern int func1(void); int mainCRTStartup(void) { return func1(); } $ cat func1.c int func1(void) { return 0; } $ cat func2.c extern int func3(void); int func2(void) { return func3(); } $ i686-w64-mingw32-gcc -Os -ffunction-sections -fdata-sections -c start.c $ i686-w64-mingw32-gcc -Os -ffunction-sections -fdata-sections -c func1.c $ i686-w64-mingw32-gcc -Os -ffunction-sections -fdata-sections -c func2.c 3. Generate export table and relocations (via LD's --base-file and dlltool) for exported functions to file test.exp $ cat test.def NAME test.exe EXPORTS func1 func2 $ i686-w64-mingw32-ld --gc-sections start.o func1.o func2.o lib.a -o test.exe --base-file test.base $ i686-w64-mingw32-dlltool -d test.def --base-file test.base --output-exp test.exp $ i686-w64-mingw32-ld --gc-sections start.o func1.o func2.o lib.a test.exp -o test.exe --base-file test.base $ i686-w64-mingw32-dlltool -d test.def --base-file test.base --output-exp test.exp (first generate raw relocation table into test.base; second use raw relocation table and list of export to generate object file with .edata and .reloc; second and third - repeat steps to supply generated object file as input for linker and regenerate that object file; similar what is doing dllwrap tool but for executable) 4. Link everything together with --gc-sections which produces final executable test.exe $ i686-w64-mingw32-ld --gc-sections start.o func1.o func2.o lib.a test.exp -o test.exe --print-gc-sections i686-w64-mingw32-ld: removing unused section '.rdata$zzz' in file 'start.o' i686-w64-mingw32-ld: removing unused section '.rdata$zzz' in file 'func1.o' i686-w64-mingw32-ld: removing unused section '.text$func2' in file 'func2.o' i686-w64-mingw32-ld: removing unused section '.rdata$zzz' in file 'func2.o' i686-w64-mingw32-ld: removing unused section '.text' in file 'lib.a(dgxvbs00000.o)' i686-w64-mingw32-ld: removing unused section '.edata' in file 'test.exp' Final executable does not export any symbol (should func1 and func2) and does not have any relocation information. LD's --print-gc-sections is writing that it discarded func2 completely and also discarded all .edata and .reloc information even the fact that object file is explicitly put on the command line (test.exp). Trying to use --gc-keep-exported did not helped at all. Without the --gc-sections (in step 3 and test 4), the test.exe executable is generated correctly with IMAGE_DIRECTORY_ENTRY_EXPORT and IMAGE_DIRECTORY_ENTRY_BASERELOC. LD should not discard sections which are important for generating the final executable like IMAGE_DIRECTORY_ENTRY_EXPORT and IMAGE_DIRECTORY_ENTRY_BASERELOC. Note: As a workaround I come up with an idea: Put some dummy symbol into .edata and .reloc sections of the generated object file test.exp by dlltool and then tell to LD that those two symbols are required. I have not figured out how to tell LD that directly section should not be dropped. After each dlltool invocation I called: i686-w64-mingw32-objcopy --add-symbol reloc=.reloc:0 --add-symbol edata=.edata:0 test.exp And for second and third LD invocation I used additional arguments: --require-defined=reloc --require-defined=edata Then the final (third) LD printed just: i686-w64-mingw32-ld: removing unused section '.rdata$zzz' in file 'start.o' i686-w64-mingw32-ld: removing unused section '.rdata$zzz' in file 'func1.o' i686-w64-mingw32-ld: removing unused section '.rdata$zzz' in file 'func2.o' And it produced correct executable with IMAGE_DIRECTORY_ENTRY_EXPORT and IMAGE_DIRECTORY_ENTRY_BASERELOC -- You are receiving this mail because: You are on the CC list for the bug.