[ELF] clang-format ReaderELF.cpp

llvm-svn: 172674
This commit is contained in:
Michael J. Spencer 2013-01-16 23:34:32 +00:00
parent 7d9669e432
commit 84d3b01fb5
1 changed files with 78 additions and 91 deletions

View File

@ -46,10 +46,9 @@ using llvm::support::endianness;
using namespace llvm::object; using namespace llvm::object;
namespace { namespace {
// \brief Read a binary, find out based on the symbol table contents what kind /// \brief Read a binary, find out based on the symbol table contents what kind
// of symbol it is and create corresponding atoms for it /// of symbol it is and create corresponding atoms for it
template<class ELFT> template <class ELFT> class FileELF : public File {
class FileELF: public File {
typedef Elf_Sym_Impl<ELFT> Elf_Sym; typedef Elf_Sym_Impl<ELFT> Elf_Sym;
typedef Elf_Shdr_Impl<ELFT> Elf_Shdr; typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
typedef Elf_Rel_Impl<ELFT, false> Elf_Rel; typedef Elf_Rel_Impl<ELFT, false> Elf_Rel;
@ -57,7 +56,7 @@ class FileELF: public File {
public: public:
FileELF(std::unique_ptr<llvm::MemoryBuffer> MB, llvm::error_code &EC) FileELF(std::unique_ptr<llvm::MemoryBuffer> MB, llvm::error_code &EC)
: File(MB->getBufferIdentifier()) { : File(MB->getBufferIdentifier()) {
llvm::OwningPtr<Binary> binaryFile; llvm::OwningPtr<Binary> binaryFile;
EC = createBinary(MB.release(), binaryFile); EC = createBinary(MB.release(), binaryFile);
if (EC) if (EC)
@ -73,7 +72,7 @@ public:
binaryFile.take(); binaryFile.take();
std::map< const Elf_Shdr *, std::vector<const Elf_Sym *>> sectionSymbols; std::map<const Elf_Shdr *, std::vector<const Elf_Sym *>> sectionSymbols;
// Handle: SHT_REL and SHT_RELA sections: // Handle: SHT_REL and SHT_RELA sections:
// Increment over the sections, when REL/RELA section types are found add // Increment over the sections, when REL/RELA section types are found add
@ -98,7 +97,7 @@ public:
auto rae(_objFile->endELFRela(section)); auto rae(_objFile->endELFRela(section));
auto &Ref = _relocationAddendRefences[sectionName]; auto &Ref = _relocationAddendRefences[sectionName];
for (; rai != rae; rai++) { for (; rai != rae; ++rai) {
Ref.push_back(&*rai); Ref.push_back(&*rai);
} }
} }
@ -115,7 +114,7 @@ public:
auto re(_objFile->endELFRel(section)); auto re(_objFile->endELFRel(section));
auto &Ref = _relocationReferences[sectionName]; auto &Ref = _relocationReferences[sectionName];
for (; ri != re; ri++) { for (; ri != re; ++ri) {
Ref.push_back(&*ri); Ref.push_back(&*ri);
} }
} }
@ -134,7 +133,7 @@ public:
return; return;
const Elf_Shdr *section = _objFile->getElfSection(sit); const Elf_Shdr *section = _objFile->getElfSection(sit);
const Elf_Sym *symbol = _objFile->getElfSymbol(it); const Elf_Sym *symbol = _objFile->getElfSymbol(it);
llvm::StringRef symbolName; llvm::StringRef symbolName;
if ((EC = _objFile->getSymbolName(section, symbol, symbolName))) if ((EC = _objFile->getSymbolName(section, symbol, symbolName)))
@ -142,34 +141,31 @@ public:
if (symbol->st_shndx == llvm::ELF::SHN_ABS) { if (symbol->st_shndx == llvm::ELF::SHN_ABS) {
// Create an absolute atom. // Create an absolute atom.
auto *newAtom = new (_readerStorage.Allocate< auto *newAtom = new (_readerStorage.Allocate<ELFAbsoluteAtom<ELFT>>())
ELFAbsoluteAtom<ELFT> > ()) ELFAbsoluteAtom<ELFT>(*this, symbolName, symbol,
ELFAbsoluteAtom<ELFT>( symbol->st_value);
*this, symbolName, symbol, symbol->st_value);
_absoluteAtoms._atoms.push_back(newAtom); _absoluteAtoms._atoms.push_back(newAtom);
_symbolToAtomMapping.insert(std::make_pair(symbol, newAtom)); _symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));
} else if (symbol->st_shndx == llvm::ELF::SHN_UNDEF) { } else if (symbol->st_shndx == llvm::ELF::SHN_UNDEF) {
// Create an undefined atom. // Create an undefined atom.
auto *newAtom = new (_readerStorage.Allocate< auto *newAtom = new (_readerStorage.Allocate<ELFUndefinedAtom<ELFT>>())
ELFUndefinedAtom<ELFT> > ()) ELFUndefinedAtom<ELFT>(*this, symbolName, symbol);
ELFUndefinedAtom<ELFT>(
*this, symbolName, symbol);
_undefinedAtoms._atoms.push_back(newAtom); _undefinedAtoms._atoms.push_back(newAtom);
_symbolToAtomMapping.insert(std::make_pair(symbol, newAtom)); _symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));
} else { } else {
// This is actually a defined symbol. Add it to its section's list of // This is actually a defined symbol. Add it to its section's list of
// symbols. // symbols.
if (symbol->getType() == llvm::ELF::STT_NOTYPE if (symbol->getType() == llvm::ELF::STT_NOTYPE ||
|| symbol->getType() == llvm::ELF::STT_OBJECT symbol->getType() == llvm::ELF::STT_OBJECT ||
|| symbol->getType() == llvm::ELF::STT_FUNC symbol->getType() == llvm::ELF::STT_FUNC ||
|| symbol->getType() == llvm::ELF::STT_GNU_IFUNC symbol->getType() == llvm::ELF::STT_GNU_IFUNC ||
|| symbol->getType() == llvm::ELF::STT_SECTION symbol->getType() == llvm::ELF::STT_SECTION ||
|| symbol->getType() == llvm::ELF::STT_FILE symbol->getType() == llvm::ELF::STT_FILE ||
|| symbol->getType() == llvm::ELF::STT_TLS symbol->getType() == llvm::ELF::STT_TLS ||
|| symbol->getType() == llvm::ELF::STT_COMMON symbol->getType() == llvm::ELF::STT_COMMON ||
|| symbol->st_shndx == llvm::ELF::SHN_COMMON) { symbol->st_shndx == llvm::ELF::SHN_COMMON) {
sectionSymbols[section].push_back(symbol); sectionSymbols[section].push_back(symbol);
} else { } else {
llvm::errs() << "Unable to create atom for: " << symbolName << "\n"; llvm::errs() << "Unable to create atom for: " << symbolName << "\n";
@ -208,14 +204,13 @@ public:
uint64_t contentSize; uint64_t contentSize;
if (si + 1 == se) { if (si + 1 == se) {
// if this is the last symbol, take up the remaining data. // if this is the last symbol, take up the remaining data.
contentSize = (isCommon) ? 0 contentSize = isCommon ? 0
: ((i.first)->sh_size - (*si)->st_value); : i.first->sh_size - (*si)->st_value;
} else { } else {
contentSize = (isCommon) ? 0 contentSize = isCommon ? 0
: (*(si + 1))->st_value - (*si)->st_value; : (*(si + 1))->st_value - (*si)->st_value;
} }
// Don't allocate content to a weak symbol, as they may be merged away. // Don't allocate content to a weak symbol, as they may be merged away.
// Create an anonymous atom to hold the data. // Create an anonymous atom to hold the data.
ELFDefinedAtom<ELFT> *anonAtom = nullptr; ELFDefinedAtom<ELFT> *anonAtom = nullptr;
@ -225,17 +220,18 @@ public:
*sym = **si; *sym = **si;
sym->setBinding(llvm::ELF::STB_GLOBAL); sym->setBinding(llvm::ELF::STB_GLOBAL);
anonAtom = createDefinedAtomAndAssignRelocations( anonAtom = createDefinedAtomAndAssignRelocations(
"", sectionName, sym, i.first, "", sectionName, sym, i.first,
ArrayRef<uint8_t>( ArrayRef<uint8_t>((uint8_t *)sectionContents.data() +
(uint8_t *)sectionContents.data() + (*si)->st_value, contentSize)); (*si)->st_value, contentSize));
contentSize = 0; contentSize = 0;
} }
ArrayRef<uint8_t> symbolData = ArrayRef<uint8_t>( ArrayRef<uint8_t> symbolData = ArrayRef<uint8_t>(
(uint8_t *)sectionContents.data() + (*si)->st_value, contentSize); (uint8_t *)sectionContents.data() +
(*si)->st_value, contentSize);
auto newAtom = createDefinedAtomAndAssignRelocations( auto newAtom = createDefinedAtomAndAssignRelocations(
symbolName, sectionName, *si, i.first, symbolData); symbolName, sectionName, *si, i.first, symbolData);
_definedAtoms._atoms.push_back(newAtom); _definedAtoms._atoms.push_back(newAtom);
_symbolToAtomMapping.insert(std::make_pair((*si), newAtom)); _symbolToAtomMapping.insert(std::make_pair((*si), newAtom));
@ -273,12 +269,9 @@ public:
} }
private: private:
ELFDefinedAtom<ELFT> * ELFDefinedAtom<ELFT> *createDefinedAtomAndAssignRelocations(
createDefinedAtomAndAssignRelocations(StringRef symbolName, StringRef symbolName, StringRef sectionName, const Elf_Sym *symbol,
StringRef sectionName, const Elf_Shdr *section, ArrayRef<uint8_t> content) {
const Elf_Sym *symbol,
const Elf_Shdr *section,
ArrayRef<uint8_t> content) {
unsigned int referenceStart = _references.size(); unsigned int referenceStart = _references.size();
// Only relocations that are inside the domain of the atom are added. // Only relocations that are inside the domain of the atom are added.
@ -286,10 +279,11 @@ private:
// Add Rela (those with r_addend) references: // Add Rela (those with r_addend) references:
for (auto &rai : _relocationAddendRefences[sectionName]) { for (auto &rai : _relocationAddendRefences[sectionName]) {
if (!((rai->r_offset >= symbol->st_value) && if (!((rai->r_offset >= symbol->st_value) &&
(rai->r_offset < symbol->st_value + content.size()))) (rai->r_offset < symbol->st_value + content.size())))
continue; continue;
auto *ERef = new (_readerStorage.Allocate<ELFReference<ELFT>> ()) auto *ERef = new (_readerStorage.Allocate<ELFReference<ELFT>>())
ELFReference<ELFT>(rai, rai->r_offset - symbol->st_value, nullptr); ELFReference<ELFT>(rai, rai->r_offset - symbol->st_value,
nullptr);
_references.push_back(ERef); _references.push_back(ERef);
} }
@ -298,52 +292,47 @@ private:
if ((ri->r_offset >= symbol->st_value) && if ((ri->r_offset >= symbol->st_value) &&
(ri->r_offset < symbol->st_value + content.size())) { (ri->r_offset < symbol->st_value + content.size())) {
auto *ERef = new (_readerStorage.Allocate<ELFReference<ELFT>>()) auto *ERef = new (_readerStorage.Allocate<ELFReference<ELFT>>())
ELFReference<ELFT>(ri, ri->r_offset - symbol->st_value, nullptr); ELFReference<ELFT>(ri, ri->r_offset - symbol->st_value,
nullptr);
_references.push_back(ERef); _references.push_back(ERef);
} }
} }
// Create the DefinedAtom and add it to the list of DefinedAtoms. // Create the DefinedAtom and add it to the list of DefinedAtoms.
return new (_readerStorage.Allocate<ELFDefinedAtom<ELFT>>()) return new (_readerStorage.Allocate<ELFDefinedAtom<ELFT>>())
ELFDefinedAtom<ELFT>(*this, ELFDefinedAtom<ELFT>(*this, symbolName, sectionName, symbol, section,
symbolName, content, referenceStart, _references.size(),
sectionName, _references);
symbol,
section,
content,
referenceStart,
_references.size(),
_references);
} }
std::unique_ptr<ELFObjectFile<ELFT>> _objFile; std::unique_ptr<ELFObjectFile<ELFT>> _objFile;
atom_collection_vector<DefinedAtom> _definedAtoms; atom_collection_vector<DefinedAtom> _definedAtoms;
atom_collection_vector<UndefinedAtom> _undefinedAtoms; atom_collection_vector<UndefinedAtom> _undefinedAtoms;
atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms; atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
atom_collection_vector<AbsoluteAtom> _absoluteAtoms; atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
/// \brief _relocationAddendRefences and _relocationReferences contain the /// \brief _relocationAddendRefences and _relocationReferences contain the
/// list of relocations references. In ELF, if a section named, ".text" has /// list of relocations references. In ELF, if a section named, ".text" has
/// relocations will also have a section named ".rel.text" or ".rela.text" /// relocations will also have a section named ".rel.text" or ".rela.text"
/// which will hold the entries. -- .rel or .rela is prepended to create /// which will hold the entries. -- .rel or .rela is prepended to create
/// the SHT_REL(A) section name. /// the SHT_REL(A) section name.
std::map<llvm::StringRef, std::vector<const Elf_Rela *>> std::map<llvm::StringRef,
_relocationAddendRefences; std::vector<const Elf_Rela *>> _relocationAddendRefences;
std::map<llvm::StringRef, std::vector<const Elf_Rel *>> std::map<llvm::StringRef,
_relocationReferences; std::vector<const Elf_Rel *>> _relocationReferences;
std::vector<ELFReference<ELFT> *> _references; std::vector<ELFReference<ELFT> *> _references;
llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping; llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;
llvm::BumpPtrAllocator _readerStorage; llvm::BumpPtrAllocator _readerStorage;
}; };
// \brief A reader object that will instantiate correct FileELF by examining the /// \brief A reader object that will instantiate correct FileELF by examining the
// memory buffer for ELF class and bit width /// memory buffer for ELF class and bit width
class ReaderELF: public Reader { class ReaderELF : public Reader {
public: public:
ReaderELF(const ReaderOptionsELF &, ReaderELF(const ReaderOptionsELF &,
ReaderOptionsArchive &readerOptionsArchive) ReaderOptionsArchive &readerOptionsArchive)
: _readerOptionsArchive(readerOptionsArchive) : _readerOptionsArchive(readerOptionsArchive),
, _readerArchive(_readerOptionsArchive) { _readerArchive(_readerOptionsArchive) {
_readerOptionsArchive.setReader(this); _readerOptionsArchive.setReader(this);
} }
@ -351,11 +340,11 @@ public:
std::vector<std::unique_ptr<File>> &result) { std::vector<std::unique_ptr<File>> &result) {
using llvm::object::ELFType; using llvm::object::ELFType;
llvm::sys::LLVMFileType fileType = llvm::sys::LLVMFileType fileType =
llvm::sys::IdentifyFileType(mb->getBufferStart(), llvm::sys::IdentifyFileType(mb->getBufferStart(),
static_cast<unsigned>(mb->getBufferSize())); static_cast<unsigned>(mb->getBufferSize()));
std::size_t MaxAlignment = std::size_t MaxAlignment =
1ULL << llvm::CountTrailingZeros_64(uintptr_t(mb->getBufferStart())); 1ULL << llvm::CountTrailingZeros_64(uintptr_t(mb->getBufferStart()));
llvm::error_code ec; llvm::error_code ec;
switch (fileType) { switch (fileType) {
@ -365,44 +354,44 @@ public:
// Instantiate the correct FileELF template instance based on the Ident // Instantiate the correct FileELF template instance based on the Ident
// pair. Once the File is created we push the file to the vector of files // pair. Once the File is created we push the file to the vector of files
// already created during parser's life. // already created during parser's life.
if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second if (Ident.first == llvm::ELF::ELFCLASS32 &&
== llvm::ELF::ELFDATA2LSB) { Ident.second == llvm::ELF::ELFDATA2LSB) {
if (MaxAlignment >= 4) if (MaxAlignment >= 4)
f.reset(new FileELF<ELFType<llvm::support::little, 4, false>>( f.reset(new FileELF<ELFType<llvm::support::little, 4, false>>(
std::move(mb), ec)); std::move(mb), ec));
else if (MaxAlignment >= 2) else if (MaxAlignment >= 2)
f.reset(new FileELF<ELFType<llvm::support::little, 2, false>>( f.reset(new FileELF<ELFType<llvm::support::little, 2, false>>(
std::move(mb), ec)); std::move(mb), ec));
else else
llvm_unreachable("Invalid alignment for ELF file!"); llvm_unreachable("Invalid alignment for ELF file!");
} else if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second } else if (Ident.first == llvm::ELF::ELFCLASS32 &&
== llvm::ELF::ELFDATA2MSB) { Ident.second == llvm::ELF::ELFDATA2MSB) {
if (MaxAlignment >= 4) if (MaxAlignment >= 4)
f.reset(new FileELF<ELFType<llvm::support::big, 4, false>>( f.reset(new FileELF<ELFType<llvm::support::big, 4, false>>(
std::move(mb), ec)); std::move(mb), ec));
else if (MaxAlignment >= 2) else if (MaxAlignment >= 2)
f.reset(new FileELF<ELFType<llvm::support::big, 2, false>>( f.reset(new FileELF<ELFType<llvm::support::big, 2, false>>(
std::move(mb), ec)); std::move(mb), ec));
else else
llvm_unreachable("Invalid alignment for ELF file!"); llvm_unreachable("Invalid alignment for ELF file!");
} else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second } else if (Ident.first == llvm::ELF::ELFCLASS64 &&
== llvm::ELF::ELFDATA2MSB) { Ident.second == llvm::ELF::ELFDATA2MSB) {
if (MaxAlignment >= 8) if (MaxAlignment >= 8)
f.reset(new FileELF<ELFType<llvm::support::big, 8, true>>( f.reset(new FileELF<ELFType<llvm::support::big, 8, true>>(
std::move(mb), ec)); std::move(mb), ec));
else if (MaxAlignment >= 2) else if (MaxAlignment >= 2)
f.reset(new FileELF<ELFType<llvm::support::big, 2, true>>( f.reset(new FileELF<ELFType<llvm::support::big, 2, true>>(
std::move(mb), ec)); std::move(mb), ec));
else else
llvm_unreachable("Invalid alignment for ELF file!"); llvm_unreachable("Invalid alignment for ELF file!");
} else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second } else if (Ident.first == llvm::ELF::ELFCLASS64 &&
== llvm::ELF::ELFDATA2LSB) { Ident.second == llvm::ELF::ELFDATA2LSB) {
if (MaxAlignment >= 8) if (MaxAlignment >= 8)
f.reset(new FileELF<ELFType<llvm::support::little, 8, true>>( f.reset(new FileELF<ELFType<llvm::support::little, 8, true>>(
std::move(mb), ec)); std::move(mb), ec));
else if (MaxAlignment >= 2) else if (MaxAlignment >= 2)
f.reset(new FileELF<ELFType<llvm::support::little, 2, true>>( f.reset(new FileELF<ELFType<llvm::support::little, 2, true>>(
std::move(mb), ec)); std::move(mb), ec));
else else
llvm_unreachable("Invalid alignment for ELF file!"); llvm_unreachable("Invalid alignment for ELF file!");
} }
@ -431,11 +420,9 @@ private:
} // end anon namespace. } // end anon namespace.
namespace lld { namespace lld {
ReaderOptionsELF::ReaderOptionsELF() { ReaderOptionsELF::ReaderOptionsELF() {}
}
ReaderOptionsELF::~ReaderOptionsELF() { ReaderOptionsELF::~ReaderOptionsELF() {}
}
Reader *createReaderELF(const ReaderOptionsELF &options, Reader *createReaderELF(const ReaderOptionsELF &options,
ReaderOptionsArchive &optionsArchive) { ReaderOptionsArchive &optionsArchive) {