[CodeView] Add support for emitting column information
authorDavid Majnemer <david.majnemer@gmail.com>
Thu, 9 Jul 2015 00:19:51 +0000 (00:19 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Thu, 9 Jul 2015 00:19:51 +0000 (00:19 +0000)
Column information is present in CodeView when the line table subsection
has bit 0 set to 1 in it's flags field.  The column information is
represented as a pair of 16-bit quantities: a starting and ending
column.  This information is present at the end of the chunk, after all
the line-PC pairs.

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

include/llvm/Support/COFF.h
lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h
test/DebugInfo/COFF/asm.ll
test/DebugInfo/COFF/multifile.ll
test/DebugInfo/COFF/multifunction.ll
test/DebugInfo/COFF/simple.ll
test/tools/llvm-readobj/codeview-linetables.test
tools/llvm-readobj/COFFDumper.cpp

index b26af61a7c7030b02b5e7d239ede7b5f42e3387e..3c5ee06969d0c6e62e419c910c7b0e4fa8ffc988 100644 (file)
@@ -655,6 +655,7 @@ namespace COFF {
   };
 
   enum CodeViewIdentifiers {
+    DEBUG_LINE_TABLES_HAVE_COLUMN_RECORDS = 0x1,
     DEBUG_SECTION_MAGIC = 0x4,
     DEBUG_SYMBOL_SUBSECTION = 0xF1,
     DEBUG_LINE_TABLE_SUBSECTION = 0xF2,
index 535b1f605853b8d85fc4816777e79fe17d58f67b..6610ac78f8c4f1ebce9dadbc617bab6806bc6bad 100644 (file)
@@ -97,7 +97,7 @@ void WinCodeViewLineTables::maybeRecordLocation(DebugLoc DL,
   MCSymbol *MCL = Asm->MMI->getContext().createTempSymbol();
   Asm->OutStreamer->EmitLabel(MCL);
   CurFn->Instrs.push_back(MCL);
-  InstrInfo[MCL] = InstrInfoTy(Filename, DL.getLine());
+  InstrInfo[MCL] = InstrInfoTy(Filename, DL.getLine(), DL.getCol());
 }
 
 WinCodeViewLineTables::WinCodeViewLineTables(AsmPrinter *AP)
@@ -264,22 +264,38 @@ void WinCodeViewLineTables::emitDebugInfoForFunction(const Function *GV) {
   // Identify the function this subsection is for.
   Asm->OutStreamer->EmitCOFFSecRel32(Fn);
   Asm->OutStreamer->EmitCOFFSectionIndex(Fn);
-  // Insert padding after a 16-bit section index.
-  Asm->EmitInt16(0);
+  // Insert flags after a 16-bit section index.
+  Asm->EmitInt16(COFF::DEBUG_LINE_TABLES_HAVE_COLUMN_RECORDS);
 
   // Length of the function's code, in bytes.
   EmitLabelDiff(*Asm->OutStreamer, Fn, FI.End);
 
   // PC-to-linenumber lookup table:
   MCSymbol *FileSegmentEnd = nullptr;
+
+  // The start of the last segment:
+  size_t LastSegmentStart = 0;
+
+  auto FinishPreviousChunk = [&] {
+    if (!FileSegmentEnd)
+      return;
+    for (size_t ColSegI = LastSegmentStart,
+                ColSegEnd = ColSegI + FilenameSegmentLengths[LastSegmentStart];
+         ColSegI != ColSegEnd; ++ColSegI) {
+      unsigned ColumnNumber = InstrInfo[FI.Instrs[ColSegI]].ColumnNumber;
+      Asm->EmitInt16(ColumnNumber); // Start column
+      Asm->EmitInt16(ColumnNumber); // End column
+    }
+    Asm->OutStreamer->EmitLabel(FileSegmentEnd);
+  };
+
   for (size_t J = 0, F = FI.Instrs.size(); J != F; ++J) {
     MCSymbol *Instr = FI.Instrs[J];
     assert(InstrInfo.count(Instr));
 
     if (FilenameSegmentLengths.count(J)) {
       // We came to a beginning of a new filename segment.
-      if (FileSegmentEnd)
-        Asm->OutStreamer->EmitLabel(FileSegmentEnd);
+      FinishPreviousChunk();
       StringRef CurFilename = InstrInfo[FI.Instrs[J]].Filename;
       assert(FileNameRegistry.Infos.count(CurFilename));
       size_t IndexInStringTable =
@@ -300,6 +316,7 @@ void WinCodeViewLineTables::emitDebugInfoForFunction(const Function *GV) {
       // records.
       FileSegmentEnd = Asm->MMI->getContext().createTempSymbol();
       EmitLabelDiff(*Asm->OutStreamer, FileSegmentBegin, FileSegmentEnd);
+      LastSegmentStart = J;
     }
 
     // The first PC with the given linenumber and the linenumber itself.
@@ -307,8 +324,7 @@ void WinCodeViewLineTables::emitDebugInfoForFunction(const Function *GV) {
     Asm->EmitInt32(InstrInfo[Instr].LineNumber);
   }
 
-  if (FileSegmentEnd)
-    Asm->OutStreamer->EmitLabel(FileSegmentEnd);
+  FinishPreviousChunk();
   Asm->OutStreamer->EmitLabel(LineTableEnd);
 }
 
index a5b399f73707bc099ba0650722cbe894243aa58a..43d1a432712eb8c914b43c159f60bfa42a018d74 100644 (file)
@@ -52,11 +52,13 @@ class LLVM_LIBRARY_VISIBILITY WinCodeViewLineTables : public AsmPrinterHandler {
   struct InstrInfoTy {
     StringRef Filename;
     unsigned LineNumber;
+    unsigned ColumnNumber;
 
-    InstrInfoTy() : LineNumber(0) {}
+    InstrInfoTy() : LineNumber(0), ColumnNumber(0) {}
 
-    InstrInfoTy(StringRef Filename, unsigned LineNumber)
-        : Filename(Filename), LineNumber(LineNumber) {}
+    InstrInfoTy(StringRef Filename, unsigned LineNumber, unsigned ColumnNumber)
+        : Filename(Filename), LineNumber(LineNumber),
+          ColumnNumber(ColumnNumber) {}
   };
   DenseMap<MCSymbol *, InstrInfoTy> InstrInfo;
 
index 55a50002b8b9389feece332bc3b84d879412744b..bc2a11d066b57f2975331215d51c984b068f50a0 100644 (file)
@@ -51,7 +51,7 @@
 ; X86-NEXT: [[F2_START]]:
 ; X86-NEXT: .secrel32 _f
 ; X86-NEXT: .secidx _f
-; X86-NEXT: .short 0
+; X86-NEXT: .short 1
 ; X86-NEXT: .long [[END_OF_F]]-_f
 ; X86-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X86-NEXT: .long   0
 ; X86-NEXT: .long   5
 ; X86-NEXT: .long [[RETURN_STMT]]-_f
 ; X86-NEXT: .long   6
+; X86-NEXT: .short  0
+; X86-NEXT: .short  0
+; X86-NEXT: .short  0
+; X86-NEXT: .short  0
+; X86-NEXT: .short  0
+; X86-NEXT: .short  0
 ; X86-NEXT: [[FILE_SEGMENT_END]]:
 ; X86-NEXT: [[F2_END]]:
 ; File index to string table offset subsection
 ; OBJ32-NEXT: ]
 ; OBJ32:      FunctionLineTable [
 ; OBJ32-NEXT:   Name: _f
+; OBJ32-NEXT:   Flags: 0x1
 ; OBJ32-NEXT:   CodeSize: 0x6
 ; OBJ32-NEXT:   FilenameSegment [
 ; OBJ32-NEXT:     Filename: D:\asm.c
 ; OBJ32-NEXT:     +0x0: 4
 ; OBJ32-NEXT:     +0x0: 5
 ; OBJ32-NEXT:     +0x5: 6
+; OBJ32-NEXT:     ColStart: 0
+; OBJ32-NEXT:     ColEnd: 0
+; OBJ32-NEXT:     ColStart: 0
+; OBJ32-NEXT:     ColEnd: 0
+; OBJ32-NEXT:     ColStart: 0
+; OBJ32-NEXT:     ColEnd: 0
 ; OBJ32-NEXT:   ]
 ; OBJ32-NEXT: ]
 ; OBJ32:    }
 ; X64-NEXT: [[F2_START]]:
 ; X64-NEXT: .secrel32 f
 ; X64-NEXT: .secidx f
-; X64-NEXT: .short 0
+; X64-NEXT: .short 1
 ; X64-NEXT: .long [[END_OF_F]]-f
 ; X64-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X64-NEXT: .long   0
 ; X64-NEXT: .long   5
 ; X64-NEXT: .long [[EPILOG_AND_RET]]-f
 ; X64-NEXT: .long   6
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
 ; X64-NEXT: [[FILE_SEGMENT_END]]:
 ; X64-NEXT: [[F2_END]]:
 ; File index to string table offset subsection
 ; OBJ64-NEXT: ]
 ; OBJ64:      FunctionLineTable [
 ; OBJ64-NEXT:   Name: f
+; OBJ64-NEXT:   Flags: 0x1
 ; OBJ64-NEXT:   CodeSize: 0xE
 ; OBJ64-NEXT:   FilenameSegment [
 ; OBJ64-NEXT:     Filename: D:\asm.c
 ; OBJ64-NEXT:     +0x4: 4
 ; OBJ64-NEXT:     +0x4: 5
 ; OBJ64-NEXT:     +0x9: 6
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
 ; OBJ64-NEXT:   ]
 ; OBJ64-NEXT: ]
 ; OBJ64:    }
index 0c9782aceec2c0fcede8d5351ba821322fd4ca77..3dedacebc140f95366f93aff8811cc16081d8f6d 100644 (file)
@@ -58,7 +58,7 @@
 ; X86-NEXT: [[F2_START]]:
 ; X86-NEXT: .secrel32 _f
 ; X86-NEXT: .secidx _f
-; X86-NEXT: .short 0
+; X86-NEXT: .short 1
 ; X86-NEXT: .long [[END_OF_F]]-_f
 ; Segment for file 'D:\\one.c' begins
 ; X86-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
@@ -67,6 +67,8 @@
 ; X86-NEXT: .long [[FILE_SEGMENT_END:.*]]-[[FILE_SEGMENT_START]]
 ; X86-NEXT: .long [[CALL_LINE_1]]-_f
 ; X86-NEXT: .long   1
+; X86-NEXT: .short  0
+; X86-NEXT: .short  0
 ; X86-NEXT: [[FILE_SEGMENT_END]]:
 ; Segment for file 'D:\\two.c' begins
 ; X86-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
@@ -75,6 +77,8 @@
 ; X86-NEXT: .long [[FILE_SEGMENT_END:.*]]-[[FILE_SEGMENT_START]]
 ; X86-NEXT: .long [[CALL_LINE_2]]-_f
 ; X86-NEXT: .long   2
+; X86-NEXT: .short  0
+; X86-NEXT: .short  0
 ; X86-NEXT: [[FILE_SEGMENT_END]]:
 ; A new segment for file 'D:\\one.c' begins
 ; X86-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X86-NEXT: .long   7
 ; X86-NEXT: .long [[RETURN_STMT]]-_f
 ; X86-NEXT: .long   8
+; X86-NEXT: .short  0
+; X86-NEXT: .short  0
+; X86-NEXT: .short  0
+; X86-NEXT: .short  0
 ; X86-NEXT: [[FILE_SEGMENT_END]]:
 ; X86-NEXT: [[F2_END]]:
 ; File index to string table offset subsection
 ; OBJ32-NEXT: ]
 ; OBJ32:      FunctionLineTable [
 ; OBJ32-NEXT:   Name: _f
+; OBJ32-NEXT:   Flags: 0x1
 ; OBJ32-NEXT:   CodeSize: 0x10
 ; OBJ32-NEXT:   FilenameSegment [
 ; OBJ32-NEXT:     Filename: D:\one.c
 ; OBJ32-NEXT:     +0x0: 1
+; OBJ32-NEXT:     ColStart: 0
+; OBJ32-NEXT:     ColEnd: 0
 ; OBJ32-NEXT:   ]
 ; OBJ32-NEXT:   FilenameSegment [
 ; OBJ32-NEXT:     Filename: D:\two.c
 ; OBJ32-NEXT:     +0x5: 2
+; OBJ32-NEXT:     ColStart: 0
+; OBJ32-NEXT:     ColEnd: 0
 ; OBJ32-NEXT:   ]
 ; OBJ32-NEXT:   FilenameSegment [
 ; OBJ32-NEXT:     Filename: D:\one.c
 ; OBJ32-NEXT:     +0xA: 7
 ; OBJ32-NEXT:     +0xF: 8
+; OBJ32-NEXT:     ColStart: 0
+; OBJ32-NEXT:     ColEnd: 0
+; OBJ32-NEXT:     ColStart: 0
+; OBJ32-NEXT:     ColEnd: 0
 ; OBJ32-NEXT:   ]
 ; OBJ32-NEXT: ]
 ; OBJ32:    }
 ; X64-NEXT: [[F2_START]]:
 ; X64-NEXT: .secrel32 f
 ; X64-NEXT: .secidx f
