Search code examples
clangllvminstrumentation

How to discover lock declaration instruction in llvm?


I'm new to llvm , and was trying to find lock declaration statement and then do some instrumention work,the code like this:

#include <iostream>
#include <thread>
#include <mutex>
using namespace std;

int share = 42;
mutex m;

void f()
{
    m.lock();
    --share;
    cout << "function f -> share: " << share << '\n';
    m.unlock();
}



int main()
{
    thread thf{f};

    thf.join();

    return 0;
}

I want to find the lock declaration instruction eg: mutex m; the llvm instrumention pass like this:

struct SkeletonPass : public FunctionPass {
static char ID;
SkeletonPass() : FunctionPass(ID) {}

virtual bool runOnFunction(Function &F) {
  // Get the function to call from our runtime library.
  LLVMContext &Ctx = F.getContext();
  Constant *logFunc = F.getParent()->getOrInsertFunction(
    "logop", Type::getVoidTy(Ctx), Type::getInt32Ty(Ctx), NULL
  );

  for (auto &B : F) {
    for (auto &I : B) {
      ***if ((&I) is lock declaration instruction)*** { 

        // Insert something *after* `op`.
        IRBuilder<> builder(op);
        builder.SetInsertPoint(&B, ++builder.GetInsertPoint());

        // Insert a call to function.

        builder.CreateCall(logFunc, ConstantInt::get(Type::getInt32Ty(Ctx), 2));

        return true;
      }
    }
  }

In short, could you please tell me how to discover lock declaration instruction, thanks!


Solution

  • The declaration would appear as a global, so you should write a module pass to find it, not a function pass. It should appear as something like:

    @m = global %mutex zeroinitializer
    

    In fact, using the demo at http://ellcc.org/demo/index.cgi to try this, you can indeed see that:

    ...    
    %"class.std::__1::mutex" = type { %struct.pthread_mutex_t }
    %struct.pthread_mutex_t = type { %union.anon }
    %union.anon = type { [5 x i8*] }
    ...
    @m = global %"class.std::__1::mutex" zeroinitializer, align 8