brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.1 KiB · 75858fc Raw
438 lines · c
1//===- BTFDebug.h -----------------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file contains support for writing BTF debug info.11///12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_LIB_TARGET_BPF_BTFDEBUG_H15#define LLVM_LIB_TARGET_BPF_BTFDEBUG_H16 17#include "llvm/ADT/StringMap.h"18#include "llvm/CodeGen/DebugHandlerBase.h"19#include "llvm/DebugInfo/BTF/BTF.h"20#include <cstdint>21#include <map>22#include <set>23#include <unordered_map>24 25namespace llvm {26 27class AsmPrinter;28class BTFDebug;29class DIType;30class GlobalVariable;31class MachineFunction;32class MachineInstr;33class MachineOperand;34class MCInst;35class MCStreamer;36class MCSymbol;37 38/// The base class for BTF type generation.39class BTFTypeBase {40protected:41  uint8_t Kind;42  bool IsCompleted;43  uint32_t Id;44  struct BTF::CommonType BTFType;45 46public:47  BTFTypeBase() : IsCompleted(false) {}48  virtual ~BTFTypeBase() = default;49  void setId(uint32_t Id) { this->Id = Id; }50  uint32_t getId() { return Id; }51  uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; }52  /// Get the size of this BTF type entry.53  virtual uint32_t getSize() { return BTF::CommonTypeSize; }54  /// Complete BTF type generation after all related DebugInfo types55  /// have been visited so their BTF type id's are available56  /// for cross referece.57  virtual void completeType(BTFDebug &BDebug) {}58  /// Emit types for this BTF type entry.59  virtual void emitType(MCStreamer &OS);60};61 62/// Handle several derived types include pointer, const,63/// volatile, typedef and restrict.64class BTFTypeDerived : public BTFTypeBase {65  const DIDerivedType *DTy;66  bool NeedsFixup;67  StringRef Name;68 69public:70  BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag, bool NeedsFixup);71  BTFTypeDerived(unsigned NextTypeId, unsigned Tag, StringRef Name);72  void completeType(BTFDebug &BDebug) override;73  void emitType(MCStreamer &OS) override;74  void setPointeeType(uint32_t PointeeType);75};76 77/// Handle struct or union forward declaration.78class BTFTypeFwd : public BTFTypeBase {79  StringRef Name;80 81public:82  BTFTypeFwd(StringRef Name, bool IsUnion);83  void completeType(BTFDebug &BDebug) override;84  void emitType(MCStreamer &OS) override;85};86 87/// Handle int type.88class BTFTypeInt : public BTFTypeBase {89  StringRef Name;90  uint32_t IntVal; ///< Encoding, offset, bits91 92public:93  BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits,94             StringRef TypeName);95  uint32_t getSize() override { return BTFTypeBase::getSize() + sizeof(uint32_t); }96  void completeType(BTFDebug &BDebug) override;97  void emitType(MCStreamer &OS) override;98};99 100/// Handle enumerate type.101class BTFTypeEnum : public BTFTypeBase {102  const DICompositeType *ETy;103  std::vector<struct BTF::BTFEnum> EnumValues;104 105public:106  BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned);107  uint32_t getSize() override {108    return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize;109  }110  void completeType(BTFDebug &BDebug) override;111  void emitType(MCStreamer &OS) override;112};113 114/// Handle array type.115class BTFTypeArray : public BTFTypeBase {116  struct BTF::BTFArray ArrayInfo;117 118public:119  BTFTypeArray(uint32_t ElemTypeId, uint32_t NumElems);120  uint32_t getSize() override { return BTFTypeBase::getSize() + BTF::BTFArraySize; }121  void completeType(BTFDebug &BDebug) override;122  void emitType(MCStreamer &OS) override;123};124 125/// Handle struct/union type.126class BTFTypeStruct : public BTFTypeBase {127  const DICompositeType *STy;128  bool HasBitField;129  std::vector<struct BTF::BTFMember> Members;130 131public:132  BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField,133                uint32_t NumMembers);134  uint32_t getSize() override {135    return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize;136  }137  void completeType(BTFDebug &BDebug) override;138  void emitType(MCStreamer &OS) override;139  std::string getName();140};141 142/// Handle function pointer.143class BTFTypeFuncProto : public BTFTypeBase {144  const DISubroutineType *STy;145  std::unordered_map<uint32_t, StringRef> FuncArgNames;146  std::vector<struct BTF::BTFParam> Parameters;147 148public:149  BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams,150                   const std::unordered_map<uint32_t, StringRef> &FuncArgNames);151  uint32_t getSize() override {152    return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize;153  }154  void completeType(BTFDebug &BDebug) override;155  void emitType(MCStreamer &OS) override;156};157 158/// Handle subprogram159class BTFTypeFunc : public BTFTypeBase {160  StringRef Name;161 162public:163  BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId, uint32_t Scope);164  uint32_t getSize() override { return BTFTypeBase::getSize(); }165  void completeType(BTFDebug &BDebug) override;166  void emitType(MCStreamer &OS) override;167};168 169/// Handle variable instances170class BTFKindVar : public BTFTypeBase {171  StringRef Name;172  uint32_t Info;173 174public:175  BTFKindVar(StringRef VarName, uint32_t TypeId, uint32_t VarInfo);176  uint32_t getSize() override { return BTFTypeBase::getSize() + 4; }177  void completeType(BTFDebug &BDebug) override;178  void emitType(MCStreamer &OS) override;179};180 181/// Handle data sections182class BTFKindDataSec : public BTFTypeBase {183  AsmPrinter *Asm;184  std::string Name;185  std::vector<std::tuple<uint32_t, const MCSymbol *, uint32_t>> Vars;186 187public:188  BTFKindDataSec(AsmPrinter *AsmPrt, std::string SecName);189  uint32_t getSize() override {190    return BTFTypeBase::getSize() + BTF::BTFDataSecVarSize * Vars.size();191  }192  void addDataSecEntry(uint32_t Id, const MCSymbol *Sym, uint32_t Size) {193    Vars.push_back(std::make_tuple(Id, Sym, Size));194  }195  std::string getName() { return Name; }196  void completeType(BTFDebug &BDebug) override;197  void emitType(MCStreamer &OS) override;198};199 200/// Handle binary floating point type.201class BTFTypeFloat : public BTFTypeBase {202  StringRef Name;203 204public:205  BTFTypeFloat(uint32_t SizeInBits, StringRef TypeName);206  void completeType(BTFDebug &BDebug) override;207};208 209/// Handle decl tags.210class BTFTypeDeclTag : public BTFTypeBase {211  uint32_t Info;212  StringRef Tag;213 214public:215  BTFTypeDeclTag(uint32_t BaseTypeId, int ComponentId, StringRef Tag);216  uint32_t getSize() override { return BTFTypeBase::getSize() + 4; }217  void completeType(BTFDebug &BDebug) override;218  void emitType(MCStreamer &OS) override;219};220 221/// Handle 64-bit enumerate type.222class BTFTypeEnum64 : public BTFTypeBase {223  const DICompositeType *ETy;224  std::vector<struct BTF::BTFEnum64> EnumValues;225 226public:227  BTFTypeEnum64(const DICompositeType *ETy, uint32_t NumValues, bool IsSigned);228  uint32_t getSize() override {229    return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnum64Size;230  }231  void completeType(BTFDebug &BDebug) override;232  void emitType(MCStreamer &OS) override;233};234 235class BTFTypeTypeTag : public BTFTypeBase {236  const DIDerivedType *DTy;237  StringRef Tag;238 239public:240  BTFTypeTypeTag(uint32_t NextTypeId, StringRef Tag);241  BTFTypeTypeTag(const DIDerivedType *DTy, StringRef Tag);242  void completeType(BTFDebug &BDebug) override;243};244 245/// String table.246class BTFStringTable {247  /// String table size in bytes.248  uint32_t Size;249  /// A mapping from string table offset to the index250  /// of the Table. It is used to avoid putting251  /// duplicated strings in the table.252  std::map<uint32_t, uint32_t> OffsetToIdMap;253  /// A vector of strings to represent the string table.254  std::vector<std::string> Table;255 256public:257  BTFStringTable() : Size(0) {}258  uint32_t getSize() { return Size; }259  std::vector<std::string> &getTable() { return Table; }260  /// Add a string to the string table and returns its offset261  /// in the table.262  uint32_t addString(StringRef S);263};264 265/// Represent one func and its type id.266struct BTFFuncInfo {267  const MCSymbol *Label; ///< Func MCSymbol268  uint32_t TypeId;       ///< Type id referring to .BTF type section269};270 271/// Represent one line info.272struct BTFLineInfo {273  MCSymbol *Label;      ///< MCSymbol identifying insn for the lineinfo274  uint32_t FileNameOff; ///< file name offset in the .BTF string table275  uint32_t LineOff;     ///< line offset in the .BTF string table276  uint32_t LineNum;     ///< the line number277  uint32_t ColumnNum;   ///< the column number278};279 280/// Represent one field relocation.281struct BTFFieldReloc {282  const MCSymbol *Label;  ///< MCSymbol identifying insn for the reloc283  uint32_t TypeID;        ///< Type ID284  uint32_t OffsetNameOff; ///< The string to traverse types285  uint32_t RelocKind;     ///< What to patch the instruction286};287 288/// Collect and emit BTF information.289class BTFDebug : public DebugHandlerBase {290  MCStreamer &OS;291  bool SkipInstruction;292  bool LineInfoGenerated;293  uint32_t SecNameOff;294  uint32_t ArrayIndexTypeId;295  bool MapDefNotCollected;296  BTFStringTable StringTable;297  std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries;298  std::unordered_map<const DIType *, uint32_t> DIToIdMap;299  std::map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable;300  std::map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable;301  std::map<uint32_t, std::vector<BTFFieldReloc>> FieldRelocTable;302  StringMap<std::vector<std::string>> FileContent;303  std::map<std::string, std::unique_ptr<BTFKindDataSec>, std::less<>>304      DataSecEntries;305  std::vector<BTFTypeStruct *> StructTypes;306  std::map<const GlobalVariable *, std::pair<int64_t, uint32_t>> PatchImms;307  std::map<const DICompositeType *,308           std::vector<std::pair<const DIDerivedType *, BTFTypeDerived *>>>309      FixupDerivedTypes;310  std::set<const Function *>ProtoFunctions;311 312  /// Add types to TypeEntries.313  /// @{314  /// Add types to TypeEntries and DIToIdMap.315  uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty);316  /// Add types to TypeEntries only and return type id.317  uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry);318  /// @}319 320  /// IR type visiting functions.321  /// @{322  void visitTypeEntry(const DIType *Ty);323  void visitTypeEntry(const DIType *Ty, uint32_t &TypeId, bool CheckPointer,324                      bool SeenPointer);325  void visitBasicType(const DIBasicType *BTy, uint32_t &TypeId);326  void visitSubroutineType(327      const DISubroutineType *STy, bool ForSubprog,328      const std::unordered_map<uint32_t, StringRef> &FuncArgNames,329      uint32_t &TypeId);330  void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion,331                        uint32_t &TypeId);332  void visitCompositeType(const DICompositeType *CTy, uint32_t &TypeId);333  void visitStructType(const DICompositeType *STy, bool IsStruct,334                       uint32_t &TypeId);335  void visitArrayType(const DICompositeType *ATy, uint32_t &TypeId);336  void visitEnumType(const DICompositeType *ETy, uint32_t &TypeId);337  void visitDerivedType(const DIDerivedType *DTy, uint32_t &TypeId,338                        bool CheckPointer, bool SeenPointer);339  void visitMapDefType(const DIType *Ty, uint32_t &TypeId);340  /// @}341 342  /// Check whether the type is a forward declaration candidate or not.343  bool IsForwardDeclCandidate(const DIType *Base);344 345  /// Get the file content for the subprogram. Certain lines of the file346  /// later may be put into string table and referenced by line info.347  std::string populateFileContent(const DIFile *File);348 349  /// Construct a line info.350  void constructLineInfo(MCSymbol *Label, const DIFile *File, uint32_t Line,351                         uint32_t Column);352 353  /// Generate types and variables for globals.354  void processGlobals(bool ProcessingMapDef);355 356  /// Process global variable initializer in pursuit for function357  /// pointers.358  void processGlobalInitializer(const Constant *C);359 360  /// Generate types for function prototypes.361  void processFuncPrototypes(const Function *);362 363  /// Generate types for decl annotations.364  void processDeclAnnotations(DINodeArray Annotations, uint32_t BaseTypeId,365                              int ComponentId);366 367  /// Generate types for DISubprogram and it's arguments.368  uint32_t processDISubprogram(const DISubprogram *SP, uint32_t ProtoTypeId,369                               uint8_t Scope);370 371  /// Generate BTF type_tag's. If BaseTypeId is nonnegative, the last372  /// BTF type_tag in the chain points to BaseTypeId. Otherwise, it points to373  /// the base type of DTy. Return the type id of the first BTF type_tag374  /// in the chain. If no type_tag's are generated, a negative value375  /// is returned.376  int genBTFTypeTags(const DIDerivedType *DTy, int BaseTypeId);377 378  /// Generate one field relocation record.379  void generatePatchImmReloc(const MCSymbol *ORSym, uint32_t RootId,380                             const GlobalVariable *, bool IsAma);381 382  /// Populating unprocessed type on demand.383  unsigned populateType(const DIType *Ty);384 385  /// Process global variables referenced by relocation instructions386  /// and extern function references.387  void processGlobalValue(const MachineOperand &MO);388 389  /// Emit common header of .BTF and .BTF.ext sections.390  void emitCommonHeader();391 392  /// Emit the .BTF section.393  void emitBTFSection();394 395  /// Emit the .BTF.ext section.396  void emitBTFExtSection();397 398protected:399  /// Gather pre-function debug information.400  void beginFunctionImpl(const MachineFunction *MF) override;401 402  /// Post process after all instructions in this function are processed.403  void endFunctionImpl(const MachineFunction *MF) override;404 405public:406  BTFDebug(AsmPrinter *AP);407 408  ///409  bool InstLower(const MachineInstr *MI, MCInst &OutMI);410 411  /// Get the special array index type id.412  uint32_t getArrayIndexTypeId() {413    assert(ArrayIndexTypeId);414    return ArrayIndexTypeId;415  }416 417  /// Add string to the string table.418  size_t addString(StringRef S) { return StringTable.addString(S); }419 420  /// Get the type id for a particular DIType.421  uint32_t getTypeId(const DIType *Ty) {422    assert(Ty && "Invalid null Type");423    assert(DIToIdMap.find(Ty) != DIToIdMap.end() &&424           "DIType not added in the BDIToIdMap");425    return DIToIdMap[Ty];426  }427 428  /// Process beginning of an instruction.429  void beginInstruction(const MachineInstr *MI) override;430 431  /// Complete all the types and emit the BTF sections.432  void endModule() override;433};434 435} // end namespace llvm436 437#endif438