[llvm-objcopy] Change handling of output file permissions

Summary: Address bug [[ https://bugs.llvm.org/show_bug.cgi?id=42082 | 42082 ]] where files were always outputted with 0775 permissions. Now, the output file is given either 0666 or 0777 if the object is executable.

Reviewers: espindola, alexshap, rupprecht, jhenderson, jakehehrlich, MaskRay

Reviewed By: rupprecht, jhenderson, jakehehrlich, MaskRay

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

Tags: #llvm

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

llvm-svn: 365162
diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
index 2ab77ea..db5609e 100644
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -196,16 +196,26 @@
                           Config.DeterministicArchives, Ar.isThin());
 }
 
-static Error restoreDateOnFile(StringRef Filename,
-                               const sys::fs::file_status &Stat) {
+static Error restoreStatOnFile(StringRef Filename,
+                               const sys::fs::file_status &Stat,
+                               bool PreserveDates) {
   int FD;
 
+  // Writing to stdout should not be treated as an error here, just
+  // do not set access/modification times or permissions.
+  if (Filename == "-")
+    return Error::success();
+
   if (auto EC =
           sys::fs::openFileForWrite(Filename, FD, sys::fs::CD_OpenExisting))
     return createFileError(Filename, EC);
 
-  if (auto EC = sys::fs::setLastAccessAndModificationTime(
-          FD, Stat.getLastAccessedTime(), Stat.getLastModificationTime()))
+  if (PreserveDates)
+    if (auto EC = sys::fs::setLastAccessAndModificationTime(
+            FD, Stat.getLastAccessedTime(), Stat.getLastModificationTime()))
+      return createFileError(Filename, EC);
+
+  if (auto EC = sys::fs::setPermissions(Filename, Stat.permissions()))
     return createFileError(Filename, EC);
 
   if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD))
@@ -219,9 +229,12 @@
 /// format-agnostic modifications, i.e. preserving dates.
 static Error executeObjcopy(const CopyConfig &Config) {
   sys::fs::file_status Stat;
-  if (Config.PreserveDates)
+  if (Config.InputFilename != "-") {
     if (auto EC = sys::fs::status(Config.InputFilename, Stat))
       return createFileError(Config.InputFilename, EC);
+  } else {
+    Stat.permissions(static_cast<sys::fs::perms>(0777));
+  }
 
   typedef Error (*ProcessRawFn)(const CopyConfig &, MemoryBuffer &, Buffer &);
   auto ProcessRaw = StringSwitch<ProcessRawFn>(Config.InputFormat)
@@ -253,12 +266,15 @@
     }
   }
 
-  if (Config.PreserveDates) {
-    if (Error E = restoreDateOnFile(Config.OutputFilename, Stat))
+  if (Error E =
+          restoreStatOnFile(Config.OutputFilename, Stat, Config.PreserveDates))
+    return E;
+
+  if (!Config.SplitDWO.empty()) {
+    Stat.permissions(static_cast<sys::fs::perms>(0666));
+    if (Error E =
+            restoreStatOnFile(Config.SplitDWO, Stat, Config.PreserveDates))
       return E;
-    if (!Config.SplitDWO.empty())
-      if (Error E = restoreDateOnFile(Config.SplitDWO, Stat))
-        return E;
   }
 
   return Error::success();