Don't own the buffer in object::Binary.

Owning the buffer is somewhat inflexible. Some Binaries have sub Binaries
(like Archive) and we had to create dummy buffers just to handle that. It is
also a bad fit for IRObjectFile where the Module wants to own the buffer too.

Keeping this ownership would make supporting IR inside native objects
particularly painful.

This patch focuses in lib/Object. If something elsewhere used to own an Binary,
now it also owns a MemoryBuffer.

This patch introduces a few new types.

* MemoryBufferRef. This is just a pair of StringRefs for the data and name.
  This is to MemoryBuffer as StringRef is to std::string.
* OwningBinary. A combination of Binary and a MemoryBuffer. This is needed
  for convenience functions that take a filename and return both the
  buffer and the Binary using that buffer.

The C api now uses OwningBinary to avoid any change in semantics. I will start
a new thread to see if we want to change it and how.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216002 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola
2014-08-19 18:44:46 +00:00
parent 2ac376ba34
commit 548f2b6e8f
48 changed files with 375 additions and 314 deletions

View File

@ -686,7 +686,7 @@ static void writeStringTable(raw_fd_ostream &Out,
static void
writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
MutableArrayRef<std::unique_ptr<MemoryBuffer>> Buffers,
ArrayRef<MemoryBufferRef> Buffers,
std::vector<std::pair<unsigned, unsigned>> &MemberOffsetRefs) {
unsigned StartOffset = 0;
unsigned MemberNum = 0;
@ -697,7 +697,7 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
for (ArrayRef<NewArchiveIterator>::iterator I = Members.begin(),
E = Members.end();
I != E; ++I, ++MemberNum) {
std::unique_ptr<MemoryBuffer> &MemberBuffer = Buffers[MemberNum];
MemoryBufferRef MemberBuffer = Buffers[MemberNum];
ErrorOr<std::unique_ptr<object::SymbolicFile>> ObjOrErr =
object::SymbolicFile::createSymbolicFile(
MemberBuffer, sys::fs::file_magic::unknown, &Context);
@ -725,7 +725,6 @@ writeSymbolTable(raw_fd_ostream &Out, ArrayRef<NewArchiveIterator> Members,
MemberOffsetRefs.push_back(std::make_pair(Out.tell(), MemberNum));
print32BE(Out, 0);
}
MemberBuffer.reset(Obj.releaseBuffer());
}
Out << NameOS.str();
@ -759,12 +758,12 @@ static void performWriteOperation(ArchiveOperation Operation,
std::vector<std::pair<unsigned, unsigned> > MemberOffsetRefs;
std::vector<std::unique_ptr<MemoryBuffer>> MemberBuffers;
MemberBuffers.resize(NewMembers.size());
std::vector<std::unique_ptr<MemoryBuffer>> Buffers;
std::vector<MemoryBufferRef> Members;
for (unsigned I = 0, N = NewMembers.size(); I < N; ++I) {
std::unique_ptr<MemoryBuffer> &MemberBuffer = MemberBuffers[I];
NewArchiveIterator &Member = NewMembers[I];
MemoryBufferRef MemberRef;
if (Member.isNewMember()) {
const char *Filename = Member.getNew();
@ -773,18 +772,20 @@ static void performWriteOperation(ArchiveOperation Operation,
ErrorOr<std::unique_ptr<MemoryBuffer>> MemberBufferOrErr =
MemoryBuffer::getOpenFile(FD, Filename, Status.getSize(), false);
failIfError(MemberBufferOrErr.getError(), Filename);
MemberBuffer = std::move(MemberBufferOrErr.get());
Buffers.push_back(std::move(MemberBufferOrErr.get()));
MemberRef = Buffers.back()->getMemBufferRef();
} else {
object::Archive::child_iterator OldMember = Member.getOld();
ErrorOr<std::unique_ptr<MemoryBuffer>> MemberBufferOrErr =
OldMember->getMemoryBuffer();
ErrorOr<MemoryBufferRef> MemberBufferOrErr =
OldMember->getMemoryBufferRef();
failIfError(MemberBufferOrErr.getError());
MemberBuffer = std::move(MemberBufferOrErr.get());
MemberRef = MemberBufferOrErr.get();
}
Members.push_back(MemberRef);
}
if (Symtab) {
writeSymbolTable(Out, NewMembers, MemberBuffers, MemberOffsetRefs);
writeSymbolTable(Out, NewMembers, Members, MemberOffsetRefs);
}
std::vector<unsigned> StringMapIndexes;
@ -808,7 +809,7 @@ static void performWriteOperation(ArchiveOperation Operation,
}
Out.seek(Pos);
const MemoryBuffer *File = MemberBuffers[MemberNum].get();
MemoryBufferRef File = Members[MemberNum];
if (I->isNewMember()) {
const char *FileName = I->getNew();
const sys::fs::file_status &Status = I->getStatus();
@ -838,7 +839,7 @@ static void performWriteOperation(ArchiveOperation Operation,
OldMember->getSize());
}
Out << File->getBuffer();
Out << File.getBuffer();
if (Out.tell() % 2)
Out << '\n';
@ -943,7 +944,7 @@ static int performOperation(ArchiveOperation Operation) {
}
if (!EC) {
object::Archive Archive(std::move(Buf.get()), EC);
object::Archive Archive(Buf.get()->getMemBufferRef(), EC);
if (EC) {
errs() << ToolName << ": error loading '" << ArchiveName