This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [LONG] RF{C,D,A,H}: pe-x86 DLLs (shared libstdc++ and others) vs C++ RTTI vs LD
- From: "Dave Korn" <dave dot korn dot cygwin at googlemail dot com>
- To: binutils at sourceware dot org
- Date: Sun, 21 Dec 2008 21:27:37 +0000
- Subject: Re: [LONG] RF{C,D,A,H}: pe-x86 DLLs (shared libstdc++ and others) vs C++ RTTI vs LD
- References: <2ca21dcc0811291717o382dc09dy67beefca36b28f5f@mail.gmail.com> <49320602.1EF0ABD5@dessent.net>
Brian Dessent wrote:
> Dave Korn wrote:
>
>> Adding "-Wl,--enable-auto-import" to the compile command line suppresses the
>> warning and informational messages, but the compiled executable fails in the
>> exact same way nonetheless.
>> ...
> But when --e-a-i is specified the special .xa version of the linker
> script is used instead of the default one, which casuses .rdata to be
> put into .data making it writable. And regardless of whether --e-a-i
> was specified, the presence of an auto-import site in .text
> automatically causes the linker to emit .text with write permission. So
> whatever the reason for the crash during process loading, it shouldn't
> be due to trying to write to a readonly page -- if it is, then that's
> the bug to fix.
>
> Can you find out more detail of the STATUS_ACCESS_EXCEPTION? In the
> past I've used ollydbg for this as it makes it pretty easy to determine
> the precise address that NTLDR was trying to modify at the time of the
> fault, and from there you can figure out what section that corresponds
> to.
Mea culpa. I bodged something up in my testing, it seems; in any case,
after a fresh rebuild I can no longer reproduce the problem in that using
--enable-auto-import now works as expected and prevents the crash from
happening. Duh me.
FWIW, I investigated what was causing the access exception (without
-e-a-i) using WinDbg, and found it was a DWORD-sized move (apparently from
__imp___ZTISt11logic_error? register trace is confusing) to
__fu0___ZTISt11logic_error. So in this case the warning from ld isn't
useless noise by any means, it's very real and indicates a problem.
0:000> g
(5c8.5ec): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=6c4ddef0 ebx=00000000 ecx=6c4d0498 edx=00409268 esi=6c4dc000 edi=6c4e05a0
eip=77f92b57 esp=0022f858 ebp=0022f888 iopl=0 nv up ei ng nz na po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010283
ntdll!NtQueryEvent+0x2fa:
*** ERROR: Module load completed but symbols could not be loaded for
image00400000
77f92b57 890a mov dword ptr [edx],ecx ds:0023:00409268=0040b1b4
0:000> !vadump
BaseAddress: 00400000
RegionSize: 00001000
State: 00001000 MEM_COMMIT
Protect: 00000002 PAGE_READONLY
Type: 01000000 MEM_IMAGE
BaseAddress: 00401000
RegionSize: 00006000
State: 00001000 MEM_COMMIT
Protect: 00000080 PAGE_EXECUTE_WRITECOPY
Type: 01000000 MEM_IMAGE
BaseAddress: 00407000
RegionSize: 00001000
State: 00001000 MEM_COMMIT
Protect: 00000008 PAGE_WRITECOPY
Type: 01000000 MEM_IMAGE
BaseAddress: 00408000
RegionSize: 00002000
State: 00001000 MEM_COMMIT
Protect: 00000002 PAGE_READONLY
Type: 01000000 MEM_IMAGE
BaseAddress: 0040a000
RegionSize: 00001000
State: 00001000 MEM_COMMIT
Protect: 00000008 PAGE_WRITECOPY
Type: 01000000 MEM_IMAGE
BaseAddress: 0040b000
RegionSize: 00001000
State: 00001000 MEM_COMMIT
Protect: 00000004 PAGE_READWRITE
Type: 01000000 MEM_IMAGE
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00005b5c 00401000 00401000 00000400 2**4
CONTENTS, ALLOC, LOAD, CODE, DATA
1 .data 00000830 00407000 00407000 00006000 2**5
CONTENTS, ALLOC, LOAD, DATA
2 .rdata 00001ab4 00408000 00408000 00006a00 2**5
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .bss 00000060 0040a000 0040a000 00000000 2**3
ALLOC
4 .idata 00000688 0040b000 0040b000 00008600 2**2
CONTENTS, ALLOC, LOAD, DATA
[1357](sec 3)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00001268
__fu0___ZTISt11logic_error
[ 94](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x000001b4 .idata$5
[1423](sec 5)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000001b4
__imp___ZTISt11logic_error
[1429](sec 5)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000001b4
__imp___ZTISt11logic_error
> dereference. I really think having multiple copies of the typeinfo is a
> bad path to go down.
I'm not entirely sure. You saw Danny's reply; I'm testing that now and
putting the typeinfo into libstdc++.dll.a has fixed
20_util/shared_ptr/thread/default_weaktoshared.cc.
>> linked into the application will have their own copies. I think the RTTI
>> system is able to handle this situation - that's why it has the options to
>> perform typeid comparisons based on fully matching the type name strings
>> rather than just comparing the name string pointers for equality, see the
>> use of __GXX_MERGED_TYPEINFO_NAMES in libsupc++ for details. Normally this
>
> That's interesting to know, as I thought that pointer comparisons for
> rtti was the only option. Is __GXX_MERGED_TYPEINFO_NAMES correctly
> being set to 0 (and __GXX_TYPEINFO_EQUALITY_INLINE to 0 as well it would
> seem) for this target then?
Had to do a rebuild to get that right, but it is now.
> I think that auto-import should be the answer here.
I now agree fully.
> For the purposes of the dejagnu testsuite, either -Wl,--e-a-i needs to
> be added to the flags for the C++ tests, or the harness needs to be
> taught to ignore the Info: lines.
I chose the first, as there are genuine failures caused by not using
-e-a-i, so ignoring the spew isn't enough.
> But outside the testsuite, if the user gets all this noise when linking
> normal C++ code it's a quality issue. I think this really speaks more
> to the general problem of this option's very existance than anything
> else. In my ideal world, the linker should be smart enough to do the
> right thing with neither a bunch informational spew nor user
> intervention. That means if it processes an auto-import in .rdata, it
> should be smart enough to mark the section writable without the user
> needing to specify a flag. At the same time, you don't want to
> pessimise every program by eliminating the optimization of having
> readonly data in a sharable segment, so you also don't want to just
> unconditionally turn on -Wl,--e-a-i in the g++ driver specs either.
Well, possibly it just needs to be taught what to do with the _fu_
fixups? Could be as simple as a quick patch to the alternative link script, no?
cheers,
DaveK