How can I traverse every character of GlobalVariable name in LLVM? - llvm

I have written a demo of getting every character of GlobalVariable name and doing XOR operation. Here is my part of my demo code(Function entry block has been created privously, gvar is the GlobalVariable and len is the GlobalVariable length):
BasicBlock *preHeaderBB=builder.GetInsertBlock();
ConstantInt* string_length = ConstantInt::get(mod->getContext(), APInt(32, len));
BasicBlock* for_body = BasicBlock::Create(mod->getContext(), "for-body", fdecode);
builder.CreateBr(for_body);
builder.SetInsertPoint(for_body);
PHINode *variable = builder.CreatePHI(Type::getInt32Ty(mod->getContext()), 2, "i");
Value *startValue = builder.getInt32(0);
Value *endValue = builder.getInt32(len);
variable->addIncoming(startValue, preHeaderBB);
LoadInst *Load=builder.CreateLoad(gvar);
Load->setAlignment(8);
Value* indexList[2] = {ConstantInt::get(startValue->getType(), 0), startValue};
ConstantInt* const_key = ConstantInt::get(mod->getContext(), APInt(8, key));
Value *GEP=builder.CreateGEP(gvar,ArrayRef<Value*>(indexList, 2),"arrayIdx");
LoadInst *loadElement=builder.CreateLoad(GEP);
loadElement->setAlignment(1);
Value *Xor = builder.CreateXor(loadElement,const_key,"xor");
StoreInst *Store = builder.CreateStore(Xor, loadElement);
Value *stepValue = builder.getInt32(1);
Value *nextValue = builder.CreateAdd(startValue, stepValue, "next-value");
Value *endCondition = builder.CreateICmpULT(startValue, endValue, "end-condition");
endCondition = builder.CreateICmpNE(endCondition, builder.getInt32(0), "loop-condion");
BasicBlock *loopEndBB = builder.GetInsertBlock();
builder.CreateCondBr(endCondition, loopEndBB, entry);
variable->addIncoming(nextValue, loopEndBB);
builder.SetInsertPoint(entry);
I used the LoadInst to get every character of GloablVariable name, but it came with error. I wander where can I improve this code. Thank you.

In LLVM's SSA form IR, the GV's name is merely an "alias" for the variable, and possibly appears in the SymbolTable, depending on the LinkageType. There is nothing as "Loading the variable's name", since the name is the variable itself. The GEP Instruction you are creating is actually an index into whatever value being represented by the GV, not the name. So that's something fundamentally wrong here. You will need to writing some code to parse the binary format and runtime and retrieve the name from the SymbolTable, providing the GV's LinkageType is not PrivateLinkage or InternalLinkage and the binary is not stripped

Related

Reforging (Rochet2) to AzerothCore

