Move definitions to cpp file. No functionality change.

llvm-svn: 196563
This commit is contained in:
Rui Ueyama
2013-12-06 04:43:01 +00:00
parent b1c2015203
commit 34efe77742
3 changed files with 170 additions and 129 deletions

View File

@@ -6,13 +6,12 @@
// License. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
#ifndef LLD_READER_WRITER_FILE_ARCHIVE_H
#define LLD_READER_WRITER_FILE_ARCHIVE_H
#include "lld/Core/ArchiveLibraryFile.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/Archive.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -23,115 +22,26 @@ namespace lld {
/// \brief The FileArchive class represents an Archive Library file
class FileArchive : public ArchiveLibraryFile {
public:
FileArchive(const LinkingContext &context, std::unique_ptr<MemoryBuffer> mb,
error_code &ec, bool isWholeArchive);
virtual ~FileArchive() {}
virtual ~FileArchive() { }
virtual const File *find(StringRef name, bool dataSymbolOnly) const;
/// \brief Check if any member of the archive contains an Atom with the
/// specified name and return the File object for that member, or nullptr.
virtual const File *find(StringRef name, bool dataSymbolOnly) const {
auto member = _symbolMemberMap.find(name);
if (member == _symbolMemberMap.end())
return nullptr;
llvm::object::Archive::child_iterator ci = member->second;
if (dataSymbolOnly) {
OwningPtr<MemoryBuffer> buff;
if (ci->getMemoryBuffer(buff, true))
return nullptr;
if (isDataSymbol(buff.take(), name))
return nullptr;
}
std::vector<std::unique_ptr<File>> result;
OwningPtr<MemoryBuffer> buff;
if (ci->getMemoryBuffer(buff, true))
return nullptr;
if (_context.logInputFiles())
llvm::outs() << buff->getBufferIdentifier() << "\n";
std::unique_ptr<MemoryBuffer> mb(buff.take());
if (_context.getDefaultReader().parseFile(mb, result))
return nullptr;
assert(result.size() == 1);
// give up the pointer so that this object no longer manages it
return result[0].release();
}
/// \brief Load all members of the archive ?
/// \brief Load all members of the archive?
virtual bool isWholeArchive() const { return _isWholeArchive; }
/// \brief parse each member
virtual error_code
parseAllMembers(std::vector<std::unique_ptr<File>> &result) const {
for (auto mf = _archive->begin_children(),
me = _archive->end_children(); mf != me; ++mf) {
OwningPtr<MemoryBuffer> buff;
error_code ec;
if ((ec = mf->getMemoryBuffer(buff, true)))
return ec;
if (_context.logInputFiles())
llvm::outs() << buff->getBufferIdentifier() << "\n";
std::unique_ptr<MemoryBuffer> mbc(buff.take());
if ((ec = _context.getDefaultReader().parseFile(mbc, result)))
return ec;
}
return error_code::success();
}
parseAllMembers(std::vector<std::unique_ptr<File> > &result) const;
virtual const atom_collection<DefinedAtom> &defined() const {
return _definedAtoms;
}
virtual const atom_collection<UndefinedAtom> &undefined() const {
return _undefinedAtoms;
}
virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const {
return _sharedLibraryAtoms;
}
virtual const atom_collection<AbsoluteAtom> &absolute() const {
return _absoluteAtoms;
}
virtual const atom_collection<DefinedAtom> &defined() const;
virtual const atom_collection<UndefinedAtom> &undefined() const;
virtual const atom_collection<SharedLibraryAtom> &sharedLibrary() const;
virtual const atom_collection<AbsoluteAtom> &absolute() const;
protected:
error_code isDataSymbol(MemoryBuffer *mb, StringRef symbol) const {
std::unique_ptr<llvm::object::ObjectFile>
obj(llvm::object::ObjectFile::createObjectFile(mb));
error_code ec;
llvm::object::SymbolRef::Type symtype;
uint32_t symflags;
llvm::object::symbol_iterator ibegin = obj->begin_symbols();
llvm::object::symbol_iterator iend = obj->end_symbols();
StringRef symbolname;
for (llvm::object::symbol_iterator i = ibegin; i != iend; i.increment(ec)) {
if (ec) return ec;
// Get symbol name
if ((ec = (i->getName(symbolname)))) return ec;
if (symbolname != symbol)
continue;
// Get symbol flags
if ((ec = (i->getFlags(symflags)))) return ec;
if (symflags <= llvm::object::SymbolRef::SF_Undefined)
continue;
// Get Symbol Type
if ((ec = (i->getType(symtype)))) return ec;
if (symtype == llvm::object::SymbolRef::ST_Data) {
return error_code::success();
}
}
return llvm::object::object_error::parse_failed;
}
error_code isDataSymbol(MemoryBuffer *mb, StringRef symbol) const;
private:
std::unique_ptr<llvm::object::Archive> _archive;
@@ -142,33 +52,7 @@ private:
bool _isWholeArchive;
std::unordered_map<StringRef, llvm::object::Archive::child_iterator>
_symbolMemberMap;
public:
/// only subclasses of ArchiveLibraryFile can be instantiated
FileArchive(const LinkingContext &context,
std::unique_ptr<MemoryBuffer> mb, error_code &ec,
bool isWholeArchive)
: ArchiveLibraryFile(context, mb->getBufferIdentifier()),
_isWholeArchive(isWholeArchive) {
std::unique_ptr<llvm::object::Archive> archive_obj(
new llvm::object::Archive(mb.release(), ec));
if (ec)
return;
_archive.swap(archive_obj);
// Cache symbols.
for (auto i = _archive->begin_symbols(), e = _archive->end_symbols();
i != e; ++i) {
StringRef name;
llvm::object::Archive::child_iterator member;
if ((ec = i->getName(name)))
return;
if ((ec = i->getMember(member)))
return;
_symbolMemberMap[name] = member;
}
}
}; // class FileArchive
};
} // end namespace lld

