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

David Majnemer david.majnemer at gmail.com
Thu Aug 6 13:58:37 PDT 2015


On Thu, Aug 6, 2015 at 1:21 PM, Edward Diener <
eldlistmailingz at tropicsoft.com> wrote:

> On 8/6/2015 12:44 PM, Reid Kleckner wrote:
>
>> 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.
>>
>
> I tried this simple example:
>
> // ex_aclass.hpp
>
> #ifndef EX_ACLASS_HPP
> #define EX_ACLASS_HPP
> #if defined(BLD_EX_EXAMPLE)
>         #define EX_DECL __attribute__((__dllexport__))
> #else
>         #define EX_DECL __attribute__((__dllimport__))
> #endif
> class EX_DECL ex_aclass
> {
> public:
>     int a_function(long);
> };
> #endif // EX_ACLASS_HPP
>
> // ex_aclass.cpp
>
> #define BLD_EX_EXAMPLE
> #include "ex_aclass.hpp"
> int ex_aclass::a_function(long amt)
>         {
>         return(amt > 1000000 ? 10 : 20);
>         }
>
> // Compile ex_aclass
>
> clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS -O0 -g -fno-inline -Wall
> -g -march=i686 -m32 -o "ex_aclass.obj" "ex_aclass.cpp"
>
> // Link to ex_ac dll
>
> clang++.exe -o "ex_ac.dll" -Wl,-soname -Wl,ex_ac.dll -shared
> -Wl,--start-group "ex_aclass.obj" -Wl,-Bstatic -Wl,-Bdynamic
> -Wl,--end-group -g -march=i686 -m32
>
> // ex_use_aclass.cpp
>
> #include "ex_aclass.hpp"
> int main(int argc,char * argv[])
>         {
>         ex_aclass aclass;
>         int ret(aclass.a_function(10000));
>         return ret;
>         }
>
> // Compile ex_use_aclass
>
> clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS -O0 -g -fno-inline -Wall
> -g -march=i686 -m32 -o "ex_use_aclass.obj" "ex_use_aclass.cpp"
>
> // Link ex_use_ac executable
>
> clang++.exe -Wl,-R -Wl,"." -Wl,-rpath-link -Wl,"." -o "ex_use_ac.exe"
> -Wl,--start-group "ex_use_aclass.obj" "ex_ac.dll" -Wl,-Bstatic
> -Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32
>
> All of this worked with no problems.
>
> So the basic ability to access functionality in a class in a DLL from
> outside that DLL works fine using clang on Windows. It is something
> specific in my original example below that is causing linking problems,
> whether I export entire classes or whether I export individual member
> functions. Just thought I would let you know. Needless to say I need to
> solve my original problem because that code mimics the design of a very
> small portion of the Boost serialization library and is the cause why the
> Boost serialization library will not build with clang on Windows targeting
> gcc.
>

Should be fixed in r244266.



>
>
>> On Thu, Aug 6, 2015 at 9:36 AM, Reid Kleckner
>> <rnk-hpIqsD4AKlfQT0dZR+AlfA at public.gmane.org
>>
>> <mailto:rnk-hpIqsD4AKlfQT0dZR+AlfA at public.gmane.org>> 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
>>     <mailto:eldlistmailingz-5p0dqD/c5LGWd6l5hS35sQ at public.gmane.org>>
>> 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/890e113f/attachment.html>


More information about the cfe-dev mailing list