Get name of a function argument - llvm

I am creating an LLVM pass and I don't understand something : when I look into the .ll file the argument of a function has a name :
call void #_ZNK2xi9spawnable9SpawnableIFvbdEEclEbd( %"class.xi::spawnable::Spawnable.0"* nonnull #_ZN2xi9spawnable2f2E, i1 zeroext %9, double %10)
So here the first argument name seems to be _ZN2xi9spawnable2f2E.
But in my pass when I use the function getName() it returns me an empty string. When I access the full argument I obtain : %"class.xi::spawnable::Spawnable.0"* %1
How can I obtain the same name as in the .ll file?
EDIT: This is a part of the code (I tried to clean it up a little so maybe there are some missing brackets)
virtual bool runOnFunction(Function &F){
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
std::string Name = demangle(F.getName ());
outs() << "Function "<< *(F.getFunctionType()) <<" " << Name << " {\n";
for(LoopInfo::iterator i = LI.begin(), e = LI.end(); i!=e; ++i)
BlocksInLoop (*i,0);
for( Function::iterator b = F.begin() , be = F.end() ;b != be; ++b){
for(BasicBlock::iterator i = b->begin() , ie = b->end();i != ie; ++i){
if(isa<CallInst>(&(*i)) || isa<InvokeInst>(&(*i))){
if (!(i->getMetadata("seen"))){
Function * fct =NULL;
if (isa<CallInst>(&(*i)))
fct = cast<CallInst>(&(*i))->getCalledFunction();
if (isa<InvokeInst>(&(*i)))
fct = cast<InvokeInst>(&(*i))->getCalledFunction();
if (fct){
outs()<<"Call " << *(fct->getFunctionType()) <<" "<< demangle(fct->getName()) << "\n";
for(Function::arg_iterator argi=fct->arg_begin(),arge=fct->arg_end(); argi!=arge;argi++ )
outs()<< argi->getName()<<"\n";
}
}
}
}
}
outs() << "}\n";
return(false);
};

You are analyzing not the call site, but the function itself. When you are looking at the function, you only have formal parameters and can't know what values are passed there.
Instead of calling ->getCalledFunction() and iterating over its args, you should iterate over cast<CallInst>(&(*i)) operands. See ->op_begin() and value_op_begin() methods.

Related

Iterating of a simple hello world program with llvm

I am new to llvm framework and I am starting very basic. What's more basic than a hello world?
I want to iterate over my main function in main.c. It looks like the section
"Iterating over the BasicBlock in a Function" would be a good place to start"
Function &Func = ...
for (BasicBlock &BB : Func)
// Print out the name of the basic block if it has one, and then the
// number of instructions that it contains
errs() << "Basic block (name=" << BB.getName() << ") has "
<< BB.size() << " instructions.\n";
What do I set Function &Func =
to?
I want to look at the main function in my main.c file.
While we're on this topic. What would I set BasicBlock& BB = ... to?
My code.
bool Prereqs::runOnModule(Module &M) {
/* Add your code here */
errs() << "Hi: ";
errs().write_escaped(M.getName()) << '\n';
NumOfFunctions +=10;
outs()<<"get opcode yields: getOpcode()" <<"\n";
Function &Func = main.c;
for (BasicBlock &BB : Func)
// Print out the name of the basic block if it has one, and then the
// // number of instructions that it contains
// errs() << "Basic block (name=" << BB.getName() << ") has "
// << BB.size() << " instructions.\n";
print(M);
return false;
}
documentation
https://releases.llvm.org/8.0.0/docs/ProgrammersManual.html#basic-inspection-and-traversal-routines
You'll probably want to set Func to the return value of Module::getFunction() and if you don't know what a Module is or how to make one, there is a tutorial.

How to get the arguments of a function call in LLVM?

