diff options
Diffstat (limited to 'contrib/llvm/include/llvm/DebugInfo')
27 files changed, 1883 insertions, 34 deletions
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h new file mode 100644 index 0000000..7728120 --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeView.h @@ -0,0 +1,367 @@ +//===- CodeView.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_CODEVIEW_H +#define LLVM_DEBUGINFO_CODEVIEW_CODEVIEW_H + +#include <cinttypes> + +namespace llvm { +namespace codeview { + +enum class CallingConvention : uint8_t { + NearC = 0x00, // near right to left push, caller pops stack + FarC = 0x01, // far right to left push, caller pops stack + NearPascal = 0x02, // near left to right push, callee pops stack + FarPascal = 0x03, // far left to right push, callee pops stack + NearFast = 0x04, // near left to right push with regs, callee pops stack + FarFast = 0x05, // far left to right push with regs, callee pops stack + NearStdCall = 0x07, // near standard call + FarStdCall = 0x08, // far standard call + NearSysCall = 0x09, // near sys call + FarSysCall = 0x0a, // far sys call + ThisCall = 0x0b, // this call (this passed in register) + MipsCall = 0x0c, // Mips call + Generic = 0x0d, // Generic call sequence + AlphaCall = 0x0e, // Alpha call + PpcCall = 0x0f, // PPC call + SHCall = 0x10, // Hitachi SuperH call + ArmCall = 0x11, // ARM call + AM33Call = 0x12, // AM33 call + TriCall = 0x13, // TriCore Call + SH5Call = 0x14, // Hitachi SuperH-5 call + M32RCall = 0x15, // M32R Call + ClrCall = 0x16, // clr call + Inline = + 0x17, // Marker for routines always inlined and thus lacking a convention + NearVector = 0x18 // near left to right push with regs, callee pops stack +}; + +enum class ClassOptions : uint16_t { + None = 0x0000, + Packed = 0x0001, + HasConstructorOrDestructor = 0x0002, + HasOverloadedOperator = 0x0004, + Nested = 0x0008, + ContainsNestedClass = 0x0010, + HasOverloadedAssignmentOperator = 0x0020, + HasConversionOperator = 0x0040, + ForwardReference = 0x0080, + Scoped = 0x0100, + HasUniqueName = 0x0200, + Sealed = 0x0400, + Intrinsic = 0x2000 +}; + +inline ClassOptions operator|(ClassOptions a, ClassOptions b) { + return static_cast<ClassOptions>(static_cast<uint16_t>(a) | + static_cast<uint16_t>(b)); +} + +inline ClassOptions operator&(ClassOptions a, ClassOptions b) { + return static_cast<ClassOptions>(static_cast<uint16_t>(a) & + static_cast<uint16_t>(b)); +} + +inline ClassOptions operator~(ClassOptions a) { + return static_cast<ClassOptions>(~static_cast<uint16_t>(a)); +} + +enum class FrameProcedureOptions : uint32_t { + None = 0x00000000, + HasAlloca = 0x00000001, + HasSetJmp = 0x00000002, + HasLongJmp = 0x00000004, + HasInlineAssembly = 0x00000008, + HasExceptionHandling = 0x00000010, + MarkedInline = 0x00000020, + HasStructuredExceptionHandling = 0x00000040, + Naked = 0x00000080, + SecurityChecks = 0x00000100, + AsynchronousExceptionHandling = 0x00000200, + NoStackOrderingForSecurityChecks = 0x00000400, + Inlined = 0x00000800, + StrictSecurityChecks = 0x00001000, + SafeBuffers = 0x00002000, + ProfileGuidedOptimization = 0x00040000, + ValidProfileCounts = 0x00080000, + OptimizedForSpeed = 0x00100000, + GuardCfg = 0x00200000, + GuardCfw = 0x00400000 +}; + +inline FrameProcedureOptions operator|(FrameProcedureOptions a, + FrameProcedureOptions b) { + return static_cast<FrameProcedureOptions>(static_cast<uint32_t>(a) | + static_cast<uint32_t>(b)); +} + +inline FrameProcedureOptions operator&(FrameProcedureOptions a, + FrameProcedureOptions b) { + return static_cast<FrameProcedureOptions>(static_cast<uint32_t>(a) & + static_cast<uint32_t>(b)); +} + +inline FrameProcedureOptions operator~(FrameProcedureOptions a) { + return static_cast<FrameProcedureOptions>(~static_cast<uint32_t>(a)); +} + +enum class FunctionOptions : uint8_t { + None = 0x00, + CxxReturnUdt = 0x01, + Constructor = 0x02, + ConstructorWithVirtualBases = 0x04 +}; + +inline FunctionOptions operator|(FunctionOptions a, FunctionOptions b) { + return static_cast<FunctionOptions>(static_cast<uint8_t>(a) | + static_cast<uint8_t>(b)); +} + +inline FunctionOptions operator&(FunctionOptions a, FunctionOptions b) { + return static_cast<FunctionOptions>(static_cast<uint8_t>(a) & + static_cast<uint8_t>(b)); +} + +inline FunctionOptions operator~(FunctionOptions a) { + return static_cast<FunctionOptions>(~static_cast<uint8_t>(a)); +} + +enum class HfaKind : uint8_t { + None = 0x00, + Float = 0x01, + Double = 0x02, + Other = 0x03 +}; + +enum class MemberAccess : uint8_t { + None = 0, + Private = 1, + Protected = 2, + Public = 3 +}; + +enum class MethodKind : uint8_t { + Vanilla = 0x00, + Virtual = 0x01, + Static = 0x02, + Friend = 0x03, + IntroducingVirtual = 0x04, + PureVirtual = 0x05, + PureIntroducingVirtual = 0x06 +}; + +enum class MethodOptions : uint16_t { + None = 0x0000, + Pseudo = 0x0020, + CompilerGenerated = 0x0100, + Sealed = 0x0200 +}; + +inline MethodOptions operator|(MethodOptions a, MethodOptions b) { + return static_cast<MethodOptions>(static_cast<uint16_t>(a) | + static_cast<uint16_t>(b)); +} + +inline MethodOptions operator&(MethodOptions a, MethodOptions b) { + return static_cast<MethodOptions>(static_cast<uint16_t>(a) & + static_cast<uint16_t>(b)); +} + +inline MethodOptions operator~(MethodOptions a) { + return static_cast<MethodOptions>(~static_cast<uint16_t>(a)); +} + +enum class ModifierOptions : uint16_t { + None = 0x0000, + Const = 0x0001, + Volatile = 0x0002, + Unaligned = 0x0004 +}; + +inline ModifierOptions operator|(ModifierOptions a, ModifierOptions b) { + return static_cast<ModifierOptions>(static_cast<uint16_t>(a) | + static_cast<uint16_t>(b)); +} + +inline ModifierOptions operator&(ModifierOptions a, ModifierOptions b) { + return static_cast<ModifierOptions>(static_cast<uint16_t>(a) & + static_cast<uint16_t>(b)); +} + +inline ModifierOptions operator~(ModifierOptions a) { + return static_cast<ModifierOptions>(~static_cast<uint16_t>(a)); +} + +enum class ModuleSubstreamKind : uint32_t { + Symbols = 0xf1, + Lines = 0xf2, + StringTable = 0xf3, + FileChecksums = 0xf4, + FrameData = 0xf5, + InlineeLines = 0xf6, + CrossScopeImports = 0xf7, + CrossScopeExports = 0xf8 +}; + +enum class PointerKind : uint8_t { + Near16 = 0x00, // 16 bit pointer + Far16 = 0x01, // 16:16 far pointer + Huge16 = 0x02, // 16:16 huge pointer + BasedOnSegment = 0x03, // based on segment + BasedOnValue = 0x04, // based on value of base + BasedOnSegmentValue = 0x05, // based on segment value of base + BasedOnAddress = 0x06, // based on address of base + BasedOnSegmentAddress = 0x07, // based on segment address of base + BasedOnType = 0x08, // based on type + BasedOnSelf = 0x09, // based on self + Near32 = 0x0a, // 32 bit pointer + Far32 = 0x0b, // 16:32 pointer + Near64 = 0x0c // 64 bit pointer +}; + +enum class PointerMode : uint8_t { + Pointer = 0x00, // "normal" pointer + LValueReference = 0x01, // "old" reference + PointerToDataMember = 0x02, // pointer to data member + PointerToMemberFunction = 0x03, // pointer to member function + RValueReference = 0x04 // r-value reference +}; + +enum class PointerOptions : uint32_t { + None = 0x00000000, + Flat32 = 0x00000100, + Volatile = 0x00000200, + Const = 0x00000400, + Unaligned = 0x00000800, + Restrict = 0x00001000, + WinRTSmartPointer = 0x00080000 +}; + +inline PointerOptions operator|(PointerOptions a, PointerOptions b) { + return static_cast<PointerOptions>(static_cast<uint16_t>(a) | + static_cast<uint16_t>(b)); +} + +inline PointerOptions operator&(PointerOptions a, PointerOptions b) { + return static_cast<PointerOptions>(static_cast<uint16_t>(a) & + static_cast<uint16_t>(b)); +} + +inline PointerOptions operator~(PointerOptions a) { + return static_cast<PointerOptions>(~static_cast<uint16_t>(a)); +} + +enum class PointerToMemberRepresentation : uint16_t { + Unknown = 0x00, // not specified (pre VC8) + SingleInheritanceData = 0x01, // member data, single inheritance + MultipleInheritanceData = 0x02, // member data, multiple inheritance + VirtualInheritanceData = 0x03, // member data, virtual inheritance + GeneralData = 0x04, // member data, most general + SingleInheritanceFunction = 0x05, // member function, single inheritance + MultipleInheritanceFunction = 0x06, // member function, multiple inheritance + VirtualInheritanceFunction = 0x07, // member function, virtual inheritance + GeneralFunction = 0x08 // member function, most general +}; + +enum class TypeRecordKind : uint16_t { + None = 0, + + VirtualTableShape = 0x000a, + Label = 0x000e, + EndPrecompiledHeader = 0x0014, + + Modifier = 0x1001, + Pointer = 0x1002, + Procedure = 0x1008, + MemberFunction = 0x1009, + + Oem = 0x100f, + Oem2 = 0x1011, + + ArgumentList = 0x1201, + FieldList = 0x1203, + BitField = 0x1205, + MethodList = 0x1206, + + BaseClass = 0x1400, + VirtualBaseClass = 0x1401, + IndirectVirtualBaseClass = 0x1402, + Index = 0x1404, + VirtualFunctionTablePointer = 0x1409, + + Enumerate = 0x1502, + Array = 0x1503, + Class = 0x1504, + Structure = 0x1505, + Union = 0x1506, + Enum = 0x1507, + Alias = 0x150a, + Member = 0x150d, + StaticMember = 0x150e, + Method = 0x150f, + NestedType = 0x1510, + OneMethod = 0x1511, + VirtualFunctionTable = 0x151d, + + FunctionId = 0x1601, + MemberFunctionId = 0x1602, + BuildInfo = 0x1603, + SubstringList = 0x1604, + StringId = 0x1605, + UdtSourceLine = 0x1606, + + SByte = 0x8000, + Int16 = 0x8001, + UInt16 = 0x8002, + Int32 = 0x8003, + UInt32 = 0x8004, + Single = 0x8005, + Double = 0x8006, + Float80 = 0x8007, + Float128 = 0x8008, + Int64 = 0x8009, + UInt64 = 0x800a, + Float48 = 0x800b, + Complex32 = 0x800c, + Complex64 = 0x800d, + Complex80 = 0x800e, + Complex128 = 0x800f, + VarString = 0x8010, + + Int128 = 0x8017, + UInt128 = 0x8018, + + Decimal = 0x8019, + Date = 0x801a, + Utf8String = 0x801b, + + Float16 = 0x801c +}; + +enum class VirtualTableSlotKind : uint8_t { + Near16 = 0x00, + Far16 = 0x01, + This = 0x02, + Outer = 0x03, + Meta = 0x04, + Near = 0x05, + Far = 0x06 +}; + +enum class WindowsRTClassKind : uint8_t { + None = 0x00, + RefClass = 0x01, + ValueClass = 0x02, + Interface = 0x03 +}; +} +} + +#endif diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewOStream.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewOStream.h new file mode 100644 index 0000000..14d057a --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CodeViewOStream.h @@ -0,0 +1,39 @@ +//===- CodeViewOStream.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_CODEVIEWOSTREAM_H +#define LLVM_DEBUGINFO_CODEVIEW_CODEVIEWOSTREAM_H + +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" + +namespace llvm { +namespace codeview { + +template <typename Writer> class CodeViewOStream { +private: + CodeViewOStream(const CodeViewOStream &) = delete; + CodeViewOStream &operator=(const CodeViewOStream &) = delete; + +public: + typedef typename Writer::LabelType LabelType; + +public: + explicit CodeViewOStream(Writer &W); + +private: + uint64_t size() const { return W.tell(); } + +private: + Writer &W; +}; +} +} + +#endif diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/FieldListRecordBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/FieldListRecordBuilder.h new file mode 100644 index 0000000..1ed6248 --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/FieldListRecordBuilder.h @@ -0,0 +1,78 @@ +//===- FieldListRecordBuilder.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_FIELDLISTRECORDBUILDER_H +#define LLVM_DEBUGINFO_CODEVIEW_FIELDLISTRECORDBUILDER_H + +#include "llvm/DebugInfo/CodeView/ListRecordBuilder.h" + +namespace llvm { +namespace codeview { + +class MethodInfo { +public: + MethodInfo() : Access(), Kind(), Options(), Type(), VTableSlotOffset(-1) {} + + MethodInfo(MemberAccess Access, MethodKind Kind, MethodOptions Options, + TypeIndex Type, int32_t VTableSlotOffset) + : Access(Access), Kind(Kind), Options(Options), Type(Type), + VTableSlotOffset(VTableSlotOffset) {} + + MemberAccess getAccess() const { return Access; } + MethodKind getKind() const { return Kind; } + MethodOptions getOptions() const { return Options; } + TypeIndex getType() const { return Type; } + int32_t getVTableSlotOffset() const { return VTableSlotOffset; } + +private: + MemberAccess Access; + MethodKind Kind; + MethodOptions Options; + TypeIndex Type; + int32_t VTableSlotOffset; +}; + +class FieldListRecordBuilder : public ListRecordBuilder { +private: + FieldListRecordBuilder(const FieldListRecordBuilder &) = delete; + void operator=(const FieldListRecordBuilder &) = delete; + +public: + FieldListRecordBuilder(); + + void writeBaseClass(MemberAccess Access, TypeIndex Type, uint64_t Offset); + void writeEnumerate(MemberAccess Access, uint64_t Value, StringRef Name); + void writeIndirectVirtualBaseClass(MemberAccess Access, TypeIndex Type, + TypeIndex VirtualBasePointerType, + int64_t VirtualBasePointerOffset, + uint64_t SlotIndex); + void writeMember(MemberAccess Access, TypeIndex Type, uint64_t Offset, + StringRef Name); + void writeOneMethod(MemberAccess Access, MethodKind Kind, + MethodOptions Options, TypeIndex Type, + int32_t VTableSlotOffset, StringRef Name); + void writeOneMethod(const MethodInfo &Method, StringRef Name); + void writeMethod(uint16_t OverloadCount, TypeIndex MethodList, + StringRef Name); + void writeNestedType(TypeIndex Type, StringRef Name); + void writeStaticMember(MemberAccess Access, TypeIndex Type, StringRef Name); + void writeVirtualBaseClass(MemberAccess Access, TypeIndex Type, + TypeIndex VirtualBasePointerType, + int64_t VirtualBasePointerOffset, + uint64_t SlotIndex); + void writeVirtualBaseClass(TypeRecordKind Kind, MemberAccess Access, + TypeIndex Type, TypeIndex VirtualBasePointerType, + int64_t VirtualBasePointerOffset, + uint64_t SlotIndex); + void writeVirtualFunctionTablePointer(TypeIndex Type); +}; +} +} + +#endif diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/FunctionId.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/FunctionId.h new file mode 100644 index 0000000..1af3da8 --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/FunctionId.h @@ -0,0 +1,56 @@ +//===- FunctionId.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_FUNCTIONID_H +#define LLVM_DEBUGINFO_CODEVIEW_FUNCTIONID_H + +#include <cinttypes> + +namespace llvm { +namespace codeview { + +class FunctionId { +public: + FunctionId() : Index(0) {} + + explicit FunctionId(uint32_t Index) : Index(Index) {} + + uint32_t getIndex() const { return Index; } + +private: + uint32_t Index; +}; + +inline bool operator==(const FunctionId &A, const FunctionId &B) { + return A.getIndex() == B.getIndex(); +} + +inline bool operator!=(const FunctionId &A, const FunctionId &B) { + return A.getIndex() != B.getIndex(); +} + +inline bool operator<(const FunctionId &A, const FunctionId &B) { + return A.getIndex() < B.getIndex(); +} + +inline bool operator<=(const FunctionId &A, const FunctionId &B) { + return A.getIndex() <= B.getIndex(); +} + +inline bool operator>(const FunctionId &A, const FunctionId &B) { + return A.getIndex() > B.getIndex(); +} + +inline bool operator>=(const FunctionId &A, const FunctionId &B) { + return A.getIndex() >= B.getIndex(); +} +} +} + +#endif diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/Line.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/Line.h new file mode 100644 index 0000000..a7cdbda --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/Line.h @@ -0,0 +1,124 @@ +//===- Line.h ---------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_LINE_H +#define LLVM_DEBUGINFO_CODEVIEW_LINE_H + +#include <cinttypes> + +namespace llvm { +namespace codeview { + +class LineInfo { +public: + static const uint32_t AlwaysStepIntoLineNumber = 0xfeefee; + static const uint32_t NeverStepIntoLineNumber = 0xf00f00; + +private: + static const uint32_t StartLineMask = 0x00ffffff; + static const uint32_t EndLineDeltaMask = 0x7f000000; + static const int EndLineDeltaShift = 24; + static const uint32_t StatementFlag = 0x80000000u; + +public: + LineInfo(uint32_t StartLine, uint32_t EndLine, bool IsStatement); + + uint32_t getStartLine() const { return LineData & StartLineMask; } + + uint32_t getLineDelta() const { + return (LineData & EndLineDeltaMask) >> EndLineDeltaShift; + } + + uint32_t getEndLine() const { return getStartLine() + getLineDelta(); } + + bool isStatement() const { return (LineData & StatementFlag) != 0; } + + uint32_t getRawData() const { return LineData; } + + bool isAlwaysStepInto() const { + return getStartLine() == AlwaysStepIntoLineNumber; + } + + bool isNeverStepInto() const { + return getStartLine() == NeverStepIntoLineNumber; + } + +private: + uint32_t LineData; +}; + +class ColumnInfo { +private: + static const uint32_t StartColumnMask = 0x0000ffffu; + static const uint32_t EndColumnMask = 0xffff0000u; + static const int EndColumnShift = 16; + +public: + ColumnInfo(uint16_t StartColumn, uint16_t EndColumn) { + ColumnData = + (static_cast<uint32_t>(StartColumn) & StartColumnMask) | + ((static_cast<uint32_t>(EndColumn) << EndColumnShift) & EndColumnMask); + } + + uint16_t getStartColumn() const { + return static_cast<uint16_t>(ColumnData & StartColumnMask); + } + + uint16_t getEndColumn() const { + return static_cast<uint16_t>((ColumnData & EndColumnMask) >> + EndColumnShift); + } + + uint32_t getRawData() const { return ColumnData; } + +private: + uint32_t ColumnData; +}; + +class Line { +private: + int32_t CodeOffset; + LineInfo LineInf; + ColumnInfo ColumnInf; + +public: + Line(int32_t CodeOffset, uint32_t StartLine, uint32_t EndLine, + uint16_t StartColumn, uint16_t EndColumn, bool IsStatement) + : CodeOffset(CodeOffset), LineInf(StartLine, EndLine, IsStatement), + ColumnInf(StartColumn, EndColumn) {} + + Line(int32_t CodeOffset, LineInfo LineInf, ColumnInfo ColumnInf) + : CodeOffset(CodeOffset), LineInf(LineInf), ColumnInf(ColumnInf) {} + + LineInfo getLineInfo() const { return LineInf; } + + ColumnInfo getColumnInfo() const { return ColumnInf; } + + int32_t getCodeOffset() const { return CodeOffset; } + + uint32_t getStartLine() const { return LineInf.getStartLine(); } + + uint32_t getLineDelta() const { return LineInf.getLineDelta(); } + + uint32_t getEndLine() const { return LineInf.getEndLine(); } + + uint16_t getStartColumn() const { return ColumnInf.getStartColumn(); } + + uint16_t getEndColumn() const { return ColumnInf.getEndColumn(); } + + bool isStatement() const { return LineInf.isStatement(); } + + bool isAlwaysStepInto() const { return LineInf.isAlwaysStepInto(); } + + bool isNeverStepInto() const { return LineInf.isNeverStepInto(); } +}; +} +} + +#endif diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/ListRecordBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/ListRecordBuilder.h new file mode 100644 index 0000000..df0a2e0 --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/ListRecordBuilder.h @@ -0,0 +1,43 @@ +//===- ListRecordBuilder.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_LISTRECORDBUILDER_H +#define LLVM_DEBUGINFO_CODEVIEW_LISTRECORDBUILDER_H + +#include "llvm/DebugInfo/CodeView/TypeRecordBuilder.h" + +namespace llvm { +namespace codeview { + +class ListRecordBuilder { +private: + ListRecordBuilder(const ListRecordBuilder &) = delete; + ListRecordBuilder &operator=(const ListRecordBuilder &) = delete; + +protected: + const int MethodKindShift = 2; + + explicit ListRecordBuilder(TypeRecordKind Kind); + +public: + llvm::StringRef str() { return Builder.str(); } + +protected: + void finishSubRecord(); + + TypeRecordBuilder &getBuilder() { return Builder; } + +private: + TypeRecordBuilder Builder; + SmallVector<size_t, 4> ContinuationOffsets; +}; +} +} + +#endif diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h new file mode 100644 index 0000000..5bfe2a0 --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/MemoryTypeTableBuilder.h @@ -0,0 +1,68 @@ +//===- MemoryTypeTableBuilder.h ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_MEMORYTYPETABLEBUILDER_H +#define LLVM_DEBUGINFO_CODEVIEW_MEMORYTYPETABLEBUILDER_H + +#include "llvm/ADT/Hashing.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h" +#include <functional> +#include <memory> +#include <unordered_map> +#include <vector> + +namespace llvm { +namespace codeview { + +class MemoryTypeTableBuilder : public TypeTableBuilder { +public: + class Record { + public: + explicit Record(llvm::StringRef RData); + + const char *data() const { return Data.get(); } + uint16_t size() const { return Size; } + + private: + uint16_t Size; + std::unique_ptr<char[]> Data; + }; + +private: + class RecordHash : std::unary_function<llvm::StringRef, size_t> { + public: + size_t operator()(llvm::StringRef Val) const { + return static_cast<size_t>(llvm::hash_value(Val)); + } + }; + +public: + MemoryTypeTableBuilder() {} + + template <typename TFunc> void ForEachRecord(TFunc Func) { + uint32_t Index = TypeIndex::FirstNonSimpleIndex; + + for (const std::unique_ptr<Record> &R : Records) { + Func(TypeIndex(Index), R.get()); + ++Index; + } + } + +private: + virtual TypeIndex writeRecord(llvm::StringRef Data) override; + +private: + std::vector<std::unique_ptr<Record>> Records; + std::unordered_map<llvm::StringRef, TypeIndex, RecordHash> HashedRecords; +}; +} +} + +#endif diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/MethodListRecordBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/MethodListRecordBuilder.h new file mode 100644 index 0000000..faa404d --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/MethodListRecordBuilder.h @@ -0,0 +1,35 @@ +//===- MethodListRecordBuilder.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_METHODLISTRECORDBUILDER_H +#define LLVM_DEBUGINFO_CODEVIEW_METHODLISTRECORDBUILDER_H + +#include "llvm/DebugInfo/CodeView/ListRecordBuilder.h" + +namespace llvm { +namespace codeview { + +class MethodInfo; + +class MethodListRecordBuilder : public ListRecordBuilder { +private: + MethodListRecordBuilder(const MethodListRecordBuilder &) = delete; + MethodListRecordBuilder &operator=(const MethodListRecordBuilder &) = delete; + +public: + MethodListRecordBuilder(); + + void writeMethod(MemberAccess Access, MethodKind Kind, MethodOptions Options, + TypeIndex Type, int32_t VTableSlotOffset); + void writeMethod(const MethodInfo &Method); +}; +} +} + +#endif diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h new file mode 100644 index 0000000..d3a541b --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h @@ -0,0 +1,176 @@ +//===- TypeIndex.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H +#define LLVM_DEBUGINFO_CODEVIEW_TYPEINDEX_H + +#include <cassert> +#include <cinttypes> + +namespace llvm { +namespace codeview { + +enum class SimpleTypeKind : uint32_t { + None = 0x0000, // uncharacterized type (no type) + Void = 0x0003, // void + NotTranslated = 0x0007, // type not translated by cvpack + HResult = 0x0008, // OLE/COM HRESULT + + SignedCharacter = 0x0010, // 8 bit signed + UnsignedCharacter = 0x0020, // 8 bit unsigned + NarrowCharacter = 0x0070, // really a char + WideCharacter = 0x0071, // wide char + + SByte = 0x0068, // 8 bit signed int + Byte = 0x0069, // 8 bit unsigned int + Int16Short = 0x0011, // 16 bit signed + UInt16Short = 0x0021, // 16 bit unsigned + Int16 = 0x0072, // 16 bit signed int + UInt16 = 0x0073, // 16 bit unsigned int + Int32Long = 0x0012, // 32 bit signed + UInt32Long = 0x0022, // 32 bit unsigned + Int32 = 0x0074, // 32 bit signed int + UInt32 = 0x0075, // 32 bit unsigned int + Int64Quad = 0x0013, // 64 bit signed + UInt64Quad = 0x0023, // 64 bit unsigned + Int64 = 0x0076, // 64 bit signed int + UInt64 = 0x0077, // 64 bit unsigned int + Int128 = 0x0078, // 128 bit signed int + UInt128 = 0x0079, // 128 bit unsigned int + + Float16 = 0x0046, // 16 bit real + Float32 = 0x0040, // 32 bit real + Float32PartialPrecision = 0x0045, // 32 bit PP real + Float48 = 0x0044, // 48 bit real + Float64 = 0x0041, // 64 bit real + Float80 = 0x0042, // 80 bit real + Float128 = 0x0043, // 128 bit real + + Complex32 = 0x0050, // 32 bit complex + Complex64 = 0x0051, // 64 bit complex + Complex80 = 0x0052, // 80 bit complex + Complex128 = 0x0053, // 128 bit complex + + Boolean8 = 0x0030, // 8 bit boolean + Boolean16 = 0x0031, // 16 bit boolean + Boolean32 = 0x0032, // 32 bit boolean + Boolean64 = 0x0033 // 64 bit boolean +}; + +enum class SimpleTypeMode : uint32_t { + Direct = 0x00000000, // Not a pointer + NearPointer = 0x00000100, // Near pointer + FarPointer = 0x00000200, // Far pointer + HugePointer = 0x00000300, // Huge pointer + NearPointer32 = 0x00000400, // 32 bit near pointer + FarPointer32 = 0x00000500, // 32 bit far pointer + NearPointer64 = 0x00000600, // 64 bit near pointer + NearPointer128 = 0x00000700 // 128 bit near pointer +}; + +class TypeIndex { +public: + static const uint32_t FirstNonSimpleIndex = 0x1000; + static const uint32_t SimpleKindMask = 0x000000ff; + static const uint32_t SimpleModeMask = 0x00000700; + +public: + TypeIndex() : Index(0) {} + explicit TypeIndex(uint32_t Index) : Index(Index) {} + explicit TypeIndex(SimpleTypeKind Kind) + : Index(static_cast<uint32_t>(Kind)) {} + TypeIndex(SimpleTypeKind Kind, SimpleTypeMode Mode) + : Index(static_cast<uint32_t>(Kind) | static_cast<uint32_t>(Mode)) {} + + uint32_t getIndex() const { return Index; } + bool isSimple() const { return Index < FirstNonSimpleIndex; } + + SimpleTypeKind getSimpleKind() const { + assert(isSimple()); + return static_cast<SimpleTypeKind>(Index & SimpleKindMask); + } + + SimpleTypeMode getSimpleMode() const { + assert(isSimple()); + return static_cast<SimpleTypeMode>(Index & SimpleModeMask); + } + + static TypeIndex Void() { return TypeIndex(SimpleTypeKind::Void); } + static TypeIndex VoidPointer32() { + return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer32); + } + static TypeIndex VoidPointer64() { + return TypeIndex(SimpleTypeKind::Void, SimpleTypeMode::NearPointer64); + } + + static TypeIndex SignedCharacter() { + return TypeIndex(SimpleTypeKind::SignedCharacter); + } + static TypeIndex UnsignedCharacter() { + return TypeIndex(SimpleTypeKind::UnsignedCharacter); + } + static TypeIndex NarrowCharacter() { + return TypeIndex(SimpleTypeKind::NarrowCharacter); + } + static TypeIndex WideCharacter() { + return TypeIndex(SimpleTypeKind::WideCharacter); + } + static TypeIndex Int16Short() { + return TypeIndex(SimpleTypeKind::Int16Short); + } + static TypeIndex UInt16Short() { + return TypeIndex(SimpleTypeKind::UInt16Short); + } + static TypeIndex Int32() { return TypeIndex(SimpleTypeKind::Int32); } + static TypeIndex UInt32() { return TypeIndex(SimpleTypeKind::UInt32); } + static TypeIndex Int32Long() { return TypeIndex(SimpleTypeKind::Int32Long); } + static TypeIndex UInt32Long() { + return TypeIndex(SimpleTypeKind::UInt32Long); + } + static TypeIndex Int64() { return TypeIndex(SimpleTypeKind::Int64); } + static TypeIndex UInt64() { return TypeIndex(SimpleTypeKind::UInt64); } + static TypeIndex Int64Quad() { return TypeIndex(SimpleTypeKind::Int64Quad); } + static TypeIndex UInt64Quad() { + return TypeIndex(SimpleTypeKind::UInt64Quad); + } + + static TypeIndex Float32() { return TypeIndex(SimpleTypeKind::Float32); } + static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); } + +private: + uint32_t Index; +}; + +inline bool operator==(const TypeIndex &A, const TypeIndex &B) { + return A.getIndex() == B.getIndex(); +} + +inline bool operator!=(const TypeIndex &A, const TypeIndex &B) { + return A.getIndex() != B.getIndex(); +} + +inline bool operator<(const TypeIndex &A, const TypeIndex &B) { + return A.getIndex() < B.getIndex(); +} + +inline bool operator<=(const TypeIndex &A, const TypeIndex &B) { + return A.getIndex() <= B.getIndex(); +} + +inline bool operator>(const TypeIndex &A, const TypeIndex &B) { + return A.getIndex() > B.getIndex(); +} + +inline bool operator>=(const TypeIndex &A, const TypeIndex &B) { + return A.getIndex() >= B.getIndex(); +} +} +} + +#endif diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h new file mode 100644 index 0000000..21755f5 --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -0,0 +1,270 @@ +//===- TypeRecord.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H +#define LLVM_DEBUGINFO_CODEVIEW_TYPERECORD_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include <cinttypes> + +namespace llvm { +namespace codeview { + +class TypeRecord { +protected: + explicit TypeRecord(TypeRecordKind Kind) : Kind(Kind) {} + +public: + TypeRecordKind getKind() const { return Kind; } + +private: + TypeRecordKind Kind; +}; + +class ModifierRecord : public TypeRecord { +public: + ModifierRecord(TypeIndex ModifiedType, ModifierOptions Options) + : TypeRecord(TypeRecordKind::Modifier), ModifiedType(ModifiedType), + Options(Options) {} + + TypeIndex getModifiedType() const { return ModifiedType; } + ModifierOptions getOptions() const { return Options; } + +private: + TypeIndex ModifiedType; + ModifierOptions Options; +}; + +class ProcedureRecord : public TypeRecord { +public: + ProcedureRecord(TypeIndex ReturnType, CallingConvention CallConv, + FunctionOptions Options, uint16_t ParameterCount, + TypeIndex ArgumentList) + : TypeRecord(TypeRecordKind::Procedure), ReturnType(ReturnType), + CallConv(CallConv), Options(Options), ParameterCount(ParameterCount), + ArgumentList(ArgumentList) {} + + TypeIndex getReturnType() const { return ReturnType; } + CallingConvention getCallConv() const { return CallConv; } + FunctionOptions getOptions() const { return Options; } + uint16_t getParameterCount() const { return ParameterCount; } + TypeIndex getArgumentList() const { return ArgumentList; } + +private: + TypeIndex ReturnType; + CallingConvention CallConv; + FunctionOptions Options; + uint16_t ParameterCount; + TypeIndex ArgumentList; +}; + +class MemberFunctionRecord : public TypeRecord { +public: + MemberFunctionRecord(TypeIndex ReturnType, TypeIndex ClassType, + TypeIndex ThisType, CallingConvention CallConv, + FunctionOptions Options, uint16_t ParameterCount, + TypeIndex ArgumentList, int32_t ThisPointerAdjustment) + : TypeRecord(TypeRecordKind::MemberFunction), ReturnType(ReturnType), + ClassType(ClassType), ThisType(ThisType), CallConv(CallConv), + Options(Options), ParameterCount(ParameterCount), + ArgumentList(ArgumentList), + ThisPointerAdjustment(ThisPointerAdjustment) {} + + TypeIndex getReturnType() const { return ReturnType; } + TypeIndex getClassType() const { return ClassType; } + TypeIndex getThisType() const { return ThisType; } + CallingConvention getCallConv() const { return CallConv; } + FunctionOptions getOptions() const { return Options; } + uint16_t getParameterCount() const { return ParameterCount; } + TypeIndex getArgumentList() const { return ArgumentList; } + int32_t getThisPointerAdjustment() const { return ThisPointerAdjustment; } + +private: + TypeIndex ReturnType; + TypeIndex ClassType; + TypeIndex ThisType; + CallingConvention CallConv; + FunctionOptions Options; + uint16_t ParameterCount; + TypeIndex ArgumentList; + int32_t ThisPointerAdjustment; +}; + +class ArgumentListRecord : public TypeRecord { +public: + explicit ArgumentListRecord(llvm::ArrayRef<TypeIndex> ArgumentTypes) + : TypeRecord(TypeRecordKind::ArgumentList), ArgumentTypes(ArgumentTypes) { + } + + llvm::ArrayRef<TypeIndex> getArgumentTypes() const { return ArgumentTypes; } + +private: + llvm::ArrayRef<TypeIndex> ArgumentTypes; +}; + +class PointerRecordBase : public TypeRecord { +public: + PointerRecordBase(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode, + PointerOptions Options, uint8_t Size) + : TypeRecord(TypeRecordKind::Pointer), ReferentType(ReferentType), + PtrKind(Kind), Mode(Mode), Options(Options), Size(Size) {} + + TypeIndex getReferentType() const { return ReferentType; } + PointerKind getPointerKind() const { return PtrKind; } + PointerMode getMode() const { return Mode; } + PointerOptions getOptions() const { return Options; } + uint8_t getSize() const { return Size; } + +private: + TypeIndex ReferentType; + PointerKind PtrKind; + PointerMode Mode; + PointerOptions Options; + uint8_t Size; +}; + +class PointerRecord : public PointerRecordBase { +public: + PointerRecord(TypeIndex ReferentType, PointerKind Kind, PointerMode Mode, + PointerOptions Options, uint8_t Size) + : PointerRecordBase(ReferentType, Kind, Mode, Options, Size) {} +}; + +class PointerToMemberRecord : public PointerRecordBase { +public: + PointerToMemberRecord(TypeIndex ReferentType, PointerKind Kind, + PointerMode Mode, PointerOptions Options, uint8_t Size, + TypeIndex ContainingType, + PointerToMemberRepresentation Representation) + : PointerRecordBase(ReferentType, Kind, Mode, Options, Size), + ContainingType(ContainingType), Representation(Representation) {} + + TypeIndex getContainingType() const { return ContainingType; } + PointerToMemberRepresentation getRepresentation() const { + return Representation; + } + +private: + TypeIndex ContainingType; + PointerToMemberRepresentation Representation; +}; + +class ArrayRecord : public TypeRecord { +public: + ArrayRecord(TypeIndex ElementType, TypeIndex IndexType, uint64_t Size, + llvm::StringRef Name) + : TypeRecord(TypeRecordKind::Array), ElementType(ElementType), + IndexType(IndexType), Size(Size), Name(Name) {} + + TypeIndex getElementType() const { return ElementType; } + TypeIndex getIndexType() const { return IndexType; } + uint64_t getSize() const { return Size; } + llvm::StringRef getName() const { return Name; } + +private: + TypeIndex ElementType; + TypeIndex IndexType; + uint64_t Size; + llvm::StringRef Name; +}; + +class TagRecord : public TypeRecord { +protected: + TagRecord(TypeRecordKind Kind, uint16_t MemberCount, ClassOptions Options, + TypeIndex FieldList, StringRef Name, StringRef UniqueName) + : TypeRecord(Kind), MemberCount(MemberCount), Options(Options), + FieldList(FieldList), Name(Name), UniqueName(UniqueName) {} + +public: + uint16_t getMemberCount() const { return MemberCount; } + ClassOptions getOptions() const { return Options; } + TypeIndex getFieldList() const { return FieldList; } + StringRef getName() const { return Name; } + StringRef getUniqueName() const { return UniqueName; } + +private: + uint16_t MemberCount; + ClassOptions Options; + TypeIndex FieldList; + StringRef Name; + StringRef UniqueName; +}; + +class AggregateRecord : public TagRecord { +public: + AggregateRecord(TypeRecordKind Kind, uint16_t MemberCount, + ClassOptions Options, HfaKind Hfa, + WindowsRTClassKind WinRTKind, TypeIndex FieldList, + TypeIndex DerivationList, TypeIndex VTableShape, + uint64_t Size, StringRef Name, StringRef UniqueName) + : TagRecord(Kind, MemberCount, Options, FieldList, Name, UniqueName), + Hfa(Hfa), WinRTKind(WinRTKind), DerivationList(DerivationList), + VTableShape(VTableShape), Size(Size) {} + + HfaKind getHfa() const { return Hfa; } + WindowsRTClassKind getWinRTKind() const { return WinRTKind; } + TypeIndex getDerivationList() const { return DerivationList; } + TypeIndex getVTableShape() const { return VTableShape; } + uint64_t getSize() const { return Size; } + +private: + HfaKind Hfa; + WindowsRTClassKind WinRTKind; + TypeIndex DerivationList; + TypeIndex VTableShape; + uint64_t Size; +}; + +class EnumRecord : public TagRecord { +public: + EnumRecord(uint16_t MemberCount, ClassOptions Options, TypeIndex FieldList, + StringRef Name, StringRef UniqueName, TypeIndex UnderlyingType) + : TagRecord(TypeRecordKind::Enum, MemberCount, Options, FieldList, Name, + UniqueName), + UnderlyingType(UnderlyingType) {} + + TypeIndex getUnderlyingType() const { return UnderlyingType; } + +private: + TypeIndex UnderlyingType; +}; + +class BitFieldRecord : TypeRecord { +public: + BitFieldRecord(TypeIndex Type, uint8_t BitSize, uint8_t BitOffset) + : TypeRecord(TypeRecordKind::BitField), Type(Type), BitSize(BitSize), + BitOffset(BitOffset) {} + + TypeIndex getType() const { return Type; } + uint8_t getBitOffset() const { return BitOffset; } + uint8_t getBitSize() const { return BitSize; } + +private: + TypeIndex Type; + uint8_t BitSize; + uint8_t BitOffset; +}; + +class VirtualTableShapeRecord : TypeRecord { +public: + explicit VirtualTableShapeRecord(ArrayRef<VirtualTableSlotKind> Slots) + : TypeRecord(TypeRecordKind::VirtualTableShape), Slots(Slots) {} + + ArrayRef<VirtualTableSlotKind> getSlots() const { return Slots; } + +private: + ArrayRef<VirtualTableSlotKind> Slots; +}; +} +} + +#endif diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordBuilder.h new file mode 100644 index 0000000..1f48cf7 --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeRecordBuilder.h @@ -0,0 +1,57 @@ +//===- TypeRecordBuilder.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPERECORDBUILDER_H +#define LLVM_DEBUGINFO_CODEVIEW_TYPERECORDBUILDER_H + +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/EndianStream.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { +namespace codeview { + +class TypeRecordBuilder { +private: + TypeRecordBuilder(const TypeRecordBuilder &) = delete; + TypeRecordBuilder &operator=(const TypeRecordBuilder &) = delete; + +public: + explicit TypeRecordBuilder(TypeRecordKind Kind); + + void writeUInt8(uint8_t Value); + void writeInt16(int16_t Value); + void writeUInt16(uint16_t Value); + void writeInt32(int32_t Value); + void writeUInt32(uint32_t Value); + void writeInt64(int64_t Value); + void writeUInt64(uint64_t Value); + void writeTypeIndex(TypeIndex TypeInd); + void writeTypeRecordKind(TypeRecordKind Kind); + void writeEncodedInteger(int64_t Value); + void writeEncodedSignedInteger(int64_t Value); + void writeEncodedUnsignedInteger(uint64_t Value); + void writeNullTerminatedString(const char *Value); + void writeNullTerminatedString(StringRef Value); + + llvm::StringRef str(); + + uint64_t size() const { return Stream.tell(); } + +private: + llvm::SmallVector<char, 256> Buffer; + llvm::raw_svector_ostream Stream; + llvm::support::endian::Writer<llvm::support::endianness::little> Writer; +}; +} +} + +#endif diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSymbolEmitter.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSymbolEmitter.h new file mode 100644 index 0000000..9de110e --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeSymbolEmitter.h @@ -0,0 +1,37 @@ +//===- TypeSymbolEmitter.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPESYMBOLEMITTER_H +#define LLVM_DEBUGINFO_CODEVIEW_TYPESYMBOLEMITTER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" + +namespace llvm { +namespace codeview { + +class TypeSymbolEmitter { +private: + TypeSymbolEmitter(const TypeSymbolEmitter &) = delete; + TypeSymbolEmitter &operator=(const TypeSymbolEmitter &) = delete; + +protected: + TypeSymbolEmitter() {} + +public: + virtual ~TypeSymbolEmitter() {} + +public: + virtual void writeUserDefinedType(TypeIndex TI, StringRef Name) = 0; +}; +} +} + +#endif diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h new file mode 100644 index 0000000..2c950e8 --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/TypeTableBuilder.h @@ -0,0 +1,60 @@ +//===- TypeTableBuilder.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPETABLEBUILDER_H +#define LLVM_DEBUGINFO_CODEVIEW_TYPETABLEBUILDER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/Support/Compiler.h" + +namespace llvm { +namespace codeview { + +class FieldListRecordBuilder; +class MethodListRecordBuilder; +class TypeRecordBuilder; + +class TypeTableBuilder { +private: + TypeTableBuilder(const TypeTableBuilder &) = delete; + TypeTableBuilder &operator=(const TypeTableBuilder &) = delete; + +protected: + TypeTableBuilder(); + +public: + virtual ~TypeTableBuilder(); + +public: + TypeIndex writeModifier(const ModifierRecord &Record); + TypeIndex writeProcedure(const ProcedureRecord &Record); + TypeIndex writeMemberFunction(const MemberFunctionRecord &Record); + TypeIndex writeArgumentList(const ArgumentListRecord &Record); + TypeIndex writeRecord(TypeRecordBuilder &builder); + TypeIndex writePointer(const PointerRecord &Record); + TypeIndex writePointerToMember(const PointerToMemberRecord &Record); + TypeIndex writeArray(const ArrayRecord &Record); + TypeIndex writeAggregate(const AggregateRecord &Record); + TypeIndex writeEnum(const EnumRecord &Record); + TypeIndex writeBitField(const BitFieldRecord &Record); + TypeIndex writeVirtualTableShape(const VirtualTableShapeRecord &Record); + + TypeIndex writeFieldList(FieldListRecordBuilder &FieldList); + TypeIndex writeMethodList(MethodListRecordBuilder &MethodList); + +private: + virtual TypeIndex writeRecord(llvm::StringRef record) = 0; +}; +} +} + +#endif diff --git a/contrib/llvm/include/llvm/DebugInfo/DIContext.h b/contrib/llvm/include/llvm/DebugInfo/DIContext.h index 871e60c..6659a97 100644 --- a/contrib/llvm/include/llvm/DebugInfo/DIContext.h +++ b/contrib/llvm/include/llvm/DebugInfo/DIContext.h @@ -57,6 +57,10 @@ class DIInliningInfo { assert(Index < Frames.size()); return Frames[Index]; } + DILineInfo *getMutableFrame(unsigned Index) { + assert(Index < Frames.size()); + return &Frames[Index]; + } uint32_t getNumberOfFrames() const { return Frames.size(); } @@ -65,6 +69,15 @@ class DIInliningInfo { } }; +/// DIGlobal - container for description of a global variable. +struct DIGlobal { + std::string Name; + uint64_t Start; + uint64_t Size; + + DIGlobal() : Name("<invalid>"), Start(0), Size(0) {} +}; + /// A DINameKind is passed to name search methods to specify a /// preference regarding the type of name resolution the caller wants. enum class DINameKind { None, ShortName, LinkageName }; @@ -99,6 +112,7 @@ enum DIDumpType { DIDT_LineDwo, DIDT_Loc, DIDT_LocDwo, + DIDT_Macro, DIDT_Ranges, DIDT_Pubnames, DIDT_Pubtypes, @@ -110,7 +124,9 @@ enum DIDumpType { DIDT_AppleNames, DIDT_AppleTypes, DIDT_AppleNamespaces, - DIDT_AppleObjC + DIDT_AppleObjC, + DIDT_CUIndex, + DIDT_TUIndex, }; class DIContext { @@ -140,17 +156,21 @@ private: /// to be used by the DIContext implementations when applying relocations /// on the fly. class LoadedObjectInfo { +protected: + LoadedObjectInfo(const LoadedObjectInfo &) = default; + LoadedObjectInfo() = default; + public: virtual ~LoadedObjectInfo() = default; - /// Obtain the Load Address of a section by Name. + /// Obtain the Load Address of a section by SectionRef. /// - /// Calculate the address of the section identified by the passed in Name. + /// Calculate the address of the given section. /// The section need not be present in the local address space. The addresses /// need to be consistent with the addresses used to query the DIContext and /// the output of this function should be deterministic, i.e. repeated calls with - /// the same Name should give the same address. - virtual uint64_t getSectionLoadAddress(StringRef Name) const = 0; + /// the same Sec should give the same address. + virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const = 0; /// If conveniently available, return the content of the given Section. /// @@ -162,7 +182,8 @@ public: /// local (unrelocated) object file and applied on the fly. Note that this method /// is used purely for optimzation purposes in the common case of JITting in the /// local address space, so returning false should always be correct. - virtual bool getLoadedSectionContents(StringRef Name, StringRef &Data) const { + virtual bool getLoadedSectionContents(const object::SectionRef &Sec, + StringRef &Data) const { return false; } diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h index 743f9c6..bae3154 100644 --- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h +++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h @@ -18,10 +18,13 @@ class DWARFCompileUnit : public DWARFUnit { public: DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, - StringRef SOS, StringRef AOS, bool LE, - const DWARFUnitSectionBase &UnitSection) - : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LE, UnitSection) {} + StringRef SOS, StringRef AOS, StringRef LS, bool LE, + const DWARFUnitSectionBase &UnitSection, + const DWARFUnitIndex::Entry *Entry) + : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, UnitSection, + Entry) {} void dump(raw_ostream &OS); + static const DWARFSectionKind Section = DW_SECT_INFO; // VTable anchor. ~DWARFCompileUnit() override; }; diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h index 423c0d3..c91012b 100644 --- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -18,6 +18,7 @@ #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h" #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" #include "llvm/DebugInfo/DWARF/DWARFSection.h" #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" @@ -40,11 +41,14 @@ class DWARFContext : public DIContext { DWARFUnitSection<DWARFCompileUnit> CUs; std::vector<DWARFUnitSection<DWARFTypeUnit>> TUs; + std::unique_ptr<DWARFUnitIndex> CUIndex; + std::unique_ptr<DWARFUnitIndex> TUIndex; std::unique_ptr<DWARFDebugAbbrev> Abbrev; std::unique_ptr<DWARFDebugLoc> Loc; std::unique_ptr<DWARFDebugAranges> Aranges; std::unique_ptr<DWARFDebugLine> Line; std::unique_ptr<DWARFDebugFrame> DebugFrame; + std::unique_ptr<DWARFDebugMacro> Macro; DWARFUnitSection<DWARFCompileUnit> DWOCUs; std::vector<DWARFUnitSection<DWARFTypeUnit>> DWOTUs; @@ -143,6 +147,9 @@ public: return DWOCUs[index].get(); } + const DWARFUnitIndex &getCUIndex(); + const DWARFUnitIndex &getTUIndex(); + /// Get a pointer to the parsed DebugAbbrev object. const DWARFDebugAbbrev *getDebugAbbrev(); @@ -161,6 +168,9 @@ public: /// Get a pointer to the parsed frame information object. const DWARFDebugFrame *getDebugFrame(); + /// Get a pointer to the parsed DebugMacro object. + const DWARFDebugMacro *getDebugMacro(); + /// Get a pointer to a parsed line table corresponding to a compile unit. const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *cu); @@ -184,6 +194,7 @@ public: virtual const DWARFSection &getLineSection() = 0; virtual StringRef getStringSection() = 0; virtual StringRef getRangeSection() = 0; + virtual StringRef getMacinfoSection() = 0; virtual StringRef getPubNamesSection() = 0; virtual StringRef getPubTypesSection() = 0; virtual StringRef getGnuPubNamesSection() = 0; @@ -203,9 +214,11 @@ public: virtual const DWARFSection& getAppleTypesSection() = 0; virtual const DWARFSection& getAppleNamespacesSection() = 0; virtual const DWARFSection& getAppleObjCSection() = 0; + virtual StringRef getCUIndexSection() = 0; + virtual StringRef getTUIndexSection() = 0; static bool isSupportedVersion(unsigned version) { - return version == 2 || version == 3 || version == 4; + return version == 2 || version == 3 || version == 4 || version == 5; } private: /// Return the compile unit that includes an offset (relative to .debug_info). @@ -232,6 +245,7 @@ class DWARFContextInMemory : public DWARFContext { DWARFSection LineSection; StringRef StringSection; StringRef RangeSection; + StringRef MacinfoSection; StringRef PubNamesSection; StringRef PubTypesSection; StringRef GnuPubNamesSection; @@ -251,6 +265,8 @@ class DWARFContextInMemory : public DWARFContext { DWARFSection AppleTypesSection; DWARFSection AppleNamespacesSection; DWARFSection AppleObjCSection; + StringRef CUIndexSection; + StringRef TUIndexSection; SmallVector<SmallString<32>, 4> UncompressedSections; @@ -268,6 +284,7 @@ public: const DWARFSection &getLineSection() override { return LineSection; } StringRef getStringSection() override { return StringSection; } StringRef getRangeSection() override { return RangeSection; } + StringRef getMacinfoSection() override { return MacinfoSection; } StringRef getPubNamesSection() override { return PubNamesSection; } StringRef getPubTypesSection() override { return PubTypesSection; } StringRef getGnuPubNamesSection() override { return GnuPubNamesSection; } @@ -293,6 +310,8 @@ public: StringRef getAddrSection() override { return AddrSection; } + StringRef getCUIndexSection() override { return CUIndexSection; } + StringRef getTUIndexSection() override { return TUIndexSection; } }; } diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index 93e7c79..760950b 100644 --- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -196,7 +196,7 @@ public: // Fills the Result argument with the file and line information // corresponding to Address. Returns true on success. - bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir, + bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir, DILineInfoSpecifier::FileLineInfoKind Kind, DILineInfo &Result) const; @@ -247,7 +247,6 @@ private: const RelocAddrMap *RelocMap; LineTableMapTy LineTableMap; }; - } #endif diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h new file mode 100644 index 0000000..f791096 --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h @@ -0,0 +1,59 @@ +//===-- DWARFDebugMacro.h ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H
+#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Dwarf.h"
+
+namespace llvm {
+
+class raw_ostream;
+
+class DWARFDebugMacro {
+ /// A single macro entry within a macro list.
+ struct Entry {
+ /// The type of the macro entry.
+ uint32_t Type;
+ union {
+ /// The source line where the macro is defined.
+ uint64_t Line;
+ /// Vendor extension constant value.
+ uint64_t ExtConstant;
+ };
+
+ union {
+ /// The string (name, value) of the macro entry.
+ const char *MacroStr;
+ // An unsigned integer indicating the identity of the source file.
+ uint64_t File;
+ /// Vendor extension string.
+ const char *ExtStr;
+ };
+ };
+
+ typedef SmallVector<Entry, 4> MacroList;
+
+ /// A list of all the macro entries in the debug_macinfo section.
+ MacroList Macros;
+
+public:
+ DWARFDebugMacro() {}
+ /// Print the macro list found within the debug_macinfo section.
+ void dump(raw_ostream &OS) const;
+ /// Parse the debug_macinfo section accessible via the 'data' parameter.
+ void parse(DataExtractor data);
+};
+
+}
+
+#endif
diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h index 7ddcc0d..3c32a3e 100644 --- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -84,6 +84,9 @@ public: const DWARFUnit *u) const; static bool skipValue(uint16_t form, DataExtractor debug_info_data, uint32_t *offset_ptr, const DWARFUnit *u); + static bool skipValue(uint16_t form, DataExtractor debug_info_data, + uint32_t *offset_ptr, uint16_t Version, + uint8_t AddrSize); static ArrayRef<uint8_t> getFixedFormSizes(uint8_t AddrSize, uint16_t Version); diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h index f24e278..894a88d 100644 --- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h +++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h @@ -21,13 +21,17 @@ private: public: DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, - StringRef SOS, StringRef AOS, bool LE, - const DWARFUnitSectionBase &UnitSection) - : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LE, UnitSection) {} + StringRef SOS, StringRef AOS, StringRef LS, bool LE, + const DWARFUnitSectionBase &UnitSection, + const DWARFUnitIndex::Entry *Entry) + : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, UnitSection, + Entry) {} uint32_t getHeaderSize() const override { return DWARFUnit::getHeaderSize() + 12; } void dump(raw_ostream &OS); + static const DWARFSectionKind Section = DW_SECT_TYPES; + protected: bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) override; }; diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h index 5604b93..681b2aa 100644 --- a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -16,6 +16,7 @@ #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/DebugInfo/DWARF/DWARFSection.h" +#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" #include <vector> namespace llvm { @@ -39,28 +40,25 @@ public: virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0; void parse(DWARFContext &C, const DWARFSection &Section); - void parseDWO(DWARFContext &C, const DWARFSection &DWOSection); + void parseDWO(DWARFContext &C, const DWARFSection &DWOSection, + DWARFUnitIndex *Index = nullptr); protected: virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, - StringRef SOS, StringRef AOS, bool isLittleEndian) = 0; + StringRef SOS, StringRef AOS, StringRef LS, + bool isLittleEndian) = 0; ~DWARFUnitSectionBase() = default; }; +const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context, + DWARFSectionKind Kind); + /// Concrete instance of DWARFUnitSection, specialized for one Unit type. template<typename UnitType> class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>, public DWARFUnitSectionBase { - - struct UnitOffsetComparator { - bool operator()(uint32_t LHS, - const std::unique_ptr<UnitType> &RHS) const { - return LHS < RHS->getNextUnitOffset(); - } - }; - bool Parsed; public: @@ -73,8 +71,11 @@ public: typedef llvm::iterator_range<typename UnitVector::iterator> iterator_range; UnitType *getUnitForOffset(uint32_t Offset) const override { - auto *CU = std::upper_bound(this->begin(), this->end(), Offset, - UnitOffsetComparator()); + auto *CU = std::upper_bound( + this->begin(), this->end(), Offset, + [](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) { + return LHS < RHS->getNextUnitOffset(); + }); if (CU != this->end()) return CU->get(); return nullptr; @@ -83,14 +84,16 @@ public: private: void parseImpl(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, - StringRef SOS, StringRef AOS, bool LE) override { + StringRef SOS, StringRef AOS, StringRef LS, bool LE) override { if (Parsed) return; + const auto &Index = getDWARFUnitIndex(Context, UnitType::Section); DataExtractor Data(Section.Data, LE, 0); uint32_t Offset = 0; while (Data.isValidOffset(Offset)) { auto U = llvm::make_unique<UnitType>(Context, Section, DA, RS, SS, SOS, - AOS, LE, *this); + AOS, LS, LE, *this, + Index.getFromOffset(Offset)); if (!U->extract(Data, &Offset)) break; this->push_back(std::move(U)); @@ -108,6 +111,7 @@ class DWARFUnit { const DWARFDebugAbbrev *Abbrev; StringRef RangeSection; uint32_t RangeSectionBase; + StringRef LineSection; StringRef StringSection; StringRef StringOffsetSection; StringRef AddrOffsetSection; @@ -134,6 +138,8 @@ class DWARFUnit { }; std::unique_ptr<DWOHolder> DWO; + const DWARFUnitIndex::Entry *IndexEntry; + protected: virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr); /// Size in bytes of the unit header. @@ -142,13 +148,15 @@ protected: public: DWARFUnit(DWARFContext &Context, const DWARFSection &Section, const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, - StringRef SOS, StringRef AOS, bool LE, - const DWARFUnitSectionBase &UnitSection); + StringRef SOS, StringRef AOS, StringRef LS, bool LE, + const DWARFUnitSectionBase &UnitSection, + const DWARFUnitIndex::Entry *IndexEntry = nullptr); virtual ~DWARFUnit(); DWARFContext& getContext() const { return Context; } + StringRef getLineSection() const { return LineSection; } StringRef getStringSection() const { return StringSection; } StringRef getStringOffsetSection() const { return StringOffsetSection; } void setAddrOffsetSection(StringRef AOS, uint32_t Base) { @@ -246,12 +254,19 @@ public: assert(!DieArray.empty()); auto it = std::lower_bound( DieArray.begin(), DieArray.end(), Offset, - [=](const DWARFDebugInfoEntryMinimal &LHS, uint32_t Offset) { + [](const DWARFDebugInfoEntryMinimal &LHS, uint32_t Offset) { return LHS.getOffset() < Offset; }); return it == DieArray.end() ? nullptr : &*it; } + uint32_t getLineTableOffset() const { + if (IndexEntry) + if (const auto *Contrib = IndexEntry->getOffset(DW_SECT_LINE)) + return Contrib->Offset; + return 0; + } + private: /// Size in bytes of the .debug_info data associated with this compile unit. size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); } diff --git a/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h new file mode 100644 index 0000000..a85c2f9 --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h @@ -0,0 +1,81 @@ +//===-- DWARFUnitIndex.h --------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_DEBUGINFO_DWARFUNITINDEX_H +#define LLVM_LIB_DEBUGINFO_DWARFUNITINDEX_H + +#include "llvm/Support/DataExtractor.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" +#include <cstdint> + +namespace llvm { + +enum DWARFSectionKind { + DW_SECT_INFO = 1, + DW_SECT_TYPES, + DW_SECT_ABBREV, + DW_SECT_LINE, + DW_SECT_LOC, + DW_SECT_STR_OFFSETS, + DW_SECT_MACINFO, + DW_SECT_MACRO, +}; + +class DWARFUnitIndex { + struct Header { + uint32_t Version; + uint32_t NumColumns; + uint32_t NumUnits; + uint32_t NumBuckets = 0; + + bool parse(DataExtractor IndexData, uint32_t *OffsetPtr); + void dump(raw_ostream &OS) const; + }; + +public: + class Entry { + public: + struct SectionContribution { + uint32_t Offset; + uint32_t Length; + }; + + private: + const DWARFUnitIndex *Index; + uint64_t Signature; + std::unique_ptr<SectionContribution[]> Contributions; + friend class DWARFUnitIndex; + + public: + const SectionContribution *getOffset(DWARFSectionKind Sec) const; + const SectionContribution *getOffset() const; + }; + +private: + struct Header Header; + + DWARFSectionKind InfoColumnKind; + int InfoColumn = -1; + std::unique_ptr<DWARFSectionKind[]> ColumnKinds; + std::unique_ptr<Entry[]> Rows; + + static StringRef getColumnHeader(DWARFSectionKind DS); + bool parseImpl(DataExtractor IndexData); + +public: + bool parse(DataExtractor IndexData); + DWARFUnitIndex(DWARFSectionKind InfoColumnKind) + : InfoColumnKind(InfoColumnKind) {} + void dump(raw_ostream &OS) const; + const Entry *getFromOffset(uint32_t Offset) const; +}; +} + +#endif diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBContext.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBContext.h index 2bb9746..9404a59 100644 --- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBContext.h +++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBContext.h @@ -32,8 +32,7 @@ class PDBContext : public DIContext { public: PDBContext(const object::COFFObjectFile &Object, - std::unique_ptr<IPDBSession> PDBSession, - bool RelativeAddress); + std::unique_ptr<IPDBSession> PDBSession); static bool classof(const DIContext *DICtx) { return DICtx->getKind() == CK_PDB; diff --git a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBTypes.h b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBTypes.h index 2d19e79..a932a56 100644 --- a/contrib/llvm/include/llvm/DebugInfo/PDB/PDBTypes.h +++ b/contrib/llvm/include/llvm/DebugInfo/PDB/PDBTypes.h @@ -11,6 +11,7 @@ #define LLVM_DEBUGINFO_PDB_PDBTYPES_H #include "llvm/Config/llvm-config.h" +#include "llvm/Support/Endian.h" #include <functional> #include <stdint.h> @@ -500,6 +501,35 @@ struct Variant { bool operator!=(const Variant &Other) const { return !(*this == Other); } }; +namespace PDB { +static const char Magic[] = {'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', + 't', ' ', 'C', '/', 'C', '+', '+', ' ', + 'M', 'S', 'F', ' ', '7', '.', '0', '0', + '\r', '\n', '\x1a', 'D', 'S', '\0', '\0', '\0'}; + +// The superblock is overlaid at the beginning of the file (offset 0). +// It starts with a magic header and is followed by information which describes +// the layout of the file system. +struct SuperBlock { + char MagicBytes[sizeof(Magic)]; + // The file system is split into a variable number of fixed size elements. + // These elements are referred to as blocks. The size of a block may vary + // from system to system. + support::ulittle32_t BlockSize; + // This field's purpose is not yet known. + support::ulittle32_t Unknown0; + // This contains the number of blocks resident in the file system. In + // practice, NumBlocks * BlockSize is equivalent to the size of the PDB file. + support::ulittle32_t NumBlocks; + // This contains the number of bytes which make up the directory. + support::ulittle32_t NumDirectoryBytes; + // This field's purpose is not yet known. + support::ulittle32_t Unknown1; + // This contains the block # of the block map. + support::ulittle32_t BlockMapAddr; +}; +} + } // namespace llvm namespace std { @@ -513,4 +543,5 @@ template <> struct hash<llvm::PDB_SymType> { }; } + #endif diff --git a/contrib/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h b/contrib/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h new file mode 100644 index 0000000..0703fb1 --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h @@ -0,0 +1,47 @@ +//===- llvm/DebugInfo/Symbolize/DIPrinter.h ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the DIPrinter class, which is responsible for printing +// structures defined in DebugInfo/DIContext.h +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_SYMBOLIZE_DIPRINTER_H +#define LLVM_DEBUGINFO_SYMBOLIZE_DIPRINTER_H + +#include "llvm/Support/raw_ostream.h" + +namespace llvm { +struct DILineInfo; +class DIInliningInfo; +struct DIGlobal; + +namespace symbolize { + +class DIPrinter { + raw_ostream &OS; + bool PrintFunctionNames; + bool PrintPretty; + void printName(const DILineInfo &Info, bool Inlined); + +public: + DIPrinter(raw_ostream &OS, bool PrintFunctionNames = true, + bool PrintPretty = false) + : OS(OS), PrintFunctionNames(PrintFunctionNames), + PrintPretty(PrintPretty) {} + + DIPrinter &operator<<(const DILineInfo &Info); + DIPrinter &operator<<(const DIInliningInfo &Info); + DIPrinter &operator<<(const DIGlobal &Global); +}; +} +} + +#endif + diff --git a/contrib/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h b/contrib/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h new file mode 100644 index 0000000..ff9cc80 --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h @@ -0,0 +1,53 @@ +//===-- SymbolizableModule.h ------------------------------------ C++ -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the SymbolizableModule interface. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEMODULE_H +#define LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEMODULE_H + +#include "llvm/DebugInfo/DIContext.h" +#include <memory> +#include <string> + +namespace llvm { +namespace object { +class ObjectFile; +} +} + +namespace llvm { +namespace symbolize { + +using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind; + +class SymbolizableModule { +public: + virtual ~SymbolizableModule() {} + virtual DILineInfo symbolizeCode(uint64_t ModuleOffset, + FunctionNameKind FNKind, + bool UseSymbolTable) const = 0; + virtual DIInliningInfo symbolizeInlinedCode(uint64_t ModuleOffset, + FunctionNameKind FNKind, + bool UseSymbolTable) const = 0; + virtual DIGlobal symbolizeData(uint64_t ModuleOffset) const = 0; + + // Return true if this is a 32-bit x86 PE COFF module. + virtual bool isWin32Module() const = 0; + + // Returns the preferred base of the module, i.e. where the loader would place + // it in memory assuming there were no conflicts. + virtual uint64_t getModulePreferredBase() const = 0; +}; + +} // namespace symbolize +} // namespace llvm + +#endif // LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEMODULE_H diff --git a/contrib/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/contrib/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h new file mode 100644 index 0000000..ec3ae00 --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -0,0 +1,105 @@ +//===-- Symbolize.h --------------------------------------------- C++ -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Header for LLVM symbolization library. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H +#define LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H + +#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/ErrorOr.h" +#include <map> +#include <memory> +#include <string> + +namespace llvm { +namespace symbolize { + +using namespace object; +using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind; + +class LLVMSymbolizer { +public: + struct Options { + FunctionNameKind PrintFunctions; + bool UseSymbolTable : 1; + bool Demangle : 1; + bool RelativeAddresses : 1; + std::string DefaultArch; + std::vector<std::string> DsymHints; + Options(FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName, + bool UseSymbolTable = true, bool Demangle = true, + bool RelativeAddresses = false, std::string DefaultArch = "") + : PrintFunctions(PrintFunctions), UseSymbolTable(UseSymbolTable), + Demangle(Demangle), RelativeAddresses(RelativeAddresses), + DefaultArch(DefaultArch) {} + }; + + LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {} + ~LLVMSymbolizer() { + flush(); + } + + ErrorOr<DILineInfo> symbolizeCode(const std::string &ModuleName, + uint64_t ModuleOffset); + ErrorOr<DIInliningInfo> symbolizeInlinedCode(const std::string &ModuleName, + uint64_t ModuleOffset); + ErrorOr<DIGlobal> symbolizeData(const std::string &ModuleName, + uint64_t ModuleOffset); + void flush(); + static std::string DemangleName(const std::string &Name, + const SymbolizableModule *ModInfo); + +private: + // Bundles together object file with code/data and object file with + // corresponding debug info. These objects can be the same. + typedef std::pair<ObjectFile*, ObjectFile*> ObjectPair; + + ErrorOr<SymbolizableModule *> + getOrCreateModuleInfo(const std::string &ModuleName); + ObjectFile *lookUpDsymFile(const std::string &Path, + const MachOObjectFile *ExeObj, + const std::string &ArchName); + ObjectFile *lookUpDebuglinkObject(const std::string &Path, + const ObjectFile *Obj, + const std::string &ArchName); + + /// \brief Returns pair of pointers to object and debug object. + ErrorOr<ObjectPair> getOrCreateObjectPair(const std::string &Path, + const std::string &ArchName); + + /// \brief Return a pointer to object file at specified path, for a specified + /// architecture (e.g. if path refers to a Mach-O universal binary, only one + /// object file from it will be returned). + ErrorOr<ObjectFile *> getOrCreateObject(const std::string &Path, + const std::string &ArchName); + + std::map<std::string, ErrorOr<std::unique_ptr<SymbolizableModule>>> Modules; + + /// \brief Contains cached results of getOrCreateObjectPair(). + std::map<std::pair<std::string, std::string>, ErrorOr<ObjectPair>> + ObjectPairForPathArch; + + /// \brief Contains parsed binary for each path, or parsing error. + std::map<std::string, ErrorOr<OwningBinary<Binary>>> BinaryForPath; + + /// \brief Parsed object file for path/architecture pair, where "path" refers + /// to Mach-O universal binary. + std::map<std::pair<std::string, std::string>, ErrorOr<std::unique_ptr<ObjectFile>>> + ObjectForUBPathAndArch; + + Options Opts; +}; + +} // namespace symbolize +} // namespace llvm + +#endif |