Mercurial > hg > CbC > CbC_llvm
diff tools/llvm-objcopy/llvm-objcopy.cpp @ 122:36195a0db682
merging ( incomplete )
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Nov 2017 20:32:31 +0900 |
parents | 803732b1fca8 |
children | 3a76565eade5 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/llvm-objcopy/llvm-objcopy.cpp Fri Nov 17 20:32:31 2017 +0900 @@ -0,0 +1,132 @@ +//===- llvm-objcopy.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +#include "llvm-objcopy.h" +#include "Object.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileOutputBuffer.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/ToolOutputFile.h" + +#include <memory> +#include <string> +#include <system_error> + +using namespace llvm; +using namespace object; +using namespace ELF; + +// The name this program was invoked as. +static StringRef ToolName; + +namespace llvm { + +LLVM_ATTRIBUTE_NORETURN void error(Twine Message) { + errs() << ToolName << ": " << Message << ".\n"; + errs().flush(); + exit(1); +} + +LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, std::error_code EC) { + assert(EC); + errs() << ToolName << ": '" << File << "': " << EC.message() << ".\n"; + exit(1); +} + +LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, llvm::Error E) { + assert(E); + std::string Buf; + raw_string_ostream OS(Buf); + logAllUnhandledErrors(std::move(E), OS, ""); + OS.flush(); + errs() << ToolName << ": '" << File << "': " << Buf; + exit(1); +} +} + +cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input>")); +cl::opt<std::string> OutputFilename(cl::Positional, cl::desc("<output>"), + cl::init("-")); +cl::opt<std::string> + OutputFormat("O", cl::desc("set output format to one of the following:" + "\n\tbinary")); +cl::list<std::string> ToRemove("remove-section", + cl::desc("Remove a specific section")); +cl::alias ToRemoveA("R", cl::desc("Alias for remove-section"), + cl::aliasopt(ToRemove)); +cl::opt<bool> StripSections("strip-sections", + cl::desc("Remove all section headers")); + +typedef std::function<bool(const SectionBase &Sec)> SectionPred; + +void CopyBinary(const ELFObjectFile<ELF64LE> &ObjFile) { + std::unique_ptr<FileOutputBuffer> Buffer; + std::unique_ptr<Object<ELF64LE>> Obj; + if (!OutputFormat.empty() && OutputFormat != "binary") + error("invalid output format '" + OutputFormat + "'"); + if (!OutputFormat.empty() && OutputFormat == "binary") + Obj = llvm::make_unique<BinaryObject<ELF64LE>>(ObjFile); + else + Obj = llvm::make_unique<ELFObject<ELF64LE>>(ObjFile); + + SectionPred RemovePred = [](const SectionBase &) { return false; }; + + if (!ToRemove.empty()) { + RemovePred = [&](const SectionBase &Sec) { + return std::find(std::begin(ToRemove), std::end(ToRemove), Sec.Name) != + std::end(ToRemove); + }; + } + + if (StripSections) { + RemovePred = [RemovePred](const SectionBase &Sec) { + return RemovePred(Sec) || (Sec.Flags & SHF_ALLOC) == 0; + }; + Obj->WriteSectionHeaders = false; + } + + Obj->removeSections(RemovePred); + + Obj->finalize(); + ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr = + FileOutputBuffer::create(OutputFilename, Obj->totalSize(), + FileOutputBuffer::F_executable); + if (BufferOrErr.getError()) + error("failed to open " + OutputFilename); + else + Buffer = std::move(*BufferOrErr); + std::error_code EC; + if (EC) + report_fatal_error(EC.message()); + Obj->write(*Buffer); + if (auto EC = Buffer->commit()) + reportError(OutputFilename, EC); +} + +int main(int argc, char **argv) { + // Print a stack trace if we signal out. + sys::PrintStackTraceOnErrorSignal(argv[0]); + PrettyStackTraceProgram X(argc, argv); + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + cl::ParseCommandLineOptions(argc, argv, "llvm objcopy utility\n"); + ToolName = argv[0]; + if (InputFilename.empty()) { + cl::PrintHelpMessage(); + return 2; + } + Expected<OwningBinary<Binary>> BinaryOrErr = createBinary(InputFilename); + if (!BinaryOrErr) + reportError(InputFilename, BinaryOrErr.takeError()); + Binary &Binary = *BinaryOrErr.get().getBinary(); + if (ELFObjectFile<ELF64LE> *o = dyn_cast<ELFObjectFile<ELF64LE>>(&Binary)) { + CopyBinary(*o); + return 0; + } + reportError(InputFilename, object_error::invalid_file_type); +}