[llvm] r257658 - [readobj] Expand CodeView dumping functionality
Reid Kleckner via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 13 11:32:37 PST 2016
Author: rnk
Date: Wed Jan 13 13:32:35 2016
New Revision: 257658
URL: http://llvm.org/viewvc/llvm-project?rev=257658&view=rev
Log:
[readobj] Expand CodeView dumping functionality
This rewrites and expands the existing codeview dumping functionality in
llvm-readobj using techniques similar to those in lib/Object. This defines a
number of new records and enums useful for reading memory mapped codeview
sections in COFF objects.
The dumper is intended as a testing tool for LLVM as it grows more codeview
output capabilities.
Reviewers: majnemer
Differential Revision: http://reviews.llvm.org/D16104
Added:
llvm/trunk/tools/llvm-readobj/CVLeafTypes.def
llvm/trunk/tools/llvm-readobj/CVSymbolTypes.def
llvm/trunk/tools/llvm-readobj/CodeView.h
Modified:
llvm/trunk/include/llvm/DebugInfo/CodeView/CodeView.h
llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h
llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h
llvm/trunk/include/llvm/Support/COFF.h
llvm/trunk/include/llvm/Support/Endian.h
llvm/trunk/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp
llvm/trunk/test/DebugInfo/COFF/asm.ll
llvm/trunk/test/DebugInfo/COFF/cpp-mangling.ll
llvm/trunk/test/DebugInfo/COFF/multifile.ll
llvm/trunk/test/DebugInfo/COFF/multifunction.ll
llvm/trunk/test/DebugInfo/COFF/simple.ll
llvm/trunk/test/tools/llvm-readobj/codeview-linetables.test
llvm/trunk/tools/llvm-pdbdump/FunctionDumper.cpp
llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
llvm/trunk/tools/llvm-readobj/StreamWriter.h
llvm/trunk/tools/llvm-readobj/llvm-readobj.h
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/CodeView.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/CodeView.h?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/CodeView.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/CodeView.h Wed Jan 13 13:32:35 2016
@@ -15,6 +15,97 @@
namespace llvm {
namespace codeview {
+/// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented
+/// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
+enum class CPUType : uint16_t {
+ Intel8080 = 0x0,
+ Intel8086 = 0x1,
+ Intel80286 = 0x2,
+ Intel80386 = 0x3,
+ Intel80486 = 0x4,
+ Pentium = 0x5,
+ PentiumPro = 0x6,
+ Pentium3 = 0x7,
+ MIPS = 0x10,
+ MIPS16 = 0x11,
+ MIPS32 = 0x12,
+ MIPS64 = 0x13,
+ MIPSI = 0x14,
+ MIPSII = 0x15,
+ MIPSIII = 0x16,
+ MIPSIV = 0x17,
+ MIPSV = 0x18,
+ M68000 = 0x20,
+ M68010 = 0x21,
+ M68020 = 0x22,
+ M68030 = 0x23,
+ M68040 = 0x24,
+ Alpha = 0x30,
+ Alpha21164 = 0x31,
+ Alpha21164A = 0x32,
+ Alpha21264 = 0x33,
+ Alpha21364 = 0x34,
+ PPC601 = 0x40,
+ PPC603 = 0x41,
+ PPC604 = 0x42,
+ PPC620 = 0x43,
+ PPCFP = 0x44,
+ PPCBE = 0x45,
+ SH3 = 0x50,
+ SH3E = 0x51,
+ SH3DSP = 0x52,
+ SH4 = 0x53,
+ SHMedia = 0x54,
+ ARM3 = 0x60,
+ ARM4 = 0x61,
+ ARM4T = 0x62,
+ ARM5 = 0x63,
+ ARM5T = 0x64,
+ ARM6 = 0x65,
+ ARM_XMAC = 0x66,
+ ARM_WMMX = 0x67,
+ ARM7 = 0x68,
+ Omni = 0x70,
+ Ia64 = 0x80,
+ Ia64_2 = 0x81,
+ CEE = 0x90,
+ AM33 = 0xa0,
+ M32R = 0xb0,
+ TriCore = 0xc0,
+ X64 = 0xd0,
+ EBC = 0xe0,
+ Thumb = 0xf0,
+ ARMNT = 0xf4,
+ D3D11_Shader = 0x100,
+};
+
+/// These values correspond to the CV_CFL_LANG enumeration, and are documented
+/// here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx
+enum SourceLanguage : uint8_t {
+ C = 0x00,
+ Cpp = 0x01,
+ Fortran = 0x02,
+ Masm = 0x03,
+ Pascal = 0x04,
+ Basic = 0x05,
+ Cobol = 0x06,
+ Link = 0x07,
+ Cvtres = 0x08,
+ Cvtpgd = 0x09,
+ CSharp = 0x0a,
+ VB = 0x0b,
+ ILAsm = 0x0c,
+ Java = 0x0d,
+ JScript = 0x0e,
+ MSIL = 0x0f,
+ HLSL = 0x10
+};
+
+/// These values correspond to the CV_call_e enumeration, and are documented
+/// at the following locations:
+/// https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
+/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680207(v=vs.85).aspx
+///
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
@@ -140,6 +231,7 @@ enum class HfaKind : uint8_t {
Other = 0x03
};
+/// Source-level access specifier. (CV_access_e)
enum class MemberAccess : uint8_t {
None = 0,
Private = 1,
@@ -147,6 +239,7 @@ enum class MemberAccess : uint8_t {
Public = 3
};
+/// Part of member attribute flags. (CV_methodprop_e)
enum class MethodKind : uint8_t {
Vanilla = 0x00,
Virtual = 0x01,
@@ -157,9 +250,14 @@ enum class MethodKind : uint8_t {
PureIntroducingVirtual = 0x06
};
+/// Equivalent to CV_fldattr_t bitfield.
enum class MethodOptions : uint16_t {
None = 0x0000,
+ AccessMask = 0x0003,
+ MethodKindMask = 0x001c,
Pseudo = 0x0020,
+ NoInherit = 0x0040,
+ NoConstruct = 0x0080,
CompilerGenerated = 0x0100,
Sealed = 0x0200
};
@@ -178,6 +276,7 @@ inline MethodOptions operator~(MethodOpt
return static_cast<MethodOptions>(~static_cast<uint16_t>(a));
}
+/// Equivalent to CV_modifier_t.
enum class ModifierOptions : uint16_t {
None = 0x0000,
Const = 0x0001,
@@ -207,9 +306,18 @@ enum class ModuleSubstreamKind : uint32_
FrameData = 0xf5,
InlineeLines = 0xf6,
CrossScopeImports = 0xf7,
- CrossScopeExports = 0xf8
+ CrossScopeExports = 0xf8,
+
+ // These appear to relate to .Net assembly info.
+ ILLines = 0xf9,
+ FuncMDTokenMap = 0xfa,
+ TypeMDTokenMap = 0xfb,
+ MergedAssemblyInput = 0xfc,
+
+ CoffSymbolRVA = 0xfd,
};
+/// Equivalent to CV_ptrtype_e.
enum class PointerKind : uint8_t {
Near16 = 0x00, // 16 bit pointer
Far16 = 0x01, // 16:16 far pointer
@@ -226,6 +334,7 @@ enum class PointerKind : uint8_t {
Near64 = 0x0c // 64 bit pointer
};
+/// Equivalent to CV_ptrmode_e.
enum class PointerMode : uint8_t {
Pointer = 0x00, // "normal" pointer
LValueReference = 0x01, // "old" reference
@@ -234,6 +343,7 @@ enum class PointerMode : uint8_t {
RValueReference = 0x04 // r-value reference
};
+/// Equivalent to misc lfPointerAttr bitfields.
enum class PointerOptions : uint32_t {
None = 0x00000000,
Flat32 = 0x00000100,
@@ -258,6 +368,7 @@ inline PointerOptions operator~(PointerO
return static_cast<PointerOptions>(~static_cast<uint16_t>(a));
}
+/// Equivalent to CV_pmtype_e.
enum class PointerToMemberRepresentation : uint16_t {
Unknown = 0x00, // not specified (pre VC8)
SingleInheritanceData = 0x01, // member data, single inheritance
Modified: llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/CodeView/TypeIndex.h Wed Jan 13 13:32:35 2016
@@ -74,6 +74,9 @@ enum class SimpleTypeMode : uint32_t {
NearPointer128 = 0x00000700 // 128 bit near pointer
};
+/// A 32-bit type reference. Types are indexed by their order of appearance in
+/// .debug$T plus 0x1000. Type indices less than 0x1000 are "simple" types,
+/// composed of a SimpleTypeMode byte followed by a SimpleTypeKind byte.
class TypeIndex {
public:
static const uint32_t FirstNonSimpleIndex = 0x1000;
@@ -91,6 +94,8 @@ public:
uint32_t getIndex() const { return Index; }
bool isSimple() const { return Index < FirstNonSimpleIndex; }
+ bool isNoType() const { return Index == 0; }
+
SimpleTypeKind getSimpleKind() const {
assert(isSimple());
return static_cast<SimpleTypeKind>(Index & SimpleKindMask);
@@ -144,7 +149,7 @@ public:
static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); }
private:
- uint32_t Index;
+ ulittle32_t Index;
};
inline bool operator==(const TypeIndex &A, const TypeIndex &B) {
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/PDBTypes.h Wed Jan 13 13:32:35 2016
@@ -11,6 +11,7 @@
#define LLVM_DEBUGINFO_PDB_PDBTYPES_H
#include "llvm/Config/llvm-config.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/Support/Endian.h"
#include <functional>
#include <stdint.h>
@@ -108,67 +109,7 @@ enum class PDB_Checksum { None = 0, MD5
/// These values correspond to the CV_CPU_TYPE_e enumeration, and are documented
/// here: https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
-enum class PDB_Cpu {
- Intel8080 = 0x0,
- Intel8086 = 0x1,
- Intel80286 = 0x2,
- Intel80386 = 0x3,
- Intel80486 = 0x4,
- Pentium = 0x5,
- PentiumPro = 0x6,
- Pentium3 = 0x7,
- MIPS = 0x10,
- MIPS16 = 0x11,
- MIPS32 = 0x12,
- MIPS64 = 0x13,
- MIPSI = 0x14,
- MIPSII = 0x15,
- MIPSIII = 0x16,
- MIPSIV = 0x17,
- MIPSV = 0x18,
- M68000 = 0x20,
- M68010 = 0x21,
- M68020 = 0x22,
- M68030 = 0x23,
- M68040 = 0x24,
- Alpha = 0x30,
- Alpha21164 = 0x31,
- Alpha21164A = 0x32,
- Alpha21264 = 0x33,
- Alpha21364 = 0x34,
- PPC601 = 0x40,
- PPC603 = 0x41,
- PPC604 = 0x42,
- PPC620 = 0x43,
- PPCFP = 0x44,
- PPCBE = 0x45,
- SH3 = 0x50,
- SH3E = 0x51,
- SH3DSP = 0x52,
- SH4 = 0x53,
- SHMedia = 0x54,
- ARM3 = 0x60,
- ARM4 = 0x61,
- ARM4T = 0x62,
- ARM5 = 0x63,
- ARM5T = 0x64,
- ARM6 = 0x65,
- ARM_XMAC = 0x66,
- ARM_WMMX = 0x67,
- ARM7 = 0x68,
- Omni = 0x70,
- Ia64 = 0x80,
- Ia64_2 = 0x81,
- CEE = 0x90,
- AM33 = 0xa0,
- M32R = 0xb0,
- TriCore = 0xc0,
- X64 = 0xd0,
- EBC = 0xe0,
- Thumb = 0xf0,
- ARMNT = 0xf4,
- D3D11_Shader = 0x100,
-};
+typedef codeview::CPUType PDB_Cpu;
enum class PDB_Machine {
Invalid = 0xffff,
@@ -200,56 +141,11 @@ enum class PDB_Machine {
/// https://msdn.microsoft.com/en-us/library/b2fc64ek.aspx
/// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680207(v=vs.85).aspx
///
-enum class PDB_CallingConv {
- NearCdecl = 0x00,
- FarCdecl = 0x01,
- NearPascal = 0x02,
- FarPascal = 0x03,
- NearFastcall = 0x04,
- FarFastcall = 0x05,
- Skipped = 0x06,
- NearStdcall = 0x07,
- FarStdcall = 0x08,
- NearSyscall = 0x09,
- FarSyscall = 0x0a,
- Thiscall = 0x0b,
- MipsCall = 0x0c,
- Generic = 0x0d,
- Alphacall = 0x0e,
- Ppccall = 0x0f,
- SuperHCall = 0x10,
- Armcall = 0x11,
- AM33call = 0x12,
- Tricall = 0x13,
- Sh5call = 0x14,
- M32R = 0x15,
- Clrcall = 0x16,
- Inline = 0x17,
- NearVectorcall = 0x18,
- Reserved = 0x19,
-};
+typedef codeview::CallingConvention PDB_CallingConv;
/// These values correspond to the CV_CFL_LANG enumeration, and are documented
/// here: https://msdn.microsoft.com/en-us/library/bw3aekw6.aspx
-enum class PDB_Lang {
- C = 0x00,
- Cpp = 0x01,
- Fortran = 0x02,
- Masm = 0x03,
- Pascal = 0x04,
- Basic = 0x05,
- Cobol = 0x06,
- Link = 0x07,
- Cvtres = 0x08,
- Cvtpgd = 0x09,
- CSharp = 0x0a,
- VB = 0x0b,
- ILAsm = 0x0c,
- Java = 0x0d,
- JScript = 0x0e,
- MSIL = 0x0f,
- HLSL = 0x10
-};
+typedef codeview::SourceLanguage PDB_Lang;
/// These values correspond to the DataKind enumeration, and are documented
/// here: https://msdn.microsoft.com/en-us/library/b2x2t313.aspx
Modified: llvm/trunk/include/llvm/Support/COFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/COFF.h?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/COFF.h (original)
+++ llvm/trunk/include/llvm/Support/COFF.h Wed Jan 13 13:32:35 2016
@@ -674,6 +674,7 @@ namespace COFF {
DEBUG_INDEX_SUBSECTION = 0xF4,
// Symbol subsections are split into records of different types.
+ DEBUG_SYMBOL_TYPE_LOCAL_PROC_START = 0x1146,
DEBUG_SYMBOL_TYPE_PROC_START = 0x1147,
DEBUG_SYMBOL_TYPE_PROC_END = 0x114F
};
Modified: llvm/trunk/include/llvm/Support/Endian.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Endian.h?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/Endian.h (original)
+++ llvm/trunk/include/llvm/Support/Endian.h Wed Jan 13 13:32:35 2016
@@ -173,6 +173,10 @@ template<typename value_type,
endianness endian,
std::size_t alignment>
struct packed_endian_specific_integral {
+ packed_endian_specific_integral() = default;
+
+ explicit packed_endian_specific_integral(value_type val) { *this = val; }
+
operator value_type() const {
return endian::read<value_type, endian, alignment>(
(const void*)Value.buffer);
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp Wed Jan 13 13:32:35 2016
@@ -199,7 +199,6 @@ void WinCodeViewLineTables::emitDebugInf
return;
assert(FI.End && "Don't know where the function ends?");
- StringRef GVName = GV->getName();
StringRef FuncName;
if (auto *SP = getDISubprogram(GV))
FuncName = SP->getDisplayName();
@@ -208,8 +207,8 @@ void WinCodeViewLineTables::emitDebugInf
// "namespace_foo::bar" function, see PR21528. Luckily, dbghelp.dll is trying
// to demangle display names anyways, so let's just put a mangled name into
// the symbols subsection until Clang gives us what we need.
- if (GVName.startswith("\01?"))
- FuncName = GVName.substr(1);
+ if (FuncName.empty())
+ FuncName = GlobalValue::getRealLinkageName(GV->getName());
// Emit a symbol subsection, required by VS2012+ to find function boundaries.
MCSymbol *SymbolsBegin = Asm->MMI->getContext().createTempSymbol(),
*SymbolsEnd = Asm->MMI->getContext().createTempSymbol();
Modified: llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/PDBExtras.cpp Wed Jan 13 13:32:35 2016
@@ -43,32 +43,30 @@ raw_ostream &llvm::operator<<(raw_ostrea
raw_ostream &llvm::operator<<(raw_ostream &OS, const PDB_CallingConv &Conv) {
OS << "__";
switch (Conv) {
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearCdecl, "cdecl", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarCdecl, "cdecl", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearPascal, "pascal", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarPascal, "pascal", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearFastcall, "fastcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarFastcall, "fastcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Skipped, "skippedcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearStdcall, "stdcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarStdcall, "stdcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearSyscall, "syscall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarSyscall, "syscall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Thiscall, "thiscall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, MipsCall, "mipscall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Generic, "genericcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Alphacall, "alphacall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Ppccall, "ppccall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, SuperHCall, "superhcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Armcall, "armcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, AM33call, "am33call", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Tricall, "tricall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Sh5call, "sh5call", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, M32R, "m32rcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Clrcall, "clrcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Inline, "inlinecall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearVectorcall, "vectorcall",
- OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearC , "cdecl", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarC , "cdecl", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearPascal , "pascal", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarPascal , "pascal", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearFast , "fastcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarFast , "fastcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearStdCall, "stdcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarStdCall , "stdcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearSysCall, "syscall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarSysCall , "syscall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, ThisCall , "thiscall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, MipsCall , "mipscall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Generic , "genericcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, AlphaCall , "alphacall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, PpcCall , "ppccall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, SHCall , "superhcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, ArmCall , "armcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, AM33Call , "am33call", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, TriCall , "tricall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, SH5Call , "sh5call", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, M32RCall , "m32rcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, ClrCall , "clrcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Inline , "inlinecall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearVector , "vectorcall", OS)
default:
OS << "unknowncall";
}
Modified: llvm/trunk/test/DebugInfo/COFF/asm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/asm.ll?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/asm.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/asm.ll Wed Jan 13 13:32:35 2016
@@ -96,14 +96,14 @@
; OBJ32-NEXT: ]
; OBJ32: CodeViewDebugInfo [
; OBJ32: Subsection [
-; OBJ32-NEXT: Type: 0xF1
+; OBJ32-NEXT: SubSectionType: Symbols (0xF1)
; OBJ32-NOT: ]
; OBJ32: ProcStart {
-; OBJ32-NEXT: DisplayName: f
-; OBJ32-NEXT: Section: _f
-; OBJ32-NEXT: CodeSize: 0x6
-; OBJ32-NEXT: }
-; OBJ32-NEXT: ProcEnd
+; OBJ32: CodeSize: 0x6
+; OBJ32: DisplayName: f
+; OBJ32: LinkageName: _f
+; OBJ32: }
+; OBJ32: ProcEnd
; OBJ32-NEXT: ]
; OBJ32: FunctionLineTable [
; OBJ32-NEXT: Name: _f
@@ -228,13 +228,13 @@
; OBJ64-NEXT: 0x48 IMAGE_REL_AMD64_SECTION f
; OBJ64-NEXT: ]
; OBJ64: Subsection [
-; OBJ64-NEXT: Type: 0xF1
+; OBJ64-NEXT: SubSectionType: Symbols (0xF1)
; OBJ64-NOT: ]
; OBJ64: ProcStart {
-; OBJ64-NEXT: DisplayName: f
-; OBJ64-NEXT: Section: f
-; OBJ64-NEXT: CodeSize: 0xE
-; OBJ64-NEXT: }
+; OBJ64: CodeSize: 0xE
+; OBJ64: DisplayName: f
+; OBJ64: LinkageName: f
+; OBJ64: }
; OBJ64-NEXT: ProcEnd
; OBJ64-NEXT: ]
; OBJ64: FunctionLineTable [
Modified: llvm/trunk/test/DebugInfo/COFF/cpp-mangling.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/cpp-mangling.ll?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/cpp-mangling.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/cpp-mangling.ll Wed Jan 13 13:32:35 2016
@@ -10,8 +10,8 @@
; CHECK: ProcStart {
; FIXME: The display name should in fact be "foo::bar", see PR21528
-; CHECK-NEXT: DisplayName: ?bar at foo@@YAHH at Z
-; CHECK-NEXT: Section: ?bar at foo@@YAHH at Z
+; CHECK: DisplayName: ?bar at foo@@YAHH at Z
+; CHECK-NEXT: LinkageName: ?bar at foo@@YAHH at Z
; Function Attrs: nounwind
define i32 @"\01?bar at foo@@YAHH at Z"(i32 %x) #0 {
Modified: llvm/trunk/test/DebugInfo/COFF/multifile.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/multifile.ll?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/multifile.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/multifile.ll Wed Jan 13 13:32:35 2016
@@ -122,13 +122,13 @@
; OBJ32-NEXT: 0x48 IMAGE_REL_I386_SECTION _f
; OBJ32-NEXT: ]
; OBJ32: Subsection [
-; OBJ32-NEXT: Type: 0xF1
+; OBJ32-NEXT: SubSectionType: Symbols (0xF1)
; OBJ32-NOT: ]
; OBJ32: ProcStart {
-; OBJ32-NEXT: DisplayName: f
-; OBJ32-NEXT: Section: _f
-; OBJ32-NEXT: CodeSize: 0x10
-; OBJ32-NEXT: }
+; OBJ32: CodeSize: 0x10
+; OBJ32: DisplayName: f
+; OBJ32: LinkageName: _f
+; OBJ32: }
; OBJ32-NEXT: ProcEnd
; OBJ32-NEXT: ]
; OBJ32: FunctionLineTable [
@@ -298,14 +298,14 @@
; OBJ64-NEXT: 0x48 IMAGE_REL_AMD64_SECTION f
; OBJ64-NEXT: ]
; OBJ64: Subsection [
-; OBJ64-NEXT: Type: 0xF1
+; OBJ64-NEXT: SubSectionType: Symbols (0xF1)
; OBJ64-NOT: ]
; OBJ64: ProcStart {
-; OBJ64-NEXT: DisplayName: f
-; OBJ64-NEXT: Section: f
-; OBJ64-NEXT: CodeSize: 0x18
-; OBJ64-NEXT: }
-; OBJ64-NEXT: ProcEnd
+; OBJ64: CodeSize: 0x18
+; OBJ64: DisplayName: f
+; OBJ64: LinkageName: f
+; OBJ64: }
+; OBJ64: ProcEnd
; OBJ64-NEXT: ]
; OBJ64: FunctionLineTable [
; OBJ64-NEXT: Name: f
Modified: llvm/trunk/test/DebugInfo/COFF/multifunction.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/multifunction.ll?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/multifunction.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/multifunction.ll Wed Jan 13 13:32:35 2016
@@ -221,43 +221,43 @@
; OBJ32-NEXT: 0x128 IMAGE_REL_I386_SECTION _f
; OBJ32-NEXT: ]
; OBJ32: Subsection [
-; OBJ32-NEXT: Type: 0xF1
+; OBJ32-NEXT: SubSectionType: Symbols (0xF1)
; OBJ32-NOT: ]
; OBJ32: ProcStart {
-; OBJ32-NEXT: DisplayName: x
-; OBJ32-NEXT: Section: _x
-; OBJ32-NEXT: CodeSize: 0x6
-; OBJ32-NEXT: }
-; OBJ32-NEXT: ProcEnd
+; OBJ32: CodeSize: 0x6
+; OBJ32: DisplayName: x
+; OBJ32: LinkageName: _x
+; OBJ32: }
+; OBJ32: ProcEnd
; OBJ32-NEXT: ]
; OBJ32: Subsection [
-; OBJ32-NEXT: Type: 0xF2
+; OBJ32-NEXT: SubSectionType: Lines (0xF2)
; OBJ32: ]
; OBJ32: Subsection [
-; OBJ32-NEXT: Type: 0xF1
+; OBJ32-NEXT: SubSectionType: Symbols (0xF1)
; OBJ32-NOT: ]
; OBJ32: ProcStart {
-; OBJ32-NEXT: DisplayName: y
-; OBJ32-NEXT: Section: _y
-; OBJ32-NEXT: CodeSize: 0x6
-; OBJ32-NEXT: }
-; OBJ32-NEXT: ProcEnd
+; OBJ32: CodeSize: 0x6
+; OBJ32: DisplayName: y
+; OBJ32: LinkageName: _y
+; OBJ32: }
+; OBJ32: ProcEnd
; OBJ32-NEXT: ]
; OBJ32: Subsection [
-; OBJ32-NEXT: Type: 0xF2
+; OBJ32-NEXT: SubSectionType: Lines (0xF2)
; OBJ32: ]
; OBJ32: Subsection [
-; OBJ32-NEXT: Type: 0xF1
+; OBJ32-NEXT: SubSectionType: Symbols (0xF1)
; OBJ32-NOT: ]
; OBJ32: ProcStart {
-; OBJ32-NEXT: DisplayName: f
-; OBJ32-NEXT: Section: _f
-; OBJ32-NEXT: CodeSize: 0x10
-; OBJ32-NEXT: }
-; OBJ32-NEXT: ProcEnd
+; OBJ32: CodeSize: 0x10
+; OBJ32: DisplayName: f
+; OBJ32: LinkageName: _f
+; OBJ32: }
+; OBJ32: ProcEnd
; OBJ32-NEXT: ]
; OBJ32: Subsection [
-; OBJ32-NEXT: Type: 0xF2
+; OBJ32-NEXT: SubSectionType: Lines (0xF2)
; OBJ32: ]
; OBJ32: FunctionLineTable [
; OBJ32-NEXT: Name: _x
@@ -564,43 +564,43 @@
; OBJ64-NEXT: 0x140 IMAGE_REL_AMD64_SECTION f
; OBJ64-NEXT: ]
; OBJ64: Subsection [
-; OBJ64-NEXT: Type: 0xF1
+; OBJ64-NEXT: SubSectionType: Symbols (0xF1)
; OBJ64-NOT: ]
; OBJ64: ProcStart {
-; OBJ64-NEXT: DisplayName: x
-; OBJ64-NEXT: Section: x
-; OBJ64-NEXT: CodeSize: 0xE
-; OBJ64-NEXT: }
-; OBJ64-NEXT: ProcEnd
+; OBJ64: CodeSize: 0xE
+; OBJ64: DisplayName: x
+; OBJ64: LinkageName: x
+; OBJ64: }
+; OBJ64: ProcEnd
; OBJ64-NEXT: ]
; OBJ64: Subsection [
-; OBJ64-NEXT: Type: 0xF2
+; OBJ64-NEXT: SubSectionType: Lines (0xF2)
; OBJ64: ]
; OBJ64: Subsection [
-; OBJ64-NEXT: Type: 0xF1
+; OBJ64-NEXT: SubSectionType: Symbols (0xF1)
; OBJ64-NOT: ]
; OBJ64: ProcStart {
-; OBJ64-NEXT: DisplayName: y
-; OBJ64-NEXT: Section: y
-; OBJ64-NEXT: CodeSize: 0xE
-; OBJ64-NEXT: }
-; OBJ64-NEXT: ProcEnd
+; OBJ64: CodeSize: 0xE
+; OBJ64: DisplayName: y
+; OBJ64: LinkageName: y
+; OBJ64: }
+; OBJ64: ProcEnd
; OBJ64-NEXT: ]
; OBJ64: Subsection [
-; OBJ64-NEXT: Type: 0xF2
+; OBJ64-NEXT: SubSectionType: Lines (0xF2)
; OBJ64: ]
; OBJ64: Subsection [
-; OBJ64-NEXT: Type: 0xF1
+; OBJ64-NEXT: SubSectionType: Symbols (0xF1)
; OBJ64-NOT: ]
; OBJ64: ProcStart {
-; OBJ64-NEXT: DisplayName: f
-; OBJ64-NEXT: Section: f
-; OBJ64-NEXT: CodeSize: 0x18
-; OBJ64-NEXT: }
-; OBJ64-NEXT: ProcEnd
+; OBJ64: CodeSize: 0x18
+; OBJ64: DisplayName: f
+; OBJ64: LinkageName: f
+; OBJ64: }
+; OBJ64: ProcEnd
; OBJ64-NEXT: ]
; OBJ64: Subsection [
-; OBJ64-NEXT: Type: 0xF2
+; OBJ64-NEXT: SubSectionType: Lines (0xF2)
; OBJ64: ]
; OBJ64: FunctionLineTable [
; OBJ64-NEXT: LinkageName: x
Modified: llvm/trunk/test/DebugInfo/COFF/simple.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/COFF/simple.ll?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/COFF/simple.ll (original)
+++ llvm/trunk/test/DebugInfo/COFF/simple.ll Wed Jan 13 13:32:35 2016
@@ -89,13 +89,13 @@
; OBJ32-NEXT: 0x48 IMAGE_REL_I386_SECTION _f
; OBJ32-NEXT: ]
; OBJ32: Subsection [
-; OBJ32-NEXT: Type: 0xF1
+; OBJ32-NEXT: SubSectionType: Symbols (0xF1)
; OBJ32-NOT: ]
; OBJ32: ProcStart {
-; OBJ32-NEXT: DisplayName: f
-; OBJ32-NEXT: Section: _f
-; OBJ32-NEXT: CodeSize: 0x6
-; OBJ32-NEXT: }
+; OBJ32: CodeSize: 0x6
+; OBJ32: DisplayName: f
+; OBJ32: LinkageName: _f
+; OBJ32: }
; OBJ32-NEXT: ProcEnd
; OBJ32-NEXT: ]
; OBJ32: FunctionLineTable [
@@ -207,13 +207,13 @@
; OBJ64-NEXT: 0x48 IMAGE_REL_AMD64_SECTION f
; OBJ64-NEXT: ]
; OBJ64: Subsection [
-; OBJ64-NEXT: Type: 0xF1
+; OBJ64-NEXT: SubSectionType: Symbols (0xF1)
; OBJ64-NOT: ]
; OBJ64: ProcStart {
-; OBJ64-NEXT: DisplayName: f
-; OBJ64-NEXT: Section: f
-; OBJ64-NEXT: CodeSize: 0xE
-; OBJ64-NEXT: }
+; OBJ64: CodeSize: 0xE
+; OBJ64: DisplayName: f
+; OBJ64: LinkageName: f
+; OBJ64: }
; OBJ64-NEXT: ProcEnd
; OBJ64-NEXT: ]
; OBJ64: FunctionLineTable [
Modified: llvm/trunk/test/tools/llvm-readobj/codeview-linetables.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/codeview-linetables.test?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/codeview-linetables.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/codeview-linetables.test Wed Jan 13 13:32:35 2016
@@ -28,79 +28,80 @@ RUN: llvm-readobj -s -codeview -section-
RUN: | FileCheck %s -check-prefix MFUN64
MFUN32: CodeViewDebugInfo [
+MFUN32-NEXT: Section: .debug$S (2)
MFUN32-NEXT: Magic: 0x4
MFUN32-NEXT: Subsection [
-MFUN32-NEXT: Type: 0xF1
-MFUN32-NEXT: PayloadSize: 0x52
+MFUN32-NEXT: SubSectionType: Symbols (0xF1)
+MFUN32-NEXT: SubSectionSize: 0x52
MFUN32: ]
-MFUN32-NEXT: Subsection [
-MFUN32-NEXT: Type: 0xF5
-MFUN32-NEXT: PayloadSize: 0x24
+MFUN32: Subsection [
+MFUN32-NEXT: SubSectionType: FrameData (0xF5)
+MFUN32-NEXT: SubSectionSize: 0x24
MFUN32: ]
MFUN32-NEXT: Subsection [
-MFUN32-NEXT: Type: 0xF1
-MFUN32-NEXT: PayloadSize: 0x4B
+MFUN32-NEXT: SubSectionType: Symbols (0xF1)
+MFUN32-NEXT: SubSectionSize: 0x4B
MFUN32: ProcStart {
-MFUN32-NEXT: DisplayName: x
-MFUN32-NEXT: Section: _x
-MFUN32-NEXT: CodeSize: 0xA
-MFUN32-NEXT: }
-MFUN32-NEXT: ProcEnd
+MFUN32: CodeSize: 0xA
+MFUN32: DisplayName: x
+MFUN32: LinkageName: _x
+MFUN32: }
+MFUN32: ProcEnd
MFUN32: ]
MFUN32-NEXT: Subsection [
-MFUN32-NEXT: Type: 0xF2
-MFUN32-NEXT: PayloadSize: 0x30
+MFUN32-NEXT: SubSectionType: Lines (0xF2)
+MFUN32-NEXT: SubSectionSize: 0x30
MFUN32: LinkageName: _x
MFUN32-NEXT: ]
MFUN32-NEXT: Subsection [
-MFUN32-NEXT: Type: 0xF5
-MFUN32-NEXT: PayloadSize: 0x24
+MFUN32-NEXT: SubSectionType: FrameData (0xF5)
+MFUN32-NEXT: SubSectionSize: 0x24
MFUN32: ]
MFUN32-NEXT: Subsection [
-MFUN32-NEXT: Type: 0xF1
-MFUN32-NEXT: PayloadSize: 0x4B
+MFUN32-NEXT: SubSectionType: Symbols (0xF1)
+MFUN32-NEXT: SubSectionSize: 0x4B
MFUN32: ProcStart {
-MFUN32-NEXT: DisplayName: y
-MFUN32-NEXT: Section: _y
-MFUN32-NEXT: CodeSize: 0xA
-MFUN32-NEXT: }
-MFUN32-NEXT: ProcEnd
+MFUN32: CodeSize: 0xA
+MFUN32: DisplayName: y
+MFUN32: LinkageName: _y
+MFUN32: }
+MFUN32: ProcEnd
MFUN32: ]
MFUN32-NEXT: Subsection [
-MFUN32-NEXT: Type: 0xF2
-MFUN32-NEXT: PayloadSize: 0x30
+MFUN32-NEXT: SubSectionType: Lines (0xF2)
+MFUN32-NEXT: SubSectionSize: 0x30
MFUN32: LinkageName: _y
MFUN32-NEXT: ]
MFUN32-NEXT: Subsection [
-MFUN32-NEXT: Type: 0xF5
-MFUN32-NEXT: PayloadSize: 0x24
+MFUN32-NEXT: SubSectionType: FrameData (0xF5)
+MFUN32-NEXT: SubSectionSize: 0x24
MFUN32: ]
MFUN32-NEXT: Subsection [
-MFUN32-NEXT: Type: 0xF1
-MFUN32-NEXT: PayloadSize: 0x4B
+MFUN32-NEXT: SubSectionType: Symbols (0xF1)
+MFUN32-NEXT: SubSectionSize: 0x4B
MFUN32: ProcStart {
-MFUN32-NEXT: DisplayName: f
-MFUN32-NEXT: Section: _f
-MFUN32-NEXT: CodeSize: 0x14
-MFUN32-NEXT: }
-MFUN32-NEXT: ProcEnd
+MFUN32: CodeSize: 0x14
+MFUN32: DisplayName: f
+MFUN32: LinkageName: _f
+MFUN32: }
+MFUN32: ProcEnd
MFUN32: ]
MFUN32-NEXT: Subsection [
-MFUN32-NEXT: Type: 0xF2
-MFUN32-NEXT: PayloadSize: 0x40
+MFUN32-NEXT: SubSectionType: Lines (0xF2)
+MFUN32-NEXT: SubSectionSize: 0x40
MFUN32: LinkageName: _f
MFUN32-NEXT: ]
MFUN32-NEXT: Subsection [
-MFUN32-NEXT: Type: 0xF4
-MFUN32-NEXT: PayloadSize: 0x18
+MFUN32-NEXT: SubSectionType: FileChecksums (0xF4)
+MFUN32-NEXT: SubSectionSize: 0x18
MFUN32: ]
MFUN32-NEXT: Subsection [
-MFUN32-NEXT: Type: 0xF3
-MFUN32-NEXT: PayloadSize: 0x46
+MFUN32-NEXT: SubSectionType: StringTable (0xF3)
+MFUN32-NEXT: SubSectionSize: 0x46
MFUN32: ]
MFUN32-NEXT: Subsection [
-MFUN32-NEXT: Type: 0xF1
-MFUN32-NEXT: PayloadSize: 0x8
+MFUN32-NEXT: SubSectionType: Symbols (0xF1)
+MFUN32-NEXT: SubSectionSize: 0x8
MFUN32: ]
MFUN32-NEXT: FunctionLineTable [
MFUN32-NEXT LinkageName: _x
@@ -181,70 +182,70 @@ MFUN32-NEXT IsStatement: Yes
MFUN32-NEXT ]
MFUN32-NEXT ]
MFUN32-NEXT ]
-MFUN32-NEXT ]
+MFUN32: ]
MFUN64: CodeViewDebugInfo [
-MFUN64-NEXT: Magic: 0x4
+MFUN64: Magic: 0x4
MFUN64-NEXT: Subsection [
-MFUN64-NEXT: Type: 0xF1
-MFUN64-NEXT: PayloadSize: 0x52
+MFUN64-NEXT: SubSectionType: Symbols (0xF1)
+MFUN64-NEXT: SubSectionSize: 0x52
MFUN64: ]
-MFUN64-NEXT: Subsection [
-MFUN64-NEXT: Type: 0xF1
-MFUN64-NEXT: PayloadSize: 0x4B
+MFUN64: Subsection [
+MFUN64-NEXT: SubSectionType: Symbols (0xF1)
+MFUN64-NEXT: SubSectionSize: 0x4B
MFUN64: ProcStart {
-MFUN64-NEXT: DisplayName: x
-MFUN64-NEXT: Section: x
-MFUN64-NEXT: CodeSize: 0xE
-MFUN64-NEXT: }
-MFUN64-NEXT: ProcEnd
+MFUN64: CodeSize: 0xE
+MFUN64: DisplayName: x
+MFUN64: LinkageName: x
+MFUN64: }
+MFUN64: ProcEnd
MFUN64: ]
MFUN64-NEXT: Subsection [
-MFUN64-NEXT: Type: 0xF2
-MFUN64-NEXT: PayloadSize: 0x30
+MFUN64-NEXT: SubSectionType: Lines (0xF2)
+MFUN64-NEXT: SubSectionSize: 0x30
MFUN64: LinkageName: x
MFUN64-NEXT: ]
MFUN64-NEXT: Subsection [
-MFUN64-NEXT: Type: 0xF1
-MFUN64-NEXT: PayloadSize: 0x4B
+MFUN64-NEXT: SubSectionType: Symbols (0xF1)
+MFUN64-NEXT: SubSectionSize: 0x4B
MFUN64: ProcStart {
-MFUN64-NEXT: DisplayName: y
-MFUN64-NEXT: Section: y
-MFUN64-NEXT: CodeSize: 0xE
-MFUN64-NEXT: }
-MFUN64-NEXT: ProcEnd
+MFUN64: CodeSize: 0xE
+MFUN64: DisplayName: y
+MFUN64: LinkageName: y
+MFUN64: }
+MFUN64: ProcEnd
MFUN64: ]
MFUN64-NEXT: Subsection [
-MFUN64-NEXT: Type: 0xF2
-MFUN64-NEXT: PayloadSize: 0x30
+MFUN64-NEXT: SubSectionType: Lines (0xF2)
+MFUN64-NEXT: SubSectionSize: 0x30
MFUN64: LinkageName: y
MFUN64-NEXT: ]
MFUN64-NEXT: Subsection [
-MFUN64-NEXT: Type: 0xF1
-MFUN64-NEXT: PayloadSize: 0x4B
+MFUN64-NEXT: SubSectionType: Symbols (0xF1)
+MFUN64-NEXT: SubSectionSize: 0x4B
MFUN64: ProcStart {
-MFUN64-NEXT: DisplayName: f
-MFUN64-NEXT: Section: f
-MFUN64-NEXT: CodeSize: 0x18
-MFUN64-NEXT: }
-MFUN64-NEXT: ProcEnd
+MFUN64: CodeSize: 0x18
+MFUN64: DisplayName: f
+MFUN64: LinkageName: f
+MFUN64: }
+MFUN64: ProcEnd
MFUN64: ]
MFUN64-NEXT: Subsection [
-MFUN64-NEXT: Type: 0xF2
-MFUN64-NEXT: PayloadSize: 0x40
+MFUN64-NEXT: SubSectionType: Lines (0xF2)
+MFUN64-NEXT: SubSectionSize: 0x40
MFUN64: LinkageName: f
MFUN64-NEXT: ]
MFUN64-NEXT: Subsection [
-MFUN64-NEXT: Type: 0xF4
-MFUN64-NEXT: PayloadSize: 0x18
+MFUN64-NEXT: SubSectionType: FileChecksums (0xF4)
+MFUN64-NEXT: SubSectionSize: 0x18
MFUN64: ]
MFUN64-NEXT: Subsection [
-MFUN64-NEXT: Type: 0xF3
-MFUN64-NEXT: PayloadSize: 0xD
+MFUN64-NEXT: SubSectionType: StringTable (0xF3)
+MFUN64-NEXT: SubSectionSize: 0xD
MFUN64: ]
MFUN64-NEXT: Subsection [
-MFUN64-NEXT: Type: 0xF1
-MFUN64-NEXT: PayloadSize: 0x8
+MFUN64-NEXT: SubSectionType: Symbols (0xF1)
+MFUN64-NEXT: SubSectionSize: 0x8
MFUN64: ]
MFUN64-NEXT: FunctionLineTable [
MFUN64-NEXT: LinkageName: x
@@ -325,7 +326,7 @@ MFUN64-NEXT: IsStatement: Yes
MFUN64-NEXT: ]
MFUN64-NEXT: ]
MFUN64-NEXT: ]
-MFUN64-NEXT: ]
+MFUN64: ]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The following two object files were generated using the following command:
@@ -352,41 +353,41 @@ RUN: llvm-readobj -s -codeview -section-
RUN: | FileCheck %s -check-prefix MFILE64
MFILE32: CodeViewDebugInfo [
-MFILE32-NEXT: Magic: 0x4
+MFILE32: Magic: 0x4
MFILE32-NEXT: Subsection [
-MFILE32-NEXT: Type: 0xF1
-MFILE32-NEXT: PayloadSize: 0x51
+MFILE32-NEXT: SubSectionType: Symbols (0xF1)
+MFILE32-NEXT: SubSectionSize: 0x51
MFILE32: ]
-MFILE32-NEXT: Subsection [
-MFILE32-NEXT: Type: 0xF5
-MFILE32-NEXT: PayloadSize: 0x24
+MFILE32: Subsection [
+MFILE32-NEXT: SubSectionType: FrameData (0xF5)
+MFILE32-NEXT: SubSectionSize: 0x24
MFILE32: ]
MFILE32-NEXT: Subsection [
-MFILE32-NEXT: Type: 0xF1
-MFILE32-NEXT: PayloadSize: 0x4B
+MFILE32-NEXT: SubSectionType: Symbols (0xF1)
+MFILE32-NEXT: SubSectionSize: 0x4B
MFILE32: ProcStart {
-MFILE32-NEXT: DisplayName: f
-MFILE32-NEXT: Section: _f
-MFILE32-NEXT: CodeSize: 0x14
-MFILE32-NEXT: }
-MFILE32-NEXT: ProcEnd
+MFILE32: CodeSize: 0x14
+MFILE32: DisplayName: f
+MFILE32: LinkageName: _f
+MFILE32: }
+MFILE32: ProcEnd
MFILE32: ]
MFILE32-NEXT: Subsection [
-MFILE32-NEXT: Type: 0xF2
-MFILE32-NEXT: PayloadSize: 0x64
+MFILE32-NEXT: SubSectionType: Lines (0xF2)
+MFILE32-NEXT: SubSectionSize: 0x64
MFILE32: LinkageName: _f
MFILE32-NEXT: ]
MFILE32-NEXT: Subsection [
-MFILE32-NEXT: Type: 0xF4
-MFILE32-NEXT: PayloadSize: 0x28
+MFILE32-NEXT: SubSectionType: FileChecksums (0xF4)
+MFILE32-NEXT: SubSectionSize: 0x28
MFILE32: ]
MFILE32-NEXT: Subsection [
-MFILE32-NEXT: Type: 0xF3
-MFILE32-NEXT: PayloadSize: 0x57
+MFILE32-NEXT: SubSectionType: StringTable (0xF3)
+MFILE32-NEXT: SubSectionSize: 0x57
MFILE32: ]
MFILE32-NEXT: Subsection [
-MFILE32-NEXT: Type: 0xF1
-MFILE32-NEXT: PayloadSize: 0x8
+MFILE32-NEXT: SubSectionType: Symbols (0xF1)
+MFILE32-NEXT: SubSectionSize: 0x8
MFILE32: ]
MFILE32-NEXT: FunctionLineTable [
MFILE32-NEXT: LinkageName: _f
@@ -430,40 +431,40 @@ MFILE32-NEXT: IsStatement: Yes
MFILE32-NEXT: ]
MFILE32-NEXT: ]
MFILE32-NEXT: ]
-MFILE32-NEXT: ]
+MFILE32: ]
MFILE64: CodeViewDebugInfo [
-MFILE64-NEXT: Magic: 0x4
+MFILE64: Magic: 0x4
MFILE64-NEXT: Subsection [
-MFILE64-NEXT: Type: 0xF1
-MFILE64-NEXT: PayloadSize: 0x51
+MFILE64-NEXT: SubSectionType: Symbols (0xF1)
+MFILE64-NEXT: SubSectionSize: 0x51
MFILE64: ]
-MFILE64-NEXT: Subsection [
-MFILE64-NEXT: Type: 0xF1
-MFILE64-NEXT: PayloadSize: 0x4B
+MFILE64: Subsection [
+MFILE64-NEXT: SubSectionType: Symbols (0xF1)
+MFILE64-NEXT: SubSectionSize: 0x4B
MFILE64: ProcStart {
-MFILE64-NEXT: DisplayName: f
-MFILE64-NEXT: Section: f
-MFILE64-NEXT: CodeSize: 0x18
-MFILE64-NEXT: }
-MFILE64-NEXT: ProcEnd
+MFILE64: CodeSize: 0x18
+MFILE64: DisplayName: f
+MFILE64: LinkageName: f
+MFILE64: }
+MFILE64: ProcEnd
MFILE64: ]
MFILE64-NEXT: Subsection [
-MFILE64-NEXT: Type: 0xF2
-MFILE64-NEXT: PayloadSize: 0x64
+MFILE64-NEXT: SubSectionType: Lines (0xF2)
+MFILE64-NEXT: SubSectionSize: 0x64
MFILE64: LinkageName: f
MFILE64-NEXT: ]
MFILE64-NEXT: Subsection [
-MFILE64-NEXT: Type: 0xF4
-MFILE64-NEXT: PayloadSize: 0x28
+MFILE64-NEXT: SubSectionType: FileChecksums (0xF4)
+MFILE64-NEXT: SubSectionSize: 0x28
MFILE64: ]
MFILE64-NEXT: Subsection [
-MFILE64-NEXT: Type: 0xF3
-MFILE64-NEXT: PayloadSize: 0x1E
+MFILE64-NEXT: SubSectionType: StringTable (0xF3)
+MFILE64-NEXT: SubSectionSize: 0x1E
MFILE64: ]
MFILE64-NEXT: Subsection [
-MFILE64-NEXT: Type: 0xF1
-MFILE64-NEXT: PayloadSize: 0x8
+MFILE64-NEXT: SubSectionType: Symbols (0xF1)
+MFILE64-NEXT: SubSectionSize: 0x8
MFILE64: ]
MFILE64-NEXT: FunctionLineTable [
MFILE64-NEXT: LinkageName: f
@@ -506,7 +507,7 @@ MFILE64-NEXT: LineNumberEndDelta:
MFILE64-NEXT: IsStatement: Yes
MFILE64-NEXT: ]
MFILE64-NEXT: ]
-MFILE64-NEXT: ]
+MFILE64: ]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; The following object files were generated using the following command:
@@ -528,10 +529,10 @@ RUN: llvm-readobj -s -codeview -section-
RUN: | FileCheck %s -check-prefix MCOMDAT
MCOMDAT: ProcStart {
-MCOMDAT-NEXT: DisplayName: f
-MCOMDAT-NEXT: Section: ?f@@YAHXZ
-MCOMDAT-NEXT: CodeSize: 0x7
-MCOMDAT-NEXT: }
+MCOMDAT: CodeSize: 0x7
+MCOMDAT: DisplayName: f
+MCOMDAT: LinkageName: ?f@@YAHXZ
+MCOMDAT: }
MCOMDAT: FunctionLineTable [
MCOMDAT-NEXT: LinkageName: ?f@@YAHXZ
MCOMDAT-NEXT: Flags: 0x0
@@ -556,10 +557,10 @@ MCOMDAT-NEXT: ]
MCOMDAT-NEXT: ]
MCOMDAT-NEXT: ]
MCOMDAT: ProcStart {
-MCOMDAT-NEXT: DisplayName: g
-MCOMDAT-NEXT: Section: ?g@@YAHXZ
-MCOMDAT-NEXT: CodeSize: 0x7
-MCOMDAT-NEXT: }
+MCOMDAT: CodeSize: 0x7
+MCOMDAT: DisplayName: g
+MCOMDAT: LinkageName: ?g@@YAHXZ
+MCOMDAT: }
MCOMDAT: FunctionLineTable [
MCOMDAT-NEXT: LinkageName: ?g@@YAHXZ
MCOMDAT-NEXT: Flags: 0x0
Modified: llvm/trunk/tools/llvm-pdbdump/FunctionDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/FunctionDumper.cpp?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/FunctionDumper.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/FunctionDumper.cpp Wed Jan 13 13:32:35 2016
@@ -27,6 +27,7 @@
#include "llvm/Support/Format.h"
using namespace llvm;
+using namespace llvm::codeview;
namespace {
template <class T>
@@ -57,10 +58,10 @@ void FunctionDumper::start(const PDBSymb
Symbol.getSession().getConcreteSymbolById<PDBSymbolTypeUDT>(
ClassParentId);
- PDB_CallingConv CC = Symbol.getCallingConvention();
+ CallingConvention CC = Symbol.getCallingConvention();
bool ShouldDumpCallingConvention = true;
- if ((ClassParent && CC == PDB_CallingConv::Thiscall) ||
- (!ClassParent && CC == PDB_CallingConv::NearStdcall)) {
+ if ((ClassParent && CC == CallingConvention::ThisCall) ||
+ (!ClassParent && CC == CallingConvention::NearStdCall)) {
ShouldDumpCallingConvention = false;
}
@@ -152,12 +153,12 @@ void FunctionDumper::start(const PDBSymb
Printer << " ";
auto ClassParent = Symbol.getClassParent();
- PDB_CallingConv CC = Signature->getCallingConvention();
+ CallingConvention CC = Signature->getCallingConvention();
if (Pointer != FunctionDumper::PointerType::None)
Printer << "(";
- if ((ClassParent && CC != PDB_CallingConv::Thiscall) ||
- (!ClassParent && CC != PDB_CallingConv::NearStdcall)) {
+ if ((ClassParent && CC != CallingConvention::ThisCall) ||
+ (!ClassParent && CC != CallingConvention::NearStdCall)) {
WithColor(Printer, PDB_ColorItem::Keyword).get()
<< Signature->getCallingConvention() << " ";
}
Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Wed Jan 13 13:32:35 2016
@@ -14,6 +14,7 @@
#include "llvm-readobj.h"
#include "ARMWinEHPrinter.h"
+#include "CodeView.h"
#include "Error.h"
#include "ObjDumper.h"
#include "StackMapPrinter.h"
@@ -22,6 +23,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/COFF.h"
@@ -39,6 +41,7 @@
using namespace llvm;
using namespace llvm::object;
+using namespace llvm::codeview;
using namespace llvm::Win64EH;
namespace {
@@ -72,12 +75,18 @@ private:
void printBaseOfDataField(const pe32_header *Hdr);
void printBaseOfDataField(const pe32plus_header *Hdr);
- void printCodeViewSection(const SectionRef &Section);
+ void printCodeViewSymbolSection(StringRef SectionName, const SectionRef &Section);
+ void printCodeViewTypeSection(StringRef SectionName, const SectionRef &Section);
+ void printCodeViewFieldList(StringRef FieldData);
+ StringRef getTypeName(TypeIndex Ty);
+ void printTypeIndex(StringRef FieldName, TypeIndex TI);
void printCodeViewSymbolsSubsection(StringRef Subsection,
const SectionRef &Section,
uint32_t Offset);
+ void printMemberAttributes(MemberAttributes Attrs);
+
void cacheRelocations();
std::error_code resolveSymbol(const coff_section *Section, uint64_t Offset,
@@ -96,6 +105,13 @@ private:
RelocMapTy RelocMap;
StringRef CVFileIndexToStringOffsetTable;
StringRef CVStringTable;
+
+ /// All user defined type records in .debug$T live in here. Type indices
+ /// greater than 0x1000 are user defined. Subtract 0x1000 from the index to
+ /// index into this vector.
+ SmallVector<StringRef, 10> CVUDTNames;
+
+ StringSet<> TypeNames;
};
} // namespace
@@ -331,6 +347,353 @@ WeakExternalCharacteristics[] = {
{ "Alias" , COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS }
};
+static const EnumEntry<CompileSym3::Flags> CompileSym3Flags[] = {
+ LLVM_READOBJ_ENUM_ENT(CompileSym3, EC),
+ LLVM_READOBJ_ENUM_ENT(CompileSym3, NoDbgInfo),
+ LLVM_READOBJ_ENUM_ENT(CompileSym3, LTCG),
+ LLVM_READOBJ_ENUM_ENT(CompileSym3, NoDataAlign),
+ LLVM_READOBJ_ENUM_ENT(CompileSym3, ManagedPresent),
+ LLVM_READOBJ_ENUM_ENT(CompileSym3, SecurityChecks),
+ LLVM_READOBJ_ENUM_ENT(CompileSym3, HotPatch),
+ LLVM_READOBJ_ENUM_ENT(CompileSym3, CVTCIL),
+ LLVM_READOBJ_ENUM_ENT(CompileSym3, MSILModule),
+ LLVM_READOBJ_ENUM_ENT(CompileSym3, Sdl),
+ LLVM_READOBJ_ENUM_ENT(CompileSym3, PGO),
+ LLVM_READOBJ_ENUM_ENT(CompileSym3, Exp),
+};
+
+static const EnumEntry<codeview::SourceLanguage> SourceLanguages[] = {
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, C),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, Cpp),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, Fortran),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, Masm),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, Pascal),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, Basic),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, Cobol),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, Link),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, Cvtres),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, Cvtpgd),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, CSharp),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, VB),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, ILAsm),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, Java),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, JScript),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, MSIL),
+ LLVM_READOBJ_ENUM_ENT(SourceLanguage, HLSL),
+};
+
+static const EnumEntry<uint32_t> SubSectionTypes[] = {
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, Symbols),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, Lines),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, StringTable),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FileChecksums),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FrameData),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, InlineeLines),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CrossScopeImports),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CrossScopeExports),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, ILLines),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, FuncMDTokenMap),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, TypeMDTokenMap),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, MergedAssemblyInput),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModuleSubstreamKind, CoffSymbolRVA),
+};
+
+static const EnumEntry<unsigned> CPUTypeNames[] = {
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel8080),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel8086),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel80286),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel80386),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Intel80486),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Pentium),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PentiumPro),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Pentium3),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPS),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPS16),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPS32),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPS64),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSI),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSII),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSIII),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSIV),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, MIPSV),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68000),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68010),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68020),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68030),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M68040),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha21164),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha21164A),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha21264),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Alpha21364),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPC601),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPC603),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPC604),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPC620),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPCFP),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, PPCBE),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SH3),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SH3E),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SH3DSP),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SH4),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, SHMedia),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM3),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM4),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM4T),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM5),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM5T),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM6),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM_XMAC),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM_WMMX),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARM7),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Omni),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Ia64),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Ia64_2),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, CEE),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, AM33),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, M32R),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, TriCore),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, X64),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, EBC),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, Thumb),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, ARMNT),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CPUType, D3D11_Shader),
+};
+
+static const EnumEntry<uint8_t> ProcSymFlags[] = {
+ LLVM_READOBJ_ENUM_ENT(ProcFlags, HasFP),
+ LLVM_READOBJ_ENUM_ENT(ProcFlags, HasIRET),
+ LLVM_READOBJ_ENUM_ENT(ProcFlags, HasFRET),
+ LLVM_READOBJ_ENUM_ENT(ProcFlags, IsNoReturn),
+ LLVM_READOBJ_ENUM_ENT(ProcFlags, IsUnreachable),
+ LLVM_READOBJ_ENUM_ENT(ProcFlags, HasCustomCallingConv),
+ LLVM_READOBJ_ENUM_ENT(ProcFlags, IsNoInline),
+ LLVM_READOBJ_ENUM_ENT(ProcFlags, HasOptimizedDebugInfo),
+};
+
+static const EnumEntry<uint32_t> FrameProcSymFlags[] = {
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasAlloca),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasSetJmp),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasLongJmp),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasInlineAssembly),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, HasExceptionHandling),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, MarkedInline),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions,
+ HasStructuredExceptionHandling),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, Naked),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, SecurityChecks),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions,
+ AsynchronousExceptionHandling),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions,
+ NoStackOrderingForSecurityChecks),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, Inlined),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, StrictSecurityChecks),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, SafeBuffers),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions,
+ ProfileGuidedOptimization),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, ValidProfileCounts),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, OptimizedForSpeed),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfg),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfw),
+};
+
+static const EnumEntry<uint32_t> FrameDataFlags[] = {
+ LLVM_READOBJ_ENUM_ENT(FrameData, HasSEH),
+ LLVM_READOBJ_ENUM_ENT(FrameData, HasEH),
+ LLVM_READOBJ_ENUM_ENT(FrameData, IsFunctionStart),
+};
+
+static const EnumEntry<uint16_t> LocalFlags[] = {
+ LLVM_READOBJ_ENUM_ENT(LocalSym, IsParameter),
+ LLVM_READOBJ_ENUM_ENT(LocalSym, IsAddressTaken),
+ LLVM_READOBJ_ENUM_ENT(LocalSym, IsCompilerGenerated),
+ LLVM_READOBJ_ENUM_ENT(LocalSym, IsAggregate),
+ LLVM_READOBJ_ENUM_ENT(LocalSym, IsAggregated),
+ LLVM_READOBJ_ENUM_ENT(LocalSym, IsAliased),
+ LLVM_READOBJ_ENUM_ENT(LocalSym, IsAlias),
+ LLVM_READOBJ_ENUM_ENT(LocalSym, IsReturnValue),
+ LLVM_READOBJ_ENUM_ENT(LocalSym, IsOptimizedOut),
+ LLVM_READOBJ_ENUM_ENT(LocalSym, IsEnregisteredGlobal),
+ LLVM_READOBJ_ENUM_ENT(LocalSym, IsEnregisteredStatic),
+};
+
+static const EnumEntry<uint16_t> FrameCookieKinds[] = {
+ LLVM_READOBJ_ENUM_ENT(FrameCookieSym, Copy),
+ LLVM_READOBJ_ENUM_ENT(FrameCookieSym, XorStackPointer),
+ LLVM_READOBJ_ENUM_ENT(FrameCookieSym, XorFramePointer),
+ LLVM_READOBJ_ENUM_ENT(FrameCookieSym, XorR13),
+};
+
+static const EnumEntry<uint16_t> ClassOptionNames[] = {
+ LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, Packed),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, HasConstructorOrDestructor),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, HasOverloadedOperator),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, Nested),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, ContainsNestedClass),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, HasOverloadedAssignmentOperator),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, HasConversionOperator),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, ForwardReference),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, Scoped),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, HasUniqueName),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, Sealed),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ClassOptions, Intrinsic),
+};
+
+static const EnumEntry<uint8_t> MemberAccessNames[] = {
+ LLVM_READOBJ_ENUM_CLASS_ENT(MemberAccess, None),
+ LLVM_READOBJ_ENUM_CLASS_ENT(MemberAccess, Private),
+ LLVM_READOBJ_ENUM_CLASS_ENT(MemberAccess, Protected),
+ LLVM_READOBJ_ENUM_CLASS_ENT(MemberAccess, Public),
+};
+
+static const EnumEntry<uint16_t> MethodOptionNames[] = {
+ LLVM_READOBJ_ENUM_CLASS_ENT(MethodOptions, Pseudo),
+ LLVM_READOBJ_ENUM_CLASS_ENT(MethodOptions, NoInherit),
+ LLVM_READOBJ_ENUM_CLASS_ENT(MethodOptions, NoConstruct),
+ LLVM_READOBJ_ENUM_CLASS_ENT(MethodOptions, CompilerGenerated),
+ LLVM_READOBJ_ENUM_CLASS_ENT(MethodOptions, Sealed),
+};
+
+static const EnumEntry<uint16_t> MemberKindNames[] = {
+ LLVM_READOBJ_ENUM_CLASS_ENT(MethodKind, Vanilla),
+ LLVM_READOBJ_ENUM_CLASS_ENT(MethodKind, Virtual),
+ LLVM_READOBJ_ENUM_CLASS_ENT(MethodKind, Static),
+ LLVM_READOBJ_ENUM_CLASS_ENT(MethodKind, Friend),
+ LLVM_READOBJ_ENUM_CLASS_ENT(MethodKind, IntroducingVirtual),
+ LLVM_READOBJ_ENUM_CLASS_ENT(MethodKind, PureVirtual),
+ LLVM_READOBJ_ENUM_CLASS_ENT(MethodKind, PureIntroducingVirtual),
+};
+
+/// The names here all end in "*". If the simple type is a pointer type, we
+/// return the whole name. Otherwise we lop off the last character in our
+/// StringRef.
+static const EnumEntry<SimpleTypeKind> SimpleTypeNames[] = {
+ {"void*", SimpleTypeKind::Void},
+ {"<not translated>*", SimpleTypeKind::NotTranslated},
+ {"HRESULT*", SimpleTypeKind::HResult},
+ {"signed char*", SimpleTypeKind::SignedCharacter},
+ {"unsigned char*", SimpleTypeKind::UnsignedCharacter},
+ {"char*", SimpleTypeKind::NarrowCharacter},
+ {"wchar_t*", SimpleTypeKind::WideCharacter},
+ {"__int8*", SimpleTypeKind::SByte},
+ {"unsigned __int8*", SimpleTypeKind::Byte},
+ {"short*", SimpleTypeKind::Int16Short},
+ {"unsigned short*", SimpleTypeKind::UInt16Short},
+ {"__int16*", SimpleTypeKind::Int16},
+ {"unsigned __int16*", SimpleTypeKind::UInt16},
+ {"long*", SimpleTypeKind::Int32Long},
+ {"unsigned long*", SimpleTypeKind::UInt32Long},
+ {"int*", SimpleTypeKind::Int32},
+ {"unsigned*", SimpleTypeKind::UInt32},
+ {"__int64*", SimpleTypeKind::Int64Quad},
+ {"unsigned __int64*", SimpleTypeKind::UInt64Quad},
+ {"__int64*", SimpleTypeKind::Int64},
+ {"unsigned __int64*", SimpleTypeKind::UInt64},
+ {"__int128*", SimpleTypeKind::Int128},
+ {"unsigned __int128*", SimpleTypeKind::UInt128},
+ {"__half*", SimpleTypeKind::Float16},
+ {"float*", SimpleTypeKind::Float32},
+ {"float*", SimpleTypeKind::Float32PartialPrecision},
+ {"__float48*", SimpleTypeKind::Float48},
+ {"double*", SimpleTypeKind::Float64},
+ {"long double*", SimpleTypeKind::Float80},
+ {"__float128*", SimpleTypeKind::Float128},
+ {"_Complex float*", SimpleTypeKind::Complex32},
+ {"_Complex double*", SimpleTypeKind::Complex64},
+ {"_Complex long double*", SimpleTypeKind::Complex80},
+ {"_Complex __float128*", SimpleTypeKind::Complex128},
+ {"bool*", SimpleTypeKind::Boolean8},
+ {"__bool16*", SimpleTypeKind::Boolean16},
+ {"__bool32*", SimpleTypeKind::Boolean32},
+ {"__bool64*", SimpleTypeKind::Boolean64},
+};
+
+static const EnumEntry<LeafType> LeafTypeNames[] = {
+#define LEAF_TYPE(name, val) LLVM_READOBJ_ENUM_ENT(LeafType, name),
+#include "CVLeafTypes.def"
+};
+
+static const EnumEntry<uint8_t> PtrKindNames[] = {
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, Near16),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, Far16),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, Huge16),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, BasedOnSegment),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, BasedOnValue),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentValue),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, BasedOnAddress),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentAddress),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, BasedOnType),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, BasedOnSelf),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, Near32),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, Far32),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerKind, Near64),
+};
+
+static const EnumEntry<uint8_t> PtrModeNames[] = {
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerMode, Pointer),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerMode, LValueReference),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerMode, PointerToDataMember),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerMode, PointerToMemberFunction),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerMode, RValueReference),
+};
+
+static const EnumEntry<uint16_t> PtrMemberRepNames[] = {
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation, Unknown),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+ SingleInheritanceData),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+ MultipleInheritanceData),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+ VirtualInheritanceData),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralData),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+ SingleInheritanceFunction),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+ MultipleInheritanceFunction),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+ VirtualInheritanceFunction),
+ LLVM_READOBJ_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralFunction),
+};
+
+static const EnumEntry<uint16_t> TypeModifierNames[] = {
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModifierOptions, Const),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModifierOptions, Volatile),
+ LLVM_READOBJ_ENUM_CLASS_ENT(ModifierOptions, Unaligned),
+};
+
+static const EnumEntry<uint8_t> CallingConventions[] = {
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, NearC),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, FarC),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, NearPascal),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, FarPascal),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, NearFast),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, FarFast),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, NearStdCall),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, FarStdCall),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, NearSysCall),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, FarSysCall),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, ThisCall),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, MipsCall),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, Generic),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, AlphaCall),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, PpcCall),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, SHCall),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, ArmCall),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, AM33Call),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, TriCall),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, SH5Call),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, M32RCall),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, ClrCall),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, Inline),
+ LLVM_READOBJ_ENUM_CLASS_ENT(CallingConvention, NearVector),
+};
+
+static const EnumEntry<uint8_t> FunctionOptionEnum[] = {
+ LLVM_READOBJ_ENUM_CLASS_ENT(FunctionOptions, CxxReturnUdt),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FunctionOptions, Constructor),
+ LLVM_READOBJ_ENUM_CLASS_ENT(FunctionOptions, ConstructorWithVirtualBases),
+};
+
template <typename T>
static std::error_code getSymbolAuxData(const COFFObjectFile *Obj,
COFFSymbolRef Symbol,
@@ -476,110 +839,165 @@ void COFFDumper::printBaseOfDataField(co
void COFFDumper::printBaseOfDataField(const pe32plus_header *) {}
void COFFDumper::printCodeViewDebugInfo() {
+ // Print types first to build CVUDTNames, then print symbols.
for (const SectionRef &S : Obj->sections()) {
- StringRef SecName;
- error(S.getName(SecName));
- if (SecName == ".debug$S")
- printCodeViewSection(S);
+ StringRef SectionName;
+ error(S.getName(SectionName));
+ if (SectionName == ".debug$T")
+ printCodeViewTypeSection(SectionName, S);
+ }
+ for (const SectionRef &S : Obj->sections()) {
+ StringRef SectionName;
+ error(S.getName(SectionName));
+ if (SectionName == ".debug$S")
+ printCodeViewSymbolSection(SectionName, S);
}
}
-void COFFDumper::printCodeViewSection(const SectionRef &Section) {
- StringRef Data;
- error(Section.getContents(Data));
+/// Consumes sizeof(T) bytes from the given byte sequence. Returns an error if
+/// there are not enough bytes remaining. Reinterprets the consumed bytes as a
+/// T object and points 'Res' at them.
+template <typename T>
+static std::error_code consumeObject(StringRef &Data, const T *&Res) {
+ if (Data.size() < sizeof(*Res))
+ return object_error::parse_failed;
+ Res = reinterpret_cast<const T *>(Data.data());
+ Data = Data.drop_front(sizeof(*Res));
+ return std::error_code();
+}
+
+static std::error_code consumeUInt32(StringRef &Data, uint32_t &Res) {
+ const ulittle32_t *IntPtr;
+ if (auto EC = consumeObject(Data, IntPtr))
+ return EC;
+ Res = *IntPtr;
+ return std::error_code();
+}
+
+void COFFDumper::printCodeViewSymbolSection(StringRef SectionName,
+ const SectionRef &Section) {
+ StringRef SectionContents;
+ error(Section.getContents(SectionContents));
+ StringRef Data = SectionContents;
SmallVector<StringRef, 10> FunctionNames;
StringMap<StringRef> FunctionLineTables;
+ std::map<StringRef, const FrameData *> FunctionFrameData;
ListScope D(W, "CodeViewDebugInfo");
- {
- // FIXME: Add more offset correctness checks.
- DataExtractor DE(Data, true, 4);
- uint32_t Offset = 0,
- Magic = DE.getU32(&Offset);
- W.printHex("Magic", Magic);
- if (Magic != COFF::DEBUG_SECTION_MAGIC) {
- error(object_error::parse_failed);
- return;
- }
+ // Print the section to allow correlation with printSections.
+ W.printNumber("Section", SectionName, Obj->getSectionID(Section));
- bool Finished = false;
- while (DE.isValidOffset(Offset) && !Finished) {
- // The section consists of a number of subsection in the following format:
- // |Type|PayloadSize|Payload...|
- uint32_t SubSectionType = DE.getU32(&Offset),
- PayloadSize = DE.getU32(&Offset);
- ListScope S(W, "Subsection");
- W.printHex("Type", SubSectionType);
- W.printHex("PayloadSize", PayloadSize);
- if (PayloadSize > Data.size() - Offset) {
+ uint32_t Magic;
+ error(consumeUInt32(Data, Magic));
+ W.printHex("Magic", Magic);
+ if (Magic != COFF::DEBUG_SECTION_MAGIC)
+ return error(object_error::parse_failed);
+
+ while (!Data.empty()) {
+ // The section consists of a number of subsection in the following format:
+ // |SubSectionType|SubSectionSize|Contents...|
+ uint32_t SubType, SubSectionSize;
+ error(consumeUInt32(Data, SubType));
+ error(consumeUInt32(Data, SubSectionSize));
+
+ ListScope S(W, "Subsection");
+ W.printEnum("SubSectionType", SubType, makeArrayRef(SubSectionTypes));
+ W.printHex("SubSectionSize", SubSectionSize);
+
+ // Get the contents of the subsection.
+ if (SubSectionSize > Data.size())
+ return error(object_error::parse_failed);
+ StringRef Contents = Data.substr(0, SubSectionSize);
+
+ // Add SubSectionSize to the current offset and align that offset to find
+ // the next subsection.
+ size_t SectionOffset = Data.data() - SectionContents.data();
+ size_t NextOffset = SectionOffset + SubSectionSize;
+ NextOffset = RoundUpToAlignment(NextOffset, 4);
+ Data = SectionContents.drop_front(NextOffset);
+
+ // Optionally print the subsection bytes in case our parsing gets confused
+ // later.
+ if (opts::CodeViewSubsectionBytes)
+ W.printBinaryBlock("SubSectionContents", Contents);
+
+ switch (ModuleSubstreamKind(SubType)) {
+ case ModuleSubstreamKind::Symbols:
+ printCodeViewSymbolsSubsection(Contents, Section, SectionOffset);
+ break;
+ case ModuleSubstreamKind::Lines: {
+ // Holds a PC to file:line table. Some data to parse this subsection is
+ // stored in the other subsections, so just check sanity and store the
+ // pointers for deferred processing.
+
+ if (SubSectionSize < 12) {
+ // There should be at least three words to store two function
+ // relocations and size of the code.
error(object_error::parse_failed);
return;
}
- StringRef Contents = Data.substr(Offset, PayloadSize);
- if (opts::CodeViewSubsectionBytes) {
- // Print the raw contents to simplify debugging if anything goes wrong
- // afterwards.
- W.printBinaryBlock("Contents", Contents);
- }
-
- switch (SubSectionType) {
- case COFF::DEBUG_SYMBOL_SUBSECTION:
- printCodeViewSymbolsSubsection(Contents, Section, Offset);
- break;
- case COFF::DEBUG_LINE_TABLE_SUBSECTION: {
- // Holds a PC to file:line table. Some data to parse this subsection is
- // stored in the other subsections, so just check sanity and store the
- // pointers for deferred processing.
-
- if (PayloadSize < 12) {
- // There should be at least three words to store two function
- // relocations and size of the code.
- error(object_error::parse_failed);
- return;
- }
+ StringRef LinkageName;
+ error(resolveSymbolName(Obj->getCOFFSection(Section), SectionOffset,
+ LinkageName));
+ W.printString("LinkageName", LinkageName);
+ if (FunctionLineTables.count(LinkageName) != 0) {
+ // Saw debug info for this function already?
+ error(object_error::parse_failed);
+ return;
+ }
- StringRef LinkageName;
- error(resolveSymbolName(Obj->getCOFFSection(Section), Offset,
- LinkageName));
- W.printString("LinkageName", LinkageName);
- if (FunctionLineTables.count(LinkageName) != 0) {
- // Saw debug info for this function already?
- error(object_error::parse_failed);
- return;
- }
+ FunctionLineTables[LinkageName] = Contents;
+ FunctionNames.push_back(LinkageName);
+ break;
+ }
+ case ModuleSubstreamKind::StringTable:
+ if (SubSectionSize == 0 || CVStringTable.data() != nullptr ||
+ Contents.back() != '\0') {
+ // Empty or duplicate or non-null-terminated subsection.
+ error(object_error::parse_failed);
+ return;
+ }
+ CVStringTable = Contents;
+ break;
+ case ModuleSubstreamKind::FileChecksums:
+ // Holds the translation table from file indices
+ // to offsets in the string table.
+
+ if (SubSectionSize == 0 ||
+ CVFileIndexToStringOffsetTable.data() != nullptr) {
+ // Empty or duplicate subsection.
+ error(object_error::parse_failed);
+ return;
+ }
+ CVFileIndexToStringOffsetTable = Contents;
+ break;
+ case ModuleSubstreamKind::FrameData: {
+ const size_t RelocationSize = 4;
+ if (SubSectionSize != sizeof(FrameData) + RelocationSize) {
+ // There should be exactly one relocation followed by the FrameData
+ // contents.
+ error(object_error::parse_failed);
+ return;
+ }
- FunctionLineTables[LinkageName] = Contents;
- FunctionNames.push_back(LinkageName);
- break;
- }
- case COFF::DEBUG_STRING_TABLE_SUBSECTION:
- if (PayloadSize == 0 || CVStringTable.data() != nullptr ||
- Contents.back() != '\0') {
- // Empty or duplicate or non-null-terminated subsection.
- error(object_error::parse_failed);
- return;
- }
- CVStringTable = Contents;
- break;
- case COFF::DEBUG_INDEX_SUBSECTION:
- // Holds the translation table from file indices
- // to offsets in the string table.
-
- if (PayloadSize == 0 ||
- CVFileIndexToStringOffsetTable.data() != nullptr) {
- // Empty or duplicate subsection.
- error(object_error::parse_failed);
- return;
- }
- CVFileIndexToStringOffsetTable = Contents;
- break;
+ const auto *FD = reinterpret_cast<const FrameData *>(
+ Contents.drop_front(RelocationSize).data());
+
+ StringRef LinkageName;
+ error(resolveSymbolName(Obj->getCOFFSection(Section), SectionOffset,
+ LinkageName));
+ if (!FunctionFrameData.emplace(LinkageName, FD).second) {
+ error(object_error::parse_failed);
+ return;
}
- Offset += PayloadSize;
+ break;
+ }
- // Align the reading pointer by 4.
- Offset += (-Offset) % 4;
+ // Do nothing for unrecognized subsections.
+ default:
+ break;
}
}
@@ -674,89 +1092,1099 @@ void COFFDumper::printCodeViewSection(co
}
}
}
+
+ for (auto FrameDataPair : FunctionFrameData) {
+ StringRef LinkageName = FrameDataPair.first;
+ const FrameData *FD = FrameDataPair.second;
+ ListScope S(W, "FunctionFrameData");
+ W.printString("LinkageName", LinkageName);
+ W.printHex("RvaStart", FD->RvaStart);
+ W.printHex("CodeSize", FD->CodeSize);
+ W.printHex("LocalSize", FD->LocalSize);
+ W.printHex("ParamsSize", FD->ParamsSize);
+ W.printHex("MaxStackSize", FD->MaxStackSize);
+ W.printString("FrameFunc", StringRef(CVStringTable.data() + FD->FrameFunc));
+ W.printHex("PrologSize", FD->PrologSize);
+ W.printHex("SavedRegsSize", FD->SavedRegsSize);
+ W.printFlags("Flags", FD->Flags, makeArrayRef(FrameDataFlags));
+ }
+}
+
+static std::error_code decodeNumerictLeaf(StringRef &Data, APSInt &Num) {
+ // Used to avoid overload ambiguity on APInt construtor.
+ bool FalseVal = false;
+ if (Data.size() < 2)
+ return object_error::parse_failed;
+ uint16_t Short = *reinterpret_cast<const ulittle16_t *>(Data.data());
+ Data = Data.drop_front(2);
+ if (Short < LF_NUMERIC) {
+ Num = APSInt(APInt(/*numBits=*/16, Short, /*isSigned=*/false),
+ /*isUnsigned=*/true);
+ return std::error_code();
+ }
+ switch (Short) {
+ case LF_CHAR:
+ Num = APSInt(APInt(/*numBits=*/8,
+ *reinterpret_cast<const int8_t *>(Data.data()),
+ /*isSigned=*/true),
+ /*isUnsigned=*/false);
+ Data = Data.drop_front(1);
+ return std::error_code();
+ case LF_SHORT:
+ Num = APSInt(APInt(/*numBits=*/16,
+ *reinterpret_cast<const little16_t *>(Data.data()),
+ /*isSigned=*/true),
+ /*isUnsigned=*/false);
+ Data = Data.drop_front(2);
+ return std::error_code();
+ case LF_USHORT:
+ Num = APSInt(APInt(/*numBits=*/16,
+ *reinterpret_cast<const ulittle16_t *>(Data.data()),
+ /*isSigned=*/false),
+ /*isUnsigned=*/true);
+ Data = Data.drop_front(2);
+ return std::error_code();
+ case LF_LONG:
+ Num = APSInt(APInt(/*numBits=*/32,
+ *reinterpret_cast<const little32_t *>(Data.data()),
+ /*isSigned=*/true),
+ /*isUnsigned=*/false);
+ Data = Data.drop_front(4);
+ return std::error_code();
+ case LF_ULONG:
+ Num = APSInt(APInt(/*numBits=*/32,
+ *reinterpret_cast<const ulittle32_t *>(Data.data()),
+ /*isSigned=*/FalseVal),
+ /*isUnsigned=*/true);
+ Data = Data.drop_front(4);
+ return std::error_code();
+ case LF_QUADWORD:
+ Num = APSInt(APInt(/*numBits=*/64,
+ *reinterpret_cast<const little64_t *>(Data.data()),
+ /*isSigned=*/true),
+ /*isUnsigned=*/false);
+ Data = Data.drop_front(8);
+ return std::error_code();
+ case LF_UQUADWORD:
+ Num = APSInt(APInt(/*numBits=*/64,
+ *reinterpret_cast<const ulittle64_t *>(Data.data()),
+ /*isSigned=*/false),
+ /*isUnsigned=*/true);
+ Data = Data.drop_front(8);
+ return std::error_code();
+ }
+ return object_error::parse_failed;
+}
+
+/// Decode an unsigned integer numeric leaf value.
+std::error_code decodeUIntLeaf(StringRef &Data, uint64_t &Num) {
+ APSInt N;
+ if (std::error_code err = decodeNumerictLeaf(Data, N))
+ return err;
+ if (N.isSigned() || !N.isIntN(64))
+ return object_error::parse_failed;
+ Num = N.getLimitedValue();
+ return std::error_code();
}
void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection,
const SectionRef &Section,
uint32_t OffsetInSection) {
- if (Subsection.size() == 0) {
- error(object_error::parse_failed);
- return;
- }
- DataExtractor DE(Subsection, true, 4);
- uint32_t Offset = 0;
+ if (Subsection.size() < sizeof(SymRecord))
+ return error(object_error::parse_failed);
+
+ // This holds the remaining data to parse.
+ StringRef Data = Subsection;
- // Function-level subsections have "procedure start" and "procedure end"
- // commands that should come in pairs and surround relevant info.
bool InFunctionScope = false;
- while (DE.isValidOffset(Offset)) {
- // Read subsection segments one by one.
- uint16_t Size = DE.getU16(&Offset);
- // The section size includes the size of the type identifier.
- if (Size < 2 || !DE.isValidOffsetForDataOfSize(Offset, Size)) {
- error(object_error::parse_failed);
- return;
- }
- Size -= 2;
- uint16_t Type = DE.getU16(&Offset);
+ while (!Data.empty()) {
+ const SymRecord *Rec;
+ error(consumeObject(Data, Rec));
+
+ StringRef SymData = Data.substr(0, Rec->RecordLength - 2);
+
+ Data = Data.drop_front(Rec->RecordLength - 2);
+
+ SymType Type = static_cast<SymType>(uint16_t(Rec->RecordType));
switch (Type) {
- case COFF::DEBUG_SYMBOL_TYPE_PROC_START: {
+ case S_LPROC32:
+ case S_GPROC32:
+ case S_GPROC32_ID:
+ case S_LPROC32_ID:
+ case S_LPROC32_DPC:
+ case S_LPROC32_DPC_ID: {
DictScope S(W, "ProcStart");
- if (InFunctionScope || Size < 36) {
- error(object_error::parse_failed);
- return;
- }
+ const ProcSym *Proc;
+ error(consumeObject(SymData, Proc));
+ if (InFunctionScope)
+ return error(object_error::parse_failed);
InFunctionScope = true;
- // We're currently interested in a limited subset of fields in this
- // segment, just ignore the rest of the fields for now.
- uint8_t Unused[12];
- DE.getU8(&Offset, Unused, 12);
- uint32_t CodeSize = DE.getU32(&Offset);
- DE.getU8(&Offset, Unused, 12);
- StringRef SectionName;
+ // In a COFF object file, the CodeOffset field is typically zero and has a
+ // relocation applied to it. Go and look up the symbol for that
+ // relocation.
+ ptrdiff_t SecOffsetOfCodeOffset =
+ reinterpret_cast<const char *>(&Proc->CodeOffset) - Subsection.data();
+ StringRef LinkageName;
error(resolveSymbolName(Obj->getCOFFSection(Section),
- OffsetInSection + Offset, SectionName));
- Offset += 4;
- DE.getU8(&Offset, Unused, 3);
- StringRef DisplayName = DE.getCStr(&Offset);
- if (!DE.isValidOffset(Offset)) {
- error(object_error::parse_failed);
- return;
- }
- W.printString("DisplayName", DisplayName);
- W.printString("Section", SectionName);
- W.printHex("CodeSize", CodeSize);
+ OffsetInSection + SecOffsetOfCodeOffset,
+ LinkageName));
+ StringRef DisplayName = SymData.split('\0').first;
+ W.printHex("PtrParent", Proc->PtrParent);
+ W.printHex("PtrEnd", Proc->PtrEnd);
+ W.printHex("PtrNext", Proc->PtrNext);
+ W.printHex("CodeSize", Proc->CodeSize);
+ W.printHex("DbgStart", Proc->DbgStart);
+ W.printHex("DbgEnd", Proc->DbgEnd);
+ printTypeIndex("FunctionType", Proc->FunctionType);
+ W.printHex("CodeOffset", Proc->CodeOffset);
+ W.printHex("Segment", Proc->Segment);
+ W.printFlags("Flags", Proc->Flags, makeArrayRef(ProcSymFlags));
+ W.printString("DisplayName", DisplayName);
+ W.printString("LinkageName", LinkageName);
break;
}
- case COFF::DEBUG_SYMBOL_TYPE_PROC_END: {
+
+ case S_PROC_ID_END: {
W.startLine() << "ProcEnd\n";
- if (!InFunctionScope || Size > 0) {
- error(object_error::parse_failed);
- return;
- }
InFunctionScope = false;
break;
}
+
+ case S_BLOCK32: {
+ DictScope S(W, "BlockStart");
+ const BlockSym *Block;
+ error(consumeObject(SymData, Block));
+
+ // In a COFF object file, the CodeOffset field is typically zero and has a
+ // relocation applied to it. Go and look up the symbol for that
+ // relocation.
+ ptrdiff_t SecOffsetOfCodeOffset =
+ reinterpret_cast<const char *>(&Block->CodeOffset) - Subsection.data();
+ StringRef LinkageName;
+ error(resolveSymbolName(Obj->getCOFFSection(Section),
+ OffsetInSection + SecOffsetOfCodeOffset,
+ LinkageName));
+
+ StringRef BlockName = SymData.split('\0').first;
+ W.printHex("PtrParent", Block->PtrParent);
+ W.printHex("PtrEnd", Block->PtrEnd);
+ W.printHex("CodeSize", Block->CodeSize);
+ W.printHex("CodeOffset", Block->CodeOffset);
+ W.printHex("Segment", Block->Segment);
+ W.printString("BlockName", BlockName);
+ W.printString("LinkageName", LinkageName);
+ break;
+ }
+
+ case S_END: {
+ W.startLine() << "BlockEnd\n";
+ InFunctionScope = false;
+ break;
+ }
+
+ case S_LABEL32: {
+ DictScope S(W, "Label");
+ const LabelSym *Label;
+ error(consumeObject(SymData, Label));
+
+ // In a COFF object file, the CodeOffset field is typically zero and has a
+ // relocation applied to it. Go and look up the symbol for that
+ // relocation.
+ ptrdiff_t SecOffsetOfCodeOffset =
+ reinterpret_cast<const char *>(&Label->CodeOffset) - Subsection.data();
+ StringRef LinkageName;
+ error(resolveSymbolName(Obj->getCOFFSection(Section),
+ OffsetInSection + SecOffsetOfCodeOffset,
+ LinkageName));
+
+ StringRef DisplayName = SymData.split('\0').first;
+ W.printHex("CodeOffset", Label->CodeOffset);
+ W.printHex("Segment", Label->Segment);
+ W.printHex("Flags", Label->Flags);
+ W.printFlags("Flags", Label->Flags, makeArrayRef(ProcSymFlags));
+ W.printString("DisplayName", DisplayName);
+ W.printString("LinkageName", LinkageName);
+ break;
+ }
+
+ case S_INLINESITE: {
+ DictScope S(W, "InlineSite");
+ const InlineSiteSym *InlineSite;
+ error(consumeObject(SymData, InlineSite));
+ W.printHex("PtrParent", InlineSite->PtrParent);
+ W.printHex("PtrEnd", InlineSite->PtrEnd);
+ printTypeIndex("Inlinee", InlineSite->Inlinee);
+ W.printBinaryBlock("BinaryAnnotations", SymData);
+ break;
+ }
+
+ case S_INLINESITE_END: {
+ DictScope S(W, "InlineSiteEnd");
+ break;
+ }
+
+ case S_LOCAL: {
+ DictScope S(W, "Local");
+ const LocalSym *Local;
+ error(consumeObject(SymData, Local));
+ printTypeIndex("Type", Local->Type);
+ W.printFlags("Flags", uint16_t(Local->Flags), makeArrayRef(LocalFlags));
+ StringRef VarName = SymData.split('\0').first;
+ W.printString("VarName", VarName);
+ break;
+ }
+
+ case S_CALLSITEINFO: {
+ DictScope S(W, "CallSiteInfo");
+ const CallSiteInfoSym *CallSiteInfo;
+ error(consumeObject(SymData, CallSiteInfo));
+
+ // In a COFF object file, the CodeOffset field is typically zero and has a
+ // relocation applied to it. Go and look up the symbol for that
+ // relocation.
+ ptrdiff_t SecOffsetOfCodeOffset =
+ reinterpret_cast<const char *>(&CallSiteInfo->CodeOffset) - Subsection.data();
+ StringRef LinkageName;
+ error(resolveSymbolName(Obj->getCOFFSection(Section),
+ OffsetInSection + SecOffsetOfCodeOffset,
+ LinkageName));
+ W.printHex("CodeOffset", CallSiteInfo->CodeOffset);
+ W.printHex("Segment", CallSiteInfo->Segment);
+ W.printHex("Reserved", CallSiteInfo->Reserved);
+ printTypeIndex("Type", CallSiteInfo->Type);
+ W.printString("LinkageName", LinkageName);
+ break;
+ }
+
+ case S_HEAPALLOCSITE: {
+ DictScope S(W, "HeapAllocationSite");
+ const HeapAllocationSiteSym *HeapAllocationSite;
+ error(consumeObject(SymData, HeapAllocationSite));
+
+ // In a COFF object file, the CodeOffset field is typically zero and has a
+ // relocation applied to it. Go and look up the symbol for that
+ // relocation.
+ ptrdiff_t SecOffsetOfCodeOffset =
+ reinterpret_cast<const char *>(&HeapAllocationSite->CodeOffset) -
+ Subsection.data();
+ StringRef LinkageName;
+ error(resolveSymbolName(Obj->getCOFFSection(Section),
+ OffsetInSection + SecOffsetOfCodeOffset,
+ LinkageName));
+ W.printHex("CodeOffset", HeapAllocationSite->CodeOffset);
+ W.printHex("Segment", HeapAllocationSite->Segment);
+ W.printHex("CallInstructionSize",
+ HeapAllocationSite->CallInstructionSize);
+ printTypeIndex("Type", HeapAllocationSite->Type);
+ W.printString("LinkageName", LinkageName);
+ break;
+ }
+
+ case S_FRAMECOOKIE: {
+ DictScope S(W, "FrameCookie");
+ const FrameCookieSym *FrameCookie;
+ error(consumeObject(SymData, FrameCookie));
+ W.printHex("CodeOffset", FrameCookie->CodeOffset);
+ W.printHex("Register", FrameCookie->Register);
+ W.printEnum("CookieKind", uint16_t(FrameCookie->CookieKind),
+ makeArrayRef(FrameCookieKinds));
+ break;
+ }
+
+ case S_LDATA32:
+ case S_GDATA32:
+ case S_LMANDATA:
+ case S_GMANDATA: {
+ DictScope S(W, "DataSym");
+ const DataSym *Data;
+ error(consumeObject(SymData, Data));
+
+ // In a COFF object file, the DataOffset field is typically zero and has a
+ // relocation applied to it. Go and look up the symbol for that
+ // relocation.
+ ptrdiff_t SecOffsetOfDataOffset =
+ reinterpret_cast<const char *>(&Data->DataOffset) - Subsection.data();
+ StringRef LinkageName;
+ error(resolveSymbolName(Obj->getCOFFSection(Section),
+ OffsetInSection + SecOffsetOfDataOffset,
+ LinkageName));
+ StringRef DisplayName = SymData.split('\0').first;
+ W.printHex("DataOffset", Data->DataOffset);
+ printTypeIndex("Type", Data->Type);
+ W.printString("DisplayName", DisplayName);
+ W.printString("LinkageName", LinkageName);
+ break;
+ }
+ case S_LTHREAD32:
+ case S_GTHREAD32: {
+ DictScope S(W, "ThreadLocalDataSym");
+ const DataSym *Data;
+ error(consumeObject(SymData, Data));
+
+ // In a COFF object file, the DataOffset field is typically zero and has a
+ // relocation applied to it. Go and look up the symbol for that
+ // relocation.
+ ptrdiff_t SecOffsetOfDataOffset =
+ reinterpret_cast<const char *>(&Data->DataOffset) - Subsection.data();
+ StringRef LinkageName;
+ error(resolveSymbolName(Obj->getCOFFSection(Section),
+ OffsetInSection + SecOffsetOfDataOffset,
+ LinkageName));
+ StringRef DisplayName = SymData.split('\0').first;
+ W.printHex("DataOffset", Data->DataOffset);
+ printTypeIndex("Type", Data->Type);
+ W.printString("DisplayName", DisplayName);
+ W.printString("LinkageName", LinkageName);
+ break;
+ }
+
+ case S_OBJNAME: {
+ DictScope S(W, "ObjectName");
+ const ObjNameSym *ObjName;
+ error(consumeObject(SymData, ObjName));
+ W.printHex("Signature", ObjName->Signature);
+ StringRef ObjectName = SymData.split('\0').first;
+ W.printString("ObjectName", ObjectName);
+ break;
+ }
+
+ case S_COMPILE3: {
+ DictScope S(W, "CompilerFlags");
+ const CompileSym3 *CompFlags;
+ error(consumeObject(SymData, CompFlags));
+ W.printEnum("Language", CompFlags->getLanguage(),
+ makeArrayRef(SourceLanguages));
+ W.printFlags("Flags", CompFlags->flags & ~0xff,
+ makeArrayRef(CompileSym3Flags));
+ W.printEnum("Machine", unsigned(CompFlags->Machine),
+ makeArrayRef(CPUTypeNames));
+ std::string FrontendVersion;
+ {
+ raw_string_ostream Out(FrontendVersion);
+ Out << CompFlags->VersionFrontendMajor << '.'
+ << CompFlags->VersionFrontendMinor << '.'
+ << CompFlags->VersionFrontendBuild << '.'
+ << CompFlags->VersionFrontendQFE;
+ }
+ std::string BackendVersion;
+ {
+ raw_string_ostream Out(BackendVersion);
+ Out << CompFlags->VersionBackendMajor << '.'
+ << CompFlags->VersionBackendMinor << '.'
+ << CompFlags->VersionBackendBuild << '.'
+ << CompFlags->VersionBackendQFE;
+ }
+ W.printString("FrontendVersion", FrontendVersion);
+ W.printString("BackendVersion", BackendVersion);
+ StringRef VersionName = SymData.split('\0').first;
+ W.printString("VersionName", VersionName);
+ break;
+ }
+
+ case S_FRAMEPROC: {
+ DictScope S(W, "FrameProc");
+ const FrameProcSym *FrameProc;
+ error(consumeObject(SymData, FrameProc));
+ W.printHex("TotalFrameBytes", FrameProc->TotalFrameBytes);
+ W.printHex("PaddingFrameBytes", FrameProc->PaddingFrameBytes);
+ W.printHex("OffsetToPadding", FrameProc->OffsetToPadding);
+ W.printHex("BytesOfCalleeSavedRegisters", FrameProc->BytesOfCalleeSavedRegisters);
+ W.printHex("OffsetOfExceptionHandler", FrameProc->OffsetOfExceptionHandler);
+ W.printHex("SectionIdOfExceptionHandler", FrameProc->SectionIdOfExceptionHandler);
+ W.printFlags("Flags", FrameProc->Flags, makeArrayRef(FrameProcSymFlags));
+ break;
+ }
+
+ case S_UDT:
+ case S_COBOLUDT: {
+ DictScope S(W, "UDT");
+ const UDTSym *UDT;
+ error(consumeObject(SymData, UDT));
+ printTypeIndex("Type", UDT->Type);
+ StringRef UDTName = SymData.split('\0').first;
+ W.printString("UDTName", UDTName);
+ break;
+ }
+
+ case S_BPREL32: {
+ DictScope S(W, "BPRelativeSym");
+ const BPRelativeSym *BPRel;
+ error(consumeObject(SymData, BPRel));
+ W.printHex("Offset", BPRel->Offset);
+ printTypeIndex("Type", BPRel->Type);
+ StringRef VarName = SymData.split('\0').first;
+ W.printString("VarName", VarName);
+ break;
+ }
+
+ case S_REGREL32: {
+ DictScope S(W, "RegRelativeSym");
+ const RegRelativeSym *RegRel;
+ error(consumeObject(SymData, RegRel));
+ W.printHex("Offset", RegRel->Offset);
+ printTypeIndex("Type", RegRel->Type);
+ W.printHex("Register", RegRel->Register);
+ StringRef VarName = SymData.split('\0').first;
+ W.printString("VarName", VarName);
+ break;
+ }
+
+ case S_BUILDINFO: {
+ DictScope S(W, "BuildInfo");
+ const BuildInfoSym *BuildInfo;
+ error(consumeObject(SymData, BuildInfo));
+ W.printNumber("BuildId", BuildInfo->BuildId);
+ break;
+ }
+
+ case S_CONSTANT:
+ case S_MANCONSTANT: {
+ DictScope S(W, "Constant");
+ const ConstantSym *Constant;
+ error(consumeObject(SymData, Constant));
+ printTypeIndex("Type", Constant->Type);
+ APSInt Value;
+ error(decodeNumerictLeaf(SymData, Value));
+ W.printNumber("Value", Value);
+ StringRef Name = SymData.split('\0').first;
+ W.printString("Name", Name);
+ break;
+ }
+
default: {
- if (opts::CodeViewSubsectionBytes) {
- ListScope S(W, "Record");
- W.printHex("Size", Size);
- W.printHex("Type", Type);
+ DictScope S(W, "UnknownSym");
+ W.printHex("Type", unsigned(Type));
+ W.printHex("Size", Rec->RecordLength);
+ W.printBinaryBlock("SymData", SymData);
+ break;
+ }
+ }
+ }
+}
+
+StringRef getRemainingTypeBytes(const TypeRecord *Rec, const char *Start) {
+ ptrdiff_t StartOffset = Start - reinterpret_cast<const char *>(Rec);
+ size_t RecSize = Rec->Len + 2;
+ assert(StartOffset >= 0 && "negative start-offset!");
+ assert(static_cast<size_t>(StartOffset) <= RecSize &&
+ "Start beyond the end of Rec");
+ return StringRef(Start, RecSize - StartOffset);
+}
+
+StringRef getRemainingBytesAsString(const TypeRecord *Rec, const char *Start) {
+ StringRef Remaining = getRemainingTypeBytes(Rec, Start);
+ StringRef Leading, Trailing;
+ std::tie(Leading, Trailing) = Remaining.split('\0');
+ return Leading;
+}
+
+StringRef COFFDumper::getTypeName(TypeIndex TI) {
+ if (TI.isNoType())
+ return "<no type>";
+
+ if (TI.isSimple()) {
+ // This is a simple type.
+ for (const auto &SimpleTypeName : SimpleTypeNames) {
+ if (SimpleTypeName.Value == TI.getSimpleKind()) {
+ if (TI.getSimpleMode() == SimpleTypeMode::Direct)
+ return SimpleTypeName.Name.drop_back(1);
+ // Otherwise, this is a pointer type. We gloss over the distinction
+ // between near, far, 64, 32, etc, and just give a pointer type.
+ return SimpleTypeName.Name;
+ }
+ }
+ return "<unknown simple type>";
+ }
+
+ // User-defined type.
+ StringRef UDTName;
+ unsigned UDTIndex = TI.getIndex() - 0x1000;
+ if (UDTIndex < CVUDTNames.size())
+ return CVUDTNames[UDTIndex];
+
+ return "<unknown UDT>";
+}
+
+void COFFDumper::printTypeIndex(StringRef FieldName, TypeIndex TI) {
+ StringRef TypeName;
+ if (!TI.isNoType())
+ TypeName = getTypeName(TI);
+ if (!TypeName.empty())
+ W.printHex(FieldName, TypeName, TI.getIndex());
+ else
+ W.printHex(FieldName, TI.getIndex());
+}
+
+static StringRef getLeafTypeName(LeafType LT) {
+ switch (LT) {
+ case LF_STRING_ID: return "StringId";
+ case LF_FIELDLIST: return "FieldList";
+ case LF_ARGLIST:
+ case LF_SUBSTR_LIST: return "ArgList";
+ case LF_CLASS:
+ case LF_STRUCTURE:
+ case LF_INTERFACE: return "ClassType";
+ case LF_UNION: return "UnionType";
+ case LF_ENUM: return "EnumType";
+ case LF_ARRAY: return "ArrayType";
+ case LF_VFTABLE: return "VFTableType";
+ case LF_MFUNC_ID: return "MemberFuncId";
+ case LF_PROCEDURE: return "ProcedureType";
+ case LF_MFUNCTION: return "MemberFunctionType";
+ case LF_METHODLIST: return "MethodListEntry";
+ case LF_FUNC_ID: return "FuncId";
+ case LF_TYPESERVER2: return "TypeServer2";
+ case LF_POINTER: return "PointerType";
+ case LF_MODIFIER: return "TypeModifier";
+ case LF_VTSHAPE: return "VTableShape";
+ case LF_UDT_SRC_LINE: return "UDTSrcLine";
+ case LF_BUILDINFO: return "BuildInfo";
+ default: break;
+ }
+ return "UnknownLeaf";
+}
+
+void COFFDumper::printCodeViewTypeSection(StringRef SectionName,
+ const SectionRef &Section) {
+ ListScope D(W, "CodeViewTypes");
+ W.printNumber("Section", SectionName, Obj->getSectionID(Section));
+ StringRef Data;
+ error(Section.getContents(Data));
+ W.printBinaryBlock("Data", Data);
+
+ unsigned Magic = *reinterpret_cast<const ulittle32_t *>(Data.data());
+ W.printHex("Magic", Magic);
+
+ Data = Data.drop_front(4);
+
+ while (!Data.empty()) {
+ const TypeRecord *Rec;
+ error(consumeObject(Data, Rec));
+ auto Leaf = static_cast<LeafType>(uint16_t(Rec->Leaf));
+
+ // This record is 'Len - 2' bytes, and the next one starts immediately
+ // afterwards.
+ StringRef LeafData = Data.substr(0, Rec->Len - 2);
+ StringRef RemainingData = Data.drop_front(LeafData.size());
+
+ // Find the name of this leaf type.
+ StringRef LeafName = getLeafTypeName(Leaf);
+ DictScope S(W, LeafName);
+ unsigned NextTypeIndex = 0x1000 + CVUDTNames.size();
+ W.printEnum("LeafType", unsigned(Leaf), makeArrayRef(LeafTypeNames));
+ W.printHex("TypeIndex", NextTypeIndex);
+
+ // Fill this in inside the switch to get something in CVUDTNames.
+ StringRef Name;
+
+ switch (Leaf) {
+ default: {
+ W.printHex("Size", Rec->Len);
+ if (opts::CodeViewSubsectionBytes)
+ W.printBinaryBlock("LeafData", LeafData);
+ break;
+ }
+
+ case LF_STRING_ID: {
+ const StringId *String;
+ error(consumeObject(LeafData, String));
+ W.printHex("Id", String->id.getIndex());
+ StringRef StringData = getRemainingBytesAsString(Rec, LeafData.data());
+ W.printString("StringData", StringData);
+ // Put this in CVUDTNames so it gets printed with LF_UDT_SRC_LINE.
+ Name = StringData;
+ break;
+ }
+
+ case LF_FIELDLIST: {
+ W.printHex("Size", Rec->Len);
+ // FieldList has no fixed prefix that can be described with a struct. All
+ // the bytes must be interpreted as more records.
+ printCodeViewFieldList(LeafData);
+ break;
+ }
+
+ case LF_ARGLIST:
+ case LF_SUBSTR_LIST: {
+ const ArgList *Args;
+ error(consumeObject(LeafData, Args));
+ W.printNumber("NumArgs", Args->NumArgs);
+ ListScope Arguments(W, "Arguments");
+ SmallString<256> TypeName("(");
+ for (uint32_t ArgI = 0; ArgI != Args->NumArgs; ++ArgI) {
+ const TypeIndex *Type;
+ error(consumeObject(LeafData, Type));
+ printTypeIndex("ArgType", *Type);
+ StringRef ArgTypeName = getTypeName(*Type);
+ TypeName.append(ArgTypeName);
+ if (ArgI + 1 != Args->NumArgs)
+ TypeName.append(", ");
+ }
+ TypeName.push_back(')');
+ Name = TypeNames.insert(TypeName).first->getKey();
+ break;
+ }
+
+ case LF_CLASS:
+ case LF_STRUCTURE:
+ case LF_INTERFACE: {
+ const ClassType *Class;
+ error(consumeObject(LeafData, Class));
+ W.printNumber("MemberCount", Class->MemberCount);
+ uint16_t Props = Class->Properties;
+ W.printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
+ printTypeIndex("FieldList", Class->FieldList);
+ printTypeIndex("DerivedFrom", Class->DerivedFrom);
+ printTypeIndex("VShape", Class->VShape);
+ uint64_t SizeOf;
+ error(decodeUIntLeaf(LeafData, SizeOf));
+ W.printNumber("SizeOf", SizeOf);
+ StringRef LinkageName;
+ std::tie(Name, LinkageName) = LeafData.split('\0');
+ W.printString("Name", Name);
+ if (Props & uint16_t(ClassOptions::HasUniqueName)) {
+ LinkageName = getRemainingBytesAsString(Rec, LinkageName.data());
+ if (LinkageName.empty())
+ return error(object_error::parse_failed);
+ W.printString("LinkageName", LinkageName);
+ }
+ break;
+ }
+
+ case LF_UNION: {
+ const UnionType *Union;
+ error(consumeObject(LeafData, Union));
+ W.printNumber("MemberCount", Union->MemberCount);
+ uint16_t Props = Union->Properties;
+ W.printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
+ printTypeIndex("FieldList", Union->FieldList);
+ uint64_t SizeOf;
+ error(decodeUIntLeaf(LeafData, SizeOf));
+ W.printNumber("SizeOf", SizeOf);
+ StringRef LinkageName;
+ std::tie(Name, LinkageName) = LeafData.split('\0');
+ W.printString("Name", Name);
+ if (Props & uint16_t(ClassOptions::HasUniqueName)) {
+ LinkageName = getRemainingBytesAsString(Rec, LinkageName.data());
+ if (LinkageName.empty())
+ return error(object_error::parse_failed);
+ W.printString("LinkageName", LinkageName);
+ }
+ break;
+ }
- StringRef Contents = DE.getData().substr(Offset, Size);
- W.printBinaryBlock("Contents", Contents);
+ case LF_ENUM: {
+ const EnumType *Enum;
+ error(consumeObject(LeafData, Enum));
+ W.printNumber("NumEnumerators", Enum->NumEnumerators);
+ W.printFlags("Properties", uint16_t(Enum->Properties),
+ makeArrayRef(ClassOptionNames));
+ printTypeIndex("UnderlyingType", Enum->UnderlyingType);
+ printTypeIndex("FieldListType", Enum->FieldListType);
+ Name = LeafData.split('\0').first;
+ W.printString("Name", Name);
+ break;
+ }
+
+ case LF_ARRAY: {
+ const ArrayType *AT;
+ error(consumeObject(LeafData, AT));
+ printTypeIndex("ElementType", AT->ElementType);
+ printTypeIndex("IndexType", AT->IndexType);
+ uint64_t SizeOf;
+ error(decodeUIntLeaf(LeafData, SizeOf));
+ W.printNumber("SizeOf", SizeOf);
+ Name = LeafData.split('\0').first;
+ W.printString("Name", Name);
+ break;
+ }
+
+ case LF_VFTABLE: {
+ const VFTableType *VFT;
+ error(consumeObject(LeafData, VFT));
+ printTypeIndex("CompleteClass", VFT->CompleteClass);
+ printTypeIndex("OverriddenVFTable", VFT->OverriddenVFTable);
+ W.printHex("VFPtrOffset", VFT->VFPtrOffset);
+ StringRef NamesData = LeafData.substr(0, VFT->NamesLen);
+ std::tie(Name, NamesData) = NamesData.split('\0');
+ W.printString("VFTableName", Name);
+ while (!NamesData.empty()) {
+ StringRef MethodName;
+ std::tie(MethodName, NamesData) = NamesData.split('\0');
+ W.printString("MethodName", MethodName);
+ }
+ break;
+ }
+
+ case LF_MFUNC_ID: {
+ const MemberFuncId *Id;
+ error(consumeObject(LeafData, Id));
+ printTypeIndex("ClassType", Id->ClassType);
+ printTypeIndex("FunctionType", Id->FunctionType);
+ Name = LeafData.split('\0').first;
+ W.printString("Name", Name);
+ break;
+ }
+
+ case LF_PROCEDURE: {
+ const ProcedureType *Proc;
+ error(consumeObject(LeafData, Proc));
+ printTypeIndex("ReturnType", Proc->ReturnType);
+ W.printEnum("CallingConvention", uint8_t(Proc->CallConv),
+ makeArrayRef(CallingConventions));
+ W.printFlags("FunctionOptions", uint8_t(Proc->Options),
+ makeArrayRef(FunctionOptionEnum));
+ W.printNumber("NumParameters", Proc->NumParameters);
+ printTypeIndex("ArgListType", Proc->ArgListType);
+
+ StringRef ReturnTypeName = getTypeName(Proc->ReturnType);
+ StringRef ArgListTypeName = getTypeName(Proc->ArgListType);
+ SmallString<256> TypeName(ReturnTypeName);
+ TypeName.push_back(' ');
+ TypeName.append(ArgListTypeName);
+ Name = TypeNames.insert(TypeName).first->getKey();
+ break;
+ }
+
+ case LF_MFUNCTION: {
+ const MemberFunctionType *MemberFunc;
+ error(consumeObject(LeafData, MemberFunc));
+ printTypeIndex("ReturnType", MemberFunc->ReturnType);
+ printTypeIndex("ClassType", MemberFunc->ClassType);
+ printTypeIndex("ThisType", MemberFunc->ThisType);
+ W.printEnum("CallingConvention", uint8_t(MemberFunc->CallConv),
+ makeArrayRef(CallingConventions));
+ W.printFlags("FunctionOptions", uint8_t(MemberFunc->Options),
+ makeArrayRef(FunctionOptionEnum));
+ W.printNumber("NumParameters", MemberFunc->NumParameters);
+ printTypeIndex("ArgListType", MemberFunc->ArgListType);
+ W.printNumber("ThisAdjustment", MemberFunc->ThisAdjustment);
+
+ StringRef ReturnTypeName = getTypeName(MemberFunc->ReturnType);
+ StringRef ClassTypeName = getTypeName(MemberFunc->ClassType);
+ StringRef ArgListTypeName = getTypeName(MemberFunc->ArgListType);
+ SmallString<256> TypeName(ReturnTypeName);
+ TypeName.push_back(' ');
+ TypeName.append(ClassTypeName);
+ TypeName.append("::");
+ TypeName.append(ArgListTypeName);
+ Name = TypeNames.insert(TypeName).first->getKey();
+ break;
+ }
+
+ case LF_METHODLIST: {
+ while (!LeafData.empty()) {
+ const MethodListEntry *Method;
+ error(consumeObject(LeafData, Method));
+ ListScope S(W, "Method");
+ printMemberAttributes(Method->Attrs);
+ printTypeIndex("Type", Method->Type);
+ if (Method->isIntroducedVirtual()) {
+ const little32_t *VFTOffsetPtr;
+ error(consumeObject(LeafData, VFTOffsetPtr));
+ W.printHex("VFTableOffset", *VFTOffsetPtr);
+ }
+ }
+ break;
+ }
+
+ case LF_FUNC_ID: {
+ const FuncId *Func;
+ error(consumeObject(LeafData, Func));
+ printTypeIndex("ParentScope", Func->ParentScope);
+ printTypeIndex("FunctionType", Func->FunctionType);
+ StringRef Name, Null;
+ std::tie(Name, Null) = LeafData.split('\0');
+ W.printString("Name", Name);
+ break;
+ }
+
+ case LF_TYPESERVER2: {
+ const TypeServer2 *TypeServer;
+ error(consumeObject(LeafData, TypeServer));
+ W.printBinary("Signature", StringRef(TypeServer->Signature, 16));
+ W.printNumber("Age", TypeServer->Age);
+ Name = LeafData.split('\0').first;
+ W.printString("Name", Name);
+ break;
+ }
+
+ case LF_POINTER: {
+ const PointerType *Ptr;
+ error(consumeObject(LeafData, Ptr));
+ printTypeIndex("PointeeType", Ptr->PointeeType);
+ W.printHex("PointerAttributes", Ptr->Attrs);
+ W.printEnum("PtrType", unsigned(Ptr->getPtrKind()),
+ makeArrayRef(PtrKindNames));
+ W.printEnum("PtrMode", unsigned(Ptr->getPtrMode()),
+ makeArrayRef(PtrModeNames));
+ W.printNumber("IsFlat", Ptr->isFlat());
+ W.printNumber("IsConst", Ptr->isConst());
+ W.printNumber("IsVolatile", Ptr->isVolatile());
+ W.printNumber("IsUnaligned", Ptr->isUnaligned());
+
+ if (Ptr->isPointerToMember()) {
+ const PointerToMemberTail *PMT;
+ error(consumeObject(LeafData, PMT));
+ printTypeIndex("ClassType", PMT->ClassType);
+ W.printEnum("Representation", PMT->Representation,
+ makeArrayRef(PtrMemberRepNames));
+
+ StringRef PointeeName = getTypeName(Ptr->PointeeType);
+ StringRef ClassName = getTypeName(PMT->ClassType);
+ SmallString<256> TypeName(PointeeName);
+ TypeName.push_back(' ');
+ TypeName.append(ClassName);
+ TypeName.append("::*");
+ Name = TypeNames.insert(TypeName).first->getKey();
+ } else {
+ W.printBinaryBlock("TailData", LeafData);
+
+ SmallString<256> TypeName;
+ if (Ptr->isConst())
+ TypeName.append("const ");
+ if (Ptr->isVolatile())
+ TypeName.append("volatile ");
+ if (Ptr->isUnaligned())
+ TypeName.append("__unaligned ");
+
+ TypeName.append(getTypeName(Ptr->PointeeType));
+
+ if (Ptr->getPtrMode() == PointerMode::LValueReference)
+ TypeName.append("&");
+ else if (Ptr->getPtrMode() == PointerMode::RValueReference)
+ TypeName.append("&&");
+ else if (Ptr->getPtrMode() == PointerMode::Pointer)
+ TypeName.append("*");
+
+ Name = TypeNames.insert(TypeName).first->getKey();
}
+ break;
+ }
+
+ case LF_MODIFIER: {
+ const TypeModifier *Mod;
+ error(consumeObject(LeafData, Mod));
+ printTypeIndex("ModifiedType", Mod->ModifiedType);
+ W.printFlags("Modifiers", Mod->Modifiers,
+ makeArrayRef(TypeModifierNames));
+
+ StringRef ModifiedName = getTypeName(Mod->ModifiedType);
+ SmallString<256> TypeName;
+ if (Mod->Modifiers & uint16_t(ModifierOptions::Const))
+ TypeName.append("const ");
+ if (Mod->Modifiers & uint16_t(ModifierOptions::Volatile))
+ TypeName.append("volatile ");
+ if (Mod->Modifiers & uint16_t(ModifierOptions::Unaligned))
+ TypeName.append("__unaligned ");
+ TypeName.append(ModifiedName);
+ Name = TypeNames.insert(TypeName).first->getKey();
+ break;
+ }
+
+ case LF_VTSHAPE: {
+ const VTableShape *Shape;
+ error(consumeObject(LeafData, Shape));
+ unsigned VFEntryCount = Shape->VFEntryCount;
+ W.printNumber("VFEntryCount", VFEntryCount);
+ // We could print out whether the methods are near or far, but in practice
+ // today everything is CV_VTS_near32, so it's just noise.
+ break;
+ }
- Offset += Size;
+ case LF_UDT_SRC_LINE: {
+ const UDTSrcLine *Line;
+ error(consumeObject(LeafData, Line));
+ printTypeIndex("UDT", Line->UDT);
+ printTypeIndex("SourceFile", Line->SourceFile);
+ W.printNumber("LineNumber", Line->LineNumber);
break;
}
+
+ case LF_BUILDINFO: {
+ const BuildInfo *Args;
+ error(consumeObject(LeafData, Args));
+ W.printNumber("NumArgs", Args->NumArgs);
+
+ ListScope Arguments(W, "Arguments");
+ for (uint32_t ArgI = 0; ArgI != Args->NumArgs; ++ArgI) {
+ const TypeIndex *Type;
+ error(consumeObject(LeafData, Type));
+ printTypeIndex("ArgType", *Type);
+ }
+ break;
}
+ }
+
+ CVUDTNames.push_back(Name);
+
+ Data = RemainingData;
+ // FIXME: The stream contains LF_PAD bytes that we need to ignore, but those
+ // are typically included in LeafData. We may need to call skipPadding() if
+ // we ever find a record that doesn't count those bytes.
}
+}
+
+static StringRef skipPadding(StringRef Data) {
+ if (Data.empty())
+ return Data;
+ uint8_t Leaf = Data.front();
+ if (Leaf < LF_PAD0)
+ return Data;
+ // Leaf is greater than 0xf0. We should advance by the number of bytes in the
+ // low 4 bits.
+ return Data.drop_front(Leaf & 0x0F);
+}
+
+void COFFDumper::printMemberAttributes(MemberAttributes Attrs) {
+ W.printEnum("AccessSpecifier", uint8_t(Attrs.getAccess()),
+ makeArrayRef(MemberAccessNames));
+ auto MK = Attrs.getMethodKind();
+ // Data members will be vanilla. Don't try to print a method kind for them.
+ if (MK != MethodKind::Vanilla)
+ W.printEnum("MethodKind", unsigned(MK), makeArrayRef(MemberKindNames));
+ if (Attrs.getFlags() != MethodOptions::None) {
+ W.printFlags("MethodOptions", unsigned(Attrs.getFlags()),
+ makeArrayRef(MethodOptionNames));
+ }
+}
+
+void COFFDumper::printCodeViewFieldList(StringRef FieldData) {
+ while (!FieldData.empty()) {
+ const ulittle16_t *LeafPtr;
+ error(consumeObject(FieldData, LeafPtr));
+ uint16_t Leaf = *LeafPtr;
+ switch (Leaf) {
+ default:
+ W.printHex("UnknownMember", Leaf);
+ // We can't advance once we hit an unknown field. The size is not encoded.
+ return;
+
+ case LF_NESTTYPE: {
+ const NestedType *Nested;
+ error(consumeObject(FieldData, Nested));
+ DictScope S(W, "NestedType");
+ printTypeIndex("Type", Nested->Type);
+ StringRef Name;
+ std::tie(Name, FieldData) = FieldData.split('\0');
+ W.printString("Name", Name);
+ break;
+ }
+
+ case LF_ONEMETHOD: {
+ const OneMethod *Method;
+ error(consumeObject(FieldData, Method));
+ DictScope S(W, "OneMethod");
+ printMemberAttributes(Method->Attrs);
+ printTypeIndex("Type", Method->Type);
+ // If virtual, then read the vftable offset.
+ if (Method->isIntroducedVirtual()) {
+ const little32_t *VFTOffsetPtr;
+ error(consumeObject(FieldData, VFTOffsetPtr));
+ W.printHex("VFTableOffset", *VFTOffsetPtr);
+ }
+ StringRef Name;
+ std::tie(Name, FieldData) = FieldData.split('\0');
+ W.printString("Name", Name);
+ break;
+ }
+
+ case LF_METHOD: {
+ const OverloadedMethod *Method;
+ error(consumeObject(FieldData, Method));
+ DictScope S(W, "OverloadedMethod");
+ W.printHex("MethodCount", Method->MethodCount);
+ W.printHex("MethodListIndex", Method->MethList.getIndex());
+ StringRef Name;
+ std::tie(Name, FieldData) = FieldData.split('\0');
+ W.printString("Name", Name);
+ break;
+ }
- if (InFunctionScope)
- error(object_error::parse_failed);
+ case LF_MEMBER: {
+ const DataMember *Field;
+ error(consumeObject(FieldData, Field));
+ DictScope S(W, "DataMember");
+ printMemberAttributes(Field->Attrs);
+ printTypeIndex("Type", Field->Type);
+ uint64_t FieldOffset;
+ error(decodeUIntLeaf(FieldData, FieldOffset));
+ W.printHex("FieldOffset", FieldOffset);
+ StringRef Name;
+ std::tie(Name, FieldData) = FieldData.split('\0');
+ W.printString("Name", Name);
+ break;
+ }
+
+ case LF_STMEMBER: {
+ const StaticDataMember *Field;
+ error(consumeObject(FieldData, Field));
+ DictScope S(W, "StaticDataMember");
+ printMemberAttributes(Field->Attrs);
+ printTypeIndex("Type", Field->Type);
+ StringRef Name;
+ std::tie(Name, FieldData) = FieldData.split('\0');
+ W.printString("Name", Name);
+ break;
+ }
+
+ case LF_VFUNCTAB: {
+ const VirtualFunctionPointer *VFTable;
+ error(consumeObject(FieldData, VFTable));
+ DictScope S(W, "VirtualFunctionPointer");
+ printTypeIndex("Type", VFTable->Type);
+ break;
+ }
+
+ case LF_ENUMERATE: {
+ const Enumerator *Enum;
+ error(consumeObject(FieldData, Enum));
+ DictScope S(W, "Enumerator");
+ printMemberAttributes(Enum->Attrs);
+ APSInt EnumValue;
+ error(decodeNumerictLeaf(FieldData, EnumValue));
+ W.printNumber("EnumValue", EnumValue);
+ StringRef Name;
+ std::tie(Name, FieldData) = FieldData.split('\0');
+ W.printString("Name", Name);
+ break;
+ }
+
+ case LF_BCLASS:
+ case LF_BINTERFACE: {
+ const BaseClass *Base;
+ error(consumeObject(FieldData, Base));
+ DictScope S(W, "BaseClass");
+ printMemberAttributes(Base->Attrs);
+ printTypeIndex("BaseType", Base->BaseType);
+ uint64_t BaseOffset;
+ error(decodeUIntLeaf(FieldData, BaseOffset));
+ W.printHex("BaseOffset", BaseOffset);
+ break;
+ }
+
+ case LF_VBCLASS:
+ case LF_IVBCLASS: {
+ const VirtualBaseClass *Base;
+ error(consumeObject(FieldData, Base));
+ DictScope S(W, "VirtualBaseClass");
+ printMemberAttributes(Base->Attrs);
+ printTypeIndex("BaseType", Base->BaseType);
+ printTypeIndex("VBPtrType", Base->VBPtrType);
+ uint64_t VBPtrOffset, VBTableIndex;
+ error(decodeUIntLeaf(FieldData, VBPtrOffset));
+ error(decodeUIntLeaf(FieldData, VBTableIndex));
+ W.printHex("VBPtrOffset", VBPtrOffset);
+ W.printHex("VBTableIndex", VBTableIndex);
+ break;
+ }
+ }
+
+ // Handle padding.
+ FieldData = skipPadding(FieldData);
+ }
}
void COFFDumper::printSections() {
Added: llvm/trunk/tools/llvm-readobj/CVLeafTypes.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/CVLeafTypes.def?rev=257658&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-readobj/CVLeafTypes.def (added)
+++ llvm/trunk/tools/llvm-readobj/CVLeafTypes.def Wed Jan 13 13:32:35 2016
@@ -0,0 +1,211 @@
+//===-- CVLeafTypes.def - All CodeView leaf types ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// See LEAF_ENUM_e in cvinfo.h. This should match the constants there.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LEAF_TYPE
+#define LEAF_TYPE(ename, value)
+#endif
+
+// 16 bit type records.
+LEAF_TYPE(LF_MODIFIER_16t, 0x0001)
+LEAF_TYPE(LF_POINTER_16t, 0x0002)
+LEAF_TYPE(LF_ARRAY_16t, 0x0003)
+LEAF_TYPE(LF_CLASS_16t, 0x0004)
+LEAF_TYPE(LF_STRUCTURE_16t, 0x0005)
+LEAF_TYPE(LF_UNION_16t, 0x0006)
+LEAF_TYPE(LF_ENUM_16t, 0x0007)
+LEAF_TYPE(LF_PROCEDURE_16t, 0x0008)
+LEAF_TYPE(LF_MFUNCTION_16t, 0x0009)
+LEAF_TYPE(LF_VTSHAPE, 0x000a)
+LEAF_TYPE(LF_COBOL0_16t, 0x000b)
+LEAF_TYPE(LF_COBOL1, 0x000c)
+LEAF_TYPE(LF_BARRAY_16t, 0x000d)
+LEAF_TYPE(LF_LABEL, 0x000e)
+LEAF_TYPE(LF_NULLLEAF, 0x000f) // LF_NULL
+LEAF_TYPE(LF_NOTTRAN, 0x0010)
+LEAF_TYPE(LF_DIMARRAY_16t, 0x0011)
+LEAF_TYPE(LF_VFTPATH_16t, 0x0012)
+LEAF_TYPE(LF_PRECOMP_16t, 0x0013)
+LEAF_TYPE(LF_ENDPRECOMP, 0x0014)
+LEAF_TYPE(LF_OEM_16t, 0x0015)
+LEAF_TYPE(LF_TYPESERVER_ST, 0x0016)
+
+LEAF_TYPE(LF_SKIP_16t, 0x0200)
+LEAF_TYPE(LF_ARGLIST_16t, 0x0201)
+LEAF_TYPE(LF_DEFARG_16t, 0x0202)
+LEAF_TYPE(LF_LIST, 0x0203)
+LEAF_TYPE(LF_FIELDLIST_16t, 0x0204)
+LEAF_TYPE(LF_DERIVED_16t, 0x0205)
+LEAF_TYPE(LF_BITFIELD_16t, 0x0206)
+LEAF_TYPE(LF_METHODLIST_16t, 0x0207)
+LEAF_TYPE(LF_DIMCONU_16t, 0x0208)
+LEAF_TYPE(LF_DIMCONLU_16t, 0x0209)
+LEAF_TYPE(LF_DIMVARU_16t, 0x020a)
+LEAF_TYPE(LF_DIMVARLU_16t, 0x020b)
+LEAF_TYPE(LF_REFSYM, 0x020c)
+
+// 16 bit member types. Generally not length prefixed.
+LEAF_TYPE(LF_BCLASS_16t, 0x0400)
+LEAF_TYPE(LF_VBCLASS_16t, 0x0401)
+LEAF_TYPE(LF_IVBCLASS_16t, 0x0402)
+LEAF_TYPE(LF_ENUMERATE_ST, 0x0403)
+LEAF_TYPE(LF_FRIENDFCN_16t, 0x0404)
+LEAF_TYPE(LF_INDEX_16t, 0x0405)
+LEAF_TYPE(LF_MEMBER_16t, 0x0406)
+LEAF_TYPE(LF_STMEMBER_16t, 0x0407)
+LEAF_TYPE(LF_METHOD_16t, 0x0408)
+LEAF_TYPE(LF_NESTTYPE_16t, 0x0409)
+LEAF_TYPE(LF_VFUNCTAB_16t, 0x040a)
+LEAF_TYPE(LF_FRIENDCLS_16t, 0x040b)
+LEAF_TYPE(LF_ONEMETHOD_16t, 0x040c)
+LEAF_TYPE(LF_VFUNCOFF_16t, 0x040d)
+
+LEAF_TYPE(LF_TI16_MAX, 0x1000)
+
+LEAF_TYPE(LF_MODIFIER, 0x1001)
+LEAF_TYPE(LF_POINTER, 0x1002)
+LEAF_TYPE(LF_ARRAY_ST, 0x1003)
+LEAF_TYPE(LF_CLASS_ST, 0x1004)
+LEAF_TYPE(LF_STRUCTURE_ST, 0x1005)
+LEAF_TYPE(LF_UNION_ST, 0x1006)
+LEAF_TYPE(LF_ENUM_ST, 0x1007)
+LEAF_TYPE(LF_PROCEDURE, 0x1008)
+LEAF_TYPE(LF_MFUNCTION, 0x1009)
+LEAF_TYPE(LF_COBOL0, 0x100a)
+LEAF_TYPE(LF_BARRAY, 0x100b)
+LEAF_TYPE(LF_DIMARRAY_ST, 0x100c)
+LEAF_TYPE(LF_VFTPATH, 0x100d)
+LEAF_TYPE(LF_PRECOMP_ST, 0x100e)
+LEAF_TYPE(LF_OEM, 0x100f)
+LEAF_TYPE(LF_ALIAS_ST, 0x1010)
+LEAF_TYPE(LF_OEM2, 0x1011)
+
+LEAF_TYPE(LF_SKIP, 0x1200)
+LEAF_TYPE(LF_ARGLIST, 0x1201)
+LEAF_TYPE(LF_DEFARG_ST, 0x1202)
+LEAF_TYPE(LF_FIELDLIST, 0x1203)
+LEAF_TYPE(LF_DERIVED, 0x1204)
+LEAF_TYPE(LF_BITFIELD, 0x1205)
+LEAF_TYPE(LF_METHODLIST, 0x1206)
+LEAF_TYPE(LF_DIMCONU, 0x1207)
+LEAF_TYPE(LF_DIMCONLU, 0x1208)
+LEAF_TYPE(LF_DIMVARU, 0x1209)
+LEAF_TYPE(LF_DIMVARLU, 0x120a)
+
+// Member type records. These are generally not length prefixed, and appear
+// inside of a field list record.
+LEAF_TYPE(LF_BCLASS, 0x1400)
+LEAF_TYPE(LF_VBCLASS, 0x1401)
+LEAF_TYPE(LF_IVBCLASS, 0x1402)
+LEAF_TYPE(LF_FRIENDFCN_ST, 0x1403)
+LEAF_TYPE(LF_INDEX, 0x1404)
+LEAF_TYPE(LF_MEMBER_ST, 0x1405)
+LEAF_TYPE(LF_STMEMBER_ST, 0x1406)
+LEAF_TYPE(LF_METHOD_ST, 0x1407)
+LEAF_TYPE(LF_NESTTYPE_ST, 0x1408)
+LEAF_TYPE(LF_VFUNCTAB, 0x1409)
+LEAF_TYPE(LF_FRIENDCLS, 0x140a)
+LEAF_TYPE(LF_ONEMETHOD_ST, 0x140b)
+LEAF_TYPE(LF_VFUNCOFF, 0x140c)
+LEAF_TYPE(LF_NESTTYPEEX_ST, 0x140d)
+LEAF_TYPE(LF_MEMBERMODIFY_ST, 0x140e)
+LEAF_TYPE(LF_MANAGED_ST, 0x140f)
+
+LEAF_TYPE(LF_ST_MAX, 0x1500)
+LEAF_TYPE(LF_TYPESERVER, 0x1501)
+LEAF_TYPE(LF_ENUMERATE, 0x1502)
+LEAF_TYPE(LF_ARRAY, 0x1503)
+LEAF_TYPE(LF_CLASS, 0x1504)
+LEAF_TYPE(LF_STRUCTURE, 0x1505)
+LEAF_TYPE(LF_UNION, 0x1506)
+LEAF_TYPE(LF_ENUM, 0x1507)
+LEAF_TYPE(LF_DIMARRAY, 0x1508)
+LEAF_TYPE(LF_PRECOMP, 0x1509)
+LEAF_TYPE(LF_ALIAS, 0x150a)
+LEAF_TYPE(LF_DEFARG, 0x150b)
+LEAF_TYPE(LF_FRIENDFCN, 0x150c)
+LEAF_TYPE(LF_MEMBER, 0x150d)
+LEAF_TYPE(LF_STMEMBER, 0x150e)
+LEAF_TYPE(LF_METHOD, 0x150f)
+LEAF_TYPE(LF_NESTTYPE, 0x1510)
+LEAF_TYPE(LF_ONEMETHOD, 0x1511)
+LEAF_TYPE(LF_NESTTYPEEX, 0x1512)
+LEAF_TYPE(LF_MEMBERMODIFY, 0x1513)
+LEAF_TYPE(LF_MANAGED, 0x1514)
+LEAF_TYPE(LF_TYPESERVER2, 0x1515)
+LEAF_TYPE(LF_STRIDED_ARRAY, 0x1516)
+LEAF_TYPE(LF_HLSL, 0x1517)
+LEAF_TYPE(LF_MODIFIER_EX, 0x1518)
+LEAF_TYPE(LF_INTERFACE, 0x1519)
+LEAF_TYPE(LF_BINTERFACE, 0x151a)
+LEAF_TYPE(LF_VECTOR, 0x151b)
+LEAF_TYPE(LF_MATRIX, 0x151c)
+LEAF_TYPE(LF_VFTABLE, 0x151d)
+
+// ID leaf records. Subsequent leaf types may be referenced from .debug$S.
+
+LEAF_TYPE(LF_FUNC_ID, 0x1601)
+LEAF_TYPE(LF_MFUNC_ID, 0x1602)
+LEAF_TYPE(LF_BUILDINFO, 0x1603)
+LEAF_TYPE(LF_SUBSTR_LIST, 0x1604)
+LEAF_TYPE(LF_STRING_ID, 0x1605)
+LEAF_TYPE(LF_UDT_SRC_LINE, 0x1606)
+LEAF_TYPE(LF_UDT_MOD_SRC_LINE, 0x1607)
+
+// Numeric leaf types. These are generally contained in other records, and not
+// encountered in the main type stream.
+
+LEAF_TYPE(LF_NUMERIC, 0x8000)
+LEAF_TYPE(LF_CHAR, 0x8000)
+LEAF_TYPE(LF_SHORT, 0x8001)
+LEAF_TYPE(LF_USHORT, 0x8002)
+LEAF_TYPE(LF_LONG, 0x8003)
+LEAF_TYPE(LF_ULONG, 0x8004)
+LEAF_TYPE(LF_REAL32, 0x8005)
+LEAF_TYPE(LF_REAL64, 0x8006)
+LEAF_TYPE(LF_REAL80, 0x8007)
+LEAF_TYPE(LF_REAL128, 0x8008)
+LEAF_TYPE(LF_QUADWORD, 0x8009)
+LEAF_TYPE(LF_UQUADWORD, 0x800a)
+LEAF_TYPE(LF_REAL48, 0x800b)
+LEAF_TYPE(LF_COMPLEX32, 0x800c)
+LEAF_TYPE(LF_COMPLEX64, 0x800d)
+LEAF_TYPE(LF_COMPLEX80, 0x800e)
+LEAF_TYPE(LF_COMPLEX128, 0x800f)
+LEAF_TYPE(LF_VARSTRING, 0x8010)
+LEAF_TYPE(LF_OCTWORD, 0x8017)
+LEAF_TYPE(LF_UOCTWORD, 0x8018)
+LEAF_TYPE(LF_DECIMAL, 0x8019)
+LEAF_TYPE(LF_DATE, 0x801a)
+LEAF_TYPE(LF_UTF8STRING, 0x801b)
+LEAF_TYPE(LF_REAL16, 0x801c)
+
+// Padding bytes. These are emitted into alignment bytes in the type stream.
+
+LEAF_TYPE(LF_PAD0, 0xf0)
+LEAF_TYPE(LF_PAD1, 0xf1)
+LEAF_TYPE(LF_PAD2, 0xf2)
+LEAF_TYPE(LF_PAD3, 0xf3)
+LEAF_TYPE(LF_PAD4, 0xf4)
+LEAF_TYPE(LF_PAD5, 0xf5)
+LEAF_TYPE(LF_PAD6, 0xf6)
+LEAF_TYPE(LF_PAD7, 0xf7)
+LEAF_TYPE(LF_PAD8, 0xf8)
+LEAF_TYPE(LF_PAD9, 0xf9)
+LEAF_TYPE(LF_PAD10, 0xfa)
+LEAF_TYPE(LF_PAD11, 0xfb)
+LEAF_TYPE(LF_PAD12, 0xfc)
+LEAF_TYPE(LF_PAD13, 0xfd)
+LEAF_TYPE(LF_PAD14, 0xfe)
+LEAF_TYPE(LF_PAD15, 0xff)
+
+#undef LEAF_TYPE
Added: llvm/trunk/tools/llvm-readobj/CVSymbolTypes.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/CVSymbolTypes.def?rev=257658&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-readobj/CVSymbolTypes.def (added)
+++ llvm/trunk/tools/llvm-readobj/CVSymbolTypes.def Wed Jan 13 13:32:35 2016
@@ -0,0 +1,237 @@
+//===-- CVLeafTypes.def - All CodeView leaf types ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// See LEAF_ENUM_e in cvinfo.h. This should match the constants there.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SYMBOL_TYPE
+#define SYMBOL_TYPE(ename, value)
+#endif
+
+// 16 bit symbol types. Not very useful, provided only for reference.
+SYMBOL_TYPE(S_COMPILE , 0x0001)
+SYMBOL_TYPE(S_REGISTER_16t , 0x0002)
+SYMBOL_TYPE(S_CONSTANT_16t , 0x0003)
+SYMBOL_TYPE(S_UDT_16t , 0x0004)
+SYMBOL_TYPE(S_SSEARCH , 0x0005)
+SYMBOL_TYPE(S_END , 0x0006)
+SYMBOL_TYPE(S_SKIP , 0x0007)
+SYMBOL_TYPE(S_CVRESERVE , 0x0008)
+SYMBOL_TYPE(S_OBJNAME_ST , 0x0009)
+SYMBOL_TYPE(S_ENDARG , 0x000a)
+SYMBOL_TYPE(S_COBOLUDT_16t , 0x000b)
+SYMBOL_TYPE(S_MANYREG_16t , 0x000c)
+SYMBOL_TYPE(S_RETURN , 0x000d)
+SYMBOL_TYPE(S_ENTRYTHIS , 0x000e)
+SYMBOL_TYPE(S_BPREL16 , 0x0100)
+SYMBOL_TYPE(S_LDATA16 , 0x0101)
+SYMBOL_TYPE(S_GDATA16 , 0x0102)
+SYMBOL_TYPE(S_PUB16 , 0x0103)
+SYMBOL_TYPE(S_LPROC16 , 0x0104)
+SYMBOL_TYPE(S_GPROC16 , 0x0105)
+SYMBOL_TYPE(S_THUNK16 , 0x0106)
+SYMBOL_TYPE(S_BLOCK16 , 0x0107)
+SYMBOL_TYPE(S_WITH16 , 0x0108)
+SYMBOL_TYPE(S_LABEL16 , 0x0109)
+SYMBOL_TYPE(S_CEXMODEL16 , 0x010a)
+SYMBOL_TYPE(S_VFTABLE16 , 0x010b)
+SYMBOL_TYPE(S_REGREL16 , 0x010c)
+SYMBOL_TYPE(S_BPREL32_16t , 0x0200)
+SYMBOL_TYPE(S_LDATA32_16t , 0x0201)
+SYMBOL_TYPE(S_GDATA32_16t , 0x0202)
+SYMBOL_TYPE(S_PUB32_16t , 0x0203)
+SYMBOL_TYPE(S_LPROC32_16t , 0x0204)
+SYMBOL_TYPE(S_GPROC32_16t , 0x0205)
+SYMBOL_TYPE(S_THUNK32_ST , 0x0206)
+SYMBOL_TYPE(S_BLOCK32_ST , 0x0207)
+SYMBOL_TYPE(S_WITH32_ST , 0x0208)
+SYMBOL_TYPE(S_LABEL32_ST , 0x0209)
+SYMBOL_TYPE(S_CEXMODEL32 , 0x020a)
+SYMBOL_TYPE(S_VFTABLE32_16t , 0x020b)
+SYMBOL_TYPE(S_REGREL32_16t , 0x020c)
+SYMBOL_TYPE(S_LTHREAD32_16t , 0x020d)
+SYMBOL_TYPE(S_GTHREAD32_16t , 0x020e)
+SYMBOL_TYPE(S_SLINK32 , 0x020f)
+SYMBOL_TYPE(S_LPROCMIPS_16t , 0x0300)
+SYMBOL_TYPE(S_GPROCMIPS_16t , 0x0301)
+SYMBOL_TYPE(S_PROCREF_ST , 0x0400)
+SYMBOL_TYPE(S_DATAREF_ST , 0x0401)
+SYMBOL_TYPE(S_ALIGN , 0x0402)
+SYMBOL_TYPE(S_LPROCREF_ST , 0x0403)
+SYMBOL_TYPE(S_OEM , 0x0404)
+
+// All post 16 bit symbol types have the 0x1000 bit set.
+SYMBOL_TYPE(S_TI16_MAX , 0x1000)
+
+// Mostly unused "start" symbol types.
+SYMBOL_TYPE(S_REGISTER_ST , 0x1001)
+SYMBOL_TYPE(S_CONSTANT_ST , 0x1002)
+SYMBOL_TYPE(S_UDT_ST , 0x1003)
+SYMBOL_TYPE(S_COBOLUDT_ST , 0x1004)
+SYMBOL_TYPE(S_MANYREG_ST , 0x1005)
+SYMBOL_TYPE(S_BPREL32_ST , 0x1006)
+SYMBOL_TYPE(S_LDATA32_ST , 0x1007)
+SYMBOL_TYPE(S_GDATA32_ST , 0x1008)
+SYMBOL_TYPE(S_PUB32_ST , 0x1009)
+SYMBOL_TYPE(S_LPROC32_ST , 0x100a)
+SYMBOL_TYPE(S_GPROC32_ST , 0x100b)
+SYMBOL_TYPE(S_VFTABLE32 , 0x100c)
+SYMBOL_TYPE(S_REGREL32_ST , 0x100d)
+SYMBOL_TYPE(S_LTHREAD32_ST , 0x100e)
+SYMBOL_TYPE(S_GTHREAD32_ST , 0x100f)
+SYMBOL_TYPE(S_LPROCMIPS_ST , 0x1010)
+SYMBOL_TYPE(S_GPROCMIPS_ST , 0x1011)
+
+// Information about the frame layout of a procedure.
+SYMBOL_TYPE(S_FRAMEPROC , 0x1012)
+
+SYMBOL_TYPE(S_COMPILE2_ST , 0x1013)
+SYMBOL_TYPE(S_MANYREG2_ST , 0x1014)
+SYMBOL_TYPE(S_LPROCIA64_ST , 0x1015)
+SYMBOL_TYPE(S_GPROCIA64_ST , 0x1016)
+SYMBOL_TYPE(S_LOCALSLOT_ST , 0x1017)
+SYMBOL_TYPE(S_PARAMSLOT_ST , 0x1018)
+SYMBOL_TYPE(S_ANNOTATION , 0x1019)
+SYMBOL_TYPE(S_GMANPROC_ST , 0x101a)
+SYMBOL_TYPE(S_LMANPROC_ST , 0x101b)
+SYMBOL_TYPE(S_RESERVED1 , 0x101c)
+SYMBOL_TYPE(S_RESERVED2 , 0x101d)
+SYMBOL_TYPE(S_RESERVED3 , 0x101e)
+SYMBOL_TYPE(S_RESERVED4 , 0x101f)
+SYMBOL_TYPE(S_LMANDATA_ST , 0x1020)
+SYMBOL_TYPE(S_GMANDATA_ST , 0x1021)
+SYMBOL_TYPE(S_MANFRAMEREL_ST, 0x1022)
+SYMBOL_TYPE(S_MANREGISTER_ST, 0x1023)
+SYMBOL_TYPE(S_MANSLOT_ST , 0x1024)
+SYMBOL_TYPE(S_MANMANYREG_ST , 0x1025)
+SYMBOL_TYPE(S_MANREGREL_ST , 0x1026)
+SYMBOL_TYPE(S_MANMANYREG2_ST, 0x1027)
+SYMBOL_TYPE(S_MANTYPREF , 0x1028)
+SYMBOL_TYPE(S_UNAMESPACE_ST , 0x1029)
+
+// End of S_*_ST symbols, which do not appear to be generated by modern
+// compilers.
+SYMBOL_TYPE(S_ST_MAX , 0x1100)
+
+SYMBOL_TYPE(S_OBJNAME , 0x1101)
+SYMBOL_TYPE(S_THUNK32 , 0x1102)
+SYMBOL_TYPE(S_BLOCK32 , 0x1103)
+SYMBOL_TYPE(S_WITH32 , 0x1104)
+SYMBOL_TYPE(S_LABEL32 , 0x1105)
+SYMBOL_TYPE(S_REGISTER , 0x1106)
+SYMBOL_TYPE(S_CONSTANT , 0x1107)
+SYMBOL_TYPE(S_UDT , 0x1108)
+SYMBOL_TYPE(S_COBOLUDT , 0x1109)
+SYMBOL_TYPE(S_MANYREG , 0x110a)
+SYMBOL_TYPE(S_BPREL32 , 0x110b)
+SYMBOL_TYPE(S_LDATA32 , 0x110c)
+SYMBOL_TYPE(S_GDATA32 , 0x110d)
+SYMBOL_TYPE(S_PUB32 , 0x110e)
+SYMBOL_TYPE(S_LPROC32 , 0x110f)
+SYMBOL_TYPE(S_GPROC32 , 0x1110)
+SYMBOL_TYPE(S_REGREL32 , 0x1111)
+SYMBOL_TYPE(S_LTHREAD32 , 0x1112)
+SYMBOL_TYPE(S_GTHREAD32 , 0x1113)
+SYMBOL_TYPE(S_LPROCMIPS , 0x1114)
+SYMBOL_TYPE(S_GPROCMIPS , 0x1115)
+SYMBOL_TYPE(S_COMPILE2 , 0x1116)
+SYMBOL_TYPE(S_MANYREG2 , 0x1117)
+SYMBOL_TYPE(S_LPROCIA64 , 0x1118)
+SYMBOL_TYPE(S_GPROCIA64 , 0x1119)
+SYMBOL_TYPE(S_LOCALSLOT , 0x111a)
+SYMBOL_TYPE(S_PARAMSLOT , 0x111b)
+
+// Managed code symbols.
+SYMBOL_TYPE(S_LMANDATA , 0x111c)
+SYMBOL_TYPE(S_GMANDATA , 0x111d)
+SYMBOL_TYPE(S_MANFRAMEREL , 0x111e)
+SYMBOL_TYPE(S_MANREGISTER , 0x111f)
+SYMBOL_TYPE(S_MANSLOT , 0x1120)
+SYMBOL_TYPE(S_MANMANYREG , 0x1121)
+SYMBOL_TYPE(S_MANREGREL , 0x1122)
+SYMBOL_TYPE(S_MANMANYREG2 , 0x1123)
+SYMBOL_TYPE(S_UNAMESPACE , 0x1124)
+SYMBOL_TYPE(S_PROCREF , 0x1125)
+SYMBOL_TYPE(S_DATAREF , 0x1126)
+SYMBOL_TYPE(S_LPROCREF , 0x1127)
+SYMBOL_TYPE(S_ANNOTATIONREF , 0x1128)
+SYMBOL_TYPE(S_TOKENREF , 0x1129)
+SYMBOL_TYPE(S_GMANPROC , 0x112a)
+SYMBOL_TYPE(S_LMANPROC , 0x112b)
+SYMBOL_TYPE(S_TRAMPOLINE , 0x112c)
+SYMBOL_TYPE(S_MANCONSTANT , 0x112d)
+SYMBOL_TYPE(S_ATTR_FRAMEREL , 0x112e)
+SYMBOL_TYPE(S_ATTR_REGISTER , 0x112f)
+SYMBOL_TYPE(S_ATTR_REGREL , 0x1130)
+SYMBOL_TYPE(S_ATTR_MANYREG , 0x1131)
+
+
+SYMBOL_TYPE(S_SEPCODE , 0x1132)
+SYMBOL_TYPE(S_LOCAL_2005 , 0x1133)
+SYMBOL_TYPE(S_DEFRANGE_2005 , 0x1134)
+SYMBOL_TYPE(S_DEFRANGE2_2005, 0x1135)
+SYMBOL_TYPE(S_SECTION , 0x1136)
+SYMBOL_TYPE(S_COFFGROUP , 0x1137)
+SYMBOL_TYPE(S_EXPORT , 0x1138)
+SYMBOL_TYPE(S_CALLSITEINFO , 0x1139)
+SYMBOL_TYPE(S_FRAMECOOKIE , 0x113a)
+SYMBOL_TYPE(S_DISCARDED , 0x113b)
+SYMBOL_TYPE(S_COMPILE3 , 0x113c)
+SYMBOL_TYPE(S_ENVBLOCK , 0x113d)
+SYMBOL_TYPE(S_LOCAL , 0x113e)
+SYMBOL_TYPE(S_DEFRANGE , 0x113f)
+SYMBOL_TYPE(S_DEFRANGE_SUBFIELD, 0x1140)
+SYMBOL_TYPE(S_DEFRANGE_REGISTER, 0x1141)
+SYMBOL_TYPE(S_DEFRANGE_FRAMEPOINTER_REL, 0x1142)
+SYMBOL_TYPE(S_DEFRANGE_SUBFIELD_REGISTER, 0x1143)
+SYMBOL_TYPE(S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE, 0x1144)
+SYMBOL_TYPE(S_DEFRANGE_REGISTER_REL, 0x1145)
+
+// Current symbol types for most procedures as of this writing.
+SYMBOL_TYPE(S_LPROC32_ID , 0x1146)
+SYMBOL_TYPE(S_GPROC32_ID , 0x1147)
+SYMBOL_TYPE(S_LPROCMIPS_ID , 0x1148)
+SYMBOL_TYPE(S_GPROCMIPS_ID , 0x1149)
+SYMBOL_TYPE(S_LPROCIA64_ID , 0x114a)
+SYMBOL_TYPE(S_GPROCIA64_ID , 0x114b)
+
+SYMBOL_TYPE(S_BUILDINFO , 0x114c)
+
+// Inlined call site delimiters.
+SYMBOL_TYPE(S_INLINESITE , 0x114d)
+SYMBOL_TYPE(S_INLINESITE_END , 0x114e)
+
+// Procedure info end delimiter.
+SYMBOL_TYPE(S_PROC_ID_END , 0x114f)
+
+SYMBOL_TYPE(S_DEFRANGE_HLSL , 0x1150)
+SYMBOL_TYPE(S_GDATA_HLSL , 0x1151)
+SYMBOL_TYPE(S_LDATA_HLSL , 0x1152)
+SYMBOL_TYPE(S_FILESTATIC , 0x1153)
+SYMBOL_TYPE(S_LOCAL_DPC_GROUPSHARED, 0x1154)
+SYMBOL_TYPE(S_LPROC32_DPC , 0x1155)
+SYMBOL_TYPE(S_LPROC32_DPC_ID , 0x1156)
+SYMBOL_TYPE(S_DEFRANGE_DPC_PTR_TAG, 0x1157)
+SYMBOL_TYPE(S_DPC_SYM_TAG_MAP, 0x1158)
+SYMBOL_TYPE(S_ARMSWITCHTABLE , 0x1159)
+SYMBOL_TYPE(S_CALLEES , 0x115a)
+SYMBOL_TYPE(S_CALLERS , 0x115b)
+SYMBOL_TYPE(S_POGODATA , 0x115c)
+SYMBOL_TYPE(S_INLINESITE2 , 0x115d)
+SYMBOL_TYPE(S_HEAPALLOCSITE , 0x115e)
+SYMBOL_TYPE(S_MOD_TYPEREF , 0x115f)
+SYMBOL_TYPE(S_REF_MINIPDB , 0x1160)
+SYMBOL_TYPE(S_PDBMAP , 0x1161)
+SYMBOL_TYPE(S_GDATA_HLSL32 , 0x1162)
+SYMBOL_TYPE(S_LDATA_HLSL32 , 0x1163)
+SYMBOL_TYPE(S_GDATA_HLSL32_EX, 0x1164)
+SYMBOL_TYPE(S_LDATA_HLSL32_EX, 0x1165)
+
+#undef SYMBOL_TYPE
Added: llvm/trunk/tools/llvm-readobj/CodeView.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/CodeView.h?rev=257658&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-readobj/CodeView.h (added)
+++ llvm/trunk/tools/llvm-readobj/CodeView.h Wed Jan 13 13:32:35 2016
@@ -0,0 +1,571 @@
+//===-- CodeView.h - On-disk record types for CodeView ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file provides data structures useful for consuming on-disk
+/// CodeView. It is based on information published by Microsoft at
+/// https://github.com/Microsoft/microsoft-pdb/.
+///
+//===----------------------------------------------------------------------===//
+
+// FIXME: Find a home for this in include/llvm/DebugInfo/CodeView/.
+
+#ifndef LLVM_READOBJ_CODEVIEW_H
+#define LLVM_READOBJ_CODEVIEW_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace codeview {
+
+/// A Symbols subsection is a sequence of SymRecords. Advancing by 'len'
+/// bytes will find the next SymRecord. These are the possible types of a
+/// record. Equivalent to SYM_ENUM_e in cvinfo.h.
+enum SymType : uint16_t {
+#define SYMBOL_TYPE(ename, value) ename = value,
+#include "CVSymbolTypes.def"
+};
+
+/// Generic record compatible with all symbol records.
+struct SymRecord {
+ ulittle16_t RecordLength; // Record length, starting from the next field
+ ulittle16_t RecordType; // Record type (SymType)
+ // Symbol data follows.
+};
+
+/// Corresponds to the CV_PROCFLAGS bitfield.
+enum ProcFlags : uint8_t {
+ HasFP = 1 << 0,
+ HasIRET = 1 << 1,
+ HasFRET = 1 << 2,
+ IsNoReturn = 1 << 3,
+ IsUnreachable = 1 << 4,
+ HasCustomCallingConv = 1 << 5,
+ IsNoInline = 1 << 6,
+ HasOptimizedDebugInfo = 1 << 7,
+};
+
+// S_GPROC32, S_LPROC32, S_GPROC32_ID, S_LPROC32_ID, S_LPROC32_DPC or
+// S_LPROC32_DPC_ID
+struct ProcSym {
+ ulittle32_t PtrParent;
+ ulittle32_t PtrEnd;
+ ulittle32_t PtrNext;
+ ulittle32_t CodeSize;
+ ulittle32_t DbgStart;
+ ulittle32_t DbgEnd;
+ TypeIndex FunctionType;
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ uint8_t Flags; // CV_PROCFLAGS
+ // Name: The null-terminated name follows.
+};
+
+// S_INLINESITE
+struct InlineSiteSym {
+ ulittle32_t PtrParent;
+ ulittle32_t PtrEnd;
+ TypeIndex Inlinee;
+ // BinaryAnnotations
+};
+
+// S_LOCAL
+struct LocalSym {
+ TypeIndex Type;
+ ulittle16_t Flags;
+ enum : uint16_t {
+ IsParameter = 1 << 0,
+ IsAddressTaken = 1 << 1,
+ IsCompilerGenerated = 1 << 2,
+ IsAggregate = 1 << 3,
+ IsAggregated = 1 << 4,
+ IsAliased = 1 << 5,
+ IsAlias = 1 << 6,
+ IsReturnValue = 1 << 7,
+ IsOptimizedOut = 1 << 8,
+ IsEnregisteredGlobal = 1 << 9,
+ IsEnregisteredStatic = 1 << 10,
+ };
+ // Name: The null-terminated name follows.
+};
+
+// S_BLOCK32
+struct BlockSym {
+ ulittle32_t PtrParent;
+ ulittle32_t PtrEnd;
+ ulittle32_t CodeSize;
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ // Name: The null-terminated name follows.
+};
+
+// S_LABEL32
+struct LabelSym {
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ uint8_t Flags; // CV_PROCFLAGS
+ // Name: The null-terminated name follows.
+};
+
+// S_OBJNAME
+struct ObjNameSym {
+ ulittle32_t Signature;
+ // Name: The null-terminated name follows.
+};
+
+// S_COMPILE3
+struct CompileSym3 {
+ ulittle32_t flags;
+ uint8_t getLanguage() const { return flags & 0xff; }
+ enum Flags : uint32_t {
+ EC = 1 << 8,
+ NoDbgInfo = 1 << 9,
+ LTCG = 1 << 10,
+ NoDataAlign = 1 << 11,
+ ManagedPresent = 1 << 12,
+ SecurityChecks = 1 << 13,
+ HotPatch = 1 << 14,
+ CVTCIL = 1 << 15,
+ MSILModule = 1 << 16,
+ Sdl = 1 << 17,
+ PGO = 1 << 18,
+ Exp = 1 << 19,
+ };
+ ulittle16_t Machine; // CPUType
+ ulittle16_t VersionFrontendMajor;
+ ulittle16_t VersionFrontendMinor;
+ ulittle16_t VersionFrontendBuild;
+ ulittle16_t VersionFrontendQFE;
+ ulittle16_t VersionBackendMajor;
+ ulittle16_t VersionBackendMinor;
+ ulittle16_t VersionBackendBuild;
+ ulittle16_t VersionBackendQFE;
+ // VersionString: The null-terminated version string follows.
+};
+
+// S_FRAMEPROC
+struct FrameProcSym {
+ ulittle32_t TotalFrameBytes;
+ ulittle32_t PaddingFrameBytes;
+ ulittle32_t OffsetToPadding;
+ ulittle32_t BytesOfCalleeSavedRegisters;
+ ulittle32_t OffsetOfExceptionHandler;
+ ulittle16_t SectionIdOfExceptionHandler;
+ ulittle32_t Flags;
+};
+
+// S_CALLSITEINFO
+struct CallSiteInfoSym {
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ ulittle16_t Reserved;
+ TypeIndex Type;
+};
+
+// S_HEAPALLOCSITE
+struct HeapAllocationSiteSym {
+ ulittle32_t CodeOffset;
+ ulittle16_t Segment;
+ ulittle16_t CallInstructionSize;
+ TypeIndex Type;
+};
+
+// S_FRAMECOOKIE
+struct FrameCookieSym {
+ ulittle32_t CodeOffset;
+ ulittle16_t Register;
+ ulittle16_t CookieKind;
+
+ enum : uint16_t {
+ Copy,
+ XorStackPointer,
+ XorFramePointer,
+ XorR13,
+ };
+};
+
+// S_UDT, S_COBOLUDT
+struct UDTSym {
+ TypeIndex Type; // Type of the UDT
+ // Name: The null-terminated name follows.
+};
+
+// S_BUILDINFO
+struct BuildInfoSym {
+ ulittle32_t BuildId;
+};
+
+// S_BPREL32
+struct BPRelativeSym {
+ ulittle32_t Offset; // Offset from the base pointer register
+ TypeIndex Type; // Type of the variable
+ // Name: The null-terminated name follows.
+};
+
+// S_REGREL32
+struct RegRelativeSym {
+ ulittle32_t Offset; // Offset from the register
+ TypeIndex Type; // Type of the variable
+ ulittle16_t Register; // Register to which the variable is relative
+ // Name: The null-terminated name follows.
+};
+
+// S_CONSTANT, S_MANCONSTANT
+struct ConstantSym {
+ TypeIndex Type;
+ // Value: The value of the constant.
+ // Name: The null-terminated name follows.
+};
+
+// S_LDATA32, S_GDATA32, S_LMANDATA, S_GMANDATA
+struct DataSym {
+ TypeIndex Type;
+ ulittle32_t DataOffset;
+ ulittle16_t Segment;
+ // Name: The null-terminated name follows.
+};
+
+// S_LTHREAD32, S_GTHREAD32
+struct ThreadLocalDataSym {
+ TypeIndex Type;
+ ulittle32_t DataOffset;
+ ulittle16_t Segment;
+ // Name: The null-terminated name follows.
+};
+
+/// Data in the the SUBSEC_FRAMEDATA subection.
+struct FrameData {
+ ulittle32_t RvaStart;
+ ulittle32_t CodeSize;
+ ulittle32_t LocalSize;
+ ulittle32_t ParamsSize;
+ ulittle32_t MaxStackSize;
+ ulittle32_t FrameFunc;
+ ulittle16_t PrologSize;
+ ulittle16_t SavedRegsSize;
+ ulittle32_t Flags;
+ enum : uint32_t {
+ HasSEH = 1 << 0,
+ HasEH = 1 << 1,
+ IsFunctionStart = 1 << 2,
+ };
+};
+
+//===----------------------------------------------------------------------===//
+// On-disk representation of type information
+
+/// Indicates the kind of TypeRecord we're dealing with here. The documentation
+/// and headers talk about this as the "leaf" type.
+enum LeafType : uint16_t {
+#define LEAF_TYPE(name, val) name = val,
+#include "CVLeafTypes.def"
+};
+
+// A CodeView type stream is a sequence of TypeRecords. Records larger than
+// 65536 must chain on to a second record. Each TypeRecord is followed by one of
+// the leaf types described below.
+struct TypeRecord {
+ ulittle16_t Len; // Type record length, starting from &Leaf.
+ ulittle16_t Leaf; // Type record kind (LeafType)
+};
+
+// LF_TYPESERVER2
+struct TypeServer2 {
+ char Signature[16]; // GUID
+ ulittle32_t Age;
+ // Name: Name of the PDB as a null-terminated string
+};
+
+// LF_STRING_ID
+struct StringId {
+ TypeIndex id;
+};
+
+// LF_FUNC_ID
+struct FuncId {
+ TypeIndex ParentScope;
+ TypeIndex FunctionType;
+ // Name: The null-terminated name follows.
+};
+
+// LF_CLASS, LF_STRUCT, LF_INTERFACE
+struct ClassType {
+ ulittle16_t MemberCount; // Number of members in FieldList.
+ ulittle16_t Properties; // ClassOptions bitset
+ TypeIndex FieldList; // LF_FIELDLIST: List of all kinds of members
+ TypeIndex DerivedFrom; // LF_DERIVED: List of known derived classes
+ TypeIndex VShape; // LF_VTSHAPE: Shape of the vftable
+ // SizeOf: The 'sizeof' the UDT in bytes is encoded as an LF_NUMERIC integer.
+ // Name: The null-terminated name follows.
+};
+
+// LF_UNION
+struct UnionType {
+ ulittle16_t MemberCount; // Number of members in FieldList.
+ ulittle16_t Properties; // ClassOptions bitset
+ TypeIndex FieldList; // LF_FIELDLIST: List of all kinds of members
+ // SizeOf: The 'sizeof' the UDT in bytes is encoded as an LF_NUMERIC integer.
+ // Name: The null-terminated name follows.
+};
+
+// LF_POINTER
+struct PointerType {
+ TypeIndex PointeeType;
+ ulittle32_t Attrs; // pointer attributes
+ // if pointer to member:
+ // PointerToMemberTail
+
+ PointerKind getPtrKind() const { return PointerKind(Attrs & 0x1f); }
+ PointerMode getPtrMode() const { return PointerMode((Attrs >> 5) & 0x07); }
+ bool isFlat() const { return Attrs & (1 << 8); }
+ bool isVolatile() const { return Attrs & (1 << 9); }
+ bool isConst() const { return Attrs & (1 << 10); }
+ bool isUnaligned() const { return Attrs & (1 << 11); }
+
+ bool isPointerToDataMember() const {
+ return getPtrMode() == PointerMode::PointerToDataMember;
+ }
+ bool isPointerToMemberFunction() const {
+ return getPtrMode() == PointerMode::PointerToMemberFunction;
+ }
+ bool isPointerToMember() const {
+ return isPointerToMemberFunction() || isPointerToDataMember();
+ }
+};
+
+struct PointerToMemberTail {
+ TypeIndex ClassType;
+ ulittle16_t Representation; // PointerToMemberRepresentation
+};
+
+/// In Clang parlance, these are "qualifiers". LF_MODIFIER
+struct TypeModifier {
+ TypeIndex ModifiedType;
+ ulittle16_t Modifiers; // ModifierOptions
+};
+
+// LF_VTSHAPE
+struct VTableShape {
+ // Number of vftable entries. Each method may have more than one entry due to
+ // things like covariant return types.
+ ulittle16_t VFEntryCount;
+ // Descriptors[]: 4-bit virtual method descriptors of type CV_VTS_desc_e.
+};
+
+// LF_UDT_SRC_LINE
+struct UDTSrcLine {
+ TypeIndex UDT; // The user-defined type
+ TypeIndex SourceFile; // StringID containing the source filename
+ ulittle32_t LineNumber;
+};
+
+// LF_ARGLIST, LF_SUBSTR_LIST
+struct ArgList {
+ ulittle32_t NumArgs; // Number of arguments
+ // ArgTypes[]: Type indicies of arguments
+};
+
+// LF_BUILDINFO
+struct BuildInfo {
+ ulittle16_t NumArgs; // Number of arguments
+ // ArgTypes[]: Type indicies of arguments
+};
+
+// LF_ENUM
+struct EnumType {
+ ulittle16_t NumEnumerators; // Number of enumerators
+ ulittle16_t Properties;
+ TypeIndex UnderlyingType;
+ TypeIndex FieldListType;
+ // Name: The null-terminated name follows.
+};
+
+// LF_ARRAY
+struct ArrayType {
+ TypeIndex ElementType;
+ TypeIndex IndexType;
+ // SizeOf: LF_NUMERIC encoded size in bytes. Not element count!
+ // Name: The null-terminated name follows.
+};
+
+// LF_VFTABLE
+struct VFTableType {
+ TypeIndex CompleteClass; // Class that owns this vftable.
+ TypeIndex OverriddenVFTable; // VFTable that this overrides.
+ ulittle32_t VFPtrOffset; // VFPtr offset in CompleteClass
+ ulittle32_t NamesLen; // Length of subsequent names array in bytes.
+ // Names: A sequence of null-terminated strings. First string is vftable
+ // names.
+};
+
+// LF_MFUNC_ID
+struct MemberFuncId {
+ TypeIndex ClassType;
+ TypeIndex FunctionType;
+ // Name: The null-terminated name follows.
+};
+
+// LF_PROCEDURE
+struct ProcedureType {
+ TypeIndex ReturnType;
+ CallingConvention CallConv;
+ FunctionOptions Options;
+ ulittle16_t NumParameters;
+ TypeIndex ArgListType;
+};
+
+// LF_MFUNCTION
+struct MemberFunctionType {
+ TypeIndex ReturnType;
+ TypeIndex ClassType;
+ TypeIndex ThisType;
+ CallingConvention CallConv;
+ FunctionOptions Options;
+ ulittle16_t NumParameters;
+ TypeIndex ArgListType;
+ little32_t ThisAdjustment;
+};
+
+//===----------------------------------------------------------------------===//
+// Field list records, which do not include leafs or sizes
+
+/// Equvalent to CV_fldattr_t in cvinfo.h.
+struct MemberAttributes {
+ ulittle16_t Attrs;
+
+ /// Get the access specifier. Valid for any kind of member.
+ MemberAccess getAccess() const {
+ return MemberAccess(unsigned(Attrs) & unsigned(MethodOptions::AccessMask));
+ }
+
+ /// Indicates if a method is defined with friend, virtual, static, etc.
+ MethodKind getMethodKind() const {
+ return MethodKind(
+ (unsigned(Attrs) & unsigned(MethodOptions::MethodKindMask)) >> 2);
+ }
+
+ /// Get the flags that are not included in access control or method
+ /// properties.
+ MethodOptions getFlags() const {
+ return MethodOptions(
+ unsigned(Attrs) &
+ ~unsigned(MethodOptions::AccessMask | MethodOptions::MethodKindMask));
+ }
+
+ /// Is this method virtual.
+ bool isVirtual() const {
+ auto MP = getMethodKind();
+ return MP != MethodKind::Vanilla && MP != MethodKind::Friend &&
+ MP != MethodKind::Static;
+ }
+
+ /// Does this member introduce a new virtual method.
+ bool isIntroducedVirtual() const {
+ auto MP = getMethodKind();
+ return MP == MethodKind::IntroducingVirtual ||
+ MP == MethodKind::PureIntroducingVirtual;
+ }
+};
+
+// LF_NESTTYPE
+struct NestedType {
+ ulittle16_t Pad0; // Should be zero
+ TypeIndex Type; // Type index of nested type
+ // Name: Null-terminated string
+};
+
+// LF_ONEMETHOD
+struct OneMethod {
+ MemberAttributes Attrs;
+ TypeIndex Type;
+ // If is introduced virtual method:
+ // VFTableOffset: int32_t offset in vftable
+ // Name: Null-terminated string
+
+ MethodKind getMethodKind() const {
+ return Attrs.getMethodKind();
+ }
+
+ bool isVirtual() const { return Attrs.isVirtual(); }
+ bool isIntroducedVirtual() const { return Attrs.isIntroducedVirtual(); }
+};
+
+struct MethodListEntry {
+ MemberAttributes Attrs;
+ ulittle16_t Padding;
+
+ TypeIndex Type;
+ // If is introduced virtual method:
+ // VFTableOffset: int32_t offset in vftable
+
+ MethodKind getMethodKind() const {
+ return Attrs.getMethodKind();
+ }
+
+ bool isVirtual() const { return Attrs.isVirtual(); }
+ bool isIntroducedVirtual() const { return Attrs.isIntroducedVirtual(); }
+};
+
+/// For method overload sets. LF_METHOD
+struct OverloadedMethod {
+ ulittle16_t MethodCount; // Size of overload set
+ TypeIndex MethList; // Type index of methods in overload set
+ // Name: Null-terminated string
+};
+
+// LF_VFUNCTAB
+struct VirtualFunctionPointer {
+ ulittle16_t Pad0;
+ TypeIndex Type; // Type of vfptr
+};
+
+// LF_MEMBER
+struct DataMember {
+ MemberAttributes Attrs; // Access control attributes, etc
+ TypeIndex Type;
+ // FieldOffset: LF_NUMERIC encoded byte offset
+ // Name: Null-terminated string
+};
+
+// LF_STMEMBER
+struct StaticDataMember {
+ MemberAttributes Attrs; // Access control attributes, etc
+ TypeIndex Type;
+ // Name: Null-terminated string
+};
+
+// LF_ENUMERATE
+struct Enumerator {
+ MemberAttributes Attrs; // Access control attributes, etc
+ // EnumValue: LF_NUMERIC encoded enumerator value
+ // Name: Null-terminated string
+};
+
+// LF_BCLASS, LF_BINTERFACE
+struct BaseClass {
+ MemberAttributes Attrs; // Access control attributes, etc
+ TypeIndex BaseType; // Base class type
+ // BaseOffset: LF_NUMERIC encoded byte offset of base from derived.
+};
+
+// LF_VBCLASS | LV_IVBCLASS
+struct VirtualBaseClass {
+ MemberAttributes Attrs; // Access control attributes, etc.
+ TypeIndex BaseType; // Base class type
+ TypeIndex VBPtrType; // Virtual base pointer type
+ // VBPtrOffset: Offset of vbptr from vfptr encoded as LF_NUMERIC.
+ // VBTableIndex: Index of vbase within vbtable encoded as LF_NUMERIC.
+};
+
+} // namespace codeview
+} // namespace llvm
+
+#endif // LLVM_READOBJ_CODEVIEW_H
Modified: llvm/trunk/tools/llvm-readobj/StreamWriter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/StreamWriter.h?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/StreamWriter.h (original)
+++ llvm/trunk/tools/llvm-readobj/StreamWriter.h Wed Jan 13 13:32:35 2016
@@ -10,6 +10,7 @@
#ifndef LLVM_TOOLS_LLVM_READOBJ_STREAMWRITER_H
#define LLVM_TOOLS_LLVM_READOBJ_STREAMWRITER_H
+#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -180,6 +181,10 @@ public:
startLine() << Label << ": " << int(Value) << "\n";
}
+ void printNumber(StringRef Label, APSInt Value) {
+ startLine() << Label << ": " << Value << "\n";
+ }
+
void printBoolean(StringRef Label, bool Value) {
startLine() << Label << ": " << (Value ? "Yes" : "No") << '\n';
}
@@ -287,6 +292,12 @@ private:
int IndentLevel;
};
+template <>
+inline void StreamWriter::printHex<ulittle16_t>(StringRef Label,
+ ulittle16_t Value) {
+ startLine() << Label << ": " << hex(Value) << "\n";
+}
+
struct DictScope {
DictScope(StreamWriter& W, StringRef N) : W(W) {
W.startLine() << N << " {\n";
Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.h?rev=257658&r1=257657&r2=257658&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.h (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.h Wed Jan 13 13:32:35 2016
@@ -47,4 +47,7 @@ namespace opts {
#define LLVM_READOBJ_ENUM_ENT(ns, enum) \
{ #enum, ns::enum }
+#define LLVM_READOBJ_ENUM_CLASS_ENT(enum_class, enum) \
+ { #enum, std::underlying_type<enum_class>::type(enum_class::enum) }
+
#endif
More information about the llvm-commits
mailing list