[cfe-dev] Linker error and obfuscated name: Part II

Reid Kleckner rnk at google.com
Thu Aug 6 09:36:23 PDT 2015


I reproduced your example, and it looks like we are forgetting to export
RTTI with dllexport in Itanium. We only export the vtable. This is what
each compiler exports for ex_xml_exception.obj:

$ dumpbin -directives ex_xml_exception.clang.obj | grep -export:_ZT |
c++filt --no-strip-underscore
   -export:virtual thunk to ex_xml_exception::~ex_xml_exception()
   -export:virtual thunk to ex_xml_exception::~ex_xml_exception()
   -export:vtable for ex_xml_exception,data

$ dumpbin -directives ex_xml_exception.gcc.obj | grep -export:_ZT | c++filt
--no-strip-underscore
   -export:typeinfo for ex_exception,data
   -export:typeinfo for ex_xml_exception,data
   -export:construction vtable for ex_exception-in-ex_xml_exception,data
   -export:VTT for ex_xml_exception,data
   -export:vtable for ex_xml_exception,data
   -export:virtual thunk to ex_xml_exception::~ex_xml_exception()
   -export:virtual thunk to ex_xml_exception::~ex_xml_exception()

In your previous example where the whole class wasn't exported, I think we
might be doing the wrong thing when the key function is dllimport /
dllexport. We think that it will provide exported symbols for vtables and
RTTI but it doesn't. This is something we didn't run into because the MSVC
ABI doesn't have key functions.

On Thu, Aug 6, 2015 at 6:16 AM, Edward Diener <
eldlistmailingz at tropicsoft.com> wrote:

