Modern equivalent of LLVM AnnotationManager? - llvm

Now that LLVM's AnnotationManager is gone (it disappeared in the 2.6 release, I think?), how can I get the annotations for specific functions, globals, and instructions?
(For example, I have bitcode compiled from C void myFunction(__attribute__((annotate("foo"))) int var) --- given an Argument * reference to this int var argument, how might I determine which annotate attributes are attached to it?)

To get annotations for a specific function, traverse the entry BasicBlock of the function to find its calls to the #llvm.var.annotation intrinsic, as follows:
Module *module;
[...]
std::string getGlobalVariableString(std::string name)
{
// assumption: the zeroth operand of a Value::GlobalVariableVal is the actual Value
Value *v = module->getNamedValue(name)->getOperand(0);
if(v->getValueID() == Value::ConstantArrayVal)
{
ConstantArray *ca = (ConstantArray *)v;
return ca->getAsString();
}
return "";
}
void dumpFunctionArgAnnotations(std::string funcName)
{
std::map<Value *,Argument*> mapValueToArgument;
Function *func = module->getFunction(funcName);
if(!func)
{
std::cout << "no function by that name.\n";
return;
}
std::cout << funcName << "() ====================\n";
// assumption: #llvm.var.annotation calls are always in the function's entry block.
BasicBlock *b = &func->getEntryBlock();
// run through entry block first to build map of pointers to arguments
for(BasicBlock::iterator it = b->begin();it!=b->end();++it)
{
Instruction *inst = it;
if(inst->getOpcode()!=Instruction::Store)
continue;
// `store` operands: http://llvm.org/docs/LangRef.html#i_store
mapValueToArgument[inst->getOperand(1)] = (Argument *)inst->getOperand(0);
}
// run through entry block a second time, to associate annotations with arguments
for(BasicBlock::iterator it = b->begin();it!=b->end();++it)
{
Instruction *inst = it;
if(inst->getOpcode()!=Instruction::Call)
continue;
// assumption: Instruction::Call's operands are the function arguments, followed by the function name
Value *calledFunction = inst->getOperand(inst->getNumOperands()-1);
if(calledFunction->getName().str() != "llvm.var.annotation")
continue;
// `llvm.var.annotation` operands: http://llvm.org/docs/LangRef.html#int_var_annotation
Value *annotatedValue = inst->getOperand(0);
if(annotatedValue->getValueID() != Value::InstructionVal + Instruction::BitCast)
continue;
Argument *a = mapValueToArgument[annotatedValue->getUnderlyingObject()];
if(!a)
continue;
Value *annotation = inst->getOperand(1);
if(annotation->getValueID() != Value::ConstantExprVal)
continue;
ConstantExpr *ce = (ConstantExpr *)annotation;
if(ce->getOpcode() != Instruction::GetElementPtr)
continue;
// `ConstantExpr` operands: http://llvm.org/docs/LangRef.html#constantexprs
Value *gv = ce->getOperand(0);
if(gv->getValueID() != Value::GlobalVariableVal)
continue;
std::cout << " argument " << a->getType()->getDescription() << " " << a->getName().str()
<< " has annotation \"" << getGlobalVariableString(gv->getName().str()) << "\"\n";
}
}

