diff --git a/llvm/test/tools/llvm-objcopy/ELF/same-file-strip.test b/llvm/test/tools/llvm-objcopy/ELF/same-file-strip.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/ELF/same-file-strip.test @@ -0,0 +1,10 @@ +# RUN: not llvm-strip - - < %p/Inputs/dynrel.elf 2>&1 | FileCheck -check-prefix=ERR %s +# RUN: not llvm-strip - %p/Inputs/dynrel.elf - < %p/Inputs/dynrel.elf 2>&1 \ +# RUN: | FileCheck -check-prefix=ERR %s +# ERR: error: cannot specify '-' as an input file more than once + +# RUN: cp %p/Inputs/dynrel.elf dynrel.elf +# RUN: llvm-strip dynrel.elf dynrel.elf 2>&1 \ +# RUN: | FileCheck -check-prefix=WARN %s +# WARN: warning: 'dynrel.elf' was already specified +# RUN: rm dynrel.elf diff --git a/llvm/tools/llvm-objcopy/CopyConfig.cpp b/llvm/tools/llvm-objcopy/CopyConfig.cpp --- a/llvm/tools/llvm-objcopy/CopyConfig.cpp +++ b/llvm/tools/llvm-objcopy/CopyConfig.cpp @@ -7,10 +7,12 @@ //===----------------------------------------------------------------------===// #include "CopyConfig.h" +#include "llvm-objcopy.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/CommandLine.h" @@ -735,7 +737,7 @@ exit(0); } - SmallVector Positional; + SmallVector Positional; for (auto Arg : InputArgs.filtered(STRIP_UNKNOWN)) return createStringError(errc::invalid_argument, "unknown argument '%s'", Arg->getAsString(InputArgs).c_str()); @@ -800,7 +802,14 @@ InputArgs.getLastArgValue(STRIP_output, Positional[0]); DC.CopyConfigs.push_back(std::move(Config)); } else { - for (const char *Filename : Positional) { + StringSet<> InputFiles; + for (StringRef Filename : Positional) { + if (InputFiles.find(Filename) != InputFiles.end()) { + if (Filename == "-") + return createStringError(errc::invalid_argument, "cannot specify '-' as an input file more than once"); + reportWarning("'" + Filename + "' was already specified"); + } + InputFiles.insert(Filename); Config.InputFilename = Filename; Config.OutputFilename = Filename; DC.CopyConfigs.push_back(Config); diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.h b/llvm/tools/llvm-objcopy/llvm-objcopy.h --- a/llvm/tools/llvm-objcopy/llvm-objcopy.h +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.h @@ -23,6 +23,7 @@ LLVM_ATTRIBUTE_NORETURN extern void reportError(StringRef File, Error E); LLVM_ATTRIBUTE_NORETURN extern void reportError(StringRef File, std::error_code EC); +extern void reportWarning(Twine Message); // This is taken from llvm-readobj. // [see here](llvm/tools/llvm-readobj/llvm-readobj.h:38) diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -83,6 +83,11 @@ exit(1); } +void reportWarning(Twine Message) { + WithColor::warning(errs(), ToolName) << Message << "\n"; + errs().flush(); +} + } // end namespace objcopy } // end namespace llvm