[llvm] 0373c76 - [llvm-objcopy][NFC] refactor error handling. part 3.

Alexey Lapshin via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 2 13:56:45 PDT 2020


Author: Alexey Lapshin
Date: 2020-10-02T23:55:05+03:00
New Revision: 0373c768c56fc7ce6fe1efa48383f7b376e7bc2a

URL: https://github.com/llvm/llvm-project/commit/0373c768c56fc7ce6fe1efa48383f7b376e7bc2a
DIFF: https://github.com/llvm/llvm-project/commit/0373c768c56fc7ce6fe1efa48383f7b376e7bc2a.diff

LOG: [llvm-objcopy][NFC] refactor error handling. part 3.

Remove usages of special error reporting functions(error(),
reportError()). Errors are reported as Expected<>/Error returning
values. This part is for ELF subfolder of llvm-objcopy.

Testing: check-all.

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

Added: 
    

Modified: 
    llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
    llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
    llvm/tools/llvm-objcopy/ELF/Object.cpp
    llvm/tools/llvm-objcopy/ELF/Object.h
    llvm/tools/llvm-objcopy/MachO/MachOReader.cpp
    llvm/tools/llvm-objcopy/MachO/Object.cpp
    llvm/tools/llvm-objcopy/llvm-objcopy.cpp
    llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp

Removed: 
    llvm/tools/llvm-objcopy/llvm-objcopy.h


################################################################################
diff  --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
index 94325c5f63a2..b5de8a45a80f 100644
--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
@@ -12,7 +12,6 @@
 #include "Object.h"
 #include "Reader.h"
 #include "Writer.h"
-#include "llvm-objcopy.h"
 
 #include "llvm/Object/Binary.h"
 #include "llvm/Object/COFF.h"

diff  --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
index 66953f9ef0d5..5a34153647cc 100644
--- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
@@ -10,7 +10,6 @@
 #include "Buffer.h"
 #include "CopyConfig.h"
 #include "Object.h"
-#include "llvm-objcopy.h"
 #include "llvm/ADT/BitmaskEnum.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/Optional.h"
