[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