[llvm] r200040 - Make ObjectFile ownership of the MemoryBuffer optional.

Rafael Espindola rafael.espindola at gmail.com
Fri Jan 24 13:32:22 PST 2014


Author: rafael
Date: Fri Jan 24 15:32:21 2014
New Revision: 200040

URL: http://llvm.org/viewvc/llvm-project?rev=200040&view=rev
Log:
Make ObjectFile ownership of the MemoryBuffer optional.

This allows llvm-ar to mmap the input files only once.

Modified:
    llvm/trunk/include/llvm/Object/Binary.h
    llvm/trunk/include/llvm/Object/COFF.h
    llvm/trunk/include/llvm/Object/ELFObjectFile.h
    llvm/trunk/include/llvm/Object/MachO.h
    llvm/trunk/include/llvm/Object/ObjectFile.h
    llvm/trunk/lib/Object/Binary.cpp
    llvm/trunk/lib/Object/COFFObjectFile.cpp
    llvm/trunk/lib/Object/ELFObjectFile.cpp
    llvm/trunk/lib/Object/MachOObjectFile.cpp
    llvm/trunk/lib/Object/ObjectFile.cpp
    llvm/trunk/tools/llvm-ar/llvm-ar.cpp

Modified: llvm/trunk/include/llvm/Object/Binary.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Binary.h?rev=200040&r1=200039&r2=200040&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/Binary.h (original)
+++ llvm/trunk/include/llvm/Object/Binary.h Fri Jan 24 15:32:21 2014
@@ -31,11 +31,12 @@ private:
   Binary(const Binary &other) LLVM_DELETED_FUNCTION;
 
   unsigned int TypeID;
+  bool BufferOwned;
 
 protected:
   MemoryBuffer *Data;
 
-  Binary(unsigned int Type, MemoryBuffer *Source);
+  Binary(unsigned int Type, MemoryBuffer *Source, bool BufferOwned = true);
 
   enum {
     ID_Archive,

Modified: llvm/trunk/include/llvm/Object/COFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/COFF.h?rev=200040&r1=200039&r2=200040&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/COFF.h (original)
+++ llvm/trunk/include/llvm/Object/COFF.h Fri Jan 24 15:32:21 2014
@@ -320,7 +320,7 @@ protected:
                                     StringRef &Result) const;
 
 public:
-  COFFObjectFile(MemoryBuffer *Object, error_code &ec);
+  COFFObjectFile(MemoryBuffer *Object, error_code &EC, bool BufferOwned = true);
   virtual symbol_iterator begin_symbols() const;
   virtual symbol_iterator end_symbols() const;
   virtual symbol_iterator begin_dynamic_symbols() const;

Modified: llvm/trunk/include/llvm/Object/ELFObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ELFObjectFile.h?rev=200040&r1=200039&r2=200040&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ELFObjectFile.h (original)
+++ llvm/trunk/include/llvm/Object/ELFObjectFile.h Fri Jan 24 15:32:21 2014
@@ -165,7 +165,7 @@ protected:
   bool isDyldELFObject;
 
 public:
-  ELFObjectFile(MemoryBuffer *Object, error_code &ec);
+  ELFObjectFile(MemoryBuffer *Object, error_code &EC, bool BufferOwned = true);
 
   const Elf_Sym *getSymbol(DataRefImpl Symb) const;
 
@@ -813,11 +813,12 @@ ELFObjectFile<ELFT>::getRela(DataRefImpl
 }
 
 template <class ELFT>
-ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec)
+ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec,
+                                   bool BufferOwned)
     : ObjectFile(getELFType(static_cast<endianness>(ELFT::TargetEndianness) ==
                                 support::little,
                             ELFT::Is64Bits),
-                 Object),
+                 Object, BufferOwned),
       EF(Object, ec) {}
 
 template <class ELFT>