AnnotationManager was deleted because it was useless (and it won't solve your problem). All the annotations are handled via the global named 'llvm.global.annotations' and annotation intrinsics, which you can surely parse and obtain the information you needed.
Look into IR to have an idea, how your C code was transformed into IR and what annotation attribute was turned into.

Related

I want to combine the list and find(), but I don't know how to merge them

Please see the part where the find() function is called. (I ran it in Visual Studio.)
Code:
using namespace std;
int main(void) {
//Implementing the find()
/*
bool Find(const Stu & a); {
return (*it).name;
}
*/
list<Astu>::iterator that;
//that = astu.begin();
//that = find(astu.begin(), astu.end(), (*it).name);
for (it = stu.begin(); it != stu.end(); it++) {
that = find_if(astu.begin(), astu.end(), (*it).name);
if (that != astu.end()) {
all = astu.erase(all);
all++;
}
else
all++;
}
/*
//Filter absenteeism from the total student roster
for (it = stu.begin(); it != stu.end(); it++) {
for (all = astu.begin(); all != astu.end();) {
if (!strcmp((*all).name, (*it).name)) {
//Delete attendees and latecomers from the list
all = astu.erase(all);
}
else
all++;
}
}
*/
cout << "---------------------\n결석자: " << endl;
//이름순으로 정렬
astu.sort(SizeComp2);
//결석자들 출력
for (all = astu.begin(); all != astu.end(); all++) {
cout << "이름: " << (*all).name << endl;
}
return 0;
}
Output:
C2064 error occurred: Term does not evaluate to a function that takes
1 argument.
Even with find_if() in this code, there is a problem. The bool() part in the comment was used for the find_if object, but it doesn't seem to be used well here.
I deleted the part where there was no problem as a result of debugging. You must use an unconditional list, not a vector.
Where should I fix it?
The third argument to std::find_if is a function.
You could use a lambda as the function:
auto that = find_if(astu.begin(), astu.end(), [it](Astu const& astu)
{
return astu.name == it->name;
});
[This assumes that Astu::name is a std::string]

Easiest way to evaluate constant SVal

I'm trying to find the easiest way to get the value in a constant SVal. Currently I am doing something along the lines of:
SVal s = ...; // Get valid SVal from somewhere
int64_t val = 0; // Will hold value of SVal
if (!s.isUnknownOrUndef() && s.isConstant()) {
switch (s.getBaseKind()) {
case NonLocKind: {
s_val = s.getAs<nonloc::ConcreteInt>().getValue();
val = s_val.getValue().getExtValue();
}
// handle other cases
// ...
}
}
llvm::outs() << "Value is " << val << "\n";
I didn't show it here but there more code checking that values are known, checking the sign and type of constants, etc. I feel like there is probably a better way.

How to verify if LLVM "ret" instruction returns void?

I have the following snippet of code:
static LLVMContext TempContext;
Type * RetTy = Type::getVoidTy(TempContext)
for (Instruction *I : ListOfInstructions) {
if (isa<ReturnInst>(I)) {
RetTy = I->getOperand(0)->getType();
break
}
}
Where I am trying to capture the RetTy of a instruction, void or not, so I can use it on
getOrInsertFunction("TempF", FunctionType::get(RetTy, ArgsTys,false));
This code works as long as the ret instruction is not a ret void.
I tried to add a second if to check the void case, but this does not seem to work, and execution stops on the in the FunctionType::get(...) function, printing a back trace.
for (Instruction *I : ListOfInstructions) {
if (isa<ReturnInst>(I)) {
if ( I->getOperand(0)->getType() != Type::getVoidTy(TempContext)) {
RetTy = I->getOperand(0)->getType();
break
}
}
}
Note that removing the for loop all together works and execution continues, as the function FunctionType::get(...) handles the initialized Type * RetTy = Type::getVoidTy(TempContext) "void" value for RetTy just fine. But then I can't capture when a llvm function returns non-void values.
How do I know when an instruction I is a return instruction and it is returning Void in LLVM IR?
The problem with your current code is that ret void does not have an operand, so calling getOperand(0) accesses invalid data.
Replacing your if with:
if (ReturnInst *ri = dyn_cast<ReturnInst>(I))
{
if (ri->getNumOperands() == 0)
{
errs() << "VOID: " << *ri << "\n";
}
else
{
errs() << "NON-VOID: " << *ri << "\n";
}
}
Now, this code will output VOID: ret void, having correctly detected the instruction.
As an alternative, you could retrieve the return type for the function using any instruction by relying on instructions being contained by a function I->getFunction()->getReturnType(); however, this would assume that the function is well-formed and its ReturnInst matches its type and the instruction is part of a function.

How to get the arguments of a function pointer from a CallExpr in Clang?

I am trying to analyse C++ source code with function calls within them. I am able to analyse normal function calls to get their arguments without problem using the source code below where ce is a CallExpr object:
1. if(ce != NULL) {
2. QualType q = ce->getType();
3. const Type *t = q.getTypePtrOrNull();
4.
5. if (t != NULL) {
6. llvm::errs() << "TYPE: " << t->isFunctionPointerType() << " " << q.getAsString() << " " << t->isPointerType() << "\n";
7. } else {
8. llvm::errs() << "FUNCTION CE HAS NO TYPE?\n";
9. }
10.
11.
12. const Decl* D = ce ->getCalleeDecl();
13. while(D->getPreviousDecl() != NULL)
14. D = D->getPreviousDecl();
15.
16. llvm::errs() << "Kind: " << D->getDeclKindName() << "\n";
17.
18. FunctionDecl* fd = (FunctionDecl*) llvm::dyn_cast<FunctionDecl>(D);
19. for(int x = 0; x< fd ->getNumParams(); x++) {
20. if(fd ->getParamDecl(x)->getType()->isAnyPointerType()) {
21. // Do Stuff Here
22. }
23. }
24. }
The problem with the above source code comes on line 18, when I try to typecast the Decl from the CallExpr to a FunctionDecl, this results in fd becoming NULL if the CallExpr is from a function pointer call.
I tried to debug by trying to print the kind on line 16. For function pointers, it specifies the Decl on 12 is a VarDecl, not a FunctionDecl like normal function calls.
I also tried using the isFunctionPointerType(), but this is returning false.
Here is a piece of source code that results in a segfault:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
void* (*mp)(size_t size);
void *mpp;
mp = &malloc;
mpp = mp(30);
free(mpp);
return (0);
}
Is there a way using clang to detect whether a CallExpr is a function pointer call? and if so, how to get a list of the arguments?
I am using clang 3.1
Thanks
Use getDirectCallee() function (I am not sure if it is available in clang 3.1 or not)
FunctionDecl *func = ce->getDirectCallee();
if (func != NULL){
for(int i = 0; i < func->getNumParams(); i++){
if(func->getParamDecl(i)->getType()->isFunctionPointerType()){
// Do stuff here
}
}
}
You should get function prototype from pointer declaration, after that you will be able to get information about return type and parameters types:
clang::CallExpr* expr;
...
auto decl = expr->getCalleeDecl();
if (decl != nullptr) {
if (decl->getKind() == clang::Decl::Var) {
clang::VarDecl *varDecl = clang::dyn_cast<clang::VarDecl>(decl);
if(varDecl->getType()->isFunctionPointerType() == true) {
const clang::PointerType *pt = varDecl->getType()->getAs<clang::PointerType>();
const clang::FunctionProtoType *ft = pt->getPointeeType()->getAs<clang::FunctionProtoType>();
if (ft != nullptr) {
std::string retTypeName = ft->getReturnType().getAsString();
...
auto paramsCount = funcType->getNumParams();
for (size_t i = 0; i < paramsCount; ++i) {
clang::QualType paramType = funcType->getParamType(i);
std::string paramTypeName = paramType.getAsString();
...
}
}
}
}
}
May be you can also use getArg(position) to get particular argument and before that you should use getNumArgs to get details about number of argument that function contains.