> Using clang on Windows targeting mingw(-64)/gcc since it does not appear
> possible to export individual member functions of a class, as well as
> export the RTTI of the class, without exporting the entire class, I have
> changed my example in my post "Linker error and obfuscated name" to export
> the entire class itself. But I am still seeing a linker error, Here is the
> changed code and command lines:
>
> // ex_decl.hpp
>
> #ifndef EX_DECL_HPP
> #define EX_DECL_HPP
> #if defined(BLD_EX_EXAMPLE)
>     #define EX_DECL __attribute__((__dllexport__))
> #else
>     #define EX_DECL __attribute__((__dllimport__))
> #endif
> #endif // EX_DECL_HPP
>
> // ex_exception.hpp
>
> #ifndef EX_EXCEPTION_HPP
> #define EX_EXCEPTION_HPP
> #include <exception>
> #include "ex_decl.hpp"
> class EX_DECL ex_exception :
>     public virtual std::exception
> {
> private:
>     char m_buffer[128];
> protected:
>     unsigned int append(unsigned int l, const char * a);
>     ex_exception() ;
> public:
>     typedef enum {
>       no_exception,
>       other_exception
>     } ex_exception_code;
>     ex_exception_code code;
>     ex_exception(ex_exception_code c,const char * e1 = 0,const char * e2 =
> 0) ;
>     ex_exception(ex_exception const &) ;
>     virtual ~ex_exception() throw() ;
>     virtual const char * what() const throw() ;
> };
> #endif // EX_EXCEPTION_HPP
>
> // ex_exception.cpp
>
> #include <exception>
> #include <cstring>
> #define BLD_EX_EXAMPLE
> #include "ex_exception.hpp"
> unsigned int ex_exception::append(unsigned int l, const char * a){
>     while(l < (sizeof(m_buffer) - 1)){
>         char c = *a++;
>         if('\0' == c)
>             break;
>         m_buffer[l++] = c;
>     }
>     m_buffer[l] = '\0';
>     return l;
> }
> ex_exception::ex_exception(ex_exception_code c,const char * e1,const char
> * e2) : code(c)
> {
>   unsigned int length = 0;
>     switch(code){
>     case no_exception:
>         length = append(length, "uninitialized exception");
>         break;
>     case other_exception:
>         length = append(length, "unknown derived exception");
>         break;
>     default:
>         length = append(length, "programming error");
>         break;
>     }
> }
> ex_exception::ex_exception(ex_exception const & oth) :
> std::exception(oth),code(oth.code)
> {
>     std::memcpy(m_buffer,oth.m_buffer,sizeof m_buffer);
> }
> ex_exception::~ex_exception() throw() {}
> const char * ex_exception::what() const throw() { return m_buffer; }
> ex_exception::ex_exception() : code(no_exception) {}
>
> // Compile ex_exception.cpp
>
> clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS
> -Wno-unused-local-typedef -Wno-dll-attribute-on-redeclaration -O0 -g
> -fno-inline -Wall -g -march=i686 -m32 -o "ex_exception.obj"
> "ex_exception.cpp"
>
> // ex_xml_exception.hpp
>
> #ifndef EX_XML_EXCEPTION_HPP
> #define EX_XML_EXCEPTION_HPP
> #include <exception>
> #include "ex_decl.hpp"
> #include "ex_exception.hpp"
> class EX_DECL ex_xml_exception :
>     public virtual ex_exception
> {
> public:
>     typedef enum {
>         xml_archive_parsing_error,
>         xml_archive_tag_mismatch,
>         xml_archive_tag_name_error
>     } ex_exception_code;
>     ex_xml_exception(ex_exception_code c,const char * e1 = 0,const char *
> e2 = 0);
>     ex_xml_exception(ex_xml_exception const &) ;
>     virtual ~ex_xml_exception() throw() ;
> };
> #endif // EX_XML_EXCEPTION_HPP
>
> // ex_xml_exception.cpp
>
> #include <exception>
> #define BLD_EX_EXAMPLE
> #include "ex_xml_exception.hpp"
> ex_xml_exception::ex_xml_exception(ex_exception_code c,const char *
> e1,const char * e2) :
>         ex_exception(other_exception, e1, e2)
>     {
>         switch(c){
>         case xml_archive_parsing_error:
>             ex_exception::append(0, "unrecognized XML syntax");
>             break;
>         case xml_archive_tag_mismatch:
>             ex_exception::append(0, "XML start/end tag mismatch");
>             if(0 != e1){
>                 ex_exception::append(0, " - ");
>                 ex_exception::append(0, e1);
>             }
>             break;
>         case xml_archive_tag_name_error:
>             ex_exception::append(0, "Invalid XML tag name");
>             break;
>         default:
>             ex_exception::append(0, "programming error");
>             break;
>         }
>     }
> ex_xml_exception::ex_xml_exception(ex_xml_exception const & oth) :
> std::exception(oth),ex_exception(oth){}
> ex_xml_exception::~ex_xml_exception() throw() {}
>
> // Compile ex_xml_exception.cpp
>
> clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS
> -Wno-unused-local-typedef -Wno-dll-attribute-on-redeclaration -O0 -g
> -fno-inline -Wall -g -march=i686 -m32 -o "ex_xml_exception.obj"
> "ex_xml_exception.cpp"
>
> // Link exmp-clang37-d-1_59.dll
>
> clang++.exe -o "exmp-clang37-d-1_59.dll" -Wl,-soname
> -Wl,exmp-clang37-d-1_59.dll -shared -Wl,--start-group "ex_exception.obj"
> "ex_xml_exception.obj"  -Wl,-Bstatic  -Wl,-Bdynamic  -Wl,--end-group -g
> -march=i686 -m32
>
> // throw_exception_ex.cpp
>
> #include "ex_xml_exception.hpp"
> template<class E> void throw_exception(E const & e) { throw e; }
> int main(int argc,char * argv[])
> {
>     if (argc > 1)
>           {
>
> throw_exception(ex_xml_exception(ex_xml_exception::xml_archive_parsing_error));
>
>           }
>     return 0;
> }
>
> // Compile throw_exception_ex.cpp
>
> clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS
> -Wno-unused-local-typedef -Wno-dll-attribute-on-redeclaration -O0 -g
> -fno-inline -Wall -g -march=i686 -m32 -o "throw_exception_ex.obj"
> "throw_exception_ex.cpp"
>
> // Link thr_exmp.exe
>
> clang++.exe -Wl,-R -Wl,"." -Wl,-rpath-link -Wl,"." -o "thr_exmp.exe"
> -Wl,--start-group "throw_exception_ex.obj" "exmp-clang37-d-1_59.dll"
> -Wl,-Bstatic -Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32
>
> // Error message from this link
>
> throw_exception_ex.obj: In function
> `Z15throw_exceptionI16ex_xml_exceptionEvRKT_':
> throw_exception_ex.cpp:2: undefined reference to
> `_imp___ZTI16ex_xml_exception'
> clang++.exe: error: linker command failed with exit code 1 (use -v to see
> invocation)
>
> So even when I export/import the entire class rather than individual
> member functions, I can not link my final module successfully as it is
> still looking for something in the shared library that it says is not
> there.
>
> This same code succeeds without problem with mingw(-64)/gcc on Windows.
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20150806/0d83c94c/attachment.html>


More information about the cfe-dev mailing list