Index: llvm/trunk/test/tools/llvm-objcopy/ELF/bad-build-id.test =================================================================== --- llvm/trunk/test/tools/llvm-objcopy/ELF/bad-build-id.test +++ llvm/trunk/test/tools/llvm-objcopy/ELF/bad-build-id.test @@ -1,7 +1,7 @@ # RUN: yaml2obj %s > %t # RUN: not llvm-objcopy --build-id-link-dir=%t-dir --build-id-link-input=.debug %t 2>&1 >/dev/null | FileCheck %s -# CHECK: build ID in file {{.*}} is smaller than two bytes. +# CHECK: build ID is smaller than two bytes. --- !ELF FileHeader: Index: llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.h =================================================================== --- llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.h +++ llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.h @@ -10,6 +10,7 @@ #define LLVM_TOOLS_OBJCOPY_COFFOBJCOPY_H namespace llvm { +class Error; namespace object { class COFFObjectFile; @@ -20,8 +21,8 @@ class Buffer; namespace coff { -void executeObjcopyOnBinary(const CopyConfig &Config, - object::COFFObjectFile &In, Buffer &Out); +Error executeObjcopyOnBinary(const CopyConfig &Config, + object::COFFObjectFile &In, Buffer &Out); } // end namespace coff } // end namespace objcopy Index: llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp =================================================================== --- llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp +++ llvm/trunk/tools/llvm-objcopy/COFF/COFFObjcopy.cpp @@ -188,19 +188,20 @@ return Error::success(); } -void executeObjcopyOnBinary(const CopyConfig &Config, - COFFObjectFile &In, Buffer &Out) { +Error executeObjcopyOnBinary(const CopyConfig &Config, COFFObjectFile &In, + Buffer &Out) { COFFReader Reader(In); Expected> ObjOrErr = Reader.create(); if (!ObjOrErr) - reportError(Config.InputFilename, ObjOrErr.takeError()); + return createFileError(Config.InputFilename, ObjOrErr.takeError()); Object *Obj = ObjOrErr->get(); assert(Obj && "Unable to deserialize COFF object"); if (Error E = handleArgs(Config, *Obj)) - reportError(Config.InputFilename, std::move(E)); + return createFileError(Config.InputFilename, std::move(E)); COFFWriter Writer(*Obj, Out); if (Error E = Writer.write()) - reportError(Config.OutputFilename, std::move(E)); + return createFileError(Config.OutputFilename, std::move(E)); + return Error::success(); } } // end namespace coff Index: llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.h =================================================================== --- llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.h +++ llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.h @@ -10,6 +10,7 @@ #define LLVM_TOOLS_OBJCOPY_ELFOBJCOPY_H namespace llvm { +class Error; class MemoryBuffer; namespace object { @@ -21,10 +22,10 @@ class Buffer; namespace elf { -void executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In, - Buffer &Out); -void executeObjcopyOnBinary(const CopyConfig &Config, - object::ELFObjectFileBase &In, Buffer &Out); +Error executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In, + Buffer &Out); +Error executeObjcopyOnBinary(const CopyConfig &Config, + object::ELFObjectFileBase &In, Buffer &Out); } // end namespace elf } // end namespace objcopy Index: llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp =================================================================== --- llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp +++ llvm/trunk/tools/llvm-objcopy/ELF/ELFObjcopy.cpp @@ -178,8 +178,8 @@ } } -static void splitDWOToFile(const CopyConfig &Config, const Reader &Reader, - StringRef File, ElfType OutputElfType) { +static Error splitDWOToFile(const CopyConfig &Config, const Reader &Reader, + StringRef File, ElfType OutputElfType) { auto DWOFile = Reader.create(); DWOFile->removeSections( [&](const SectionBase &Sec) { return onlyKeepDWOPred(*DWOFile, Sec); }); @@ -188,9 +188,8 @@ FileBuffer FB(File); auto Writer = createWriter(Config, *DWOFile, FB, OutputElfType); if (Error E = Writer->finalize()) - error(std::move(E)); - if (Error E = Writer->write()) - error(std::move(E)); + return E; + return Writer->write(); } static Error dumpSectionToFile(StringRef SecName, StringRef Filename, @@ -269,12 +268,14 @@ // any previous removals. Lastly whether or not something is removed shouldn't // depend a) on the order the options occur in or b) on some opaque priority // system. The only priority is that keeps/copies overrule removes. -static void handleArgs(const CopyConfig &Config, Object &Obj, - const Reader &Reader, ElfType OutputElfType) { +static Error handleArgs(const CopyConfig &Config, Object &Obj, + const Reader &Reader, ElfType OutputElfType) { + + if (!Config.SplitDWO.empty()) + if (Error E = + splitDWOToFile(Config, Reader, Config.SplitDWO, OutputElfType)) + return E; - if (!Config.SplitDWO.empty()) { - splitDWOToFile(Config, Reader, Config.SplitDWO, OutputElfType); - } if (Config.OutputArch) Obj.Machine = Config.OutputArch.getValue().EMachine; @@ -520,7 +521,7 @@ ErrorOr> BufOrErr = MemoryBuffer::getFile(File); if (!BufOrErr) - reportError(File, BufOrErr.getError()); + return createFileError(File, errorCodeToError(BufOrErr.getError())); std::unique_ptr Buf = std::move(*BufOrErr); ArrayRef Data( reinterpret_cast(Buf->getBufferStart()), @@ -538,16 +539,18 @@ StringRef SecName = SecPair.first; StringRef File = SecPair.second; if (Error E = dumpSectionToFile(SecName, File, Obj)) - reportError(Config.InputFilename, std::move(E)); + return createFileError(Config.InputFilename, std::move(E)); } } if (!Config.AddGnuDebugLink.empty()) Obj.addSection(Config.AddGnuDebugLink); + + return Error::success(); } -void executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In, - Buffer &Out) { +Error executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In, + Buffer &Out) { BinaryReader Reader(Config.BinaryArch, &In); std::unique_ptr Obj = Reader.create(); @@ -555,17 +558,17 @@ // (-B). const ElfType OutputElfType = getOutputElfType( Config.OutputArch ? Config.OutputArch.getValue() : Config.BinaryArch); - handleArgs(Config, *Obj, Reader, OutputElfType); + if (Error E = handleArgs(Config, *Obj, Reader, OutputElfType)) + return E; std::unique_ptr Writer = createWriter(Config, *Obj, Out, OutputElfType); if (Error E = Writer->finalize()) - error(std::move(E)); - if (Error E = Writer->write()) - error(std::move(E)); + return E; + return Writer->write(); } -void executeObjcopyOnBinary(const CopyConfig &Config, - object::ELFObjectFileBase &In, Buffer &Out) { +Error executeObjcopyOnBinary(const CopyConfig &Config, + object::ELFObjectFileBase &In, Buffer &Out) { ELFReader Reader(&In); std::unique_ptr Obj = Reader.create(); // Prefer OutputArch (-O) if set, otherwise infer it from the input. @@ -577,25 +580,29 @@ if (!Config.BuildIdLinkDir.empty()) { BuildIdBytes = unwrapOrError(findBuildID(In)); if (BuildIdBytes.size() < 2) - error("build ID in file '" + Config.InputFilename + - "' is smaller than two bytes"); + return createFileError( + Config.InputFilename, + createStringError(object_error::parse_failed, + "build ID is smaller than two bytes.")); } if (!Config.BuildIdLinkDir.empty() && Config.BuildIdLinkInput) { linkToBuildIdDir(Config, Config.InputFilename, Config.BuildIdLinkInput.getValue(), BuildIdBytes); } - handleArgs(Config, *Obj, Reader, OutputElfType); + if (Error E = handleArgs(Config, *Obj, Reader, OutputElfType)) + return E; std::unique_ptr Writer = createWriter(Config, *Obj, Out, OutputElfType); if (Error E = Writer->finalize()) - error(std::move(E)); + return E; if (Error E = Writer->write()) - error(std::move(E)); + return E; if (!Config.BuildIdLinkDir.empty() && Config.BuildIdLinkOutput) { linkToBuildIdDir(Config, Config.OutputFilename, Config.BuildIdLinkOutput.getValue(), BuildIdBytes); } + return Error::success(); } } // end namespace elf Index: llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp =================================================================== --- llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp +++ llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp @@ -122,8 +122,8 @@ /// The function executeObjcopyOnRawBinary does the dispatch based on the format /// of the output specified by the command line options. -static void executeObjcopyOnRawBinary(const CopyConfig &Config, - MemoryBuffer &In, Buffer &Out) { +static Error executeObjcopyOnRawBinary(const CopyConfig &Config, + MemoryBuffer &In, Buffer &Out) { // TODO: llvm-objcopy should parse CopyConfig.OutputFormat to recognize // formats other than ELF / "binary" and invoke // elf::executeObjcopyOnRawBinary, macho::executeObjcopyOnRawBinary or @@ -133,18 +133,19 @@ /// The function executeObjcopyOnBinary does the dispatch based on the format /// of the input binary (ELF, MachO or COFF). -static void executeObjcopyOnBinary(const CopyConfig &Config, object::Binary &In, - Buffer &Out) { +static Error executeObjcopyOnBinary(const CopyConfig &Config, + object::Binary &In, Buffer &Out) { if (auto *ELFBinary = dyn_cast(&In)) return elf::executeObjcopyOnBinary(Config, *ELFBinary, Out); else if (auto *COFFBinary = dyn_cast(&In)) return coff::executeObjcopyOnBinary(Config, *COFFBinary, Out); else - error("Unsupported object file format"); + return createStringError(object_error::invalid_file_type, + "Unsupported object file format"); } -static void executeObjcopyOnArchive(const CopyConfig &Config, - const Archive &Ar) { +static Error executeObjcopyOnArchive(const CopyConfig &Config, + const Archive &Ar) { std::vector NewArchiveMembers; Error Err = Error::success(); for (const Archive::Child &Child : Ar.children(Err)) { @@ -158,7 +159,8 @@ reportError(Ar.getFileName(), ChildNameOrErr.takeError()); MemBuffer MB(ChildNameOrErr.get()); - executeObjcopyOnBinary(Config, *Bin, MB); + if (Error E = executeObjcopyOnBinary(Config, *Bin, MB)) + return E; Expected Member = NewArchiveMember::getOldMember(Child, Config.DeterministicArchives); @@ -175,6 +177,7 @@ Ar.hasSymbolTable(), Ar.kind(), Config.DeterministicArchives, Ar.isThin())) reportError(Config.OutputFilename, std::move(E)); + return Error::success(); } static void restoreDateOnFile(StringRef Filename, @@ -207,7 +210,8 @@ if (!BufOrErr) reportError(Config.InputFilename, BufOrErr.getError()); FileBuffer FB(Config.OutputFilename); - executeObjcopyOnRawBinary(Config, *BufOrErr->get(), FB); + if (Error E = executeObjcopyOnRawBinary(Config, *BufOrErr->get(), FB)) + error(std::move(E)); } else { Expected> BinaryOrErr = createBinary(Config.InputFilename); @@ -215,10 +219,13 @@ reportError(Config.InputFilename, BinaryOrErr.takeError()); if (Archive *Ar = dyn_cast(BinaryOrErr.get().getBinary())) { - executeObjcopyOnArchive(Config, *Ar); + if (Error E = executeObjcopyOnArchive(Config, *Ar)) + error(std::move(E)); } else { FileBuffer FB(Config.OutputFilename); - executeObjcopyOnBinary(Config, *BinaryOrErr.get().getBinary(), FB); + if (Error E = executeObjcopyOnBinary(Config, + *BinaryOrErr.get().getBinary(), FB)) + error(std::move(E)); } }