mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-25 06:40:18 +00:00
COFF: Make the Driver own all MemoryBuffers. NFC.
Previously, a MemoryBuffer of a file was owned by each InputFile object. This patch makes the Driver own all of them. InputFiles now have only MemoryBufferRefs. This change simplifies ownership managment (particularly for ObjectFile -- the object owned a MemoryBuffer only when it's not created from an archive file, because in that case a parent archive file owned the entire buffer. Now it owns nothing unconditionally.) llvm-svn: 238690
This commit is contained in:
parent
faa8bfdd1a
commit
d7c2f5847a
@ -60,10 +60,18 @@ static std::string getOutputPath(llvm::opt::InputArgList *Args) {
|
||||
llvm_unreachable("internal error");
|
||||
}
|
||||
|
||||
std::unique_ptr<InputFile> createFile(StringRef Path) {
|
||||
// Opens a file. Path has to be resolved already.
|
||||
// Newly created memory buffers are owned by this driver.
|
||||
ErrorOr<std::unique_ptr<InputFile>> LinkerDriver::createFile(StringRef Path) {
|
||||
auto MBOrErr = MemoryBuffer::getFile(Path);
|
||||
if (auto EC = MBOrErr.getError())
|
||||
return EC;
|
||||
std::unique_ptr<MemoryBuffer> MB = std::move(MBOrErr.get());
|
||||
MemoryBufferRef MBRef = MB->getMemBufferRef();
|
||||
OwningMBs.push_back(std::move(MB)); // take ownership
|
||||
if (StringRef(Path).endswith_lower(".lib"))
|
||||
return llvm::make_unique<ArchiveFile>(Path);
|
||||
return llvm::make_unique<ObjectFile>(Path);
|
||||
return std::unique_ptr<InputFile>(new ArchiveFile(MBRef));
|
||||
return std::unique_ptr<InputFile>(new ObjectFile(MBRef));
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -95,9 +103,15 @@ LinkerDriver::parseDirectives(StringRef S,
|
||||
return EC;
|
||||
std::unique_ptr<llvm::opt::InputArgList> Args = std::move(ArgsOrErr.get());
|
||||
|
||||
for (auto *Arg : Args->filtered(OPT_defaultlib))
|
||||
if (Optional<StringRef> Path = findLib(Arg->getValue()))
|
||||
Res->push_back(llvm::make_unique<ArchiveFile>(*Path));
|
||||
for (auto *Arg : Args->filtered(OPT_defaultlib)) {
|
||||
if (Optional<StringRef> Path = findLib(Arg->getValue())) {
|
||||
auto FileOrErr = createFile(*Path);
|
||||
if (auto EC = FileOrErr.getError())
|
||||
return EC;
|
||||
std::unique_ptr<InputFile> File = std::move(FileOrErr.get());
|
||||
Res->push_back(std::move(File));
|
||||
}
|
||||
}
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
@ -289,7 +303,13 @@ bool LinkerDriver::link(int Argc, const char *Argv[]) {
|
||||
// Parse all input files and put all symbols to the symbol table.
|
||||
// The symbol table will take care of name resolution.
|
||||
for (StringRef Path : Inputs) {
|
||||
if (auto EC = Symtab.addFile(createFile(Path))) {
|
||||
auto FileOrErr = createFile(Path);
|
||||
if (auto EC = FileOrErr.getError()) {
|
||||
llvm::errs() << Path << ": " << EC.message() << "\n";
|
||||
return false;
|
||||
}
|
||||
std::unique_ptr<InputFile> File = std::move(FileOrErr.get());
|
||||
if (auto EC = Symtab.addFile(std::move(File))) {
|
||||
llvm::errs() << Path << ": " << EC.message() << "\n";
|
||||
return false;
|
||||
}
|
||||
|
@ -47,6 +47,9 @@ public:
|
||||
private:
|
||||
StringAllocator Alloc;
|
||||
|
||||
// Opens a file. Path has to be resolved already.
|
||||
ErrorOr<std::unique_ptr<InputFile>> createFile(StringRef Path);
|
||||
|
||||
// Searches a file from search paths.
|
||||
Optional<StringRef> findFile(StringRef Filename);
|
||||
Optional<StringRef> findLib(StringRef Filename);
|
||||
@ -59,6 +62,10 @@ private:
|
||||
|
||||
std::vector<StringRef> SearchPaths;
|
||||
std::set<std::string> VisitedFiles;
|
||||
|
||||
// Driver is the owner of all opened files.
|
||||
// InputFiles have MemoryBufferRefs to them.
|
||||
std::vector<std::unique_ptr<MemoryBuffer>> OwningMBs;
|
||||
};
|
||||
|
||||
ErrorOr<std::unique_ptr<llvm::opt::InputArgList>>
|
||||
|
@ -46,14 +46,8 @@ std::string InputFile::getShortName() {
|
||||
}
|
||||
|
||||
std::error_code ArchiveFile::parse() {
|
||||
// Get a memory buffer.
|
||||
auto MBOrErr = MemoryBuffer::getFile(Filename);
|
||||
if (auto EC = MBOrErr.getError())
|
||||
return EC;
|
||||
MB = std::move(MBOrErr.get());
|
||||
|
||||
// Parse a memory buffer as an archive file.
|
||||
auto ArchiveOrErr = Archive::create(MB->getMemBufferRef());
|
||||
// Parse a MemoryBufferRef as an archive file.
|
||||
auto ArchiveOrErr = Archive::create(MB);
|
||||
if (auto EC = ArchiveOrErr.getError())
|
||||
return EC;
|
||||
File = std::move(ArchiveOrErr.get());
|
||||
@ -89,17 +83,8 @@ ErrorOr<MemoryBufferRef> ArchiveFile::getMember(const Archive::Symbol *Sym) {
|
||||
}
|
||||
|
||||
std::error_code ObjectFile::parse() {
|
||||
// MBRef is not initialized if this is not an archive member.
|
||||
if (MBRef.getBuffer().empty()) {
|
||||
auto MBOrErr = MemoryBuffer::getFile(Filename);
|
||||
if (auto EC = MBOrErr.getError())
|
||||
return EC;
|
||||
MB = std::move(MBOrErr.get());
|
||||
MBRef = MB->getMemBufferRef();
|
||||
}
|
||||
|
||||
// Parse a memory buffer as a COFF file.
|
||||
auto BinOrErr = createBinary(MBRef);
|
||||
auto BinOrErr = createBinary(MB);
|
||||
if (auto EC = BinOrErr.getError())
|
||||
return EC;
|
||||
std::unique_ptr<Binary> Bin = std::move(BinOrErr.get());
|
||||
@ -108,7 +93,7 @@ std::error_code ObjectFile::parse() {
|
||||
Bin.release();
|
||||
COFFObj.reset(Obj);
|
||||
} else {
|
||||
return make_dynamic_error_code(Twine(Filename) + " is not a COFF file.");
|
||||
return make_dynamic_error_code(getName() + " is not a COFF file.");
|
||||
}
|
||||
|
||||
// Read section and symbol tables.
|
||||
@ -160,14 +145,14 @@ std::error_code ObjectFile::initializeSymbols() {
|
||||
// Get a COFFSymbolRef object.
|
||||
auto SymOrErr = COFFObj->getSymbol(I);
|
||||
if (auto EC = SymOrErr.getError())
|
||||
return make_dynamic_error_code(Twine("broken object file: ") + Filename +
|
||||
return make_dynamic_error_code("broken object file: " + getName() +
|
||||
": " + EC.message());
|
||||
COFFSymbolRef Sym = SymOrErr.get();
|
||||
|
||||
// Get a symbol name.
|
||||
StringRef SymbolName;
|
||||
if (auto EC = COFFObj->getSymbolName(Sym, SymbolName))
|
||||
return make_dynamic_error_code(Twine("broken object file: ") + Filename +
|
||||
return make_dynamic_error_code("broken object file: " + getName() +
|
||||
": " + EC.message());
|
||||
// Skip special symbols.
|
||||
if (SymbolName == "@comp.id" || SymbolName == "@feat.00")
|
||||
@ -220,8 +205,8 @@ SymbolBody *ObjectFile::createSymbolBody(StringRef Name, COFFSymbolRef Sym,
|
||||
}
|
||||
|
||||
std::error_code ImportFile::parse() {
|
||||
const char *Buf = MBRef.getBufferStart();
|
||||
const char *End = MBRef.getBufferEnd();
|
||||
const char *Buf = MB.getBufferStart();
|
||||
const char *End = MB.getBufferEnd();
|
||||
const auto *Hdr = reinterpret_cast<const coff_import_header *>(Buf);
|
||||
|
||||
// Check if the total size is valid.
|
||||
|
@ -63,7 +63,7 @@ private:
|
||||
// .lib or .a file.
|
||||
class ArchiveFile : public InputFile {
|
||||
public:
|
||||
explicit ArchiveFile(StringRef S) : InputFile(ArchiveKind), Filename(S) {}
|
||||
explicit ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind), MB(M) {}
|
||||
static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
|
||||
std::error_code parse() override;
|
||||
StringRef getName() override { return Filename; }
|
||||
@ -79,7 +79,7 @@ public:
|
||||
private:
|
||||
std::unique_ptr<Archive> File;
|
||||
std::string Filename;
|
||||
std::unique_ptr<MemoryBuffer> MB;
|
||||
MemoryBufferRef MB;
|
||||
std::vector<SymbolBody *> SymbolBodies;
|
||||
std::set<const char *> Seen;
|
||||
llvm::MallocAllocator Alloc;
|
||||
@ -88,13 +88,10 @@ private:
|
||||
// .obj or .o file. This may be a member of an archive file.
|
||||
class ObjectFile : public InputFile {
|
||||
public:
|
||||
explicit ObjectFile(StringRef S) : InputFile(ObjectKind), Filename(S) {}
|
||||
ObjectFile(StringRef S, MemoryBufferRef M)
|
||||
: InputFile(ObjectKind), Filename(S), MBRef(M) {}
|
||||
|
||||
explicit ObjectFile(MemoryBufferRef M) : InputFile(ObjectKind), MB(M) {}
|
||||
static bool classof(const InputFile *F) { return F->kind() == ObjectKind; }
|
||||
std::error_code parse() override;
|
||||
StringRef getName() override { return Filename; }
|
||||
StringRef getName() override { return MB.getBufferIdentifier(); }
|
||||
std::vector<Chunk *> &getChunks() { return Chunks; }
|
||||
std::vector<SymbolBody *> &getSymbols() override { return SymbolBodies; }
|
||||
|
||||
@ -115,10 +112,8 @@ private:
|
||||
SymbolBody *createSymbolBody(StringRef Name, COFFSymbolRef Sym,
|
||||
const void *Aux, bool IsFirst);
|
||||
|
||||
std::string Filename;
|
||||
std::unique_ptr<COFFObjectFile> COFFObj;
|
||||
std::unique_ptr<MemoryBuffer> MB;
|
||||
MemoryBufferRef MBRef;
|
||||
MemoryBufferRef MB;
|
||||
StringRef Directives;
|
||||
llvm::BumpPtrAllocator Alloc;
|
||||
|
||||
@ -148,15 +143,15 @@ private:
|
||||
// for details about the format.
|
||||
class ImportFile : public InputFile {
|
||||
public:
|
||||
explicit ImportFile(MemoryBufferRef M) : InputFile(ImportKind), MBRef(M) {}
|
||||
explicit ImportFile(MemoryBufferRef M) : InputFile(ImportKind), MB(M) {}
|
||||
static bool classof(const InputFile *F) { return F->kind() == ImportKind; }
|
||||
StringRef getName() override { return MBRef.getBufferIdentifier(); }
|
||||
StringRef getName() override { return MB.getBufferIdentifier(); }
|
||||
std::vector<SymbolBody *> &getSymbols() override { return SymbolBodies; }
|
||||
|
||||
private:
|
||||
std::error_code parse() override;
|
||||
|
||||
MemoryBufferRef MBRef;
|
||||
MemoryBufferRef MB;
|
||||
std::vector<SymbolBody *> SymbolBodies;
|
||||
llvm::BumpPtrAllocator Alloc;
|
||||
StringAllocator StringAlloc;
|
||||
|
@ -87,7 +87,7 @@ ErrorOr<std::unique_ptr<InputFile>> Lazy::getMember() {
|
||||
if (Magic != file_magic::coff_object)
|
||||
return make_dynamic_error_code("unknown file type");
|
||||
|
||||
std::unique_ptr<InputFile> Obj(new ObjectFile(MBRef.getBufferIdentifier(), MBRef));
|
||||
std::unique_ptr<InputFile> Obj(new ObjectFile(MBRef));
|
||||
Obj->setParentName(File->getName());
|
||||
return std::move(Obj);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user