Does anyone has already successfully added Rochet2's Reforging script on AC ?
Mine works but not completely.
On character login the script should re-apply bonuses on reforged (& equipped) items, but it seems "player->GetItemByGuid()" can't find the requested item, so it's returning nothing.
TrinityCore code (works) :
uint32 lowGUID = (*result)[0].GetUInt32();
Item* invItem = player->GetItemByGuid(ObjectGuid(HighGuid::Item, 0, lowGUID));
if (invItem)
player->_ApplyItemMods(invItem, invItem->GetSlot(), false);
ReforgeData& data = player->reforgeMap[lowGUID];
data.increase = (*result)[1].GetUInt32();
data.decrease = (*result)[2].GetUInt32();
data.stat_value = (*result)[3].GetInt32();
if (invItem)
player->_ApplyItemMods(invItem, invItem->GetSlot(), true);
AzerothCore code (works, but "if (invItem)" condition never satisfied.
uint32 lowGUID = (*result)[0].GetUInt32();
Item* invItem = player->GetItemByGuid((uint64) MAKE_NEW_GUID(HIGHGUID_ITEM, 0, lowGUID));
if (invItem /*&& invItem->IsEquipped()*/)
player->_ApplyItemMods(invItem, invItem->GetSlot(), false);
ReforgeData& data = player->reforgeMap[lowGUID];
data.increase = (*result)[1].GetUInt32();
data.decrease = (*result)[2].GetUInt32();
data.stat_value = (*result)[3].GetInt32();
if (invItem /*&& invItem->IsEquipped()*/)
player->_ApplyItemMods(invItem, invItem->GetSlot(), true);
MAKE_NEW_GUID() returns something that looks like a guid.
But I don't know why "player->GetItemByGuid()" can't find the item.
The order of arguments to MAKE_NEW_GUID is different from ObjectGuid constructor. So since your arguments are in wrong order then the result is also wrong and item is not found. See the definition and use of MAKE_NEW_GUID for the correct order of arguments.

How to get the results of a stored procedure when using cfscript new StoredProc()

First time trying to use a stored procedure via cfscript and I can't figure out how to get the results. With a regular query I do something like this to get my result set:
queryResult = queryResult.execute().getResult();
With the stored procedure my code is:
queryResult = new storedProc( procedure = 'stpQueryMyResultSet', datasource = 'mydsn' );
queryResult = queryResult.execute();
writeDump(queryResult);
That returns 3 structs - prefix, procResultSets and procOutVariables, but I can't seem to figure out how to get my query results.
Thanks to #Ageax for pointing me to that page. Here's how I got it working (I also added in a param for max rows to return):
queryResult = new storedProc( procedure = 'stpQueryMyResultSet', datasource = 'mydsn' );
queryResult.addParam( type = 'in', cfsqltype = 'cf_sql_integer', value = '10');
queryResult.addProcResult( name = 'result' );
qResult = queryResult.execute().getProcResultSets().result;
writeDump(qResult);

How to generate metadata for LLVM IR?

I am trying to generate a metadata for the LLVM IR i have generated. I want to generate a metadata of the form :
!nvvm.annotations = !{!0}
!0 = metadata !{void ()* #foo, metadata !"kernel", i32 1}
Where foo is a function in my LLVM IR. Right now I am only able to generate a metadata of the form:
!nvvm.annotations = !{!0}
!0 = !{!"kernel"}
I used the following code for the above metadata generation.
char metaDataArgument[512];
sprintf(metaDataArgument, "%s", pipelineKernelName);
llvm::NamedMDNode *nvvmMetadataNode = LLVMModule->getOrInsertNamedMetadata("nvvm.annotations");
llvm::MDNode *MDNOdeNVVM = llvm::MDNode::get(*context, llvm::MDString::get(*context, "kernel"));
nvvmMetadataNode->addOperand(MDNOdeNVVM);
Could someone tell me how to modify the above code to generate metadata of the required form
Your metadata will be a tuple with 3 elements.
The first one is a global value, which is wrapped when insert in the metadata hierarchy as "ValueAsMetadata" (we can use the Constant subclass since GlobalValues are constant).
The second is a MDString, you got this one.
The last one is wrapped as a ConstantAsMetadata.
This should look approximately like the follow:
SmallVector<Metadata *, 32> Ops; // Tuple operands
GlobalValue *Foo = Mod.getNamedValue("foo");
if (!Foo) report_fatal_error("Expected foo..");
Ops.push_back(llvm::ValueAsMetadata::getConstant(Foo));
Ops.push_back(llvm::MDString::get(*context, "kernel"));
// get constant i32 1
Type *I32Ty = Type::getInt32Ty(*context);
Contant *One = ConstantInt::get(I32Ty, 1);
Ops.push_back(llvm::ValueAsMetadata::getConstant(One));
auto *Node = MDTuple::get(Context, Ops);

Using rocksdb::Iterator and Column Family is not working

I have the following piece of code:
rocksdb::DBWithTTL* db = ...
rocksdb::WriteOptions writeOptions;
rocksdb::ColumnFamilyHandle cfHandle = ...
std::string keyPrefix = "prefix";
std::string key = keyPrefix + "_key";
std::string value = "value";
rocksdb::Status s = db->Put(writeOptions, cfHandle, key, value);
rocksdb::ReadOptions readOptions;
readOptions.prefix_same_as_start;
readOptions.snapshot = db->GetSnapshot();
rocksdb::Iterator* iterator = db->NewIterator(readOptions);
rocksdb::Sliced start = rocksdb::Slice(keyPrefix);
for (iterator->Seek(start); iterator->Valid(); iterator->Next()) {
printf("hello");
}
The printf is never hit.
However, if I change the Put line to:
rocksdb::Status s = db->Put(writeOptions, key, value);
Meaning, removing the column family handle, I'm getting the line printed fine.
I'm guessing the iterator API should take the column family into account, but I couldn't find any documentation.
Indeed the missing API call was:
rocksdb::Iterator* iterator = db->NewIterator(readOptions, cfHandle);

Qjson handling an returned array of ojbects

I'm using Qjson to parse a json object that is returned from a web service. I'm stuck on handling an array of complex ojects.
At the first level the web service returns a map consisting of "error", "id", and "return". If there are no errors I can get the first level value by using
nestedMap = m_jsonObject["result"].toMap();
group = new Group();
group->Caption = nestedMap["Caption"].toString();
group->CollectionCount = nestedMap["CollectionCount"].toInt();
I can even get a date item value that is at the second level using
group->ModifiedOn = nestedMap["ModifiedOn"].toMap()["Value"].toDateTime();
I have an object called "Elements" that consists of 29 key-value pairs. The web service is returning an array of these "Elements" and I am unable to find the right way to parse it. In the header file the container for the elements is defined as
QList<GroupElement> Elements;
The line
group->Elements = nestedMap["Elements"].toList();
causes the compiler to throw an error 'error: no match for 'operator=' in '((MyClass*)this)->MyClass::group->Group::Elements = QVariant::toMap() const()'
I would like to learn the correct syntax to put this element into the class.
Update: I wrote another function to convert the QVariantMap object to a
first:
The group-> Elements object was changed to a
class ParentClass{
QList<SharedDataPointer<Address> > Elements;
other class memmbers...
};
Second:
A method to convert the QMap object to an Address object was created
QSharedDataPointer<Address>
API_1_6::mapToAddress(QVariantMap o)
{
QSharedDataPointer<Address> address (new Address());
address-> FirstName = o["FirstName"].toString();
address->LastName = o["LastName"].toString();
address->CompanyName = o["CompanyName"].toString();
address->Street = o["Street"].toString();
address->Street2 = o["Street2"].toString();
address->City = o["City"].toString();
address->Zip = o["Zip"].toString();
address-> State = o["State"].toString();
address->Country = o["Country"].toString();
address->Phone = o["Phone"].toString();
address->Phone2 = o["Phone2"].toString();
address-> Fax = o["Fax"].toString();
address-> Url = o["Url"].toString();
address->Email = o["Email"].toString();
address->Other = o["Other"].toString();
return address;
}
third: In the code, foreach is used to walk through the list and create and store the new objects
// get the list of the elements
elementsList = nestedMap["Elements"].toList();
// Add the element, converted to the new type, to the Elements object of the'parent' class
foreach(QVariant qElement, elementsList){
group-> Elements.append(mapToAddress(qElement))
}