Path: blob/main/contrib/llvm-project/llvm/lib/Target/BPF/BTFDebug.h
35267 views
//===- BTFDebug.h -----------------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7///8/// \file9/// This file contains support for writing BTF debug info.10///11//===----------------------------------------------------------------------===//1213#ifndef LLVM_LIB_TARGET_BPF_BTFDEBUG_H14#define LLVM_LIB_TARGET_BPF_BTFDEBUG_H1516#include "llvm/ADT/StringMap.h"17#include "llvm/CodeGen/DebugHandlerBase.h"18#include "llvm/DebugInfo/BTF/BTF.h"19#include <cstdint>20#include <map>21#include <set>22#include <unordered_map>2324namespace llvm {2526class AsmPrinter;27class BTFDebug;28class DIType;29class GlobalVariable;30class MachineFunction;31class MachineInstr;32class MachineOperand;33class MCInst;34class MCStreamer;35class MCSymbol;3637/// The base class for BTF type generation.38class BTFTypeBase {39protected:40uint8_t Kind;41bool IsCompleted;42uint32_t Id;43struct BTF::CommonType BTFType;4445public:46BTFTypeBase() : IsCompleted(false) {}47virtual ~BTFTypeBase() = default;48void setId(uint32_t Id) { this->Id = Id; }49uint32_t getId() { return Id; }50uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; }51/// Get the size of this BTF type entry.52virtual uint32_t getSize() { return BTF::CommonTypeSize; }53/// Complete BTF type generation after all related DebugInfo types54/// have been visited so their BTF type id's are available55/// for cross referece.56virtual void completeType(BTFDebug &BDebug) {}57/// Emit types for this BTF type entry.58virtual void emitType(MCStreamer &OS);59};6061/// Handle several derived types include pointer, const,62/// volatile, typedef and restrict.63class BTFTypeDerived : public BTFTypeBase {64const DIDerivedType *DTy;65bool NeedsFixup;66StringRef Name;6768public:69BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup);70BTFTypeDerived(unsigned NextTypeId, unsigned Tag, StringRef Name);71void completeType(BTFDebug &BDebug) override;72void emitType(MCStreamer &OS) override;73void setPointeeType(uint32_t PointeeType);74};7576/// Handle struct or union forward declaration.77class BTFTypeFwd : public BTFTypeBase {78StringRef Name;7980public:81BTFTypeFwd(StringRef Name, bool IsUnion);82void completeType(BTFDebug &BDebug) override;83void emitType(MCStreamer &OS) override;84};8586/// Handle int type.87class BTFTypeInt : public BTFTypeBase {88StringRef Name;89uint32_t IntVal; ///< Encoding, offset, bits9091public:92BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits,93StringRef TypeName);94uint32_t getSize() override { return BTFTypeBase::getSize() + sizeof(uint32_t); }95void completeType(BTFDebug &BDebug) override;96void emitType(MCStreamer &OS) override;97};9899/// Handle enumerate type.100class BTFTypeEnum : public BTFTypeBase {101const DICompositeType *ETy;102std::vector<struct BTF::BTFEnum> EnumValues;103104public:105BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned);106uint32_t getSize() override {107return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize;108}109void completeType(BTFDebug &BDebug) override;110void emitType(MCStreamer &OS) override;111};112113/// Handle array type.114class BTFTypeArray : public BTFTypeBase {115struct BTF::BTFArray ArrayInfo;116117public:118BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems);119uint32_t getSize() override { return BTFTypeBase::getSize() + BTF::BTFArraySize; }120void completeType(BTFDebug &BDebug) override;121void emitType(MCStreamer &OS) override;122};123124/// Handle struct/union type.125class BTFTypeStruct : public BTFTypeBase {126const DICompositeType *STy;127bool HasBitField;128std::vector<struct BTF::BTFMember> Members;129130public:131BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField,132uint32_t NumMembers);133uint32_t getSize() override {134return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize;135}136void completeType(BTFDebug &BDebug) override;137void emitType(MCStreamer &OS) override;138std::string getName();139};140141/// Handle function pointer.142class BTFTypeFuncProto : public BTFTypeBase {143const DISubroutineType *STy;144std::unordered_map<uint32_t, StringRef> FuncArgNames;145std::vector<struct BTF::BTFParam> Parameters;146147public:148BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams,149const std::unordered_map<uint32_t, StringRef> &FuncArgNames);150uint32_t getSize() override {151return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize;152}153void completeType(BTFDebug &BDebug) override;154void emitType(MCStreamer &OS) override;155};156157/// Handle subprogram158class BTFTypeFunc : public BTFTypeBase {159StringRef Name;160161public:162BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, uint32_t Scope);163uint32_t getSize() override { return BTFTypeBase::getSize(); }164void completeType(BTFDebug &BDebug) override;165void emitType(MCStreamer &OS) override;166};167168/// Handle variable instances169class BTFKindVar : public BTFTypeBase {170StringRef Name;171uint32_t Info;172173public:174BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo);175uint32_t getSize() override { return BTFTypeBase::getSize() + 4; }176void completeType(BTFDebug &BDebug) override;177void emitType(MCStreamer &OS) override;178};179180/// Handle data sections181class BTFKindDataSec : public BTFTypeBase {182AsmPrinter *Asm;183std::string Name;184std::vector<std::tuple<uint32_t, const MCSymbol *, uint32_t>> Vars;185186public:187BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName);188uint32_t getSize() override {189return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize * Vars.size();190}191void addDataSecEntry(uint32_t Id, const MCSymbol *Sym, uint32_t Size) {192Vars.push_back(std::make_tuple(Id, Sym, Size));193}194std::string getName() { return Name; }195void completeType(BTFDebug &BDebug) override;196void emitType(MCStreamer &OS) override;197};198199/// Handle binary floating point type.200class BTFTypeFloat : public BTFTypeBase {201StringRef Name;202203public:204BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName);205void completeType(BTFDebug &BDebug) override;206};207208/// Handle decl tags.209class BTFTypeDeclTag : public BTFTypeBase {210uint32_t Info;211StringRef Tag;212213public:214BTFTypeDeclTag(uint32_t BaseTypeId, int ComponentId, StringRef Tag);215uint32_t getSize() override { return BTFTypeBase::getSize() + 4; }216void completeType(BTFDebug &BDebug) override;217void emitType(MCStreamer &OS) override;218};219220/// Handle 64-bit enumerate type.221class BTFTypeEnum64 : public BTFTypeBase {222const DICompositeType *ETy;223std::vector<struct BTF::BTFEnum64> EnumValues;224225public:226BTFTypeEnum64(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned);227uint32_t getSize() override {228return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnum64Size;229}230void completeType(BTFDebug &BDebug) override;231void emitType(MCStreamer &OS) override;232};233234class BTFTypeTypeTag : public BTFTypeBase {235const DIDerivedType *DTy;236StringRef Tag;237238public:239BTFTypeTypeTag(uint32_t NextTypeId, StringRef Tag);240BTFTypeTypeTag(const DIDerivedType *DTy, StringRef Tag);241void completeType(BTFDebug &BDebug) override;242};243244/// String table.245class BTFStringTable {246/// String table size in bytes.247uint32_t Size;248/// A mapping from string table offset to the index249/// of the Table. It is used to avoid putting250/// duplicated strings in the table.251std::map<uint32_t, uint32_t> OffsetToIdMap;252/// A vector of strings to represent the string table.253std::vector<std::string> Table;254255public:256BTFStringTable() : Size(0) {}257uint32_t getSize() { return Size; }258std::vector<std::string> &getTable() { return Table; }259/// Add a string to the string table and returns its offset260/// in the table.261uint32_t addString(StringRef S);262};263264/// Represent one func and its type id.265struct BTFFuncInfo {266const MCSymbol *Label; ///< Func MCSymbol267uint32_t TypeId; ///< Type id referring to .BTF type section268};269270/// Represent one line info.271struct BTFLineInfo {272MCSymbol *Label; ///< MCSymbol identifying insn for the lineinfo273uint32_t FileNameOff; ///< file name offset in the .BTF string table274uint32_t LineOff; ///< line offset in the .BTF string table275uint32_t LineNum; ///< the line number276uint32_t ColumnNum; ///< the column number277};278279/// Represent one field relocation.280struct BTFFieldReloc {281const MCSymbol *Label; ///< MCSymbol identifying insn for the reloc282uint32_t TypeID; ///< Type ID283uint32_t OffsetNameOff; ///< The string to traverse types284uint32_t RelocKind; ///< What to patch the instruction285};286287/// Collect and emit BTF information.288class BTFDebug : public DebugHandlerBase {289MCStreamer &OS;290bool SkipInstruction;291bool LineInfoGenerated;292uint32_t SecNameOff;293uint32_t ArrayIndexTypeId;294bool MapDefNotCollected;295BTFStringTable StringTable;296std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries;297std::unordered_map<const DIType *, uint32_t> DIToIdMap;298std::map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable;299std::map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable;300std::map<uint32_t, std::vector<BTFFieldReloc>> FieldRelocTable;301StringMap<std::vector<std::string>> FileContent;302std::map<std::string, std::unique_ptr<BTFKindDataSec>> DataSecEntries;303std::vector<BTFTypeStruct *> StructTypes;304std::map<const GlobalVariable *, std::pair<int64_t, uint32_t>> PatchImms;305std::map<const DICompositeType *,306std::vector<std::pair<const DIDerivedType *, BTFTypeDerived *>>>307FixupDerivedTypes;308std::set<const Function *>ProtoFunctions;309310/// Add types to TypeEntries.311/// @{312/// Add types to TypeEntries and DIToIdMap.313uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty);314/// Add types to TypeEntries only and return type id.315uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry);316/// @}317318/// IR type visiting functions.319/// @{320void visitTypeEntry(const DIType *Ty);321void visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer,322bool SeenPointer);323void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId);324void visitSubroutineType(325const DISubroutineType *STy, bool ForSubprog,326const std::unordered_map<uint32_t, StringRef> &FuncArgNames,327uint32_t &TypeId);328void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,329uint32_t &TypeId);330void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId);331void visitStructType(const DICompositeType *STy, bool IsStruct,332uint32_t &TypeId);333void visitArrayType(const DICompositeType *ATy, uint32_t &TypeId);334void visitEnumType(const DICompositeType *ETy, uint32_t &TypeId);335void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,336bool CheckPointer, bool SeenPointer);337void visitMapDefType(const DIType *Ty, uint32_t &TypeId);338/// @}339340/// Check whether the type is a forward declaration candidate or not.341bool IsForwardDeclCandidate(const DIType *Base);342343/// Get the file content for the subprogram. Certain lines of the file344/// later may be put into string table and referenced by line info.345std::string populateFileContent(const DIFile *File);346347/// Construct a line info.348void constructLineInfo(MCSymbol *Label, const DIFile *File, uint32_t Line,349uint32_t Column);350351/// Generate types and variables for globals.352void processGlobals(bool ProcessingMapDef);353354/// Process global variable initializer in pursuit for function355/// pointers.356void processGlobalInitializer(const Constant *C);357358/// Generate types for function prototypes.359void processFuncPrototypes(const Function *);360361/// Generate types for decl annotations.362void processDeclAnnotations(DINodeArray Annotations, uint32_t BaseTypeId,363int ComponentId);364365/// Generate types for DISubprogram and it's arguments.366uint32_t processDISubprogram(const DISubprogram *SP, uint32_t ProtoTypeId,367uint8_t Scope);368369/// Generate BTF type_tag's. If BaseTypeId is nonnegative, the last370/// BTF type_tag in the chain points to BaseTypeId. Otherwise, it points to371/// the base type of DTy. Return the type id of the first BTF type_tag372/// in the chain. If no type_tag's are generated, a negative value373/// is returned.374int genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId);375376/// Generate one field relocation record.377void generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId,378const GlobalVariable *, bool IsAma);379380/// Populating unprocessed type on demand.381unsigned populateType(const DIType *Ty);382383/// Process global variables referenced by relocation instructions384/// and extern function references.385void processGlobalValue(const MachineOperand &MO);386387/// Emit common header of .BTF and .BTF.ext sections.388void emitCommonHeader();389390/// Emit the .BTF section.391void emitBTFSection();392393/// Emit the .BTF.ext section.394void emitBTFExtSection();395396protected:397/// Gather pre-function debug information.398void beginFunctionImpl(const MachineFunction *MF) override;399400/// Post process after all instructions in this function are processed.401void endFunctionImpl(const MachineFunction *MF) override;402403public:404BTFDebug(AsmPrinter *AP);405406///407bool InstLower(const MachineInstr *MI, MCInst &OutMI);408409/// Get the special array index type id.410uint32_t getArrayIndexTypeId() {411assert(ArrayIndexTypeId);412return ArrayIndexTypeId;413}414415/// Add string to the string table.416size_t addString(StringRef S) { return StringTable.addString(S); }417418/// Get the type id for a particular DIType.419uint32_t getTypeId(const DIType *Ty) {420assert(Ty && "Invalid null Type");421assert(DIToIdMap.find(Ty) != DIToIdMap.end() &&422"DIType not added in the BDIToIdMap");423return DIToIdMap[Ty];424}425426/// Process beginning of an instruction.427void beginInstruction(const MachineInstr *MI) override;428429/// Complete all the types and emit the BTF sections.430void endModule() override;431};432433} // end namespace llvm434435#endif436437438