diff options
author | Yonghong Song <yhs@fb.com> | 2018-12-19 16:40:25 +0000 |
---|---|---|
committer | Yonghong Song <yhs@fb.com> | 2018-12-19 16:40:25 +0000 |
commit | 7b410ac352bea299441a34f3b899e728bae460a7 (patch) | |
tree | bc17e744edff0a02e91472f79f9d88c39f657223 /llvm/lib/Target/BPF/BTFDebug.h | |
parent | 8d221b40a7963caf19eaedf29f0512f6a09cd994 (diff) | |
download | bcm5719-llvm-7b410ac352bea299441a34f3b899e728bae460a7.tar.gz bcm5719-llvm-7b410ac352bea299441a34f3b899e728bae460a7.zip |
[BPF] Generate BTF DebugInfo under BPF target
This patch implements BTF (BPF Type Format).
The BTF is the debug info format for BPF, introduced
in the below linux patch:
https://github.com/torvalds/linux/commit/69b693f0aefa0ed521e8bd02260523b5ae446ad7#diff-06fb1c8825f653d7e539058b72c83332
and further extended several times, e.g.,
https://www.spinics.net/lists/netdev/msg534640.html
https://www.spinics.net/lists/netdev/msg538464.html
https://www.spinics.net/lists/netdev/msg540246.html
The main advantage of implementing in LLVM is:
. better integration/deployment as no extra tools are needed.
. bpf JIT based compilation (like bcc, bpftrace, etc.) can get
BTF without much extra effort.
. BTF line_info needs selective source codes, which can be
easily retrieved when inside the compiler.
This patch implemented BTF generation by registering a BPF
specific DebugHandler in BPFAsmPrinter.
Signed-off-by: Yonghong Song <yhs@fb.com>
Differential Revision: https://reviews.llvm.org/D55752
llvm-svn: 349640
Diffstat (limited to 'llvm/lib/Target/BPF/BTFDebug.h')
-rw-r--r-- | llvm/lib/Target/BPF/BTFDebug.h | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/llvm/lib/Target/BPF/BTFDebug.h b/llvm/lib/Target/BPF/BTFDebug.h new file mode 100644 index 00000000000..afd4ed87f63 --- /dev/null +++ b/llvm/lib/Target/BPF/BTFDebug.h @@ -0,0 +1,285 @@ +//===- BTFDebug.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file contains support for writing BTF debug info. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_BPF_BTFDEBUG_H +#define LLVM_LIB_TARGET_BPF_BTFDEBUG_H + +#include "llvm/ADT/StringMap.h" +#include "llvm/CodeGen/DebugHandlerBase.h" +#include <unordered_map> +#include "BTF.h" + +namespace llvm { + +class AsmPrinter; +class BTFDebug; +class DIType; +class MCStreamer; +class MCSymbol; +class MachineFunction; + +/// The base class for BTF type generation. +class BTFTypeBase { +protected: + uint8_t Kind; + uint32_t Id; + struct BTF::CommonType BTFType; + +public: + virtual ~BTFTypeBase() = default; + void setId(uint32_t Id) { this->Id = Id; } + uint32_t getId() { return Id; } + uint32_t roundupToBytes(uint32_t NumBits) { return (NumBits + 7) >> 3; } + /// Get the size of this BTF type entry. + virtual uint32_t getSize() { return BTF::CommonTypeSize; } + /// Complete BTF type generation after all related DebugInfo types + /// have been visited so their BTF type id's are available + /// for cross referece. + virtual void completeType(BTFDebug &BDebug) {} + /// Emit types for this BTF type entry. + virtual void emitType(MCStreamer &OS); +}; + +/// Handle several derived types include pointer, const, +/// volatile, typedef and restrict. +class BTFTypeDerived : public BTFTypeBase { + const DIDerivedType *DTy; + +public: + BTFTypeDerived(const DIDerivedType *Ty, unsigned Tag); + void completeType(BTFDebug &BDebug); + void emitType(MCStreamer &OS); +}; + +/// Handle struct or union forward declaration. +class BTFTypeFwd : public BTFTypeBase { + StringRef Name; + +public: + BTFTypeFwd(StringRef Name, bool IsUnion); + void completeType(BTFDebug &BDebug); + void emitType(MCStreamer &OS); +}; + +/// Handle int type. +class BTFTypeInt : public BTFTypeBase { + StringRef Name; + uint32_t IntVal; ///< Encoding, offset, bits + +public: + BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, uint32_t OffsetInBits, + StringRef TypeName); + uint32_t getSize() { return BTFTypeBase::getSize() + sizeof(uint32_t); } + void completeType(BTFDebug &BDebug); + void emitType(MCStreamer &OS); +}; + +/// Handle enumerate type. +class BTFTypeEnum : public BTFTypeBase { + const DICompositeType *ETy; + std::vector<struct BTF::BTFEnum> EnumValues; + +public: + BTFTypeEnum(const DICompositeType *ETy, uint32_t NumValues); + uint32_t getSize() { + return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize; + } + void completeType(BTFDebug &BDebug); + void emitType(MCStreamer &OS); +}; + +/// Handle array type. +class BTFTypeArray : public BTFTypeBase { + const DICompositeType *ATy; + struct BTF::BTFArray ArrayInfo; + +public: + BTFTypeArray(const DICompositeType *ATy); + uint32_t getSize() { return BTFTypeBase::getSize() + BTF::BTFArraySize; } + void completeType(BTFDebug &BDebug); + void emitType(MCStreamer &OS); +}; + +/// Handle struct/union type. +class BTFTypeStruct : public BTFTypeBase { + const DICompositeType *STy; + bool HasBitField; + std::vector<struct BTF::BTFMember> Members; + +public: + BTFTypeStruct(const DICompositeType *STy, bool IsStruct, bool HasBitField, + uint32_t NumMembers); + uint32_t getSize() { + return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize; + } + void completeType(BTFDebug &BDebug); + void emitType(MCStreamer &OS); +}; + +/// Handle function pointer. +class BTFTypeFuncProto : public BTFTypeBase { + const DISubroutineType *STy; + std::unordered_map<uint32_t, StringRef> FuncArgNames; + std::vector<struct BTF::BTFParam> Parameters; + +public: + BTFTypeFuncProto(const DISubroutineType *STy, uint32_t NumParams, + const std::unordered_map<uint32_t, StringRef> &FuncArgNames); + uint32_t getSize() { + return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize; + } + void completeType(BTFDebug &BDebug); + void emitType(MCStreamer &OS); +}; + +/// Handle subprogram +class BTFTypeFunc : public BTFTypeBase { + StringRef Name; + +public: + BTFTypeFunc(StringRef FuncName, uint32_t ProtoTypeId); + uint32_t getSize() { return BTFTypeBase::getSize(); } + void completeType(BTFDebug &BDebug); + void emitType(MCStreamer &OS); +}; + +/// String table. +class BTFStringTable { + /// String table size in bytes. + uint32_t Size; + /// A mapping from string table offset to the index + /// of the Table. It is used to avoid putting + /// duplicated strings in the table. + std::unordered_map<uint32_t, uint32_t> OffsetToIdMap; + /// A vector of strings to represent the string table. + std::vector<std::string> Table; + +public: + BTFStringTable() : Size(0) {} + uint32_t getSize() { return Size; } + std::vector<std::string> &getTable() { return Table; } + /// Add a string to the string table and returns its offset + /// in the table. + uint32_t addString(StringRef S); +}; + +/// Represent one func and its type id. +struct BTFFuncInfo { + const MCSymbol *Label; ///< Func MCSymbol + uint32_t TypeId; ///< Type id referring to .BTF type section +}; + +/// Represent one line info. +struct BTFLineInfo { + MCSymbol *Label; ///< MCSymbol identifying insn for the lineinfo + uint32_t FileNameOff; ///< file name offset in the .BTF string table + uint32_t LineOff; ///< line offset in the .BTF string table + uint32_t LineNum; ///< the line number + uint32_t ColumnNum; ///< the column number +}; + +/// Collect and emit BTF information. +class BTFDebug : public DebugHandlerBase { + MCStreamer &OS; + bool SkipInstruction; + bool LineInfoGenerated; + uint32_t SecNameOff; + uint32_t ArrayIndexTypeId; + BTFStringTable StringTable; + std::vector<std::unique_ptr<BTFTypeBase>> TypeEntries; + std::unordered_map<const DIType *, uint32_t> DIToIdMap; + std::unordered_map<uint32_t, std::vector<BTFFuncInfo>> FuncInfoTable; + std::unordered_map<uint32_t, std::vector<BTFLineInfo>> LineInfoTable; + StringMap<std::vector<std::string>> FileContent; + + /// Add types to TypeEntries. + /// @{ + /// Add types to TypeEntries and DIToIdMap. + void addType(std::unique_ptr<BTFTypeBase> TypeEntry, const DIType *Ty); + /// Add types to TypeEntries only and return type id. + uint32_t addType(std::unique_ptr<BTFTypeBase> TypeEntry); + /// @} + + /// IR type visiting functions. + /// @{ + void visitTypeEntry(const DIType *Ty); + void visitBasicType(const DIBasicType *BTy); + void visitSubroutineType( + const DISubroutineType *STy, bool ForSubprog, + const std::unordered_map<uint32_t, StringRef> &FuncArgNames, + uint32_t &TypeId); + void visitFwdDeclType(const DICompositeType *CTy, bool IsUnion); + void visitCompositeType(const DICompositeType *CTy); + void visitStructType(const DICompositeType *STy, bool IsStruct); + void visitArrayType(const DICompositeType *ATy); + void visitEnumType(const DICompositeType *ETy); + void visitDerivedType(const DIDerivedType *DTy); + /// @} + + /// Get the file content for the subprogram. Certain lines of the file + /// later may be put into string table and referenced by line info. + std::string populateFileContent(const DISubprogram *SP); + + /// Construct a line info. + void constructLineInfo(const DISubprogram *SP, MCSymbol *Label, uint32_t Line, + uint32_t Column); + + /// Emit common header of .BTF and .BTF.ext sections. + void emitCommonHeader(); + + /// Emit the .BTF section. + void emitBTFSection(); + + /// Emit the .BTF.ext section. + void emitBTFExtSection(); + +protected: + /// Gather pre-function debug information. + void beginFunctionImpl(const MachineFunction *MF) override; + + /// Post process after all instructions in this function are processed. + void endFunctionImpl(const MachineFunction *MF) override; + +public: + BTFDebug(AsmPrinter *AP); + + /// Get the special array index type id. + uint32_t getArrayIndexTypeId() { + assert(ArrayIndexTypeId); + return ArrayIndexTypeId; + } + + /// Add string to the string table. + size_t addString(StringRef S) { return StringTable.addString(S); } + + /// Get the type id for a particular DIType. + uint32_t getTypeId(const DIType *Ty) { + assert(Ty && "Invalid null Type"); + assert(DIToIdMap.find(Ty) != DIToIdMap.end() && + "DIType not added in the BDIToIdMap"); + return DIToIdMap[Ty]; + } + + void setSymbolSize(const MCSymbol *Symbol, uint64_t Size) override {} + + /// Process beginning of an instruction. + void beginInstruction(const MachineInstr *MI) override; + + /// Complete all the types and emit the BTF sections. + void endModule() override; +}; + +} // end namespace llvm + +#endif |