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

Alp Toker alp at nuanti.com
Fri Jan 24 14:01:54 PST 2014


On 24/01/2014 21:32, Rafael Espindola wrote:
> 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);

Managing MemoryBuffer lifetimes this way seems unsatisfactory. Would it 
be possible to refcount or use some kind of smart pointer?

Alp.


>   
>     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';
>     }
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

-- 
http://www.nuanti.com
the browser experts




More information about the llvm-commits mailing list