Modified: llvm/trunk/include/llvm/Object/MachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachO.h?rev=200040&r1=200039&r2=200040&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/MachO.h (original)
+++ llvm/trunk/include/llvm/Object/MachO.h Fri Jan 24 15:32:21 2014
@@ -57,7 +57,7 @@ public:
   };
 
   MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits,
-                  error_code &ec);
+                  error_code &EC, bool BufferOwned = true);
 
   virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
   virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;

Modified: llvm/trunk/include/llvm/Object/ObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/ObjectFile.h?rev=200040&r1=200039&r2=200040&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/ObjectFile.h (original)
+++ llvm/trunk/include/llvm/Object/ObjectFile.h Fri Jan 24 15:32:21 2014
@@ -270,7 +270,7 @@ class ObjectFile : public Binary {
   ObjectFile(const ObjectFile &other) LLVM_DELETED_FUNCTION;
 
 protected:
-  ObjectFile(unsigned int Type, MemoryBuffer *source);
+  ObjectFile(unsigned int Type, MemoryBuffer *Source, bool BufferOwned = true);
 
   const uint8_t *base() const {
     return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
@@ -379,7 +379,7 @@ public:
   /// @brief Create ObjectFile from path.
   static ErrorOr<ObjectFile *> createObjectFile(StringRef ObjectPath);
   static ErrorOr<ObjectFile *>
-  createObjectFile(MemoryBuffer *Object,
+  createObjectFile(MemoryBuffer *Object, bool BufferOwned = true,
                    sys::fs::file_magic Type = sys::fs::file_magic::unknown);
 
   static inline bool classof(const Binary *v) {
@@ -387,9 +387,12 @@ public:
   }
 
 public:
-  static ErrorOr<ObjectFile *> createCOFFObjectFile(MemoryBuffer *Object);
-  static ErrorOr<ObjectFile *> createELFObjectFile(MemoryBuffer *Object);
-  static ErrorOr<ObjectFile *> createMachOObjectFile(MemoryBuffer *Object);
+  static ErrorOr<ObjectFile *> createCOFFObjectFile(MemoryBuffer *Object,
+                                                    bool BufferOwned = true);
+  static ErrorOr<ObjectFile *> createELFObjectFile(MemoryBuffer *Object,
+                                                   bool BufferOwned = true);
+  static ErrorOr<ObjectFile *> createMachOObjectFile(MemoryBuffer *Object,
+                                                     bool BufferOwned = true);
 };
 
 // Inline function definitions.

Modified: llvm/trunk/lib/Object/Binary.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/Binary.cpp?rev=200040&r1=200039&r2=200040&view=diff
==============================================================================
--- llvm/trunk/lib/Object/Binary.cpp (original)
+++ llvm/trunk/lib/Object/Binary.cpp Fri Jan 24 15:32:21 2014
@@ -26,12 +26,12 @@ using namespace llvm;
 using namespace object;
 
 Binary::~Binary() {
-  delete Data;
+  if (BufferOwned)
+    delete Data;
 }
 
-Binary::Binary(unsigned int Type, MemoryBuffer *Source)
-  : TypeID(Type)
-  , Data(Source) {}
+Binary::Binary(unsigned int Type, MemoryBuffer *Source, bool BufferOwned)
+  : TypeID(Type), BufferOwned(BufferOwned), Data(Source) {}
 
 StringRef Binary::getData() const {
   return Data->getBuffer();

Modified: llvm/trunk/lib/Object/COFFObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/COFFObjectFile.cpp?rev=200040&r1=200039&r2=200040&view=diff
==============================================================================
--- llvm/trunk/lib/Object/COFFObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/COFFObjectFile.cpp Fri Jan 24 15:32:21 2014
@@ -463,11 +463,12 @@ error_code COFFObjectFile::initExportTab
   return object_error::success;
 }
 
-COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &EC)
-  : ObjectFile(Binary::ID_COFF, Object), COFFHeader(0), PE32Header(0),
-    DataDirectory(0), SectionTable(0), SymbolTable(0), StringTable(0),
-    StringTableSize(0), ImportDirectory(0), NumberOfImportDirectory(0),
-    ExportDirectory(0) {
+COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &EC,
+                               bool BufferOwned)
+    : ObjectFile(Binary::ID_COFF, Object, BufferOwned), COFFHeader(0),
+      PE32Header(0), DataDirectory(0), SectionTable(0), SymbolTable(0),
+      StringTable(0), StringTableSize(0), ImportDirectory(0),
+      NumberOfImportDirectory(0), ExportDirectory(0) {
   // Check that we at least have enough room for a header.
   if (!checkSize(Data, EC, sizeof(coff_file_header))) return;
 
@@ -1015,9 +1016,10 @@ error_code ExportDirectoryEntryRef::getS
   return object_error::success;
 }
 
-ErrorOr<ObjectFile *> ObjectFile::createCOFFObjectFile(MemoryBuffer *Object) {
+ErrorOr<ObjectFile *> ObjectFile::createCOFFObjectFile(MemoryBuffer *Object,
+                                                       bool BufferOwned) {
   error_code EC;
-  OwningPtr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC));
+  OwningPtr<COFFObjectFile> Ret(new COFFObjectFile(Object, EC, BufferOwned));
   if (EC)
     return EC;
   return Ret.take();

Modified: llvm/trunk/lib/Object/ELFObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/ELFObjectFile.cpp?rev=200040&r1=200039&r2=200040&view=diff
==============================================================================
--- llvm/trunk/lib/Object/ELFObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/ELFObjectFile.cpp Fri Jan 24 15:32:21 2014
@@ -17,7 +17,8 @@
 namespace llvm {
 using namespace object;
 
-ErrorOr<ObjectFile *> ObjectFile::createELFObjectFile(MemoryBuffer *Obj) {
+ErrorOr<ObjectFile *> ObjectFile::createELFObjectFile(MemoryBuffer *Obj,
+                                                      bool BufferOwned) {
   std::pair<unsigned char, unsigned char> Ident = getElfArchType(Obj);
   std::size_t MaxAlignment =
     1ULL << countTrailingZeros(uintptr_t(Obj->getBufferStart()));
@@ -27,41 +28,49 @@ ErrorOr<ObjectFile *> ObjectFile::create
   if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB)
 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
     if (MaxAlignment >= 4)
-      R.reset(new ELFObjectFile<ELFType<support::little, 4, false> >(Obj, EC));
+      R.reset(new ELFObjectFile<ELFType<support::little, 4, false> >(
+          Obj, EC, BufferOwned));
     else
 #endif
     if (MaxAlignment >= 2)
-      R.reset(new ELFObjectFile<ELFType<support::little, 2, false> >(Obj, EC));
+      R.reset(new ELFObjectFile<ELFType<support::little, 2, false> >(
+          Obj, EC, BufferOwned));
     else
       llvm_unreachable("Invalid alignment for ELF file!");
   else if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2MSB)
 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
     if (MaxAlignment >= 4)
-      R.reset(new ELFObjectFile<ELFType<support::big, 4, false> >(Obj, EC));
+      R.reset(new ELFObjectFile<ELFType<support::big, 4, false> >(Obj, EC,
+                                                                  BufferOwned));
     else
 #endif
     if (MaxAlignment >= 2)
-      R.reset(new ELFObjectFile<ELFType<support::big, 2, false> >(Obj, EC));
+      R.reset(new ELFObjectFile<ELFType<support::big, 2, false> >(Obj, EC,
+                                                                  BufferOwned));
     else
       llvm_unreachable("Invalid alignment for ELF file!");
   else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2MSB)
 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
     if (MaxAlignment >= 8)
-      R.reset(new ELFObjectFile<ELFType<support::big, 8, true> >(Obj, EC));
+      R.reset(new ELFObjectFile<ELFType<support::big, 8, true> >(Obj, EC,
+                                                                 BufferOwned));
     else
 #endif
     if (MaxAlignment >= 2)
-      R.reset(new ELFObjectFile<ELFType<support::big, 2, true> >(Obj, EC));
+      R.reset(new ELFObjectFile<ELFType<support::big, 2, true> >(Obj, EC,
+                                                                 BufferOwned));
     else
       llvm_unreachable("Invalid alignment for ELF file!");
   else if (Ident.first == ELF::ELFCLASS64 && Ident.second == ELF::ELFDATA2LSB) {
 #if !LLVM_IS_UNALIGNED_ACCESS_FAST
     if (MaxAlignment >= 8)
-      R.reset(new ELFObjectFile<ELFType<support::little, 8, true> >(Obj, EC));
+      R.reset(new ELFObjectFile<ELFType<support::little, 8, true> >(
+          Obj, EC, BufferOwned));
     else
 #endif
     if (MaxAlignment >= 2)
-      R.reset(new ELFObjectFile<ELFType<support::little, 2, true> >(Obj, EC));
+      R.reset(new ELFObjectFile<ELFType<support::little, 2, true> >(
+          Obj, EC, BufferOwned));
     else
       llvm_unreachable("Invalid alignment for ELF file!");
   }

Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=200040&r1=200039&r2=200040&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Fri Jan 24 15:32:21 2014
@@ -419,10 +419,10 @@ static uint32_t getSectionFlags(const Ma
   return Sect.flags;
 }
 
-MachOObjectFile::MachOObjectFile(MemoryBuffer *Object,
-                                 bool IsLittleEndian, bool Is64bits,
-                                 error_code &ec)
-    : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
+MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian,
+                                 bool Is64bits, error_code &EC,
+                                 bool BufferOwned)
+    : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object, BufferOwned),
       SymtabLoadCmd(NULL), DysymtabLoadCmd(NULL), DataInCodeLoadCmd(NULL) {
   uint32_t LoadCommandCount = this->getHeader().ncmds;
   MachO::LoadCommandType SegmentLoadType = is64Bit() ?
@@ -1582,18 +1582,19 @@ void MachOObjectFile::ReadULEB128s(uint6
   }
 }
 
