Index: llvm/test/tools/llvm-objcopy/ELF/mirror-permissions.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-objcopy/ELF/mirror-permissions.test @@ -0,0 +1,36 @@ +# RUN: touch %t +# RUN: chmod 0777 %t +# RUN: ls -l %t | cut -f 1 -d ' ' > %t.0777 +# RUN: chmod 0666 %t +# RUN: ls -l %t | cut -f 1 -d ' ' > %t.0666 +# RUN: chmod 0640 %t +# RUN: ls -l %t | cut -f 1 -d ' ' > %t.0640 + +## Set umask to be permissive of all permissions, +## only test mirroring of permissions. umask(1) doesn't +## exist on Windows. +# RUN: if [[ "$OSTYPE" != "win32" ]]; then umask 0; fi + +# RUN: yaml2obj %s -o %t + +# RUN: chmod 0777 %t +# RUN: llvm-objcopy %t %t1 +# RUN: ls -l %t1 | cut -f 1 -d ' ' > %t1.perms +# RUN: cmp %t1.perms %t.0777 + +# RUN: chmod 0666 %t +# RUN: llvm-objcopy %t %t1 +# RUN: ls -l %t1 | cut -f 1 -d ' ' > %t1.perms +# RUN: cmp %t1.perms %t.0666 + +# RUN: chmod 0640 %t +# RUN: llvm-objcopy %t %t1 +# RUN: ls -l %t1 | cut -f 1 -d ' ' > %t1.perms +# RUN: cmp %t1.perms %t.0640 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 Index: llvm/test/tools/llvm-objcopy/ELF/respect-umask.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-objcopy/ELF/respect-umask.test @@ -0,0 +1,37 @@ +# UNSUPPORTED: windows + +# RUN: touch %t +# RUN: chmod 0755 %t +# RUN: ls -l %t | cut -f 1 -d ' ' > %t.0755 +# RUN: chmod 0500 %t +# RUN: ls -l %t | cut -f 1 -d ' ' > %t.0500 +# RUN: chmod 0555 %t +# RUN: ls -l %t | cut -f 1 -d ' ' > %t.0555 + +# RUN: yaml2obj %s -o %t + +# RUN: umask 0022 +# RUN: chmod 0777 %t +# RUN: llvm-objcopy %t %t1 +# RUN: ls -l %t1 | cut -f 1 -d ' ' > %t1.perms +# RUN: cmp %t1.perms %t.0755 + +# RUN: umask 0237 +# RUN: chmod 0707 %t +# RUN: llvm-objcopy %t %t1 +# RUN: ls -l %t1 | cut -f 1 -d ' ' > %t1.perms +# RUN: cmp %t1.perms %t.0500 + +# RUN: umask 0222 +# RUN: chmod 0777 %t +# RUN: llvm-objcopy %t %t1 +# RUN: ls -l %t1 | cut -f 1 -d ' ' > %t1.perms +# RUN: cmp %t1.perms %t.0555 + + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 Index: llvm/tools/llvm-objcopy/llvm-objcopy.cpp =================================================================== --- llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -45,6 +45,10 @@ #include #include #include +// TODO: Remove this if D63583 lands. +#ifndef _WIN32 +#include +#endif namespace llvm { namespace objcopy { @@ -196,16 +200,32 @@ Config.DeterministicArchives, Ar.isThin()); } -static Error restoreDateOnFile(StringRef Filename, - const sys::fs::file_status &Stat) { +static Error restoreStatOnFile(StringRef Filename, 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); + + // TODO: Rework this if D63583 lands. +#ifndef _WIN32 + unsigned Mask = ::umask(0); + (void)::umask(Mask); + Stat.permissions(static_cast(Stat.permissions & ~Mask)); +#endif + + if (auto EC = sys::fs::setPermissions(Filename, Stat.permissions())) return createFileError(Filename, EC); if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD)) @@ -219,9 +239,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(0775)); + } typedef Error (*ProcessRawFn)(const CopyConfig &, MemoryBuffer &, Buffer &); auto ProcessRaw = StringSwitch(Config.InputFormat) @@ -253,12 +276,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(0664)); + 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();