[llvm] [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 04:08:34 PST 2025


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

>From 3a8ea88839a9f4c656cc48af3af039e340608e69 Mon Sep 17 00:00:00 2001
From: SHENGYI HONG <aokblast at FreeBSD.org>
Date: Fri, 3 Jan 2025 01:54:52 +0800
Subject: [PATCH] objcopy: fix llvm-objcopy replaced faiiled when the file is
 modified inplace.

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
---
 llvm/include/llvm/ObjCopy/ObjCopy.h      |  5 ++++-
 llvm/lib/ObjCopy/Archive.cpp             | 11 +++++++----
 llvm/tools/llvm-objcopy/llvm-objcopy.cpp |  4 +++-
 3 files changed, 14 insertions(+), 6 deletions(-)

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..85db7df140ec2a 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,13 @@ 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))
+                             Deterministic, Thin, std::move(Buffer)))
     return createFileError(ArcName, std::move(E));
 
   if (!Thin)
@@ -96,7 +98,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 +109,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.



More information about the llvm-commits mailing list