-; X64-NEXT: .short 0
+; X64-NEXT: .short 1
 ; X64-NEXT: .long [[END_OF_F]]-f
 ; Segment for file 'D:\\input.c' begins
 ; X64-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X64-NEXT: .long [[FILE_SEGMENT_END:.*]]-[[FILE_SEGMENT_START]]
 ; X64-NEXT: .long [[START]]-f
 ; X64-NEXT: .long   3
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
 ; X64-NEXT: [[FILE_SEGMENT_END]]:
 ; Segment for file 'D:\\one.c' begins
 ; X64-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X64-NEXT: .long [[FILE_SEGMENT_END:.*]]-[[FILE_SEGMENT_START]]
 ; X64-NEXT: .long [[CALL_LINE_1]]-f
 ; X64-NEXT: .long   1
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
 ; X64-NEXT: [[FILE_SEGMENT_END]]:
 ; Segment for file 'D:\\two.c' begins
 ; X64-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X64-NEXT: .long [[FILE_SEGMENT_END:.*]]-[[FILE_SEGMENT_START]]
 ; X64-NEXT: .long [[CALL_LINE_2]]-f
 ; X64-NEXT: .long   2
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
 ; X64-NEXT: [[FILE_SEGMENT_END]]:
 ; A new segment for file 'D:\\one.c' begins
 ; X64-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X64-NEXT: .long   7
 ; X64-NEXT: .long [[EPILOG_AND_RET]]-f
 ; X64-NEXT: .long   8
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
 ; X64-NEXT: [[FILE_SEGMENT_END]]:
 ; X64-NEXT: [[F2_END]]:
 ; File index to string table offset subsection
 ; OBJ64-NEXT: ]
 ; OBJ64:      FunctionLineTable [
 ; OBJ64-NEXT:   Name: f
+; OBJ64-NEXT:   Flags: 0x1
 ; OBJ64-NEXT:   CodeSize: 0x18
 ; OBJ64-NEXT:   FilenameSegment [
 ; OBJ64-NEXT:     Filename: D:\input.c
 ; OBJ64-NEXT:     +0x0: 3
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
 ; OBJ64-NEXT:   ]
 ; OBJ64-NEXT:   FilenameSegment [
 ; OBJ64-NEXT:     Filename: D:\one.c
 ; OBJ64-NEXT:     +0x4: 1
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
 ; OBJ64-NEXT:   ]
 ; OBJ64-NEXT:   FilenameSegment [
 ; OBJ64-NEXT:     Filename: D:\two.c
 ; OBJ64-NEXT:     +0x9: 2
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
 ; OBJ64-NEXT:   ]
 ; OBJ64-NEXT:   FilenameSegment [
 ; OBJ64-NEXT:     Filename: D:\one.c
 ; OBJ64-NEXT:     +0xE: 7
 ; OBJ64-NEXT:     +0x13: 8
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
 ; OBJ64-NEXT:   ]
 ; OBJ64-NEXT: ]
 ; OBJ64:    }
