llvm-dwp: Include the dwo name (if available) when diagnosing duplicate CU IDs from...
authorDavid Blaikie <dblaikie@gmail.com>
Sat, 26 Mar 2016 20:32:14 +0000 (20:32 +0000)
committerDavid Blaikie <dblaikie@gmail.com>
Sat, 26 Mar 2016 20:32:14 +0000 (20:32 +0000)
If you're building dwps from other dwps, it can be hard to track down a
duplicate CU ID if it comes from two compilations of the same file in
different modes, etc. By including the .dwo path (which is hopefully
more unique than the file path) it can help track down where the
duplicates came from.

llvm-svn: 264520

llvm/test/tools/llvm-dwp/Inputs/duplicate_dwo_name/ac.dwp [new file with mode: 0644]
llvm/test/tools/llvm-dwp/Inputs/duplicate_dwo_name/bc.dwp [new file with mode: 0644]
llvm/test/tools/llvm-dwp/Inputs/duplicate_dwo_name/c.dwo [new file with mode: 0644]
llvm/test/tools/llvm-dwp/X86/duplicate.test
llvm/tools/llvm-dwp/llvm-dwp.cpp

diff --git a/llvm/test/tools/llvm-dwp/Inputs/duplicate_dwo_name/ac.dwp b/llvm/test/tools/llvm-dwp/Inputs/duplicate_dwo_name/ac.dwp
new file mode 100644 (file)
index 0000000..c154122
Binary files /dev/null and b/llvm/test/tools/llvm-dwp/Inputs/duplicate_dwo_name/ac.dwp differ
diff --git a/llvm/test/tools/llvm-dwp/Inputs/duplicate_dwo_name/bc.dwp b/llvm/test/tools/llvm-dwp/Inputs/duplicate_dwo_name/bc.dwp
new file mode 100644 (file)
index 0000000..674f6fa
Binary files /dev/null and b/llvm/test/tools/llvm-dwp/Inputs/duplicate_dwo_name/bc.dwp differ
diff --git a/llvm/test/tools/llvm-dwp/Inputs/duplicate_dwo_name/c.dwo b/llvm/test/tools/llvm-dwp/Inputs/duplicate_dwo_name/c.dwo
new file mode 100644 (file)
index 0000000..9fa811d
Binary files /dev/null and b/llvm/test/tools/llvm-dwp/Inputs/duplicate_dwo_name/c.dwo differ
index 1330cf3..67b6829 100644 (file)
@@ -1,18 +1,27 @@
 RUN: not llvm-dwp %p/../Inputs/duplicate/c.dwo %p/../Inputs/duplicate/c.dwo -o %t 2>&1 \
-RUN:   | FileCheck --check-prefix=CHECK %s
+RUN:   | FileCheck --check-prefix=DWOS %s
 
 RUN: not llvm-dwp %p/../Inputs/duplicate/c.dwo %p/../Inputs/duplicate/bc.dwp -o %t 2>&1 \
-RUN:   | FileCheck --check-prefix=CHECK --check-prefix=DWP2 %s
+RUN:   | FileCheck --check-prefix=2DWP %s
 
 RUN: not llvm-dwp %p/../Inputs/duplicate/ac.dwp %p/../Inputs/duplicate/c.dwo -o %t 2>&1 \
-RUN:   | FileCheck --check-prefix=CHECK --check-prefix=DWP1 %s
+RUN:   | FileCheck --check-prefix=1DWP %s
 
-RUN: not llvm-dwp %p/../Inputs/duplicate/ac.dwp %p/../Inputs/duplicate/bc.dwp -o %t 2>&1 \
-RUN:   | FileCheck --check-prefix=CHECK --check-prefix=DWP1 --check-prefix=DWP2 %s
+RUN: not llvm-dwp %p/../Inputs/duplicate_dwo_name/c.dwo %p/../Inputs/duplicate_dwo_name/c.dwo -o %t 2>&1 \
+RUN:   | FileCheck --check-prefix=DWODWOS %s
+
+RUN: not llvm-dwp %p/../Inputs/duplicate_dwo_name/c.dwo %p/../Inputs/duplicate_dwo_name/bc.dwp -o %t 2>&1 \
+RUN:   | FileCheck --check-prefix=DWO2DWP %s
+
+RUN: not llvm-dwp %p/../Inputs/duplicate_dwo_name/ac.dwp %p/../Inputs/duplicate_dwo_name/c.dwo -o %t 2>&1 \
+RUN:   | FileCheck --check-prefix=DWO1DWP %s
 
 Build from a, b, and c.c all containing a single void() func by the name of the file.
 
