Index: llvm/test/tools/llvm-elfabi/keep-timestamp.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-elfabi/keep-timestamp.test @@ -0,0 +1,6 @@ +# RUN: llvm-elfabi --elf %p/Inputs/gnu_hash.so --emit-tbe=%t --keep-timestamp +# RUN: touch -m -d "1970-01-01 00:00:00" %t +# RUN: llvm-elfabi --elf %p/Inputs/gnu_hash.so --emit-tbe=%t --keep-timestamp +# RUN: stat %t | FileCheck %s + +# CHECK: Modify: 1970-01-01 00:00:00.000000000 -0800 Index: llvm/tools/llvm-elfabi/llvm-elfabi.cpp =================================================================== --- llvm/tools/llvm-elfabi/llvm-elfabi.cpp +++ llvm/tools/llvm-elfabi/llvm-elfabi.cpp @@ -57,22 +57,37 @@ clEnumValN(ELFTarget::ELF64BE, "elf64-big", "64-bit big-endian ELF stub"))); cl::opt BinaryOutputFilePath(cl::Positional, cl::desc("output")); +cl::opt KeepOutputFileTimeStamp( + "keep-timestamp", cl::desc("Keep the timestamp of the output file " + "unchanged if the content is not changed")); /// writeTBE() writes a Text-Based ELF stub to a file using the latest version /// of the YAML parser. static Error writeTBE(StringRef FilePath, ELFStub &Stub) { std::error_code SysErr; - - // Open file for writing. - raw_fd_ostream Out(FilePath, SysErr); - if (SysErr) - return createStringError(SysErr, "Couldn't open `%s` for writing", - FilePath.data()); - // Write file. - Error YAMLErr = writeTBEToOutputStream(Out, Stub); + // Write TBE to memory first. + std::string TBEStr; + raw_string_ostream OutStr(TBEStr); + Error YAMLErr = writeTBEToOutputStream(OutStr, Stub); if (YAMLErr) return YAMLErr; - + OutStr.str(); + + if (KeepOutputFileTimeStamp) { + ErrorOr> BufOrError = + MemoryBuffer::getFile(FilePath); + if (BufOrError) { + // Compare TBE output with existing TBE file. + std::unique_ptr FileReadBuffer = std::move(*BufOrError); + if (FileReadBuffer->getBuffer().equals(TBEStr)) { + // TBE file unchanged, abort updating. + return Error::success(); + } + } + } + // Open TBE file for writing. + raw_fd_ostream Out(FilePath, SysErr); + Out << TBEStr; return Error::success(); }