From 1c3b5087b781c239fbef4317fa620e1ac11275bd Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Mon, 3 Apr 2017 21:25:20 +0000 Subject: [PATCH] [codeview] Add support for label type records MASM can produce these type records. llvm-svn: 299388 --- llvm/include/llvm/DebugInfo/CodeView/CodeView.h | 6 ++++++ .../llvm/DebugInfo/CodeView/TypeRecord.h | 10 ++++++++++ .../llvm/DebugInfo/CodeView/TypeRecords.def | 2 +- .../DebugInfo/CodeView/TypeDatabaseVisitor.cpp | 4 ++++ llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp | 9 +++++++++ .../DebugInfo/CodeView/TypeRecordMapping.cpp | 5 +++++ .../lib/DebugInfo/CodeView/TypeStreamMerger.cpp | 4 ++++ .../llvm-readobj/Inputs/codeview-label.obj | Bin 0 -> 830 bytes .../test/tools/llvm-readobj/codeview-label.test | 16 ++++++++++++++++ llvm/tools/llvm-pdbdump/YamlTypeDumper.cpp | 11 +++++++++++ 10 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 llvm/test/tools/llvm-readobj/Inputs/codeview-label.obj create mode 100644 llvm/test/tools/llvm-readobj/codeview-label.test diff --git a/llvm/include/llvm/DebugInfo/CodeView/CodeView.h b/llvm/include/llvm/DebugInfo/CodeView/CodeView.h index e21cfa3d030a..2791c9dc3746 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/CodeView.h +++ b/llvm/include/llvm/DebugInfo/CodeView/CodeView.h @@ -275,6 +275,12 @@ enum class MethodOptions : uint16_t { }; CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(MethodOptions) +/// Equivalent to CV_LABEL_TYPE_e. +enum class LabelType : uint16_t { + Near = 0x0, + Far = 0x4, +}; + /// Equivalent to CV_modifier_t. /// TODO: Add flag for _Atomic modifier enum class ModifierOptions : uint16_t { diff --git a/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h b/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h index aa70cffa0e02..1f10872c8768 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h +++ b/llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h @@ -199,6 +199,16 @@ public: int32_t ThisPointerAdjustment; }; +// LF_LABEL +class LabelRecord : public TypeRecord { +public: + explicit LabelRecord(TypeRecordKind Kind) : TypeRecord(Kind) {} + + LabelRecord(LabelType Mode) : TypeRecord(TypeRecordKind::Label), Mode(Mode) {} + + LabelType Mode; +}; + // LF_MFUNC_ID class MemberFuncIdRecord : public TypeRecord { public: diff --git a/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def b/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def index 1ca061d0ac14..8c193bb13cb7 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def +++ b/llvm/include/llvm/DebugInfo/CodeView/TypeRecords.def @@ -41,6 +41,7 @@ TYPE_RECORD(LF_POINTER, 0x1002, Pointer) TYPE_RECORD(LF_MODIFIER, 0x1001, Modifier) TYPE_RECORD(LF_PROCEDURE, 0x1008, Procedure) TYPE_RECORD(LF_MFUNCTION, 0x1009, MemberFunction) +TYPE_RECORD(LF_LABEL, 0x000e, Label) TYPE_RECORD(LF_ARGLIST, 0x1201, ArgList) TYPE_RECORD(LF_FIELDLIST, 0x1203, FieldList) @@ -101,7 +102,6 @@ CV_TYPE(LF_MFUNCTION_16t, 0x0009) CV_TYPE(LF_COBOL0_16t, 0x000b) CV_TYPE(LF_COBOL1, 0x000c) CV_TYPE(LF_BARRAY_16t, 0x000d) -CV_TYPE(LF_LABEL, 0x000e) CV_TYPE(LF_NULLLEAF, 0x000f) // LF_NULL CV_TYPE(LF_NOTTRAN, 0x0010) CV_TYPE(LF_DIMARRAY_16t, 0x0011) diff --git a/llvm/lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp b/llvm/lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp index 4c56ab03644b..c234afd2288b 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp @@ -299,6 +299,10 @@ Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, BuildInfoRecord &BI) { return Error::success(); } +Error TypeDatabaseVisitor::visitKnownRecord(CVType &CVR, LabelRecord &R) { + return Error::success(); +} + Error TypeDatabaseVisitor::visitKnownMember(CVMemberRecord &CVR, VFPtrRecord &VFP) { return Error::success(); diff --git a/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp b/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp index 0656d645d90f..870d95221e7d 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp @@ -146,6 +146,10 @@ static const EnumEntry FunctionOptionEnum[] = { ENUM_ENTRY(FunctionOptions, ConstructorWithVirtualBases), }; +static const EnumEntry LabelTypeEnum[] = { + ENUM_ENTRY(LabelType, Near), ENUM_ENTRY(LabelType, Far), +}; + #undef ENUM_ENTRY static StringRef getLeafTypeName(TypeLeafKind LT) { @@ -547,3 +551,8 @@ Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR, printTypeIndex("ContinuationIndex", Cont.getContinuationIndex()); return Error::success(); } + +Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, LabelRecord &LR) { + W->printEnum("Mode", uint16_t(LR.Mode), makeArrayRef(LabelTypeEnum)); + return Error::success(); +} diff --git a/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp b/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp index a81caed8a37c..114f6fd2897e 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeRecordMapping.cpp @@ -380,6 +380,11 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, return Error::success(); } +Error TypeRecordMapping::visitKnownRecord(CVType &CVR, LabelRecord &Record) { + error(IO.mapEnum(Record.Mode)); + return Error::success(); +} + Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, BaseClassRecord &Record) { error(IO.mapInteger(Record.Attrs.Attrs)); diff --git a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp index 9d7af8db9e66..abd6e5e11104 100644 --- a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -301,6 +301,10 @@ Error TypeStreamMerger::visitKnownRecord(CVType &, TypeServer2Record &R) { return writeRecord(R, true); } +Error TypeStreamMerger::visitKnownRecord(CVType &, LabelRecord &R) { + return writeRecord(R, true); +} + Error TypeStreamMerger::visitKnownRecord(CVType &, VFTableRecord &R) { bool Success = true; Success &= remapIndex(R.CompleteClass); diff --git a/llvm/test/tools/llvm-readobj/Inputs/codeview-label.obj b/llvm/test/tools/llvm-readobj/Inputs/codeview-label.obj new file mode 100644 index 0000000000000000000000000000000000000000..ae49a061bb7ccf2c34ddc4e61220ccf54ea295d1 GIT binary patch literal 830 zcma)4O-md>5PjpQkX6GjcnIV&he6E2W|N4DB(S;%3AnhdL2_s`^U<5k(&H>UqwY!k z3;HAS3lehEK>mqWPipR3)jNah7o?!7t6sgH?yh<3)+plB^Dq7gFo}VQO!YH2-pxx` zl>97;e09+LDnc*w9^enl8k&DZsQkTe?q<>J(+7W1A?QrDQSutft2ytp0V(i(wsKB^ zG4C&LxF#2j)|X}43#8Wj@m#l;bX1T@e=pLZ43bdoN9tfsd%n`bOJkz{BY#ECk1AV7 z`bYZv?8TZp^SX09(>w;Q2zST}V;&o?(IYmx*e%O#J~etT-ODZE?JB!)jwu*pDd~ pRvOROwpeQ{mpdC)8Fy@}(ES}}XYgDD@G&EB-KsH$7_rS)Zvn17kCp%c literal 0 HcmV?d00001 diff --git a/llvm/test/tools/llvm-readobj/codeview-label.test b/llvm/test/tools/llvm-readobj/codeview-label.test new file mode 100644 index 000000000000..3bf6debe0d7f --- /dev/null +++ b/llvm/test/tools/llvm-readobj/codeview-label.test @@ -0,0 +1,16 @@ +; RUN: llvm-readobj -codeview %S/Inputs/codeview-label.obj | FileCheck %s + +; CHECK-LABEL: Label (0x1000) { +; CHECK-NEXT: TypeLeafKind: LF_LABEL (0xE) +; CHECK-NEXT: Mode: Near (0x0) +; CHECK-NEXT: } + +; To reproduce codeview-label.obj: +; $ cat codeview-label.asm +; .model flat, C +; .code +; public foo +; foo: +; ret +; end +; $ ml -c -Zi codeview-label.asm diff --git a/llvm/tools/llvm-pdbdump/YamlTypeDumper.cpp b/llvm/tools/llvm-pdbdump/YamlTypeDumper.cpp index c7ad02b746ee..b4eb197e866a 100644 --- a/llvm/tools/llvm-pdbdump/YamlTypeDumper.cpp +++ b/llvm/tools/llvm-pdbdump/YamlTypeDumper.cpp @@ -194,6 +194,13 @@ template <> struct ScalarEnumerationTraits { } }; +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &IO, LabelType &Value) { + IO.enumCase(Value, "Near", LabelType::Near); + IO.enumCase(Value, "Far", LabelType::Far); + } +}; + template <> struct ScalarBitSetTraits { static void bitset(IO &IO, PointerOptions &Options) { IO.bitSetCase(Options, "None", PointerOptions::None); @@ -431,6 +438,10 @@ void MappingTraits::mapping(IO &IO, BuildInfoRecord &Args) { IO.mapRequired("ArgIndices", Args.ArgIndices); } +void MappingTraits::mapping(IO &IO, LabelRecord &R) { + IO.mapRequired("Mode", R.Mode); +} + void MappingTraits::mapping(IO &IO, NestedTypeRecord &Nested) { IO.mapRequired("Type", Nested.Type);