diff options
Diffstat (limited to 'llvm/lib/Target/BPF/BTFDebug.cpp')
| -rw-r--r-- | llvm/lib/Target/BPF/BTFDebug.cpp | 81 |
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() { |
