in lib/BPFCov.cpp [428:647]
bool annotateCounters(Module &M)
{
bool Annotated = false;
DIBuilder DIB(M);
Module::debug_compile_units_iterator CUIterator = M.debug_compile_units_begin();
auto *DebugCU = *CUIterator;
auto *DebugFile = DebugCU->getFile();
// Save the current list of globals from the CU debug info
SmallVector<Metadata *> DebugGlobals;
for (auto *DG : DebugCU->getGlobalVariables())
{
DebugGlobals.push_back(DG);
}
for (auto gv_iter = M.global_begin(); gv_iter != M.global_end(); gv_iter++)
{
GlobalVariable *GV = &*gv_iter;
if (GV->hasName())
{
if (GV->getName().startswith("__profc") && GV->getValueType()->isArrayTy())
{
// Change to DSO local
GV->setLinkage(GlobalValue::LinkageTypes::ExternalLinkage);
GV->setDSOLocal(true);
auto N = GV->getValueType()->getArrayNumElements();
auto *S64Ty = DIB.createBasicType("long long int", 64, dwarf::DW_ATE_signed);
auto *DebugArrayTy = DIB.createArrayType(
/*Size=*/N * 64,
/*AlignInBits=*/0,
/*Ty=*/S64Ty,
/*Subscripts=*/DIB.getOrCreateArray({DIB.getOrCreateSubrange(0, N)}));
auto *DebugGVE = DIB.createGlobalVariableExpression(
/*Context=*/DebugCU,
/*Name=*/GV->getName(),
/*LinkageName=*/"",
/*File=*/DebugFile,
/*LineNo=*/0,
/*Ty=*/DebugArrayTy,
/*IsLocalToUnit=*/GV->hasLocalLinkage(),
/*IsDefinition=*/true,
/*Expr=*/nullptr,
/*Decl=*/nullptr,
/*TemplateParams=*/nullptr,
/*AlignInBits=*/0);
GV->addDebugInfo(DebugGVE);
DebugGlobals.push_back(DebugGVE);
Annotated = true;
}
else if (GV->getName() == "__llvm_prf_nm" && GV->getValueType()->isArrayTy())
{
// Change to DSO local
GV->setLinkage(GlobalValue::LinkageTypes::ExternalLinkage);
GV->setDSOLocal(true);
auto N = GV->getValueType()->getArrayNumElements();
auto *S8Ty = DIB.createBasicType("char", 8, dwarf::DW_ATE_signed_char);
auto *ConstS8Ty = DIB.createQualifiedType(dwarf::DW_TAG_const_type, S8Ty);
auto *DebugArrayTy = DIB.createArrayType(
/*Size=*/N * 8,
/*AlignInBits=*/0,
/*Ty=*/ConstS8Ty,
/*Subscripts=*/DIB.getOrCreateArray({DIB.getOrCreateSubrange(0, N)}));
auto *DebugGVE = DIB.createGlobalVariableExpression(
/*Context=*/DebugCU,
/*Name=*/GV->getName(),
/*LinkageName=*/"",
/*File=*/DebugFile,
/*LineNo=*/0,
/*Ty=*/DebugArrayTy,
/*IsLocalToUnit=*/GV->hasLocalLinkage(),
/*IsDefinition=*/true,
/*Expr=*/nullptr,
/*Decl=*/nullptr,
/*TemplateParams=*/nullptr,
/*AlignInBits=*/0);
GV->addDebugInfo(DebugGVE);
DebugGlobals.push_back(DebugGVE);
Annotated = true;
}
else if (GV->getName().startswith("__profd"))
{
DIBasicType *Ty;
if (GV->getName().endswith(".0") || GV->getName().endswith(".1") || GV->getName().endswith(".2") || GV->getName().endswith(".3") || GV->getName().endswith(".4"))
{
Ty = DIB.createBasicType("long long int", 64, dwarf::DW_ATE_signed);
}
else if (GV->getName().endswith(".5") || GV->getName().endswith(".6"))
{
Ty = DIB.createBasicType("int", 32, dwarf::DW_ATE_signed);
}
auto *DebugGVE = DIB.createGlobalVariableExpression(
/*Context=*/DebugCU,
/*Name=*/GV->getName(),
/*LinkageName=*/"",
/*File=*/DebugFile,
/*LineNo=*/0,
/*Ty=*/Ty,
/*IsLocalToUnit=*/GV->hasLocalLinkage(),
/*IsDefinition=*/true,
/*Expr=*/nullptr,
/*Decl=*/nullptr,
/*TemplateParams=*/nullptr,
/*AlignInBits=*/0);
GV->addDebugInfo(DebugGVE);
DebugGlobals.push_back(DebugGVE);
Annotated = true;
}
else if (GV->getName().startswith("__covrec"))
{
DIType *GVTy;
if (GV->getName().endswith(".0"))
{
auto *Ty = DIB.createBasicType("long long int", 64, dwarf::DW_ATE_signed);
GVTy = DIB.createQualifiedType(dwarf::DW_TAG_const_type, Ty);
}
if (GV->getName().endswith(".4"))
{
auto *Ty = DIB.createBasicType("char", 8, dwarf::DW_ATE_signed_char);
auto N = GV->getValueType()->getArrayNumElements();
GVTy = DIB.createArrayType(
/*Size=*/N * 8,
/*AlignInBits=*/0,
/*Ty=*/DIB.createQualifiedType(dwarf::DW_TAG_const_type, Ty),
/*Subscripts=*/DIB.getOrCreateArray({DIB.getOrCreateSubrange(0, N)}));
}
auto *DebugGVE = DIB.createGlobalVariableExpression(
/*Context=*/DebugCU,
/*Name=*/GV->getName(),
/*LinkageName=*/"",
/*File=*/DebugFile,
/*LineNo=*/0,
/*Ty=*/GVTy,
/*IsLocalToUnit=*/GV->hasLocalLinkage(),
/*IsDefinition=*/true,
/*Expr=*/nullptr,
/*Decl=*/nullptr,
/*TemplateParams=*/nullptr,
/*AlignInBits=*/0);
GV->addDebugInfo(DebugGVE);
DebugGlobals.push_back(DebugGVE);
Annotated = true;
}
else if (GV->getName().startswith("__llvm_coverage"))
{
auto N = GV->getValueType()->getArrayNumElements();
auto Size = N;
DIBasicType *Ty;
if (GV->getName().endswith(".0"))
{
Ty = DIB.createBasicType("int", 32, dwarf::DW_ATE_signed);
Size *= 32;
}
if (GV->getName().endswith(".1"))
{
Ty = DIB.createBasicType("char", 8, dwarf::DW_ATE_signed_char);
Size *= 8;
}
auto *ConstTy = DIB.createQualifiedType(dwarf::DW_TAG_const_type, Ty);
auto *DebugArrayTy = DIB.createArrayType(
/*Size=*/Size,
/*AlignInBits=*/0,
/*Ty=*/ConstTy,
/*Subscripts=*/DIB.getOrCreateArray({DIB.getOrCreateSubrange(0, N)}));
auto *DebugGVE = DIB.createGlobalVariableExpression(
/*Context=*/DebugCU,
/*Name=*/GV->getName(),
/*LinkageName=*/"",
/*File=*/DebugFile,
/*LineNo=*/0,
/*Ty=*/DebugArrayTy,
/*IsLocalToUnit=*/GV->hasLocalLinkage(),
/*IsDefinition=*/true,
/*Expr=*/nullptr,
/*Decl=*/nullptr,
/*TemplateParams=*/nullptr,
/*AlignInBits=*/0);
GV->addDebugInfo(DebugGVE);
DebugGlobals.push_back(DebugGVE);
Annotated = true;
}
}
}
if (Annotated)
{
errs() << "updating compile unit's globals debug info\n";
DebugCU->replaceGlobalVariables(MDTuple::get(M.getContext(), DebugGlobals));
DIB.finalize();
}
return Annotated;
}