Index: include/llvm/BinaryFormat/BTF.h =================================================================== --- /dev/null +++ include/llvm/BinaryFormat/BTF.h @@ -0,0 +1,201 @@ +//===-- llvm/BinaryFormat/BTF.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 the layout of .BTF and .BTF.ext ELF sections. +/// +/// The binary layout for .BTF section: +/// struct Header +/// Type and Str subsections +/// The Type subsection is a collection of types with type id starting with 1. +/// The Str subsection is simply a collection of strings. +/// +/// The binary layout for .BTF.ext section: +/// struct ExtHeader +/// FuncInfo and LineInfo subsections +/// The FuncInfo subsection is defined as below: +/// struct SecFuncInfo for ELF section #1 +/// A number of struct BPFFuncInfo for ELF section #1 +/// struct SecFuncInfo for ELF section #2 +/// A number of struct BPFFuncInfo for ELF section #2 +/// ... +/// The LineInfo subsection is defined as below: +/// struct SecLineInfo for ELF section #1 +/// A number of struct BPFLineInfo for ELF section #1 +/// struct SecLineInfo for ELF section #2 +/// A number of struct BPFLineInfo for ELF section #2 +/// ... +/// +/// The section formats are also defined at +/// https://github.com/torvalds/linux/blob/master/include/uapi/linux/btf.h +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BINARYFORMAT_BTF_H +#define LLVM_BINARYFORMAT_BTF_H + +namespace llvm { +namespace BTF { + +enum { MAGIC = 0xeB9F, VERSION = 1 }; + +/// Sizes in bytes of various things in the BTF format. +enum { + HeaderSize = 24, + ExtHeaderSize = 24, + CommonTypeSize = 12, + BTFArraySize = 12, + BTFEnumSize = 8, + BTFMemberSize = 12, + BTFParamSize = 8, + SecFuncInfoSize = 8, + SecLineInfoSize = 8, + BPFFuncInfoSize = 8, + BPFLineInfoSize = 16 +}; + +/// The .BTF section header definition. +struct Header { + uint16_t Magic; ///< Magic value + uint8_t Version; ///< Version number + uint8_t Flags; ///< Extra flags + uint32_t HdrLen; ///< Length of this header + + /// All offsets are in bytes relative to the end of this header. + uint32_t TypeOff; ///< Offset of type section + uint32_t TypeLen; ///< Length of type section + uint32_t StrOff; ///< Offset of string section + uint32_t StrLen; ///< Length of string section +}; + +enum { + MAX_TYPE = 0xffff, ///< Max # of type identifier + MAX_NAME_OFFSET = 0xffff, ///< Max offset into the string section + MAX_VLEN = 0xffff ///< Max # of struct/union/enum members or func args +}; + +enum TypeKinds { +#define HANDLE_BTF_KIND(ID, NAME) BTF_KIND_##NAME = ID, +#include "llvm/BinaryFormat/BTF.def" +}; + +/// The BTF common type definition. Different kinds may have +/// additional information after this structure data. +struct CommonType { + /// Type name offset in the string table. + uint32_t NameOff; + + /// "Info" bits arrangement: + /// Bits 0-15: vlen (e.g. # of struct's members) + /// Bits 16-23: unused + /// Bits 24-27: kind (e.g. int, ptr, array...etc) + /// Bits 28-31: unused + uint32_t Info; + + /// "Size" is used by INT, ENUM, STRUCT and UNION. + /// "Size" tells the size of the type it is describing. + /// + /// "Type" is used by PTR, TYPEDEF, VOLATILE, CONST, RESTRICT + /// and FUNC. + /// "Type" is a type_id referring to another type. + union { + uint32_t Size; + uint32_t Type; + }; +}; + +// For some specific BTF_KIND, "struct CommonType" is immediately +// followed by extra data. + +// BTF_KIND_INT is followed by a u32 and the following +// is the 32 bits arrangement: +// BTF_INT_ENCODING(VAL) : (((VAL) & 0x0f000000) >> 24) +// BTF_INT_OFFSET(VAL) : (((VAL & 0x00ff0000)) >> 16) +// BTF_INT_BITS(VAL) : ((VAL) & 0x000000ff) + +/// Attributes stored in the INT_ENCODING. +enum { INT_SIGNED = (1 << 0), INT_CHAR = (1 << 1), INT_BOOL = (1 << 2) }; + +/// BTF_KIND_ENUM is followed by multiple "struct BTFEnum". +/// The exact number of btf_enum is stored in the vlen (of the +/// info in "struct CommonType"). +struct BTFEnum { + uint32_t NameOff; ///< Enum name offset in the string table + int32_t Val; ///< Enum member value +}; + +/// BTF_KIND_ARRAY is followed by one "struct BTFArray". +struct BTFArray { + uint32_t ElemType; ///< Element type + uint32_t IndexType; ///< Index type + uint32_t Nelems; ///< Number of elements for this array +}; + +/// BTF_KIND_STRUCT and BTF_KIND_UNION are followed +/// by multiple "struct BTFMember". The exact number +/// of BTFMember is stored in the vlen (of the info in +/// "struct CommonType"). +struct BTFMember { + uint32_t NameOff; ///< Member name offset in the string table + uint32_t Type; ///< Member type + uint32_t Offset; ///< Offset in bits from the struct start +}; + +/// BTF_KIND_FUNC are followed by multiple "struct BTFParam". +/// The exist number of BTFParam is stored in the vlen (of the info +/// in "struct CommonType"). +struct BTFParam { + uint32_t NameOff; + uint32_t Type; +}; + +/// The .BTF.ext section header definition. +struct ExtHeader { + uint16_t Magic; + uint8_t Version; + uint8_t Flags; + uint32_t HdrLen; + + uint32_t FuncInfoOff; ///< Offset of func info section + uint32_t FuncInfoLen; ///< Length of func info section + uint32_t LineInfoOff; ///< Offset of line info section + uint32_t LineInfoLen; ///< Length of line info section +}; + +/// Specifying one function info. +struct BPFFuncInfo { + uint32_t InsnOffset; ///< Byte offset in the section + uint32_t TypeId; ///< Type id referring to .BTF type section +}; + +/// Specifying function info's in one section. +struct SecFuncInfo { + uint32_t SecNameOff; ///< Section name index in the .BTF string table + uint32_t NumFuncInfo; ///< Number of func info's in this section +}; + +/// Specifying one line info. +struct BPFLineInfo { + uint32_t InsnOffset; ///< Byte offset in this section + uint32_t FileNameOff; ///< File name index in the .BTF string table + uint32_t LineOff; ///< Line index in the .BTF string table + uint32_t LineCol; ///< Line num: line_col >> 10, + /// col num: line_col & 0x3ff +}; + +/// Specifying line info's in one section. +struct SecLineInfo { + uint32_t SecNameOff; ///< Section name index in the .BTF string tble + uint32_t NumLineInfo; ///< Number of line info's in this section +}; + +} // End namespace BTF. +} // End namespace llvm. + +#endif Index: include/llvm/BinaryFormat/BTF.def =================================================================== --- /dev/null +++ include/llvm/BinaryFormat/BTF.def @@ -0,0 +1,32 @@ +//===- llvm/BinaryFormat/BTF.def - BTF definitions --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Macros for BTF. +// +//===----------------------------------------------------------------------===// + +#if !defined(HANDLE_BTF_KIND) +#error "Missing macro definition of HANDLE_BTF_*" +#endif + +HANDLE_BTF_KIND(0, UNKN) +HANDLE_BTF_KIND(1, INT) +HANDLE_BTF_KIND(2, PTR) +HANDLE_BTF_KIND(3, ARRAY) +HANDLE_BTF_KIND(4, STRUCT) +HANDLE_BTF_KIND(5, UNION) +HANDLE_BTF_KIND(6, ENUM) +HANDLE_BTF_KIND(7, FWD) +HANDLE_BTF_KIND(8, TYPEDEF) +HANDLE_BTF_KIND(9, VOLATILE) +HANDLE_BTF_KIND(10, CONST) +HANDLE_BTF_KIND(11, RESTRICT) +HANDLE_BTF_KIND(12, FUNC) + +#undef HANDLE_BTF_KIND Index: include/llvm/MC/MCObjectFileInfo.h =================================================================== --- include/llvm/MC/MCObjectFileInfo.h +++ include/llvm/MC/MCObjectFileInfo.h @@ -207,6 +207,11 @@ MCSection *SXDataSection; MCSection *GFIDsSection; + /// @{ + MCSection *BTFSection; + MCSection *BTFExtSection; + /// @} + public: void InitMCObjectFileInfo(const Triple &TT, bool PIC, MCContext &ctx, bool LargeCodeModel = false); @@ -372,6 +377,10 @@ return EHFrameSection; } + // BTF specific sections. + MCSection *getBTFSection() const { return BTFSection; } + MCSection *getBTFExtSection() const { return BTFExtSection; } + enum Environment { IsMachO, IsELF, IsCOFF, IsWasm }; Environment getObjectFileType() const { return Env; } Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -13,6 +13,7 @@ #include "llvm/CodeGen/AsmPrinter.h" #include "AsmPrinterHandler.h" +#include "BTFDebug.h" #include "CodeViewDebug.h" #include "DwarfDebug.h" #include "DwarfException.h" @@ -138,6 +139,8 @@ static const char *const CodeViewLineTablesGroupName = "linetables"; static const char *const CodeViewLineTablesGroupDescription = "CodeView Line Tables"; +static const char *const BTFGroupName = "BTF"; +static const char *const BTFGroupDescription = "BTF Emission"; STATISTIC(EmittedInsts, "Number of machine instrs printed"); @@ -309,6 +312,12 @@ Handlers.push_back(HandlerInfo(DD, DbgTimerName, DbgTimerDescription, DWARFGroupName, DWARFGroupDescription)); } + const Triple &TT = TM.getTargetTriple(); + if (TT.getArch() == Triple::bpfel || TT.getArch() == Triple::bpfeb) { + Handlers.push_back(HandlerInfo(new BTFDebug(this), + DbgTimerName, DbgTimerDescription, + BTFGroupName, BTFGroupDescription)); + } } switch (MAI->getExceptionHandlingType()) { Index: lib/CodeGen/AsmPrinter/BTFDebug.h =================================================================== --- /dev/null +++ lib/CodeGen/AsmPrinter/BTFDebug.h @@ -0,0 +1,258 @@ +//===- llvm/lib/CodeGen/AsmPrinter/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_CODEGEN_ASMPRINTER_BTFDEBUG_H +#define LLVM_LIB_CODEGEN_ASMPRINTER_BTFDEBUG_H + +#include "DbgEntityHistoryCalculator.h" +#include "DebugHandlerBase.h" +#include "llvm/BinaryFormat/BTF.h" +#include + +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; } + virtual uint32_t getSize() { return BTF::CommonTypeSize; } + virtual void completeData(BTFDebug &BDebug) {} + virtual void emitData(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 completeData(BTFDebug &BDebug); + void emitData(MCStreamer &OS); +}; + +/// Handle struct or union forward declaration. +class BTFTypeFwd : public BTFTypeBase { + StringRef Name; + +public: + BTFTypeFwd(StringRef Name); + void completeData(BTFDebug &BDebug); + void emitData(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 completeData(BTFDebug &BDebug); + void emitData(MCStreamer &OS); +}; + +/// Handle enumerate type. +class BTFTypeEnum : public BTFTypeBase { + const DICompositeType *ETy; + std::vector EnumValues; + +public: + BTFTypeEnum(const DICompositeType *ETy, uint32_t VLen); + uint32_t getSize() { + return BTFTypeBase::getSize() + EnumValues.size() * BTF::BTFEnumSize; + } + void completeData(BTFDebug &BDebug); + void emitData(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 completeData(BTFDebug &BDebug); + void emitData(MCStreamer &OS); +}; + +/// Handle struct/union type. +class BTFTypeStruct : public BTFTypeBase { + const DICompositeType *STy; + std::vector Members; + +public: + BTFTypeStruct(const DICompositeType *STy, bool IsStruct, uint32_t Vlen); + uint32_t getSize() { + return BTFTypeBase::getSize() + Members.size() * BTF::BTFMemberSize; + } + void completeData(BTFDebug &BDebug); + void emitData(MCStreamer &OS); +}; + +/// Handle subprogram and function pointer. +class BTFTypeFunc : public BTFTypeBase { + const DISubroutineType *STy; + StringRef Name; + std::map FuncArgNames; + std::vector Parameters; + +public: + BTFTypeFunc(const DISubroutineType *STy, StringRef FuncName, uint32_t VLen, + const std::map &FuncArgNames); + uint32_t getSize() { + return BTFTypeBase::getSize() + Parameters.size() * BTF::BTFParamSize; + } + void completeData(BTFDebug &BDebug); + void emitData(MCStreamer &OS); +}; + +/// String table. +class BTFStringTable { + size_t Size; ///< Total size in bytes + std::map OffsetToIdMap; + std::vector Table; + +public: + BTFStringTable() : Size(0) {} + size_t getSize() { return Size; } + std::vector &getTable() { return Table; } + size_t addString(std::string S) { + // Check whether the string already exists. + for (auto &OffsetM : OffsetToIdMap) { + if (Table[OffsetM.second] == S) + return OffsetM.first; + } + // Not find, add to the string table. + size_t Offset = Size; + OffsetToIdMap[Offset] = Table.size(); + Table.push_back(S); + Size += S.size() + 1; + return Offset; + } +}; + +/// Represent one func and its type id. +struct BTFFuncInfo { + const MCSymbol *Label; ///< Func MCSymbol + unsigned int TypeId; ///< Type id referring to .BTF type section +}; + +/// Represent one line info. +struct BTFLineInfo { + MCSymbol *Label; ///< MCSymbol identifying insn for the lineinfo + unsigned int FileNameOff; ///< file name offset in the .BTF string table + unsigned int LineOff; ///< line offset in the .BTF string table + unsigned int LineNum; ///< the line number + unsigned int ColumnNum; ///< the column number +}; + +/// Collect and emit BTF information. +class BTFDebug : public DebugHandlerBase { + MCStreamer &OS; + bool SkipInstruction; + uint32_t SecNameOff; + uint32_t ArrayIndexTypeId; + BTFStringTable StringTable; + std::vector> TypeEntries; + std::map DIToIdMap; + std::map BitFieldTypeMap; + std::map> FuncInfoTable; + std::map> LineInfoTable; + std::map> FileContent; + + using InlinedEntity = DbgValueHistoryMap::InlinedEntity; + + // Add types to TypeEntries. + void addType(std::unique_ptr TypeEntry, const DIType *Ty); + uint32_t addType(std::unique_ptr TypeEntry); + + // IR type visiting functions. + void visitTypeEntry(const DIType *Ty); + void visitBasicType(const DIBasicType *BTy); + void visitSubroutineType(const DISubroutineType *STy, StringRef Name, + const std::map &FuncArgNames, + uint32_t &TypeId); + void visitFwdDeclType(const DICompositeType *CTy); + 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); + + StringRef populateFileContent(const DISubprogram *SP); + void addLineInfo(const DISubprogram *SP, MCSymbol *Label, uint32_t Line, + uint32_t Column); + + void emitCommonHeader(); + void emitBTFSection(); + void emitBTFExtSection(); + +protected: + /// Gather pre-function debug information. + void beginFunctionImpl(const MachineFunction *MF) override; + + void endFunctionImpl(const MachineFunction *MF) override; + +public: + BTFDebug(AsmPrinter *AP); + uint32_t getArrayIndexType() { + assert(ArrayIndexTypeId); + return ArrayIndexTypeId; + } + size_t addString(std::string S) { return StringTable.addString(S); } + uint32_t getTypeIndex(const DIType *Ty) { + assert(Ty && "Invalid null Type"); + assert(DIToIdMap.find(Ty) != DIToIdMap.end() && + "DIType not added in the BDIToIdMap"); + return DIToIdMap[Ty]; + } + uint32_t getBitFieldTypeIndex(const DIDerivedType *Ty) { + assert(Ty && "Invalid null Type"); + assert(BitFieldTypeMap.find(Ty) != BitFieldTypeMap.end() && + "DIDerivedType not added in the BitFieldTypeMap"); + return BitFieldTypeMap[Ty]; + } + + void setSymbolSize(const MCSymbol *Symbol, uint64_t Size) override {} + + /// Process beginning of an instruction. + void beginInstruction(const MachineInstr *MI) override; + + /// Emit the BTF sections. + void endModule() override; +}; + +} // end namespace llvm + +#endif // LLVM_LIB_CODEGEN_ASMPRINTER_BTFDEBUG_H Index: lib/CodeGen/AsmPrinter/BTFDebug.cpp =================================================================== --- /dev/null +++ lib/CodeGen/AsmPrinter/BTFDebug.cpp @@ -0,0 +1,663 @@ +//===- llvm/lib/CodeGen/AsmPrinter/BTFDebug.cpp ---------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains support for writing BTF debug info. +// +//===----------------------------------------------------------------------===// + +#include "BTFDebug.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCStreamer.h" +#include +#include + +using namespace llvm; + +static const char *BTFKindStr[] = { +#define HANDLE_BTF_KIND(ID, NAME) "BTF_KIND_" #NAME, +#include "llvm/BinaryFormat/BTF.def" +}; + +void BTFTypeBase::emitData(MCStreamer &OS) { + OS.AddComment(std::string(BTFKindStr[Kind]) + "(id = " + std::to_string(Id) + + ")"); + OS.EmitIntValue(BTFType.NameOff, 4); + OS.AddComment("0x" + Twine::utohexstr(BTFType.Info)); + OS.EmitIntValue(BTFType.Info, 4); + OS.EmitIntValue(BTFType.Size, 4); +} + +BTFTypeDerived::BTFTypeDerived(const DIDerivedType *DTy, unsigned Tag) + : DTy(DTy) { + switch (Tag) { + case dwarf::DW_TAG_pointer_type: + Kind = BTF::BTF_KIND_PTR; + break; + case dwarf::DW_TAG_const_type: + Kind = BTF::BTF_KIND_CONST; + break; + case dwarf::DW_TAG_volatile_type: + Kind = BTF::BTF_KIND_VOLATILE; + break; + case dwarf::DW_TAG_typedef: + Kind = BTF::BTF_KIND_TYPEDEF; + break; + case dwarf::DW_TAG_restrict_type: + Kind = BTF::BTF_KIND_RESTRICT; + break; + default: + llvm_unreachable("Unknown DIDerivedType Tag"); + } + BTFType.Info = Kind << 24; +} + +void BTFTypeDerived::completeData(BTFDebug &BDebug) { + BTFType.NameOff = BDebug.addString(DTy->getName()); + + const DIType *ResolvedType = DTy->getBaseType().resolve(); + if (!ResolvedType) { + assert((Kind == BTF::BTF_KIND_PTR || Kind == BTF::BTF_KIND_CONST || + Kind == BTF::BTF_KIND_VOLATILE) && + "Invalid null basetype"); + BTFType.Type = 0; // Pointer to (const) (volatile) void + } else { + BTFType.Type = BDebug.getTypeIndex(ResolvedType); + } +} + +void BTFTypeDerived::emitData(MCStreamer &OS) { BTFTypeBase::emitData(OS); } + +BTFTypeFwd::BTFTypeFwd(StringRef Name) : Name(Name) { + Kind = BTF::BTF_KIND_FWD; + BTFType.Info = Kind << 24; + BTFType.Type = 0; +} + +void BTFTypeFwd::completeData(BTFDebug &BDebug) { + BTFType.NameOff = BDebug.addString(Name); +} + +void BTFTypeFwd::emitData(MCStreamer &OS) { BTFTypeBase::emitData(OS); } + +BTFTypeInt::BTFTypeInt(uint32_t Encoding, uint32_t SizeInBits, + uint32_t OffsetInBits, StringRef TypeName) + : Name(TypeName) { + uint8_t BTFEncoding; + switch (Encoding) { + case dwarf::DW_ATE_boolean: + BTFEncoding = BTF::INT_BOOL; + break; + case dwarf::DW_ATE_signed: + BTFEncoding = BTF::INT_SIGNED; + break; + case dwarf::DW_ATE_signed_char: + BTFEncoding = BTF::INT_SIGNED | BTF::INT_CHAR; + break; + case dwarf::DW_ATE_unsigned: + BTFEncoding = 0; + break; + case dwarf::DW_ATE_unsigned_char: + BTFEncoding = BTF::INT_CHAR; + break; + default: + llvm_unreachable("Unknown BTFTypeInt Encoding"); + } + + Kind = BTF::BTF_KIND_INT; + BTFType.Info = Kind << 24; + BTFType.Size = roundupToBytes(SizeInBits); + IntVal = (BTFEncoding << 24) | OffsetInBits << 16 | SizeInBits; +} + +void BTFTypeInt::completeData(BTFDebug &BDebug) { + BTFType.NameOff = BDebug.addString(Name); +} + +void BTFTypeInt::emitData(MCStreamer &OS) { + BTFTypeBase::emitData(OS); + OS.AddComment("0x" + Twine::utohexstr(IntVal)); + OS.EmitIntValue(IntVal, 4); +} + +BTFTypeEnum::BTFTypeEnum(const DICompositeType *ETy, uint32_t VLen) : ETy(ETy) { + Kind = BTF::BTF_KIND_ENUM; + BTFType.Info = Kind << 24 | VLen; + BTFType.Size = roundupToBytes(ETy->getSizeInBits()); +} + +void BTFTypeEnum::completeData(BTFDebug &BDebug) { + BTFType.NameOff = BDebug.addString(ETy->getName()); + + DINodeArray Elements = ETy->getElements(); + for (const auto Element : Elements) { + auto *Enum = dyn_cast_or_null(Element); + assert(Enum && "Invalid null DIEnumerator"); + + struct BTF::BTFEnum BTFEnum; + BTFEnum.NameOff = BDebug.addString(Enum->getName()); + BTFEnum.Val = static_cast(Enum->getValue()); + EnumValues.push_back(BTFEnum); + } +} + +void BTFTypeEnum::emitData(MCStreamer &OS) { + BTFTypeBase::emitData(OS); + for (const auto &Enum : EnumValues) { + OS.EmitIntValue(Enum.NameOff, 4); + OS.EmitIntValue(Enum.Val, 4); + } +} + +BTFTypeArray::BTFTypeArray(const DICompositeType *ATy) : ATy(ATy) { + Kind = BTF::BTF_KIND_ARRAY; + BTFType.Info = Kind << 24; +} + +void BTFTypeArray::completeData(BTFDebug &BDebug) { + BTFType.NameOff = BDebug.addString(ATy->getName()); + BTFType.Size = 0; + + auto *BaseType = ATy->getBaseType().resolve(); + ArrayInfo.ElemType = BDebug.getTypeIndex(BaseType); + ArrayInfo.IndexType = BDebug.getArrayIndexType(); + + uint64_t ArraySizeInBits = ATy->getSizeInBits(); + if (!ArraySizeInBits) { + ArrayInfo.Nelems = 0; + } else { + // Get the array element type size. + uint32_t BaseTypeSize = BaseType->getSizeInBits(); + while (!BaseTypeSize) { + auto *DDTy = dyn_cast(BaseType); + assert(DDTy); + BaseType = DDTy->getBaseType().resolve(); + assert(BaseType); + BaseTypeSize = BaseType->getSizeInBits(); + } + ArrayInfo.Nelems = ATy->getSizeInBits() / BaseTypeSize; + } +} + +void BTFTypeArray::emitData(MCStreamer &OS) { + BTFTypeBase::emitData(OS); + OS.EmitIntValue(ArrayInfo.ElemType, 4); + OS.EmitIntValue(ArrayInfo.IndexType, 4); + OS.EmitIntValue(ArrayInfo.Nelems, 4); +} + +BTFTypeStruct::BTFTypeStruct(const DICompositeType *STy, bool IsStruct, + uint32_t Vlen) + : STy(STy) { + Kind = IsStruct ? BTF::BTF_KIND_STRUCT : BTF::BTF_KIND_UNION; + BTFType.Size = roundupToBytes(STy->getSizeInBits()); + BTFType.Info = (Kind << 24) | Vlen; +} + +void BTFTypeStruct::completeData(BTFDebug &BDebug) { + BTFType.NameOff = BDebug.addString(STy->getName()); + + const DINodeArray Elements = STy->getElements(); + for (const auto *Element : Elements) { + struct BTF::BTFMember BTFMember; + auto *DDTy = dyn_cast(Element); + + BTFMember.NameOff = BDebug.addString(DDTy->getName()); + BTFMember.Offset = DDTy->getOffsetInBits(); + if (DDTy->isBitField()) + BTFMember.Type = BDebug.getBitFieldTypeIndex(DDTy); + else + BTFMember.Type = BDebug.getTypeIndex(DDTy->getBaseType().resolve()); + Members.push_back(BTFMember); + } +} + +void BTFTypeStruct::emitData(MCStreamer &OS) { + BTFTypeBase::emitData(OS); + for (const auto &Member : Members) { + OS.EmitIntValue(Member.NameOff, 4); + OS.EmitIntValue(Member.Type, 4); + OS.EmitIntValue(Member.Offset, 4); + } +} + +BTFTypeFunc::BTFTypeFunc(const DISubroutineType *STy, StringRef FuncName, + uint32_t VLen, + const std::map &FuncArgNames) + : STy(STy), Name(FuncName), FuncArgNames(FuncArgNames) { + Kind = BTF::BTF_KIND_FUNC; + BTFType.Info = (Kind << 24) | VLen; +} + +void BTFTypeFunc::completeData(BTFDebug &BDebug) { + DITypeRefArray Elements = STy->getTypeArray(); + auto RetType = Elements[0].resolve(); + BTFType.Type = RetType ? BDebug.getTypeIndex(RetType) : 0; + BTFType.NameOff = BDebug.addString(Name); + + for (unsigned I = 1, N = Elements.size(); I < N; ++I) { + struct BTF::BTFParam Param; + auto Element = Elements[I].resolve(); + if (Element) { + Param.NameOff = BDebug.addString(FuncArgNames[I]); + Param.Type = BDebug.getTypeIndex(Element); + } else { + Param.NameOff = 0; + Param.Type = 0; + } + Parameters.push_back(Param); + } +} + +void BTFTypeFunc::emitData(MCStreamer &OS) { + BTFTypeBase::emitData(OS); + for (const auto &Param : Parameters) { + OS.EmitIntValue(Param.NameOff, 4); + OS.EmitIntValue(Param.Type, 4); + } +} + +BTFDebug::BTFDebug(AsmPrinter *AP) + : DebugHandlerBase(AP), OS(*Asm->OutStreamer), SkipInstruction(false), + SecNameOff(0), ArrayIndexTypeId(0) { + addString("\0"); +} + +void BTFDebug::addType(std::unique_ptr TypeEntry, + const DIType *Ty) { + TypeEntry->setId(TypeEntries.size() + 1); + DIToIdMap[Ty] = TypeEntry->getId(); + TypeEntries.push_back(std::move(TypeEntry)); +} + +uint32_t BTFDebug::addType(std::unique_ptr TypeEntry) { + TypeEntry->setId(TypeEntries.size() + 1); + uint32_t Id = TypeEntry->getId(); + TypeEntries.push_back(std::move(TypeEntry)); + return Id; +} + +void BTFDebug::visitBasicType(const DIBasicType *BTy) { + 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) + return; + + auto TypeEntry = llvm::make_unique( + Encoding, BTy->getSizeInBits(), BTy->getOffsetInBits(), BTy->getName()); + addType(std::move(TypeEntry), BTy); +} + +void BTFDebug::visitSubroutineType( + const DISubroutineType *STy, StringRef Name, + const std::map &FuncArgNames, uint32_t &TypeId) { + DITypeRefArray Elements = STy->getTypeArray(); + uint32_t VLen = Elements.size() - 1; + if (VLen > BTF::MAX_VLEN) + return; + + auto TypeEntry = + llvm::make_unique(STy, Name, VLen, FuncArgNames); + if (Name.size()) + TypeId = addType(std::move(TypeEntry)); // For subprogram + else + addType(std::move(TypeEntry), STy); // For func ptr + + for (const auto Element : Elements) { + visitTypeEntry(Element.resolve()); + } +} + +void BTFDebug::visitStructType(const DICompositeType *CTy, bool IsStruct) { + const DINodeArray Elements = CTy->getElements(); + uint32_t VLen = Elements.size(); + if (VLen > BTF::MAX_VLEN) + return; + + auto TypeEntry = llvm::make_unique(CTy, IsStruct, VLen); + addType(std::move(TypeEntry), CTy); + + for (const auto *Element : Elements) { + auto *DDTy = dyn_cast(Element); + assert(DDTy && "Invalid structure/union member type"); + visitTypeEntry(DDTy); + } +} + +void BTFDebug::visitArrayType(const DICompositeType *CTy) { + auto TypeEntry = llvm::make_unique(CTy); + addType(std::move(TypeEntry), CTy); + + // Create an array index type if there is none. + if (!ArrayIndexTypeId) { + auto TypeEntry = llvm::make_unique(dwarf::DW_ATE_unsigned, 32, + 0, "__ARRAY_SIZE_TYPE__"); + ArrayIndexTypeId = addType(std::move(TypeEntry)); + } + + visitTypeEntry(CTy->getBaseType().resolve()); +} + +void BTFDebug::visitEnumType(const DICompositeType *CTy) { + DINodeArray Elements = CTy->getElements(); + uint32_t VLen = Elements.size(); + if (VLen > BTF::MAX_VLEN) + return; + + auto TypeEntry = llvm::make_unique(CTy, VLen); + addType(std::move(TypeEntry), CTy); + // No need to visit base type as BTF does not encode it. +} + +void BTFDebug::visitFwdDeclType(const DICompositeType *CTy) { + auto TypeEntry = llvm::make_unique(CTy->getName()); + addType(std::move(TypeEntry), CTy); +} + +void BTFDebug::visitCompositeType(const DICompositeType *CTy) { + auto Tag = CTy->getTag(); + if (Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) { + if (CTy->isForwardDecl()) + visitFwdDeclType(CTy); + else + visitStructType(CTy, Tag == dwarf::DW_TAG_structure_type); + } else if (Tag == dwarf::DW_TAG_array_type) + visitArrayType(CTy); + else if (Tag == dwarf::DW_TAG_enumeration_type) + visitEnumType(CTy); +} + +void BTFDebug::visitDerivedType(const DIDerivedType *DTy) { + unsigned Tag = DTy->getTag(); + + 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(DTy, Tag); + addType(std::move(TypeEntry), DTy); + } else if (Tag != dwarf::DW_TAG_member) { + return; + } else { + if (DTy->isBitField()) { + const DIType *ResolvedTy = DTy->getBaseType().resolve(); + + while (ResolvedTy) { + if (const auto *DerivedTy = dyn_cast(ResolvedTy)) { + ResolvedTy = DerivedTy->getBaseType().resolve(); + } else if (const auto *CompositeTy = + dyn_cast(ResolvedTy)) { + assert(CompositeTy->getTag() == dwarf::DW_TAG_enumeration_type && + "Invalid member composite type"); + ResolvedTy = CompositeTy->getBaseType().resolve(); + } else + break; + } + + const DIBasicType *BaseTy = dyn_cast(ResolvedTy); + assert(BaseTy && "Incorrect bitfield member basetype"); + auto TypeEntry = llvm::make_unique( + BaseTy->getEncoding(), DTy->getSizeInBits(), 0, BaseTy->getName()); + BitFieldTypeMap[DTy] = addType(std::move(TypeEntry)); + return; + } + } + + visitTypeEntry(DTy->getBaseType().resolve()); +} + +void BTFDebug::visitTypeEntry(const DIType *Ty) { + if (!Ty || DIToIdMap.find(Ty) != DIToIdMap.end()) + return; + + uint32_t TypeId; + if (const auto *BTy = dyn_cast(Ty)) + visitBasicType(BTy); + else if (const auto *STy = dyn_cast(Ty)) + visitSubroutineType(STy, StringRef(), std::map(), + TypeId); + else if (const auto *CTy = dyn_cast(Ty)) + visitCompositeType(CTy); + else if (const auto *DTy = dyn_cast(Ty)) + visitDerivedType(DTy); + else + llvm_unreachable("Unknown DIType"); +} + +StringRef BTFDebug::populateFileContent(const DISubprogram *SP) { + auto File = SP->getFile(); + std::string FileName; + + if (File->getDirectory().size()) + FileName = File->getDirectory().str() + "/" + File->getFilename().str(); + else + FileName = File->getFilename(); + + if (FileContent.find(FileName) != FileContent.end()) + return FileName; + + std::vector Content; + std::string Line; + Content.push_back(Line); // Line 0 for empty string + + auto Source = File->getSource(); + if (Source) { + std::istringstream InputString(Source.getValue()); + while (std::getline(InputString, Line)) + Content.push_back(Line); + } else { + std::ifstream InputFile(FileName); + while (std::getline(InputFile, Line)) + Content.push_back(Line); + } + + FileContent[FileName] = Content; + return FileName; +} + +void BTFDebug::addLineInfo(const DISubprogram *SP, MCSymbol *Label, + uint32_t Line, uint32_t Column) { + std::string FileName = populateFileContent(SP); + BTFLineInfo LineInfo; + + LineInfo.Label = Label; + LineInfo.FileNameOff = addString(FileName); + if (Line < FileContent[FileName].size()) + LineInfo.LineOff = addString(FileContent[FileName][Line]); + else + LineInfo.LineOff = 0; + LineInfo.LineNum = Line; + LineInfo.ColumnNum = Column; + LineInfoTable[SecNameOff].push_back(LineInfo); +} + +void BTFDebug::emitCommonHeader() { + OS.AddComment("0x" + Twine::utohexstr(BTF::MAGIC)); + OS.EmitIntValue(BTF::MAGIC, 2); + OS.EmitIntValue(BTF::VERSION, 1); + OS.EmitIntValue(0, 1); +} + +void BTFDebug::emitBTFSection() { + MCContext &context = OS.getContext(); + OS.SwitchSection(context.getObjectFileInfo()->getBTFSection()); + + // Emit header. + emitCommonHeader(); + OS.EmitIntValue(BTF::HeaderSize, 4); + + uint32_t TypeLen = 0, StrLen; + for (const auto &TypeEntry : TypeEntries) + TypeLen += TypeEntry->getSize(); + StrLen = StringTable.getSize(); + + OS.EmitIntValue(0, 4); + OS.EmitIntValue(TypeLen, 4); + OS.EmitIntValue(TypeLen, 4); + OS.EmitIntValue(StrLen, 4); + + // Emit type table. + for (const auto &TypeEntry : TypeEntries) + TypeEntry->emitData(OS); + + // Emit string table. + uint32_t StringOffset = 0; + for (const auto &S : StringTable.getTable()) { + OS.AddComment("string offset=" + std::to_string(StringOffset)); + OS.EmitBytes(S); + OS.EmitBytes(StringRef("\0", 1)); + StringOffset += S.size() + 1; + } +} + +void BTFDebug::emitBTFExtSection() { + MCContext &context = OS.getContext(); + OS.SwitchSection(context.getObjectFileInfo()->getBTFExtSection()); + + // Emit header. + emitCommonHeader(); + OS.EmitIntValue(BTF::ExtHeaderSize, 4); + + uint32_t FuncLen = 0, LineLen = 0; + for (const auto &FuncSec : FuncInfoTable) { + FuncLen += BTF::SecFuncInfoSize; + FuncLen += FuncSec.second.size() * BTF::BPFFuncInfoSize; + } + for (const auto &LineSec : LineInfoTable) { + LineLen += BTF::SecLineInfoSize; + LineLen += LineSec.second.size() * BTF::BPFLineInfoSize; + } + + OS.EmitIntValue(0, 4); + OS.EmitIntValue(FuncLen, 4); + OS.EmitIntValue(FuncLen, 4); + OS.EmitIntValue(LineLen, 4); + + // Emit func_info table. + for (const auto &FuncSec : FuncInfoTable) { + OS.AddComment("FuncInfo section string offset=" + + std::to_string(FuncSec.first)); + OS.EmitIntValue(FuncSec.first, 4); + OS.EmitIntValue(FuncSec.second.size(), 4); + for (const auto &FuncInfo : FuncSec.second) { + Asm->EmitLabelReference(FuncInfo.Label, 4); + OS.EmitIntValue(FuncInfo.TypeId, 4); + } + } + + // Emit line_info table. + for (const auto &LineSec : LineInfoTable) { + OS.AddComment("LineInfo section string offset=" + + std::to_string(LineSec.first)); + OS.EmitIntValue(LineSec.first, 4); + OS.EmitIntValue(LineSec.second.size(), 4); + for (const auto &LineInfo : LineSec.second) { + Asm->EmitLabelReference(LineInfo.Label, 4); + OS.EmitIntValue(LineInfo.FileNameOff, 4); + OS.EmitIntValue(LineInfo.LineOff, 4); + OS.AddComment("Line " + std::to_string(LineInfo.LineNum) + " Col " + + std::to_string(LineInfo.ColumnNum)); + OS.EmitIntValue(LineInfo.LineNum << 10 | LineInfo.ColumnNum, 4); + } + } +} + +void BTFDebug::beginFunctionImpl(const MachineFunction *MF) { + auto *SP = MF->getFunction().getSubprogram(); + auto *Unit = SP->getUnit(); + + if (Unit->getEmissionKind() == DICompileUnit::NoDebug) { + SkipInstruction = true; + return; + } + SkipInstruction = false; + + // Collect all types locally referenced in this function. + std::map FuncArgNames; + for (const auto &I : DbgValues) { + InlinedEntity IV = I.first; + const DILocalVariable *DIVar = cast(IV.first); + visitTypeEntry(DIVar->getType().resolve()); + + // Collect function arguments for subprogram func type. + uint32_t Arg = DIVar->getArg(); + if (Arg) + FuncArgNames[Arg] = DIVar->getName(); + } + + // Construct subprogram func type. + uint32_t TypeId; + visitSubroutineType(SP->getType(), SP->getName(), FuncArgNames, TypeId); + + // Add funcinfo and emit the first lineinfo for the function. + MCSymbol *FuncLabel = Asm->getFunctionBegin(); + BTFFuncInfo FuncInfo; + FuncInfo.Label = FuncLabel; + FuncInfo.TypeId = TypeId; + if (FuncLabel->isInSection()) { + MCSection &Section = FuncLabel->getSection(); + MCSectionELF *SectionELF = dyn_cast(&Section); + assert(SectionELF && "Null section for Function Label"); + SecNameOff = addString(SectionELF->getSectionName()); + } else { + SecNameOff = addString(".text"); + } + FuncInfoTable[SecNameOff].push_back(FuncInfo); + addLineInfo(SP, FuncLabel, SP->getLine(), 0); +} + +void BTFDebug::endFunctionImpl(const MachineFunction *MF) { + SkipInstruction = false; + SecNameOff = 0; +} + +void BTFDebug::beginInstruction(const MachineInstr *MI) { + DebugHandlerBase::beginInstruction(MI); + + if (SkipInstruction || MI->isMetaInstruction() || + MI->getFlag(MachineInstr::FrameSetup)) + return; + + const DebugLoc &DL = MI->getDebugLoc(); + if (!DL || PrevInstLoc == DL) + return; + + // Create a temporary label to remember the insn for lineinfo. + MCSymbol *LineSym = OS.getContext().createTempSymbol(); + OS.EmitLabel(LineSym); + + // Emit the lineinfo. + auto SP = DL.get()->getScope()->getSubprogram(); + addLineInfo(SP, LineSym, DL.getLine(), DL.getCol()); + + PrevInstLoc = DL; +} + +void BTFDebug::endModule() { + // Collect all types referenced by globals. + const Module *M = MMI->getModule(); + for (const DICompileUnit *CUNode : M->debug_compile_units()) { + for (const auto *GVE : CUNode->getGlobalVariables()) { + DIGlobalVariable *GV = GVE->getVariable(); + visitTypeEntry(GV->getType().resolve()); + } + } + + // Complete BTF type cross refereences. + for (const auto &TypeEntry : TypeEntries) + TypeEntry->completeData(*this); + + // Emit BTF sections. + emitBTFSection(); + emitBTFExtSection(); +} Index: lib/CodeGen/AsmPrinter/CMakeLists.txt =================================================================== --- lib/CodeGen/AsmPrinter/CMakeLists.txt +++ lib/CodeGen/AsmPrinter/CMakeLists.txt @@ -23,6 +23,7 @@ WinCFGuard.cpp WinException.cpp CodeViewDebug.cpp + BTFDebug.cpp DEPENDS intrinsics_gen Index: lib/CodeGen/AsmPrinter/DebugHandlerBase.h =================================================================== --- lib/CodeGen/AsmPrinter/DebugHandlerBase.h +++ lib/CodeGen/AsmPrinter/DebugHandlerBase.h @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // Common functionality for different debug information format backends. -// LLVM currently supports DWARF and CodeView. +// LLVM currently supports DWARF, CodeView and BTF. // //===----------------------------------------------------------------------===// Index: lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // Common functionality for different debug information format backends. -// LLVM currently supports DWARF and CodeView. +// LLVM currently supports DWARF, CodeView and BTF. // //===----------------------------------------------------------------------===// Index: lib/MC/MCObjectFileInfo.cpp =================================================================== --- lib/MC/MCObjectFileInfo.cpp +++ lib/MC/MCObjectFileInfo.cpp @@ -471,6 +471,9 @@ Ctx->getELFSection(".eh_frame", EHSectionType, EHSectionFlags); StackSizesSection = Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, 0); + + BTFSection = Ctx->getELFSection(".BTF", ELF::SHT_PROGBITS, 0); + BTFExtSection = Ctx->getELFSection(".BTF.ext", ELF::SHT_PROGBITS, 0); } void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) { Index: test/DebugInfo/BTF/array-1d-char.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/array-1d-char.ll @@ -0,0 +1,66 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; char a[10]; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global [10 x i8] zeroinitializer, align 1, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!10, !11, !12} +!llvm.ident = !{!13} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 1) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 21 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 50331656 # 0x3000008 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=21 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 80, elements: !8) +!7 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!8 = !{!9} +!9 = !DISubrange(count: 10) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} Index: test/DebugInfo/BTF/array-1d-int.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/array-1d-int.ll @@ -0,0 +1,66 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int a[10]; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global [10 x i32] zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!10, !11, !12} +!llvm.ident = !{!13} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 25 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 1) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 21 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=21 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 320, elements: !8) +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !{!9} +!9 = !DISubrange(count: 10) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} Index: test/DebugInfo/BTF/array-2d-int.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/array-2d-int.ll @@ -0,0 +1,66 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int a[10][10]; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global [10 x [10 x i32]] zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!10, !11, !12} +!llvm.ident = !{!13} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 56 +; CHECK-NEXT: .long 25 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 1) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 100 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 21 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=21 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 3200, elements: !8) +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !{!9, !9} +!9 = !DISubrange(count: 10) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} Index: test/DebugInfo/BTF/array-size-0.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/array-size-0.ll @@ -0,0 +1,68 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; struct t {}; +; struct t a[10]; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t = type {} + +@a = common dso_local local_unnamed_addr global [10 x %struct.t] zeroinitializer, align 1, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!10, !11, !12} +!llvm.ident = !{!13} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 52 +; CHECK-NEXT: .long 52 +; CHECK-NEXT: .long 23 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 1) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 21 # BTF_KIND_STRUCT(id = 3) +; CHECK-NEXT: .long 67108864 # 0x4000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 116 # string offset=21 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, elements: !8) +!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: !3, line: 1, elements: !4) +!8 = !{!9} +!9 = !DISubrange(count: 10) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} Index: test/DebugInfo/BTF/array-typedef.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/array-typedef.ll @@ -0,0 +1,80 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; typedef unsigned _int; +; typedef _int __int; +; __int a[10]; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global [10 x i32] zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!12, !13, !14} +!llvm.ident = !{!15} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 80 +; CHECK-NEXT: .long 80 +; CHECK-NEXT: .long 45 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 1) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 21 # BTF_KIND_TYPEDEF(id = 3) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 27 # BTF_KIND_TYPEDEF(id = 4) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 32 # BTF_KIND_INT(id = 5) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__int" # string offset=21 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "_int" # string offset=27 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "unsigned int" # string offset=32 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 3, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 320, elements: !10) +!7 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !3, line: 2, baseType: !8) +!8 = !DIDerivedType(tag: DW_TAG_typedef, name: "_int", file: !3, line: 1, baseType: !9) +!9 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!10 = !{!11} +!11 = !DISubrange(count: 10) +!12 = !{i32 2, !"Dwarf Version", i32 4} +!13 = !{i32 2, !"Debug Info Version", i32 3} +!14 = !{i32 1, !"wchar_size", i32 4} +!15 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} Index: test/DebugInfo/BTF/binary-format.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/binary-format.ll @@ -0,0 +1,64 @@ +; RUN: llc -march=bpfel -filetype=obj -o - %s | llvm-readelf -x ".BTF" -x ".BTF.ext" | FileCheck -check-prefixes=CHECK,CHECK-EL %s +; RUN: llc -march=bpfeb -filetype=obj -o - %s | llvm-readelf -x ".BTF" -x ".BTF.ext" | FileCheck -check-prefixes=CHECK,CHECK-EB %s + +; Source code: +; int f(int a) { return a; } +; Compilation flag: +; clang -target bpf -O2 -g -gdwarf-5 -gembed-source -S -emit-llvm t.c + +; Function Attrs: nounwind readnone +define dso_local i32 @f(i32 returned %a) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata i32 %a, metadata !12, metadata !DIExpression()), !dbg !13 + ret i32 %a, !dbg !14 +} + +; CHECK: '.BTF' +; CHECK-EL: 0x00000000 9feb0100 18000000 00000000 24000000 +; CHECK-EL: 0x00000010 24000000 33000000 2b000000 00000001 +; CHECK-EL: 0x00000020 04000000 20000001 2f000000 0100000c +; CHECK-EL: 0x00000030 01000000 31000000 01000000 002e7465 +; CHECK-EB: 0x00000000 eb9f0100 00000018 00000000 00000024 +; CHECK-EB: 0x00000010 00000024 00000033 0000002b 01000000 +; CHECK-EB: 0x00000020 00000004 01000020 0000002f 0c000001 +; CHECK-EB: 0x00000030 00000001 00000031 00000001 002e7465 +; CHECK: 0x00000040 7874002f 746d702f 742e6300 696e7420 +; CHECK: 0x00000050 6628696e 74206129 207b2072 65747572 +; CHECK: 0x00000060 6e20613b 207d0069 6e740066 006100 +; CHECK: '.BTF.ext' +; CHECK-EL: 0x00000000 9feb0100 18000000 00000000 10000000 +; CHECK-EL: 0x00000010 10000000 28000000 01000000 01000000 +; CHECK-EL: 0x00000020 00000000 02000000 01000000 02000000 +; CHECK-EL: 0x00000030 00000000 07000000 10000000 00040000 +; CHECK-EL: 0x00000040 08000000 07000000 10000000 10040000 +; CHECK-EB: 0x00000000 eb9f0100 00000018 00000000 00000010 +; CHECK-EB: 0x00000010 00000010 00000028 00000001 00000001 +; CHECK-EB: 0x00000020 00000000 00000002 00000001 00000002 +; CHECK-EB: 0x00000030 00000000 00000007 00000010 00000400 +; CHECK-EB: 0x00000040 00000008 00000007 00000010 00000410 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "1924f0d78deb326ceb76cd8e9f450775", source: "int f(int a) { return a; }\0A") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 5} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} +!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, isOptimized: true, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{!12} +!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 1, type: !10) +!13 = !DILocation(line: 1, column: 11, scope: !7) +!14 = !DILocation(line: 1, column: 16, scope: !7) Index: test/DebugInfo/BTF/char.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/char.ll @@ -0,0 +1,51 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; char a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i8 0, align 1, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 50331656 # 0x3000008 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "char" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/enum-basic.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/enum-basic.ll @@ -0,0 +1,60 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; enum { A = -1, B = 2 } a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i32 0, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # BTF_KIND_ENUM(id = 1) +; CHECK-NEXT: .long 100663298 # 0x6000002 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long -1 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .byte 65 # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 66 # string offset=3 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !5, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !10, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{!5} +!5 = !DICompositeType(tag: DW_TAG_enumeration_type, file: !3, line: 1, baseType: !6, size: 32, elements: !7) +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = !{!8, !9} +!8 = !DIEnumerator(name: "A", value: -1) +!9 = !DIEnumerator(name: "B", value: 2) +!10 = !{!0} +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/func-func-ptr.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/func-func-ptr.ll @@ -0,0 +1,106 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; void (*a)(void); +; struct t { void (*a)(void); } b; +; void f(void) { } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t = type { void ()* } + +@a = common dso_local local_unnamed_addr global void ()* null, align 8, !dbg !0 +@b = common dso_local local_unnamed_addr global %struct.t zeroinitializer, align 8, !dbg !6 + +; Function Attrs: norecurse nounwind readnone +define dso_local void @f() local_unnamed_addr #0 !dbg !18 { +entry: + ret void, !dbg !19 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 60 +; CHECK-NEXT: .long 60 +; CHECK-NEXT: .long 22 +; CHECK-NEXT: .long 16 # BTF_KIND_FUNC(id = 1) +; CHECK-NEXT: .long 201326592 # 0xc000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC(id = 3) +; CHECK-NEXT: .long 201326592 # 0xc000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 18 # BTF_KIND_STRUCT(id = 4) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 20 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii ".text" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/t.c" # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 102 # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 116 # string offset=18 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=20 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 1 # FuncInfo section string offset=1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 # LineInfo section string offset=1 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3072 # Line 3 Col 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3088 # Line 3 Col 16 + +attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!14, !15, !16} +!llvm.ident = !{!17} + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !11, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/tmp") +!4 = !{} +!5 = !{!0, !6} +!6 = !DIGlobalVariableExpression(var: !7, expr: !DIExpression()) +!7 = distinct !DIGlobalVariable(name: "b", scope: !2, file: !3, line: 2, type: !8, isLocal: false, isDefinition: true) +!8 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: !3, line: 2, size: 64, elements: !9) +!9 = !{!10} +!10 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !8, file: !3, line: 2, baseType: !11, size: 64) +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !12, size: 64) +!12 = !DISubroutineType(types: !13) +!13 = !{null} +!14 = !{i32 2, !"Dwarf Version", i32 4} +!15 = !{i32 2, !"Debug Info Version", i32 3} +!16 = !{i32 1, !"wchar_size", i32 4} +!17 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} +!18 = distinct !DISubprogram(name: "f", scope: !3, file: !3, line: 3, type: !12, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !2, retainedNodes: !4) +!19 = !DILocation(line: 3, column: 16, scope: !18) Index: test/DebugInfo/BTF/func-non-void.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/func-non-void.ll @@ -0,0 +1,93 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int f(int a) { return a; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +; Function Attrs: nounwind readnone +define dso_local i32 @f(i32 returned %a) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata i32 %a, metadata !12, metadata !DIExpression()), !dbg !13 + ret i32 %a, !dbg !14 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 16 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 20 # BTF_KIND_FUNC(id = 2) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 22 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii ".text" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/t.c" # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 102 # string offset=20 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=22 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 1 # FuncInfo section string offset=1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # LineInfo section string offset=1 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1024 # Line 1 Col 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1040 # Line 1 Col 16 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} +!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !11) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !10} +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{!12} +!12 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 1, type: !10) +!13 = !DILocation(line: 1, column: 11, scope: !7) +!14 = !DILocation(line: 1, column: 16, scope: !7) Index: test/DebugInfo/BTF/func-source.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/func-source.ll @@ -0,0 +1,79 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; void f(void) { } +; Compilation flag: +; clang -target bpf -O2 -g -gdwarf-5 -gembed-source -S -emit-llvm t.c +; +; This test embeds the source code in the IR, so the line info should have +; correct reference to the lines in the string table. + +; Function Attrs: norecurse nounwind readnone +define dso_local void @f() local_unnamed_addr #0 !dbg !7 { +entry: + ret void, !dbg !10 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 35 +; CHECK-NEXT: .long 33 # BTF_KIND_FUNC(id = 1) +; CHECK-NEXT: .long 201326592 # 0xc000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii ".text" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/t.c" # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "void f(void) { }" # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 102 # string offset=33 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 1 # FuncInfo section string offset=1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 # LineInfo section string offset=1 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 1024 # Line 1 Col 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 1040 # Line 1 Col 16 + +attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp", checksumkind: CSK_MD5, checksum: "978599fafe3a080b456e3d95a3710359", source: "void f(void) { }\0A") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 5} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} +!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, isOptimized: true, unit: !0, retainedNodes: !2) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !DILocation(line: 1, column: 16, scope: !7) Index: test/DebugInfo/BTF/func-typedef.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/func-typedef.ll @@ -0,0 +1,107 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; typedef int _int; +; typedef _int __int; +; __int f(__int a) { return a; } +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +; Function Attrs: nounwind readnone +define dso_local i32 @f(i32 returned %a) local_unnamed_addr #0 !dbg !7 { +entry: + call void @llvm.dbg.value(metadata i32 %a, metadata !14, metadata !DIExpression()), !dbg !15 + ret i32 %a, !dbg !16 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 60 +; CHECK-NEXT: .long 60 +; CHECK-NEXT: .long 35 +; CHECK-NEXT: .long 16 # BTF_KIND_TYPEDEF(id = 1) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 22 # BTF_KIND_TYPEDEF(id = 2) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 27 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 31 # BTF_KIND_FUNC(id = 4) +; CHECK-NEXT: .long 201326593 # 0xc000001 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 33 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii ".text" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/t.c" # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__int" # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "_int" # string offset=22 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=27 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 102 # string offset=31 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 97 # string offset=33 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 1 # FuncInfo section string offset=1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 1 # LineInfo section string offset=1 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3072 # Line 3 Col 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3092 # Line 3 Col 20 + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.value(metadata, metadata, metadata) #1 + +attributes #0 = { nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} +!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !13) +!8 = !DISubroutineType(types: !9) +!9 = !{!10, !10} +!10 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !1, line: 2, baseType: !11) +!11 = !DIDerivedType(tag: DW_TAG_typedef, name: "_int", file: !1, line: 1, baseType: !12) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !{!14} +!14 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !10) +!15 = !DILocation(line: 3, column: 15, scope: !7) +!16 = !DILocation(line: 3, column: 20, scope: !7) Index: test/DebugInfo/BTF/func-void.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/func-void.ll @@ -0,0 +1,74 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; void f(void) {} +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +; Function Attrs: norecurse nounwind readnone +define dso_local void @f() local_unnamed_addr #0 !dbg !7 { +entry: + ret void, !dbg !10 +} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 12 +; CHECK-NEXT: .long 18 +; CHECK-NEXT: .long 16 # BTF_KIND_FUNC(id = 1) +; CHECK-NEXT: .long 201326592 # 0xc000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii ".text" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "/tmp/t.c" # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 102 # string offset=16 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 1 # FuncInfo section string offset=1 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 1 # LineInfo section string offset=1 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long .Lfunc_begin0 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1024 # Line 1 Col 0 +; CHECK-NEXT: .long .Ltmp{{[0-9]+}} +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 1040 # Line 1 Col 16 + +attributes #0 = { norecurse nounwind readnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5} +!llvm.ident = !{!6} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None) +!1 = !DIFile(filename: "t.c", directory: "/tmp") +!2 = !{} +!3 = !{i32 2, !"Dwarf Version", i32 4} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 4} +!6 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} +!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !2) +!8 = !DISubroutineType(types: !9) +!9 = !{null} +!10 = !DILocation(line: 1, column: 16, scope: !7) Index: test/DebugInfo/BTF/fwd-no-define.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/fwd-no-define.ll @@ -0,0 +1,71 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; struct t1; +; struct t2 {struct t1 *p;} a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t2 = type { %struct.t1* } +%struct.t1 = type opaque + +@a = common dso_local local_unnamed_addr global %struct.t2 zeroinitializer, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 48 +; CHECK-NEXT: .long 9 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 6 # BTF_KIND_FWD(id = 3) +; CHECK-NEXT: .long 117440512 # 0x7000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "t2" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 112 # string offset=4 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "t1" # string offset=6 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t2", file: !3, line: 2, size: 64, elements: !7) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "p", scope: !6, file: !3, line: 2, baseType: !9, size: 64) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 64) +!10 = !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 1, flags: DIFlagFwdDecl) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/fwd-with-define.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/fwd-with-define.ll @@ -0,0 +1,64 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; struct t1; +; struct t1 {struct t1 *p;} a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t1 = type { %struct.t1* } + +@a = common dso_local local_unnamed_addr global %struct.t1 zeroinitializer, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!10, !11, !12} +!llvm.ident = !{!13} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "t1" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 112 # string offset=4 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 2, size: 64, elements: !7) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "p", scope: !6, file: !3, line: 2, baseType: !9, size: 64) +!9 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !6, size: 64) +!10 = !{i32 2, !"Dwarf Version", i32 4} +!11 = !{i32 2, !"Debug Info Version", i32 3} +!12 = !{i32 1, !"wchar_size", i32 4} +!13 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/int.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/int.ll @@ -0,0 +1,51 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i32 0, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/lit.local.cfg =================================================================== --- /dev/null +++ test/DebugInfo/BTF/lit.local.cfg @@ -0,0 +1,2 @@ +if not 'BPF' in config.root.targets: + config.unsupported = True Index: test/DebugInfo/BTF/longlong.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/longlong.ll @@ -0,0 +1,51 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; long long a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i64 0, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 15 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 16777280 # 0x1000040 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "long long int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "long long int", size: 64, encoding: DW_ATE_signed) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/ptr-const-void.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/ptr-const-void.ll @@ -0,0 +1,52 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; const void *a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@p = common dso_local local_unnamed_addr global i8* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!8, !9, !10} +!llvm.ident = !{!11} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_CONST(id = 2) +; CHECK-NEXT: .long 167772160 # 0xa000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DIDerivedType(tag: DW_TAG_const_type, baseType: null) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{i32 1, !"wchar_size", i32 4} +!11 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/ptr-func-1.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/ptr-func-1.ll @@ -0,0 +1,53 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; void (*a)(void); +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global void ()* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC(id = 2) +; CHECK-NEXT: .long 201326592 # 0xc000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DISubroutineType(types: !8) +!8 = !{null} +!9 = !{i32 2, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/ptr-func-2.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/ptr-func-2.ll @@ -0,0 +1,71 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int (*a)(int a, char b); +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i32 (i32, i8)* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 72 +; CHECK-NEXT: .long 72 +; CHECK-NEXT: .long 10 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC(id = 2) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .long 5 # BTF_KIND_INT(id = 4) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 50331656 # 0x3000008 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !9, !10} +!9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!10 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/ptr-func-3.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/ptr-func-3.ll @@ -0,0 +1,71 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; typedef int __int; +; __int (*a)(__int a, __int b); +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i32 (i32, i32)* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!11, !12, !13} +!llvm.ident = !{!14} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 68 +; CHECK-NEXT: .long 68 +; CHECK-NEXT: .long 11 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_FUNC(id = 2) +; CHECK-NEXT: .long 201326594 # 0xc000002 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 1 # BTF_KIND_TYPEDEF(id = 3) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 7 # BTF_KIND_INT(id = 4) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "__int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DISubroutineType(types: !8) +!8 = !{!9, !9, !9} +!9 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !3, line: 1, baseType: !10) +!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!11 = !{i32 2, !"Dwarf Version", i32 4} +!12 = !{i32 2, !"Debug Info Version", i32 3} +!13 = !{i32 1, !"wchar_size", i32 4} +!14 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/ptr-int.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/ptr-int.ll @@ -0,0 +1,56 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int *a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i32* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!8, !9, !10} +!llvm.ident = !{!11} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{i32 1, !"wchar_size", i32 4} +!11 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/ptr-void.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/ptr-void.ll @@ -0,0 +1,51 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; void *a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i8 0, align 1, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 50331656 # 0x3000008 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "char" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/ptr-volatile-const-void.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/ptr-volatile-const-void.ll @@ -0,0 +1,56 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; volatile const void *p; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@p = common dso_local local_unnamed_addr global i8* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 36 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_CONST(id = 2) +; CHECK-NEXT: .long 167772160 # 0xa000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 3) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !8) +!8 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: null) +!9 = !{i32 2, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/ptr-volatile-void.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/ptr-volatile-void.ll @@ -0,0 +1,52 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; volatile void *a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@p = common dso_local local_unnamed_addr global i8* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!8, !9, !10} +!llvm.ident = !{!11} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 1) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_VOLATILE(id = 2) +; CHECK-NEXT: .long 150994944 # 0x9000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!7 = !DIDerivedType(tag: DW_TAG_volatile_type, baseType: null) +!8 = !{i32 2, !"Dwarf Version", i32 4} +!9 = !{i32 2, !"Debug Info Version", i32 3} +!10 = !{i32 1, !"wchar_size", i32 4} +!11 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/restrict-ptr.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/restrict-ptr.ll @@ -0,0 +1,59 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; int * restrict p; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@p = common dso_local local_unnamed_addr global i32* null, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!9, !10, !11} +!llvm.ident = !{!12} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 40 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 # BTF_KIND_RESTRICT(id = 1) +; CHECK-NEXT: .long 184549376 # 0xb000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 # BTF_KIND_PTR(id = 2) +; CHECK-NEXT: .long 33554432 # 0x2000000 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIDerivedType(tag: DW_TAG_restrict_type, baseType: !7) +!7 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !8, size: 64) +!8 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!9 = !{i32 2, !"Dwarf Version", i32 4} +!10 = !{i32 2, !"Debug Info Version", i32 3} +!11 = !{i32 1, !"wchar_size", i32 4} +!12 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/short.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/short.ll @@ -0,0 +1,52 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; short a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + + +@a = common dso_local local_unnamed_addr global i16 0, align 2, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 16777232 # 0x1000010 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "short" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/struct-anon.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/struct-anon.ll @@ -0,0 +1,74 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; struct { struct {int m;}; } a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.anon = type { %struct.anon.0 } +%struct.anon.0 = type { i32 } + +@a = common dso_local local_unnamed_addr global %struct.anon zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!13, !14, !15} +!llvm.ident = !{!16} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 64 +; CHECK-NEXT: .long 64 +; CHECK-NEXT: .long 7 +; CHECK-NEXT: .long 0 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_STRUCT(id = 2) +; CHECK-NEXT: .long 67108865 # 0x4000001 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .byte 109 # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=3 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !3, line: 1, size: 32, elements: !7) +!7 = !{!8} +!8 = !DIDerivedType(tag: DW_TAG_member, scope: !6, file: !3, line: 1, baseType: !9, size: 32) +!9 = distinct !DICompositeType(tag: DW_TAG_structure_type, scope: !6, file: !3, line: 1, size: 32, elements: !10) +!10 = !{!11} +!11 = !DIDerivedType(tag: DW_TAG_member, name: "m", scope: !9, file: !3, line: 1, baseType: !12, size: 32) +!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!13 = !{i32 2, !"Dwarf Version", i32 4} +!14 = !{i32 2, !"Debug Info Version", i32 3} +!15 = !{i32 1, !"wchar_size", i32 4} +!16 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/struct-basic.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/struct-basic.ll @@ -0,0 +1,79 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; struct t {char m; int n;} a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t = type { i8, i32 } + +@a = common dso_local local_unnamed_addr global %struct.t zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!12, !13, !14} +!llvm.ident = !{!15} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 68 +; CHECK-NEXT: .long 68 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 7 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 50331656 # 0x3000008 +; CHECK-NEXT: .long 12 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .byte 116 # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 109 # string offset=3 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 110 # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=12 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: !3, line: 1, size: 64, elements: !7) +!7 = !{!8, !10} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "m", scope: !6, file: !3, line: 1, baseType: !9, size: 8) +!9 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "n", scope: !6, file: !3, line: 1, baseType: !11, size: 32, offset: 32) +!11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!12 = !{i32 2, !"Dwarf Version", i32 4} +!13 = !{i32 2, !"Debug Info Version", i32 3} +!14 = !{i32 1, !"wchar_size", i32 4} +!15 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/struct-bitfield-typedef.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/struct-bitfield-typedef.ll @@ -0,0 +1,91 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; typedef int _int; +; typedef _int __int; +; struct {char m:2; __int n:3; char p;} a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.anon = type { i8, i8, [2 x i8] } + +@a = common dso_local local_unnamed_addr global %struct.anon zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!15, !16, !17} +!llvm.ident = !{!18} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 96 +; CHECK-NEXT: .long 96 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 0 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 67108867 # 0x4000003 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 7 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 50331650 # 0x3000002 +; CHECK-NEXT: .long 12 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 16777219 # 0x1000003 +; CHECK-NEXT: .long 7 # BTF_KIND_INT(id = 4) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 50331656 # 0x3000008 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .byte 109 # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 110 # string offset=3 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 112 # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=12 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 3, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, file: !3, line: 3, size: 32, elements: !7) +!7 = !{!8, !10, !14} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "m", scope: !6, file: !3, line: 3, baseType: !9, size: 2, flags: DIFlagBitField, extraData: i64 0) +!9 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!10 = !DIDerivedType(tag: DW_TAG_member, name: "n", scope: !6, file: !3, line: 3, baseType: !11, size: 3, offset: 2, flags: DIFlagBitField, extraData: i64 0) +!11 = !DIDerivedType(tag: DW_TAG_typedef, name: "__int", file: !3, line: 2, baseType: !12) +!12 = !DIDerivedType(tag: DW_TAG_typedef, name: "_int", file: !3, line: 1, baseType: !13) +!13 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!14 = !DIDerivedType(tag: DW_TAG_member, name: "p", scope: !6, file: !3, line: 3, baseType: !9, size: 8, offset: 8) +!15 = !{i32 2, !"Dwarf Version", i32 4} +!16 = !{i32 2, !"Debug Info Version", i32 3} +!17 = !{i32 1, !"wchar_size", i32 4} +!18 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/struct-enum.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/struct-enum.ll @@ -0,0 +1,90 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; enum t1 { A , B }; +; struct t2 { enum t1 m:2; enum t1 n; } a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%struct.t2 = type { i8, i32 } + +@a = common dso_local local_unnamed_addr global %struct.t2 zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!15, !16, !17} +!llvm.ident = !{!18} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 80 +; CHECK-NEXT: .long 80 +; CHECK-NEXT: .long 28 +; CHECK-NEXT: .long 1 # BTF_KIND_STRUCT(id = 1) +; CHECK-NEXT: .long 67108866 # 0x4000002 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 32 +; CHECK-NEXT: .long 8 # BTF_KIND_INT(id = 2) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 2 # 0x2 +; CHECK-NEXT: .long 21 # BTF_KIND_ENUM(id = 3) +; CHECK-NEXT: .long 100663298 # 0x6000002 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 26 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "t2" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 109 # string offset=4 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 110 # string offset=6 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "unsigned int" # string offset=8 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "t1" # string offset=21 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 65 # string offset=24 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 66 # string offset=26 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 2, type: !11, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !10, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{!5} +!5 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "t1", file: !3, line: 1, baseType: !6, size: 32, elements: !7) +!6 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!7 = !{!8, !9} +!8 = !DIEnumerator(name: "A", value: 0, isUnsigned: true) +!9 = !DIEnumerator(name: "B", value: 1, isUnsigned: true) +!10 = !{!0} +!11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t2", file: !3, line: 2, size: 64, elements: !12) +!12 = !{!13, !14} +!13 = !DIDerivedType(tag: DW_TAG_member, name: "m", scope: !11, file: !3, line: 2, baseType: !5, size: 2, flags: DIFlagBitField, extraData: i64 0) +!14 = !DIDerivedType(tag: DW_TAG_member, name: "n", scope: !11, file: !3, line: 2, baseType: !5, size: 32, offset: 32) +!15 = !{i32 2, !"Dwarf Version", i32 4} +!16 = !{i32 2, !"Debug Info Version", i32 3} +!17 = !{i32 1, !"wchar_size", i32 4} +!18 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/uchar.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/uchar.ll @@ -0,0 +1,51 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; unsigned char a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i8 0, align 1, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 15 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 33554440 # 0x2000008 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "unsigned char" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "unsigned char", size: 8, encoding: DW_ATE_unsigned_char) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/uint.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/uint.ll @@ -0,0 +1,51 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; unsigned a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i32 0, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 14 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "unsigned int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/ulonglong.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/ulonglong.ll @@ -0,0 +1,51 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; unsigned long long a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i64 0, align 8, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 8 +; CHECK-NEXT: .long 64 # 0x40 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "long long unsigned int" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "long long unsigned int", size: 64, encoding: DW_ATE_unsigned) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"} Index: test/DebugInfo/BTF/union-array-typedef.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/union-array-typedef.ll @@ -0,0 +1,101 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; typedef int _int; +; union t {char m[4]; _int n;} a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +%union.t = type { i32 } + +@a = common dso_local local_unnamed_addr global %union.t zeroinitializer, align 4, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!16, !17, !18} +!llvm.ident = !{!19} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 120 +; CHECK-NEXT: .long 120 +; CHECK-NEXT: .long 41 +; CHECK-NEXT: .long 1 # BTF_KIND_UNION(id = 1) +; CHECK-NEXT: .long 83886082 # 0x5000002 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 5 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 # BTF_KIND_ARRAY(id = 2) +; CHECK-NEXT: .long 50331648 # 0x3000000 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 3 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 7 # BTF_KIND_INT(id = 3) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 32 # 0x20 +; CHECK-NEXT: .long 27 # BTF_KIND_INT(id = 4) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 1 +; CHECK-NEXT: .long 50331656 # 0x3000008 +; CHECK-NEXT: .long 32 # BTF_KIND_TYPEDEF(id = 5) +; CHECK-NEXT: .long 134217728 # 0x8000000 +; CHECK-NEXT: .long 6 +; CHECK-NEXT: .long 37 # BTF_KIND_INT(id = 6) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 4 +; CHECK-NEXT: .long 16777248 # 0x1000020 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .byte 116 # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 109 # string offset=3 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .byte 110 # string offset=5 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "__ARRAY_SIZE_TYPE__" # string offset=7 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "char" # string offset=27 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "_int" # string offset=32 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .ascii "int" # string offset=37 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "t", file: !3, line: 2, size: 32, elements: !7) +!7 = !{!8, !13} +!8 = !DIDerivedType(tag: DW_TAG_member, name: "m", scope: !6, file: !3, line: 2, baseType: !9, size: 32) +!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 32, elements: !11) +!10 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) +!11 = !{!12} +!12 = !DISubrange(count: 4) +!13 = !DIDerivedType(tag: DW_TAG_member, name: "n", scope: !6, file: !3, line: 2, baseType: !14, size: 32) +!14 = !DIDerivedType(tag: DW_TAG_typedef, name: "_int", file: !3, line: 1, baseType: !15) +!15 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!16 = !{i32 2, !"Dwarf Version", i32 4} +!17 = !{i32 2, !"Debug Info Version", i32 3} +!18 = !{i32 1, !"wchar_size", i32 4} +!19 = !{!"clang version 8.0.0 (trunk 345296) (llvm/trunk 345297)"} Index: test/DebugInfo/BTF/ushort.ll =================================================================== --- /dev/null +++ test/DebugInfo/BTF/ushort.ll @@ -0,0 +1,51 @@ +; RUN: llc -march=bpfel -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s +; RUN: llc -march=bpfeb -filetype=asm -o - %s | FileCheck -check-prefixes=CHECK %s + +; Source code: +; unsigned short a; +; Compilation flag: +; clang -target bpf -O2 -g -S -emit-llvm t.c + +@a = common dso_local local_unnamed_addr global i16 0, align 2, !dbg !0 + +!llvm.dbg.cu = !{!2} +!llvm.module.flags = !{!7, !8, !9} +!llvm.ident = !{!10} + +; CHECK: .section .BTF,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 16 +; CHECK-NEXT: .long 1 # BTF_KIND_INT(id = 1) +; CHECK-NEXT: .long 16777216 # 0x1000000 +; CHECK-NEXT: .long 2 +; CHECK-NEXT: .long 16 # 0x10 +; CHECK-NEXT: .byte 0 # string offset=0 +; CHECK-NEXT: .ascii "unsigned short" # string offset=1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .section .BTF.ext,"",@progbits +; CHECK-NEXT: .short 60319 # 0xeb9f +; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 0 +; CHECK-NEXT: .long 24 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 +; CHECK-NEXT: .long 0 + +!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) +!1 = distinct !DIGlobalVariable(name: "a", scope: !2, file: !3, line: 1, type: !6, isLocal: false, isDefinition: true) +!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None) +!3 = !DIFile(filename: "t.c", directory: "/home/yhs/tmp") +!4 = !{} +!5 = !{!0} +!6 = !DIBasicType(name: "unsigned short", size: 16, encoding: DW_ATE_unsigned) +!7 = !{i32 2, !"Dwarf Version", i32 4} +!8 = !{i32 2, !"Debug Info Version", i32 3} +!9 = !{i32 1, !"wchar_size", i32 4} +!10 = !{!"clang version 8.0.0 (trunk 344789) (llvm/trunk 344782)"}