[LLVMdev] libstdc++ as bytecode, and compiling C++ to C

Emil Mikulic emil at cs.rmit.edu.au
Mon Nov 20 15:57:08 PST 2006


On Mon, Nov 20, 2006 at 08:01:23AM -0800, Reid Spencer wrote:
> On Mon, 2006-11-20 at 17:49 +1100, Emil Mikulic wrote:
> > I've compiled all the object files that make up libstdc++ and libsupc++
> > into LLVM bytecode:
> > 	http://goanna.cs.rmit.edu.au/~emil/libstdcxx.tar.bz2 (438KB)
> > 
> > A simple test program, x.cpp:
> > 
> > 	#include <iostream>
> > 	int main() { std::cout << "hello world\n"; return 0; }
> > 
> > $ llvm-g++ -emit-llvm -c x.cpp
> > $ llvmc -o=out x.o std/*.o sup/*.o
> > $ lli out.bc
> > Segmentation fault (core dumped)
> > $
> 
> llvmc isn't a completed tool. In particular it doesn't handle native
> linking properly. However, I'm not sure what it would do in your example
> above that would cause the program to seg fault. Can you get a stack
> trace?

Actually, it looks to me like it generates bad code.

$ llvm-dis < out.bc | grep -- -3
	%tmp4.i.i = getelementptr int (...)** %tmp.i.i, int -3
[and a bunch more, one of which is in main()...]

$ llc -march=c -o=cbe.c out.bc
WARNING: this target does not support the llvm.stacksave intrinsic.
$ gcc -g cbe.c
[n.b.: compiles successfully!]
$ gdb a.out
(gdb) run
Starting program: a.out 

Program received signal SIGSEGV, Segmentation fault.
0x08048958 in main () at cbe.c:1154
1154      ltmp_173_15 = *((int *)(&ltmp_172_54[-3]));
(gdb) print ltmp_172_54
$1 = (int (**)()) 0x0

Can I send you bytecode files or any further diagnostics to chase this
up?

> > Oops, no go.  Try a different way:
> > 
> > $ llvm-g++ -emit-llvm -c x.cpp
> > $ llvm-link -o=linked.o x.o std/*.o sup/*.o
> > $ lli linked.o
> > hello world
> > $
> > 
> > So far, so good!  Compile to C:
> 
> llvm-link should work fine because its just dealing with bytecode. BTW,
> You could put all the std/*.o and sup/*.o files into a bc archive using
> llvm-ar and then just link with that archive.

I thought so, and I even tried playing with llvm-ar, but couldn't figure
it out.

$ llvm-ar rs mylib.a std/*.o sup/*.o
llvm-ar: creating mylib.a
$ llvm-link -o=linked.o x.o mylib.a 
llvm-link: error loading file 'mylib.a'

> > $ llc -o=cbe.c -march=c linked.o
> > WARNING: this target does not support the llvm.stacksave intrinsic.
> > $ gcc cbe.c
> > /var/tmp//ccVAM4W2.o(.text+0x329a): In function `operator new(unsigned int)':
> > : undefined reference to `__cxa_throw'
> > [...and more errors]
> > $
> > 
> > But __cxa_throw is right there, in sup/eh_throw.o, and in linked.o, it
> > just isn't being emitted as C code.  (at this point, I suspect the
> > problem might be that I don't quite understand how some of the llvm
> > tools are intended to work - e.g. llvm-link vs llvmc)
> 
> CBE doesn't support exceptions ?

Fair enough.  It's just that if I use llc to compile sup/eh_throw.o to a
C file, it contains a __cxa_throw() function.  (whether it does the
right thing or not, I don't know - I haven't gotten that far)

But, after the big llvm-link step, cbe.c doesn't contain a __cxa_throw()
function even though it's called from the code.

> > Strangely enough:
> > 
> > $ llvm-g++ -emit-llvm -c x.cpp
> > $ llvm-link -o=linked.o x.o std/*.o sup/*.o
> > $ llvmc -o=out linked.o
> > $ llc -o=cbe.c -march=c out.bc
> > WARNING: this target does not support the llvm.stacksave intrinsic.
> 
> CBE doesn't support llvm.stacksave

Fair enough.  =)

> > $ gcc cbe.c
> > $ ./a.out
> > hello world
> > $
> > 
> > Works!
> 
> However it doesn't seem to matter for this program.

The program is very simple, and doesn't use any EH itself, but I think
pieces of libstdc++ do...

--Emil



More information about the llvm-dev mailing list