From b1d6ad18ba46bed91e1f39222cd7be9b0cd5e3fa Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Thu, 9 Jul 2015 00:19:51 +0000 Subject: [PATCH] [CodeView] Add support for emitting column information 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 | 1 + .../AsmPrinter/WinCodeViewLineTables.cpp | 30 +++- .../AsmPrinter/WinCodeViewLineTables.h | 8 +- test/DebugInfo/COFF/asm.ll | 34 ++++- test/DebugInfo/COFF/multifile.ll | 42 +++++- test/DebugInfo/COFF/multifunction.ll | 138 ++++++++++++++---- test/DebugInfo/COFF/simple.ll | 26 +++- .../llvm-readobj/codeview-linetables.test | 10 ++ tools/llvm-readobj/COFFDumper.cpp | 20 ++- 9 files changed, 259 insertions(+), 50 deletions(-) diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h index b26af61a7c7..3c5ee06969d 100644 --- a/include/llvm/Support/COFF.h +++ b/include/llvm/Support/COFF.h @@ -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, diff --git a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp index 535b1f60585..6610ac78f8c 100644 --- a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp +++ b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp @@ -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); } diff --git a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h index a5b399f7370..43d1a432712 100644 --- a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h +++ b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h @@ -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 InstrInfo; diff --git a/test/DebugInfo/COFF/asm.ll b/test/DebugInfo/COFF/asm.ll index 55a50002b8b..bc2a11d066b 100644 --- a/test/DebugInfo/COFF/asm.ll +++ b/test/DebugInfo/COFF/asm.ll @@ -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 @@ -63,6 +63,12 @@ ; 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 @@ -101,6 +107,7 @@ ; 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 @@ -110,6 +117,12 @@ ; 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: } @@ -157,7 +170,7 @@ ; 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 @@ -171,6 +184,14 @@ ; 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 @@ -209,6 +230,7 @@ ; 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 @@ -218,6 +240,14 @@ ; 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: } diff --git a/test/DebugInfo/COFF/multifile.ll b/test/DebugInfo/COFF/multifile.ll index 0c9782aceec..3dedacebc14 100644 --- a/test/DebugInfo/COFF/multifile.ll +++ b/test/DebugInfo/COFF/multifile.ll @@ -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:[^:]*]]: @@ -85,6 +89,10 @@ ; 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 @@ -126,19 +134,28 @@ ; 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: } @@ -189,7 +206,7 @@ ; 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:[^:]*]]: @@ -198,6 +215,8 @@ ; 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:[^:]*]]: @@ -206,6 +225,8 @@ ; 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:[^:]*]]: @@ -214,6 +235,8 @@ ; 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:[^:]*]]: @@ -224,6 +247,10 @@ ; 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 @@ -269,23 +296,34 @@ ; 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: } diff --git a/test/DebugInfo/COFF/multifunction.ll b/test/DebugInfo/COFF/multifunction.ll index 53a8115252d..bbf97dd4afc 100644 --- a/test/DebugInfo/COFF/multifunction.ll +++ b/test/DebugInfo/COFF/multifunction.ll @@ -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 @@ -92,6 +92,10 @@ ; 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 @@ -121,7 +125,7 @@ ; 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 @@ -131,6 +135,10 @@ ; 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 @@ -160,7 +168,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 @@ -174,6 +182,14 @@ ; 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 @@ -198,14 +214,14 @@ ; 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 @@ -248,24 +264,35 @@ ; 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 @@ -273,6 +300,14 @@ ; 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: } @@ -349,7 +384,7 @@ ; 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 @@ -361,6 +396,12 @@ ; 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 @@ -390,7 +431,7 @@ ; 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 @@ -402,6 +443,12 @@ ; 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 @@ -431,7 +478,7 @@ ; 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 @@ -447,6 +494,16 @@ ; 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 @@ -471,14 +528,14 @@ ; 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 @@ -521,26 +578,41 @@ ; 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 @@ -549,6 +621,16 @@ ; 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) diff --git a/test/DebugInfo/COFF/simple.ll b/test/DebugInfo/COFF/simple.ll index 9cb1d1e1d90..0d9857c7831 100644 --- a/test/DebugInfo/COFF/simple.ll +++ b/test/DebugInfo/COFF/simple.ll @@ -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 @@ -59,6 +59,10 @@ ; 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 @@ -97,11 +101,16 @@ ; 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: } @@ -148,7 +157,7 @@ ; 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 @@ -160,6 +169,12 @@ ; 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 @@ -198,12 +213,19 @@ ; 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: } diff --git a/test/tools/llvm-readobj/codeview-linetables.test b/test/tools/llvm-readobj/codeview-linetables.test index b2acee1200b..d124e6e2d45 100644 --- a/test/tools/llvm-readobj/codeview-linetables.test +++ b/test/tools/llvm-readobj/codeview-linetables.test @@ -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 diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index 91a4435d848..c6ff1c4dd21 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -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); + } + } } } } -- 2.34.1