aboutsummaryrefslogtreecommitdiff
path: root/tools/llvm-objcopy/llvm-objcopy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-objcopy/llvm-objcopy.cpp')
-rw-r--r--tools/llvm-objcopy/llvm-objcopy.cpp53
1 files changed, 38 insertions, 15 deletions
diff --git a/tools/llvm-objcopy/llvm-objcopy.cpp b/tools/llvm-objcopy/llvm-objcopy.cpp
index e9372176e43b..a68210f3fdd3 100644
--- a/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -29,6 +29,7 @@
#include "llvm/Option/ArgList.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
@@ -36,6 +37,7 @@
#include "llvm/Support/Memory.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
+#include "llvm/Support/StringSaver.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -84,7 +86,7 @@ LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, Error E) {
ErrorSuccess reportWarning(Error E) {
assert(E);
- WithColor::warning(errs(), ToolName) << toString(std::move(E));
+ WithColor::warning(errs(), ToolName) << toString(std::move(E)) << '\n';
return Error::success();
}
@@ -130,16 +132,18 @@ static Error deepWriteArchive(StringRef ArcName,
/// The function executeObjcopyOnIHex does the dispatch based on the format
/// of the output specified by the command line options.
-static Error executeObjcopyOnIHex(const CopyConfig &Config, MemoryBuffer &In,
+static Error executeObjcopyOnIHex(CopyConfig &Config, MemoryBuffer &In,
Buffer &Out) {
// TODO: support output formats other than ELF.
+ if (Error E = Config.parseELFConfig())
+ return E;
return elf::executeObjcopyOnIHex(Config, In, Out);
}
/// The function executeObjcopyOnRawBinary does the dispatch based on the format
/// of the output specified by the command line options.
-static Error executeObjcopyOnRawBinary(const CopyConfig &Config,
- MemoryBuffer &In, Buffer &Out) {
+static Error executeObjcopyOnRawBinary(CopyConfig &Config, MemoryBuffer &In,
+ Buffer &Out) {
switch (Config.OutputFormat) {
case FileFormat::ELF:
// FIXME: Currently, we call elf::executeObjcopyOnRawBinary even if the
@@ -148,6 +152,8 @@ static Error executeObjcopyOnRawBinary(const CopyConfig &Config,
case FileFormat::Binary:
case FileFormat::IHex:
case FileFormat::Unspecified:
+ if (Error E = Config.parseELFConfig())
+ return E;
return elf::executeObjcopyOnRawBinary(Config, In, Out);
}
@@ -156,11 +162,13 @@ static Error executeObjcopyOnRawBinary(const CopyConfig &Config,
/// The function executeObjcopyOnBinary does the dispatch based on the format
/// of the input binary (ELF, MachO or COFF).
-static Error executeObjcopyOnBinary(const CopyConfig &Config,
- object::Binary &In, Buffer &Out) {
- if (auto *ELFBinary = dyn_cast<object::ELFObjectFileBase>(&In))
+static Error executeObjcopyOnBinary(CopyConfig &Config, object::Binary &In,
+ Buffer &Out) {
+ if (auto *ELFBinary = dyn_cast<object::ELFObjectFileBase>(&In)) {
+ if (Error E = Config.parseELFConfig())
+ return E;
return elf::executeObjcopyOnBinary(Config, *ELFBinary, Out);
- else if (auto *COFFBinary = dyn_cast<object::COFFObjectFile>(&In))
+ } else if (auto *COFFBinary = dyn_cast<object::COFFObjectFile>(&In))
return coff::executeObjcopyOnBinary(Config, *COFFBinary, Out);
else if (auto *MachOBinary = dyn_cast<object::MachOObjectFile>(&In))
return macho::executeObjcopyOnBinary(Config, *MachOBinary, Out);
@@ -169,8 +177,7 @@ static Error executeObjcopyOnBinary(const CopyConfig &Config,
"unsupported object file format");
}
-static Error executeObjcopyOnArchive(const CopyConfig &Config,
- const Archive &Ar) {
+static Error executeObjcopyOnArchive(CopyConfig &Config, const Archive &Ar) {
std::vector<NewArchiveMember> NewArchiveMembers;
Error Err = Error::success();
for (const Archive::Child &Child : Ar.children(Err)) {
@@ -246,7 +253,7 @@ static Error restoreStatOnFile(StringRef Filename,
/// The function executeObjcopy does the higher level dispatch based on the type
/// of input (raw binary, archive or single object file) and takes care of the
/// format-agnostic modifications, i.e. preserving dates.
-static Error executeObjcopy(const CopyConfig &Config) {
+static Error executeObjcopy(CopyConfig &Config) {
sys::fs::file_status Stat;
if (Config.InputFilename != "-") {
if (auto EC = sys::fs::status(Config.InputFilename, Stat))
@@ -255,7 +262,7 @@ static Error executeObjcopy(const CopyConfig &Config) {
Stat.permissions(static_cast<sys::fs::perms>(0777));
}
- typedef Error (*ProcessRawFn)(const CopyConfig &, MemoryBuffer &, Buffer &);
+ using ProcessRawFn = Error (*)(CopyConfig &, MemoryBuffer &, Buffer &);
ProcessRawFn ProcessRaw;
switch (Config.InputFormat) {
case FileFormat::Binary:
@@ -310,15 +317,31 @@ int main(int argc, char **argv) {
InitLLVM X(argc, argv);
ToolName = argv[0];
bool IsStrip = sys::path::stem(ToolName).contains("strip");
+
+ // Expand response files.
+ // TODO: Move these lines, which are copied from lib/Support/CommandLine.cpp,
+ // into a separate function in the CommandLine library and call that function
+ // here. This is duplicated code.
+ SmallVector<const char *, 20> NewArgv(argv, argv + argc);
+ BumpPtrAllocator A;
+ StringSaver Saver(A);
+ cl::ExpandResponseFiles(Saver,
+ Triple(sys::getProcessTriple()).isOSWindows()
+ ? cl::TokenizeWindowsCommandLine
+ : cl::TokenizeGNUCommandLine,
+ NewArgv);
+
+ auto Args = makeArrayRef(NewArgv).drop_front();
+
Expected<DriverConfig> DriverConfig =
- IsStrip ? parseStripOptions(makeArrayRef(argv + 1, argc), reportWarning)
- : parseObjcopyOptions(makeArrayRef(argv + 1, argc));
+ IsStrip ? parseStripOptions(Args, reportWarning)
+ : parseObjcopyOptions(Args, reportWarning);
if (!DriverConfig) {
logAllUnhandledErrors(DriverConfig.takeError(),
WithColor::error(errs(), ToolName));
return 1;
}
- for (const CopyConfig &CopyConfig : DriverConfig->CopyConfigs) {
+ for (CopyConfig &CopyConfig : DriverConfig->CopyConfigs) {
if (Error E = executeObjcopy(CopyConfig)) {
logAllUnhandledErrors(std::move(E), WithColor::error(errs(), ToolName));
return 1;