[llvm] r317350 - [llvm-objcopy] Add support for dwarf fission

Jake Ehrlich via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 3 11:58:41 PDT 2017


Author: jakehehrlich
Date: Fri Nov  3 11:58:41 2017
New Revision: 317350

URL: http://llvm.org/viewvc/llvm-project?rev=317350&view=rev
Log:
[llvm-objcopy] Add support for dwarf fission

This change adds support for dwarf fission.

Differential Revision: https://reviews.llvm.org/D39207

Added:
    llvm/trunk/test/tools/llvm-objcopy/Inputs/dwarf.dwo
    llvm/trunk/test/tools/llvm-objcopy/drawf-fission.test
Modified:
    llvm/trunk/tools/llvm-objcopy/Object.h
    llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp

Added: llvm/trunk/test/tools/llvm-objcopy/Inputs/dwarf.dwo
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/Inputs/dwarf.dwo?rev=317350&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/llvm-objcopy/Inputs/dwarf.dwo (added) and llvm/trunk/test/tools/llvm-objcopy/Inputs/dwarf.dwo Fri Nov  3 11:58:41 2017 differ

Added: llvm/trunk/test/tools/llvm-objcopy/drawf-fission.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/drawf-fission.test?rev=317350&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/drawf-fission.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/drawf-fission.test Fri Nov  3 11:58:41 2017
@@ -0,0 +1,43 @@
+# RUN: llvm-objcopy -extract-dwo %p/Inputs/dwarf.dwo %t
+# RUN: llvm-objcopy -strip-dwo %p/Inputs/dwarf.dwo %t2
+# RUN: llvm-objcopy -split-dwo=%t3 %p/Inputs/dwarf.dwo %t4
+# RUN: llvm-readobj -file-headers -sections %t | FileCheck %s -check-prefix=DWARF
+# RUN: llvm-readobj -file-headers -sections %t2 | FileCheck %s -check-prefix=STRIP
+# RUN: diff %t %t3
+# RUN: diff %t2 %t4
+
+#DWARF:     SectionHeaderCount: 8
+
+#DWARF:     Name: .debug_loc.dwo
+#DWARF:     Name: .debug_str.dwo
+#DWARF:     Name: .debug_str_offsets.dwo
+#DWARF:     Name: .debug_info.dwo
+#DWARF:     Name: .debug_abbrev.dwo
+#DWARF:     Name: .debug_line.dwo
+#DWARF:     Name: .strtab
+
+#STRIP:     SectionHeaderCount: 24
+
+#STRIP:    Name: .text
+#STRIP:    Name: .rodata.str1.1
+#STRIP:    Name: .debug_str
+#STRIP:    Name: .debug_abbrev
+#STRIP:    Name: .debug_info
+#STRIP:    Name: .debug_ranges
+#STRIP:    Name: .debug_macinfo
+#STRIP:    Name: .debug_addr
+#STRIP:    Name: .debug_pubnames
+#STRIP:    Name: .debug_pubtypes
+#STRIP:    Name: .comment
+#STRIP:    Name: .note.GNU-stack
+#STRIP:    Name: .debug_frame
+#STRIP:    Name: .debug_line
+#STRIP:    Name: .symtab
+#STRIP:    Name: .rela.text
+#STRIP:    Name: .rela.debug_info
+#STRIP:    Name: .rela.debug_addr
+#STRIP:    Name: .rela.debug_pubnames
+#STRIP:    Name: .rela.debug_pubtypes
+#STRIP:    Name: .rela.debug_frame
+#STRIP:    Name: .rela.debug_line
+#STRIP:    Name: .strtab

Modified: llvm/trunk/tools/llvm-objcopy/Object.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.h?rev=317350&r1=317349&r2=317350&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Object.h (original)
+++ llvm/trunk/tools/llvm-objcopy/Object.h Fri Nov  3 11:58:41 2017
@@ -368,6 +368,7 @@ public:
   Object(const object::ELFObjectFile<ELFT> &Obj);
   virtual ~Object() = default;
 
+  const SectionBase *getSectionHeaderStrTab() const { return SectionNames; }
   void removeSections(std::function<bool(const SectionBase &)> ToRemove);
   virtual size_t totalSize() const = 0;
   virtual void finalize() = 0;

Modified: llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp?rev=317350&r1=317349&r2=317350&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp Fri Nov  3 11:58:41 2017
@@ -83,12 +83,63 @@ static cl::alias ToRemoveA("R", cl::desc
                            cl::aliasopt(ToRemove));
 static cl::opt<bool> StripSections("strip-sections",
                                    cl::desc("Remove all section headers"));