index 53a8115252d0db11296ef596c8c38d384992173b..bbf97dd4afc0fee0983b9c7a012f7dcf39826ff4 100644 (file)
@@ -82,7 +82,7 @@
 ; X86-NEXT: [[F2_START]]:
 ; X86-NEXT: .secrel32       _x
 ; X86-NEXT: .secidx _x
-; X86-NEXT: .short 0
+; X86-NEXT: .short 1
 ; X86-NEXT: .long [[END_OF_X]]-_x
 ; X86-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X86-NEXT: .long   0
 ; X86-NEXT: .long   4
 ; X86-NEXT: .long [[X_RETURN]]-_x
 ; X86-NEXT: .long   5
+; X86-NEXT: .short 42
+; X86-NEXT: .short 42
+; X86-NEXT: .short 43
+; X86-NEXT: .short 43
 ; X86-NEXT: [[FILE_SEGMENT_END]]:
 ; X86-NEXT: [[F2_END]]:
 ; Symbol subsection for y
 ; X86-NEXT: [[F2_START]]:
 ; X86-NEXT: .secrel32       _y
 ; X86-NEXT: .secidx _y
-; X86-NEXT: .short 0
+; X86-NEXT: .short 1
 ; X86-NEXT: .long [[END_OF_Y]]-_y
 ; X86-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X86-NEXT: .long   0
 ; X86-NEXT: .long   8
 ; X86-NEXT: .long [[Y_RETURN]]-_y
 ; X86-NEXT: .long   9
