I've been implementing a compiler that targets LLVM, and was looking
into using the shadow-stack gc strategy. Currently, I build the runtime
with clang (using -emit-llvm), and then link that with the LLVM bitcode
output from my compiler using llvm-ld.
This works fine without the gc strategy annotations and use of the
llvm.gcroot intrinsic, but adding them causes some odd behavior: the
resulting bitcode will generate a large stack trace from lli (appended
at the end of this message), and the resulting native assembly,
generated with llc, will never update my llvm_gc_root_chain global.
Interestingly, if I build my runtime with g++, or clang without
-emit-llvm, and link everything together after generating native
assembly from the output of my compiler, it works. The stack roots get
registered, and the llvm_gc_root_chain global gets updated.
Is linking in the runtime as an LLVM bitcode object something that I
should expect to work, or does it make more sense to build the runtime
for the target, and not try to emit LLVM bitcode programs from my compiler?
Thanks!
--trevor
0 libLLVM-2.8.so 0x0000003cc36eee9f
1 libLLVM-2.8.so 0x0000003cc36ef99a
2 libpthread.so.0 0x0000003cc200f4a0
3 libLLVM-2.8.so 0x0000003cc33360dd
llvm::StructType::StructType(llvm::LLVMContext&, std::vector<llvm::Type
const*, std::allocator<llvm::Type const*> > const&, bool) + 237
4 libLLVM-2.8.so 0x0000003cc3337c95
llvm::StructType::get(llvm::LLVMContext&, std::vector<llvm::Type const*,
std::allocator<llvm::Type const*> > const&, bool) + 533
5 libLLVM-2.8.so 0x0000003cc3242d58
6 libLLVM-2.8.so 0x0000003cc318f09e
7 libLLVM-2.8.so 0x0000003cc3330628
llvm::FPPassManager::runOnFunction(llvm::Function&) + 424
8 libLLVM-2.8.so 0x0000003cc33307cb
llvm::FunctionPassManagerImpl::run(llvm::Function&) + 91
9 libLLVM-2.8.so 0x0000003cc33309bd
llvm::FunctionPassManager::run(llvm::Function&) + 173
10 libLLVM-2.8.so 0x0000003cc33e8647
llvm::JIT::jitTheFunction(llvm::Function*, llvm::MutexGuard const&) + 39
11 libLLVM-2.8.so 0x0000003cc33e8a2f
llvm::JIT::runJITOnFunctionUnlocked(llvm::Function*, llvm::MutexGuard
const&) + 15
12 libLLVM-2.8.so 0x0000003cc33e8cde
llvm::JIT::getPointerToFunction(llvm::Function*) + 606
13 libLLVM-2.8.so 0x0000003cc33ea253
llvm::JIT::runFunction(llvm::Function*, std::vector<llvm::GenericValue,
std::allocator<llvm::GenericValue> > const&) + 67
14 libLLVM-2.8.so 0x0000003cc336ad4a
llvm::ExecutionEngine::runFunctionAsMain(llvm::Function*,
std::vector<std::string, std::allocator<std::string> > const&, char
const* const*) + 1130
15 lli 0x0000000000404cd6 main + 2054
16 libc.so.6 0x0000003cc1c1ec5d __libc_start_main + 253
17 lli 0x0000000000403689
Stack dump:
0. Program arguments: lli test.bc
1. Running pass 'Lower Garbage Collection Instructions' on function '@main'
zsh: segmentation fault (core dumped) ./test
----- Forwarded Message ----
> From: Samuel Crow <samura...@yahoo.com>
> To: Trevor Elliott <tre...@galois.com>
> Sent: Fri, January 14, 2011 7:33:15 PM
> Subject: Re: [LLVMdev] LLVM GC
>
> Hi Trevor,
>
> Are you linking with LibStdC++ or LibC++? That is a requirement for running
> code that has been compiled from C++ to bitcode.
>
> Hope this helps,
>
> --Sam Crow
_______________________________________________
LLVM Developers mailing list
LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
I've not actually gotten to the linking process with my runtime, as I've
compiled it with clang -emit-llvm -c, and then archived it with llvm-ar
and llvm-ranlib. I'm also not producing a GC plugin, as I'm using the
builtin "shadow-stack" strategy.
My current build process looks like this:
1. build the compiler
2. build the runtime using clang -emit-llvm -c
3. generate an archive from the runtime .bc files using llvm-ar and
llvm-ranlib
3. compile a program with the compiler, producing a .bc file
4. link the program and runtime together using llvm-ld
5. run the program with lli
This all works fine until step 5 when the stack trace gets generated.
The function that it complains about, @main, is the main function from
my runtime. When disassembled with llvm-dis, it doesn't have a gc
attribute on the declaration. Should it still be getting processed by
the "shadow-stack" strategy?
Thanks!
--trevor
--trevor
I've built a minimal test that exposes the problem that I'm encountering
[1]. The Makefile that it includes has two targets of interest,
test-llvm and test.
The test-llvm target will compile a c++ main using "clang -emit-llvm
-c", and link it with an llvm-assembly program that uses the
shadow-stack gc strategy. The asm_main function will allocate 32 bytes
using malloc, and then register that as a gc root, using the llvm.gcroot
intrinsic. It will then print the value of the llvm_gc_root_chain
global, and exit.
The test target will build the c++ main using "clang -c" producing
native code, then use llc and as to produce a native object from the
asm-main.bc bitcode file. It then links everything together using clang
to produce a native executable called test.
The test-llvm target will produce the stack trace that I attached in a
previous message, while the test target produces a program that will
output a non-nil value for the llvm_gc_root_chain when run.
Disassembling test.bc using llvm-dis shows that everything has been
inlined into the @main function, though I'm not sure if this is actually
a problem.
Is there a reason that the test-llvm target isn't working? I was under
the impression that the shadow-stack gc strategy was available when
using lli, though there certainly could be something wrong with the way
I'm putting all of the constituents together.
Thanks,
--trevor
[1] http://www.internetofdeath.com/~moltar/gc.tar.gz
On 01/16/2011 10:51 PM, Trevor Elliott wrote: