aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-objcopy/llvm-objcopy.cpp')
-rw-r--r--llvm/tools/llvm-objcopy/llvm-objcopy.cpp76
1 files changed, 50 insertions, 26 deletions
diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
index 68b5e97..a8a570a 100644
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -322,44 +322,68 @@ static Error executeObjcopy(CopyConfig &Config) {
Stat.permissions(static_cast<sys::fs::perms>(0777));
}
- using ProcessRawFn = Error (*)(CopyConfig &, MemoryBuffer &, raw_ostream &);
- ProcessRawFn ProcessRaw;
- switch (Config.InputFormat) {
- case FileFormat::Binary:
- ProcessRaw = executeObjcopyOnRawBinary;
- break;
- case FileFormat::IHex:
- ProcessRaw = executeObjcopyOnIHex;
- break;
- default:
- ProcessRaw = nullptr;
- }
+ std::function<Error(raw_ostream & OutFile)> ObjcopyFunc;
- if (ProcessRaw) {
- auto BufOrErr = MemoryBuffer::getFileOrSTDIN(Config.InputFilename);
+ OwningBinary<llvm::object::Binary> BinaryHolder;
+ std::unique_ptr<MemoryBuffer> MemoryBufferHolder;
+
+ if (Config.InputFormat == FileFormat::Binary ||
+ Config.InputFormat == FileFormat::IHex) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
+ MemoryBuffer::getFileOrSTDIN(Config.InputFilename);
if (!BufOrErr)
return createFileError(Config.InputFilename, BufOrErr.getError());
-
- if (Error E = writeToFile(
- Config.OutputFilename, [&](raw_ostream &OutFile) -> Error {
- return ProcessRaw(Config, *BufOrErr->get(), OutFile);
- }))
- return E;
+ MemoryBufferHolder = std::move(*BufOrErr);
+
+ if (Config.InputFormat == FileFormat::Binary)
+ ObjcopyFunc = [&](raw_ostream &OutFile) -> Error {
+ // Handle FileFormat::Binary.
+ return executeObjcopyOnRawBinary(Config, *MemoryBufferHolder, OutFile);
+ };
+ else
+ ObjcopyFunc = [&](raw_ostream &OutFile) -> Error {
+ // Handle FileFormat::IHex.
+ return executeObjcopyOnIHex(Config, *MemoryBufferHolder, OutFile);
+ };
} else {
Expected<OwningBinary<llvm::object::Binary>> BinaryOrErr =
createBinary(Config.InputFilename);
if (!BinaryOrErr)
return createFileError(Config.InputFilename, BinaryOrErr.takeError());
+ BinaryHolder = std::move(*BinaryOrErr);
- if (Archive *Ar = dyn_cast<Archive>(BinaryOrErr.get().getBinary())) {
+ if (Archive *Ar = dyn_cast<Archive>(BinaryHolder.getBinary())) {
+ // Handle Archive.
if (Error E = executeObjcopyOnArchive(Config, *Ar))
return E;
} else {
- if (Error E = writeToFile(
- Config.OutputFilename, [&](raw_ostream &OutFile) -> Error {
- return executeObjcopyOnBinary(
- Config, *BinaryOrErr.get().getBinary(), OutFile);
- }))
+ // Handle llvm::object::Binary.
+ ObjcopyFunc = [&](raw_ostream &OutFile) -> Error {
+ return executeObjcopyOnBinary(Config, *BinaryHolder.getBinary(),
+ OutFile);
+ };
+ }
+ }
+
+ if (ObjcopyFunc) {
+ if (Config.SplitDWO.empty()) {
+ // Apply transformations described by Config and store result into
+ // Config.OutputFilename using specified ObjcopyFunc function.
+ if (Error E = writeToFile(Config.OutputFilename, ObjcopyFunc))
+ return E;
+ } else {
+ Config.ExtractDWO = true;
+ Config.StripDWO = false;
+ // Copy .dwo tables from the Config.InputFilename into Config.SplitDWO
+ // file using specified ObjcopyFunc function.
+ if (Error E = writeToFile(Config.SplitDWO, ObjcopyFunc))
+ return E;
+ Config.ExtractDWO = false;
+ Config.StripDWO = true;
+ // Apply transformations described by Config, remove .dwo tables and
+ // store result into Config.OutputFilename using specified ObjcopyFunc
+ // function.
+ if (Error E = writeToFile(Config.OutputFilename, ObjcopyFunc))
return E;
}
}