Enabling C++ RTTI in usermode for own OS

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Enabling C++ RTTI in usermode for own OS

Post by Candy »

When trying to enable userspace RTTI for my OS, I ran against this error:

Code: Select all

x86_64-pc-elf/lib/libaos/baselib/thread.o:(.rodata._ZTI11thread_base[_ZTI11thread_base]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
What is __cxxabiv1 supposed to be?
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Re:Enabling C++ RTTI in usermode for own OS

Post by Brynet-Inc »

Not sure, But I think its trying to link with libstdc++/libsupc++... ???

There is a cxxabi.h file...

I'm guessing it provides an interface to the C++ ABI.. lol ;)

Code: Select all

http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/cxxabi_8h.html
Searched here also...

Code: Select all

http://koders.com/cpp/fid645659D1540BDC33C20F6992E1C57E91878EF60B.aspx?s=__cxxabiv1
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
bluecode

Re:Enabling C++ RTTI in usermode for own OS

Post by bluecode »

gcc C++ ABI. Look under 2.9.5 RTTI Layout.
This class is derived from std::type_info and holds information about normal classes (without a base class).

[edit: I think, the special namespace is supposed to handle changes in the abi correctly]
Cemre

Re:Enabling C++ RTTI in usermode for own OS

Post by Cemre »

Add this to your main header file

Code: Select all

namespace std
{

   class type_info
   {

      private:

         const char* tname;

      public:

         virtual ~type_info ( void ) ;

         type_info ( const type_info& ) ;

         explicit type_info ( const char* ) ;

         const char* name ( void ) const ;

         bool operator == ( const type_info& ) const ;

         bool operator != ( const type_info& ) const ;

   };

}

namespace __cxxabiv1
{

   #define ADD_CXX_TYPEINFO_HEADER(t) \
      class t : public std::type_info \
      { \
         public: \
            virtual ~t ( void ); \
            explicit t ( const char* ); \
      } \

   ADD_CXX_TYPEINFO_HEADER ( __fundamental_type_info );
   ADD_CXX_TYPEINFO_HEADER ( __array_type_info );
   ADD_CXX_TYPEINFO_HEADER ( __function_type_info );
   ADD_CXX_TYPEINFO_HEADER ( __enum_type_info );
   ADD_CXX_TYPEINFO_HEADER ( __pbase_type_info );
   ADD_CXX_TYPEINFO_HEADER ( __pointer_type_info );
   ADD_CXX_TYPEINFO_HEADER ( __pointer_to_member_type_info );
   ADD_CXX_TYPEINFO_HEADER ( __class_type_info );
   ADD_CXX_TYPEINFO_HEADER ( __si_class_type_info );
   ADD_CXX_TYPEINFO_HEADER ( __vmi_class_type_info );

   #undef ADD_CXX_TYPEINFO_HEADER

}
Add this to your main library or directly into source file

Code: Select all

namespace std
{

   type_info::~type_info ( void )
   {
   }

   type_info::type_info ( const type_info& arg )
      : tname ( arg.tname )
   {
   }

   type_info::type_info ( const char* pname )
      : tname ( pname )
   {
   }

   const char* type_info::name ( void ) const
   {
      return tname;
   }

   bool type_info::operator == ( const type_info& arg ) const
   {
      return tname == arg.tname;
   }

   bool type_info::operator != ( const type_info& arg ) const
   {
      return tname != arg.tname;
   }

}

namespace __cxxabiv1
{

   #define ADD_CXX_TYPEINFO_SOURCE(t) \
      t::~t ( void ) {;} \
      t::t ( const char* n ) : std::type_info ( n ) {;} \

   ADD_CXX_TYPEINFO_SOURCE ( __fundamental_type_info )
   ADD_CXX_TYPEINFO_SOURCE ( __array_type_info )
   ADD_CXX_TYPEINFO_SOURCE ( __function_type_info )
   ADD_CXX_TYPEINFO_SOURCE ( __enum_type_info )
   ADD_CXX_TYPEINFO_SOURCE ( __pbase_type_info )
   ADD_CXX_TYPEINFO_SOURCE ( __pointer_type_info )
   ADD_CXX_TYPEINFO_SOURCE ( __pointer_to_member_type_info )
   ADD_CXX_TYPEINFO_SOURCE ( __class_type_info )
   ADD_CXX_TYPEINFO_SOURCE ( __si_class_type_info )
   ADD_CXX_TYPEINFO_SOURCE ( __vmi_class_type_info )

   #undef ADD_CXX_TYPEINFO_SOURCE

}
PS: you can only to typeid with this, you need to do other stuff to implement try catch exception handling

regards.
bluecode

Re:Enabling C++ RTTI in usermode for own OS

Post by bluecode »

Cemre wrote:PS: you can only to typeid with this, you need to do other stuff to implement try catch exception handling
You also need to write your own dynamic_cast, if you want to fully support RTTI.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Enabling C++ RTTI in usermode for own OS

Post by Pype.Clicker »

what's that "explicit" keyword? i never heard of it before ...
oswizard

Re:Enabling C++ RTTI in usermode for own OS

Post by oswizard »

I think it means that the compiler doesn't do any implicit type conversions using the constructor. You would have to explicitly call it. But that's just what I think, not what the docs say ;)
Habbit

Re:Enabling C++ RTTI in usermode for own OS

Post by Habbit »

An explicit constructor has to be called by name, so it can't be used as a "conversion operator".

Code: Select all

class C
{
    C(int i);
    explicit C(double d);
}

int main(int, char**)
{
    C fromInt = 20;
    //C fromDoubleE = 3.14159; // Fails
    C fromDoubleOK(3.14159);
}
Or so I think, I didn't try to compile this code :P
If you ask me, I prefer the .NET way: both to and from conversion operators are declared as static methods like this:

Code: Select all

class C
{
    static implicit operator C(int from);  // int -> C
    static explicit operator double(C from);  // C -> double
}
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Enabling C++ RTTI in usermode for own OS

Post by Candy »

Habbit wrote: Or so I think, I didn't try to compile this code :P
If you ask me, I prefer the .NET way: both to and from conversion operators are declared as static methods like this:

Code: Select all

class C
{
    static implicit operator C(int from);  // int -> C
    static explicit operator double(C from);  // C -> double
}
You needn't prefer .NET for that, C++ allows it as well. C++ does allow other ways too, which I prefer.
Habbit

Re:Enabling C++ RTTI in usermode for own OS

Post by Habbit »

Candy wrote: You needn't prefer .NET for that, C++ allows it as well. C++ does allow other ways too, which I prefer.
AFAIK, C++ conversion operators are only from the class being declared to another type (like [tt]class C { operator int(void) const; }[/tt]). All conversions from other types to the class being declared must be done either through constructors or assignment operators.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Enabling C++ RTTI in usermode for own OS

Post by Candy »

bluecode wrote:
Cemre wrote:PS: you can only to typeid with this, you need to do other stuff to implement try catch exception handling
You also need to write your own dynamic_cast, if you want to fully support RTTI.
Those will follow, this was just for being able to not say -fno-rtti to the compiler. I'll do those on-demand at first (when I accidentally use them and get a compile error) and when I think I should add them explicitly.

Do you happen to know the copyrights on the code by any chance?
Post Reply