Passing an array to an external function

Hi all,

I am new to LLVM, and I am learning how to use LLVM for profiling. I need to
pass an array to an external method, and insert a call instruction to the
method in the code.

After reading a few source files, I've tried using GetElementPtrInst to pass
an array, but it fails at llvm::GetElementPtrInst::hasAllZeroIndices() const
+ 0

      std::vector<Value*> Args(1);
                            
                        //Vector with array values
                        SmallVector<Constant*, 2> counts;
                       
counts.push_back(ConstantInt::get(Type::getInt32Ty(BB->getContext()),32,
false));
                       
counts.push_back(ConstantInt::get(Type::getInt32Ty(BB->getContext()),12,
false));

      //Array with 2 integers
      ArrayType* ar_type =
llvm::ArrayType::get(llvm::Type::getInt32Ty(BI->getContext()),2);
                        Value* array = ConstantArray::get(&(*ar_type),
counts);
                            
                        //Indicies
        std::vector<Value*> ids(1);
                       
ids.push_back(ConstantInt::get(Type::getInt32Ty(BB->getContext()),1));
                       
ids.push_back(ConstantInt::get(Type::getInt32Ty(BB->getContext()),2));
                            
                        Args[1] = GetElementPtrInst::Create(array, ids, "
");

                        //Instrument the branch target instructions
                        CallInst::Create(hook, Args, "",CI);

Also, I 'hook' is defined as M.getOrInsertFunction("hook",
Type::getVoidTy(M.getContext()),
                                                   
PointerType::get(Type::getInt32PtrTy(M.getContext()),0), //??
                                                    (Type*)0);

Could someone kindly keep me a few pointers on passing arrays to an external
function (say with the signature void hook(int abc[]) ). I am probably wrong
all the way through, and would really appreciate some help.

Thanks!

I'm fairly new to LLVM myself, but I'm not sure why you're using GEP at all, let alone with two indices. Does it work to just pass the array value? If not, try using GEP with a single index of 0. The second index would try to index off of element 1 (the second), and then the third element of that, which is an int, and doesn't have sub elements.

Hi,

I tried passing the array directly using and changing the
getorInsertFunction accordingly but this didn't work. It fails with
Assertion `(i >= FTy->getNumParams() || FTy->getParamType(i) ==
Args[i]->getType()) && "Calling a function with a bad signature!"' failed.

hookFunc = M.getOrInsertFunction("hook", Type::getVoidTy(M.getContext()),
llvm::ArrayType::get(llvm::Type::getInt32Ty(M.getContext()),2), (Type*)0);
.....
Args[0] =
ConstantArray::get(llvm::ArrayType::get(llvm::Type::getInt32Ty(BI->getContext()),2),
arr);

I tried using index 0 in the GEP, but it fails with

7 opt 0x00000000006c59f5 bool llvm::isa<llvm::Constant,
llvm::Value*>(llvm::Value* const&) + 24
8 opt 0x00000000006c5a0f llvm::cast_retty<llvm::Constant,
llvm::Value*>::ret_type llvm::cast<llvm::Constant,
llvm::Value*>(llvm::Value* const&) + 24
9 opt 0x0000000000b2b22f
10 opt 0x0000000000b2a4fe
llvm::ConstantFoldGetElementPtr(llvm::Constant*, bool,
llvm::ArrayRef<llvm::Value*>) + 55
11 opt 0x0000000000b33df2
llvm::ConstantExpr::getGetElementPtr(llvm::Constant*,
llvm::ArrayRef<llvm::Value*>, bool) + 82

Probably the ConstantArray could't be casted to Value*. Any ideas?
Thanks!

Hmm.

So, I made a change to my copy of release_32 to show the types involved when you get that assertion. I wish the LLVM philosophy was more in line with that notion, reporting all the little details when there's an issue (not to mention using lots of temporaries so you can step through it in the debugger more easily).

Replace the init() method on line 265 in release_32/lib/VMCore/Instructions.cpp with this:

  http://pastebin.com/QKjtGzvu

You can see how your passed parameter differs from what the function expects. You might be able to use a bitcast instruction instead.