I want to write an LLVM pass that'll extract the arguments of function calls. If the argument is a constant one, my objective is to recover what that constant is.
The IR looks like
%2 = call noalias i8* #malloc(i64 512) #3
The LLVM pass looks like
bool runOnFunction(Function &F) override {
for (auto& B : F) {
for (auto& I : B) {
if(CallInst* call_inst = dyn_cast<CallInst>(&I)) {
Function* fn = call_inst->getCalledFunction();
StringRef fn_name = fn->getName();
errs() << fn_name << " : " << call_inst->getArgOperand(0) << "\n";
for(auto arg = fn->arg_begin(); arg != fn->arg_end(); ++arg) {
errs() << *arg << "\n";
}
}
}
}
return false;
}
If I run the pass through opt, it produces the following
malloc : 0x3df3f40
i64 %0
What does 0x3df3f40 represent? Instead of i64 and 512, why does it produce i64 and %0?
It is a pointer to Value. Try cast<>ing it to ConstantInt and then calling getValue():
for(auto arg = fn->arg_begin(); arg != fn->arg_end(); ++arg) {
if(auto* ci = dyn_cast<ConstantInt>(arg))
errs() << ci->getValue() << "\n";
errs() << *arg << "\n";
}

C++ Pointer not updating the value

//Inside the header.h
class telefonbok{
std::map<std::string,std::string> telebok;
std::map<std::string,std::string> aliasbok;
}
//Inside the cpp file
void telefonbok::alias(string name, string alias){
if (telebok.find(name) == telebok.end()) {
cout << "Not found" << endl;
} else {
//pointer = Adress stored in pointer.
//*pointer = Value of *pointer
string *pointer;
pointer = &telebok.find(name)->second;
aliasbok.insert(make_pair(alias, *pointer));
cout << *pointer << endl;
}
When i change the value in the first map(telebok) the second value in the map(aliasbok) stays the same (the one who is supposed to have the pointer as the value).
Example:
add peter 123
lookup peter:
peter : 123
alias peter pete
lookup pete:
pete : 123
change peter 987
lookup peter:
peter : 987
lookup pete:
pete : 123
(Pete never changes wich is the issue, it's supposed to always have the same value as peter)
First of all your code is inefficient (you call find twice, which is pretty expensive operation), so you should work with iterators, not pointers and it also will help to resolve your issue:
class telefonbok{
typedef std::map<std::string,std::string> Telebok;
typedef std::map<std::string,Telebok::const_iterator> Aliasbok;
Telebok telebok;
Aliasbok aliasbok;
};
void telefonbok::alias(string name, string alias)
{
Telebok::const_iterator f = telebok.find( name );
if( f == telebok.end() )
cout << "Not found" << endl;
else
aliasbok.insert( make_pair( alias, f );
}
now you have following:
you do not call std::map::find() twice
through alias you can not only find number but original name as well
to print values from alias code little bit more complicated:
for( Aliasbok::const_iterator it = aliasbok.begin(); it != aliasbok.end(); ++it )
cout << "alias " << it->first << " has number " << it->second->second << " original name " << it->second->first << endl;
or to find a value:
Aliasbok::const_iterator it = aliasbok.find( "abcd" );
if( it != aliasbok.end() )
cout << "phone for " << it->first << " is " << it->second->second << endl;
else
cout << "phone for abcd not found" << endl;
but you should get used to it when using iterators
Note: if you delete records from phonebook you need to clean aliasbook first, otherwise it will hold invalid iterators. Proper solution would be to use boost::multi_index but that probably too complicated for your level.
When i change the value in the first map(telebok) the second value in the map(aliasbok) stays the same (the one who is supposed to have the pointer as the value).
If the aliasbok is supposed to have pointer as the value, then your bug is that you've defined the map incorrectly. Here is your definition:
std::map<std::string,std::string> aliasbok;
Pay attention to how the value type of the map is std::string which is a value type and not std::string* which would be a pointer type.
Also pay attention to this line:
aliasbok.insert(make_pair(alias, *pointer));
Where you dereference the pointer and copy the pointed string into the pair, instead of copying a pointer.
You have to store shared pointers and set them apropriatelly to the same string.
class telefonbok{
std::map<std::string,std::shared_ptr<std::string>> telebok;
std::map<std::string,std::shared_ptr<std::string>> aliasbok;
}
and provide the methods to update the pointers as needed e.g.
void addphone(std::string const & name,
std::string const & alias,
std::string const & phone);
{
std::shared_ptr<std::string> phone_ptr(new std::string(phone));
telefonbok.telebok.emplace(name,phone_ptr);
telefonbok.aliasbok.emplace(alias,phone_ptr);
}
and this way when you modify the phone on either it will get updated on both. Your phone will also not die when you exit the scope of the function.
Then you can do this for updates
void update_phone(std::string const & name,
std::string const & newphone)
{
if( auto iter = telefonbok.telebok.find(name) )
{
*(iter->second.get()) = newphone;
} else if ( auto iter = telefonbok.aliasbok.find(name) )
{
*(iter->second.get()) = newphone;
}
}

Variable change without any direct action

I have wrote an API as defined below. This API is used to find the index of a filename in a file system. The filesystem is coming from an Android device through mtp. What I'm doing is to request a list of files stored on the Android device and compare each file listed to the one I'm looking for 'name2look'
I have created a vector table to store what I'm doing but it's not mandatory. My concerns is that the variable name2look contain the right name I'm looking for "Pictures"
uint32_t USBDevice::GetIndexFromName(LIBMTP_mtpdevice_t *dev, uint32_t storage,const char *name2look)
{
uint32_t idx_fold = 1;
std::vector<MyFileTreeItem*> FSimage;
LIBMTP_file_t *files;
LIBMTP_file_t *file;
std::cout << "NAME : " << name2look << "\n";
files = this->GetFileAndFolder(dev, storage,0);
file = files;
while (file != NULL) {
MyFileTreeItem* FSitem = new MyFileTreeItem();
FSitem->filename = file->filename;
FSitem->index = file->item_id;
FSitem->FileType = file->filetype;
FSimage.push_back(FSitem);
std::cout << "NAME : " << name2look << "\n";
std::cout << "FS NAME : " << file->filename << "\n";
if(std::strcmp(file->filename, name2look)==0) {
std::cout << "FIND IDX : " << file->item_id << "\n";
return file->item_id;
}
file = file->next;
}
return 0;
}
The Log is showing that the first display 'std::cout' is ok. the variable name is still 'Pictures' but when I ask to display it after in the "while" the variable name2look change and is not the same anymore.
First display
NAME : Pictures
second one in the while
NAME : Martin).mp3
FS NAME : Music
How is it possible to be corrupted ??
The function is called by a Qt C++ code:
void MyButtonGroup::buttonClick(QAbstractButton *button)
{
uint32_t status;
QList<QTreeWidgetItem *> itemList;
uint32_t index = 0;
if (button->text() == "Create Folder") {
itemList = this->MyTree->selectedItems();
QString str = itemList[0]->text(0);
char *utf8_text = str.toLatin1().data();
if(utf8_text != NULL)
{
std::cout << "A CHERCHER " << utf8_text << "\n";
index = this->MyDevice.GetIndexFromName(this->dev_id, storage->id, utf8_text);
}
else
index = 0;
CreateFolderDialog *dialog = new CreateFolderDialog(this->MyTree, this->MyDevice, this->dev_id, this->storage, index);
dialog->show();
}
utf8_text report the right value.
Any idea ?
This might be the problem. I am not sure. Check it out.
This line:
char *utf8_text = str.toLatin1().data();
What does the documentation say toLatin1() does? It creates a new QByteArray object and then you call data() on that and you get a pointer to character and then the QByteArray is destroyed at the end of the line because it was TEMPORARY.
And now you have an invalid pointer to freed memory that you then pass into your function. It probably gets overwritten by the first call to new() in your function.
I think you should change it to something like this:
QByteArray latin_str = str.toLatin1();
char *utf8_text = latin_str.data();
Your name utf8_text is weird since you just converted it to Latin1 which isn't UTF8.

c++ private member variable unknown in another function

I have a newbie question about how to assign class member (setter). I am used to scripting and mostly there it's done via (in python)
def set_mymember(mymember):
self.mymeber = mymember
My coworker told me "self" and "this" are not needed in C++ , "this" exists and it's not wrong in this context but that would be hard to understand for me so he said I should not care. So I first tried according to his advice:
My class definition: - (it should create a sql query string)
class Query
{
public:
Query() { }
~Query() { }
void setoptions( std::string qtext_where="", bool qtext_erl=true, std::vector<std::string> kids=std::vector<std::string>() );
Query build_query( );
void set_db_table( std::string db_table );
void set_db_key( std::string db_key );
void set_m_qtext( std::string m_qtext );
void set_foo( std::string foo );
std::string sql();
std::string get_sql_update();
private:
std::string m_db_table; // Tabellenname
std::string m_db_key; // Tabellen-key
std::string m_qtext_where; // add.optionale where clause
std::string m_qtext; // fertiger SELECT
std::string m_sql_update; // fertiger UPDATE
bool m_erl; // nur erledigte waehlen?
std::vector<std::string> m_kids; // Liste von keys zu selecten
};
ANd here's one of the setter methods: I call them with filled string and vector, double check it in this code
void Query::setoptions( string qtext_where, bool erl, vector<string> kids ) {
m_qtext_where = qtext_where;
m_erl = erl;
m_kids = kids;
}
But when my app later calls query.build_query()
the variables are empty
Query Query::build_query( ) {
cout << "kids size" << m_kids.size() << endl;
cout << "m_qtext_where " << m_qtext_where << endl;
// Query zur auswahl der zu uebertragenden Datensaetze
string sql_update = "UPDATE " + m_db_table;
string qtext = "SELECT * FROM " + m_db_table;
string qtext_order = " ORDER BY " + m_db_key;
(...)
EDIT: So here's part of the app code which calls 1.setoptions, and 2.build_query
// read file line by line into vector of strings
vector<string> text_file;
ifstream ifs( input );
string temp;
while( getline( ifs, temp ) ) {
if (temp.substr(0,1) == "#" ) {
cout << "COMMENT: " << temp << endl;
continue;
}
cout << temp << endl;
text_file.push_back( temp );
}
// check: yes, vector has a size = number of lines
cout << "text_file size " << text_file.size() << endl;
// create Query object
Query query = Query();
// set the members, bool erl = true
query.setoptions( "", erl, text_file );
// call 2nd method
q2 = query.build_query();
Can't really tell whats going on without the full code, but I suspect that you're returning a query object from query.build_query that isn't a full copy of the query object, if that makes sense? Can you include the full text of build_query?
Also, I'd make the build_query method void, and not try to assign a fresh Query object back to a second Query object (q2) at all (unless you really need to, again, can't really tell without the full code), something like this:
void Query::build_query( ) {
std::cout << "kids size" << m_kids.size() << std::endl;
std::cout << "m_qtext_where " << m_qtext_where << std::endl;
}
main
{
...
Query query = Query();
// set the members, bool erl = true
query.setoptions( "", true, text_file );
// call 2nd method
query.build_query();
}
Also, just being pedantic here, but given that you're providing default args for all the options, I'd be inclined to initialise them in the constructor like this:
Query::Query()
: m_qtext_where("")
, qtext_erl(true)
, kids (std::vector<std::string>()
{}
And then instead of a setOptions method, have setters for each individual variable:
void setWhere(std::string qtext_where) {m_qtext_where = qtext_where ;}
void setErl(bool query_erl) { m_erl = query_erl; }
void setKids(std::vector<std::string> kids) { m_kids = kids; }
which you call only when you need to..