aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/BPF/BTFDebug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/BPF/BTFDebug.cpp')
-rw-r--r--llvm/lib/Target/BPF/BTFDebug.cpp81
1 files changed, 60 insertions, 21 deletions
diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp
index f9bdffe7cbae..c1f8ea99b959 100644
--- a/llvm/lib/Target/BPF/BTFDebug.cpp
+++ b/llvm/lib/Target/BPF/BTFDebug.cpp
@@ -371,6 +371,21 @@ void BTFKindDataSec::emitType(MCStreamer &OS) {
}
}
+BTFTypeFloat::BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName)
+ : Name(TypeName) {
+ Kind = BTF::BTF_KIND_FLOAT;
+ BTFType.Info = Kind << 24;
+ BTFType.Size = roundupToBytes(SizeInBits);
+}
+
+void BTFTypeFloat::completeType(BTFDebug &BDebug) {
+ if (IsCompleted)
+ return;
+ IsCompleted = true;
+
+ BTFType.NameOff = BDebug.addString(Name);
+}
+
uint32_t BTFStringTable::addString(StringRef S) {
// Check whether the string already exists.
for (auto &OffsetM : OffsetToIdMap) {
@@ -409,18 +424,28 @@ uint32_t BTFDebug::addType(std::unique_ptr<BTFTypeBase> TypeEntry) {
}
void BTFDebug::visitBasicType(const DIBasicType *BTy, uint32_t &TypeId) {
- // Only int types are supported in BTF.
+ // Only int and binary floating point types are supported in BTF.
uint32_t Encoding = BTy->getEncoding();
- if (Encoding != dwarf::DW_ATE_boolean && Encoding != dwarf::DW_ATE_signed &&
- Encoding != dwarf::DW_ATE_signed_char &&
- Encoding != dwarf::DW_ATE_unsigned &&
- Encoding != dwarf::DW_ATE_unsigned_char)
+ std::unique_ptr<BTFTypeBase> TypeEntry;
+ switch (Encoding) {
+ case dwarf::DW_ATE_boolean:
+ case dwarf::DW_ATE_signed:
+ case dwarf::DW_ATE_signed_char:
+ case dwarf::DW_ATE_unsigned:
+ case dwarf::DW_ATE_unsigned_char:
+ // Create a BTF type instance for this DIBasicType and put it into
+ // DIToIdMap for cross-type reference check.
+ TypeEntry = std::make_unique<BTFTypeInt>(
+ Encoding, BTy->getSizeInBits(), BTy->getOffsetInBits(), BTy->getName());
+ break;
+ case dwarf::DW_ATE_float:
+ TypeEntry =
+ std::make_unique<BTFTypeFloat>(BTy->getSizeInBits(), BTy->getName());
+ break;
+ default:
return;
+ }
- // Create a BTF type instance for this DIBasicType and put it into
- // DIToIdMap for cross-type reference check.
- auto TypeEntry = std::make_unique<BTFTypeInt>(
- Encoding, BTy->getSizeInBits(), BTy->getOffsetInBits(), BTy->getName());
TypeId = addType(std::move(TypeEntry), BTy);
}
@@ -1005,13 +1030,16 @@ void BTFDebug::generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId,
FieldRelocTable[SecNameOff].push_back(FieldReloc);
}
-void BTFDebug::processReloc(const MachineOperand &MO) {
+void BTFDebug::processGlobalValue(const MachineOperand &MO) {
// check whether this is a candidate or not
if (MO.isGlobal()) {
const GlobalValue *GVal = MO.getGlobal();
auto *GVar = dyn_cast<GlobalVariable>(GVal);
- if (!GVar)
+ if (!GVar) {
+ // Not a global variable. Maybe an extern function reference.
+ processFuncPrototypes(dyn_cast<Function>(GVal));
return;
+ }
if (!GVar->hasAttribute(BPFCoreSharedInfo::AmaAttr) &&
!GVar->hasAttribute(BPFCoreSharedInfo::TypeIdAttr))
@@ -1062,12 +1090,12 @@ void BTFDebug::beginInstruction(const MachineInstr *MI) {
//
// If the insn is "r2 = LD_imm64 @<an TypeIdAttr global>",
// The LD_imm64 result will be replaced with a btf type id.
- processReloc(MI->getOperand(1));
+ processGlobalValue(MI->getOperand(1));
} else if (MI->getOpcode() == BPF::CORE_MEM ||
MI->getOpcode() == BPF::CORE_ALU32_MEM ||
MI->getOpcode() == BPF::CORE_SHIFT) {
// relocation insn is a load, store or shift insn.
- processReloc(MI->getOperand(3));
+ processGlobalValue(MI->getOperand(3));
} else if (MI->getOpcode() == BPF::JAL) {
// check extern function references
const MachineOperand &MO = MI->getOperand(0);
@@ -1121,10 +1149,6 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) {
SecName = ".rodata";
else
SecName = Global.getInitializer()->isZeroValue() ? ".bss" : ".data";
- } else {
- // extern variables without explicit section,
- // put them into ".extern" section.
- SecName = ".extern";
}
if (ProcessingMapDef != SecName.startswith(".maps"))
@@ -1171,6 +1195,7 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) {
if (Linkage != GlobalValue::InternalLinkage &&
Linkage != GlobalValue::ExternalLinkage &&
Linkage != GlobalValue::WeakAnyLinkage &&
+ Linkage != GlobalValue::WeakODRLinkage &&
Linkage != GlobalValue::ExternalWeakLinkage)
continue;
@@ -1187,7 +1212,9 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) {
std::make_unique<BTFKindVar>(Global.getName(), GVTypeId, GVarInfo);
uint32_t VarId = addType(std::move(VarEntry));
- assert(!SecName.empty());
+ // An empty SecName means an extern variable without section attribute.
+ if (SecName.empty())
+ continue;
// Find or create a DataSec
if (DataSecEntries.find(std::string(SecName)) == DataSecEntries.end()) {
@@ -1199,8 +1226,8 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) {
const DataLayout &DL = Global.getParent()->getDataLayout();
uint32_t Size = DL.getTypeAllocSize(Global.getType()->getElementType());
- DataSecEntries[std::string(SecName)]->addVar(VarId, Asm->getSymbol(&Global),
- Size);
+ DataSecEntries[std::string(SecName)]->addDataSecEntry(VarId,
+ Asm->getSymbol(&Global), Size);
}
}
@@ -1278,7 +1305,19 @@ void BTFDebug::processFuncPrototypes(const Function *F) {
uint8_t Scope = BTF::FUNC_EXTERN;
auto FuncTypeEntry =
std::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId, Scope);
- addType(std::move(FuncTypeEntry));
+ uint32_t FuncId = addType(std::move(FuncTypeEntry));
+ if (F->hasSection()) {
+ StringRef SecName = F->getSection();
+
+ if (DataSecEntries.find(std::string(SecName)) == DataSecEntries.end()) {
+ DataSecEntries[std::string(SecName)] =
+ std::make_unique<BTFKindDataSec>(Asm, std::string(SecName));
+ }
+
+ // We really don't know func size, set it to 0.
+ DataSecEntries[std::string(SecName)]->addDataSecEntry(FuncId,
+ Asm->getSymbol(F), 0);
+ }
}
void BTFDebug::endModule() {