Referring to an argument in another function

I would like to instrument certain function calls with a function call
of my own that takes some of the same arguments. For example, I would
like to instrument calls to free with some function foo, so the C code
would look like:

foo(myarg1, myarg2, ptr);
free(ptr);

The problem occurs when I grab the arg from the free function and try
to pass it to foo...

  if (isCallToFree(&I)) {
    Value* P;
    if (Function *F = I.getCalledFunction()) {
      Function::arg_iterator ait = F->arg_begin();
      if (ait) {
        P = &(*ait);
      }
      createCallInst(mem_fcall, &I, 3, getOpcodeValue(I),
                     getInstrIDValue(), P);
    }
  }

createCallInst is my own wrapper. The error thrown during the pass is:

"Referring to an argument in another function!"

Any suggestions?

Thanks,
Scott

Scott Ricketts wrote:

I would like to instrument certain function calls with a function call
of my own that takes some of the same arguments. For example, I would
like to instrument calls to free with some function foo, so the C code
would look like:

foo(myarg1, myarg2, ptr);
free(ptr);

The problem occurs when I grab the arg from the free function and try
to pass it to foo...

  if (isCallToFree(&I)) {
    Value* P;
    if (Function *F = I.getCalledFunction()) {
      Function::arg_iterator ait = F->arg_begin();

You want to look at the operands of the call/invoke/free instruction, not the arguments of the function being called.
So if you're sure it's a call or invoke (not a 'free' instruction), try something like this:

#include "llvm/Support/CallSite.h"
// ...
         CallSite CS(&I);
         CallSite::arg_iterator ait = CS.arg_begin(), aend = CS.arg_end();

      if (ait) {

You want
         if (ait != aend) {
here.

Thanks!

CallSite is what I needed. I ended up getting P with CS.getArgument(0)
instead of an arg_iterator, but only because I first check that it is
an externally linked call to free with 1 argument.

Scott