]> granicus.if.org Git - llvm/commitdiff
[codeview] Add support for label type records
authorReid Kleckner <rnk@google.com>
Mon, 3 Apr 2017 21:25:20 +0000 (21:25 +0000)
committerReid Kleckner <rnk@google.com>
Mon, 3 Apr 2017 21:25:20 +0000 (21:25 +0000)
MASM can produce these type records.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@299388 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/CodeView/CodeView.h
include/llvm/DebugInfo/CodeView/TypeRecord.h
include/llvm/DebugInfo/CodeView/TypeRecords.def
lib/DebugInfo/CodeView/TypeDatabaseVisitor.cpp
lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
lib/DebugInfo/CodeView/TypeRecordMapping.cpp
lib/DebugInfo/CodeView/TypeStreamMerger.cpp
test/tools/llvm-readobj/Inputs/codeview-label.obj [new file with mode: 0644]
test/tools/llvm-readobj/codeview-label.test [new file with mode: 0644]
tools/llvm-pdbdump/YamlTypeDumper.cpp

index e21cfa3d030ae5111d7757c6bf0515cef26b5539..2791c9dc374651b8c1289cecdb1cc323f36b1dcd 100644 (file)
@@ -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 {
index aa70cffa0e02f52b814b7c3d68927aa9dbc2de82..1f10872c8768040b20a87265cdbde2a8ed317059 100644 (file)
@@ -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:
index 1ca061d0ac147760b6726a2ec0a8f06008724857..8c193bb13cb7e87dcf2ee00af434e8f65640e4c1 100644 (file)
@@ -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)
index 4c56ab03644b6b7b925be63121ec1fa042d641e7..c234afd2288bdfa862033d6bf7585874f940f0ef 100644 (file)
@@ -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();
index 0656d645d90fd41839fa38f57a7af7ca455c8427..870d95221e7d0f0549d7dc6f144cc531c3f64f50 100644 (file)
@@ -146,6 +146,10 @@ static const EnumEntry<uint8_t> FunctionOptionEnum[] = {
     ENUM_ENTRY(FunctionOptions, ConstructorWithVirtualBases),
 };
 
+static const EnumEntry<uint16_t> 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();
+}
index a81caed8a37ca5dc2526e2579623e3882f2baa75..114f6fd2897e711d7f36c9b0be0aeaefb16138ff 100644 (file)
@@ -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));
index 9d7af8db9e662eae63d7e7d7824095951842265a..abd6e5e111040c67528d3ae9c731fe2c2c417d30 100644 (file)
@@ -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/test/tools/llvm-readobj/Inputs/codeview-label.obj b/test/tools/llvm-readobj/Inputs/codeview-label.obj
new file mode 100644 (file)
index 0000000..ae49a06
Binary files /dev/null and b/test/tools/llvm-readobj/Inputs/codeview-label.obj differ
diff --git a/test/tools/llvm-readobj/codeview-label.test b/test/tools/llvm-readobj/codeview-label.test
new file mode 100644 (file)
index 0000000..3bf6deb
--- /dev/null
@@ -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
index c7ad02b746eee91cb3777b8eeff5f3aeac082f6c..b4eb197e866a4631aa8eaaffb15faf625814ead8 100644 (file)
@@ -194,6 +194,13 @@ template <> struct ScalarEnumerationTraits<WindowsRTClassKind> {
   }
 };
 
+template <> struct ScalarEnumerationTraits<LabelType> {
+  static void enumeration(IO &IO, LabelType &Value) {
+    IO.enumCase(Value, "Near", LabelType::Near);
+    IO.enumCase(Value, "Far", LabelType::Far);
+  }
+};
+
 template <> struct ScalarBitSetTraits<PointerOptions> {
   static void bitset(IO &IO, PointerOptions &Options) {
     IO.bitSetCase(Options, "None", PointerOptions::None);
@@ -431,6 +438,10 @@ void MappingTraits<BuildInfoRecord>::mapping(IO &IO, BuildInfoRecord &Args) {
   IO.mapRequired("ArgIndices", Args.ArgIndices);
 }
 
+void MappingTraits<LabelRecord>::mapping(IO &IO, LabelRecord &R) {
+  IO.mapRequired("Mode", R.Mode);
+}
+
 void MappingTraits<NestedTypeRecord>::mapping(IO &IO,
                                               NestedTypeRecord &Nested) {
   IO.mapRequired("Type", Nested.Type);