aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-objcopy
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-objcopy')
-rw-r--r--llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp47
-rw-r--r--llvm/tools/llvm-objcopy/llvm-objcopy.cpp76
2 files changed, 61 insertions, 62 deletions
diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
index 0cf0172..d139814 100644
--- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
@@ -173,32 +173,6 @@ static Error makeStringError(std::error_code EC, const Twine &Msg,
return createStringError(EC, FullMsg.c_str(), std::forward<Ts>(Args)...);
}
-static Error splitDWOToFile(const CopyConfig &Config, const Reader &Reader,
- StringRef File, ElfType OutputElfType) {
- Expected<std::unique_ptr<Object>> DWOFile = Reader.create(false);
- if (!DWOFile)
- return DWOFile.takeError();
-
- auto OnlyKeepDWOPred = [&DWOFile](const SectionBase &Sec) {
- return onlyKeepDWOPred(**DWOFile, Sec);
- };
- 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;
- }
-
- return writeToFile(File, [&](raw_ostream &OutFile) -> Error {
- std::unique_ptr<Writer> Writer =
- createWriter(Config, **DWOFile, OutFile, OutputElfType);
- if (Error E = Writer->finalize())
- return E;
- return Writer->write();
- });
-}
-
static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
Object &Obj) {
for (auto &Sec : Obj.sections()) {
@@ -374,7 +348,7 @@ static Error replaceAndRemoveSections(const CopyConfig &Config, Object &Obj) {
};
}
- if (Config.StripDWO || !Config.SplitDWO.empty())
+ if (Config.StripDWO)
RemovePred = [RemovePred](const SectionBase &Sec) {
return isDWOSection(Sec) || RemovePred(Sec);
};
@@ -532,21 +506,22 @@ static Error replaceAndRemoveSections(const CopyConfig &Config, Object &Obj) {
// 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 Error handleArgs(const CopyConfig &Config, Object &Obj,
- const Reader &Reader, ElfType OutputElfType) {
+static Error handleArgs(const CopyConfig &Config, Object &Obj) {
if (Config.StripSwiftSymbols || Config.KeepUndefined)
return createStringError(llvm::errc::invalid_argument,
"option not supported by llvm-objcopy for ELF");
- if (!Config.SplitDWO.empty())
- if (Error E =
- splitDWOToFile(Config, Reader, Config.SplitDWO, OutputElfType))
- return E;
if (Config.OutputArch) {
Obj.Machine = Config.OutputArch.getValue().EMachine;
Obj.OSABI = Config.OutputArch.getValue().OSABI;
}
+ if (!Config.SplitDWO.empty() && Config.ExtractDWO) {
+ return Obj.removeSections(
+ Config.AllowBrokenLinks,
+ [&Obj](const SectionBase &Sec) { return onlyKeepDWOPred(Obj, Sec); });
+ }
+
// Dump sections before add/remove for compatibility with GNU objcopy.
for (StringRef Flag : Config.DumpSection) {
StringRef SectionName;
@@ -706,7 +681,7 @@ Error executeObjcopyOnIHex(const CopyConfig &Config, MemoryBuffer &In,
const ElfType OutputElfType =
getOutputElfType(Config.OutputArch.getValueOr(MachineInfo()));
- if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
+ if (Error E = handleArgs(Config, **Obj))
return E;
return writeOutput(Config, **Obj, Out, OutputElfType);
}
@@ -724,7 +699,7 @@ Error executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In,
// (-B<arch>).
const ElfType OutputElfType =
getOutputElfType(Config.OutputArch.getValueOr(MachineInfo()));
- if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
+ if (Error E = handleArgs(Config, **Obj))
return E;
return writeOutput(Config, **Obj, Out, OutputElfType);
}
@@ -741,7 +716,7 @@ Error executeObjcopyOnBinary(const CopyConfig &Config,
Config.OutputArch ? getOutputElfType(Config.OutputArch.getValue())
: getOutputElfType(In);
- if (Error E = handleArgs(Config, **Obj, Reader, OutputElfType))
+ if (Error E = handleArgs(Config, **Obj))
return createFileError(Config.InputFilename, std::move(E));
if (Error E = writeOutput(Config, **Obj, Out, OutputElfType))
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;
}
}