[llvm] r254431 - [llvm-dwp] Correctly update debug_str_offsets.dwo when linking dwo files

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 1 10:07:08 PST 2015


Author: dblaikie
Date: Tue Dec  1 12:07:07 2015
New Revision: 254431

URL: http://llvm.org/viewvc/llvm-project?rev=254431&view=rev
Log:
[llvm-dwp] Correctly update debug_str_offsets.dwo when linking dwo files

This doesn't deduplicate strings in the debug_str section, nor does it
properly wire up the index so that debug_info can /find/ these strings,
but it does correct the str_offsets specifically.

Follow up patches to address those related/next issues.

Modified:
    llvm/trunk/test/tools/llvm-dwp/X86/simple.test
    llvm/trunk/tools/llvm-dwp/llvm-dwp.cpp

Modified: llvm/trunk/test/tools/llvm-dwp/X86/simple.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-dwp/X86/simple.test?rev=254431&r1=254430&r2=254431&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-dwp/X86/simple.test (original)
+++ llvm/trunk/test/tools/llvm-dwp/X86/simple.test Tue Dec  1 12:07:07 2015
@@ -47,12 +47,12 @@ CHECK: .debug_str.dwo contents:
 CHECK: "clang version
 CHECK: 0x[[ACPP:.*]]: "a.cpp"
 FIXME: Remove duplicates
-CHECK: "clang version
+CHECK: 0x[[SECONDREV:.*]]: "clang version
 CHECK: 0x[[BCPP:.*]]: "b.cpp"
 
 CHECK: .debug_str_offsets.dwo contents:
 CHECK: : 00000000
 CHECK: : [[ACPP]]
-CHECK: : 00000000
+CHECK: : [[SECONDREV]]
 FIXME: Update str offset indexes, this should be BCPP \/
-CHECK: : [[ACPP]]
+CHECK: : [[BCPP]]

Modified: llvm/trunk/tools/llvm-dwp/llvm-dwp.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dwp/llvm-dwp.cpp?rev=254431&r1=254430&r2=254431&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-dwp/llvm-dwp.cpp (original)
+++ llvm/trunk/tools/llvm-dwp/llvm-dwp.cpp Tue Dec  1 12:07:07 2015
@@ -9,6 +9,7 @@
 #include "llvm/MC/MCSectionELF.h"
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/DataExtractor.h"
 #include "llvm/Support/Options.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -21,6 +22,7 @@
 #include <unordered_set>
 
 using namespace llvm;
+using namespace llvm::object;
 using namespace cl;
 
 OptionCategory DwpCategory("Specific Options");
@@ -36,39 +38,88 @@ static int error(const Twine &Error, con
   return 1;
 }
 
-static std::error_code writeSection(MCStreamer &Out, MCSection *OutSection,
-                                    const object::SectionRef &Sym) {
-  StringRef Contents;
-  if (auto Err = Sym.getContents(Contents))
-    return Err;
-  Out.SwitchSection(OutSection);
-  Out.EmitBytes(Contents);
+static std::error_code
+writeStringsAndOffsets(MCStreamer &Out, StringMap<uint32_t> &Strings,
+                       uint32_t &StringOffset, MCSection *StrOffsetSection,
+                       StringRef CurStrSection, StringRef CurStrOffsetSection) {
+  // Could possibly produce an error or warning if one of these was non-null but
+  // the other was null.
+  if (CurStrSection.empty() || CurStrOffsetSection.empty())
+    return std::error_code();
+
+  DenseMap<uint32_t, uint32_t> OffsetRemapping;
+
+  DataExtractor Data(CurStrSection, true, 0);
+  uint32_t LocalOffset = 0;
+  uint32_t PrevOffset = 0;
+  while (const char *s = Data.getCStr(&LocalOffset)) {
+    StringRef Str(s, LocalOffset - PrevOffset - 1);
+    OffsetRemapping[PrevOffset] = StringOffset;
+    // insert, if successful, write new string to the str.dwo section
+    StringOffset += Str.size() + 1;
+    PrevOffset = LocalOffset;
+  }
+
+  Data = DataExtractor(CurStrOffsetSection, true, 0);
+
+  Out.SwitchSection(StrOffsetSection);
+
+  uint32_t Offset = 0;
+  uint64_t Size = CurStrOffsetSection.size();
+  while (Offset < Size) {
+    auto OldOffset = Data.getU32(&Offset);
+    auto NewOffset = OffsetRemapping[OldOffset];
+    Out.EmitIntValue(NewOffset, 4);
+  }
+
   return std::error_code();
 }
 
 static std::error_code write(MCStreamer &Out, ArrayRef<std::string> Inputs) {
+  const auto &MCOFI = *Out.getContext().getObjectFileInfo();
+  MCSection *const StrSection = MCOFI.getDwarfStrDWOSection();
+  MCSection *const StrOffsetSection = MCOFI.getDwarfStrOffDWOSection();
+  const StringMap<MCSection *> KnownSections = {
+      {"debug_info.dwo", MCOFI.getDwarfInfoDWOSection()},
+      {"debug_types.dwo", MCOFI.getDwarfTypesDWOSection()},
+      {"debug_str_offsets.dwo", StrOffsetSection},
+      {"debug_str.dwo", StrSection},
+      {"debug_loc.dwo", MCOFI.getDwarfLocDWOSection()},
+      {"debug_abbrev.dwo", MCOFI.getDwarfAbbrevDWOSection()}};
+
+  StringMap<uint32_t> Strings;
+  uint32_t StringOffset = 0;
+
   for (const auto &Input : Inputs) {
     auto ErrOrObj = object::ObjectFile::createObjectFile(Input);
     if (!ErrOrObj)
       return ErrOrObj.getError();
     const auto *Obj = ErrOrObj->getBinary();
+    StringRef CurStrSection;
+    StringRef CurStrOffsetSection;
     for (const auto &Section : Obj->sections()) {
-      const auto &MCOFI = *Out.getContext().getObjectFileInfo();
-      static const StringMap<MCSection *> KnownSections = {
-          {"debug_info.dwo", MCOFI.getDwarfInfoDWOSection()},
-          {"debug_types.dwo", MCOFI.getDwarfTypesDWOSection()},
-          {"debug_str_offsets.dwo", MCOFI.getDwarfStrOffDWOSection()},
-          {"debug_str.dwo", MCOFI.getDwarfStrDWOSection()},
-          {"debug_loc.dwo", MCOFI.getDwarfLocDWOSection()},
-          {"debug_abbrev.dwo", MCOFI.getDwarfAbbrevDWOSection()}};
       StringRef Name;
       if (std::error_code Err = Section.getName(Name))
         return Err;
       if (MCSection *OutSection =
-              KnownSections.lookup(Name.substr(Name.find_first_not_of("._"))))
-        if (auto Err = writeSection(Out, OutSection, Section))
+              KnownSections.lookup(Name.substr(Name.find_first_not_of("._")))) {
+        StringRef Contents;
+        if (auto Err = Section.getContents(Contents))
           return Err;
+        if (OutSection == StrOffsetSection) {
+          CurStrOffsetSection = Contents;
+          continue;
+        }
+        if (OutSection == StrSection)
+          CurStrSection = Contents;
+        Out.SwitchSection(OutSection);
+        Out.EmitBytes(Contents);
+      }
     }
+    if (auto Err =
+            writeStringsAndOffsets(Out, Strings, StringOffset, StrOffsetSection,
+                                   CurStrSection, CurStrOffsetSection))
+      return Err;
   }
   return std::error_code();
 }




More information about the llvm-commits mailing list