Bug 40905 - GCC creates invalid executable with auto-imported DLL and __attribute__((cold))
GCC creates invalid executable with auto-imported DLL and __attribute__((cold))
Status: RESOLVED WORKSFORME
Product: gcc
Classification: Unclassified
Component: target
4.4.1
: P3 normal
: ---
Assigned To: Not yet assigned to anyone
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2009-07-29 16:06 UTC by Ramiro Polla
Modified: 2010-05-23 07:41 UTC (History)
3 users (show)

See Also:
Host:
Target: i686-mingw32
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ramiro Polla 2009-07-29 16:06:51 UTC
GCC creates invalid executable when an array from one DLL is accessed from another DLL in a function with __attribute__((cold)).

----------
$ cat dll1.c 
int foo[2] = {0, 1};
$ cat dll2.c
extern int foo[2];
__attribute__((cold))
int bar(void)
{
    return foo[1];
}
$ cat main.c
int bar(void);
int main()
{
    bar();
    return 0;
}
$ cat Makefile 
CC=i686-mingw32-gcc-4.4.1

all:
	$(CC) -shared -o dll1.dll dll1.c
	$(CC) -shared -o dll2.dll dll2.c dll1.dll -O2
	$(CC) -o main.exe main.c dll1.dll dll2.dll
$ make
i686-mingw32-gcc-4.4.1 -shared -o dll1.dll dll1.c
i686-mingw32-gcc-4.4.1 -shared -o dll2.dll dll2.c dll1.dll -O2
Info: resolving _foo by linking to __imp__foo (auto-import)
/opt/i686-mingw32/lib/gcc/i686-mingw32/4.4.1/../../../../i686-mingw32/bin/ld: warning: auto-importing has been activated without --enable-auto-import specified on the command line.
This should work unless it involves constant data structures referencing symbols from auto-imported DLLs.
i686-mingw32-gcc-4.4.1 -o main.exe main.c dll1.dll dll2.dll
$ ./main.exe
err:module:attach_process_dlls "dll2.dll" failed to initialize, aborting
err:module:LdrInitializeThunk Main exe initialization for L"Z:\\home\\ramiro\\code\\smalls\\gcc_bug\\main.exe" failed, status c0000005
----------
This error message is from wine, but it also fails on Windows XP.

The auto-import warning seems to fit perfectly here but the same test doesn't fail at -O1, or if __attribute__((cold)) is removed.
Comment 1 Andrew Pinski 2009-07-29 16:10:02 UTC
IIRC the cold attribute does a couple of things.  The only thing I think that might cause this is putting it into a .text.cold section.
Comment 2 Ramiro Polla 2009-07-30 03:43:53 UTC
I might be guessing wildly since I don't know that much about PE, but this is what more I've found:

It crashes loading the dll in __pei386_runtime_relocator at address 65ec12a8:
65ec1290 <__pei386_runtime_relocator>:
65ec1290:       55                      push   %ebp
65ec1291:       b9 28 40 ec 65          mov    $0x65ec4028,%ecx
65ec1296:       89 e5                   mov    %esp,%ebp
65ec1298:       eb 14                   jmp    65ec12ae <__pei386_runtime_relocator+0x1e>
65ec129a:       8d b6 00 00 00 00       lea    0x0(%esi),%esi
65ec12a0:       8b 51 04                mov    0x4(%ecx),%edx
65ec12a3:       8b 01                   mov    (%ecx),%eax
65ec12a5:       83 c1 08                add    $0x8,%ecx
65ec12a8:       01 82 00 00 ec 65       add    %eax,0x65ec0000(%edx)
65ec12ae:       81 f9 30 40 ec 65       cmp    $0x65ec4030,%ecx
65ec12b4:       72 ea                   jb     65ec12a0 <__pei386_runtime_relocator+0x10>
65ec12b6:       5d                      pop    %ebp
65ec12b7:       c3                      ret    


In the same testcase compiled without -O2, I get the sole entry of runtime_pseudo_reloc in __RUNTIME_PSEUDO_RELOC_LIST__ (the equivalent to 0x65ec4028) is:

addend = 0x00000004
target = 0x000011d5

and the .text section is:
  0 .text         00000344  67701000  67701000  00000400  2**4
                  CONTENTS, ALLOC, LOAD, CODE, DATA

With -O2 it is:
addend = 0x00000004
target = 0x00002005

  0 .text         00000334  65ec1000  65ec1000  00000600  2**4
                  CONTENTS, ALLOC, LOAD, CODE, DATA
  1 .text.unlikely 0000000c  65ec2000  65ec2000  00000a00  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE

Is it possible that it triggers the exception trying to write in text.unlikely which is READONLY?
Comment 3 Andrew Pinski 2009-07-30 03:59:45 UTC
Doesn't DLL source need to be compiled with -fPIC to allow it to work?

So what is happening is you are getting a runtime relocation inside the .text.unlikely section which should not happen for DLLs I think ...
Comment 4 Danny Smith 2009-07-30 08:00:16 UTC
(In reply to comment #2)

> 
> Is it possible that it triggers the exception trying to write in text.unlikely
> which is READONLY?
> 

Exactly.  This is a linker, not a compiler issue.  If you are using a relatively recent binutils and mingw run time, the addition of the switch
-Wl,--enable-runtime-pseudo-reloc-v2 should get around the READONLY problem.
Otherwise, you could always just add __declspec (dllimport) to
 extern int foo[2]; and so retain portability with the rest of the PE-COFF world.

Danny
Comment 5 Kai Tietz 2009-09-04 13:27:27 UTC
(In reply to comment #4)
> (In reply to comment #2)
> 
> > 
> > Is it possible that it triggers the exception trying to write in text.unlikely
> > which is READONLY?
> > 
> 
> Exactly.  This is a linker, not a compiler issue.  If you are using a
> relatively recent binutils and mingw run time, the addition of the switch
> -Wl,--enable-runtime-pseudo-reloc-v2 should get around the READONLY problem.
> Otherwise, you could always just add __declspec (dllimport) to
>  extern int foo[2]; and so retain portability with the rest of the PE-COFF
> world.
> 
> Danny
> 

Right, this is a linker issue (or runtime issue of pseudo-relocation). But newer mingw32's runtime uses new code for v1 relocations, too. So for it, this issue should be solved, too.

So can we close this bug?

Cheers,
Kai
Comment 6 Kai Tietz 2009-09-12 10:55:52 UTC
I added you to this thread, as you merged new pseudo-relocation code to mingw.org's runtime.
Comment 7 Kai Tietz 2010-04-05 09:17:56 UTC
(In reply to comment #6)
> I added you to this thread, as you merged new pseudo-relocation code to
> mingw.org's runtime.
> 

As cygwin and mingw.org are supporting now new linker generated runtime-pseudo-relocation, could you please confirm that your issue is solved.
I tested your issue and for me it works with recent version of cygwin/mingw.org runtimes.

Kai
Comment 8 Kai Tietz 2010-05-23 07:41:09 UTC
As there is no feed-back for some time now. I've tested this issue with recent mingw runtimes and the issue is solved.
As this isse is related to old pseudo-relocation and linker, and not related to gcc itself, I close this bug as works-for-me.