-ErrorOr<ObjectFile *> ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
+ErrorOr<ObjectFile *> ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer,
+                                                        bool BufferOwned) {
   StringRef Magic = Buffer->getBuffer().slice(0, 4);
   error_code EC;
   OwningPtr<MachOObjectFile> Ret;
   if (Magic == "\xFE\xED\xFA\xCE")
-    Ret.reset(new MachOObjectFile(Buffer, false, false, EC));
+    Ret.reset(new MachOObjectFile(Buffer, false, false, EC, BufferOwned));
   else if (Magic == "\xCE\xFA\xED\xFE")
-    Ret.reset(new MachOObjectFile(Buffer, true, false, EC));
+    Ret.reset(new MachOObjectFile(Buffer, true, false, EC, BufferOwned));
   else if (Magic == "\xFE\xED\xFA\xCF")
-    Ret.reset(new MachOObjectFile(Buffer, false, true, EC));
+    Ret.reset(new MachOObjectFile(Buffer, false, true, EC, BufferOwned));
   else if (Magic == "\xCF\xFA\xED\xFE")
-    Ret.reset(new MachOObjectFile(Buffer, true, true, EC));
+    Ret.reset(new MachOObjectFile(Buffer, true, true, EC, BufferOwned));
   else {
     delete Buffer;
     return object_error::parse_failed;

Modified: llvm/trunk/lib/Object/ObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/ObjectFile.cpp?rev=200040&r1=200039&r2=200040&view=diff
==============================================================================
--- llvm/trunk/lib/Object/ObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/ObjectFile.cpp Fri Jan 24 15:32:21 2014
@@ -23,9 +23,9 @@ using namespace object;
 
 void ObjectFile::anchor() { }
 
-ObjectFile::ObjectFile(unsigned int Type, MemoryBuffer *source)
-  : Binary(Type, source) {
-}
+ObjectFile::ObjectFile(unsigned int Type, MemoryBuffer *Source,
+                       bool BufferOwned)
+    : Binary(Type, Source, BufferOwned) {}
 
 error_code ObjectFile::getSymbolAlignment(DataRefImpl DRI,
                                           uint32_t &Result) const {
@@ -38,8 +38,8 @@ section_iterator ObjectFile::getRelocate
 }
 
 ErrorOr<ObjectFile *> ObjectFile::createObjectFile(MemoryBuffer *Object,
+                                                   bool BufferOwned,
                                                    sys::fs::file_magic Type) {
-  OwningPtr<MemoryBuffer> ScopedObj(Object);
   if (Type == sys::fs::file_magic::unknown)
     Type = sys::fs::identify_magic(Object->getBuffer());
 
@@ -49,12 +49,14 @@ ErrorOr<ObjectFile *> ObjectFile::create
   case sys::fs::file_magic::archive:
   case sys::fs::file_magic::macho_universal_binary:
   case sys::fs::file_magic::windows_resource:
+    if (BufferOwned)
+      delete Object;
     return object_error::invalid_file_type;
   case sys::fs::file_magic::elf_relocatable:
   case sys::fs::file_magic::elf_executable:
   case sys::fs::file_magic::elf_shared_object:
   case sys::fs::file_magic::elf_core:
-    return createELFObjectFile(ScopedObj.take());
+    return createELFObjectFile(Object, BufferOwned);
   case sys::fs::file_magic::macho_object:
   case sys::fs::file_magic::macho_executable:
   case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib:
@@ -65,11 +67,11 @@ ErrorOr<ObjectFile *> ObjectFile::create
   case sys::fs::file_magic::macho_bundle:
   case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub:
   case sys::fs::file_magic::macho_dsym_companion:
-    return createMachOObjectFile(ScopedObj.take());
+    return createMachOObjectFile(Object, BufferOwned);
   case sys::fs::file_magic::coff_object:
   case sys::fs::file_magic::coff_import_library:
   case sys::fs::file_magic::pecoff_executable:
-    return createCOFFObjectFile(ScopedObj.take());
+    return createCOFFObjectFile(Object, BufferOwned);
   }
   llvm_unreachable("Unexpected Object File Type");
 }

Modified: llvm/trunk/tools/llvm-ar/llvm-ar.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-ar/llvm-ar.cpp?rev=200040&r1=200039&r2=200040&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-ar/llvm-ar.cpp (original)
+++ llvm/trunk/tools/llvm-ar/llvm-ar.cpp Fri Jan 24 15:32:21 2014
@@ -692,6 +692,7 @@ static void writeStringTable(raw_fd_ostr
 
 static void writeSymbolTable(
     raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
+    ArrayRef<OwningPtr<MemoryBuffer> > Buffers,
     std::vector<std::pair<unsigned, unsigned> > &MemberOffsetRefs) {
   unsigned StartOffset = 0;
   unsigned MemberNum = 0;
@@ -700,36 +701,13 @@ static void writeSymbolTable(
   for (ArrayRef<NewArchiveIterator>::iterator I = Members.begin(),
                                               E = Members.end();
        I != E; ++I, ++MemberNum) {
-    object::ObjectFile *Obj;
-    if (I->isNewMember()) {
-      const char *Filename = I->getNew();
-      int FD = I->getFD();
-      const sys::fs::file_status &Status = I->getStatus();
-
-      OwningPtr<MemoryBuffer> File;
-      failIfError(MemoryBuffer::getOpenFile(FD, Filename, File,
-                                            Status.getSize(), false),
-                  Filename);
+    const OwningPtr<MemoryBuffer> &MemberBuffer = Buffers[MemberNum];
+    ErrorOr<object::ObjectFile *> ObjOrErr =
+        object::ObjectFile::createObjectFile(MemberBuffer.get(), false);
+    if (!ObjOrErr)
+      continue;  // FIXME: check only for "not an object file" errors.
+    object::ObjectFile *Obj = ObjOrErr.get();
 
-      if (ErrorOr<object::ObjectFile *> ObjOrErr =
-              object::ObjectFile::createObjectFile(File.take()))
-        Obj = ObjOrErr.get();
-      else
-        Obj = NULL;
-    } else {
-      object::Archive::child_iterator OldMember = I->getOld();
-      OwningPtr<object::Binary> Binary;
-      error_code EC = OldMember->getAsBinary(Binary);
-      if (EC) { // FIXME: check only for "not an object file" errors.
-        Obj = NULL;
-      } else {
-        Obj = dyn_cast<object::ObjectFile>(Binary.get());
-        if (Obj)
-          Binary.take();
-      }
-    }
-    if (!Obj)
-      continue;
     DeleteIt.push_back(Obj);
     if (!StartOffset) {
       printMemberHeader(Out, "", sys::TimeValue::now(), 0, 0, 0, 0);
@@ -800,8 +778,29 @@ static void performWriteOperation(Archiv
 
   std::vector<std::pair<unsigned, unsigned> > MemberOffsetRefs;
 
+  std::vector<OwningPtr<MemoryBuffer> > MemberBuffers;
+  MemberBuffers.resize(NewMembers.size());
+
+  for (unsigned I = 0, N = NewMembers.size(); I < N; ++I) {
+    OwningPtr<MemoryBuffer> &MemberBuffer = MemberBuffers[I];
+    NewArchiveIterator &Member = NewMembers[I];
+
+    if (Member.isNewMember()) {
+      const char *Filename = Member.getNew();
+      int FD = Member.getFD();
+      const sys::fs::file_status &Status = Member.getStatus();
+      failIfError(MemoryBuffer::getOpenFile(FD, Filename, MemberBuffer,
+                                            Status.getSize(), false),
+                  Filename);
+
+    } else {
+      object::Archive::child_iterator OldMember = Member.getOld();
+      failIfError(OldMember->getMemoryBuffer(MemberBuffer));
+    }
+  }
+
   if (Symtab) {
-    writeSymbolTable(Out, NewMembers, MemberOffsetRefs);
+    writeSymbolTable(Out, NewMembers, MemberBuffers, MemberOffsetRefs);
   }
 
   std::vector<unsigned> StringMapIndexes;
@@ -825,16 +824,11 @@ static void performWriteOperation(Archiv
     }
     Out.seek(Pos);
 
+    const OwningPtr<MemoryBuffer> &File = MemberBuffers[MemberNum];
     if (I->isNewMember()) {
       const char *FileName = I->getNew();
-      int FD = I->getFD();
       const sys::fs::file_status &Status = I->getStatus();
 
-      OwningPtr<MemoryBuffer> File;
-      failIfError(MemoryBuffer::getOpenFile(FD, FileName, File,
-                                            Status.getSize(), false),
-                  FileName);
-
       StringRef Name = sys::path::filename(FileName);
       if (Name.size() < 16)
         printMemberHeader(Out, Name, Status.getLastModificationTime(),
@@ -845,7 +839,6 @@ static void performWriteOperation(Archiv
                           Status.getLastModificationTime(), Status.getUser(),
                           Status.getGroup(), Status.permissions(),
                           Status.getSize());
-      Out << File->getBuffer();
     } else {
       object::Archive::child_iterator OldMember = I->getOld();
       StringRef Name = I->getName();
@@ -859,9 +852,10 @@ static void performWriteOperation(Archiv
                           OldMember->getLastModified(), OldMember->getUID(),
                           OldMember->getGID(), OldMember->getAccessMode(),
                           OldMember->getSize());
-      Out << OldMember->getBuffer();
     }
 
+    Out << File->getBuffer();
+
     if (Out.tell() % 2)
       Out << '\n';
   }





More information about the llvm-commits mailing list