-CHECK: Duplicate DWO ID ({{.*}}) in 'c.c'
-DWP1-SAME: (from '{{.*}}ac.dwp')
-CHECK-SAME: and 'c.c'
-DWP2-SAME: (from '{{.*}}bc.dwp')
+DWOS: Duplicate DWO ID ({{.*}}) in 'c.c' and 'c.c'{{$}}
+1DWP: Duplicate DWO ID ({{.*}}) in 'c.c' (from '{{.*}}ac.dwp') and 'c.c'{{$}}
+2DWP: Duplicate DWO ID ({{.*}}) in 'c.c' and 'c.c' (from '{{.*}}bc.dwp'){{$}}
+
+DWODWOS: Duplicate DWO ID ({{.*}}) in 'c.c' and 'c.c'{{$}}
+DWO1DWP: Duplicate DWO ID ({{.*}}) in 'c.c' (from 'c.dwo' in '{{.*}}ac.dwp') and 'c.c'{{$}}
+DWO2DWP: Duplicate DWO ID ({{.*}}) in 'c.c' and 'c.c' (from 'c.dwo' in '{{.*}}bc.dwp'){{$}}
index 70bad75..9fa22dc 100644 (file)
@@ -122,10 +122,19 @@ static uint32_t getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode) {
 
 struct CompileUnitIdentifiers {
   uint64_t Signature = 0;
-  const char *Name = nullptr;
-  const char *DWOName = nullptr;
+  const char *Name = "";
+  const char *DWOName = "";
 };
 
+static const char *getIndexedString(uint32_t StrIndex, StringRef StrOffsets,
+                                    StringRef Str) {
+  DataExtractor StrOffsetsData(StrOffsets, true, 0);
+  uint32_t StrOffsetsOffset = 4 * StrIndex;
+  uint32_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset);
+  DataExtractor StrData(Str, true, 0);
+  return StrData.getCStr(&StrOffset);
+}
+
 static CompileUnitIdentifiers getCUIdentifiers(StringRef Abbrev, StringRef Info,
                                                StringRef StrOffsets,
                                                StringRef Str) {
@@ -154,13 +163,12 @@ static CompileUnitIdentifiers getCUIdentifiers(StringRef Abbrev, StringRef Info,
          (Name != 0 || Form != 0)) {
     switch (Name) {
     case dwarf::DW_AT_name: {
-      auto StrIndex = InfoData.getULEB128(&Offset);
-
-      DataExtractor StrOffsetsData(StrOffsets, true, 0);
-      uint32_t StrOffsetsOffset = 4 * StrIndex;
-      uint32_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset);
-      DataExtractor StrData(Str, true, 0);
-      ID.Name = StrData.getCStr(&StrOffset);
+      ID.Name = getIndexedString(InfoData.getULEB128(&Offset), StrOffsets, Str);
+      break;
+    }
+    case dwarf::DW_AT_GNU_dwo_name: {
+      ID.DWOName =
+          getIndexedString(InfoData.getULEB128(&Offset), StrOffsets, Str);
       break;
     }
     case dwarf::DW_AT_GNU_dwo_id:
@@ -176,6 +184,7 @@ static CompileUnitIdentifiers getCUIdentifiers(StringRef Abbrev, StringRef Info,
 struct UnitIndexEntry {
   DWARFUnitIndex::Entry::SectionContribution Contributions[8];
   std::string Name;
+  std::string DWOName;
   StringRef DWPName;
 };
 
@@ -331,6 +340,25 @@ static bool consumeCompressedDebugSectionHeader(StringRef &data,
   return true;
 }
 
+void printDuplicateError(const std::pair<uint64_t, UnitIndexEntry> &PrevE,
+                         const CompileUnitIdentifiers &ID, StringRef DWPName) {
+  errs() << "Duplicate DWO ID (" << PrevE.first << ") in '" << PrevE.second.Name
+         << '\'';
+  if (!PrevE.second.DWPName.empty()) {
+    errs() << " (from ";
+    if (!PrevE.second.DWOName.empty())
+      errs() << '\'' << PrevE.second.DWOName << "' in ";
+    errs() << "'" << PrevE.second.DWPName.str() << "')";
+  }
+  errs() << " and '" << ID.Name << '\'';
+  if (!DWPName.empty()) {
+    errs() << " (from ";
+    if (*ID.DWOName)
+      errs() << '\'' << ID.DWOName << "\' in ";
+    errs() << '\'' << DWPName << "')";
+  }
+  errs() << '\n';
+}
 static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
   const auto &MCOFI = *Out.getContext().getObjectFileInfo();
   MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
@@ -468,15 +496,12 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
             getSubsection(CurStrOffsetSection, E, DW_SECT_STR_OFFSETS),
             CurStrSection);
         if (!P.second) {
-          auto &PrevE = *P.first;
-          std::cerr << "Duplicate DWO ID (" << PrevE.first << ") in '" << PrevE.second.Name << "' ";
-          if (!PrevE.second.DWPName.empty())
-            std::cerr << "(from '" << PrevE.second.DWPName.str() << "') ";
-          std::cerr << "and '" << ID.Name << "' (from '" << Input << "')\n";
+          printDuplicateError(*P.first, ID, Input);
           return make_error_code(std::errc::invalid_argument);
         }
         auto &NewEntry = P.first->second;
         NewEntry.Name = ID.Name;
+        NewEntry.DWOName = ID.DWOName;
         NewEntry.DWPName = Input;
         for (auto Kind : CUIndex.getColumnKinds()) {
           auto &C = NewEntry.Contributions[Kind - DW_SECT_INFO];
@@ -503,15 +528,11 @@ static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
           AbbrevSection, InfoSection, CurStrOffsetSection, CurStrSection);
       auto P = IndexEntries.insert(std::make_pair(ID.Signature, CurEntry));
       if (!P.second) {
-        auto &E = *P.first;
-        std::cerr << "Duplicate DWO ID (" << E.first << ") in '" << ID.Name
-                  << "' ";
-        if (!E.second.DWPName.empty())
-          std::cerr << "(from '" << E.second.DWPName.str() << "') ";
-        std::cerr << "and '" << E.second.Name << "'\n";
+        printDuplicateError(*P.first, ID, "");
         return make_error_code(std::errc::invalid_argument);
       }
       P.first->second.Name = ID.Name;
+      P.first->second.DWOName = ID.DWOName;
       addAllTypes(Out, TypeIndexEntries, TypesSection, CurTypesSection,
                   CurEntry, ContributionOffsets[DW_SECT_TYPES - DW_SECT_INFO]);
     }