diff --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp @@ -360,14 +360,11 @@ Error executeObjcopyOnBinary(const CopyConfig &Config, object::MachOObjectFile &In, Buffer &Out) { MachOReader Reader(In); - std::unique_ptr O = Reader.create(); + Expected> O = Reader.create(); if (!O) - return createFileError( - Config.InputFilename, - createStringError(object_error::parse_failed, - "unable to deserialize MachO object")); + return createFileError(Config.InputFilename, O.takeError()); - if (Error E = handleArgs(Config, *O)) + if (Error E = handleArgs(Config, **O)) return createFileError(Config.InputFilename, std::move(E)); // Page size used for alignment of segment sizes in Mach-O executables and @@ -383,7 +380,7 @@ PageSize = 4096; } - MachOWriter Writer(*O, In.is64Bit(), In.isLittleEndian(), PageSize, Out); + MachOWriter Writer(**O, In.is64Bit(), In.isLittleEndian(), PageSize, Out); if (auto E = Writer.finalize()) return E; return Writer.write(); diff --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.h b/llvm/tools/llvm-objcopy/MachO/MachOReader.h --- a/llvm/tools/llvm-objcopy/MachO/MachOReader.h +++ b/llvm/tools/llvm-objcopy/MachO/MachOReader.h @@ -21,14 +21,14 @@ class Reader { public: virtual ~Reader(){}; - virtual std::unique_ptr create() const = 0; + virtual Expected> create() const = 0; }; class MachOReader : public Reader { const object::MachOObjectFile &MachOObj; void readHeader(Object &O) const; - void readLoadCommands(Object &O) const; + Error readLoadCommands(Object &O) const; void readSymbolTable(Object &O) const; void setSymbolInRelocationInfo(Object &O) const; void readRebaseInfo(Object &O) const; @@ -46,7 +46,7 @@ public: explicit MachOReader(const object::MachOObjectFile &Obj) : MachOObj(Obj) {} - std::unique_ptr create() const override; + Expected> create() const override; }; } // end namespace macho diff --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp b/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp @@ -11,6 +11,7 @@ #include "Object.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/Object/MachO.h" +#include "llvm/Support/Errc.h" #include namespace llvm { @@ -59,9 +60,8 @@ return S; } -// TODO: get rid of reportError and make MachOReader return Expected<> instead. template -std::vector> +Expected>> extractSections(const object::MachOObjectFile::LoadCommandInfo &LoadCmd, const object::MachOObjectFile &MachOObj, uint32_t &NextSectionIndex) { @@ -86,14 +86,15 @@ Expected SecRef = MachOObj.getSection(NextSectionIndex++); if (!SecRef) - reportError(MachOObj.getFileName(), SecRef.takeError()); + return SecRef.takeError(); - if (Expected> E = - MachOObj.getSectionContents(SecRef->getRawDataRefImpl())) - S.Content = - StringRef(reinterpret_cast(E->data()), E->size()); - else - reportError(MachOObj.getFileName(), E.takeError()); + Expected> Data = + MachOObj.getSectionContents(SecRef->getRawDataRefImpl()); + if (!Data) + return Data.takeError(); + + S.Content = + StringRef(reinterpret_cast(Data->data()), Data->size()); S.Relocations.reserve(S.NReloc); for (auto RI = MachOObj.section_rel_begin(SecRef->getRawDataRefImpl()), @@ -113,7 +114,7 @@ return Sections; } -void MachOReader::readLoadCommands(Object &O) const { +Error MachOReader::readLoadCommands(Object &O) const { // For MachO sections indices start from 1. uint32_t NextSectionIndex = 1; for (auto LoadCmd : MachOObj.load_commands()) { @@ -123,13 +124,20 @@ O.CodeSignatureCommandIndex = O.LoadCommands.size(); break; case MachO::LC_SEGMENT: - LC.Sections = extractSections( - LoadCmd, MachOObj, NextSectionIndex); + if (Expected>> Sections = + extractSections( + LoadCmd, MachOObj, NextSectionIndex)) + LC.Sections = std::move(*Sections); + else + return Sections.takeError(); break; case MachO::LC_SEGMENT_64: - LC.Sections = - extractSections( - LoadCmd, MachOObj, NextSectionIndex); + if (Expected>> Sections = + extractSections( + LoadCmd, MachOObj, NextSectionIndex)) + LC.Sections = std::move(*Sections); + else + return Sections.takeError(); break; case MachO::LC_SYMTAB: O.SymTabCommandIndex = O.LoadCommands.size(); @@ -177,6 +185,7 @@ } O.LoadCommands.push_back(std::move(LC)); } + return Error::success(); } template @@ -308,10 +317,11 @@ } } -std::unique_ptr MachOReader::create() const { +Expected> MachOReader::create() const { auto Obj = std::make_unique(); readHeader(*Obj); - readLoadCommands(*Obj); + if (Error E = readLoadCommands(*Obj)) + return std::move(E); readSymbolTable(*Obj); setSymbolInRelocationInfo(*Obj); readRebaseInfo(*Obj);