本文整理汇总了C++中ConstantArray类的典型用法代码示例。如果您正苦于以下问题:C++ ConstantArray类的具体用法?C++ ConstantArray怎么用?C++ ConstantArray使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了ConstantArray类的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: assert
// what a hack
static Function *getStubFunctionForCtorList(Module *m,
GlobalVariable *gv,
std::string name) {
assert(!gv->isDeclaration() && !gv->hasInternalLinkage() &&
"do not support old LLVM style constructor/destructor lists");
std::vector<const Type*> nullary;
Function *fn = Function::Create(FunctionType::get(Type::getVoidTy(getGlobalContext()),
nullary, false),
GlobalVariable::InternalLinkage,
name,
m);
BasicBlock *bb = BasicBlock::Create(getGlobalContext(), "entry", fn);
// From lli:
// Should be an array of '{ int, void ()* }' structs. The first value is
// the init priority, which we ignore.
ConstantArray *arr = dyn_cast<ConstantArray>(gv->getInitializer());
if (arr) {
for (unsigned i=0; i<arr->getNumOperands(); i++) {
ConstantStruct *cs = cast<ConstantStruct>(arr->getOperand(i));
assert(cs->getNumOperands()==2 && "unexpected element in ctor initializer list");
Constant *fp = cs->getOperand(1);
if (!fp->isNullValue()) {
if (llvm::ConstantExpr *ce = dyn_cast<llvm::ConstantExpr>(fp))
fp = ce->getOperand(0);
if (Function *f = dyn_cast<Function>(fp)) {
CallInst::Create(f, "", bb);
} else {
assert(0 && "unable to get function pointer from ctor initializer list");
}
}
}
}
ReturnInst::Create(getGlobalContext(), bb);
return fn;
}
示例2: assert
bool CheckInserter::doFinalization(Module &M) {
// We couldn't directly add an element to a constant array, because doing so
// changes the type of the constant array.
// element type of llvm.global_ctors
StructType *ST = StructType::get(IntType,
PointerType::getUnqual(InitFiniType),
NULL); // end with null
// Move all existing elements of <GlobalName> to <Constants>.
vector<Constant *> Constants;
if (GlobalVariable *GlobalCtors = M.getNamedGlobal("llvm.global_ctors")) {
ConstantArray *CA = cast<ConstantArray>(GlobalCtors->getInitializer());
for (unsigned j = 0; j < CA->getNumOperands(); ++j) {
ConstantStruct *CS = cast<ConstantStruct>(CA->getOperand(j));
assert(CS->getType() == ST);
// Assume nobody is using the highest priority, so that <F> will be the
// first to run as a ctor.
assert(!cast<ConstantInt>(CS->getOperand(0))->isMinValue(true));
Constants.push_back(CS);
}
GlobalCtors->eraseFromParent();
}
// Add <F> with the highest priority.
Constants.push_back(ConstantStruct::get(ST,
ConstantInt::get(IntType, INT_MIN),
EnterProcess,
NULL));
// Create the new llvm.global_ctors.
ArrayType *ArrType = ArrayType::get(ST, Constants.size());
new GlobalVariable(M,
ArrType,
true,
GlobalValue::AppendingLinkage,
ConstantArray::get(ArrType, Constants),
"llvm.global_ctors");
return true;
}
示例3: GetConstant
//----------------------------------------------------------------------------
bool FxCompiler::GetConstant (const TokenArray& tokens,
const std::string& name, Shader::VariableType type,
ConstantArray& constants)
{
std::string::size_type begin, end;
if (tokens[5].size() < 4
|| tokens[5][0] != 'c'
|| tokens[5][1] != '['
|| (end = tokens[5].find("]", 0)) == std::string::npos)
{
ReportError("Expecting 'c[register]' token", &tokens);
return false;
}
// Get the base register for the constant.
begin = 2; // character after '['
std::string number = tokens[5].substr(begin, end - begin);
int baseRegister = atoi(number.c_str());
if (baseRegister == 0 && number != "0")
{
ReportError("Invalid base register", &tokens);
return false;
}
// Get the number of registers used by the constant.
int numRegistersUsed;
if (tokens[5].find(",", 0) == std::string::npos)
{
// The constant uses one register.
numRegistersUsed = 1;
}
else
{
// The constant uses more than one register.
numRegistersUsed = atoi(tokens[6].c_str());
if (numRegistersUsed == 0)
{
ReportError("Invalid number of registers", &tokens);
return false;
}
}
Constant constant;
constant.Name = name;
constant.Type = type;
constant.BaseRegister = baseRegister;
constant.NumRegistersUsed = numRegistersUsed;
constants.push_back(constant);
return true;
}
示例4: GetConstantStringInfo
/// GetConstantStringInfo - This function computes the length of a
/// null-terminated C string pointed to by V. If successful, it returns true
/// and returns the string in Str. If unsuccessful, it returns false.
bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset,
bool StopAtNul) {
// If V is NULL then return false;
if (V == NULL) return false;
// Look through bitcast instructions.
if (BitCastInst *BCI = dyn_cast<BitCastInst>(V))
return GetConstantStringInfo(BCI->getOperand(0), Str, Offset, StopAtNul);
// If the value is not a GEP instruction nor a constant expression with a
// GEP instruction, then return false because ConstantArray can't occur
// any other way
User *GEP = 0;
if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) {
GEP = GEPI;
} else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
if (CE->getOpcode() == Instruction::BitCast)
return GetConstantStringInfo(CE->getOperand(0), Str, Offset, StopAtNul);
if (CE->getOpcode() != Instruction::GetElementPtr)
return false;
GEP = CE;
}
if (GEP) {
// Make sure the GEP has exactly three arguments.
if (GEP->getNumOperands() != 3)
return false;
// Make sure the index-ee is a pointer to array of i8.
const PointerType *PT = cast<PointerType>(GEP->getOperand(0)->getType());
const ArrayType *AT = dyn_cast<ArrayType>(PT->getElementType());
if (AT == 0 || AT->getElementType() != Type::Int8Ty)
return false;
// Check to make sure that the first operand of the GEP is an integer and
// has value 0 so that we are sure we're indexing into the initializer.
ConstantInt *FirstIdx = dyn_cast<ConstantInt>(GEP->getOperand(1));
if (FirstIdx == 0 || !FirstIdx->isZero())
return false;
// If the second index isn't a ConstantInt, then this is a variable index
// into the array. If this occurs, we can't say anything meaningful about
// the string.
uint64_t StartIdx = 0;
if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2)))
StartIdx = CI->getZExtValue();
else
return false;
return GetConstantStringInfo(GEP->getOperand(0), Str, StartIdx+Offset,
StopAtNul);
}
// The GEP instruction, constant or instruction, must reference a global
// variable that is a constant and is initialized. The referenced constant
// initializer is the array that we'll use for optimization.
GlobalVariable* GV = dyn_cast<GlobalVariable>(V);
if (!GV || !GV->isConstant() || !GV->hasInitializer())
return false;
Constant *GlobalInit = GV->getInitializer();
// Handle the ConstantAggregateZero case
if (isa<ConstantAggregateZero>(GlobalInit)) {
// This is a degenerate case. The initializer is constant zero so the
// length of the string must be zero.
Str.clear();
return true;
}
// Must be a Constant Array
ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
if (Array == 0 || Array->getType()->getElementType() != Type::Int8Ty)
return false;
// Get the number of elements in the array
uint64_t NumElts = Array->getType()->getNumElements();
if (Offset > NumElts)
return false;
// Traverse the constant array from 'Offset' which is the place the GEP refers
// to in the array.
Str.reserve(NumElts-Offset);
for (unsigned i = Offset; i != NumElts; ++i) {
Constant *Elt = Array->getOperand(i);
ConstantInt *CI = dyn_cast<ConstantInt>(Elt);
if (!CI) // This array isn't suitable, non-int initializer.
return false;
if (StopAtNul && CI->isZero())
return true; // we found end of string, success!
Str += (char)CI->getZExtValue();
}
// The array isn't null terminated, but maybe this is a memcpy, not a strcpy.
return true;
}
示例5: SDEBUG
void ClassHierarchyUtils::processTypeInfo(GlobalVariable* TI, Module& M) {
if (find(classes.begin(), classes.end(), TI) == classes.end()) {
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Adding class " << TI->getName() << "\n");
classes.push_back(TI);
// First process the correspoding virtual table. We store the indexes of the primary
// and secondary vtables, indexed by the corresponding subobject offset. This will allow
// us to quickly jump to a particular sub-vtable.
if (typeInfoToVTable.find(TI) != typeInfoToVTable.end()) {
GlobalVariable* VT = typeInfoToVTable[TI];
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Found vtable: " << VT->getName() << "\n");
ConstantStruct* VTinit = cast<ConstantStruct>(VT->getInitializer());
for (int i=0; i<VTinit->getNumOperands(); i++) {
ConstantArray* VTinitElem = cast<ConstantArray>(VTinit->getOperand(i));
for (int j=0; j<VTinitElem->getNumOperands(); j++) {
// Each sub-vtable is preceded by a reference to the class's type_info instance.
// (See https://mentorembedded.github.io/cxx-abi/abi.html).
if (TI == VTinitElem->getOperand(j)->stripPointerCasts()) {
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Found TI at index " << i << "\n");
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Storing mapping " << VT->getName() << " <-> " << TI->getName() << "\n");
// the offset to top is the offset from the vptr pointing to this
// sub-vtable, back to the top of the object. This will be negative,
// but the absolute value gives us the offset from the start of the
// object (i.e. first vptr), to the subobject.
int offsetToTop = 0;
if (ConstantExpr* offsetValCast = dyn_cast<ConstantExpr>(VTinitElem->getOperand(j-1)->stripPointerCasts())) {
ConstantInt* offsetVal = cast<ConstantInt>(offsetValCast->getOperand(0));
offsetToTop = offsetVal->getSExtValue(); // will be 0 for the primary
}
if (offsetToTop > 0) {
report_fatal_error("ERROR: offsetToTop is positive!");
}
else {
offsetToTop *= -1;
}
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "offsetToTop: " << offsetToTop << "\n")
vTableToSecondaryVTableMaps[VT][offsetToTop] = pair<int, int>(i, j+1);
}
}
}
}
else {
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "No vtable found for " << TI->getName() << "\n");
}
// Now process the type_info struct, extract direct base class info (what
// their subobject offsets are, or if they are virtual then their
// virtual-base-offset-offset)
if (TI->hasInitializer()) {
ConstantStruct* TIinit = cast<ConstantStruct>(TI->getInitializer());
int TInumOperands = TIinit->getNumOperands();
if (TInumOperands > 2) { // first two operands are vptr and type name
// we have >= 1 base class(es).
if (TInumOperands == 3) {
// abi::__si_class_type_info: single, public, non-virtual base at
// offset 0
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "abi::__si_class_type_info\n");
GlobalVariable* baseTI = cast<GlobalVariable>(TIinit->getOperand(2)->stripPointerCasts());
classToSubclasses[baseTI].push_back(TI);
//dbgs() << " " << *baseTI << "\n";
classToBaseOffset[TI][baseTI] = 0;
processTypeInfo(baseTI, M);
}
else {
// abi::__vmi_class_type_info: all other cases
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "abi::__vmi_class_type_info\n");
// (skip over first two additional fields, which are "flags" and "base_count")
for (int i=4; i<TInumOperands; i+=2) {
GlobalVariable* baseTI = cast<GlobalVariable>(TIinit->getOperand(i)->stripPointerCasts());
classToSubclasses[baseTI].push_back(TI);
long offset_flags = cast<ConstantInt>(TIinit->getOperand(i+1))->getSExtValue();
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << TI->getName() << " -> " << baseTI->getName() << "\n");
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << " offset_flags = " << offset_flags << "\n");
ptrdiff_t offset = offset_flags >> offset_shift;
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << " offset = " << offset << "\n");
// If this a virtual base class, then we obtain the
// vbase-offset-offset. This is the offset from the start of the
// derived class's (primary) vtable to the location containing the
// vbase-offset, which is the offset from the start of the object
// to the virtual base's subobject. Note that virtual base
// subobjects only exist once and are laid out after all other
// non-virtual objects. We keep track of the vbase-offset-offset,
// so that we can find the vbase offset when going down the class
// hierarchy. (The vbase offset may differ every time but the
// vbase-offset-offset will remain the same relative to the current
// class's vtable in subclasses).
if (offset_flags & virtual_mask) { // is this a virtual base class?
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "virtual base class: " << baseTI->getName() << "\n");
int vbaseOffsetOffset = offset/sizeof(long); // this should be negative
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "vbase-offset-offset: " << vbaseOffsetOffset << "\n");
classToVBaseOffsetOffset[TI][baseTI] = vbaseOffsetOffset;
if (typeInfoToVTable.find(TI) != typeInfoToVTable.end()) {
GlobalVariable* VT = typeInfoToVTable[TI];
int vbaseOffsetIdx = vTableToSecondaryVTableMaps[VT][0].second+vbaseOffsetOffset;
SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "vbase-offset-idx: " << vbaseOffsetIdx << "\n");
}
else {
//.........这里部分代码省略.........
示例6: if
bool SDFix::fixDestructors() {
bool replaced = false;
for (GlobalVariable& gv : module->getGlobalList()) {
if (! sd_isVtableName_ref(gv.getName()))
continue;
else if (! gv.hasInitializer())
continue;
Constant* init = gv.getInitializer();
assert(init);
ConstantArray* vtable = dyn_cast<ConstantArray>(init);
assert(vtable);
// get an idea about the virtual function regions
std::vector<vtbl_pair_t> vtblRegions = findSubVtables(vtable);
// for each subvtable
for(unsigned vtblInd = 0; vtblInd < vtblRegions.size(); vtblInd++) {
// record the destructors used in the vtable
std::vector<DestructorInfo> destructors(3);
vtbl_pair_t p = vtblRegions[vtblInd];
for(unsigned i=p.first; i<p.second; i++) {
Constant* destructor = sd_getDestructorFunction(vtable->getOperand(i));
if (destructor == NULL)
continue;
// get the type from its name
unsigned s = destructor->getName().size();
char type = destructor->getName()[s-3];
assert('0' <= type && type <= '2');
unsigned typeInt = type - '0';
// store it temporarily
destructors[typeInt] = DestructorInfo(destructor, i);
}
// deleting destructor should always be defined
assert(! destructors[0].needsReplacement());
DestructorInfo* d1 = &destructors[1];
DestructorInfo* d2 = &destructors[2];
// only one of the rest could be undefined
assert(! d1->needsReplacement() || ! d2->needsReplacement());
// if complete object destructor is missing...
if (d1->needsReplacement()) {
std::string gv2Name = d1->function->getName();
unsigned l = gv2Name.length();
gv2Name = gv2Name.replace(l-3, 1, "2");
Function* f1 = d1->getFunction();
assert(f1);
Function* f2 = module->getFunction(gv2Name);
assert(f2);
sd_print("Replacing %s with %s inside %s\n",
d1->function->getName().data(),
gv2Name.c_str(),
gv.getName().data());
f1->replaceAllUsesWith(f2);
replaced = true;
// if base object destructor is missing...
} else if (d2->needsReplacement()) {
std::string gv1Name = d2->function->getName();
unsigned l = gv1Name.length();
gv1Name = gv1Name.replace(l-3, 1, "1");
Function* f2 = d2->getFunction();
assert(f2);
Function* f1 = module->getFunction(gv1Name);
assert(f1);
sd_print("Replacing %s with %s inside %s\n",
d2->function->getName().data(),
gv1Name.c_str(),
gv.getName().data());
f2->replaceAllUsesWith(f1);
replaced = true;
}
}
}
return replaced;
}
示例7: calculateGraphs
//
// Method: postOrderInline()
//
// Description:
// This methods does a post order traversal of the call graph and performs
// bottom-up inlining of the DSGraphs.
//
void
BUDataStructures::postOrderInline (Module & M) {
// Variables used for Tarjan SCC-finding algorithm. These are passed into
// the recursive function used to find SCCs.
std::vector<const Function*> Stack;
std::map<const Function*, unsigned> ValMap;
unsigned NextID = 1;
// Do post order traversal on the global ctors. Use this information to update
// the globals graph.
const char *Name = "llvm.global_ctors";
GlobalVariable *GV = M.getNamedGlobal(Name);
if (GV && !(GV->isDeclaration()) && !(GV->hasLocalLinkage())) {
// Should be an array of '{ int, void ()* }' structs. The first value is
// the init priority, which we ignore.
ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
if (InitList) {
for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))) {
if (CS->getNumOperands() != 2)
break; // Not array of 2-element structs.
Constant *FP = CS->getOperand(1);
if (FP->isNullValue())
break; // Found a null terminator, exit.
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
if (CE->isCast())
FP = CE->getOperand(0);
Function *F = dyn_cast<Function>(FP);
if (F && !F->isDeclaration() && !ValMap.count(F)) {
calculateGraphs(F, Stack, NextID, ValMap);
CloneAuxIntoGlobal(getDSGraph(*F));
}
}
GlobalsGraph->removeTriviallyDeadNodes();
GlobalsGraph->maskIncompleteMarkers();
// Mark external globals incomplete.
GlobalsGraph->markIncompleteNodes(DSGraph::IgnoreGlobals);
GlobalsGraph->computeExternalFlags(DSGraph::DontMarkFormalsExternal);
GlobalsGraph->computeIntPtrFlags();
//
// Create equivalence classes for aliasing globals so that we only need to
// record one global per DSNode.
//
formGlobalECs();
// propogte information calculated
// from the globals graph to the other graphs.
for (Module::iterator F = M.begin(); F != M.end(); ++F) {
if (!(F->isDeclaration())){
DSGraph *Graph = getDSGraph(*F);
cloneGlobalsInto(Graph, DSGraph::DontCloneCallNodes |
DSGraph::DontCloneAuxCallNodes);
Graph->buildCallGraph(callgraph, GlobalFunctionList, filterCallees);
Graph->maskIncompleteMarkers();
Graph->markIncompleteNodes(DSGraph::MarkFormalArgs |
DSGraph::IgnoreGlobals);
Graph->computeExternalFlags(DSGraph::DontMarkFormalsExternal);
Graph->computeIntPtrFlags();
}
}
}
}
//
// Start the post order traversal with the main() function. If there is no
// main() function, don't worry; we'll have a separate traversal for inlining
// graphs for functions not reachable from main().
//
Function *MainFunc = M.getFunction ("main");
if (MainFunc && !MainFunc->isDeclaration()) {
calculateGraphs(MainFunc, Stack, NextID, ValMap);
CloneAuxIntoGlobal(getDSGraph(*MainFunc));
}
//
// Calculate the graphs for any functions that are unreachable from main...
//
for (Function &F : M)
if (!F.isDeclaration() && !ValMap.count(&F)) {
if (MainFunc)
DEBUG(errs() << debugname << ": Function unreachable from main: "
<< F.getName() << "\n");
calculateGraphs(&F, Stack, NextID, ValMap); // Calculate all graphs.
CloneAuxIntoGlobal(getDSGraph(F));
// Mark this graph as processed. Do this by finding all functions
// in the graph that map to it, and mark them visited.
// Note that this really should be handled neatly by calculateGraphs
// itself, not here. However this catches the worst offenders.
DSGraph *G = getDSGraph(F);
//.........这里部分代码省略.........
示例8: UpdateShader
//----------------------------------------------------------------------------
bool FxCompiler::UpdateShader (Shader* shader, const Program& program,
InputArray& inputs, OutputArray& outputs, ConstantArray& constants,
SamplerArray& samplers)
{
int numInputs = (int)inputs.size();
if (numInputs != shader->GetNumInputs())
{
ReportError("Mismatch in number of inputs.\n");
return false;
}
int numOutputs = (int)outputs.size();
if (numOutputs != shader->GetNumOutputs())
{
ReportError("Mismatch in number of outputs.\n");
return false;
}
int numConstants = (int)constants.size();
if (numConstants != shader->GetNumConstants())
{
ReportError("Mismatch in number of constants.\n");
return false;
}
int numSamplers = (int)samplers.size();
if (numSamplers != shader->GetNumSamplers())
{
ReportError("Mismatch in number of samplers.\n");
return false;
}
std::string message;
int i;
for (i = 0; i < numInputs; ++i)
{
Input& input = inputs[i];
if (input.Name != shader->GetInputName(i))
{
message = "Mismatch in input names '" +
input.Name +
"' and '" +
shader->GetInputName(i);
ReportError(message);
return false;
}
if (input.Type != shader->GetInputType(i))
{
message = "Mismatch in input types '" +
msVTName[input.Type] +
"' and '" +
msVTName[shader->GetInputType(i)];
ReportError(message);
return false;
}
if (input.Semantic != shader->GetInputSemantic(i))
{
message = "Mismatch in input semantics '" +
msVSName[input.Semantic] +
"' and '" +
msVSName[shader->GetInputSemantic(i)];
ReportError(message);
return false;
}
}
for (i = 0; i < numOutputs; ++i)
{
Output& output = outputs[i];
if (output.Name != shader->GetOutputName(i))
{
message = "Mismatch in output names '" +
output.Name +
"' and '" +
shader->GetOutputName(i);
ReportError(message);
return false;
}
if (output.Type != shader->GetOutputType(i))
{
message = "Mismatch in output types '" +
msVTName[output.Type] +
"' and '" +
msVTName[shader->GetOutputType(i)];
ReportError(message);
return false;
}
if (output.Semantic != shader->GetOutputSemantic(i))
{
message = "Mismatch in output semantics '" +
msVSName[output.Semantic] +
"' and '" +
msVSName[shader->GetOutputSemantic(i)];
//.........这里部分代码省略.........
示例9: Process
//----------------------------------------------------------------------------
bool FxCompiler::Process (const Program& program, InputArray& inputs,
OutputArray& outputs, ConstantArray& constants, SamplerArray& samplers)
{
// Variable lines are one of the following:
// var TYPE NAME : $vin.SEMANTIC : inputType : index : 1
// var TYPE NAME : $vout.SEMANTIC : outputType : index : 1
// var TYPE NAME : : c[REGISTER] : index : 1
// var TYPE NAME : : c[REGISTER], NUMREG : index : 1
// var TYPE NAME : : texunit UNITNUMBER : -1 : 1
// The last field is "used", a value of "0" or "1". However, the parser
// stored in 'program' only those variables with a used value "1". The
// all-capitals identifiers are needed by the Wild Magic FX system.
TokenArrays::const_iterator iter = program.Variables.begin();
TokenArrays::const_iterator end = program.Variables.end();
for (/**/; iter != end; ++iter)
{
const TokenArray& tokens = *iter;
// The token array has 10 or 11 tokens.
if (tokens.size() < 10 || tokens.size() > 11)
{
ReportError("Invalid number of tokens", &tokens);
return false;
}
// Get the variable type.
Shader::VariableType vartype = Shader::VT_NONE;
Shader::SamplerType samtype = Shader::ST_NONE;
std::string::size_type begin = tokens[1].find("sampler", 0);
if (begin != std::string::npos)
{
SamplerTypeMap::iterator iter = mSamplerTypes.find(tokens[1]);
if (iter == mSamplerTypes.end())
{
ReportError("Invalid sampler type", &tokens);
return false;
}
samtype = iter->second;
}
else
{
VariableTypeMap::iterator iter = mVariableTypes.find(tokens[1]);
if (iter == mVariableTypes.end())
{
ReportError("Invalid variable type", &tokens);
return false;
}
vartype = iter->second;
}
// Get the variable name.
std::string name = tokens[2];
// Test whether the variable is a singleton or was declared as an
// array. If it is an array, we need to determine how many registers
// it uses. This requires processing variable lines with the same
// variable index.
bool varArray;
begin = name.find("[", 0);
if (begin != std::string::npos)
{
varArray = true;
name = name.substr(0, begin); // strip off "[register]"
}
else
{
varArray = false;
}
// Get the separator before the classifier.
if (tokens[3] != ":")
{
ReportError("Expecting separator character at index 3", &tokens);
return false;
}
// Get the classifier.
begin = tokens[4].find("$vin.", 0);
if (begin != std::string::npos)
{
// The variable is a shader input.
if (!GetInput(tokens, name, vartype, inputs))
{
return false;
}
continue;
}
begin = tokens[4].find("$vout.", 0);
if (begin != std::string::npos)
{
// The variable is a shader output.
if (!GetOutput(tokens, name, vartype, outputs))
{
return false;
}
continue;
}
//.........这里部分代码省略.........
示例10: Regex
SandboxVector SandboxUtils::findSandboxes(Module& M) {
FunctionIntMap funcToOverhead;
FunctionIntMap funcToClearances;
map<Function*,string> funcToSandboxName;
map<string,FunctionSet> sandboxNameToEntryPoints;
StringSet ephemeralSandboxes;
SandboxVector sandboxes;
// function-level annotations of sandboxed code
Regex *sboxPerfRegex = new Regex("perf_overhead_\\(([0-9]{1,2})\\)", true);
SmallVector<StringRef, 4> matches;
if (GlobalVariable* lga = M.getNamedGlobal("llvm.global.annotations")) {
ConstantArray* lgaArray = dyn_cast<ConstantArray>(lga->getInitializer()->stripPointerCasts());
for (User::op_iterator i=lgaArray->op_begin(), e = lgaArray->op_end(); e!=i; i++) {
ConstantStruct* lgaArrayElement = dyn_cast<ConstantStruct>(i->get());
// get the annotation value first
GlobalVariable* annotationStrVar = dyn_cast<GlobalVariable>(lgaArrayElement->getOperand(1)->stripPointerCasts());
ConstantDataArray* annotationStrArray = dyn_cast<ConstantDataArray>(annotationStrVar->getInitializer());
StringRef annotationStrArrayCString = annotationStrArray->getAsCString();
GlobalValue* annotatedVal = dyn_cast<GlobalValue>(lgaArrayElement->getOperand(0)->stripPointerCasts());
if (isa<Function>(annotatedVal)) {
Function* annotatedFunc = dyn_cast<Function>(annotatedVal);
StringRef sandboxName;
if (annotationStrArrayCString.startswith(SANDBOX_PERSISTENT) || annotationStrArrayCString.startswith(SANDBOX_EPHEMERAL)) {
sandboxEntryPoints.insert(annotatedFunc);
outs() << INDENT_1 << "Found sandbox entrypoint " << annotatedFunc->getName() << "\n";
outs() << INDENT_2 << "Annotation string: " << annotationStrArrayCString << "\n";
if (annotationStrArrayCString.startswith(SANDBOX_PERSISTENT)) {
sandboxName = annotationStrArrayCString.substr(strlen(SANDBOX_PERSISTENT)+1);
}
else if (annotationStrArrayCString.startswith(SANDBOX_EPHEMERAL)) {
sandboxName = annotationStrArrayCString.substr(strlen(SANDBOX_EPHEMERAL)+1);
ephemeralSandboxes.insert(sandboxName);
}
outs() << INDENT_2 << "Sandbox name: " << sandboxName << "\n";
if (funcToSandboxName.find(annotatedFunc) != funcToSandboxName.end()) {
outs() << INDENT_1 << "*** Error: Function " << annotatedFunc->getName() << " is already an entrypoint for another sandbox\n";
}
else {
funcToSandboxName[annotatedFunc] = sandboxName;
sandboxNameToEntryPoints[sandboxName].insert(annotatedFunc);
}
}
else if (sboxPerfRegex->match(annotationStrArrayCString, &matches)) {
int overhead;
outs() << INDENT_2 << "Threshold set to " << matches[1].str() <<
"%\n";
matches[1].getAsInteger(0, overhead);
funcToOverhead[annotatedFunc] = overhead;
}
else if (annotationStrArrayCString.startswith(CLEARANCE)) {
StringRef className = annotationStrArrayCString.substr(strlen(CLEARANCE)+1);
outs() << INDENT_2 << "Sandbox has clearance for \"" << className << "\"\n";
ClassifiedUtils::assignBitIdxToClassName(className);
funcToClearances[annotatedFunc] |= (1 << ClassifiedUtils::getBitIdxFromClassName(className));
}
}
}
}
// TODO: sanity check overhead and clearance annotations
// Combine all annotation information for function-level sandboxes to create Sandbox instances
for (pair<string,FunctionSet> p : sandboxNameToEntryPoints) {
string sandboxName = p.first;
FunctionSet entryPoints = p.second;
int idx = assignBitIdxToSandboxName(sandboxName);
int overhead = 0;
int clearances = 0;
bool persistent = find(ephemeralSandboxes.begin(), ephemeralSandboxes.end(), sandboxName) == ephemeralSandboxes.end();
// set overhead and clearances; any of the entry points could be annotated
for (Function* entryPoint : entryPoints) {
if (funcToOverhead.find(entryPoint) != funcToOverhead.end()) {
overhead = funcToOverhead[entryPoint];
}
if (funcToClearances.find(entryPoint) != funcToClearances.end()) {
clearances = funcToClearances[entryPoint];
}
}
SDEBUG("soaap.util.sandbox", 3, dbgs() << INDENT_2 << "Creating new Sandbox instance for " << sandboxName << "\n");
sandboxes.push_back(new Sandbox(sandboxName, idx, entryPoints, persistent, M, overhead, clearances));
SDEBUG("soaap.util.sandbox", 3, dbgs() << INDENT_2 << "Created new Sandbox instance\n");
}
/*
for (map<Function*,string>::iterator I=funcToSandboxName.begin(), E=funcToSandboxName.end(); I!=E; I++) {
Function* entryPoint = I->first;
string sandboxName = I->second;
int idx = assignBitIdxToSandboxName(sandboxName);
int overhead = funcToOverhead[entryPoint];
int clearances = funcToClearances[entryPoint];
bool persistent = find(ephemeralSandboxes.begin(), ephemeralSandboxes.end(), entryPoint) == ephemeralSandboxes.end();
SDEBUG("soaap.util.sandbox", 3, dbgs() << INDENT_2 << "Creating new Sandbox instance\n");
sandboxes.push_back(new Sandbox(sandboxName, idx, entryPoint, persistent, M, overhead, clearances));
SDEBUG("soaap.util.sandbox", 3, dbgs() << INDENT_2 << "Created new Sandbox instance\n");
}
//.........这里部分代码省略.........
示例11: APInt
/**
* This function creates a module constructor function to create the
* map from function keys to function names. This function will be
* automatically called when the module is loaded.
*
* The code was generated by using clang on a test file. The test
* file looked like (foo.cc):
* __attribute__((constructor))
* static void init()
* {
* }
*
* Then, run:
* 1. clang -S -emit-llvm -c foo.cc
* 2. llc -march=cpp foo.bc -o foo.lc
* The output foo.lc provides code for generating a ctor using LLVM.
*
*/
void BytesFlops::initializeKeyMap(Module& module)
{
if ( module.getFunction("func_key_map_ctor") )
return;
LLVMContext& ctx = module.getContext();
// Type Definitions
std::vector<Type*>StructTy_1_fields;
StructTy_1_fields.push_back(IntegerType::get(ctx, 32));
std::vector<Type*>FuncTy_3_args;
FunctionType* FuncTy_3 = FunctionType::get(
/*Result=*/ Type::getVoidTy(ctx),
/*Params=*/ FuncTy_3_args,
/*isVarArg=*/ false);
PointerType* PointerTy_2 = PointerType::get(FuncTy_3, 0);
StructTy_1_fields.push_back(PointerTy_2);
StructType *
StructTy_1 = StructType::get(ctx, StructTy_1_fields,
/*isPacked=*/false);
ArrayType* ArrayTy_0 = NULL;
// Function Declarations
func_map_ctor = Function::Create(
/*Type=*/FuncTy_3,
/*Linkage=*/GlobalValue::InternalLinkage,
/*Name=*/"func_key_map_ctor", &module);
func_map_ctor->setCallingConv(CallingConv::C);
AttributeSet func__ZL4initv_PAL;
SmallVector<AttributeSet, 4> Attrs;
AttributeSet PAS;
AttrBuilder B;
B.addAttribute(Attribute::NoUnwind);
B.addAttribute(Attribute::UWTable);
PAS = AttributeSet::get(ctx, ~0U, B);
Attrs.push_back(PAS);
func__ZL4initv_PAL = AttributeSet::get(ctx, Attrs);
func_map_ctor->setAttributes(func__ZL4initv_PAL);
// Global Variable Declarations
// Constant Definitions
std::vector<Constant*> ctor_elems;
std::vector<Constant*> const_struct_8_fields;
ConstantInt* const_int32_9 = ConstantInt::get(ctx, APInt(32, StringRef("65535"), 10));
const_struct_8_fields.push_back(const_int32_9);
const_struct_8_fields.push_back(func_map_ctor);
Constant* const_struct_8 = ConstantStruct::get(StructTy_1, const_struct_8_fields);
ctor_elems.push_back(const_struct_8);
GlobalVariable* llvm_global_ctors;
/**
* Add our constructor to the list of global constructors for the
* module. It's possible that a module already contains a ctor.
*/
GlobalVariable*
current_ctors = module.getGlobalVariable("llvm.global_ctors");
if ( !current_ctors )
{
ArrayTy_0 = ArrayType::get(StructTy_1, 1);
}
else
{
// there are existing ctors, and the initializer points to them.
// add ours to the initializer list (actually, we create a new
// initializer list and add the existing ones to it).
Constant * initializer = current_ctors->getInitializer();
ConstantArray *
ar = llvm::dyn_cast<ConstantArray>(initializer);
assert( ar );
int cnt = 0;
Constant *
elt = ar->getAggregateElement(cnt);
//.........这里部分代码省略.........
示例12: doAnalysis
void PrivilegedCallAnalysis::doAnalysis(Module& M, SandboxVector& sandboxes) {
// first find all methods annotated as being privileged and then check calls within sandboxes
if (GlobalVariable* lga = M.getNamedGlobal("llvm.global.annotations")) {
ConstantArray* lgaArray = dyn_cast<ConstantArray>(lga->getInitializer()->stripPointerCasts());
for (User::op_iterator i=lgaArray->op_begin(), e = lgaArray->op_end(); e!=i; i++) {
ConstantStruct* lgaArrayElement = dyn_cast<ConstantStruct>(i->get());
// get the annotation value first
GlobalVariable* annotationStrVar = dyn_cast<GlobalVariable>(lgaArrayElement->getOperand(1)->stripPointerCasts());
ConstantDataArray* annotationStrArray = dyn_cast<ConstantDataArray>(annotationStrVar->getInitializer());
StringRef annotationStrArrayCString = annotationStrArray->getAsCString();
GlobalValue* annotatedVal = dyn_cast<GlobalValue>(lgaArrayElement->getOperand(0)->stripPointerCasts());
if (isa<Function>(annotatedVal)) {
Function* annotatedFunc = dyn_cast<Function>(annotatedVal);
if (annotationStrArrayCString == SOAAP_PRIVILEGED) {
outs() << " Found function: " << annotatedFunc->getName() << "\n";
privAnnotFuncs.push_back(annotatedFunc);
}
}
}
}
// now check calls within sandboxes
for (Function* privilegedFunc : privAnnotFuncs) {
for (User* U : privilegedFunc->users()) {
if (CallInst* C = dyn_cast<CallInst>(U)) {
Function* enclosingFunc = C->getParent()->getParent();
for (Sandbox* S : sandboxes) {
if (!S->hasCallgate(privilegedFunc) && S->containsFunction(enclosingFunc)) {
outs() << " *** Sandbox \"" << S->getName() << "\" calls privileged function \"" << privilegedFunc->getName() << "\" that they are not allowed to. If intended, annotate this permission using the __soaap_callgates annotation.\n";
if (MDNode *N = C->getMetadata("dbg")) { // Here I is an LLVM instruction
DILocation Loc(N); // DILocation is in DebugInfo.h
unsigned Line = Loc.getLineNumber();
StringRef File = Loc.getFilename();
outs() << " +++ Line " << Line << " of file " << File << "\n";
}
}
}
}
}
}
/*
for (Sandbox* S : sandboxes) {
FunctionVector callgates = S->getCallgates();
for (Function* F : S->getFunctions()) {
for (BasicBlock& BB : F->getBasicBlockList()) {
for (Instruction& I : BB.getInstList()) {
if (CallInst* C = dyn_cast<CallInst>(&I)) {
if (Function* Target = C->getCalledFunction()) {
if (find(privAnnotFuncs.begin(), privAnnotFuncs.end(), Target) != privAnnotFuncs.end()) {
// check if this sandbox is allowed to call the privileged function
DEBUG(dbgs() << " Found privileged call: ");
DEBUG(C->dump());
if (find(callgates.begin(), callgates.end(), Target) == callgates.end()) {
outs() << " *** Sandbox \"" << S->getName() << "\" calls privileged function \"" << Target->getName() << "\" that they are not allowed to. If intended, annotate this permission using the __soaap_callgates annotation.\n";
if (MDNode *N = C->getMetadata("dbg")) { // Here I is an LLVM instruction
DILocation Loc(N); // DILocation is in DebugInfo.h
unsigned Line = Loc.getLineNumber();
StringRef File = Loc.getFilename();
outs() << " +++ Line " << Line << " of file " << File << "\n";
}
}
}
}
}
}
}
}
}
*/
}