Skip to content

Commit

Permalink
[readobj] Expand CodeView dumping functionality
Browse files Browse the repository at this point in the history
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

llvm-svn: 257658
  • Loading branch information
rnk committed Jan 13, 2016
1 parent a39ca60 commit 72e2ba7
Show file tree
Hide file tree
Showing 20 changed files with 2,969 additions and 492 deletions.
113 changes: 112 additions & 1 deletion llvm/include/llvm/DebugInfo/CodeView/CodeView.h
Expand Up @@ -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
Expand Down Expand Up @@ -140,13 +231,15 @@ enum class HfaKind : uint8_t {
Other = 0x03
};

/// Source-level access specifier. (CV_access_e)
enum class MemberAccess : uint8_t {
None = 0,
Private = 1,
Protected = 2,
Public = 3
};

/// Part of member attribute flags. (CV_methodprop_e)
enum class MethodKind : uint8_t {
Vanilla = 0x00,
Virtual = 0x01,
Expand All @@ -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
};
Expand All @@ -178,6 +276,7 @@ inline MethodOptions operator~(MethodOptions a) {
return static_cast<MethodOptions>(~static_cast<uint16_t>(a));
}

/// Equivalent to CV_modifier_t.
enum class ModifierOptions : uint16_t {
None = 0x0000,
Const = 0x0001,
Expand Down Expand Up @@ -207,9 +306,18 @@ enum class ModuleSubstreamKind : uint32_t {
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
Expand All @@ -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
Expand All @@ -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,
Expand All @@ -258,6 +368,7 @@ inline PointerOptions operator~(PointerOptions a) {
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
Expand Down
7 changes: 6 additions & 1 deletion llvm/include/llvm/DebugInfo/CodeView/TypeIndex.h
Expand Up @@ -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;
Expand All @@ -91,6 +94,8 @@ class TypeIndex {
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);
Expand Down Expand Up @@ -144,7 +149,7 @@ class TypeIndex {
static TypeIndex Float64() { return TypeIndex(SimpleTypeKind::Float64); }

private:
uint32_t Index;
ulittle32_t Index;
};

inline bool operator==(const TypeIndex &A, const TypeIndex &B) {
Expand Down
112 changes: 4 additions & 108 deletions llvm/include/llvm/DebugInfo/PDB/PDBTypes.h
Expand Up @@ -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>
Expand Down Expand Up @@ -108,67 +109,7 @@ enum class PDB_Checksum { None = 0, MD5 = 1, SHA1 = 2 };

/// 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,
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/Support/COFF.h
Expand Up @@ -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
};
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/Support/Endian.h
Expand Up @@ -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);
Expand Down
5 changes: 2 additions & 3 deletions llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
Expand Up @@ -199,7 +199,6 @@ void WinCodeViewLineTables::emitDebugInfoForFunction(const Function *GV) {
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();
Expand All @@ -208,8 +207,8 @@ void WinCodeViewLineTables::emitDebugInfoForFunction(const Function *GV) {
// "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();
Expand Down

0 comments on commit 72e2ba7

Please sign in to comment.