Page 1 of 1

Cross-compiled libsupc++ for x86_64

Posted: Wed Nov 11, 2015 1:59 pm
by evoex
Hello all,

I'm working on a x86_64 kernel. I've got usermode working and got a basic allocator for my applications. As my kernel is in C++, so will my usermode programs, and I would like to be able to use all C++ features there, including exceptions and the standard library. My current task is to add exceptions, RTTI, etc.
If I'm not mistaken I could simply link my programs with -lsupc++, if I'd have a working library. This should, I believe, implement those features.
But getting a good libsupc++.a doesn't really seem to work (I've tried a lot of things, including but not limited to http://wiki.osdev.org/Libsupcxx ).
Hence I'm trying to compile libsupc++.a on my Mac, to run on my x86_64 emulator.

For example, I ran the following commands:

Code: Select all

export CC=/opt/local/bin/gcc-mp-4.9
export CXX=/opt/local/bin/g++-mp-4.9
export CPP=/opt/local/bin/cpp-mp-4.9
export LD=/opt/local/bin/gcc-mp-4.9
export PREFIX=/usr/local/cross
export TARGET=x86_64-elf
export PATH="$PREFIX/bin:$PATH

cd /usr/local/cross/files/src/gcc-4.8.3/libstdc++-v3
CPP=/usr/local/cross/bin/x86_64-elf-cpp ./configure --host=x86_64-elf --prefix=/usr/local/cross --disable-hosted-libstdcxx --disable-nls
cd libsupc++
make
And it creates a file ".libs/libsupc++.a". However, I can't link to this file:

Code: Select all

$ /usr/local/cross/bin/x86_64-elf-nm .libs/libsupc++.a 
/usr/local/cross/bin/x86_64-elf-nm: array_type_info.o: File format not recognized
/usr/local/cross/bin/x86_64-elf-nm: atexit_arm.o: File format not recognized
[...]
/usr/local/cross/bin/x86_64-elf-nm: vmi_class_type_info.o: File format not recognized
/usr/local/cross/bin/x86_64-elf-nm: vterminate.o: File format not recognized
The usual nm from Mac OS X does produce the expected output. So it seems to be compiling for the wrong target. Which isn't surprising from the make output (one example line):

Code: Select all

/bin/sh ../libtool --tag CXX --tag disable-shared   --mode=compile /opt/local/bin/g++-mp-4.9 -I/usr/local/cross/files/src/gcc-4.8.3/libstdc++-v3/../libgcc -I/usr/local/cross/files/src/gcc-4.8.3/libstdc++-v3/include/x86_64-elf -I/usr/local/cross/files/src/gcc-4.8.3/libstdc++-v3/include -I/usr/local/cross/files/src/gcc-4.8.3/libstdc++-v3/libsupc++     -Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi  -fdiagnostics-show-location=once    -ffunction-sections -fdata-sections  -frandom-seed=vterminate.lo   -c -o vterminate.lo vterminate.cc
I've tried several other methods. For example, it seemed reasonable to try to compile with the cross-compiled compilers:

Code: Select all

export CC=/usr/local/cross/bin/x86_64-elf-gcc
export CXX=/usr/local/cross/bin/x86_64-elf-g++
export CPP=/usr/local/cross/bin/x86_64-elf-cpp
export LD=/usr/local/cross/bin/x86_64-elf-gcc

cd /usr/local/cross/files/src/gcc-4.8.3/libstdc++-v3
./configure --host=x86_64-elf --prefix=/usr/local/cross --disable-hosted-libstdcxx --disable-nls
But this won't even finish:

Code: Select all

[...]
checking whether the /usr/local/cross/bin/x86_64-elf-gcc linker (/usr/local/cross/bin/x86_64-elf-gcc) supports shared libraries... no
checking dynamic linker characteristics... no
checking how to hardcode library paths into programs... unsupported
checking for shl_load... configure: error: Link tests are not allowed after GCC_NO_EXECUTABLES.
So, any ideas on how I could get a proper libsupc++ here?

Thanks in advance!

Re: Cross-compiled libsupc++ for x86_64

Posted: Thu Nov 12, 2015 6:42 am
by evoex
Let me report some progress... I think I successfully compiled libsupc++.a, but I'm not sure. At least it's now recognised by x86_64-elf-nm. I did it as follows:
I ran configure as the initial method explained. Then I modified the Makefile to change all the compilers to the x86_64 versions. Then I had to modify the CFLAGS and CXXFLAGS as follows:

Code: Select all

CFLAGS = -g -O2 -I../../x86_64-elf/libgcc -I/usr/include/ -I/usr/include/tr1
CXXFLAGS = -I../../x86_64-elf/libgcc -I/usr/include/ -I/usr/include/tr1
This compiles fine, but when linking to libsupc++.a it reports an error:

Code: Select all

mods/testmod/Main.cpp:12: undefined reference to `_Unwind_Resume'
.bin/mods/testmod/Main_cpp.o:(.eh_frame+0x4b): undefined reference to `__gxx_personality_v0'
Which seems to be right:

Code: Select all

$ /usr/local/cross/bin/x86_64-elf-nm /usr/local/cross/lib/libsupc++.a |grep _Unwind_Resume
                 U _Unwind_Resume
                 [...]
I'm not yet sure where _Unwind_Resume ought to be defined, but I guess I'll try to find out now...

Input is still very welcome. I wouldn't be surprised if my entire method will end up failing completely with some page fault...

Re: Cross-compiled libsupc++ for x86_64

Posted: Thu Nov 12, 2015 8:55 am
by evoex
Another update: I trivially compiled libgcc, and it fixed some of the warnings. However, there's still a warning:

Code: Select all

$ /usr/local/cross/bin/x86_64-elf-g++ -T mods/linker.ld -z max-page-size=0x1000 -L /usr/local/cross/lib/gcc/x86_64-elf/4.8.3/ -L /usr/local/cross/lib -ffreestanding -nostdlib -mno-mmx -mno-sse -mno-sse2 -mno-red-zone -L .bin/lib .bin/mods/testmod/Main_cpp.o -lcore -lgcc -lsupc++ -o .bin/testmod.glm
Returns error (among others, but they look easily fixable):

Code: Select all

.bin/mods/testmod/Main_cpp.o:(.eh_frame+0x4b): undefined reference to `__gxx_personality_v0'
Even though:

Code: Select all

$ /usr/local/cross/bin/x86_64-elf-nm /usr/local/cross/lib/libsupc++.a |grep __gxx_personality_v0
                 U __gxx_personality_v0
                 U __gxx_personality_v0
0000000000000000 T __gxx_personality_v0
                 U __gxx_personality_v0
                 U __gxx_personality_v0
                 U __gxx_personality_v0
                 U __gxx_personality_v0
                 U __gxx_personality_v0
                 U __gxx_personality_v0
                 U __gxx_personality_v0
                 U __gxx_personality_v0
                 U __gxx_personality_v0
So it seems to be defined. Any ideas why it ends up undefined?

Re: Cross-compiled libsupc++ for x86_64

Posted: Thu Nov 12, 2015 10:20 am
by evoex
Okay, I figured it out... I'm not sure what I was doing wrong, but after a "make distclean" the compilation failed. This turned out to be due to a bug in some header file (only google instance I found searching for the error, changing "void abort()" to "void abort(void)"). Then it compiled, and the linking went fine.
Exceptions and RTTI seem to work now...

That was quite a challenge...