View File

@@ -7,6 +7,7 @@ add_subdirectory(PECOFF)
add_subdirectory(YAML)
add_lld_library(lldReaderWriter
CoreLinkingContext.cpp
FileArchive.cpp
LinkerScript.cpp
Reader.cpp
Writer.cpp

View File

@@ -0,0 +1,156 @@
//===- lld/ReaderWriter/FileArchive.cpp - Archive Library File -----------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===---------------------------------------------------------------------===//
#include "lld/ReaderWriter/FileArchive.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/Archive.h"
#include "llvm/Support/MemoryBuffer.h"
#include <unordered_map>
namespace lld {
/// \brief Check if any member of the archive contains an Atom with the
/// specified name and return the File object for that member, or nullptr.
const File *FileArchive::find(StringRef name, bool dataSymbolOnly) const {
auto member = _symbolMemberMap.find(name);
if (member == _symbolMemberMap.end())
return nullptr;
llvm::object::Archive::child_iterator ci = member->second;
if (dataSymbolOnly) {
OwningPtr<MemoryBuffer> buff;
if (ci->getMemoryBuffer(buff, true))
return nullptr;
if (isDataSymbol(buff.take(), name))
return nullptr;
}
std::vector<std::unique_ptr<File> > result;
OwningPtr<MemoryBuffer> buff;
if (ci->getMemoryBuffer(buff, true))
return nullptr;
if (_context.logInputFiles())
llvm::outs() << buff->getBufferIdentifier() << "\n";
std::unique_ptr<MemoryBuffer> mb(buff.take());
if (_context.getDefaultReader().parseFile(mb, result))
return nullptr;
assert(result.size() == 1);
// give up the pointer so that this object no longer manages it
return result[0].release();
}
/// \brief parse each member
error_code FileArchive::parseAllMembers(
std::vector<std::unique_ptr<File> > &result) const {
for (auto mf = _archive->begin_children(), me = _archive->end_children();
mf != me; ++mf) {
OwningPtr<MemoryBuffer> buff;
error_code ec;
if ((ec = mf->getMemoryBuffer(buff, true)))
return ec;
if (_context.logInputFiles())
llvm::outs() << buff->getBufferIdentifier() << "\n";
std::unique_ptr<MemoryBuffer> mbc(buff.take());
if ((ec = _context.getDefaultReader().parseFile(mbc, result)))
return ec;
}
return error_code::success();
}
const ArchiveLibraryFile::atom_collection<DefinedAtom> &
FileArchive::defined() const {
return _definedAtoms;
}
const ArchiveLibraryFile::atom_collection<UndefinedAtom> &
FileArchive::undefined() const {
return _undefinedAtoms;
}
const ArchiveLibraryFile::atom_collection<SharedLibraryAtom> &
FileArchive::sharedLibrary() const {
return _sharedLibraryAtoms;
}
const ArchiveLibraryFile::atom_collection<AbsoluteAtom> &
FileArchive::absolute() const {
return _absoluteAtoms;
}
error_code FileArchive::isDataSymbol(MemoryBuffer *mb, StringRef symbol) const {
std::unique_ptr<llvm::object::ObjectFile> obj(
llvm::object::ObjectFile::createObjectFile(mb));
error_code ec;
llvm::object::SymbolRef::Type symtype;
uint32_t symflags;
llvm::object::symbol_iterator ibegin = obj->begin_symbols();
llvm::object::symbol_iterator iend = obj->end_symbols();
StringRef symbolname;
for (llvm::object::symbol_iterator i = ibegin; i != iend; i.increment(ec)) {
if (ec)
return ec;
// Get symbol name
if ((ec = i->getName(symbolname)))
return ec;
if (symbolname != symbol)
continue;
// Get symbol flags
if ((ec = i->getFlags(symflags)))
return ec;
if (symflags <= llvm::object::SymbolRef::SF_Undefined)
continue;
// Get Symbol Type
if ((ec = (i->getType(symtype))))
return ec;
if (symtype == llvm::object::SymbolRef::ST_Data) {
return error_code::success();
}
}
return llvm::object::object_error::parse_failed;
}
FileArchive::FileArchive(const LinkingContext &context,
std::unique_ptr<MemoryBuffer> mb, error_code &ec,
bool isWholeArchive)
: ArchiveLibraryFile(context, mb->getBufferIdentifier()),
_isWholeArchive(isWholeArchive) {
std::unique_ptr<llvm::object::Archive> archive_obj(
new llvm::object::Archive(mb.release(), ec));
if (ec)
return;
_archive.swap(archive_obj);
// Cache symbols.
for (auto i = _archive->begin_symbols(), e = _archive->end_symbols(); i != e;
++i) {
StringRef name;
llvm::object::Archive::child_iterator member;
if ((ec = i->getName(name)))
return;
if ((ec = i->getMember(member)))
return;
_symbolMemberMap[name] = member;
}
}
} // end namespace lld