How to find out shared variables among functions by using LLVM API?

Recently I used LLVM API to test C++ program. Now I want to find out the shared variables among different functions, is there any way to do that? It seems that the AliasAnalysis doesn't work!
I write a Function Pass as following:
bool EscapeAnalysis::runOnFunction(Function& F) {
EscapePoints.clear();
TargetData& TD = getAnalysis<TargetData>();
AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
Module* M = F.getParent();
// errs() << *M << "\n";
// Walk through all instructions in the function, identifying those that
// may allow their inputs to escape.
for(inst_iterator II = inst_begin(F), IE = inst_end(F); II != IE; ++II) {
Instruction* I = &*II;
// The most obvious case is stores. Any store that may write to global
// memory or to a function argument potentially allows its input to escape.
if (StoreInst* S = dyn_cast<StoreInst>(I)) {
Type* StoreType = S->getOperand(0)->getType();
unsigned StoreSize = TD.getTypeStoreSize(StoreType);
Value* Pointer = S->getPointerOperand();
bool inserted = false;
for (Function::arg_iterator AI = F.arg_begin(), AE = F.arg_end();
AI != AE; ++AI) {
if (!isa<PointerType>(AI->getType())) continue;
AliasAnalysis::AliasResult R = AA.alias(Pointer, StoreSize, AI, ~0UL);
if (R != AliasAnalysis::NoAlias) {
EscapePoints.insert(S);
inserted = true;
break;
}
}
if (inserted)
continue;
for (Module::global_iterator GI = M->global_begin(), GE = M->global_end();
GI != GE; ++GI) {
errs() << *GI << "\n";
AliasAnalysis::AliasResult R = AA.alias(Pointer, StoreSize, GI, ~0UL);
errs() << "R: " << R << " , NoAlias: " << AliasAnalysis::NoAlias << "\n";
if (R != AliasAnalysis::NoAlias) {
EscapePoints.insert(S);
break;
}
}
// Calls and invokes potentially allow their parameters to escape.
// FIXME: This can and should be refined. Intrinsics have known escape
// behavior, and alias analysis may be able to tell us more about callees.
} else if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
EscapePoints.insert(I);
// Returns allow the return value to escape. This is mostly important
// for malloc to alloca promotion.
} else if (isa<ReturnInst>(I)) {
EscapePoints.insert(I);
// Branching on the value of a pointer may allow the value to escape through
// methods not discoverable via def-use chaining.
} else if(isa<BranchInst>(I) || isa<SwitchInst>(I)) {
EscapePoints.insert(I);
}
// FIXME: Are there any other possible escape points?
}
return false;
}
Test the main.cpp as following:
#include
using namespace std;
int X = 0;
int foo() {
X = 1;
int b = 1;
return 0;
}
int bar(int param) {
int y = X;
int z = 9;
int a = z;
++a;
return 0;
}
int main(int argc, char *argv[])
{
cout << "Hello world!" << endl;
return 0;
}
the global variable X is the shared variable between function bar and function foo.
But when I use the command as following to run the pass:
opt -load ./EscapeAnalysis.so -escape-analysis main.o | llc > main.ss
I get the result:
R: 1 , NoAlias: 0
all result are the same.
I print out the variables in escapePoint, find that variable a, z, y in function bar are in escapePoint. It is not right!
Note: I write a opt pass to test program.
Alias analysis is required if you want to identify when two different variables might point to the same memory. If you just want to check which variables are shared with other functions in the same module, you can:
Iterate over all instructions, and for each:
Iterate over all its operands, and for each:
Check whether it's a GlobalVariable (via isa, for instance), and if so:
Iterate over all the global's uses (via use_begin and use_end), and for each:
Check whether it's an Instruction, and if so:
Retrieve the enclosing function (via getParent()->getParent()), and for that function:
Check whether it is the currently-processed function. If not, it means you found a variable shared between the current function and another function.
There are also other ways of checking this, for example going over all the globals in the current module.