diff options
Diffstat (limited to 'llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp')
| -rw-r--r-- | llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp | 153 |
1 files changed, 90 insertions, 63 deletions
diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp index 66953f9ef0d5..c53a34bc46a3 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" @@ -185,28 +184,28 @@ findBuildID(const CopyConfig &Config, const object::ELFFile<ELFT> &In) { return createFileError(Config.InputFilename, std::move(Err)); } - return createFileError( - Config.InputFilename, - createStringError(llvm::errc::invalid_argument, - "could not find build ID")); + return createFileError(Config.InputFilename, + createStringError(llvm::errc::invalid_argument, + "could not find build ID")); } static Expected<ArrayRef<uint8_t>> findBuildID(const CopyConfig &Config, const object::ELFObjectFileBase &In) { if (auto *O = dyn_cast<ELFObjectFile<ELF32LE>>(&In)) - return findBuildID(Config, *O->getELFFile()); + return findBuildID(Config, O->getELFFile()); else if (auto *O = dyn_cast<ELFObjectFile<ELF64LE>>(&In)) - return findBuildID(Config, *O->getELFFile()); + return findBuildID(Config, O->getELFFile()); else if (auto *O = dyn_cast<ELFObjectFile<ELF32BE>>(&In)) - return findBuildID(Config, *O->getELFFile()); + return findBuildID(Config, O->getELFFile()); else if (auto *O = dyn_cast<ELFObjectFile<ELF64BE>>(&In)) - return findBuildID(Config, *O->getELFFile()); + return findBuildID(Config, O->getELFFile()); llvm_unreachable("Bad file format"); } template <class... Ts> -static Error makeStringError(std::error_code EC, const Twine &Msg, Ts &&... Args) { +static Error makeStringError(std::error_code EC, const Twine &Msg, + Ts &&... Args) { std::string FullMsg = (EC.message() + ": " + Msg).str(); return createStringError(EC, FullMsg.c_str(), std::forward<Ts>(Args)...); } @@ -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,22 +316,27 @@ 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<bool(const SectionBase &)> ShouldReplace, + 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()) - if (shouldReplace(Sec)) + if (ShouldReplace(Sec)) ToReplace.push_back(&Sec); // 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 @@ -336,9 +344,11 @@ static void replaceDebugSections( for (auto &Sec : Obj.sections()) Sec.replaceSectionReferences(FromTo); - RemovePred = [shouldReplace, RemovePred](const SectionBase &Sec) { - return shouldReplace(Sec) || RemovePred(Sec); + 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); } @@ -701,16 +719,6 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj, } } - if (!Config.SetSectionFlags.empty()) { - for (auto &Sec : Obj.sections()) { - const auto Iter = Config.SetSectionFlags.find(Sec.Name); - if (Iter != Config.SetSectionFlags.end()) { - const SectionFlagsUpdate &SFU = Iter->second; - setSectionFlagsAndType(Sec, SFU.NewFlags); - } - } - } - if (Config.OnlyKeepDebug) for (auto &Sec : Obj.sections()) if (Sec.Flags & SHF_ALLOC && Sec.Type != SHT_NOTE) @@ -740,9 +748,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); @@ -752,6 +760,17 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj, Sec ? (uint16_t)SYMBOL_SIMPLE_INDEX : (uint16_t)SHN_ABS, 0); } + // --set-section-flags works with sections added by --add-section. + if (!Config.SetSectionFlags.empty()) { + for (auto &Sec : Obj.sections()) { + const auto Iter = Config.SetSectionFlags.find(Sec.Name); + if (Iter != Config.SetSectionFlags.end()) { + const SectionFlagsUpdate &SFU = Iter->second; + setSectionFlagsAndType(Sec, SFU.NewFlags); + } + } + } + if (Config.EntryExpr) Obj.Entry = Config.EntryExpr(Obj.Entry); return Error::success(); @@ -769,12 +788,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)) + getOutputElfType(Config.OutputArch.getValueOr(MachineInfo())); + 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 +804,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 +849,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 = |
