How to get line number of a function in a bitcode file?

Hi All,

I hope to get some information about functions in a bitcode file. Say, if we have a function foo(), and the bitcode file is generated by a single source file, then I want to get the line number foo() locates in that source file.
If the bitcode file is linked by multiple bitcode files, is it possible to also get which file foo() locates in?

Thanks,
Chen

Hi All,

I hope to get some information about functions in a bitcode file. Say, if we have a function foo(), and the bitcode file is generated by a single source file, then I want to get the line number foo() locates in that source file.
If the bitcode file is linked by multiple bitcode files, is it possible to also get which file foo() locates in?

I think you can get this information by looking at the debugging metadata that is associated with the function or with one of its arguments. That said, this will only work if debugging metadata is available (e.g., if the code was compiled with the -g flag).

– John T.

Hi Chen,

There is code to do this in the DebugInstrumentation.cpp file in my SAFECode patch to LLVM mainline. You can find the patch at . – John T.

I tried to install the SAFECode in LLVM 2.6 following the instruction in
Install.html. But when I do the step:
# cd projects/poolalloc
# make

I get the errore below:
llvm[2]: Compiling qsort.c for Release build (bytecode)
llvm[2]: Compiling strdup.c for Release build (bytecode)
llvm[2]: Compiling qsort.c for Release build
llvm[2]: Compiling strdup.c for Release build
llvm[2]: Compiling qsort.ll to qsort.bc for Release build (bytecode)
llvm[2]: Compiling strdup.ll to strdup.bc for Release build (bytecode)
/home/chenliu/llvm-2.6/llvm/Release/bin/llvm-as: assembly parsed, but does
not verify as correct!
Intrinsic prototype has incorrect number of arguments!
void (i8*, i8*, i64, i32, i1)* @llvm.memcpy.p0i8.p0i8.i64
Broken module found, compilation terminated.
Broken module found, compilation terminated.
/home/chenliu/llvm-2.6/llvm/Release/bin/opt: Invalid bitcode signature
make[2]: ***
[/home/chenliu/llvm-2.6/llvm/projects/poolalloc/runtime/PreRT/Release/strdup.bc]
Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: Leaving directory
`/home/chenliu/llvm-2.6/llvm/projects/poolalloc/runtime/PreRT'
make[1]: *** [all] Error 1
make[1]: Leaving directory
`/home/chenliu/llvm-2.6/llvm/projects/poolalloc/runtime'
make: *** [all] Error 1

I tried to install the SAFECode in LLVM 2.6 following the instruction in
Install.html. But when I do the step:

First, if you're wanting the code in DebugInstrumentation.cpp, you need to get the version in my patch (http://llvm.cs.uiuc.edu/~criswell/sc.tar.gz). The debug metadata API changed between LLVM 2.6 and LLVM 2.7, so if you're working with mainline LLVM, you should get the newer version of the code that is available in the patch.

Second, to answer your specific question, I believe you have a mismatched version of llvm-gcc or Clang. Please see my answer on svadev this morning to the same issue: http://lists.cs.uiuc.edu/pipermail/svadev/2011-July/000086.html; this will hopefully fix your problem if, in fact, you do want to compile SAFECode.

-- John T.

I'm using the following code to get source information about functions without using an instruction of the function, and it seems to work well.

     // Get metadata about functions (subprograms)
     if (NamedMDNode *namedMD = km->module->getNamedMetadata("llvm.dbg.sp")) {
       for (unsigned i = 0, e = namedMD->getNumOperands(); i != e; ++i) {
         MDNode *mdnode = namedMD->getOperand(i);
         DIDescriptor diDesc(mdnode);
         if (!diDesc.isSubprogram())
           continue;

         DISubprogram subProg(mdnode);
         unsigned line = subProg.getLineNumber();
         StringRef dir = subProg.getDirectory();
         StringRef file = subProg.getFilename();
         std::cout << "Function name: " << subProg.getName().str()
                   << " at line "
                   << line << " in " << dir.str() << file.str() << "\n";
       }
     }

The way that elements of a metadata node is called "operands" confused me very much. After I figured it out that it actually means a referred (sub-)node or (sub-)element of a node, it's really straightforward to use metadata information.

Lu

Sorry, I directly copied the code from my file without editing it.

"km->module" in the code is a pointer to a Module, which contains all named metadata.

I'm using the following code to get source information about functions without using an instruction of the function, and it seems to work well.

     // Get metadata about functions (subprograms)
     if (NamedMDNode *namedMD = km->module->getNamedMetadata("llvm.dbg.sp")) {
       for (unsigned i = 0, e = namedMD->getNumOperands(); i != e; ++i) {
         MDNode *mdnode = namedMD->getOperand(i);
         DIDescriptor diDesc(mdnode);
         if (!diDesc.isSubprogram())
           continue;

         DISubprogram subProg(mdnode);
         unsigned line = subProg.getLineNumber();
         StringRef dir = subProg.getDirectory();
         StringRef file = subProg.getFilename();
         std::cout << "Function name: " << subProg.getName().str()
                   << " at line "
                   << line << " in " << dir.str() << file.str() << "\n";
       }
     }

The way that elements of a metadata node is called "operands" confused me very much. After I figured it out that it actually means a referred (sub-)node or (sub-)element of a node, it's really straightforward to use metadata information.

Lu