This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: cygwin, libtool, dlpreopen, and .rdata


On Wed, 22 Sep 2004, Charles Wilson wrote:

> [cygwin list: I'm CC'ing this so that it goes into the archives, but
> it's pretty technical about the innards of libtool...]

This doesn't seem libtool related at all to me (other than it's a gcc bug
that affects libtool).

> With newer gcc's (cygwin version numbers 3.3.3-3, 3.4.1-1, but not
> 3.3.1-3), const variables are placed in an .rdata section.  This causes
> problems when those variables contain references to OTHER vars that are
> imported from a dll -- because the runtime relocation machinery can't
> fixup the address, since the variable holding the address is const --
> and is in .rdata!

Yes, I see.  I hope Danny Smith might weigh in here?

http://sources.redhat.com/ml/binutils/2004-02/msg00003.html

> Concrete example: the demo test program from libtool itself.  When
> building helldl, libtool creates the following virtual lookup table:
>
> helldl.exeS.c (important bits only):
> *************************************
> /* External symbol declarations for the compiler. */
> extern int foo;
> extern int hello;
> extern int nothing;
>
> /* The mapping between symbol names and symbols. */
> const struct {
>    const char *name;
>    lt_ptr address;
> }
> lt_preloaded_symbols[] =
> {
>    {"libhello.a", (lt_ptr) 0},
>    {"hello", (lt_ptr) &hello},
>    {"foo", (lt_ptr) &foo},
>    {"nothing", (lt_ptr) &nothing},
>    {0, (lt_ptr) 0}
> };
> *************************************
>
> Because lt_preloaded_symbols[] is an array of const structs, it is
> placed in .rdata.  However, the "nothing" symbol is a DATA export from
> cyghello-2.dll -- so the runtime psuedo-reloc machinery needs to fixup
> the address stored in "lt_preloaded_symbols[3].address" to point to the
> actual, relocated memory location of the "nothing" variable.
>
> But it can't, because .rdata is non-writable.  However, this is a
> *runtime* error; the *link* succeeds.  But when you run the app, you get
> a popup window declaring:
>
> "The application failed to initialize properly (0xc0000005). Click on OK
> to terminate the application."
>
> Note that
>   (1) the "nothing" relocation works fine for "normal" links; hell.exe
> works ok, and imports "nothing" correctly.
>
>   (2) the lt_preloaded_symbol[] object works fine, as long as it doesn't
> contain references to DATA items imported from DLL's: staticly linked
> helldl.exe works ok, and dynamically linked helldl.exe works IF
> "nothing" is expunged from the application code (manually removed from
> helldl.exeS.c, and from dlmain.c)
>
>   (3) even with newer compilers, if lt_preloaded_symbol[] is in .data
> (by changing its definition from "const struct" to "struct") then
> everything works fine.  Note that you only need to do this in
> helldl.exeS.c; the application (dlmain.c, in this case) can still
> declare 'extern const struct ....').
>
> *************************************
> I see two solutions: a short term libtool-focused workaround, and a
> longer term general solution.
>
> The short term workaround is to simply change lt_preloaded_symbol[]'s
> constness in the *.exeS.c file, so that it goes in the .data section.
> Mabye this could be done for cygwin/mingw only (but application code can
> remain unchanged, declaring 'extern const struct ...').  But that won't
> fix any OTHER problems out there which put the address of DLL DATA
> imports into const variables.
>
> The long term solution is...er...hard.  Somehow, ld/(gcc?) should be
> modified to detect that a dllreloc is being put into an .rdata, and move
> the entire enclosing variable into .data.  This is difficult:
> lt_preloaded_symbol[3].address can be flagged easily, but how can the
> linker figure out that the whole lt_preloaded_symbol variable should be
> moved from .rdata to .data?  And didn't the compiler put the symbol into
> .rdata in the first place -- so maybe gcc is the one who should detect
> this?  But gcc doesn't know how the link will be performed: it doesn't
> know that "nothing" is a DATA import from a DLL, but "foo" is a function
> import from a DLL!  (Worse, you might link to a STATIC library and not a
> DLL at all, so lt_preloaded_symbol could STAY in .rdata in that case.)
>
> This might be one of those "doctor, it hurts when I do this/OK, don't do
> that" situations.
>
> Note, I found this problem in libtool-1.5.x, but it exists in HEAD, too.
>   The following patch is against HEAD...
>
> --
> Chuck

-- 
Brian Ford
Senior Realtime Software Engineer
VITAL - Visual Simulation Systems
FlightSafety International
the best safety device in any aircraft is a well-trained pilot...

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]