]> granicus.if.org Git - llvm/commitdiff
[llvm-strip] Error when using stdin twice
authorAlex Brachet <alexbrachetmialot@gmail.com>
Tue, 18 Jun 2019 00:39:10 +0000 (00:39 +0000)
committerAlex Brachet <alexbrachetmialot@gmail.com>
Tue, 18 Jun 2019 00:39:10 +0000 (00:39 +0000)
Summary: Implements bug [[ https://bugs.llvm.org/show_bug.cgi?id=42204 | 42204 ]]. llvm-strip now warns when the same input file is used more than once, and errors when stdin is used more than once.

Reviewers: jhenderson, rupprecht, espindola, alexshap

Reviewed By: jhenderson, rupprecht

Subscribers: emaste, arichardson, jakehehrlich, MaskRay, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D63122

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@363638 91177308-0d34-0410-b5e6-96231b3b80d8

test/tools/llvm-objcopy/ELF/same-file-strip.test [new file with mode: 0644]
tools/llvm-objcopy/CopyConfig.cpp
tools/llvm-objcopy/CopyConfig.h
tools/llvm-objcopy/llvm-objcopy.cpp

diff --git a/test/tools/llvm-objcopy/ELF/same-file-strip.test b/test/tools/llvm-objcopy/ELF/same-file-strip.test
new file mode 100644 (file)
index 0000000..304ecaf
--- /dev/null
@@ -0,0 +1,26 @@
+## Test llvm-strip using the same input file more than once.
+## When using stdin ('-') more than once llvm-strip should give an error
+## while a file more than once should be simply a warning.
+
+# RUN: yaml2obj %s -o %t
+
+# RUN: not llvm-strip - - < %t 2>&1 | FileCheck -check-prefix=ERR %s
+# RUN: not llvm-strip - %t - < %t 2>&1 | FileCheck -check-prefix=ERR %s
+
+# ERR: error: cannot specify '-' as an input file more than once
+
+# RUN: llvm-strip %t %t 2>&1 | FileCheck -check-prefix=WARN %s -DFILE=%t
+# RUN: llvm-strip %t %t %t 2>&1 | FileCheck -check-prefix=WARN %s -DFILE=%t
+
+# WARN: warning: '[[FILE]]' was already specified
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name:  .alloc
+    Type:  SHT_PROGBITS
+    Flags: [ SHF_ALLOC ]
index 577e9644dc929ec198b4444929205be75b9c888c..a654d8713aa4d2043a9032068188b10846c8027d 100644 (file)
@@ -11,6 +11,7 @@
 #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"
@@ -722,7 +723,9 @@ Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr) {
 // ParseStripOptions returns the config and sets the input arguments. If a
 // help flag is set then ParseStripOptions will print the help messege and
 // exit.
-Expected<DriverConfig> parseStripOptions(ArrayRef<const char *> ArgsArr) {
+Expected<DriverConfig>
+parseStripOptions(ArrayRef<const char *> ArgsArr,
+                  std::function<Error(Error)> ErrorCallback) {
   StripOptTable T;
   unsigned MissingArgumentIndex, MissingArgumentCount;
   llvm::opt::InputArgList InputArgs =
@@ -809,7 +812,18 @@ Expected<DriverConfig> parseStripOptions(ArrayRef<const char *> ArgsArr) {
         InputArgs.getLastArgValue(STRIP_output, Positional[0]);
     DC.CopyConfigs.push_back(std::move(Config));
   } else {
+    StringMap<unsigned> InputFiles;
     for (StringRef Filename : Positional) {
+      if (InputFiles[Filename]++ == 1) {
+        if (Filename == "-")
+          return createStringError(
+              errc::invalid_argument,
+              "cannot specify '-' as an input file more than once");
+        if (Error E = ErrorCallback(createStringError(
+                errc::invalid_argument, "'%s' was already specified",
+                Filename.str().c_str())))
+          return std::move(E);
+      }
       Config.InputFilename = Filename;
       Config.OutputFilename = Filename;
       DC.CopyConfigs.push_back(Config);
index 06b3efddb5adfb4495afafa6023b64704f3b5368..9ae4270f4fe56d50beb5dca8496904f2bbc1777a 100644 (file)
@@ -188,8 +188,11 @@ Expected<DriverConfig> parseObjcopyOptions(ArrayRef<const char *> ArgsArr);
 
 // ParseStripOptions returns the config and sets the input arguments. If a
 // help flag is set then ParseStripOptions will print the help messege and
-// exit.
-Expected<DriverConfig> parseStripOptions(ArrayRef<const char *> ArgsArr);
+// exit. ErrorCallback is used to handle recoverable errors. An Error returned
+// by the callback aborts the parsing and is then returned by this function.
+Expected<DriverConfig>
+parseStripOptions(ArrayRef<const char *> ArgsArr,
+                  std::function<Error(Error)> ErrorCallback);
 
 } // namespace objcopy
 } // namespace llvm
index 416b295ab3ed5653ed8d62e8ae155819139abc11..2ab77ea5c8684756152541d22f3111ccf92c7fc3 100644 (file)
@@ -82,6 +82,12 @@ LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, Error E) {
   exit(1);
 }
 
+ErrorSuccess reportWarning(Error E) {
+  assert(E);
+  WithColor::warning(errs(), ToolName) << toString(std::move(E));
+  return Error::success();
+}
+
 } // end namespace objcopy
 } // end namespace llvm
 
@@ -263,7 +269,7 @@ int main(int argc, char **argv) {
   ToolName = argv[0];
   bool IsStrip = sys::path::stem(ToolName).contains("strip");
   Expected<DriverConfig> DriverConfig =
-      IsStrip ? parseStripOptions(makeArrayRef(argv + 1, argc))
+      IsStrip ? parseStripOptions(makeArrayRef(argv + 1, argc), reportWarning)
               : parseObjcopyOptions(makeArrayRef(argv + 1, argc));
   if (!DriverConfig) {
     logAllUnhandledErrors(DriverConfig.takeError(),