diff options
Diffstat (limited to 'llvm/tools/llvm-objcopy/llvm-objcopy.cpp')
-rw-r--r-- | llvm/tools/llvm-objcopy/llvm-objcopy.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp index edc45ee3611..0c153d521c7 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -137,6 +137,7 @@ struct CopyConfig { std::vector<StringRef> Keep; std::vector<StringRef> OnlyKeep; std::vector<StringRef> AddSection; + std::vector<StringRef> DumpSection; std::vector<StringRef> SymbolsToLocalize; std::vector<StringRef> SymbolsToGlobalize; std::vector<StringRef> SymbolsToWeaken; @@ -323,6 +324,30 @@ static void SplitDWOToFile(const CopyConfig &Config, const Reader &Reader, Writer->write(); } +static Error dumpSectionToFile(StringRef SecName, StringRef Filename, + Object &Obj) { + for (auto &Sec : Obj.sections()) { + if (Sec.Name == SecName) { + if (Sec.OriginalData.size() == 0) + return make_error<StringError>("Can't dump section \"" + SecName + + "\": it has no contents", + object_error::parse_failed); + Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr = + FileOutputBuffer::create(Filename, Sec.OriginalData.size()); + if (!BufferOrErr) + return BufferOrErr.takeError(); + std::unique_ptr<FileOutputBuffer> Buf = std::move(*BufferOrErr); + std::copy(Sec.OriginalData.begin(), Sec.OriginalData.end(), + Buf->getBufferStart()); + if (Error E = Buf->commit()) + return E; + return Error::success(); + } + } + return make_error<StringError>("Section not found", + object_error::parse_failed); +} + // This function handles the high level operations of GNU objcopy including // handling command line options. It's important to outline certain properties // we expect to hold of the command line operations. Any operation that "keeps" @@ -555,6 +580,16 @@ static void HandleArgs(const CopyConfig &Config, Object &Obj, } } + if (!Config.DumpSection.empty()) { + for (const auto &Flag : Config.DumpSection) { + std::pair<StringRef, StringRef> SecPair = Flag.split("="); + StringRef SecName = SecPair.first; + StringRef File = SecPair.second; + if (Error E = dumpSectionToFile(SecName, File, Obj)) + reportError(Config.InputFilename, std::move(E)); + } + } + if (!Config.AddGnuDebugLink.empty()) Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink); } @@ -711,6 +746,8 @@ static CopyConfig ParseObjcopyOptions(ArrayRef<const char *> ArgsArr) { Config.OnlyKeep.push_back(Arg->getValue()); for (auto Arg : InputArgs.filtered(OBJCOPY_add_section)) Config.AddSection.push_back(Arg->getValue()); + for (auto Arg : InputArgs.filtered(OBJCOPY_dump_section)) + Config.DumpSection.push_back(Arg->getValue()); Config.StripAll = InputArgs.hasArg(OBJCOPY_strip_all); Config.StripAllGNU = InputArgs.hasArg(OBJCOPY_strip_all_gnu); Config.StripDebug = InputArgs.hasArg(OBJCOPY_strip_debug); |