+; X86-NEXT: .short 52
+; X86-NEXT: .short 52
+; X86-NEXT: .short 53
+; X86-NEXT: .short 53
 ; X86-NEXT: [[FILE_SEGMENT_END]]:
 ; X86-NEXT: [[F2_END]]:
 ; Symbol subsection for f
 ; X86-NEXT: [[F2_START]]:
 ; X86-NEXT: .secrel32 _f
 ; X86-NEXT: .secidx _f
-; X86-NEXT: .short 0
+; X86-NEXT: .short 1
 ; X86-NEXT: .long [[END_OF_F]]-_f
 ; X86-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X86-NEXT: .long   0
 ; X86-NEXT: .long   14
 ; X86-NEXT: .long [[F_RETURN]]-_f
 ; X86-NEXT: .long   15
+; X86-NEXT: .short 62
+; X86-NEXT: .short 62
+; X86-NEXT: .short 63
+; X86-NEXT: .short 63
+; X86-NEXT: .short 72
+; X86-NEXT: .short 72
+; X86-NEXT: .short 73
+; X86-NEXT: .short 73
 ; X86-NEXT: [[FILE_SEGMENT_END]]:
 ; X86-NEXT: [[F2_END]]:
 ; File index to string table offset subsection
 ; OBJ32-NEXT:   0x30 IMAGE_REL_I386_SECTION _x
 ; OBJ32-NEXT:   0x44 IMAGE_REL_I386_SECREL _x
 ; OBJ32-NEXT:   0x48 IMAGE_REL_I386_SECTION _x
