in lib/BPFCov.cpp [97:148]
bool fixupUsedGlobals(Module &M)
{
auto U = M.getNamedGlobal("llvm.used");
if (!U || !U->hasInitializer())
{
return false;
}
SmallVector<Constant *, 8> UsedGlobals;
auto UArray = dyn_cast<ConstantArray>(U->getInitializer());
auto NElems = UArray->getNumOperands();
for (unsigned int i = 0; i < NElems; i++)
{
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(UArray->getOperand(i)))
{
auto OC = CE->getOpcode();
if (OC == Instruction::BitCast || OC == Instruction::GetElementPtr)
{
if (GlobalValue *GV = dyn_cast<GlobalValue>(CE->getOperand(0)))
{
auto Name = GV->getName();
if (!Name.startswith("__llvm_profile_runtime") && !Name.startswith("__profd") && !Name.startswith("__covrec") && !Name.startswith("__llvm_coverage"))
{
UsedGlobals.push_back(UArray->getOperand(i));
}
}
}
}
// TODO(leodido) > almost certainly the following doesn't make sense for "llvm.used" array
else if (GlobalValue *GV = dyn_cast<GlobalValue>(UArray->getOperand(i)))
{
auto Name = GV->getName();
if (!Name.startswith("__llvm_profile_runtime") && !Name.startswith("__profd") && !Name.startswith("__covrec") && !Name.startswith("__llvm_coverage"))
{
UsedGlobals.push_back(UArray->getOperand(i));
}
}
}
if (UsedGlobals.size() < NElems)
{
errs() << "fixing llvm.used\n";
U->eraseFromParent();
ArrayType *AType = ArrayType::get(Type::getInt8PtrTy(M.getContext()), UsedGlobals.size());
U = new GlobalVariable(M, AType, false, GlobalValue::AppendingLinkage, ConstantArray::get(AType, UsedGlobals), "llvm.used");
U->setSection("llvm.metadata");
return true;
}
return false;
}