diff options
Diffstat (limited to 'lib/Target/BPF/BTFDebug.cpp')
-rw-r--r-- | lib/Target/BPF/BTFDebug.cpp | 281 |
1 files changed, 83 insertions, 198 deletions
diff --git a/lib/Target/BPF/BTFDebug.cpp b/lib/Target/BPF/BTFDebug.cpp index fa35c6619e21..db551e739bd7 100644 --- a/lib/Target/BPF/BTFDebug.cpp +++ b/lib/Target/BPF/BTFDebug.cpp @@ -184,9 +184,7 @@ void BTFTypeEnum::emitType(MCStreamer &OS) { } } -BTFTypeArray::BTFTypeArray(uint32_t ElemTypeId, uint32_t ElemSize, - uint32_t NumElems) - : ElemSize(ElemSize) { +BTFTypeArray::BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems) { Kind = BTF::BTF_KIND_ARRAY; BTFType.NameOff = 0; BTFType.Info = Kind << 24; @@ -216,12 +214,6 @@ void BTFTypeArray::emitType(MCStreamer &OS) { OS.EmitIntValue(ArrayInfo.Nelems, 4); } -void BTFTypeArray::getLocInfo(uint32_t Loc, uint32_t &LocOffset, - uint32_t &ElementTypeId) { - ElementTypeId = ArrayInfo.ElemType; - LocOffset = Loc * ElemSize; -} - /// Represent either a struct or a union. BTFTypeStruct::BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField, uint32_t Vlen) @@ -251,7 +243,8 @@ void BTFTypeStruct::completeType(BTFDebug &BDebug) { } else { BTFMember.Offset = DDTy->getOffsetInBits(); } - BTFMember.Type = BDebug.getTypeId(DDTy->getBaseType()); + const auto *BaseTy = DDTy->getBaseType(); + BTFMember.Type = BDebug.getTypeId(BaseTy); Members.push_back(BTFMember); } } @@ -268,15 +261,6 @@ void BTFTypeStruct::emitType(MCStreamer &OS) { std::string BTFTypeStruct::getName() { return STy->getName(); } -void BTFTypeStruct::getMemberInfo(uint32_t Loc, uint32_t &MemberOffset, - uint32_t &MemberType) { - MemberType = Members[Loc].Type; - MemberOffset = - HasBitField ? Members[Loc].Offset & 0xffffff : Members[Loc].Offset; -} - -uint32_t BTFTypeStruct::getStructSize() { return STy->getSizeInBits() >> 3; } - /// The Func kind represents both subprogram and pointee of function /// pointers. If the FuncName is empty, it represents a pointee of function /// pointer. Otherwise, it represents a subprogram. The func arg names @@ -428,7 +412,7 @@ void BTFDebug::visitBasicType(const DIBasicType *BTy, uint32_t &TypeId) { // Create a BTF type instance for this DIBasicType and put it into // DIToIdMap for cross-type reference check. - auto TypeEntry = llvm::make_unique<BTFTypeInt>( + auto TypeEntry = std::make_unique<BTFTypeInt>( Encoding, BTy->getSizeInBits(), BTy->getOffsetInBits(), BTy->getName()); TypeId = addType(std::move(TypeEntry), BTy); } @@ -447,7 +431,7 @@ void BTFDebug::visitSubroutineType( // a function pointer has an empty name. The subprogram type will // not be added to DIToIdMap as it should not be referenced by // any other types. - auto TypeEntry = llvm::make_unique<BTFTypeFuncProto>(STy, VLen, FuncArgNames); + auto TypeEntry = std::make_unique<BTFTypeFuncProto>(STy, VLen, FuncArgNames); if (ForSubprog) TypeId = addType(std::move(TypeEntry)); // For subprogram else @@ -478,7 +462,7 @@ void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct, } auto TypeEntry = - llvm::make_unique<BTFTypeStruct>(CTy, IsStruct, HasBitField, VLen); + std::make_unique<BTFTypeStruct>(CTy, IsStruct, HasBitField, VLen); StructTypes.push_back(TypeEntry.get()); TypeId = addType(std::move(TypeEntry), CTy); @@ -489,35 +473,29 @@ void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct, void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) { // Visit array element type. - uint32_t ElemTypeId, ElemSize; + uint32_t ElemTypeId; const DIType *ElemType = CTy->getBaseType(); visitTypeEntry(ElemType, ElemTypeId, false, false); - ElemSize = ElemType->getSizeInBits() >> 3; - if (!CTy->getSizeInBits()) { - auto TypeEntry = llvm::make_unique<BTFTypeArray>(ElemTypeId, 0, 0); - ArrayTypes.push_back(TypeEntry.get()); - ElemTypeId = addType(std::move(TypeEntry), CTy); - } else { - // Visit array dimensions. - DINodeArray Elements = CTy->getElements(); - for (int I = Elements.size() - 1; I >= 0; --I) { - if (auto *Element = dyn_cast_or_null<DINode>(Elements[I])) - if (Element->getTag() == dwarf::DW_TAG_subrange_type) { - const DISubrange *SR = cast<DISubrange>(Element); - auto *CI = SR->getCount().dyn_cast<ConstantInt *>(); - int64_t Count = CI->getSExtValue(); - - auto TypeEntry = - llvm::make_unique<BTFTypeArray>(ElemTypeId, ElemSize, Count); - ArrayTypes.push_back(TypeEntry.get()); - if (I == 0) - ElemTypeId = addType(std::move(TypeEntry), CTy); - else - ElemTypeId = addType(std::move(TypeEntry)); - ElemSize = ElemSize * Count; - } - } + // Visit array dimensions. + DINodeArray Elements = CTy->getElements(); + for (int I = Elements.size() - 1; I >= 0; --I) { + if (auto *Element = dyn_cast_or_null<DINode>(Elements[I])) + if (Element->getTag() == dwarf::DW_TAG_subrange_type) { + const DISubrange *SR = cast<DISubrange>(Element); + auto *CI = SR->getCount().dyn_cast<ConstantInt *>(); + int64_t Count = CI->getSExtValue(); + + // For struct s { int b; char c[]; }, the c[] will be represented + // as an array with Count = -1. + auto TypeEntry = + std::make_unique<BTFTypeArray>(ElemTypeId, + Count >= 0 ? Count : 0); + if (I == 0) + ElemTypeId = addType(std::move(TypeEntry), CTy); + else + ElemTypeId = addType(std::move(TypeEntry)); + } } // The array TypeId is the type id of the outermost dimension. @@ -526,7 +504,7 @@ void BTFDebug::visitArrayType(const DICompositeType *CTy, uint32_t &TypeId) { // The IR does not have a type for array index while BTF wants one. // So create an array index type if there is none. if (!ArrayIndexTypeId) { - auto TypeEntry = llvm::make_unique<BTFTypeInt>(dwarf::DW_ATE_unsigned, 32, + auto TypeEntry = std::make_unique<BTFTypeInt>(dwarf::DW_ATE_unsigned, 32, 0, "__ARRAY_SIZE_TYPE__"); ArrayIndexTypeId = addType(std::move(TypeEntry)); } @@ -538,7 +516,7 @@ void BTFDebug::visitEnumType(const DICompositeType *CTy, uint32_t &TypeId) { if (VLen > BTF::MAX_VLEN) return; - auto TypeEntry = llvm::make_unique<BTFTypeEnum>(CTy, VLen); + auto TypeEntry = std::make_unique<BTFTypeEnum>(CTy, VLen); TypeId = addType(std::move(TypeEntry), CTy); // No need to visit base type as BTF does not encode it. } @@ -546,7 +524,7 @@ void BTFDebug::visitEnumType(const DICompositeType *CTy, uint32_t &TypeId) { /// Handle structure/union forward declarations. void BTFDebug::visitFwdDeclType(const DICompositeType *CTy, bool IsUnion, uint32_t &TypeId) { - auto TypeEntry = llvm::make_unique<BTFTypeFwd>(CTy->getName(), IsUnion); + auto TypeEntry = std::make_unique<BTFTypeFwd>(CTy->getName(), IsUnion); TypeId = addType(std::move(TypeEntry), CTy); } @@ -588,7 +566,7 @@ void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId, /// Find a candidate, generate a fixup. Later on the struct/union /// pointee type will be replaced with either a real type or /// a forward declaration. - auto TypeEntry = llvm::make_unique<BTFTypeDerived>(DTy, Tag, true); + auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy, Tag, true); auto &Fixup = FixupDerivedTypes[CTy->getName()]; Fixup.first = CTag == dwarf::DW_TAG_union_type; Fixup.second.push_back(TypeEntry.get()); @@ -602,7 +580,7 @@ void BTFDebug::visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId, if (Tag == dwarf::DW_TAG_pointer_type || Tag == dwarf::DW_TAG_typedef || Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type || Tag == dwarf::DW_TAG_restrict_type) { - auto TypeEntry = llvm::make_unique<BTFTypeDerived>(DTy, Tag, false); + auto TypeEntry = std::make_unique<BTFTypeDerived>(DTy, Tag, false); TypeId = addType(std::move(TypeEntry), DTy); } else if (Tag != dwarf::DW_TAG_member) { return; @@ -669,7 +647,7 @@ void BTFDebug::visitMapDefType(const DIType *Ty, uint32_t &TypeId) { } auto TypeEntry = - llvm::make_unique<BTFTypeStruct>(CTy, true, HasBitField, Elements.size()); + std::make_unique<BTFTypeStruct>(CTy, true, HasBitField, Elements.size()); StructTypes.push_back(TypeEntry.get()); TypeId = addType(std::move(TypeEntry), CTy); @@ -774,9 +752,10 @@ void BTFDebug::emitBTFSection() { } void BTFDebug::emitBTFExtSection() { - // Do not emit section if empty FuncInfoTable and LineInfoTable. + // Do not emit section if empty FuncInfoTable and LineInfoTable + // and FieldRelocTable. if (!FuncInfoTable.size() && !LineInfoTable.size() && - !OffsetRelocTable.size() && !ExternRelocTable.size()) + !FieldRelocTable.size()) return; MCContext &Ctx = OS.getContext(); @@ -788,8 +767,8 @@ void BTFDebug::emitBTFExtSection() { // Account for FuncInfo/LineInfo record size as well. uint32_t FuncLen = 4, LineLen = 4; - // Do not account for optional OffsetReloc/ExternReloc. - uint32_t OffsetRelocLen = 0, ExternRelocLen = 0; + // Do not account for optional FieldReloc. + uint32_t FieldRelocLen = 0; for (const auto &FuncSec : FuncInfoTable) { FuncLen += BTF::SecFuncInfoSize; FuncLen += FuncSec.second.size() * BTF::BPFFuncInfoSize; @@ -798,28 +777,20 @@ void BTFDebug::emitBTFExtSection() { LineLen += BTF::SecLineInfoSize; LineLen += LineSec.second.size() * BTF::BPFLineInfoSize; } - for (const auto &OffsetRelocSec : OffsetRelocTable) { - OffsetRelocLen += BTF::SecOffsetRelocSize; - OffsetRelocLen += OffsetRelocSec.second.size() * BTF::BPFOffsetRelocSize; - } - for (const auto &ExternRelocSec : ExternRelocTable) { - ExternRelocLen += BTF::SecExternRelocSize; - ExternRelocLen += ExternRelocSec.second.size() * BTF::BPFExternRelocSize; + for (const auto &FieldRelocSec : FieldRelocTable) { + FieldRelocLen += BTF::SecFieldRelocSize; + FieldRelocLen += FieldRelocSec.second.size() * BTF::BPFFieldRelocSize; } - if (OffsetRelocLen) - OffsetRelocLen += 4; - if (ExternRelocLen) - ExternRelocLen += 4; + if (FieldRelocLen) + FieldRelocLen += 4; OS.EmitIntValue(0, 4); OS.EmitIntValue(FuncLen, 4); OS.EmitIntValue(FuncLen, 4); OS.EmitIntValue(LineLen, 4); OS.EmitIntValue(FuncLen + LineLen, 4); - OS.EmitIntValue(OffsetRelocLen, 4); - OS.EmitIntValue(FuncLen + LineLen + OffsetRelocLen, 4); - OS.EmitIntValue(ExternRelocLen, 4); + OS.EmitIntValue(FieldRelocLen, 4); // Emit func_info table. OS.AddComment("FuncInfo"); @@ -853,35 +824,20 @@ void BTFDebug::emitBTFExtSection() { } } - // Emit offset reloc table. - if (OffsetRelocLen) { - OS.AddComment("OffsetReloc"); - OS.EmitIntValue(BTF::BPFOffsetRelocSize, 4); - for (const auto &OffsetRelocSec : OffsetRelocTable) { - OS.AddComment("Offset reloc section string offset=" + - std::to_string(OffsetRelocSec.first)); - OS.EmitIntValue(OffsetRelocSec.first, 4); - OS.EmitIntValue(OffsetRelocSec.second.size(), 4); - for (const auto &OffsetRelocInfo : OffsetRelocSec.second) { - Asm->EmitLabelReference(OffsetRelocInfo.Label, 4); - OS.EmitIntValue(OffsetRelocInfo.TypeID, 4); - OS.EmitIntValue(OffsetRelocInfo.OffsetNameOff, 4); - } - } - } - - // Emit extern reloc table. - if (ExternRelocLen) { - OS.AddComment("ExternReloc"); - OS.EmitIntValue(BTF::BPFExternRelocSize, 4); - for (const auto &ExternRelocSec : ExternRelocTable) { - OS.AddComment("Extern reloc section string offset=" + - std::to_string(ExternRelocSec.first)); - OS.EmitIntValue(ExternRelocSec.first, 4); - OS.EmitIntValue(ExternRelocSec.second.size(), 4); - for (const auto &ExternRelocInfo : ExternRelocSec.second) { - Asm->EmitLabelReference(ExternRelocInfo.Label, 4); - OS.EmitIntValue(ExternRelocInfo.ExternNameOff, 4); + // Emit field reloc table. + if (FieldRelocLen) { + OS.AddComment("FieldReloc"); + OS.EmitIntValue(BTF::BPFFieldRelocSize, 4); + for (const auto &FieldRelocSec : FieldRelocTable) { + OS.AddComment("Field reloc section string offset=" + + std::to_string(FieldRelocSec.first)); + OS.EmitIntValue(FieldRelocSec.first, 4); + OS.EmitIntValue(FieldRelocSec.second.size(), 4); + for (const auto &FieldRelocInfo : FieldRelocSec.second) { + Asm->EmitLabelReference(FieldRelocInfo.Label, 4); + OS.EmitIntValue(FieldRelocInfo.TypeID, 4); + OS.EmitIntValue(FieldRelocInfo.OffsetNameOff, 4); + OS.EmitIntValue(FieldRelocInfo.RelocKind, 4); } } } @@ -942,7 +898,7 @@ void BTFDebug::beginFunctionImpl(const MachineFunction *MF) { // Construct subprogram func type auto FuncTypeEntry = - llvm::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId); + std::make_unique<BTFTypeFunc>(SP->getName(), ProtoTypeId); uint32_t FuncTypeId = addType(std::move(FuncTypeEntry)); for (const auto &TypeEntry : TypeEntries) @@ -980,71 +936,27 @@ unsigned BTFDebug::populateStructType(const DIType *Ty) { return Id; } -// Find struct/array debuginfo types given a type id. -void BTFDebug::setTypeFromId(uint32_t TypeId, BTFTypeStruct **PrevStructType, - BTFTypeArray **PrevArrayType) { - for (const auto &StructType : StructTypes) { - if (StructType->getId() == TypeId) { - *PrevStructType = StructType; - return; - } - } - for (const auto &ArrayType : ArrayTypes) { - if (ArrayType->getId() == TypeId) { - *PrevArrayType = ArrayType; - return; - } - } -} - -/// Generate a struct member offset relocation. -void BTFDebug::generateOffsetReloc(const MachineInstr *MI, +/// Generate a struct member field relocation. +void BTFDebug::generateFieldReloc(const MachineInstr *MI, const MCSymbol *ORSym, DIType *RootTy, StringRef AccessPattern) { - BTFTypeStruct *PrevStructType = nullptr; - BTFTypeArray *PrevArrayType = nullptr; unsigned RootId = populateStructType(RootTy); - setTypeFromId(RootId, &PrevStructType, &PrevArrayType); - unsigned RootTySize = PrevStructType->getStructSize(); - - BTFOffsetReloc OffsetReloc; - OffsetReloc.Label = ORSym; - OffsetReloc.OffsetNameOff = addString(AccessPattern.drop_back()); - OffsetReloc.TypeID = RootId; - - uint32_t Start = 0, End = 0, Offset = 0; - bool FirstAccess = true; - for (auto C : AccessPattern) { - if (C != ':') { - End++; - } else { - std::string SubStr = AccessPattern.substr(Start, End - Start); - int Loc = std::stoi(SubStr); - - if (FirstAccess) { - Offset = Loc * RootTySize; - FirstAccess = false; - } else if (PrevStructType) { - uint32_t MemberOffset, MemberTypeId; - PrevStructType->getMemberInfo(Loc, MemberOffset, MemberTypeId); - - Offset += MemberOffset >> 3; - PrevStructType = nullptr; - setTypeFromId(MemberTypeId, &PrevStructType, &PrevArrayType); - } else if (PrevArrayType) { - uint32_t LocOffset, ElementTypeId; - PrevArrayType->getLocInfo(Loc, LocOffset, ElementTypeId); - - Offset += LocOffset; - PrevArrayType = nullptr; - setTypeFromId(ElementTypeId, &PrevStructType, &PrevArrayType); - } - Start = End + 1; - End = Start; - } - } - AccessOffsets[RootTy->getName().str() + ":" + AccessPattern.str()] = Offset; - OffsetRelocTable[SecNameOff].push_back(OffsetReloc); + size_t FirstDollar = AccessPattern.find_first_of('$'); + size_t FirstColon = AccessPattern.find_first_of(':'); + size_t SecondColon = AccessPattern.find_first_of(':', FirstColon + 1); + StringRef IndexPattern = AccessPattern.substr(FirstDollar + 1); + StringRef RelocKindStr = AccessPattern.substr(FirstColon + 1, + SecondColon - FirstColon); + StringRef PatchImmStr = AccessPattern.substr(SecondColon + 1, + FirstDollar - SecondColon); + + BTFFieldReloc FieldReloc; + FieldReloc.Label = ORSym; + FieldReloc.OffsetNameOff = addString(IndexPattern); + FieldReloc.TypeID = RootId; + FieldReloc.RelocKind = std::stoull(RelocKindStr); + PatchImms[AccessPattern.str()] = std::stoul(PatchImmStr); + FieldRelocTable[SecNameOff].push_back(FieldReloc); } void BTFDebug::processLDimm64(const MachineInstr *MI) { @@ -1052,7 +964,7 @@ void BTFDebug::processLDimm64(const MachineInstr *MI) { // will generate an .BTF.ext record. // // If the insn is "r2 = LD_imm64 @__BTF_...", - // add this insn into the .BTF.ext OffsetReloc subsection. + // add this insn into the .BTF.ext FieldReloc subsection. // Relocation looks like: // . SecName: // . InstOffset @@ -1083,16 +995,7 @@ void BTFDebug::processLDimm64(const MachineInstr *MI) { MDNode *MDN = GVar->getMetadata(LLVMContext::MD_preserve_access_index); DIType *Ty = dyn_cast<DIType>(MDN); - generateOffsetReloc(MI, ORSym, Ty, GVar->getName()); - } else if (GVar && !GVar->hasInitializer() && GVar->hasExternalLinkage() && - GVar->getSection() == BPFCoreSharedInfo::PatchableExtSecName) { - MCSymbol *ORSym = OS.getContext().createTempSymbol(); - OS.EmitLabel(ORSym); - - BTFExternReloc ExternReloc; - ExternReloc.Label = ORSym; - ExternReloc.ExternNameOff = addString(GVar->getName()); - ExternRelocTable[SecNameOff].push_back(ExternReloc); + generateFieldReloc(MI, ORSym, Ty, GVar->getName()); } } } @@ -1200,12 +1103,12 @@ void BTFDebug::processGlobals(bool ProcessingMapDef) { ? BTF::VAR_GLOBAL_ALLOCATED : BTF::VAR_STATIC; auto VarEntry = - llvm::make_unique<BTFKindVar>(Global.getName(), GVTypeId, GVarInfo); + std::make_unique<BTFKindVar>(Global.getName(), GVTypeId, GVarInfo); uint32_t VarId = addType(std::move(VarEntry)); // Find or create a DataSec if (DataSecEntries.find(SecName) == DataSecEntries.end()) { - DataSecEntries[SecName] = llvm::make_unique<BTFKindDataSec>(Asm, SecName); + DataSecEntries[SecName] = std::make_unique<BTFKindDataSec>(Asm, SecName); } // Calculate symbol size @@ -1224,30 +1127,12 @@ bool BTFDebug::InstLower(const MachineInstr *MI, MCInst &OutMI) { const GlobalValue *GVal = MO.getGlobal(); auto *GVar = dyn_cast<GlobalVariable>(GVal); if (GVar && GVar->hasAttribute(BPFCoreSharedInfo::AmaAttr)) { - MDNode *MDN = GVar->getMetadata(LLVMContext::MD_preserve_access_index); - DIType *Ty = dyn_cast<DIType>(MDN); - std::string TypeName = Ty->getName(); - int64_t Imm = AccessOffsets[TypeName + ":" + GVar->getName().str()]; - - // Emit "mov ri, <imm>" for abstract member accesses. + // Emit "mov ri, <imm>" for patched immediate. + uint32_t Imm = PatchImms[GVar->getName().str()]; OutMI.setOpcode(BPF::MOV_ri); OutMI.addOperand(MCOperand::createReg(MI->getOperand(0).getReg())); OutMI.addOperand(MCOperand::createImm(Imm)); return true; - } else if (GVar && !GVar->hasInitializer() && - GVar->hasExternalLinkage() && - GVar->getSection() == BPFCoreSharedInfo::PatchableExtSecName) { - const IntegerType *IntTy = dyn_cast<IntegerType>(GVar->getValueType()); - assert(IntTy); - // For patchable externals, emit "LD_imm64, ri, 0" if the external - // variable is 64bit width, emit "mov ri, 0" otherwise. - if (IntTy->getBitWidth() == 64) - OutMI.setOpcode(BPF::LD_imm64); - else - OutMI.setOpcode(BPF::MOV_ri); - OutMI.addOperand(MCOperand::createReg(MI->getOperand(0).getReg())); - OutMI.addOperand(MCOperand::createImm(0)); - return true; } } } @@ -1281,7 +1166,7 @@ void BTFDebug::endModule() { } if (StructTypeId == 0) { - auto FwdTypeEntry = llvm::make_unique<BTFTypeFwd>(TypeName, IsUnion); + auto FwdTypeEntry = std::make_unique<BTFTypeFwd>(TypeName, IsUnion); StructTypeId = addType(std::move(FwdTypeEntry)); } |