-; OBJ32-NEXT:   0x94 IMAGE_REL_I386_SECREL _y
-; OBJ32-NEXT:   0x98 IMAGE_REL_I386_SECTION _y
-; OBJ32-NEXT:   0xAC IMAGE_REL_I386_SECREL _y
-; OBJ32-NEXT:   0xB0 IMAGE_REL_I386_SECTION _y
-; OBJ32-NEXT:   0xFC IMAGE_REL_I386_SECREL _f
-; OBJ32-NEXT:   0x100 IMAGE_REL_I386_SECTION _f
-; OBJ32-NEXT:   0x114 IMAGE_REL_I386_SECREL _f
-; OBJ32-NEXT:   0x118 IMAGE_REL_I386_SECTION _f
+; OBJ32-NEXT:   0x9C IMAGE_REL_I386_SECREL _y
+; OBJ32-NEXT:   0xA0 IMAGE_REL_I386_SECTION _y
+; OBJ32-NEXT:   0xB4 IMAGE_REL_I386_SECREL _y
+; OBJ32-NEXT:   0xB8 IMAGE_REL_I386_SECTION _y
+; OBJ32-NEXT:   0x10C IMAGE_REL_I386_SECREL _f
+; OBJ32-NEXT:   0x110 IMAGE_REL_I386_SECTION _f
+; OBJ32-NEXT:   0x124 IMAGE_REL_I386_SECREL _f
+; OBJ32-NEXT:   0x128 IMAGE_REL_I386_SECTION _f
 ; OBJ32-NEXT: ]
 ; OBJ32:      Subsection [
 ; OBJ32-NEXT:   Type: 0xF1
 ; OBJ32:      ]
 ; OBJ32:      FunctionLineTable [
 ; OBJ32-NEXT:   Name: _x
+; OBJ32-NEXT:   Flags: 0x1
 ; OBJ32-NEXT:   CodeSize: 0x6
 ; OBJ32-NEXT:   FilenameSegment [
 ; OBJ32-NEXT:     Filename: D:\source.c
 ; OBJ32-NEXT:     +0x0: 4
 ; OBJ32-NEXT:     +0x5: 5
+; OBJ32-NEXT:     ColStart: 42
+; OBJ32-NEXT:     ColEnd: 42
+; OBJ32-NEXT:     ColStart: 43
+; OBJ32-NEXT:     ColEnd: 43
 ; OBJ32-NEXT:   ]
 ; OBJ32-NEXT: ]
 ; OBJ32-NEXT: FunctionLineTable [
 ; OBJ32-NEXT:   Name: _y
+; OBJ32-NEXT:   Flags: 0x1
 ; OBJ32-NEXT:   CodeSize: 0x6
 ; OBJ32-NEXT:   FilenameSegment [
 ; OBJ32-NEXT:     Filename: D:\source.c
 ; OBJ32-NEXT:     +0x0: 8
 ; OBJ32-NEXT:     +0x5: 9
+; OBJ32-NEXT:     ColStart: 52
+; OBJ32-NEXT:     ColEnd: 52
+; OBJ32-NEXT:     ColStart: 53
+; OBJ32-NEXT:     ColEnd: 53
 ; OBJ32-NEXT:   ]
 ; OBJ32-NEXT: ]
 ; OBJ32-NEXT: FunctionLineTable [
 ; OBJ32-NEXT:   Name: _f
+; OBJ32-NEXT:   Flags: 0x1
 ; OBJ32-NEXT:   CodeSize: 0x10
 ; OBJ32-NEXT:   FilenameSegment [
 ; OBJ32-NEXT:     Filename: D:\source.c
 ; OBJ32-NEXT:     +0x5: 13
 ; OBJ32-NEXT:     +0xA: 14
 ; OBJ32-NEXT:     +0xF: 15
+; OBJ32-NEXT:     ColStart: 62
+; OBJ32-NEXT:     ColEnd: 62
+; OBJ32-NEXT:     ColStart: 63
+; OBJ32-NEXT:     ColEnd: 63
+; OBJ32-NEXT:     ColStart: 72
+; OBJ32-NEXT:     ColEnd: 72
+; OBJ32-NEXT:     ColStart: 73
+; OBJ32-NEXT:     ColEnd: 73
 ; OBJ32-NEXT:   ]
 ; OBJ32-NEXT: ]
 ; OBJ32:    }
 ; X64-NEXT: [[F2_START]]:
 ; X64-NEXT: .secrel32 x
 ; X64-NEXT: .secidx x
-; X64-NEXT: .short 0
+; X64-NEXT: .short 1
 ; X64-NEXT: .long [[END_OF_X]]-x
 ; X64-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X64-NEXT: .long   0
 ; X64-NEXT: .long   4
 ; X64-NEXT: .long [[X_EPILOG_AND_RET]]-x
 ; X64-NEXT: .long   5
+; X64-NEXT: .short 0
+; X64-NEXT: .short 0
+; X64-NEXT: .short 42
+; X64-NEXT: .short 42
+; X64-NEXT: .short 43
+; X64-NEXT: .short 43
 ; X64-NEXT: [[FILE_SEGMENT_END]]:
 ; X64-NEXT: [[F2_END]]:
 ; Symbol subsection for y
 ; X64-NEXT: [[F2_START]]:
 ; X64-NEXT: .secrel32 y
 ; X64-NEXT: .secidx y
-; X64-NEXT: .short 0
+; X64-NEXT: .short 1
 ; X64-NEXT: .long [[END_OF_Y]]-y
 ; X64-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X64-NEXT: .long   0
 ; X64-NEXT: .long   8
 ; X64-NEXT: .long [[Y_EPILOG_AND_RET]]-y
 ; X64-NEXT: .long   9
+; X64-NEXT: .short 0
+; X64-NEXT: .short 0
+; X64-NEXT: .short 52
+; X64-NEXT: .short 52
+; X64-NEXT: .short 53
+; X64-NEXT: .short 53
 ; X64-NEXT: [[FILE_SEGMENT_END]]:
 ; X64-NEXT: [[F2_END]]:
 ; Symbol subsection for f
 ; X64-NEXT: [[F2_START]]:
 ; X64-NEXT: .secrel32 f
 ; X64-NEXT: .secidx f
-; X64-NEXT: .short 0
+; X64-NEXT: .short 1
 ; X64-NEXT: .long [[END_OF_F]]-f
 ; X64-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X64-NEXT: .long   0
 ; X64-NEXT: .long   14
 ; X64-NEXT: .long [[F_EPILOG_AND_RET]]-f
 ; X64-NEXT: .long   15
+; X64-NEXT: .short 0
+; X64-NEXT: .short 0
+; X64-NEXT: .short 62
+; X64-NEXT: .short 62
+; X64-NEXT: .short 63
+; X64-NEXT: .short 63
+; X64-NEXT: .short 72
+; X64-NEXT: .short 72
+; X64-NEXT: .short 73
+; X64-NEXT: .short 73
 ; X64-NEXT: [[FILE_SEGMENT_END]]:
 ; X64-NEXT: [[F2_END]]:
 ; File index to string table offset subsection
 ; OBJ64-NEXT:   0x30 IMAGE_REL_AMD64_SECTION x
 ; OBJ64-NEXT:   0x44 IMAGE_REL_AMD64_SECREL x
 ; OBJ64-NEXT:   0x48 IMAGE_REL_AMD64_SECTION x
