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.

Reply via email to