@@ -266,19 +265,23 @@ static Error linkToBuildIdDir(const CopyConfig &Config, StringRef ToLink,
 
 static Error splitDWOToFile(const CopyConfig &Config, const Reader &Reader,
                             StringRef File, ElfType OutputElfType) {
-  auto DWOFile = Reader.create(false);
+  Expected<std::unique_ptr<Object>> DWOFile = Reader.create(false);
+  if (!DWOFile)
+    return DWOFile.takeError();
+
   auto OnlyKeepDWOPred = [&DWOFile](const SectionBase &Sec) {
-    return onlyKeepDWOPred(*DWOFile, Sec);
+    return onlyKeepDWOPred(**DWOFile, Sec);
   };
-  if (Error E = DWOFile->removeSections(Config.AllowBrokenLinks,
-                                        OnlyKeepDWOPred))
+  if (Error E =
+          (*DWOFile)->removeSections(Config.AllowBrokenLinks, OnlyKeepDWOPred))
     return E;
   if (Config.OutputArch) {
-    DWOFile->Machine = Config.OutputArch.getValue().EMachine;
-    DWOFile->OSABI = Config.OutputArch.getValue().OSABI;
+    (*DWOFile)->Machine = Config.OutputArch.getValue().EMachine;
+    (*DWOFile)->OSABI = Config.OutputArch.getValue().OSABI;
   }
   FileBuffer FB(File);
-  auto Writer = createWriter(Config, *DWOFile, FB, OutputElfType);
+  std::unique_ptr<Writer> Writer =
+      createWriter(Config, **DWOFile, FB, OutputElfType);
   if (Error E = Writer->finalize())
     return E;
   return Writer->write();
@@ -313,12 +316,12 @@ static bool isCompressable(const SectionBase &Sec) {
          StringRef(Sec.Name).startswith(".debug");
 }
 
-static void replaceDebugSections(
+static Error replaceDebugSections(
     Object &Obj, SectionPred &RemovePred,
     function_ref<bool(const SectionBase &)> shouldReplace,
-    function_ref<SectionBase *(const SectionBase *)> addSection) {
+    function_ref<Expected<SectionBase *>(const SectionBase *)> addSection) {
   // Build a list of the debug sections we are going to replace.
-  // We can't call `addSection` while iterating over sections,
+  // We can't call `AddSection` while iterating over sections,
   // because it would mutate the sections array.
   SmallVector<SectionBase *, 13> ToReplace;
   for (auto &Sec : Obj.sections())
@@ -327,8 +330,13 @@ static void replaceDebugSections(
 
   // Build a mapping from original section to a new one.
   DenseMap<SectionBase *, SectionBase *> FromTo;
-  for (SectionBase *S : ToReplace)
-    FromTo[S] = addSection(S);
+  for (SectionBase *S : ToReplace) {
+    Expected<SectionBase *> NewSection = addSection(S);
+    if (!NewSection)
+      return NewSection.takeError();
+
+    FromTo[S] = *NewSection;
+  }
 
   // Now we want to update the target sections of relocation
   // sections. Also we will update the relocations themselves
@@ -339,6 +347,8 @@ static void replaceDebugSections(
   RemovePred = [shouldReplace, RemovePred](const SectionBase &Sec) {
     return shouldReplace(Sec) || RemovePred(Sec);
   };
+
+  return Error::success();
 }
 
 static bool isUnneededSymbol(const Symbol &Sym) {
@@ -577,20 +587,28 @@ static Error replaceAndRemoveSections(const CopyConfig &Config, Object &Obj) {
     };
   }
 
-  if (Config.CompressionType != DebugCompressionType::None)
-    replaceDebugSections(Obj, RemovePred, isCompressable,
-                         [&Config, &Obj](const SectionBase *S) {
-                           return &Obj.addSection<CompressedSection>(
-                                *S, Config.CompressionType);
-                         });
-  else if (Config.DecompressDebugSections)
-    replaceDebugSections(
-        Obj, RemovePred,
-        [](const SectionBase &S) { return isa<CompressedSection>(&S); },
-        [&Obj](const SectionBase *S) {
-          auto CS = cast<CompressedSection>(S);
-          return &Obj.addSection<DecompressedSection>(*CS);
-        });
+  if (Config.CompressionType != DebugCompressionType::None) {
+    if (Error Err = replaceDebugSections(
+            Obj, RemovePred, isCompressable,
+            [&Config, &Obj](const SectionBase *S) -> Expected<SectionBase *> {
+              Expected<CompressedSection> NewSection =
+                  CompressedSection::create(*S, Config.CompressionType);
+              if (!NewSection)
+                return NewSection.takeError();
+
+              return &Obj.addSection<CompressedSection>(std::move(*NewSection));
+            }))
+      return Err;
+  } else if (Config.DecompressDebugSections) {
+    if (Error Err = replaceDebugSections(
+            Obj, RemovePred,
+            [](const SectionBase &S) { return isa<CompressedSection>(&S); },
+            [&Obj](const SectionBase *S) {
+              const CompressedSection *CS = cast<CompressedSection>(S);
+              return &Obj.addSection<DecompressedSection>(*CS);
+            }))
+      return Err;
+  }
 
   return Obj.removeSections(Config.AllowBrokenLinks, RemovePred);
 }
@@ -740,9 +758,9 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj,
 
   // If the symbol table was previously removed, we need to create a new one
   // before adding new symbols.
-  if (!Obj.SymbolTable && !Config.ELF->SymbolsToAdd.empty()) {
-    Obj.addNewSymbolTable();
-  }
+  if (!Obj.SymbolTable && !Config.ELF->SymbolsToAdd.empty())
+    if (Error E = Obj.addNewSymbolTable())
+      return E;
 
   for (const NewSymbolInfo &SI : Config.ELF->SymbolsToAdd) {
     SectionBase *Sec = Obj.findSection(SI.SectionName);
@@ -769,12 +787,15 @@ static Error writeOutput(const CopyConfig &Config, Object &Obj, Buffer &Out,
 Error executeObjcopyOnIHex(const CopyConfig &Config, MemoryBuffer &In,
                            Buffer &Out) {
   IHexReader Reader(&In);
-  std::unique_ptr<Object> Obj = Reader.create(true);
+  Expected<std::unique_ptr<Object>> Obj = Reader.create(true);
+  if (!Obj)
+    return Obj.takeError();
+
   const ElfType OutputElfType =
     getOutputElfType(Config.OutputArch.getValueOr(MachineInfo()));
-  if (Error E = handleArgs(Config, *Obj, Reader, OutputElfType))
+  if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
     return E;
-  return writeOutput(Config, *Obj, Out, OutputElfType);
+  return writeOutput(Config, **Obj, Out, OutputElfType);
 }
 
 Error executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In,
@@ -782,21 +803,26 @@ Error executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In,
   uint8_t NewSymbolVisibility =
       Config.ELF->NewSymbolVisibility.getValueOr((uint8_t)ELF::STV_DEFAULT);
   BinaryReader Reader(&In, NewSymbolVisibility);
-  std::unique_ptr<Object> Obj = Reader.create(true);
+  Expected<std::unique_ptr<Object>> Obj = Reader.create(true);
+  if (!Obj)
+    return Obj.takeError();
 
   // Prefer OutputArch (-O<format>) if set, otherwise fallback to BinaryArch
   // (-B<arch>).
   const ElfType OutputElfType =
       getOutputElfType(Config.OutputArch.getValueOr(MachineInfo()));
-  if (Error E = handleArgs(Config, *Obj, Reader, OutputElfType))
+  if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
     return E;
-  return writeOutput(Config, *Obj, Out, OutputElfType);
+  return writeOutput(Config, **Obj, Out, OutputElfType);
 }
 
 Error executeObjcopyOnBinary(const CopyConfig &Config,
                              object::ELFObjectFileBase &In, Buffer &Out) {
   ELFReader Reader(&In, Config.ExtractPartition);
-  std::unique_ptr<Object> Obj = Reader.create(!Config.SymbolsToAdd.empty());
+  Expected<std::unique_ptr<Object>> Obj =
+      Reader.create(!Config.SymbolsToAdd.empty());
+  if (!Obj)
+    return Obj.takeError();
   // Prefer OutputArch (-O<format>) if set, otherwise infer it from the input.
   const ElfType OutputElfType =
       Config.OutputArch ? getOutputElfType(Config.OutputArch.getValue())
@@ -822,10 +848,10 @@ Error executeObjcopyOnBinary(const CopyConfig &Config,
                              Config.BuildIdLinkInput.getValue(), BuildIdBytes))
       return E;
 
-  if (Error E = handleArgs(Config, *Obj, Reader, OutputElfType))
+  if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
     return createFileError(Config.InputFilename, std::move(E));
 
-  if (Error E = writeOutput(Config, *Obj, Out, OutputElfType))
+  if (Error E = writeOutput(Config, **Obj, Out, OutputElfType))
     return createFileError(Config.InputFilename, std::move(E));
   if (!Config.BuildIdLinkDir.empty() && Config.BuildIdLinkOutput)
     if (Error E =

diff  --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp
index e19285ee97ea..5eadb5c683bd 100644
--- a/llvm/tools/llvm-objcopy/ELF/Object.cpp
+++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp
@@ -7,7 +7,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "Object.h"
-#include "llvm-objcopy.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
@@ -15,6 +14,7 @@
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/BinaryFormat/ELF.h"
 #include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Object/ELF.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Support/Compression.h"
 #include "llvm/Support/Endian.h"
@@ -60,7 +60,7 @@ Error SectionBase::removeSymbols(function_ref<bool(const Symbol &)> ToRemove) {
   return Error::success();
 }
 
-void SectionBase::initialize(SectionTableRef SecTable) {}
+Error SectionBase::initialize(SectionTableRef) { return Error::success(); }
 void SectionBase::finalize() {}
 void SectionBase::markSymbols() {}
 void SectionBase::replaceSectionReferences(
@@ -82,72 +82,98 @@ template <class ELFT> void ELFWriter<ELFT>::writeShdr(const SectionBase &Sec) {
   Shdr.sh_entsize = Sec.EntrySize;
 }
 
-template <class ELFT> void ELFSectionSizer<ELFT>::visit(Section &Sec) {}
+template <class ELFT> Error ELFSectionSizer<ELFT>::visit(Section &) {
+  return Error::success();
+}
 
-template <class ELFT>
-void ELFSectionSizer<ELFT>::visit(OwnedDataSection &Sec) {}
+template <class ELFT> Error ELFSectionSizer<ELFT>::visit(OwnedDataSection &) {
+  return Error::success();
+}
 
-template <class ELFT>
-void ELFSectionSizer<ELFT>::visit(StringTableSection &Sec) {}
+template <class ELFT> Error ELFSectionSizer<ELFT>::visit(StringTableSection &) {
+  return Error::success();
+}
 
 template <class ELFT>
-void ELFSectionSizer<ELFT>::visit(DynamicRelocationSection &Sec) {}
+Error ELFSectionSizer<ELFT>::visit(DynamicRelocationSection &) {
+  return Error::success();
+}
 
 template <class ELFT>
-void ELFSectionSizer<ELFT>::visit(SymbolTableSection &Sec) {
+Error ELFSectionSizer<ELFT>::visit(SymbolTableSection &Sec) {
   Sec.EntrySize = sizeof(Elf_Sym);
   Sec.Size = Sec.Symbols.size() * Sec.EntrySize;
   // Align to the largest field in Elf_Sym.
   Sec.Align = ELFT::Is64Bits ? sizeof(Elf_Xword) : sizeof(Elf_Word);
+  return Error::success();
 }
 
 template <class ELFT>
-void ELFSectionSizer<ELFT>::visit(RelocationSection &Sec) {
+Error ELFSectionSizer<ELFT>::visit(RelocationSection &Sec) {
   Sec.EntrySize = Sec.Type == SHT_REL ? sizeof(Elf_Rel) : sizeof(Elf_Rela);
   Sec.Size = Sec.Relocations.size() * Sec.EntrySize;
   // Align to the largest field in Elf_Rel(a).
   Sec.Align = ELFT::Is64Bits ? sizeof(Elf_Xword) : sizeof(Elf_Word);
+  return Error::success();
 }
 
 template <class ELFT>
-void ELFSectionSizer<ELFT>::visit(GnuDebugLinkSection &Sec) {}
+Error ELFSectionSizer<ELFT>::visit(GnuDebugLinkSection &) {
+  return Error::success();
+}
 
-template <class ELFT> void ELFSectionSizer<ELFT>::visit(GroupSection &Sec) {
+template <class ELFT> Error ELFSectionSizer<ELFT>::visit(GroupSection &Sec) {
   Sec.Size = sizeof(Elf_Word) + Sec.GroupMembers.size() * sizeof(Elf_Word);
+  return Error::success();
 }
 
 template <class ELFT>
-void ELFSectionSizer<ELFT>::visit(SectionIndexSection &Sec) {}
+Error ELFSectionSizer<ELFT>::visit(SectionIndexSection &) {
+  return Error::success();
+}
 
-template <class ELFT>
-void ELFSectionSizer<ELFT>::visit(CompressedSection &Sec) {}
+template <class ELFT> Error ELFSectionSizer<ELFT>::visit(CompressedSection &) {
+  return Error::success();
+}
 
 template <class ELFT>
-void ELFSectionSizer<ELFT>::visit(DecompressedSection &Sec) {}
+Error ELFSectionSizer<ELFT>::visit(DecompressedSection &) {
+  return Error::success();
+}
 
-void BinarySectionWriter::visit(const SectionIndexSection &Sec) {
-  error("cannot write symbol section index table '" + Sec.Name + "' ");
+Error BinarySectionWriter::visit(const SectionIndexSection &Sec) {
+  return createStringError(errc::operation_not_permitted,
+                           "cannot write symbol section index table '" +
+                               Sec.Name + "' ");
 }
 
-void BinarySectionWriter::visit(const SymbolTableSection &Sec) {
-  error("cannot write symbol table '" + Sec.Name + "' out to binary");
+Error BinarySectionWriter::visit(const SymbolTableSection &Sec) {
+  return createStringError(errc::operation_not_permitted,
+                           "cannot write symbol table '" + Sec.Name +
+                               "' out to binary");
 }
 
-void BinarySectionWriter::visit(const RelocationSection &Sec) {
-  error("cannot write relocation section '" + Sec.Name + "' out to binary");
+Error BinarySectionWriter::visit(const RelocationSection &Sec) {
+  return createStringError(errc::operation_not_permitted,
+                           "cannot write relocation section '" + Sec.Name +
+                               "' out to binary");
 }
 
-void BinarySectionWriter::visit(const GnuDebugLinkSection &Sec) {
-  error("cannot write '" + Sec.Name + "' out to binary");
+Error BinarySectionWriter::visit(const GnuDebugLinkSection &Sec) {
+  return createStringError(errc::operation_not_permitted,
+                           "cannot write '" + Sec.Name + "' out to binary");
 }
 
-void BinarySectionWriter::visit(const GroupSection &Sec) {
-  error("cannot write '" + Sec.Name + "' out to binary");
+Error BinarySectionWriter::visit(const GroupSection &Sec) {
+  return createStringError(errc::operation_not_permitted,
+                           "cannot write '" + Sec.Name + "' out to binary");
 }
 
-void SectionWriter::visit(const Section &Sec) {
+Error SectionWriter::visit(const Section &Sec) {
   if (Sec.Type != SHT_NOBITS)
     llvm::copy(Sec.Contents, Out.getBufferStart() + Sec.Offset);
+
+  return Error::success();
 }
 
 static bool addressOverflows32bit(uint64_t Addr) {
@@ -352,30 +378,34 @@ uint64_t IHexSectionWriterBase::writeBaseAddr(uint64_t Addr) {
   return Base;
 }
 
-void IHexSectionWriterBase::writeData(uint8_t Type, uint16_t Addr,
+void IHexSectionWriterBase::writeData(uint8_t, uint16_t,
                                       ArrayRef<uint8_t> Data) {
   Offset += IHexRecord::getLineLength(Data.size());
 }
 
-void IHexSectionWriterBase::visit(const Section &Sec) {
+Error IHexSectionWriterBase::visit(const Section &Sec) {
   writeSection(&Sec, Sec.Contents);
+  return Error::success();
 }
 
-void IHexSectionWriterBase::visit(const OwnedDataSection &Sec) {
+Error IHexSectionWriterBase::visit(const OwnedDataSection &Sec) {
   writeSection(&Sec, Sec.Data);
+  return Error::success();
 }
 
-void IHexSectionWriterBase::visit(const StringTableSection &Sec) {
+Error IHexSectionWriterBase::visit(const StringTableSection &Sec) {
   // Check that sizer has already done its work
   assert(Sec.Size == Sec.StrTabBuilder.getSize());
   // We are free to pass an invalid pointer to writeSection as long
   // as we don't actually write any data. The real writer class has
   // to override this method .
   writeSection(&Sec, {nullptr, static_cast<size_t>(Sec.Size)});
+  return Error::success();
 }
 
-void IHexSectionWriterBase::visit(const DynamicRelocationSection &Sec) {
+Error IHexSectionWriterBase::visit(const DynamicRelocationSection &Sec) {
   writeSection(&Sec, Sec.Contents);
+  return Error::success();
 }
 
 void IHexSectionWriter::writeData(uint8_t Type, uint16_t Addr,
@@ -385,19 +415,25 @@ void IHexSectionWriter::writeData(uint8_t Type, uint16_t Addr,
   Offset += HexData.size();
 }
 
-void IHexSectionWriter::visit(const StringTableSection &Sec) {
+Error IHexSectionWriter::visit(const StringTableSection &Sec) {
   assert(Sec.Size == Sec.StrTabBuilder.getSize());
   std::vector<uint8_t> Data(Sec.Size);
   Sec.StrTabBuilder.write(Data.data());
   writeSection(&Sec, Data);
+  return Error::success();
 }
 
-void Section::accept(SectionVisitor &Visitor) const { Visitor.visit(*this); }
+Error Section::accept(SectionVisitor &Visitor) const {
+  return Visitor.visit(*this);
+}
 
-void Section::accept(MutableSectionVisitor &Visitor) { Visitor.visit(*this); }
+Error Section::accept(MutableSectionVisitor &Visitor) {
+  return Visitor.visit(*this);
+}
 
-void SectionWriter::visit(const OwnedDataSection &Sec) {
+Error SectionWriter::visit(const OwnedDataSection &Sec) {
   llvm::copy(Sec.Data, Out.getBufferStart() + Sec.Offset);
+  return Error::success();
 }
 
 static constexpr std::array<uint8_t, 4> ZlibGnuMagic = {{'Z', 'L', 'I', 'B'}};
@@ -424,7 +460,7 @@ getDecompressedSizeAndAlignment(ArrayRef<uint8_t> Data) {
 }
 
 template <class ELFT>
-void ELFSectionWriter<ELFT>::visit(const DecompressedSection &Sec) {
+Error ELFSectionWriter<ELFT>::visit(const DecompressedSection &Sec) {
   const size_t DataOffset = isDataGnuCompressed(Sec.OriginalData)
                                 ? (ZlibGnuMagic.size() + sizeof(Sec.Size))
                                 : sizeof(Elf_Chdr_Impl<ELFT>);
@@ -434,32 +470,37 @@ void ELFSectionWriter<ELFT>::visit(const DecompressedSection &Sec) {
       Sec.OriginalData.size() - DataOffset);
 
   SmallVector<char, 128> DecompressedContent;
-  if (Error E = zlib::uncompress(CompressedContent, DecompressedContent,
-                                 static_cast<size_t>(Sec.Size)))
-    reportError(Sec.Name, std::move(E));
+  if (Error Err = zlib::uncompress(CompressedContent, DecompressedContent,
+                                   static_cast<size_t>(Sec.Size)))
+    return createStringError(errc::invalid_argument,
+                             "'" + Sec.Name + "': " + toString(std::move(Err)));
 
   uint8_t *Buf = Out.getBufferStart() + Sec.Offset;
   std::copy(DecompressedContent.begin(), DecompressedContent.end(), Buf);
+
+  return Error::success();
 }
 
-void BinarySectionWriter::visit(const DecompressedSection &Sec) {
-  error("cannot write compressed section '" + Sec.Name + "' ");
+Error BinarySectionWriter::visit(const DecompressedSection &Sec) {
+  return createStringError(errc::operation_not_permitted,
+                           "cannot write compressed section '" + Sec.Name +
+                               "' ");
 }
 
-void DecompressedSection::accept(SectionVisitor &Visitor) const {
-  Visitor.visit(*this);
+Error DecompressedSection::accept(SectionVisitor &Visitor) const {
+  return Visitor.visit(*this);
 }
 
-void DecompressedSection::accept(MutableSectionVisitor &Visitor) {
-  Visitor.visit(*this);
+Error DecompressedSection::accept(MutableSectionVisitor &Visitor) {
+  return Visitor.visit(*this);
 }
 
-void OwnedDataSection::accept(SectionVisitor &Visitor) const {
-  Visitor.visit(*this);
+Error OwnedDataSection::accept(SectionVisitor &Visitor) const {
+  return Visitor.visit(*this);
 }
 
-void OwnedDataSection::accept(MutableSectionVisitor &Visitor) {
-  Visitor.visit(*this);
+Error OwnedDataSection::accept(MutableSectionVisitor &Visitor) {
+  return Visitor.visit(*this);
 }
 
 void OwnedDataSection::appendHexData(StringRef HexData) {
@@ -471,16 +512,18 @@ void OwnedDataSection::appendHexData(StringRef HexData) {
   Size = Data.size();
 }
 
-void BinarySectionWriter::visit(const CompressedSection &Sec) {
-  error("cannot write compressed section '" + Sec.Name + "' ");
+Error BinarySectionWriter::visit(const CompressedSection &Sec) {
+  return createStringError(errc::operation_not_permitted,
+                           "cannot write compressed section '" + Sec.Name +
+                               "' ");
 }
 
 template <class ELFT>
-void ELFSectionWriter<ELFT>::visit(const CompressedSection &Sec) {
+Error ELFSectionWriter<ELFT>::visit(const CompressedSection &Sec) {
   uint8_t *Buf = Out.getBufferStart() + Sec.Offset;
   if (Sec.CompressionType == DebugCompressionType::None) {
     std::copy(Sec.OriginalData.begin(), Sec.OriginalData.end(), Buf);
-    return;
+    return Error::success();
   }
 
   if (Sec.CompressionType == DebugCompressionType::GNU) {
@@ -501,17 +544,42 @@ void ELFSectionWriter<ELFT>::visit(const CompressedSection &Sec) {
   }
 
   std::copy(Sec.CompressedData.begin(), Sec.CompressedData.end(), Buf);
+  return Error::success();
+}
+
+Expected<CompressedSection>
+CompressedSection::create(const SectionBase &Sec,
+                          DebugCompressionType CompressionType) {
+  Error Err = Error::success();
+  CompressedSection Section(Sec, CompressionType, Err);
+
+  if (Err)
+    return std::move(Err);
+
+  return Section;
+}
+Expected<CompressedSection>
+CompressedSection::create(ArrayRef<uint8_t> CompressedData,
+                          uint64_t DecompressedSize,
+                          uint64_t DecompressedAlign) {
+  return CompressedSection(CompressedData, DecompressedSize, DecompressedAlign);
 }
 
 CompressedSection::CompressedSection(const SectionBase &Sec,
-                                     DebugCompressionType CompressionType)
+                                     DebugCompressionType CompressionType,
+                                     Error &OutErr)
     : SectionBase(Sec), CompressionType(CompressionType),
       DecompressedSize(Sec.OriginalData.size()), DecompressedAlign(Sec.Align) {
-  if (Error E = zlib::compress(
+  ErrorAsOutParameter EAO(&OutErr);
+
+  if (Error Err = zlib::compress(
           StringRef(reinterpret_cast<const char *>(OriginalData.data()),
                     OriginalData.size()),
-          CompressedData))
-    reportError(Name, std::move(E));
+          CompressedData)) {
+    OutErr = createStringError(llvm::errc::invalid_argument,
+                               "'" + Name + "': " + toString(std::move(Err)));
+    return;
+  }
 
   size_t ChdrSize;
   if (CompressionType == DebugCompressionType::GNU) {
@@ -537,12 +605,12 @@ CompressedSection::CompressedSection(ArrayRef<uint8_t> CompressedData,
   OriginalData = CompressedData;
 }
 
-void CompressedSection::accept(SectionVisitor &Visitor) const {
-  Visitor.visit(*this);
+Error CompressedSection::accept(SectionVisitor &Visitor) const {
+  return Visitor.visit(*this);
 }
 
-void CompressedSection::accept(MutableSectionVisitor &Visitor) {
-  Visitor.visit(*this);
+Error CompressedSection::accept(MutableSectionVisitor &Visitor) {
+  return Visitor.visit(*this);
 }
 
 void StringTableSection::addString(StringRef Name) { StrTabBuilder.add(Name); }
@@ -556,42 +624,51 @@ void StringTableSection::prepareForLayout() {
   Size = StrTabBuilder.getSize();
 }
 
-void SectionWriter::visit(const StringTableSection &Sec) {
+Error SectionWriter::visit(const StringTableSection &Sec) {
   Sec.StrTabBuilder.write(Out.getBufferStart() + Sec.Offset);
+  return Error::success();
 }
 
-void StringTableSection::accept(SectionVisitor &Visitor) const {
-  Visitor.visit(*this);
+Error StringTableSection::accept(SectionVisitor &Visitor) const {
+  return Visitor.visit(*this);
 }
 
-void StringTableSection::accept(MutableSectionVisitor &Visitor) {
-  Visitor.visit(*this);
+Error StringTableSection::accept(MutableSectionVisitor &Visitor) {
+  return Visitor.visit(*this);
 }
 
 template <class ELFT>
-void ELFSectionWriter<ELFT>::visit(const SectionIndexSection &Sec) {
+Error ELFSectionWriter<ELFT>::visit(const SectionIndexSection &Sec) {
   uint8_t *Buf = Out.getBufferStart() + Sec.Offset;
   llvm::copy(Sec.Indexes, reinterpret_cast<Elf_Word *>(Buf));
+  return Error::success();
 }
 
-void SectionIndexSection::initialize(SectionTableRef SecTable) {
+Error SectionIndexSection::initialize(SectionTableRef SecTable) {
   Size = 0;
-  setSymTab(SecTable.getSectionOfType<SymbolTableSection>(
-      Link,
-      "Link field value " + Twine(Link) + " in section " + Name + " is invalid",
-      "Link field value " + Twine(Link) + " in section " + Name +
-          " is not a symbol table"));
+  Expected<SymbolTableSection *> Sec =
+      SecTable.getSectionOfType<SymbolTableSection>(
+          Link,
+          "Link field value " + Twine(Link) + " in section " + Name +
+              " is invalid",
+          "Link field value " + Twine(Link) + " in section " + Name +
+              " is not a symbol table");
+  if (!Sec)
+    return Sec.takeError();
+
+  setSymTab(*Sec);
   Symbols->setShndxTable(this);
+  return Error::success();
 }
 
 void SectionIndexSection::finalize() { Link = Symbols->Index; }
 
-void SectionIndexSection::accept(SectionVisitor &Visitor) const {
-  Visitor.visit(*this);
+Error SectionIndexSection::accept(SectionVisitor &Visitor) const {
+  return Visitor.visit(*this);
 }
 
-void SectionIndexSection::accept(MutableSectionVisitor &Visitor) {
-  Visitor.visit(*this);
+Error SectionIndexSection::accept(MutableSectionVisitor &Visitor) {
+  return Visitor.visit(*this);
 }
 
 static bool isValidReservedSectionIndex(uint16_t Index, uint16_t Machine) {
@@ -718,14 +795,20 @@ void SymbolTableSection::replaceSectionReferences(
       Sym->DefinedIn = To;
 }
 
-void SymbolTableSection::initialize(SectionTableRef SecTable) {
+Error SymbolTableSection::initialize(SectionTableRef SecTable) {
   Size = 0;
-  setStrTab(SecTable.getSectionOfType<StringTableSection>(
-      Link,
-      "Symbol table has link index of " + Twine(Link) +
-          " which is not a valid index",
-      "Symbol table has link index of " + Twine(Link) +
-          " which is not a string table"));
+  Expected<StringTableSection *> Sec =
+      SecTable.getSectionOfType<StringTableSection>(
+          Link,
+          "Symbol table has link index of " + Twine(Link) +
+              " which is not a valid index",
+          "Symbol table has link index of " + Twine(Link) +
+              " which is not a string table");
+  if (!Sec)
+    return Sec.takeError();
+
+  setStrTab(*Sec);
+  return Error::success();
 }
 
 void SymbolTableSection::finalize() {
@@ -770,19 +853,25 @@ void SymbolTableSection::fillShndxTable() {
   }
 }
 
-const Symbol *SymbolTableSection::getSymbolByIndex(uint32_t Index) const {
+Expected<const Symbol *>
+SymbolTableSection::getSymbolByIndex(uint32_t Index) const {
   if (Symbols.size() <= Index)
-    error("invalid symbol index: " + Twine(Index));
+    return createStringError(errc::invalid_argument,
+                             "invalid symbol index: " + Twine(Index));
   return Symbols[Index].get();
 }
 
-Symbol *SymbolTableSection::getSymbolByIndex(uint32_t Index) {
-  return const_cast<Symbol *>(
-      static_cast<const SymbolTableSection *>(this)->getSymbolByIndex(Index));
+Expected<Symbol *> SymbolTableSection::getSymbolByIndex(uint32_t Index) {
+  Expected<const Symbol *> Sym =
+      static_cast<const SymbolTableSection *>(this)->getSymbolByIndex(Index);
+  if (!Sym)
+    return Sym.takeError();
+
+  return const_cast<Symbol *>(*Sym);
 }
 
 template <class ELFT>
-void ELFSectionWriter<ELFT>::visit(const SymbolTableSection &Sec) {
+Error ELFSectionWriter<ELFT>::visit(const SymbolTableSection &Sec) {
   Elf_Sym *Sym = reinterpret_cast<Elf_Sym *>(Out.getBufferStart() + Sec.Offset);
   // Loop though symbols setting each entry of the symbol table.
   for (const std::unique_ptr<Symbol> &Symbol : Sec.Symbols) {
@@ -795,14 +884,15 @@ void ELFSectionWriter<ELFT>::visit(const SymbolTableSection &Sec) {
     Sym->st_shndx = Symbol->getShndx();
     ++Sym;
   }
+  return Error::success();
 }
 
-void SymbolTableSection::accept(SectionVisitor &Visitor) const {
-  Visitor.visit(*this);
+Error SymbolTableSection::accept(SectionVisitor &Visitor) const {
+  return Visitor.visit(*this);
 }
 
-void SymbolTableSection::accept(MutableSectionVisitor &Visitor) {
-  Visitor.visit(*this);
+Error SymbolTableSection::accept(MutableSectionVisitor &Visitor) {
+  return Visitor.visit(*this);
 }
 
 Error RelocationSection::removeSectionReferences(
@@ -834,22 +924,33 @@ Error RelocationSection::removeSectionReferences(
 }
 
 template <class SymTabType>
-void RelocSectionWithSymtabBase<SymTabType>::initialize(
+Error RelocSectionWithSymtabBase<SymTabType>::initialize(
     SectionTableRef SecTable) {
-  if (Link != SHN_UNDEF)
-    setSymTab(SecTable.getSectionOfType<SymTabType>(
+  if (Link != SHN_UNDEF) {
+    Expected<SymTabType *> Sec = SecTable.getSectionOfType<SymTabType>(
         Link,
         "Link field value " + Twine(Link) + " in section " + Name +
             " is invalid",
         "Link field value " + Twine(Link) + " in section " + Name +
-            " is not a symbol table"));
+            " is not a symbol table");
+    if (!Sec)
+      return Sec.takeError();
 
-  if (Info != SHN_UNDEF)
-    setSection(SecTable.getSection(Info, "Info field value " + Twine(Info) +
-                                             " in section " + Name +
-                                             " is invalid"));
-  else
+    setSymTab(*Sec);
+  }
+
+  if (Info != SHN_UNDEF) {
+    Expected<SectionBase *> Sec =
+        SecTable.getSection(Info, "Info field value " + Twine(Info) +
+                                      " in section " + Name + " is invalid");
+    if (!Sec)
+      return Sec.takeError();
+
+    setSection(*Sec);
+  } else
     setSection(nullptr);
+
+  return Error::success();
 }
 
 template <class SymTabType>
@@ -880,20 +981,21 @@ static void writeRel(const RelRange &Relocations, T *Buf) {
 }
 
 template <class ELFT>
-void ELFSectionWriter<ELFT>::visit(const RelocationSection &Sec) {
+Error ELFSectionWriter<ELFT>::visit(const RelocationSection &Sec) {
   uint8_t *Buf = Out.getBufferStart() + Sec.Offset;
   if (Sec.Type == SHT_REL)
     writeRel(Sec.Relocations, reinterpret_cast<Elf_Rel *>(Buf));
   else
     writeRel(Sec.Relocations, reinterpret_cast<Elf_Rela *>(Buf));
+  return Error::success();
 }
 
-void RelocationSection::accept(SectionVisitor &Visitor) const {
-  Visitor.visit(*this);
+Error RelocationSection::accept(SectionVisitor &Visitor) const {
+  return Visitor.visit(*this);
 }
 
-void RelocationSection::accept(MutableSectionVisitor &Visitor) {
-  Visitor.visit(*this);
+Error RelocationSection::accept(MutableSectionVisitor &Visitor) {
+  return Visitor.visit(*this);
 }
 
 Error RelocationSection::removeSymbols(
@@ -920,16 +1022,17 @@ void RelocationSection::replaceSectionReferences(
     SecToApplyRel = To;
 }
 
-void SectionWriter::visit(const DynamicRelocationSection &Sec) {
+Error SectionWriter::visit(const DynamicRelocationSection &Sec) {
   llvm::copy(Sec.Contents, Out.getBufferStart() + Sec.Offset);
+  return Error::success();
 }
 
-void DynamicRelocationSection::accept(SectionVisitor &Visitor) const {
-  Visitor.visit(*this);
+Error DynamicRelocationSection::accept(SectionVisitor &Visitor) const {
+  return Visitor.visit(*this);
 }
 
-void DynamicRelocationSection::accept(MutableSectionVisitor &Visitor) {
-  Visitor.visit(*this);
+Error DynamicRelocationSection::accept(MutableSectionVisitor &Visitor) {
+  return Visitor.visit(*this);
 }
 
 Error DynamicRelocationSection::removeSectionReferences(
@@ -1015,14 +1118,22 @@ void GroupSection::onRemove() {
     Sec->Flags &= ~SHF_GROUP;
 }
 
-void Section::initialize(SectionTableRef SecTable) {
+Error Section::initialize(SectionTableRef SecTable) {
   if (Link == ELF::SHN_UNDEF)
-    return;
-  LinkSection =
+    return Error::success();
+
+  Expected<SectionBase *> Sec =
       SecTable.getSection(Link, "Link field value " + Twine(Link) +
                                     " in section " + Name + " is invalid");
+  if (!Sec)
+    return Sec.takeError();
+
+  LinkSection = *Sec;
+
   if (LinkSection->Type == ELF::SHT_SYMTAB)
     LinkSection = nullptr;
+
+  return Error::success();
 }
 
 void Section::finalize() { this->Link = LinkSection ? LinkSection->Index : 0; }
@@ -1051,37 +1162,39 @@ GnuDebugLinkSection::GnuDebugLinkSection(StringRef File,
 }
 
 template <class ELFT>
-void ELFSectionWriter<ELFT>::visit(const GnuDebugLinkSection &Sec) {
+Error ELFSectionWriter<ELFT>::visit(const GnuDebugLinkSection &Sec) {
   unsigned char *Buf = Out.getBufferStart() + Sec.Offset;
   Elf_Word *CRC =
       reinterpret_cast<Elf_Word *>(Buf + Sec.Size - sizeof(Elf_Word));
   *CRC = Sec.CRC32;
   llvm::copy(Sec.FileName, Buf);
+  return Error::success();
 }
 
-void GnuDebugLinkSection::accept(SectionVisitor &Visitor) const {
-  Visitor.visit(*this);
+Error GnuDebugLinkSection::accept(SectionVisitor &Visitor) const {
+  return Visitor.visit(*this);
 }
 
-void GnuDebugLinkSection::accept(MutableSectionVisitor &Visitor) {
-  Visitor.visit(*this);
+Error GnuDebugLinkSection::accept(MutableSectionVisitor &Visitor) {
+  return Visitor.visit(*this);
 }
 
 template <class ELFT>
-void ELFSectionWriter<ELFT>::visit(const GroupSection &Sec) {
+Error ELFSectionWriter<ELFT>::visit(const GroupSection &Sec) {
   ELF::Elf32_Word *Buf =
       reinterpret_cast<ELF::Elf32_Word *>(Out.getBufferStart() + Sec.Offset);
   *Buf++ = Sec.FlagWord;
   for (SectionBase *S : Sec.GroupMembers)
     support::endian::write32<ELFT::TargetEndianness>(Buf++, S->Index);
+  return Error::success();
 }
 
-void GroupSection::accept(SectionVisitor &Visitor) const {
-  Visitor.visit(*this);
+Error GroupSection::accept(SectionVisitor &Visitor) const {
+  return Visitor.visit(*this);
 }
 
-void GroupSection::accept(MutableSectionVisitor &Visitor) {
-  Visitor.visit(*this);
+Error GroupSection::accept(MutableSectionVisitor &Visitor) {
+  return Visitor.visit(*this);
 }
 
 // Returns true IFF a section is wholly inside the range of a segment
@@ -1161,9 +1274,12 @@ SymbolTableSection *BasicELFBuilder::addSymTab(StringTableSection *StrTab) {
   return &SymTab;
 }
 
-void BasicELFBuilder::initSections() {
+Error BasicELFBuilder::initSections() {
   for (SectionBase &Sec : Obj->sections())
-    Sec.initialize(Obj->sections());
+    if (Error Err = Sec.initialize(Obj->sections()))
+      return Err;
+
+  return Error::success();
 }
 
 void BinaryELFBuilder::addData(SymbolTableSection *SymTab) {
@@ -1190,12 +1306,13 @@ void BinaryELFBuilder::addData(SymbolTableSection *SymTab) {
                     0);
 }
 
-std::unique_ptr<Object> BinaryELFBuilder::build() {
+Expected<std::unique_ptr<Object>> BinaryELFBuilder::build() {
   initFileHeader();
   initHeaderSegment();
 
   SymbolTableSection *SymTab = addSymTab(addStrTab());
-  initSections();
+  if (Error Err = initSections())
+    return std::move(Err);
   addData(SymTab);
 
   return std::move(Obj);
@@ -1246,12 +1363,13 @@ void IHexELFBuilder::addDataSections() {
   }
 }
 
-std::unique_ptr<Object> IHexELFBuilder::build() {
+Expected<std::unique_ptr<Object>> IHexELFBuilder::build() {
   initFileHeader();
   initHeaderSegment();
   StringTableSection *StrTab = addStrTab();
   addSymTab(StrTab);
-  initSections();
+  if (Error Err = initSections())
+    return std::move(Err);
   addDataSections();
 
   return std::move(Obj);
@@ -1273,27 +1391,37 @@ template <class ELFT> void ELFBuilder<ELFT>::setParentSegment(Segment &Child) {
   }
 }
 
-template <class ELFT> void ELFBuilder<ELFT>::findEhdrOffset() {
+template <class ELFT> Error ELFBuilder<ELFT>::findEhdrOffset() {
   if (!ExtractPartition)
-    return;
+    return Error::success();
 
   for (const SectionBase &Sec : Obj.sections()) {
     if (Sec.Type == SHT_LLVM_PART_EHDR && Sec.Name == *ExtractPartition) {
       EhdrOffset = Sec.Offset;
-      return;
+      return Error::success();
     }
   }
-  error("could not find partition named '" + *ExtractPartition + "'");
+  return createStringError(errc::invalid_argument,
+                           "could not find partition named '" +
+                               *ExtractPartition + "'");
 }
 
 template <class ELFT>
-void ELFBuilder<ELFT>::readProgramHeaders(const ELFFile<ELFT> &HeadersFile) {
+Error ELFBuilder<ELFT>::readProgramHeaders(const ELFFile<ELFT> &HeadersFile) {
   uint32_t Index = 0;
-  for (const auto &Phdr : unwrapOrError(HeadersFile.program_headers())) {
+
+  Expected<typename ELFFile<ELFT>::Elf_Phdr_Range> Headers =
+      HeadersFile.program_headers();
+  if (!Headers)
+    return Headers.takeError();
+
+  for (const typename ELFFile<ELFT>::Elf_Phdr &Phdr : *Headers) {
     if (Phdr.p_offset + Phdr.p_filesz > HeadersFile.getBufSize())
-      error("program header with offset 0x" + Twine::utohexstr(Phdr.p_offset) +
-            " and file size 0x" + Twine::utohexstr(Phdr.p_filesz) +
-            " goes past the end of the file");
+      return createStringError(
+          errc::invalid_argument,
+          "program header with offset 0x" + Twine::utohexstr(Phdr.p_offset) +
+              " and file size 0x" + Twine::utohexstr(Phdr.p_filesz) +
+              " goes past the end of the file");
 
     ArrayRef<uint8_t> Data{HeadersFile.base() + Phdr.p_offset,
                            (size_t)Phdr.p_filesz};
@@ -1341,13 +1469,16 @@ void ELFBuilder<ELFT>::readProgramHeaders(const ELFFile<ELFT> &HeadersFile) {
     setParentSegment(Child);
   setParentSegment(ElfHdr);
   setParentSegment(PrHdr);
+
+  return Error::success();
 }
 
 template <class ELFT>
-void ELFBuilder<ELFT>::initGroupSection(GroupSection *GroupSec) {
+Error ELFBuilder<ELFT>::initGroupSection(GroupSection *GroupSec) {
   if (GroupSec->Align % sizeof(ELF::Elf32_Word) != 0)
-    error("invalid alignment " + Twine(GroupSec->Align) + " of group section '" +
-          GroupSec->Name + "'");
+    return createStringError(errc::invalid_argument,
+                             "invalid alignment " + Twine(GroupSec->Align) +
+                                 " of group section '" + GroupSec->Name + "'");
   SectionTableRef SecTable = Obj.sections();
   if (GroupSec->Link != SHN_UNDEF) {
     auto SymTab = SecTable.template getSectionOfType<SymbolTableSection>(
@@ -1356,16 +1487,23 @@ void ELFBuilder<ELFT>::initGroupSection(GroupSection *GroupSec) {
             GroupSec->Name + "' is invalid",
         "link field value '" + Twine(GroupSec->Link) + "' in section '" +
             GroupSec->Name + "' is not a symbol table");
-    Symbol *Sym = SymTab->getSymbolByIndex(GroupSec->Info);
+    if (!SymTab)
+      return SymTab.takeError();
+
+    Expected<Symbol *> Sym = (*SymTab)->getSymbolByIndex(GroupSec->Info);
     if (!Sym)
-      error("info field value '" + Twine(GroupSec->Info) + "' in section '" +
-            GroupSec->Name + "' is not a valid symbol index");
-    GroupSec->setSymTab(SymTab);
-    GroupSec->setSymbol(Sym);
+      return createStringError(errc::invalid_argument,
+                               "info field value '" + Twine(GroupSec->Info) +
+                                   "' in section '" + GroupSec->Name +
+                                   "' is not a valid symbol index");
+    GroupSec->setSymTab(*SymTab);
+    GroupSec->setSymbol(*Sym);
   }
   if (GroupSec->Contents.size() % sizeof(ELF::Elf32_Word) ||
       GroupSec->Contents.empty())
-    error("the content of the section " + GroupSec->Name + " is malformed");
+    return createStringError(errc::invalid_argument,
+                             "the content of the section " + GroupSec->Name +
+                                 " is malformed");
   const ELF::Elf32_Word *Word =
       reinterpret_cast<const ELF::Elf32_Word *>(GroupSec->Contents.data());
   const ELF::Elf32_Word *End =
@@ -1373,57 +1511,99 @@ void ELFBuilder<ELFT>::initGroupSection(GroupSection *GroupSec) {
   GroupSec->setFlagWord(*Word++);
   for (; Word != End; ++Word) {
     uint32_t Index = support::endian::read32<ELFT::TargetEndianness>(Word);
-    GroupSec->addMember(SecTable.getSection(
+    Expected<SectionBase *> Sec = SecTable.getSection(
         Index, "group member index " + Twine(Index) + " in section '" +
-                   GroupSec->Name + "' is invalid"));
+                   GroupSec->Name + "' is invalid");
+    if (!Sec)
+      return Sec.takeError();
+
+    GroupSec->addMember(*Sec);
   }
+
+  return Error::success();
 }
 
 template <class ELFT>
-void ELFBuilder<ELFT>::initSymbolTable(SymbolTableSection *SymTab) {
-  const Elf_Shdr &Shdr = *unwrapOrError(ElfFile.getSection(SymTab->Index));
-  StringRef StrTabData = unwrapOrError(ElfFile.getStringTableForSymtab(Shdr));
+Error ELFBuilder<ELFT>::initSymbolTable(SymbolTableSection *SymTab) {
+  Expected<const Elf_Shdr *> Shdr = ElfFile.getSection(SymTab->Index);
+  if (!Shdr)
+    return Shdr.takeError();
+
+  Expected<StringRef> StrTabData = ElfFile.getStringTableForSymtab(**Shdr);
+  if (!StrTabData)
+    return StrTabData.takeError();
+
   ArrayRef<Elf_Word> ShndxData;
 
-  auto Symbols = unwrapOrError(ElfFile.symbols(&Shdr));
-  for (const auto &Sym : Symbols) {
+  Expected<typename ELFFile<ELFT>::Elf_Sym_Range> Symbols =
+      ElfFile.symbols(*Shdr);
+  if (!Symbols)
+    return Symbols.takeError();
+
+  for (const typename ELFFile<ELFT>::Elf_Sym &Sym : *Symbols) {
     SectionBase *DefSection = nullptr;
-    StringRef Name = unwrapOrError(Sym.getName(StrTabData));
+
+    Expected<StringRef> Name = Sym.getName(*StrTabData);
+    if (!Name)
+      return Name.takeError();
 
     if (Sym.st_shndx == SHN_XINDEX) {
       if (SymTab->getShndxTable() == nullptr)
-        error("symbol '" + Name +
-              "' has index SHN_XINDEX but no SHT_SYMTAB_SHNDX section exists");
+        return createStringError(errc::invalid_argument,
+                                 "symbol '" + *Name +
+                                     "' has index SHN_XINDEX but no "
+                                     "SHT_SYMTAB_SHNDX section exists");
       if (ShndxData.data() == nullptr) {
-        const Elf_Shdr &ShndxSec =
-            *unwrapOrError(ElfFile.getSection(SymTab->getShndxTable()->Index));
-        ShndxData = unwrapOrError(
-            ElfFile.template getSectionContentsAsArray<Elf_Word>(ShndxSec));
-        if (ShndxData.size() != Symbols.size())
-          error("symbol section index table does not have the same number of "
-                "entries as the symbol table");
+        Expected<const Elf_Shdr *> ShndxSec =
+            ElfFile.getSection(SymTab->getShndxTable()->Index);
+        if (!ShndxSec)
+          return ShndxSec.takeError();
+
+        Expected<ArrayRef<Elf_Word>> Data =
+            ElfFile.template getSectionContentsAsArray<Elf_Word>(**ShndxSec);
+        if (!Data)
+          return Data.takeError();
+
+        ShndxData = *Data;
+        if (ShndxData.size() != Symbols->size())
+          return createStringError(
+              errc::invalid_argument,
+              "symbol section index table does not have the same number of "
+              "entries as the symbol table");
       }
-      Elf_Word Index = ShndxData[&Sym - Symbols.begin()];
-      DefSection = Obj.sections().getSection(
+      Elf_Word Index = ShndxData[&Sym - Symbols->begin()];
+      Expected<SectionBase *> Sec = Obj.sections().getSection(
           Index,
-          "symbol '" + Name + "' has invalid section index " + Twine(Index));
+          "symbol '" + *Name + "' has invalid section index " + Twine(Index));
+      if (!Sec)
+        return Sec.takeError();
+
+      DefSection = *Sec;
     } else if (Sym.st_shndx >= SHN_LORESERVE) {
       if (!isValidReservedSectionIndex(Sym.st_shndx, Obj.Machine)) {
-        error(
-            "symbol '" + Name +
-            "' has unsupported value greater than or equal to SHN_LORESERVE: " +
-            Twine(Sym.st_shndx));
+        return createStringError(
+            errc::invalid_argument,
+            "symbol '" + *Name +
+                "' has unsupported value greater than or equal "
+                "to SHN_LORESERVE: " +
+                Twine(Sym.st_shndx));
       }
     } else if (Sym.st_shndx != SHN_UNDEF) {
-      DefSection = Obj.sections().getSection(
-          Sym.st_shndx, "symbol '" + Name +
+      Expected<SectionBase *> Sec = Obj.sections().getSection(
+          Sym.st_shndx, "symbol '" + *Name +
                             "' is defined has invalid section index " +
                             Twine(Sym.st_shndx));
+      if (!Sec)
+        return Sec.takeError();
+
+      DefSection = *Sec;
     }
 
-    SymTab->addSymbol(Name, Sym.getBinding(), Sym.getType(), DefSection,
+    SymTab->addSymbol(*Name, Sym.getBinding(), Sym.getType(), DefSection,
                       Sym.getValue(), Sym.st_other, Sym.st_shndx, Sym.st_size);
   }
+
+  return Error::success();
 }
 
 template <class ELFT>
@@ -1435,8 +1615,8 @@ static void getAddend(uint64_t &ToSet, const Elf_Rel_Impl<ELFT, true> &Rela) {
 }
 
 template <class T>
-static void initRelocations(RelocationSection *Relocs,
-                            SymbolTableSection *SymbolTable, T RelRange) {
+static Error initRelocations(RelocationSection *Relocs,
+                             SymbolTableSection *SymbolTable, T RelRange) {
   for (const auto &Rel : RelRange) {
     Relocation ToAdd;
     ToAdd.Offset = Rel.r_offset;
@@ -1445,39 +1625,54 @@ static void initRelocations(RelocationSection *Relocs,
 
     if (uint32_t Sym = Rel.getSymbol(false)) {
       if (!SymbolTable)
-        error("'" + Relocs->Name +
-              "': relocation references symbol with index " + Twine(Sym) +
-              ", but there is no symbol table");
-      ToAdd.RelocSymbol = SymbolTable->getSymbolByIndex(Sym);
+        return createStringError(
+            errc::invalid_argument,
+            "'" + Relocs->Name + "': relocation references symbol with index " +
+                Twine(Sym) + ", but there is no symbol table");
+      Expected<Symbol *> SymByIndex = SymbolTable->getSymbolByIndex(Sym);
+      if (!SymByIndex)
+        return SymByIndex.takeError();
+
+      ToAdd.RelocSymbol = *SymByIndex;
     }
 
     Relocs->addRelocation(ToAdd);
   }
+
+  return Error::success();
 }
 
-SectionBase *SectionTableRef::getSection(uint32_t Index, Twine ErrMsg) {
+Expected<SectionBase *> SectionTableRef::getSection(uint32_t Index,
+                                                    Twine ErrMsg) {
   if (Index == SHN_UNDEF || Index > Sections.size())
-    error(ErrMsg);
+    return createStringError(errc::invalid_argument, ErrMsg);
   return Sections[Index - 1].get();
 }
 
 template <class T>
-T *SectionTableRef::getSectionOfType(uint32_t Index, Twine IndexErrMsg,
-                                     Twine TypeErrMsg) {
-  if (T *Sec = dyn_cast<T>(getSection(Index, IndexErrMsg)))
+Expected<T *> SectionTableRef::getSectionOfType(uint32_t Index,
+                                                Twine IndexErrMsg,
+                                                Twine TypeErrMsg) {
+  Expected<SectionBase *> BaseSec = getSection(Index, IndexErrMsg);
+  if (!BaseSec)
+    return BaseSec.takeError();
+
+  if (T *Sec = dyn_cast<T>(*BaseSec))
     return Sec;
-  error(TypeErrMsg);
+
+  return createStringError(errc::invalid_argument, TypeErrMsg);
 }
 
 template <class ELFT>
-SectionBase &ELFBuilder<ELFT>::makeSection(const Elf_Shdr &Shdr) {
-  ArrayRef<uint8_t> Data;
+Expected<SectionBase &> ELFBuilder<ELFT>::makeSection(const Elf_Shdr &Shdr) {
   switch (Shdr.sh_type) {
   case SHT_REL:
   case SHT_RELA:
     if (Shdr.sh_flags & SHF_ALLOC) {
-      Data = unwrapOrError(ElfFile.getSectionContents(Shdr));
-      return Obj.addSection<DynamicRelocationSection>(Data);
+      if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
+        return Obj.addSection<DynamicRelocationSection>(*Data);
+      else
+        return Data.takeError();
     }
     return Obj.addSection<RelocationSection>();
   case SHT_STRTAB:
@@ -1485,25 +1680,35 @@ SectionBase &ELFBuilder<ELFT>::makeSection(const Elf_Shdr &Shdr) {
     // mean altering the memory image. There are no special link types or
     // anything so we can just use a Section.
     if (Shdr.sh_flags & SHF_ALLOC) {
-      Data = unwrapOrError(ElfFile.getSectionContents(Shdr));
-      return Obj.addSection<Section>(Data);
+      if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
+        return Obj.addSection<Section>(*Data);
+      else
+        return Data.takeError();
     }
     return Obj.addSection<StringTableSection>();
   case SHT_HASH:
   case SHT_GNU_HASH:
     // Hash tables should refer to SHT_DYNSYM which we're not going to change.
     // Because of this we don't need to mess with the hash tables either.
-    Data = unwrapOrError(ElfFile.getSectionContents(Shdr));
-    return Obj.addSection<Section>(Data);
+    if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
+      return Obj.addSection<Section>(*Data);
+    else
+      return Data.takeError();
   case SHT_GROUP:
-    Data = unwrapOrError(ElfFile.getSectionContents(Shdr));
-    return Obj.addSection<GroupSection>(Data);
+    if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
+      return Obj.addSection<GroupSection>(*Data);
+    else
+      return Data.takeError();
   case SHT_DYNSYM:
-    Data = unwrapOrError(ElfFile.getSectionContents(Shdr));
-    return Obj.addSection<DynamicSymbolTableSection>(Data);
+    if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
+      return Obj.addSection<DynamicSymbolTableSection>(*Data);
+    else
+      return Data.takeError();
   case SHT_DYNAMIC:
-    Data = unwrapOrError(ElfFile.getSectionContents(Shdr));
-    return Obj.addSection<DynamicSection>(Data);
+    if (Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr))
+      return Obj.addSection<DynamicSection>(*Data);
+    else
+      return Data.takeError();
   case SHT_SYMTAB: {
     auto &SymTab = Obj.addSection<SymbolTableSection>();
     Obj.SymbolTable = &SymTab;
@@ -1515,114 +1720,175 @@ SectionBase &ELFBuilder<ELFT>::makeSection(const Elf_Shdr &Shdr) {
     return ShndxSection;
   }
   case SHT_NOBITS:
-    return Obj.addSection<Section>(Data);
+    return Obj.addSection<Section>(ArrayRef<uint8_t>());
   default: {
-    Data = unwrapOrError(ElfFile.getSectionContents(Shdr));
+    Expected<ArrayRef<uint8_t>> Data = ElfFile.getSectionContents(Shdr);
+    if (!Data)
+      return Data.takeError();
+
+    Expected<StringRef> Name = ElfFile.getSectionName(Shdr);
+    if (!Name)
+      return Name.takeError();
 
-    StringRef Name = unwrapOrError(ElfFile.getSectionName(Shdr));
-    if (Name.startswith(".zdebug") || (Shdr.sh_flags & ELF::SHF_COMPRESSED)) {
+    if (Name->startswith(".zdebug") || (Shdr.sh_flags & ELF::SHF_COMPRESSED)) {
       uint64_t DecompressedSize, DecompressedAlign;
       std::tie(DecompressedSize, DecompressedAlign) =
-          getDecompressedSizeAndAlignment<ELFT>(Data);
-      return Obj.addSection<CompressedSection>(Data, DecompressedSize,
-                                               DecompressedAlign);
+          getDecompressedSizeAndAlignment<ELFT>(*Data);
+      Expected<CompressedSection> NewSection =
+          CompressedSection::create(*Data, DecompressedSize, DecompressedAlign);
+      if (!NewSection)
+        return NewSection.takeError();
+
+      return Obj.addSection<CompressedSection>(std::move(*NewSection));
     }
 
-    return Obj.addSection<Section>(Data);
+    return Obj.addSection<Section>(*Data);
   }
   }
 }
 
-template <class ELFT> void ELFBuilder<ELFT>::readSectionHeaders() {
+template <class ELFT> Error ELFBuilder<ELFT>::readSectionHeaders() {
   uint32_t Index = 0;
-  for (const auto &Shdr : unwrapOrError(ElfFile.sections())) {
+  Expected<typename ELFFile<ELFT>::Elf_Shdr_Range> Sections =
+      ElfFile.sections();
+  if (!Sections)
+    return Sections.takeError();
+
+  for (const typename ELFFile<ELFT>::Elf_Shdr &Shdr : *Sections) {
     if (Index == 0) {
       ++Index;
       continue;
     }
-    auto &Sec = makeSection(Shdr);
-    Sec.Name = std::string(unwrapOrError(ElfFile.getSectionName(Shdr)));
-    Sec.Type = Sec.OriginalType = Shdr.sh_type;
-    Sec.Flags = Sec.OriginalFlags = Shdr.sh_flags;
-    Sec.Addr = Shdr.sh_addr;
-    Sec.Offset = Shdr.sh_offset;
-    Sec.OriginalOffset = Shdr.sh_offset;
-    Sec.Size = Shdr.sh_size;
-    Sec.Link = Shdr.sh_link;
-    Sec.Info = Shdr.sh_info;
-    Sec.Align = Shdr.sh_addralign;
-    Sec.EntrySize = Shdr.sh_entsize;
-    Sec.Index = Index++;
-    Sec.OriginalData =
+    Expected<SectionBase &> Sec = makeSection(Shdr);
+    if (!Sec)
+      return Sec.takeError();
+
+    Expected<StringRef> SecName = ElfFile.getSectionName(Shdr);
+    if (!SecName)
+      return SecName.takeError();
+    Sec->Name = SecName->str();
+    Sec->Type = Sec->OriginalType = Shdr.sh_type;
+    Sec->Flags = Sec->OriginalFlags = Shdr.sh_flags;
+    Sec->Addr = Shdr.sh_addr;
+    Sec->Offset = Shdr.sh_offset;
+    Sec->OriginalOffset = Shdr.sh_offset;
+    Sec->Size = Shdr.sh_size;
+    Sec->Link = Shdr.sh_link;
+    Sec->Info = Shdr.sh_info;
+    Sec->Align = Shdr.sh_addralign;
+    Sec->EntrySize = Shdr.sh_entsize;
+    Sec->Index = Index++;
+    Sec->OriginalData =
         ArrayRef<uint8_t>(ElfFile.base() + Shdr.sh_offset,
                           (Shdr.sh_type == SHT_NOBITS) ? 0 : Shdr.sh_size);
   }
+
+  return Error::success();
 }
 
-template <class ELFT> void ELFBuilder<ELFT>::readSections(bool EnsureSymtab) {
+template <class ELFT> Error ELFBuilder<ELFT>::readSections(bool EnsureSymtab) {
   uint32_t ShstrIndex = ElfFile.getHeader().e_shstrndx;
-  if (ShstrIndex == SHN_XINDEX)
-    ShstrIndex = unwrapOrError(ElfFile.getSection(0))->sh_link;
+  if (ShstrIndex == SHN_XINDEX) {
+    Expected<const Elf_Shdr *> Sec = ElfFile.getSection(0);
+    if (!Sec)
+      return Sec.takeError();
+
+    ShstrIndex = (*Sec)->sh_link;
+  }
 
   if (ShstrIndex == SHN_UNDEF)
     Obj.HadShdrs = false;
-  else
-    Obj.SectionNames =
+  else {
+    Expected<StringTableSection *> Sec =
         Obj.sections().template getSectionOfType<StringTableSection>(
             ShstrIndex,
             "e_shstrndx field value " + Twine(ShstrIndex) + " in elf header " +
                 " is invalid",
             "e_shstrndx field value " + Twine(ShstrIndex) + " in elf header " +
                 " does not reference a string table");
+    if (!Sec)
+      return Sec.takeError();
+
+    Obj.SectionNames = *Sec;
+  }
 
   // If a section index table exists we'll need to initialize it before we
   // initialize the symbol table because the symbol table might need to
   // reference it.
   if (Obj.SectionIndexTable)
-    Obj.SectionIndexTable->initialize(Obj.sections());
+    if (Error Err = Obj.SectionIndexTable->initialize(Obj.sections()))
+      return Err;
 
   // Now that all of the sections have been added we can fill out some extra
   // details about symbol tables. We need the symbol table filled out before
   // any relocations.
   if (Obj.SymbolTable) {
-    Obj.SymbolTable->initialize(Obj.sections());
-    initSymbolTable(Obj.SymbolTable);
+    if (Error Err = Obj.SymbolTable->initialize(Obj.sections()))
+      return Err;
+    if (Error Err = initSymbolTable(Obj.SymbolTable))
+      return Err;
   } else if (EnsureSymtab) {
-    Obj.addNewSymbolTable();
+    if (Error Err = Obj.addNewSymbolTable())
+      return Err;
   }
 
   // Now that all sections and symbols have been added we can add
   // relocations that reference symbols and set the link and info fields for
   // relocation sections.
-  for (auto &Sec : Obj.sections()) {
+  for (SectionBase &Sec : Obj.sections()) {
     if (&Sec == Obj.SymbolTable)
       continue;
-    Sec.initialize(Obj.sections());
+    if (Error Err = Sec.initialize(Obj.sections()))
+      return Err;
     if (auto RelSec = dyn_cast<RelocationSection>(&Sec)) {
-      auto Shdr = unwrapOrError(ElfFile.sections()).begin() + RelSec->Index;
-      if (RelSec->Type == SHT_REL)
-        initRelocations(RelSec, Obj.SymbolTable,
-                        unwrapOrError(ElfFile.rels(*Shdr)));
-      else
-        initRelocations(RelSec, Obj.SymbolTable,
-                        unwrapOrError(ElfFile.relas(*Shdr)));
+      Expected<typename ELFFile<ELFT>::Elf_Shdr_Range> Sections =
+          ElfFile.sections();
+      if (!Sections)
+        return Sections.takeError();
+
+      const typename ELFFile<ELFT>::Elf_Shdr *Shdr =
+          Sections->begin() + RelSec->Index;
+      if (RelSec->Type == SHT_REL) {
+        Expected<typename ELFFile<ELFT>::Elf_Rel_Range> Rels =
+            ElfFile.rels(*Shdr);
+        if (!Rels)
+          return Rels.takeError();
+
+        if (Error Err = initRelocations(RelSec, Obj.SymbolTable, *Rels))
+          return Err;
+      } else {
+        Expected<typename ELFFile<ELFT>::Elf_Rela_Range> Relas =
+            ElfFile.relas(*Shdr);
+        if (!Relas)
+          return Relas.takeError();
+
+        if (Error Err = initRelocations(RelSec, Obj.SymbolTable, *Relas))
+          return Err;
+      }
     } else if (auto GroupSec = dyn_cast<GroupSection>(&Sec)) {
-      initGroupSection(GroupSec);
+      if (Error Err = initGroupSection(GroupSec))
+        return Err;
     }
   }
+
+  return Error::success();
 }
 
-template <class ELFT> void ELFBuilder<ELFT>::build(bool EnsureSymtab) {
-  readSectionHeaders();
-  findEhdrOffset();
+template <class ELFT> Error ELFBuilder<ELFT>::build(bool EnsureSymtab) {
+  if (Error E = readSectionHeaders())
+    return E;
+  if (Error E = findEhdrOffset())
+    return E;
 
   // The ELFFile whose ELF headers and program headers are copied into the
   // output file. Normally the same as ElfFile, but if we're extracting a
   // loadable partition it will point to the partition's headers.
-  ELFFile<ELFT> HeadersFile = unwrapOrError(ELFFile<ELFT>::create(toStringRef(
-      {ElfFile.base() + EhdrOffset, ElfFile.getBufSize() - EhdrOffset})));
+  Expected<ELFFile<ELFT>> HeadersFile = ELFFile<ELFT>::create(toStringRef(
+      {ElfFile.base() + EhdrOffset, ElfFile.getBufSize() - EhdrOffset}));
+  if (!HeadersFile)
+    return HeadersFile.takeError();
 
-  auto &Ehdr = HeadersFile.getHeader();
+  const typename ELFFile<ELFT>::Elf_Ehdr &Ehdr = HeadersFile->getHeader();
   Obj.OSABI = Ehdr.e_ident[EI_OSABI];
   Obj.ABIVersion = Ehdr.e_ident[EI_ABIVERSION];
   Obj.Type = Ehdr.e_type;
@@ -1631,15 +1897,17 @@ template <class ELFT> void ELFBuilder<ELFT>::build(bool EnsureSymtab) {
   Obj.Entry = Ehdr.e_entry;
   Obj.Flags = Ehdr.e_flags;
 
-  readSections(EnsureSymtab);
-  readProgramHeaders(HeadersFile);
+  if (Error E = readSections(EnsureSymtab))
+    return E;
+  return readProgramHeaders(*HeadersFile);
 }
 
 Writer::~Writer() {}
 
 Reader::~Reader() {}
 
-std::unique_ptr<Object> BinaryReader::create(bool /*EnsureSymtab*/) const {
+Expected<std::unique_ptr<Object>>
+BinaryReader::create(bool /*EnsureSymtab*/) const {
   return BinaryELFBuilder(MemBuf, NewSymbolVisibility).build();
 }
 
@@ -1669,31 +1937,39 @@ Expected<std::vector<IHexRecord>> IHexReader::parse() const {
   return std::move(Records);
 }
 
-std::unique_ptr<Object> IHexReader::create(bool /*EnsureSymtab*/) const {
-  std::vector<IHexRecord> Records = unwrapOrError(parse());
-  return IHexELFBuilder(Records).build();
+Expected<std::unique_ptr<Object>>
+IHexReader::create(bool /*EnsureSymtab*/) const {
+  Expected<std::vector<IHexRecord>> Records = parse();
+  if (!Records)
+    return Records.takeError();
+
+  return IHexELFBuilder(*Records).build();
 }
 
-std::unique_ptr<Object> ELFReader::create(bool EnsureSymtab) const {
+Expected<std::unique_ptr<Object>> ELFReader::create(bool EnsureSymtab) const {
   auto Obj = std::make_unique<Object>();
   if (auto *O = dyn_cast<ELFObjectFile<ELF32LE>>(Bin)) {
     ELFBuilder<ELF32LE> Builder(*O, *Obj, ExtractPartition);
-    Builder.build(EnsureSymtab);
-    return Obj;
+    if (Error Err = Builder.build(EnsureSymtab))
+      return std::move(Err);
+    return std::move(Obj);
   } else if (auto *O = dyn_cast<ELFObjectFile<ELF64LE>>(Bin)) {
     ELFBuilder<ELF64LE> Builder(*O, *Obj, ExtractPartition);
-    Builder.build(EnsureSymtab);
-    return Obj;
+    if (Error Err = Builder.build(EnsureSymtab))
+      return std::move(Err);
+    return std::move(Obj);
   } else if (auto *O = dyn_cast<ELFObjectFile<ELF32BE>>(Bin)) {
     ELFBuilder<ELF32BE> Builder(*O, *Obj, ExtractPartition);
-    Builder.build(EnsureSymtab);
-    return Obj;
+    if (Error Err = Builder.build(EnsureSymtab))
+      return std::move(Err);
+    return std::move(Obj);
   } else if (auto *O = dyn_cast<ELFObjectFile<ELF64BE>>(Bin)) {
     ELFBuilder<ELF64BE> Builder(*O, *Obj, ExtractPartition);
-    Builder.build(EnsureSymtab);
-    return Obj;
+    if (Error Err = Builder.build(EnsureSymtab))
+      return std::move(Err);
+    return std::move(Obj);
   }
-  error("invalid file type");
+  return createStringError(errc::invalid_argument, "invalid file type");
 }
 
 template <class ELFT> void ELFWriter<ELFT>::writeEhdr() {
@@ -1787,13 +2063,16 @@ template <class ELFT> void ELFWriter<ELFT>::writeShdrs() {
     writeShdr(Sec);
 }
 
-template <class ELFT> void ELFWriter<ELFT>::writeSectionData() {
+template <class ELFT> Error ELFWriter<ELFT>::writeSectionData() {
   for (SectionBase &Sec : Obj.sections())
     // Segments are responsible for writing their contents, so only write the
     // section data if the section is not in a segment. Note that this renders
     // sections in segments effectively immutable.
     if (Sec.ParentSegment == nullptr)
-      Sec.accept(*SecWriter);
+      if (Error Err = Sec.accept(*SecWriter))
+        return Err;
+
+  return Error::success();
 }
 
 template <class ELFT> void ELFWriter<ELFT>::writeSegmentData() {
@@ -1880,7 +2159,7 @@ Error Object::removeSymbols(function_ref<bool(const Symbol &)> ToRemove) {
   return Error::success();
 }
 
-void Object::addNewSymbolTable() {
+Error Object::addNewSymbolTable() {
   assert(!SymbolTable && "Object must not has a SymbolTable.");
 
   // Reuse an existing SHT_STRTAB section if it exists.
@@ -1901,10 +2180,13 @@ void Object::addNewSymbolTable() {
   SymbolTableSection &SymTab = addSection<SymbolTableSection>();
   SymTab.Name = ".symtab";
   SymTab.Link = StrTab->Index;
-  SymTab.initialize(sections());
+  if (Error Err = SymTab.initialize(sections()))
+    return Err;
   SymTab.addSymbol("", 0, 0, nullptr, 0, 0, 0, 0);
 
   SymbolTable = &SymTab;
+
+  return Error::success();
 }
 
 void Object::sortSections() {
@@ -2118,7 +2400,8 @@ template <class ELFT> Error ELFWriter<ELFT>::write() {
   writeSegmentData();
   writeEhdr();
   writePhdrs();
-  writeSectionData();
+  if (Error E = writeSectionData())
+    return E;
   if (WriteSectionHeaders)
     writeShdrs();
   return Buf.commit();
@@ -2207,7 +2490,8 @@ template <class ELFT> Error ELFWriter<ELFT>::finalize() {
   auto SecSizer = std::make_unique<ELFSectionSizer<ELFT>>();
   for (SectionBase &Sec : Obj.sections()) {
     Sec.Index = Index++;
-    Sec.accept(*SecSizer);
+    if (Error Err = Sec.accept(*SecSizer))
+      return Err;
   }
 
   // The symbol table does not update all other sections on update. For
@@ -2248,7 +2532,9 @@ template <class ELFT> Error ELFWriter<ELFT>::finalize() {
 
 Error BinaryWriter::write() {
   for (const SectionBase &Sec : Obj.allocSections())
-    Sec.accept(*SecWriter);
+    if (Error Err = Sec.accept(*SecWriter))
+      return Err;
+
   return Buf.commit();
 }
 
@@ -2320,7 +2606,8 @@ Error IHexWriter::write() {
   IHexSectionWriter Writer(Buf);
   // Write sections.
   for (const SectionBase *Sec : Sections)
-    Sec->accept(Writer);
+    if (Error Err = Sec->accept(Writer))
+      return Err;
 
   uint64_t Offset = Writer.getBufferOffset();
   // Write entry point address.
@@ -2374,7 +2661,8 @@ Error IHexWriter::finalize() {
 
   IHexSectionWriterBase LengthCalc(Buf);
   for (const SectionBase *Sec : Sections)
-    Sec->accept(LengthCalc);
+    if (Error Err = Sec->accept(LengthCalc))
+      return Err;
 
   // We need space to write section records + StartAddress record
   // (if start adress is not zero) + EndOfFile record.

diff  --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/tools/llvm-objcopy/ELF/Object.h
index ed89e916b838..8fee4e29e964 100644
--- a/llvm/tools/llvm-objcopy/ELF/Object.h
+++ b/llvm/tools/llvm-objcopy/ELF/Object.h
@@ -61,10 +61,11 @@ class SectionTableRef {
   iterator end() const { return iterator(Sections.data() + Sections.size()); }
   size_t size() const { return Sections.size(); }
 
-  SectionBase *getSection(uint32_t Index, Twine ErrMsg);
+  Expected<SectionBase *> getSection(uint32_t Index, Twine ErrMsg);
 
   template <class T>
-  T *getSectionOfType(uint32_t Index, Twine IndexErrMsg, Twine TypeErrMsg);
+  Expected<T *> getSectionOfType(uint32_t Index, Twine IndexErrMsg,
+                                 Twine TypeErrMsg);
 };
 
 enum ElfType { ELFT_ELF32LE, ELFT_ELF64LE, ELFT_ELF32BE, ELFT_ELF64BE };
@@ -73,34 +74,34 @@ class SectionVisitor {
 public:
   virtual ~SectionVisitor() = default;
 
-  virtual void visit(const Section &Sec) = 0;
-  virtual void visit(const OwnedDataSection &Sec) = 0;
-  virtual void visit(const StringTableSection &Sec) = 0;
-  virtual void visit(const SymbolTableSection &Sec) = 0;
-  virtual void visit(const RelocationSection &Sec) = 0;
-  virtual void visit(const DynamicRelocationSection &Sec) = 0;
-  virtual void visit(const GnuDebugLinkSection &Sec) = 0;
-  virtual void visit(const GroupSection &Sec) = 0;
-  virtual void visit(const SectionIndexSection &Sec) = 0;
-  virtual void visit(const CompressedSection &Sec) = 0;
-  virtual void visit(const DecompressedSection &Sec) = 0;
+  virtual Error visit(const Section &Sec) = 0;
+  virtual Error visit(const OwnedDataSection &Sec) = 0;
+  virtual Error visit(const StringTableSection &Sec) = 0;
+  virtual Error visit(const SymbolTableSection &Sec) = 0;
+  virtual Error visit(const RelocationSection &Sec) = 0;
+  virtual Error visit(const DynamicRelocationSection &Sec) = 0;
+  virtual Error visit(const GnuDebugLinkSection &Sec) = 0;
+  virtual Error visit(const GroupSection &Sec) = 0;
+  virtual Error visit(const SectionIndexSection &Sec) = 0;
+  virtual Error visit(const CompressedSection &Sec) = 0;
+  virtual Error visit(const DecompressedSection &Sec) = 0;
 };
 
 class MutableSectionVisitor {
 public:
   virtual ~MutableSectionVisitor() = default;
 
-  virtual void visit(Section &Sec) = 0;
-  virtual void visit(OwnedDataSection &Sec) = 0;
-  virtual void visit(StringTableSection &Sec) = 0;
-  virtual void visit(SymbolTableSection &Sec) = 0;
-  virtual void visit(RelocationSection &Sec) = 0;
-  virtual void visit(DynamicRelocationSection &Sec) = 0;
-  virtual void visit(GnuDebugLinkSection &Sec) = 0;
-  virtual void visit(GroupSection &Sec) = 0;
-  virtual void visit(SectionIndexSection &Sec) = 0;
-  virtual void visit(CompressedSection &Sec) = 0;
-  virtual void visit(DecompressedSection &Sec) = 0;
+  virtual Error visit(Section &Sec) = 0;
+  virtual Error visit(OwnedDataSection &Sec) = 0;
+  virtual Error visit(StringTableSection &Sec) = 0;
+  virtual Error visit(SymbolTableSection &Sec) = 0;
+  virtual Error visit(RelocationSection &Sec) = 0;
+  virtual Error visit(DynamicRelocationSection &Sec) = 0;
+  virtual Error visit(GnuDebugLinkSection &Sec) = 0;
+  virtual Error visit(GroupSection &Sec) = 0;
+  virtual Error visit(SectionIndexSection &Sec) = 0;
+  virtual Error visit(CompressedSection &Sec) = 0;
+  virtual Error visit(DecompressedSection &Sec) = 0;
 };
 
 class SectionWriter : public SectionVisitor {
@@ -110,17 +111,17 @@ class SectionWriter : public SectionVisitor {
 public:
   virtual ~SectionWriter() = default;
 
-  void visit(const Section &Sec) override;
-  void visit(const OwnedDataSection &Sec) override;
-  void visit(const StringTableSection &Sec) override;
-  void visit(const DynamicRelocationSection &Sec) override;
-  virtual void visit(const SymbolTableSection &Sec) override = 0;
-  virtual void visit(const RelocationSection &Sec) override = 0;
-  virtual void visit(const GnuDebugLinkSection &Sec) override = 0;
-  virtual void visit(const GroupSection &Sec) override = 0;
-  virtual void visit(const SectionIndexSection &Sec) override = 0;
-  virtual void visit(const CompressedSection &Sec) override = 0;
-  virtual void visit(const DecompressedSection &Sec) override = 0;
+  Error visit(const Section &Sec) override;
+  Error visit(const OwnedDataSection &Sec) override;
+  Error visit(const StringTableSection &Sec) override;
+  Error visit(const DynamicRelocationSection &Sec) override;
+  virtual Error visit(const SymbolTableSection &Sec) override = 0;
+  virtual Error visit(const RelocationSection &Sec) override = 0;
+  virtual Error visit(const GnuDebugLinkSection &Sec) override = 0;
+  virtual Error visit(const GroupSection &Sec) override = 0;
+  virtual Error visit(const SectionIndexSection &Sec) override = 0;
+  virtual Error visit(const CompressedSection &Sec) override = 0;
+  virtual Error visit(const DecompressedSection &Sec) override = 0;
 
   explicit SectionWriter(Buffer &Buf) : Out(Buf) {}
 };
@@ -134,13 +135,13 @@ template <class ELFT> class ELFSectionWriter : public SectionWriter {
 
 public:
   virtual ~ELFSectionWriter() {}
-  void visit(const SymbolTableSection &Sec) override;
-  void visit(const RelocationSection &Sec) override;
-  void visit(const GnuDebugLinkSection &Sec) override;
-  void visit(const GroupSection &Sec) override;
-  void visit(const SectionIndexSection &Sec) override;
-  void visit(const CompressedSection &Sec) override;
-  void visit(const DecompressedSection &Sec) override;
+  Error visit(const SymbolTableSection &Sec) override;
+  Error visit(const RelocationSection &Sec) override;
+  Error visit(const GnuDebugLinkSection &Sec) override;
+  Error visit(const GroupSection &Sec) override;
+  Error visit(const SectionIndexSection &Sec) override;
+  Error visit(const CompressedSection &Sec) override;
+  Error visit(const DecompressedSection &Sec) override;
 
   explicit ELFSectionWriter(Buffer &Buf) : SectionWriter(Buf) {}
 };
@@ -154,17 +155,17 @@ template <class ELFT> class ELFSectionSizer : public MutableSectionVisitor {
   using Elf_Xword = typename ELFT::Xword;
 
 public:
-  void visit(Section &Sec) override;
-  void visit(OwnedDataSection &Sec) override;
-  void visit(StringTableSection &Sec) override;
-  void visit(DynamicRelocationSection &Sec) override;
-  void visit(SymbolTableSection &Sec) override;
-  void visit(RelocationSection &Sec) override;
-  void visit(GnuDebugLinkSection &Sec) override;
-  void visit(GroupSection &Sec) override;
-  void visit(SectionIndexSection &Sec) override;
-  void visit(CompressedSection &Sec) override;
-  void visit(DecompressedSection &Sec) override;
+  Error visit(Section &Sec) override;
+  Error visit(OwnedDataSection &Sec) override;
+  Error visit(StringTableSection &Sec) override;
+  Error visit(DynamicRelocationSection &Sec) override;
+  Error visit(SymbolTableSection &Sec) override;
+  Error visit(RelocationSection &Sec) override;
+  Error visit(GnuDebugLinkSection &Sec) override;
+  Error visit(GroupSection &Sec) override;
+  Error visit(SectionIndexSection &Sec) override;
+  Error visit(CompressedSection &Sec) override;
+  Error visit(DecompressedSection &Sec) override;
 };
 
 #define MAKE_SEC_WRITER_FRIEND                                                 \
@@ -178,13 +179,13 @@ class BinarySectionWriter : public SectionWriter {
 public:
   virtual ~BinarySectionWriter() {}
 
-  void visit(const SymbolTableSection &Sec) override;
-  void visit(const RelocationSection &Sec) override;
-  void visit(const GnuDebugLinkSection &Sec) override;
-  void visit(const GroupSection &Sec) override;
-  void visit(const SectionIndexSection &Sec) override;
-  void visit(const CompressedSection &Sec) override;
-  void visit(const DecompressedSection &Sec) override;
+  Error visit(const SymbolTableSection &Sec) override;
+  Error visit(const RelocationSection &Sec) override;
+  Error visit(const GnuDebugLinkSection &Sec) override;
+  Error visit(const GroupSection &Sec) override;
+  Error visit(const SectionIndexSection &Sec) override;
+  Error visit(const CompressedSection &Sec) override;
+  Error visit(const DecompressedSection &Sec) override;
 
   explicit BinarySectionWriter(Buffer &Buf) : SectionWriter(Buf) {}
 };
@@ -285,10 +286,10 @@ class IHexSectionWriterBase : public BinarySectionWriter {
   explicit IHexSectionWriterBase(Buffer &Buf) : BinarySectionWriter(Buf) {}
 
   uint64_t getBufferOffset() const { return Offset; }
-  void visit(const Section &Sec) final;
-  void visit(const OwnedDataSection &Sec) final;
-  void visit(const StringTableSection &Sec) override;
-  void visit(const DynamicRelocationSection &Sec) final;
+  Error visit(const Section &Sec) final;
+  Error visit(const OwnedDataSection &Sec) final;
+  Error visit(const StringTableSection &Sec) override;
+  Error visit(const DynamicRelocationSection &Sec) final;
   using BinarySectionWriter::visit;
 };
 
@@ -298,7 +299,7 @@ class IHexSectionWriter : public IHexSectionWriterBase {
   IHexSectionWriter(Buffer &Buf) : IHexSectionWriterBase(Buf) {}
 
   void writeData(uint8_t Type, uint16_t Addr, ArrayRef<uint8_t> Data) override;
-  void visit(const StringTableSection &Sec) override;
+  Error visit(const StringTableSection &Sec) override;
 };
 
 class Writer {
@@ -329,7 +330,7 @@ template <class ELFT> class ELFWriter : public Writer {
 
   void writePhdrs();
   void writeShdrs();
-  void writeSectionData();
+  Error writeSectionData();
   void writeSegmentData();
 
   void assignOffsets();
@@ -412,15 +413,15 @@ class SectionBase {
 
   virtual ~SectionBase() = default;
 
-  virtual void initialize(SectionTableRef SecTable);
+  virtual Error initialize(SectionTableRef SecTable);
   virtual void finalize();
   // Remove references to these sections. The list of sections must be sorted.
   virtual Error
   removeSectionReferences(bool AllowBrokenLinks,
                           function_ref<bool(const SectionBase *)> ToRemove);
   virtual Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove);
-  virtual void accept(SectionVisitor &Visitor) const = 0;
-  virtual void accept(MutableSectionVisitor &Visitor) = 0;
+  virtual Error accept(SectionVisitor &Visitor) const = 0;
+  virtual Error accept(MutableSectionVisitor &Visitor) = 0;
   virtual void markSymbols();
   virtual void
   replaceSectionReferences(const DenseMap<SectionBase *, SectionBase *> &);
@@ -481,11 +482,11 @@ class Section : public SectionBase {
 public:
   explicit Section(ArrayRef<uint8_t> Data) : Contents(Data) {}
 
-  void accept(SectionVisitor &Visitor) const override;
-  void accept(MutableSectionVisitor &Visitor) override;
+  Error accept(SectionVisitor &Visitor) const override;
+  Error accept(MutableSectionVisitor &Visitor) override;
   Error removeSectionReferences(bool AllowBrokenLinks,
       function_ref<bool(const SectionBase *)> ToRemove) override;
-  void initialize(SectionTableRef SecTable) override;
+  Error initialize(SectionTableRef SecTable) override;
   void finalize() override;
 };
 
@@ -513,8 +514,8 @@ class OwnedDataSection : public SectionBase {
   }
 
   void appendHexData(StringRef HexData);
-  void accept(SectionVisitor &Sec) const override;
-  void accept(MutableSectionVisitor &Visitor) override;
+  Error accept(SectionVisitor &Sec) const override;
+  Error accept(MutableSectionVisitor &Visitor) override;
 };
 
 class CompressedSection : public SectionBase {
@@ -526,21 +527,28 @@ class CompressedSection : public SectionBase {
   SmallVector<char, 128> CompressedData;
 
 public:
-  CompressedSection(const SectionBase &Sec,
-                    DebugCompressionType CompressionType);
-  CompressedSection(ArrayRef<uint8_t> CompressedData, uint64_t DecompressedSize,
-                    uint64_t DecompressedAlign);
+  static Expected<CompressedSection>
+  create(const SectionBase &Sec, DebugCompressionType CompressionType);
+  static Expected<CompressedSection> create(ArrayRef<uint8_t> CompressedData,
+                                            uint64_t DecompressedSize,
+                                            uint64_t DecompressedAlign);
 
   uint64_t getDecompressedSize() const { return DecompressedSize; }
   uint64_t getDecompressedAlign() const { return DecompressedAlign; }
 
-  void accept(SectionVisitor &Visitor) const override;
-  void accept(MutableSectionVisitor &Visitor) override;
+  Error accept(SectionVisitor &Visitor) const override;
+  Error accept(MutableSectionVisitor &Visitor) override;
 
   static bool classof(const SectionBase *S) {
     return (S->OriginalFlags & ELF::SHF_COMPRESSED) ||
            (StringRef(S->Name).startswith(".zdebug"));
   }
+
+private:
+  CompressedSection(const SectionBase &Sec,
+                    DebugCompressionType CompressionType, Error &Err);
+  CompressedSection(ArrayRef<uint8_t> CompressedData, uint64_t DecompressedSize,
+                    uint64_t DecompressedAlign);
 };
 
 class DecompressedSection : public SectionBase {
@@ -556,8 +564,8 @@ class DecompressedSection : public SectionBase {
       Name = "." + Name.substr(2);
   }
 
-  void accept(SectionVisitor &Visitor) const override;
-  void accept(MutableSectionVisitor &Visitor) override;
+  Error accept(SectionVisitor &Visitor) const override;
+  Error accept(MutableSectionVisitor &Visitor) override;
 };
 
 // There are two types of string tables that can exist, dynamic and not dynamic.
@@ -581,8 +589,8 @@ class StringTableSection : public SectionBase {
   void addString(StringRef Name);
   uint32_t findIndex(StringRef Name) const;
   void prepareForLayout();
-  void accept(SectionVisitor &Visitor) const override;
-  void accept(MutableSectionVisitor &Visitor) override;
+  Error accept(SectionVisitor &Visitor) const override;
+  Error accept(MutableSectionVisitor &Visitor) override;
 
   static bool classof(const SectionBase *S) {
     if (S->OriginalFlags & ELF::SHF_ALLOC)
@@ -647,10 +655,10 @@ class SectionIndexSection : public SectionBase {
     Size = NumSymbols * 4;
   }  
   void setSymTab(SymbolTableSection *SymTab) { Symbols = SymTab; }
-  void initialize(SectionTableRef SecTable) override;
+  Error initialize(SectionTableRef SecTable) override;
   void finalize() override;
-  void accept(SectionVisitor &Visitor) const override;
-  void accept(MutableSectionVisitor &Visitor) override;
+  Error accept(SectionVisitor &Visitor) const override;
+  Error accept(MutableSectionVisitor &Visitor) override;
 
   SectionIndexSection() {
     Name = ".symtab_shndx";
@@ -688,16 +696,16 @@ class SymbolTableSection : public SectionBase {
   const SectionIndexSection *getShndxTable() const { return SectionIndexTable; }
   void fillShndxTable();
   const SectionBase *getStrTab() const { return SymbolNames; }
-  const Symbol *getSymbolByIndex(uint32_t Index) const;
-  Symbol *getSymbolByIndex(uint32_t Index);
+  Expected<const Symbol *> getSymbolByIndex(uint32_t Index) const;
+  Expected<Symbol *> getSymbolByIndex(uint32_t Index);
   void updateSymbols(function_ref<void(Symbol &)> Callable);
 
   Error removeSectionReferences(bool AllowBrokenLinks,
       function_ref<bool(const SectionBase *)> ToRemove) override;
-  void initialize(SectionTableRef SecTable) override;
+  Error initialize(SectionTableRef SecTable) override;
   void finalize() override;
-  void accept(SectionVisitor &Visitor) const override;
-  void accept(MutableSectionVisitor &Visitor) override;
+  Error accept(SectionVisitor &Visitor) const override;
+  Error accept(MutableSectionVisitor &Visitor) override;
   Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
   void replaceSectionReferences(
       const DenseMap<SectionBase *, SectionBase *> &FromTo) override;
@@ -748,7 +756,7 @@ class RelocSectionWithSymtabBase : public RelocationSectionBase {
   SymTabType *Symbols = nullptr;
 
 public:
-  void initialize(SectionTableRef SecTable) override;
+  Error initialize(SectionTableRef SecTable) override;
   void finalize() override;
 };
 
@@ -760,8 +768,8 @@ class RelocationSection
 
 public:
   void addRelocation(Relocation Rel) { Relocations.push_back(Rel); }
-  void accept(SectionVisitor &Visitor) const override;
-  void accept(MutableSectionVisitor &Visitor) override;
+  Error accept(SectionVisitor &Visitor) const override;
+  Error accept(MutableSectionVisitor &Visitor) override;
   Error removeSectionReferences(bool AllowBrokenLinks,
       function_ref<bool(const SectionBase *)> ToRemove) override;
   Error removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override;
@@ -798,8 +806,8 @@ class GroupSection : public SectionBase {
   void setFlagWord(ELF::Elf32_Word W) { FlagWord = W; }
   void addMember(SectionBase *Sec) { GroupMembers.push_back(Sec); }
 
-  void accept(SectionVisitor &) const override;
-  void accept(MutableSectionVisitor &Visitor) override;
+  Error accept(SectionVisitor &) const override;
+  Error accept(MutableSectionVisitor &Visitor) override;
   void finalize() override;
   Error removeSectionReferences(
       bool AllowBrokenLinks,
@@ -843,8 +851,8 @@ class DynamicRelocationSection
 public:
   explicit DynamicRelocationSection(ArrayRef<uint8_t> Data) : Contents(Data) {}
 
-  void accept(SectionVisitor &) const override;
-  void accept(MutableSectionVisitor &Visitor) override;
+  Error accept(SectionVisitor &) const override;
+  Error accept(MutableSectionVisitor &Visitor) override;
   Error removeSectionReferences(
       bool AllowBrokenLinks,
       function_ref<bool(const SectionBase *)> ToRemove) override;
@@ -868,14 +876,14 @@ class GnuDebugLinkSection : public SectionBase {
 public:
   // If we add this section from an external source we can use this ctor.
   explicit GnuDebugLinkSection(StringRef File, uint32_t PrecomputedCRC);
-  void accept(SectionVisitor &Visitor) const override;
-  void accept(MutableSectionVisitor &Visitor) override;
+  Error accept(SectionVisitor &Visitor) const override;
+  Error accept(MutableSectionVisitor &Visitor) override;
 };
 
 class Reader {
 public:
   virtual ~Reader();
-  virtual std::unique_ptr<Object> create(bool EnsureSymtab) const = 0;
+  virtual Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const = 0;
 };
 
 using object::Binary;
@@ -891,7 +899,7 @@ class BasicELFBuilder {
   void initHeaderSegment();
   StringTableSection *addStrTab();
   SymbolTableSection *addSymTab(StringTableSection *StrTab);
-  void initSections();
+  Error initSections();
 
 public:
   BasicELFBuilder() : Obj(std::make_unique<Object>()) {}
@@ -907,7 +915,7 @@ class BinaryELFBuilder : public BasicELFBuilder {
       : BasicELFBuilder(), MemBuf(MB),
         NewSymbolVisibility(NewSymbolVisibility) {}
 
-  std::unique_ptr<Object> build();
+  Expected<std::unique_ptr<Object>> build();
 };
 
 class IHexELFBuilder : public BasicELFBuilder {
@@ -919,7 +927,7 @@ class IHexELFBuilder : public BasicELFBuilder {
   IHexELFBuilder(const std::vector<IHexRecord> &Records)
       : BasicELFBuilder(), Records(Records) {}
 
-  std::unique_ptr<Object> build();
+  Expected<std::unique_ptr<Object>> build();
 };
 
 template <class ELFT> class ELFBuilder {
@@ -934,13 +942,13 @@ template <class ELFT> class ELFBuilder {
   Optional<StringRef> ExtractPartition;
 
   void setParentSegment(Segment &Child);
-  void readProgramHeaders(const ELFFile<ELFT> &HeadersFile);
-  void initGroupSection(GroupSection *GroupSec);
-  void initSymbolTable(SymbolTableSection *SymTab);
-  void readSectionHeaders();
-  void readSections(bool EnsureSymtab);
-  void findEhdrOffset();
-  SectionBase &makeSection(const Elf_Shdr &Shdr);
+  Error readProgramHeaders(const ELFFile<ELFT> &HeadersFile);
+  Error initGroupSection(GroupSection *GroupSec);
+  Error initSymbolTable(SymbolTableSection *SymTab);
+  Error readSectionHeaders();
+  Error readSections(bool EnsureSymtab);
+  Error findEhdrOffset();
+  Expected<SectionBase &> makeSection(const Elf_Shdr &Shdr);
 
 public:
   ELFBuilder(const ELFObjectFile<ELFT> &ElfObj, Object &Obj,
@@ -948,7 +956,7 @@ template <class ELFT> class ELFBuilder {
       : ElfFile(*ElfObj.getELFFile()), Obj(Obj),
         ExtractPartition(ExtractPartition) {}
 
-  void build(bool EnsureSymtab);
+  Error build(bool EnsureSymtab);
 };
 
 class BinaryReader : public Reader {
@@ -958,7 +966,7 @@ class BinaryReader : public Reader {
 public:
   BinaryReader(MemoryBuffer *MB, const uint8_t NewSymbolVisibility)
       : MemBuf(MB), NewSymbolVisibility(NewSymbolVisibility) {}
-  std::unique_ptr<Object> create(bool EnsureSymtab) const override;
+  Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
 };
 
 class IHexReader : public Reader {
@@ -980,7 +988,7 @@ class IHexReader : public Reader {
 public:
   IHexReader(MemoryBuffer *MB) : MemBuf(MB) {}
 
-  std::unique_ptr<Object> create(bool EnsureSymtab) const override;
+  Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
 };
 
 class ELFReader : public Reader {
@@ -988,7 +996,7 @@ class ELFReader : public Reader {
   Optional<StringRef> ExtractPartition;
 
 public:
-  std::unique_ptr<Object> create(bool EnsureSymtab) const override;
+  Expected<std::unique_ptr<Object>> create(bool EnsureSymtab) const override;
   explicit ELFReader(Binary *B, Optional<StringRef> ExtractPartition)
       : Bin(B), ExtractPartition(ExtractPartition) {}
 };
@@ -1072,7 +1080,7 @@ class Object {
     Ptr->Index = Sections.size();
     return *Ptr;
   }
-  void addNewSymbolTable();
+  Error addNewSymbolTable();
   Segment &addSegment(ArrayRef<uint8_t> Data) {
     Segments.emplace_back(std::make_unique<Segment>(Data));
     return *Segments.back();

diff  --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp b/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp
index 46c869d72c6e..6e6975c35139 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp
+++ b/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp
@@ -7,7 +7,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "MachOReader.h"
-#include "../llvm-objcopy.h"
 #include "Object.h"
 #include "llvm/BinaryFormat/MachO.h"
 #include "llvm/Object/MachO.h"

diff  --git a/llvm/tools/llvm-objcopy/MachO/Object.cpp b/llvm/tools/llvm-objcopy/MachO/Object.cpp
index 6a89076bafcf..4302904437fd 100644
--- a/llvm/tools/llvm-objcopy/MachO/Object.cpp
+++ b/llvm/tools/llvm-objcopy/MachO/Object.cpp
@@ -7,7 +7,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "Object.h"
-#include "../llvm-objcopy.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include <unordered_set>
 

diff  --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
index ee882ffb2742..175f2929eb23 100644
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -6,7 +6,6 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm-objcopy.h"
 #include "Buffer.h"
 #include "COFF/COFFObjcopy.h"
 #include "CopyConfig.h"
@@ -57,36 +56,6 @@ namespace objcopy {
 // The name this program was invoked as.
 StringRef ToolName;
 
-LLVM_ATTRIBUTE_NORETURN void error(Twine Message) {
-  WithColor::error(errs(), ToolName) << Message << "\n";
-  exit(1);
-}
-
-LLVM_ATTRIBUTE_NORETURN void error(Error E) {
-  assert(E);
-  std::string Buf;
-  raw_string_ostream OS(Buf);
-  logAllUnhandledErrors(std::move(E), OS);
-  OS.flush();
-  WithColor::error(errs(), ToolName) << Buf;
-  exit(1);
-}
-
-LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, std::error_code EC) {
-  assert(EC);
-  error(createFileError(File, EC));
-}
-
-LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, Error E) {
-  assert(E);
-  std::string Buf;
-  raw_string_ostream OS(Buf);
-  logAllUnhandledErrors(std::move(E), OS);
-  OS.flush();
-  WithColor::error(errs(), ToolName) << "'" << File << "': " << Buf;
-  exit(1);
-}
-
 ErrorSuccess reportWarning(Error E) {
   assert(E);
   WithColor::warning(errs(), ToolName) << toString(std::move(E)) << '\n';

diff  --git a/llvm/tools/llvm-objcopy/llvm-objcopy.h b/llvm/tools/llvm-objcopy/llvm-objcopy.h
deleted file mode 100644
index 18a789ca1f83..000000000000
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.h
+++ /dev/null
@@ -1,42 +0,0 @@
-//===- llvm-objcopy.h -------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TOOLS_OBJCOPY_OBJCOPY_H
-#define LLVM_TOOLS_OBJCOPY_OBJCOPY_H
-
-#include "llvm/ADT/Twine.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/raw_ostream.h"
-#include <string>
-
-namespace llvm {
-namespace objcopy {
-
-LLVM_ATTRIBUTE_NORETURN extern void error(Twine Message);
-LLVM_ATTRIBUTE_NORETURN extern void error(Error E);
-LLVM_ATTRIBUTE_NORETURN extern void reportError(StringRef File, Error E);
-LLVM_ATTRIBUTE_NORETURN extern void reportError(StringRef File,
-                                                std::error_code EC);
-
-// This is taken from llvm-readobj.
-// [see here](llvm/tools/llvm-readobj/llvm-readobj.h:38)
-template <class T> T unwrapOrError(Expected<T> EO) {
-  if (EO)
-    return *EO;
-  std::string Buf;
-  raw_string_ostream OS(Buf);
-  logAllUnhandledErrors(EO.takeError(), OS);
-  OS.flush();
-  error(Buf);
-}
-
-} // end namespace objcopy
-} // end namespace llvm
-
-#endif // LLVM_TOOLS_OBJCOPY_OBJCOPY_H

diff  --git a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp b/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp
index 20781cef2d33..eb0e5635cef9 100644
--- a/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/wasm/WasmObjcopy.cpp
@@ -12,7 +12,6 @@
 #include "Object.h"
 #include "Reader.h"
 #include "Writer.h"
-#include "llvm-objcopy.h"
 #include "llvm/Support/Errc.h"
 
 namespace llvm {


        


More information about the llvm-commits mailing list