-; OBJ64-NEXT:   0x9C IMAGE_REL_AMD64_SECREL y
-; OBJ64-NEXT:   0xA0 IMAGE_REL_AMD64_SECTION y
-; OBJ64-NEXT:   0xB4 IMAGE_REL_AMD64_SECREL y
-; OBJ64-NEXT:   0xB8 IMAGE_REL_AMD64_SECTION y
-; OBJ64-NEXT:   0x10C IMAGE_REL_AMD64_SECREL f
-; OBJ64-NEXT:   0x110 IMAGE_REL_AMD64_SECTION f
+; OBJ64-NEXT:   0xA8 IMAGE_REL_AMD64_SECREL y
+; OBJ64-NEXT:   0xAC IMAGE_REL_AMD64_SECTION y
+; OBJ64-NEXT:   0xC0 IMAGE_REL_AMD64_SECREL y
+; OBJ64-NEXT:   0xC4 IMAGE_REL_AMD64_SECTION y
 ; OBJ64-NEXT:   0x124 IMAGE_REL_AMD64_SECREL f
 ; OBJ64-NEXT:   0x128 IMAGE_REL_AMD64_SECTION f
+; OBJ64-NEXT:   0x13C IMAGE_REL_AMD64_SECREL f
+; OBJ64-NEXT:   0x140 IMAGE_REL_AMD64_SECTION f
 ; OBJ64-NEXT: ]
 ; OBJ64:      Subsection [
 ; OBJ64-NEXT:   Type: 0xF1
 ; OBJ64:      ]
 ; OBJ64:      FunctionLineTable [
 ; OBJ64-NEXT:   Name: x
+; OBJ64-NEXT:   Flags: 0x1
 ; OBJ64-NEXT:   CodeSize: 0xE
 ; OBJ64-NEXT:   FilenameSegment [
 ; OBJ64-NEXT:     Filename: D:\source.c
 ; OBJ64-NEXT:     +0x0: 3
 ; OBJ64-NEXT:     +0x4: 4
 ; OBJ64-NEXT:     +0x9: 5
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
+; OBJ64-NEXT:     ColStart: 42
+; OBJ64-NEXT:     ColEnd: 42
+; OBJ64-NEXT:     ColStart: 43
+; OBJ64-NEXT:     ColEnd: 43
 ; OBJ64-NEXT:   ]
 ; OBJ64-NEXT: ]
 ; OBJ64-NEXT: FunctionLineTable [
 ; OBJ64-NEXT:   Name: y
+; OBJ64-NEXT:   Flags: 0x1
 ; OBJ64-NEXT:   CodeSize: 0xE
 ; OBJ64-NEXT:   FilenameSegment [
 ; OBJ64-NEXT:     Filename: D:\source.c
 ; OBJ64-NEXT:     +0x0: 7
 ; OBJ64-NEXT:     +0x4: 8
 ; OBJ64-NEXT:     +0x9: 9
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
+; OBJ64-NEXT:     ColStart: 52
+; OBJ64-NEXT:     ColEnd: 52
+; OBJ64-NEXT:     ColStart: 53
+; OBJ64-NEXT:     ColEnd: 53
 ; OBJ64-NEXT:   ]
 ; OBJ64-NEXT: ]
 ; OBJ64-NEXT: FunctionLineTable [
 ; OBJ64-NEXT:   Name: f
+; OBJ64-NEXT:   Flags: 0x1
 ; OBJ64-NEXT:   CodeSize: 0x18
 ; OBJ64-NEXT:   FilenameSegment [
 ; OBJ64-NEXT:     Filename: D:\source.c
 ; OBJ64-NEXT:     +0x9: 13
 ; OBJ64-NEXT:     +0xE: 14
 ; OBJ64-NEXT:     +0x13: 15
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
+; OBJ64-NEXT:     ColStart: 62
+; OBJ64-NEXT:     ColEnd: 62
+; OBJ64-NEXT:     ColStart: 63
+; OBJ64-NEXT:     ColEnd: 63
+; OBJ64-NEXT:     ColStart: 72
+; OBJ64-NEXT:     ColEnd: 72
+; OBJ64-NEXT:     ColStart: 73
+; OBJ64-NEXT:     ColEnd: 73
 ; OBJ64-NEXT:   ]
 ; OBJ64-NEXT: ]
 ; OBJ64:    }
@@ -599,11 +681,11 @@ attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "
 !11 = !{i32 2, !"Dwarf Version", i32 4}
 !12 = !{i32 1, !"Debug Info Version", i32 3}
 !13 = !{!"clang version 3.5 "}
-!14 = !DILocation(line: 4, scope: !4)
-!15 = !DILocation(line: 5, scope: !4)
-!16 = !DILocation(line: 8, scope: !9)
-!17 = !DILocation(line: 9, scope: !9)
-!18 = !DILocation(line: 12, scope: !10)
-!19 = !DILocation(line: 13, scope: !10)
-!20 = !DILocation(line: 14, scope: !10)
-!21 = !DILocation(line: 15, scope: !10)
+!14 = !DILocation(line: 4, column: 42, scope: !4)
+!15 = !DILocation(line: 5, column: 43, scope: !4)
+!16 = !DILocation(line: 8, column: 52, scope: !9)
+!17 = !DILocation(line: 9, column: 53, scope: !9)
+!18 = !DILocation(line: 12, column: 62, scope: !10)
+!19 = !DILocation(line: 13, column: 63, scope: !10)
+!20 = !DILocation(line: 14, column: 72, scope: !10)
+!21 = !DILocation(line: 15, column: 73, scope: !10)
index 9cb1d1e1d9046c1c8405d4becafac364a921a8fe..0d9857c7831d5fded805526e196616e88e48fd5d 100644 (file)
@@ -49,7 +49,7 @@
 ; X86-NEXT: [[F2_START]]:
 ; X86-NEXT: .secrel32 _f
 ; X86-NEXT: .secidx _f