+static cl::opt<bool>
+    StripDWO("strip-dwo", cl::desc("remove all DWARF .dwo sections from file"));
+static cl::opt<bool> ExtractDWO(
+    "extract-dwo",
+    cl::desc("remove all sections that are not DWARF .dwo sections from file"));
+static cl::opt<std::string>
+    SplitDWO("split-dwo",
+             cl::desc("equivalent to extract-dwo on the input file to "
+                      "<dwo-file>, then strip-dwo on the input file"),
+             cl::value_desc("dwo-file"));
 
 using SectionPred = std::function<bool(const SectionBase &Sec)>;
 
-void CopyBinary(const ELFObjectFile<ELF64LE> &ObjFile) {
+bool IsDWOSection(const SectionBase &Sec) {
+  return Sec.Name.endswith(".dwo");
+}
+
+template <class ELFT>
+bool OnlyKeepDWOPred(const Object<ELFT> &Obj, const SectionBase &Sec) {
+  // We can't remove the section header string table.
+  if (&Sec == Obj.getSectionHeaderStrTab())
+    return false;
+  // Short of keeping the string table we want to keep everything that is a DWO
+  // section and remove everything else.
+  return !IsDWOSection(Sec);
+}
+
+template <class ELFT>
+void WriteObjectFile(const Object<ELFT> &Obj, StringRef File) {
   std::unique_ptr<FileOutputBuffer> Buffer;
+  ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
+      FileOutputBuffer::create(File, Obj.totalSize(),
+                               FileOutputBuffer::F_executable);
+  if (BufferOrErr.getError())
+    error("failed to open " + OutputFilename);
+  else
+    Buffer = std::move(*BufferOrErr);
+  Obj.write(*Buffer);
+  if (auto EC = Buffer->commit())
+    reportError(File, EC);
+}
+
+template <class ELFT>
+void SplitDWOToFile(const ELFObjectFile<ELFT> &ObjFile, StringRef File) {
+  // Construct a second output file for the DWO sections.
+  ELFObject<ELFT> DWOFile(ObjFile);
+
+  DWOFile.removeSections([&](const SectionBase &Sec) {
+    return OnlyKeepDWOPred<ELFT>(DWOFile, Sec);
+  });
+  DWOFile.finalize();
+  WriteObjectFile(DWOFile, File);
+}
+
+void CopyBinary(const ELFObjectFile<ELF64LE> &ObjFile) {
   std::unique_ptr<Object<ELF64LE>> Obj;
+
   if (!OutputFormat.empty() && OutputFormat != "binary")
     error("invalid output format '" + OutputFormat + "'");
   if (!OutputFormat.empty() && OutputFormat == "binary")
@@ -96,6 +147,9 @@ void CopyBinary(const ELFObjectFile<ELF6
   else
     Obj = llvm::make_unique<ELFObject<ELF64LE>>(ObjFile);
 
+  if (!SplitDWO.empty())
+    SplitDWOToFile<ELF64LE>(ObjFile, SplitDWO.getValue());
+
   SectionPred RemovePred = [](const SectionBase &) { return false; };
 
   if (!ToRemove.empty()) {
@@ -105,6 +159,16 @@ void CopyBinary(const ELFObjectFile<ELF6
     };
   }
 
+  if (StripDWO || !SplitDWO.empty())
+    RemovePred = [RemovePred, &Obj](const SectionBase &Sec) {
+      return IsDWOSection(Sec) || RemovePred(Sec);
+    };
+
+  if (ExtractDWO)
+    RemovePred = [RemovePred, &Obj](const SectionBase &Sec) {
+      return OnlyKeepDWOPred(*Obj, Sec) || RemovePred(Sec);
+    };
+
   if (StripSections) {
     RemovePred = [RemovePred](const SectionBase &Sec) {
       return RemovePred(Sec) || (Sec.Flags & SHF_ALLOC) == 0;
@@ -113,21 +177,8 @@ void CopyBinary(const ELFObjectFile<ELF6
   }
 
   Obj->removeSections(RemovePred);
-
   Obj->finalize();
-  ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
-      FileOutputBuffer::create(OutputFilename, Obj->totalSize(),
-                               FileOutputBuffer::F_executable);
-  if (BufferOrErr.getError())
-    error("failed to open " + OutputFilename);
-  else
-    Buffer = std::move(*BufferOrErr);
-  std::error_code EC;
-  if (EC)
-    report_fatal_error(EC.message());
-  Obj->write(*Buffer);
-  if (auto EC = Buffer->commit())
-    reportError(OutputFilename, EC);
+  WriteObjectFile(*Obj, OutputFilename.getValue());
 }
 
 int main(int argc, char **argv) {




More information about the llvm-commits mailing list