Menu

#19 Autoimport may fail for C++ symbols

Known_bugs
closed
ld (17)
2001-12-11
2000-12-24
No

Description:
I saw autoimport failing for DLLized libstdc++. I tried it on simple app (iostreams only) without patching headers and end up with unresolved references to some C++ symbols.

Cause:
?

Solution/Workaround:
More information (e.g., easy non-libstdc++-relying testcase) required.

Discussion

  • Danny Smith

    Danny Smith - 2000-12-27

    Hello Paul,

    What were the unresolved symbols?

    I had initial problems with libstdc++ revolving around functions taking long double args (mainly in complexio).

    Removing these (by editing an output-def file) and rebuilding libstdc++dll with this def fixed the problem and I was able to use autoimport and autoexport together to build a dll that linked against libstdc++.dll names (that is, autoimport to get symbols from libstdc++.dll, autoexport to build new dll).

    Danny

     
  • Paul Sokolovsky

    Paul Sokolovsky - 2000-12-31

    Making libstdc++.dll with my a2dll from static lib, and compiling

    #include <iostream.h>

    main()
    {
    cout<<"Happy New year1";
    }
    ====
    give

    ====
    Warning: resolving _cout by linking to __imp__cout (auto-import)
    fu000001.o(.idata$3+0xc): undefined reference to `libstdc___a_iname'
    nmth000000.o(.idata$4+0x0): undefined reference to `_nm__cout'
    ====

    For reference, here's patch (against Mumit's) for new gcc release (of course, I postponed it due problem report from you):

    ====
    diff -cr gcc-2.95.2-1/include/g++-3/iostream.h E:\packages\mingw\gcc/include/g++-3/iostream.h
    *** gcc-2.95.2-1/include/g++-3/iostream.h Fri Jan 21 20:12:00 2000
    --- E:\packages\mingw\gcc/include/g++-3/iostream.h Thu Dec 14 04:03:00 2000
    ***************
    *** 30,35 ****
    --- 30,41 ----

    #include <streambuf.h>

    + #ifndef __STATIC__
    + #define _LIBSTDCPP_IMPORT __declspec(dllimport)
    + #else
    + #define _LIBSTDCPP_IMPORT
    + #endif
    +
    extern "C++" {
    class istream; class ostream;
    typedef ios& (*__manip)(ios&);
    ***************
    *** 245,255 ****
    { return operator= (static_cast<ostream&> (rhs)); }
    };

    ! extern _IO_istream_withassign cin;
    // clog->rdbuf() == cerr->rdbuf()
    ! extern _IO_ostream_withassign cout, cerr;

    ! extern _IO_ostream_withassign clog
    #if _G_CLOG_CONFLICT
    __asm__ ("__IO_clog")
    #endif
    --- 251,261 ----
    { return operator= (static_cast<ostream&> (rhs)); }
    };

    ! _LIBSTDCPP_IMPORT extern _IO_istream_withassign cin;
    // clog->rdbuf() == cerr->rdbuf()
    ! _LIBSTDCPP_IMPORT extern _IO_ostream_withassign cout, cerr;

    ! _LIBSTDCPP_IMPORT extern _IO_ostream_withassign clog
    #if _G_CLOG_CONFLICT
    __asm__ ("__IO_clog")
    #endif
    *** gcc-2.95.2-1/\gcc-lib\mingw32\2.95.2specs Sat Aug 12 12:56:38 2000
    --- E:\packages\mingw\gcc\lib\gcc-lib\mingw32\2.95.2\specs Fri Dec 29 03:13:57 2000
    ***************
    *** 5,11 ****

    *cpp:
    ! -idirafter /usr/local/include -remap %(cpp_cpu) %{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT}

    *cc1:
    %(cc1_spec)
    --- 5,11 ----

    *cpp:
    ! -remap %(cpp_cpu) %{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} %{static:-D__STATIC__}

    *cc1:
    %(cc1_spec)
    ***************
    *** 20,26 ****
    %{mwindows:--subsystem windows} %{mconsole:--subsystem console} %{shared: %{mdll: %eshared and mdll are not compatible}} %{shared: --shared} %{mdll:--dll} %{shared|mdll: -e _DllMainCRTStartup@12}

    *lib:
    ! %{pg:-lgmon} %{mwindows:-lgdi32 -lcomdlg32} -luser32 -lkernel32 -ladvapi32 -lshell32

    *libgcc:
    %{mthreads:-lmingwthrd} -lmingw32 -lgcc -lmoldname -lmsvcrt
    --- 20,26 ----
    %{mwindows:--subsystem windows} %{mconsole:--subsystem console} %{shared: %{mdll: %eshared and mdll are not compatible}} %{shared: --shared} %{mdll:--dll} %{shared|mdll: -e _DllMainCRTStartup@12}

    *lib:
    ! -liberty %{pg:-lgmon} %{mwindows:-lgdi32 -lcomdlg32} -luser32 -lkernel32 -ladvapi32 -lshell32

    *libgcc:
    %{mthreads:-lmingwthrd} -lmingw32 -lgcc -lmoldname -lmsvcrt
    ***************
    *** 41,47 ****
    0

    *version:
    ! 2.95.2

    *multilib:
    . ;
    --- 41,47 ----
    0

    *version:
    ! 2.95.2-mingw snapshot 20001228

    *multilib:
    . ;
    ***************
    *** 80,86 ****
    %{!mcpu*: %{m386:-mcpu=i386 -march=i386} %{m486:-mcpu=i486 -march=i486} %{mpentium:-mcpu=pentium} %{mpentiumpro:-mcpu=pentiumpro}}

    *mingw_include_path:
    ! i386-mingw32msvc

    *link_command:
    %{!fsyntax-only: %{!c:%{!M:%{!MM:%{!E:%{!S:%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}} %{static:} %{L*} %D %o %{!nostdlib:%{!nodefaultlibs:%G %L %G}} %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*}
    --- 80,86 ----
    %{!mcpu*: %{m386:-mcpu=i386 -march=i386} %{m486:-mcpu=i486 -march=i486} %{mpentium:-mcpu=pentium} %{mpentiumpro:-mcpu=pentiumpro}}

    *mingw_include_path:
    ! mingw32

    *link_command:
    %{!fsyntax-only: %{!c:%{!M:%{!MM:%{!E:%{!S:%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}} %{static:} %{L*} %D %o %{!nostdlib:%{!nodefaultlibs:%G %L %G}} %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*}
    diff -c specs E:\packages\mingw\gcc\lib\gcc-lib\mingw32\2.95.2\specs
    *** specs Sat Aug 12 12:56:38 2000
    --- E:\packages\mingw\gcc\lib\gcc-lib\mingw32\2.95.2\specs Fri Dec 29 03:13:57 2000
    ***************
    *** 5,11 ****

    *cpp:
    ! -remap %(cpp_cpu) %{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT}

    *cc1:
    %(cc1_spec)
    --- 5,11 ----

    *cpp:
    ! -remap %(cpp_cpu) %{posix:-D_POSIX_SOURCE} %{mthreads:-D_MT} %{static:-D__STATIC__}

    *cc1:
    %(cc1_spec)
    ***************
    *** 20,26 ****
    %{mwindows:--subsystem windows} %{mconsole:--subsystem console} %{shared: %{mdll: %eshared and mdll are not compatible}} %{shared: --shared} %{mdll:--dll} %{shared|mdll: -e _DllMainCRTStartup@12}

    *lib:
    ! %{pg:-lgmon} %{mwindows:-lgdi32 -lcomdlg32} -luser32 -lkernel32 -ladvapi32 -lshell32

    *libgcc:
    %{mthreads:-lmingwthrd} -lmingw32 -lgcc -lmoldname -lmsvcrt
    --- 20,26 ----
    %{mwindows:--subsystem windows} %{mconsole:--subsystem console} %{shared: %{mdll: %eshared and mdll are not compatible}} %{shared: --shared} %{mdll:--dll} %{shared|mdll: -e _DllMainCRTStartup@12}

    *lib:
    ! -liberty %{pg:-lgmon} %{mwindows:-lgdi32 -lcomdlg32} -luser32 -lkernel32 -ladvapi32 -lshell32

    *libgcc:
    %{mthreads:-lmingwthrd} -lmingw32 -lgcc -lmoldname -lmsvcrt
    ***************
    *** 41,47 ****
    0

    *version:
    ! 2.95.2

    *multilib:
    . ;
    --- 41,47 ----
    0

    *version:
    ! 2.95.2-mingw snapshot 20001228

    *multilib:
    . ;
    ***************
    *** 80,86 ****
    %{!mcpu*: %{m386:-mcpu=i386 -march=i386} %{m486:-mcpu=i486 -march=i486} %{mpentium:-mcpu=pentium} %{mpentiumpro:-mcpu=pentiumpro}}

    *mingw_include_path:
    ! i386-mingw32msvc

    *link_command:
    %{!fsyntax-only: %{!c:%{!M:%{!MM:%{!E:%{!S:%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}} %{static:} %{L*} %D %o %{!nostdlib:%{!nodefaultlibs:%G %L %G}} %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*}
    --- 80,86 ----
    %{!mcpu*: %{m386:-mcpu=i386 -march=i386} %{m486:-mcpu=i486 -march=i486} %{mpentium:-mcpu=pentium} %{mpentiumpro:-mcpu=pentiumpro}}

    *mingw_include_path:
    ! mingw32

    *link_command:
    %{!fsyntax-only: %{!c:%{!M:%{!MM:%{!E:%{!S:%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}} %{static:} %{L*} %D %o %{!nostdlib:%{!nodefaultlibs:%G %L %G}} %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*}
    ====

     
  • Danny Smith

    Danny Smith - 2001-01-01

    Paul,
    That "long double" business was misleading. I was get getting unresolved references to things like
    nmth000000.o(.idata$4+0x0): undefined reference to `_nm(char,...)(long double, long double)' Now I realise that is not a problem with long double but a sign of a confused demangler.

    Your Happy New Year test works with auto-import if I do following:

    1) Build libstdc++.dll and implib as per a2dll, but using ld-20001204, and excluding static libstdc++.a from the build (by using gcc -shared rather than g++ -shared).

    2) Build test program with auto-import using ld-20001204.

    If I used old ld to build libstdc++.dll.a in step 1 I get the unresolved references to _nm__cout or to the screwy long double name '_nm(char,...)(long double, long double)'
    if test code has
    cerr<<"Happy New Year" ;

    Cheers
    Danny

     
  • Danny Smith

    Danny Smith - 2001-01-23

    Paul, here's a test case showing failure with C++ code, not using iostreams. The problem is when there is dependency between two objects *within* the dll (like cerr and cout, in libstdc++.dll).

    Testing was done with lastest beta (Jan 2001) of ld and bfd.

    If dll implib is built with release or CVS ld, there is problem with auto-import.

    If dll implib is built with your ld, no problem.

    Here is the script:

    rem build dll the old way (with declspecs)
    c++ -c -DBUILDING_DLL=1 -DUSE_DECLSPEC -I. -g \ -o dllclass.o dllclass.cpp
    c++ -c -DBUILDING_DLL=1 -DUSE_DECLSPEC -I. -g \
    -o dllexterns.o dllexterns.cpp

    rem use cvs ld to build dll
    rm -f useCVSdll.exe
    c++ -shared -Wl,--out-implib,libCVScxxdll.a \ -o CVScxxdll.dll dllclass.o dllexterns.o
    rem don't use declspecs in client to test Paul's auto-import
    c++ -c -I. -g -o usedll.o usedll.cpp
    c++ -Bd:/test/ld-auto/ -o useCVSdll.exe -g usedll.o \ -L./ -lCVScxxdll
    rem fails to link
    useCVSdll

    rem use Paul's ld
    rm -f usePauldll.exe
    c++ -shared -Bd:/test/ld-auto/ \ -Wl,--out-implib,libPaulcxxdll.a -o Paulcxxdll.dll \ dllclass.o dllexterns.o
    rem don't use declspecs in client to test auto-import
    c++ -c -I. -g -o usedll.o usedll.cpp
    c++ -Bd:/test/ld-auto/ -o usePauldll.exe -g usedll.o \ -L./ -lPaulcxxdll
    usePauldll

    Here is the code:

    /**********************************************
    * dllclass.h
    */

    #ifndef dllclass_h_included
    #define dllclass_h_included

    #if defined USE_DECLSPEC
    #if BUILDING_DLL
    # define DLLIMPORT __declspec (dllexport)
    #else /* Not BUILDING_DLL */
    # define DLLIMPORT __declspec (dllimport)
    #endif /* Not BUILDING_DLL */
    #else
    #define DLLIMPORT
    #endif

    struct DLLIMPORT
    InnerClass {
    InnerClass(int i=0);
    int inner_int;
    int in_method() const;
    };

    struct DLLIMPORT
    OuterClass {
    OuterClass();
    OuterClass(InnerClass);
    int out_method () const;
    InnerClass InnerObject;
    };
    #endif /* dllclass_h_included */

    /*****************************************************
    * dllclass.cpp
    */

    #include "dllclass.h"
    #include <stdio.h>

    InnerClass::InnerClass(const int i):inner_int(i)
    {
    printf("In InnerClass ctor in dll\n");
    };

    int
    InnerClass::in_method () const
    {
    int retval=inner_int;
    printf("In InnerClass method in dll, retval= %i \n", retval);
    return retval;
    }

    OuterClass::OuterClass()
    {
    printf("In OuterClass ctor in dll\n");
    InnerClass InnerObject();
    }

    OuterClass::OuterClass(InnerClass src):InnerObject(src)
    {
    printf("In OuterClass ctor in dll\n");
    };

    int
    OuterClass::out_method () const
    {
    int retval= (InnerObject.in_method() + 10);
    printf("In OuterClass method in dll, retval= %i \n", retval);
    return retval;
    }

    /***************************************************************
    * dllexterns.cpp
    */

    #include "dllclass.h"

    DLLIMPORT InnerClass global_innerclass(10);
    DLLIMPORT OuterClass global_outerclass(global_innerclass);

    /**********************************************************
    * usedll.cpp
    */

    #include <stdio.h>
    #include "dllclass.h"

    extern DLLIMPORT InnerClass global_innerclass;
    extern DLLIMPORT OuterClass global_outerclass;

    int main () {
    printf("In main\n");
    global_outerclass.out_method();
    return 1;
    }

    ************************************************************

    Cheers
    Danny

     
  • Earnie Boyd

    Earnie Boyd - 2001-12-11
    • status: open --> closed