-; X86-NEXT: .short  0
+; X86-NEXT: .short  1
 ; X86-NEXT: .long [[END_OF_F]]-_f
 ; X86-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X86-NEXT: .long   0
 ; X86-NEXT: .long   4
 ; X86-NEXT: .long [[RETURN_STMT]]-_f
 ; X86-NEXT: .long   5
+; X86-NEXT: .short  0
+; X86-NEXT: .short  0
+; X86-NEXT: .short  0
+; X86-NEXT: .short  0
 ; X86-NEXT: [[FILE_SEGMENT_END]]:
 ; X86-NEXT: [[F2_END]]:
 ; File index to string table offset subsection
 ; OBJ32-NEXT: ]
 ; OBJ32:      FunctionLineTable [
 ; OBJ32-NEXT:   Name: _f
+; OBJ32-NEXT:   Flags: 0x1
 ; OBJ32-NEXT:   CodeSize: 0x6
 ; OBJ32-NEXT:   FilenameSegment [
 ; OBJ32-NEXT:     Filename: D:\test.c
 ; OBJ32-NEXT:     +0x0: 4
 ; OBJ32-NEXT:     +0x5: 5
+; OBJ32-NEXT:     ColStart: 0
+; OBJ32-NEXT:     ColEnd: 0
+; OBJ32-NEXT:     ColStart: 0
+; OBJ32-NEXT:     ColEnd: 0
 ; OBJ32-NEXT:   ]
 ; OBJ32-NEXT: ]
 ; OBJ32:    }
 ; X64-NEXT: [[F2_START]]:
 ; X64-NEXT: .secrel32 f
 ; X64-NEXT: .secidx f
-; X64-NEXT: .short  0
+; X64-NEXT: .short  1
 ; X64-NEXT: .long [[END_OF_F]]-f
 ; X64-NEXT: [[FILE_SEGMENT_START:[^:]*]]:
 ; X64-NEXT: .long   0
 ; X64-NEXT: .long   4
 ; X64-NEXT: .long [[EPILOG_AND_RET]]-f
 ; X64-NEXT: .long   5
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
+; X64-NEXT: .short  0
 ; X64-NEXT: [[FILE_SEGMENT_END]]:
 ; X64-NEXT: [[F2_END]]:
 ; File index to string table offset subsection
 ; OBJ64-NEXT: ]
 ; OBJ64:      FunctionLineTable [
 ; OBJ64-NEXT:   Name: f
+; OBJ64-NEXT:   Flags: 0x1
 ; OBJ64-NEXT:   CodeSize: 0xE
 ; OBJ64-NEXT:   FilenameSegment [
 ; OBJ64-NEXT:     Filename: D:\test.c
 ; OBJ64-NEXT:     +0x0: 3
 ; OBJ64-NEXT:     +0x4: 4
 ; OBJ64-NEXT:     +0x9: 5
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
+; OBJ64-NEXT:     ColStart: 0
+; OBJ64-NEXT:     ColEnd: 0
 ; OBJ64-NEXT:   ]
 ; OBJ64-NEXT: ]
 ; OBJ64:    }
