From 3e3908e2c743d9346e9326fd2f9c5bc81e12e210 Mon Sep 17 00:00:00 2001 From: Timur Iskhodzhanov Date: Mon, 6 Oct 2014 16:59:44 +0000 Subject: [PATCH] Fix dumping codeview line tables when there are multiple debug sections Codeview line tables for functions in different sections refer to a common STRING_TABLE_SUBSECTION for filenames. This happens when building with -Gy or with inline functions with MSVC. Original patch by Jeff Muizelaar! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219125 91177308-0d34-0410-b5e6-96231b3b80d8 --- ...dat-function-linetables.obj.coff-2013-i386 | Bin 0 -> 8501 bytes .../llvm-readobj/codeview-linetables.test | 78 +++++++++++++----- tools/llvm-readobj/COFFDumper.cpp | 20 ++--- 3 files changed, 69 insertions(+), 29 deletions(-) create mode 100755 test/tools/llvm-readobj/Inputs/comdat-function-linetables.obj.coff-2013-i386 diff --git a/test/tools/llvm-readobj/Inputs/comdat-function-linetables.obj.coff-2013-i386 b/test/tools/llvm-readobj/Inputs/comdat-function-linetables.obj.coff-2013-i386 new file mode 100755 index 0000000000000000000000000000000000000000..4adaf2edc6f7b90f21c7223d12a971be0d0facaa GIT binary patch literal 8501 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 literal 0 HcmV?d00001 diff --git a/test/tools/llvm-readobj/codeview-linetables.test b/test/tools/llvm-readobj/codeview-linetables.test index 28e34b7d4fb..4b169336cd9 100644 --- a/test/tools/llvm-readobj/codeview-linetables.test +++ b/test/tools/llvm-readobj/codeview-linetables.test @@ -1,3 +1,4 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; The following two object files were generated using the following command: ; D:\> cl /Z7 /c source.c ; with the following contents of D:\source.c: @@ -22,25 +23,6 @@ RUN: | FileCheck %s -check-prefix MFUN32 RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifunction-linetables.obj.coff-2013-x86_64 \ RUN: | FileCheck %s -check-prefix MFUN64 -; The following two object files were generated using the following command: -; D:\> cl /Z7 /c input.c -; with the following contents of D:\input.c: -; void g(void); -; -; void f(void) { -; #line 1 "one.c" -; g(); -; #line 2 "two.c" -; g(); -; #line 7 "one.c" -; g(); -; } -; using CL v18.00.21005.1 32-/64-bit versions respectively. -RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifile-linetables.obj.coff-2013-i368 \ -RUN: | FileCheck %s -check-prefix MFILE32 -RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifile-linetables.obj.coff-2013-x86_64 \ -RUN: | FileCheck %s -check-prefix MFILE64 - MFUN32: CodeViewLineTables [ MFUN32-NEXT: Magic: 0x4 MFUN32-NEXT: Subsection [ @@ -211,6 +193,26 @@ MFUN64-NEXT: ] MFUN64-NEXT: ] MFUN64-NEXT: ] +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; The following two object files were generated using the following command: +; D:\> cl /Z7 /c input.c +; with the following contents of D:\input.c: +; void g(void); +; +; void f(void) { +; #line 1 "one.c" +; g(); +; #line 2 "two.c" +; g(); +; #line 7 "one.c" +; g(); +; } +; using CL v18.00.21005.1 32-/64-bit versions respectively. +RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifile-linetables.obj.coff-2013-i368 \ +RUN: | FileCheck %s -check-prefix MFILE32 +RUN: llvm-readobj -s -codeview-linetables %p/Inputs/multifile-linetables.obj.coff-2013-x86_64 \ +RUN: | FileCheck %s -check-prefix MFILE64 + MFILE32: CodeViewLineTables [ MFILE32-NEXT: Magic: 0x4 MFILE32-NEXT: Subsection [ @@ -314,3 +316,41 @@ MFILE64-NEXT: +0x13: 8 MFILE64-NEXT: ] MFILE64-NEXT: ] MFILE64-NEXT: ] + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; The following object file was generated using the following command: +; C:\src> cl /Z7 /Gy /c test.cc +; with the following contents of C:\src\test.cc: +; int f() +; { +; return 0; +; } +; +; int g() +; { +; return 0; +; } +; using 32-version of CL v18.00.21005.1. +RUN: llvm-readobj -s -codeview-linetables %p/Inputs/comdat-function-linetables.obj.coff-2013-i386 \ +RUN: | FileCheck %s -check-prefix MCOMDAT + +MCOMDAT: FunctionLineTable [ +MCOMDAT-NEXT: FunctionName: ?f@@YAHXZ +MCOMDAT-NEXT: CodeSize: 0x7 +MCOMDAT-NEXT: FilenameSegment [ +MCOMDAT-NEXT: Filename: c:\src\test.cc +MCOMDAT-NEXT: +0x0: 2 +MCOMDAT-NEXT: +0x3: 3 +MCOMDAT-NEXT: +0x5: 4 +MCOMDAT-NEXT: ] +MCOMDAT-NEXT: ] +MCOMDAT: FunctionLineTable [ +MCOMDAT-NEXT: FunctionName: ?g@@YAHXZ +MCOMDAT-NEXT: CodeSize: 0x7 +MCOMDAT-NEXT: FilenameSegment [ +MCOMDAT-NEXT: Filename: c:\src\test.cc +MCOMDAT-NEXT: +0x0: 7 +MCOMDAT-NEXT: +0x3: 8 +MCOMDAT-NEXT: +0x5: 9 +MCOMDAT-NEXT: ] +MCOMDAT-NEXT: ] diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index 53fba14a36e..8e7fcc06c1b 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -82,6 +82,8 @@ private: const llvm::object::COFFObjectFile *Obj; RelocMapTy RelocMap; + StringRef CVFileIndexToStringOffsetTable; + StringRef CVStringTable; }; } // namespace @@ -440,8 +442,6 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) { SmallVector FunctionNames; StringMap FunctionLineTables; - StringRef FileIndexToStringOffsetTable; - StringRef StringTable; ListScope D(W, "CodeViewLineTables"); { @@ -502,25 +502,25 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) { break; } case COFF::DEBUG_STRING_TABLE_SUBSECTION: - if (PayloadSize == 0 || StringTable.data() != nullptr || + if (PayloadSize == 0 || CVStringTable.data() != nullptr || Contents.back() != '\0') { // Empty or duplicate or non-null-terminated subsection. error(object_error::parse_failed); return; } - StringTable = Contents; + CVStringTable = Contents; break; case COFF::DEBUG_INDEX_SUBSECTION: // Holds the translation table from file indices // to offsets in the string table. if (PayloadSize == 0 || - FileIndexToStringOffsetTable.data() != nullptr) { + CVFileIndexToStringOffsetTable.data() != nullptr) { // Empty or duplicate subsection. error(object_error::parse_failed); return; } - FileIndexToStringOffsetTable = Contents; + CVFileIndexToStringOffsetTable = Contents; break; } Offset += PayloadSize; @@ -555,7 +555,7 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) { uint32_t FilenameOffset; { - DataExtractor SDE(FileIndexToStringOffsetTable, true, 4); + DataExtractor SDE(CVFileIndexToStringOffsetTable, true, 4); uint32_t OffsetInSDE = OffsetInIndex; if (!SDE.isValidOffset(OffsetInSDE)) { error(object_error::parse_failed); @@ -564,15 +564,15 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) { FilenameOffset = SDE.getU32(&OffsetInSDE); } - if (FilenameOffset == 0 || FilenameOffset + 1 >= StringTable.size() || - StringTable.data()[FilenameOffset - 1] != '\0') { + if (FilenameOffset == 0 || FilenameOffset + 1 >= CVStringTable.size() || + CVStringTable.data()[FilenameOffset - 1] != '\0') { // Each string in an F3 subsection should be preceded by a null // character. error(object_error::parse_failed); return; } - StringRef Filename(StringTable.data() + FilenameOffset); + StringRef Filename(CVStringTable.data() + FilenameOffset); ListScope S(W, "FilenameSegment"); W.printString("Filename", Filename); for (unsigned J = 0; J != SegmentLength && DE.isValidOffset(Offset);