[llvm] objcopy: fix llvm-objcopy replaced faiiled when the file is modified inplace (PR #121564)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 3 03:56:58 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-binary-utilities

Author: None (aokblast)

<details>
<summary>Changes</summary>

# Purpose

In Windows, the deleted file cannot be opened when they are deleted.

It is needed to free the old archive before move from the temp file

# Discover

This error is discover when I mount the sambafs from Windows (Server) to Linux (Client). And do llvm-obcopy over the code on the sambafs.

---
Full diff: https://github.com/llvm/llvm-project/pull/121564.diff


3 Files Affected:

- (modified) llvm/include/llvm/ObjCopy/ObjCopy.h (+4-1) 
- (modified) llvm/lib/ObjCopy/Archive.cpp (+9-5) 
- (modified) llvm/tools/llvm-objcopy/llvm-objcopy.cpp (+3-1) 


``````````diff
diff --git a/llvm/include/llvm/ObjCopy/ObjCopy.h b/llvm/include/llvm/ObjCopy/ObjCopy.h
index 023814002c7271..2b8233c22d2dbe 100644
--- a/llvm/include/llvm/ObjCopy/ObjCopy.h
+++ b/llvm/include/llvm/ObjCopy/ObjCopy.h
@@ -10,6 +10,8 @@
 #define LLVM_OBJCOPY_OBJCOPY_H
 
 #include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <memory>
 
 namespace llvm {
 class raw_ostream;
@@ -27,7 +29,8 @@ class MultiFormatConfig;
 /// Writes a result in a file specified by \p Config.OutputFilename.
 /// \returns any Error encountered whilst performing the operation.
 Error executeObjcopyOnArchive(const MultiFormatConfig &Config,
-                              const object::Archive &Ar);
+                              const object::Archive &Ar,
+                              std::unique_ptr<MemoryBuffer> Buffer);
 
 /// Applies the transformations described by \p Config to \p In and writes
 /// the result into \p Out. This function does the dispatch based on the
diff --git a/llvm/lib/ObjCopy/Archive.cpp b/llvm/lib/ObjCopy/Archive.cpp
index b6da4dc1e239c8..0512b0ddfb909b 100644
--- a/llvm/lib/ObjCopy/Archive.cpp
+++ b/llvm/lib/ObjCopy/Archive.cpp
@@ -13,7 +13,9 @@
 #include "llvm/Object/Error.h"
 #include "llvm/Object/MachO.h"
 #include "llvm/Support/FileOutputBuffer.h"
+#include "llvm/Support/MemoryBufferRef.h"
 #include "llvm/Support/SmallVectorMemoryBuffer.h"
+#include <memory>
 
 namespace llvm {
 namespace objcopy {
@@ -62,13 +64,14 @@ static Error deepWriteArchive(StringRef ArcName,
                               ArrayRef<NewArchiveMember> NewMembers,
                               SymtabWritingMode WriteSymtab,
                               object::Archive::Kind Kind, bool Deterministic,
-                              bool Thin) {
+                              bool Thin, std::unique_ptr<MemoryBuffer> Buffer) {
   if (Kind == object::Archive::K_BSD && !NewMembers.empty() &&
       NewMembers.front().detectKindFromObject() == object::Archive::K_DARWIN)
     Kind = object::Archive::K_DARWIN;
 
-  if (Error E = writeArchive(ArcName, NewMembers, WriteSymtab, Kind,
-                             Deterministic, Thin))
+  if (Error E =
+          writeArchive(ArcName, NewMembers, WriteSymtab, Kind, Deterministic,
+                       Thin, std::move(Buffer)))
     return createFileError(ArcName, std::move(E));
 
   if (!Thin)
@@ -96,7 +99,8 @@ static Error deepWriteArchive(StringRef ArcName,
 }
 
 Error executeObjcopyOnArchive(const MultiFormatConfig &Config,
-                              const object::Archive &Ar) {
+                              const object::Archive &Ar,
+                              std::unique_ptr<MemoryBuffer> Buffer) {
   Expected<std::vector<NewArchiveMember>> NewArchiveMembersOrErr =
       createNewArchiveMembers(Config, Ar);
   if (!NewArchiveMembersOrErr)
@@ -106,7 +110,7 @@ Error executeObjcopyOnArchive(const MultiFormatConfig &Config,
                           Ar.hasSymbolTable() ? SymtabWritingMode::NormalSymtab
                                               : SymtabWritingMode::NoSymtab,
                           Ar.kind(), CommonConfig.DeterministicArchives,
-                          Ar.isThin());
+                          Ar.isThin(), std::move(Buffer));
 }
 
 } // end namespace objcopy
diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
index ad3e60472369bf..2005bb746b4ec3 100644
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -176,7 +176,9 @@ static Error executeObjcopy(ConfigManager &ConfigMgr) {
 
     if (Archive *Ar = dyn_cast<Archive>(BinaryHolder.getBinary())) {
       // Handle Archive.
-      if (Error E = executeObjcopyOnArchive(ConfigMgr, *Ar))
+      auto [Binary, MemBuf] = BinaryHolder.takeBinary();
+      Ar = dyn_cast<Archive>(Binary.get());
+      if (Error E = executeObjcopyOnArchive(ConfigMgr, *Ar, std::move(MemBuf)))
         return E;
     } else {
       // Handle llvm::object::Binary.

``````````

</details>


https://github.com/llvm/llvm-project/pull/121564


More information about the llvm-commits mailing list