index b2acee1200b93366446d12f3920cc6a3ad1c3978..d124e6e2d4548a99f6d9b7644340c1062d6b3b65 100644 (file)
@@ -104,6 +104,7 @@ MFUN32-NEXT:     PayloadSize: 0x8
 MFUN32:        ]
 MFUN32-NEXT:   FunctionLineTable [
 MFUN32-NEXT:     FunctionName: _x
+MFUN32-NEXT:     Flags: 0x0
 MFUN32-NEXT:     CodeSize: 0xA
 MFUN32-NEXT:     FilenameSegment [
 MFUN32-NEXT:       Filename: d:\source.c
@@ -114,6 +115,7 @@ MFUN32-NEXT:     ]
 MFUN32-NEXT:   ]
 MFUN32-NEXT:   FunctionLineTable [
 MFUN32-NEXT:     FunctionName: _y
+MFUN32-NEXT:     Flags: 0x0
 MFUN32-NEXT:     CodeSize: 0xA
 MFUN32-NEXT:     FilenameSegment [
 MFUN32-NEXT:       Filename: d:\source.c
@@ -124,6 +126,7 @@ MFUN32-NEXT:     ]
 MFUN32-NEXT:   ]
 MFUN32-NEXT:   FunctionLineTable [
 MFUN32-NEXT:     FunctionName: _f
+MFUN32-NEXT:     Flags: 0x0
 MFUN32-NEXT:     CodeSize: 0x14
 MFUN32-NEXT:     FilenameSegment [
 MFUN32-NEXT:       Filename: d:\source.c
@@ -201,6 +204,7 @@ MFUN64-NEXT:     PayloadSize: 0x8
 MFUN64:        ]
 MFUN64-NEXT:   FunctionLineTable [
 MFUN64-NEXT:     FunctionName: x
+MFUN64-NEXT:     Flags: 0x0
 MFUN64-NEXT:     CodeSize: 0xE
 MFUN64-NEXT:     FilenameSegment [
 MFUN64-NEXT:       Filename: d:\source.c
@@ -211,6 +215,7 @@ MFUN64-NEXT:     ]
 MFUN64-NEXT:   ]
 MFUN64-NEXT:   FunctionLineTable [
 MFUN64-NEXT:     FunctionName: y
+MFUN64-NEXT:     Flags: 0x0
 MFUN64-NEXT:     CodeSize: 0xE
 MFUN64-NEXT:     FilenameSegment [
 MFUN64-NEXT:       Filename: d:\source.c
@@ -221,6 +226,7 @@ MFUN64-NEXT:     ]
 MFUN64-NEXT:   ]
 MFUN64-NEXT:   FunctionLineTable [
 MFUN64-NEXT:     FunctionName: f
+MFUN64-NEXT:     Flags: 0x0
 MFUN64-NEXT:     CodeSize: 0x18
 MFUN64-NEXT:     FilenameSegment [
 MFUN64-NEXT:       Filename: d:\source.c
@@ -296,6 +302,7 @@ MFILE32-NEXT:     PayloadSize: 0x8
 MFILE32:        ]
 MFILE32-NEXT:   FunctionLineTable [
 MFILE32-NEXT:     FunctionName: _f
+MFILE32-NEXT:     Flags: 0x0
 MFILE32-NEXT:     CodeSize: 0x14
 MFILE32-NEXT:     FilenameSegment [
 MFILE32-NEXT:       Filename: d:\input.c
@@ -352,6 +359,7 @@ MFILE64-NEXT:     PayloadSize: 0x8
 MFILE64:        ]
 MFILE64-NEXT:   FunctionLineTable [
 MFILE64-NEXT:     FunctionName: f
+MFILE64-NEXT:     Flags: 0x0
 MFILE64-NEXT:     CodeSize: 0x18
 MFILE64-NEXT:     FilenameSegment [
 MFILE64-NEXT:       Filename: d:\input.c
@@ -399,6 +407,7 @@ MCOMDAT-NEXT:   CodeSize: 0x7
 MCOMDAT-NEXT: }
 MCOMDAT:      FunctionLineTable [
 MCOMDAT-NEXT:   FunctionName: ?f@@YAHXZ
+MCOMDAT-NEXT:   Flags: 0x0
 MCOMDAT-NEXT:   CodeSize: 0x7
 MCOMDAT-NEXT:   FilenameSegment [
 MCOMDAT-NEXT:     Filename: c:\src\test.cc
@@ -414,6 +423,7 @@ MCOMDAT-NEXT:   CodeSize: 0x7
 MCOMDAT-NEXT: }
 MCOMDAT:      FunctionLineTable [
 MCOMDAT-NEXT:   FunctionName: ?g@@YAHXZ
+MCOMDAT-NEXT:   Flags: 0x0
 MCOMDAT-NEXT:   CodeSize: 0x7
 MCOMDAT-NEXT:   FilenameSegment [
 MCOMDAT-NEXT:     Filename: c:\src\test.cc
index 91a4435d848772ef65ff65b7f69cf94636d9329f..c6ff1c4dd21fa0fd174bd6e002e44379ea297e42 100644 (file)
@@ -585,7 +585,11 @@ void COFFDumper::printCodeViewDebugInfo(const SectionRef &Section) {
     W.printString("FunctionName", Name);
 
     DataExtractor DE(FunctionLineTables[Name], true, 4);
-    uint32_t Offset = 8;  // Skip relocations.
+    uint32_t Offset = 6;  // Skip relocations.
+    uint16_t Flags = DE.getU16(&Offset);
+    W.printHex("Flags", Flags);
+    bool HasColumnInformation =
+        Flags & COFF::DEBUG_LINE_TABLES_HAVE_COLUMN_RECORDS;
     uint32_t FunctionSize = DE.getU32(&Offset);
     W.printHex("CodeSize", FunctionSize);
     while (DE.isValidOffset(Offset)) {
@@ -595,11 +599,6 @@ void COFFDumper::printCodeViewDebugInfo(const SectionRef &Section) {
       uint32_t OffsetInIndex = DE.getU32(&Offset),
                SegmentLength   = DE.getU32(&Offset),
                FullSegmentSize = DE.getU32(&Offset);
-      if (FullSegmentSize != 12 + 8 * SegmentLength) {
-        error(object_error::parse_failed);
-        return;
-      }
-
       uint32_t FilenameOffset;
       {
         DataExtractor SDE(CVFileIndexToStringOffsetTable, true, 4);
@@ -636,6 +635,15 @@ void COFFDumper::printCodeViewDebugInfo(const SectionRef &Section) {
         format("+0x%X", PC).snprint(Buffer, 32);
         W.printNumber(Buffer, LineNumber);
       }
+      if (HasColumnInformation) {
+        for (unsigned J = 0; J != SegmentLength && DE.isValidOffset(Offset);
+             ++J) {
+          uint16_t ColStart = DE.getU16(&Offset);
+          W.printNumber("ColStart", ColStart);
+          uint16_t ColEnd = DE.getU16(&Offset);
+          W.printNumber("ColEnd", ColEnd);
+        }
+      }
     }
   }
 }