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

Reid Kleckner rnk at google.com
Thu Aug 6 09:44:33 PDT 2015


Hm, GCC never tries to import RTTI, so maybe it makes sense that we never
export it. Anyway, there's a bug here. Maybe David knows what's up.

On Thu, Aug 6, 2015 at 9:36 AM, Reid Kleckner <rnk at google.com> wrote:

> 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/32b451c3/attachment.html>


More information about the cfe-dev mailing list