[lld] r200175 - [ELF] Add Target specific Readers.
Shankar Easwaran
shankare at codeaurora.org
Sun Jan 26 17:02:03 PST 2014
Author: shankare
Date: Sun Jan 26 19:02:03 2014
New Revision: 200175
URL: http://llvm.org/viewvc/llvm-project?rev=200175&view=rev
Log:
[ELF] Add Target specific Readers.
No change in functionality.
Added:
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h
- copied, changed from r200173, lld/trunk/lib/ReaderWriter/ELF/ELFReader.h
Modified:
lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
lld/trunk/include/lld/ReaderWriter/Reader.h
lld/trunk/lib/Driver/GnuLdDriver.cpp
lld/trunk/lib/ReaderWriter/ELF/Atoms.h
lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h
lld/trunk/lib/ReaderWriter/ELF/ELFFile.h
lld/trunk/lib/ReaderWriter/ELF/ELFReader.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h
lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/Reader.cpp
lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h
Modified: lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h Sun Jan 26 19:02:03 2014
@@ -14,6 +14,7 @@
#include "lld/Core/PassManager.h"
#include "lld/Core/Pass.h"
#include "lld/Core/range.h"
+#include "lld/Core/STDExtras.h"
#include "lld/ReaderWriter/Reader.h"
#include "lld/ReaderWriter/Writer.h"
@@ -37,6 +38,10 @@ class TargetHandlerBase {
public:
virtual ~TargetHandlerBase() {}
virtual void registerRelocationNames(Registry &) = 0;
+
+ virtual std::unique_ptr<Reader> getObjReader(bool) = 0;
+
+ virtual std::unique_ptr<Reader> getDSOReader(bool) = 0;
};
class ELFLinkingContext : public LinkingContext {
Modified: lld/trunk/include/lld/ReaderWriter/Reader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/Reader.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/Reader.h (original)
+++ lld/trunk/include/lld/ReaderWriter/Reader.h Sun Jan 26 19:02:03 2014
@@ -125,7 +125,8 @@ public:
void addSupportWindowsResourceFiles();
void addSupportMachOObjects(StringRef archName);
void addSupportELFObjects(bool atomizeStrings, TargetHandlerBase *handler);
- void addSupportELFDynamicSharedObjects(bool useShlibUndefines);
+ void addSupportELFDynamicSharedObjects(bool useShlibUndefines,
+ TargetHandlerBase *handler);
/// To convert between kind values and names, the registry walks the list
/// of registered kind tables. Each table is a zero terminated array of
Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Sun Jan 26 19:02:03 2014
@@ -119,7 +119,7 @@ bool GnuLdDriver::linkELF(int argc, cons
options->registry().addSupportNativeObjects();
if (options->allowLinkWithDynamicLibraries())
options->registry().addSupportELFDynamicSharedObjects(
- options->useShlibUndefines());
+ options->useShlibUndefines(), options->targetHandler());
return link(*options, diagnostics);
}
Modified: lld/trunk/lib/ReaderWriter/ELF/Atoms.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Atoms.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Atoms.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Atoms.h Sun Jan 26 19:02:03 2014
@@ -25,7 +25,6 @@ namespace lld {
namespace elf {
template <class ELFT> class DynamicFile;
template <typename ELFT> class ELFFile;
-template <typename ELFT> class TargetAtomHandler;
/// \brief Relocation References: Defined Atoms may contain references that will
/// need to be patched before the executable is written.
@@ -36,7 +35,7 @@ template <typename ELFT> class TargetAto
/// (not target atom) about a relocation, so we store the index to
/// ELFREference. In the second pass, ELFReferences are revisited to update
/// target atoms by target symbol indexes.
-template <class ELFT> class ELFReference LLVM_FINAL : public Reference {
+template <class ELFT> class ELFReference : public Reference {
typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
public:
@@ -88,8 +87,7 @@ private:
/// \brief These atoms store symbols that are fixed to a particular address.
/// This atom has no content its address will be used by the writer to fixup
/// references that point to it.
-template<class ELFT>
-class ELFAbsoluteAtom LLVM_FINAL : public AbsoluteAtom {
+template <class ELFT> class ELFAbsoluteAtom : public AbsoluteAtom {
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
public:
@@ -128,8 +126,7 @@ private:
/// \brief ELFUndefinedAtom: These atoms store undefined symbols and are place
/// holders that will be replaced by defined atoms later in the linking process.
-template<class ELFT>
-class ELFUndefinedAtom LLVM_FINAL : public lld::UndefinedAtom {
+template <class ELFT> class ELFUndefinedAtom : public lld::UndefinedAtom {
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
public:
@@ -158,8 +155,7 @@ private:
/// \brief This atom stores defined symbols and will contain either data or
/// code.
-template<class ELFT>
-class ELFDefinedAtom LLVM_FINAL : public DefinedAtom {
+template <class ELFT> class ELFDefinedAtom : public DefinedAtom {
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
@@ -172,8 +168,8 @@ public:
: _owningFile(file), _symbolName(symbolName), _sectionName(sectionName),
_symbol(symbol), _section(section), _contentData(contentData),
_referenceStartIndex(referenceStart), _referenceEndIndex(referenceEnd),
- _referenceList(referenceList), _targetAtomHandler(nullptr),
- _contentType(typeUnknown), _permissions(permUnknown) {}
+ _referenceList(referenceList), _contentType(typeUnknown),
+ _permissions(permUnknown) {}
~ELFDefinedAtom() {}
@@ -196,15 +192,6 @@ public:
virtual uint64_t size() const {
// Common symbols are not allocated in object files,
// so use st_size to tell how many bytes are required.
-
- // Treat target defined common symbols
- if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
- _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
- if (!_targetAtomHandler)
- _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
- if (_targetAtomHandler->getType(_symbol) == llvm::ELF::STT_COMMON)
- return (uint64_t) _symbol->st_size;
- }
if ((_symbol->getType() == llvm::ELF::STT_COMMON) ||
_symbol->st_shndx == llvm::ELF::SHN_COMMON)
return (uint64_t) _symbol->st_size;
@@ -231,17 +218,6 @@ public:
if (_symbol->getBinding() == llvm::ELF::STB_WEAK)
return mergeAsWeak;
- // If the symbol is a target defined and if the target
- // defines the symbol as a common symbol treat it as
- // mergeTentative
- if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
- _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
- if (!_targetAtomHandler)
- _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
- if (_targetAtomHandler->getType(_symbol) == llvm::ELF::STT_COMMON)
- return mergeAsTentative;
- }
-
if ((_symbol->getType() == llvm::ELF::STT_COMMON) ||
_symbol->st_shndx == llvm::ELF::SHN_COMMON)
return mergeAsTentative;
@@ -256,15 +232,6 @@ public:
ContentType ret = typeUnknown;
uint64_t flags = _section->sh_flags;
- // Treat target defined symbols
- if ((_section->sh_flags & llvm::ELF::SHF_MASKPROC) ||
- ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
- _symbol->st_shndx < llvm::ELF::SHN_HIPROC))) {
- if (!_targetAtomHandler)
- _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
- return _contentType = _targetAtomHandler->contentType(this);
- }
-
if (!(flags & llvm::ELF::SHF_ALLOC))
return _contentType = typeNoAlloc;
@@ -337,16 +304,6 @@ public:
virtual Alignment alignment() const {
// Unallocated common symbols specify their alignment constraints in
// st_value.
-
- // Treat target defined common symbols
- if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
- _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
- if (!_targetAtomHandler)
- _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
- if (_targetAtomHandler->getType(_symbol) == llvm::ELF::STT_COMMON)
- return Alignment(llvm::Log2_64(_symbol->st_value));
- }
-
if ((_symbol->getType() == llvm::ELF::STT_COMMON) ||
_symbol->st_shndx == llvm::ELF::SHN_COMMON) {
return Alignment(llvm::Log2_64(_symbol->st_value));
@@ -396,13 +353,6 @@ public:
return _permissions;
uint64_t flags = _section->sh_flags;
- // Treat target defined symbols
- if ((_symbol->st_shndx > llvm::ELF::SHN_LOPROC &&
- _symbol->st_shndx < llvm::ELF::SHN_HIPROC)) {
- if (!_targetAtomHandler)
- _targetAtomHandler = &_owningFile.targetHandler()->targetAtomHandler();
- return _permissions = _targetAtomHandler->contentPermissions(this);
- }
if (!(flags & llvm::ELF::SHF_ALLOC))
return _permissions = perm___;
@@ -492,7 +442,7 @@ public:
virtual void setOrdinal(uint64_t ord) { _ordinal = ord; }
-private:
+protected:
const ELFFile<ELFT> &_owningFile;
StringRef _symbolName;
StringRef _sectionName;
@@ -505,14 +455,12 @@ private:
unsigned int _referenceStartIndex;
unsigned int _referenceEndIndex;
std::vector<ELFReference<ELFT> *> &_referenceList;
- // Cached size of the TLS segment.
- mutable TargetAtomHandler<ELFT> *_targetAtomHandler;
mutable ContentType _contentType;
mutable ContentPermissions _permissions;
};
/// \brief This atom stores mergeable Strings
-template <class ELFT> class ELFMergeAtom LLVM_FINAL : public DefinedAtom {
+template <class ELFT> class ELFMergeAtom : public DefinedAtom {
typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
public:
@@ -596,8 +544,7 @@ private:
uint64_t _offset;
};
-template <class ELFT>
-class ELFCommonAtom LLVM_FINAL : public DefinedAtom {
+template <class ELFT> class ELFCommonAtom : public DefinedAtom {
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
public:
ELFCommonAtom(const ELFFile<ELFT> &file,
@@ -643,10 +590,6 @@ public:
}
virtual ContentType contentType() const {
- if (_symbol->st_shndx >= llvm::ELF::SHN_LORESERVE &&
- _symbol->st_shndx <= llvm::ELF::SHN_HIOS)
- return _owningFile.targetHandler()->targetAtomHandler().contentType(
- nullptr, _symbol);
return typeZeroFill;
}
@@ -703,7 +646,6 @@ protected:
virtual void incrementIterator(const void *&iter) const {}
-private:
const ELFFile<ELFT> &_owningFile;
StringRef _symbolName;
const Elf_Sym *_symbol;
@@ -711,8 +653,7 @@ private:
};
/// \brief An atom from a shared library.
-template <class ELFT>
-class ELFDynamicAtom LLVM_FINAL : public SharedLibraryAtom {
+template <class ELFT> class ELFDynamicAtom : public SharedLibraryAtom {
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
public:
Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultTargetHandler.h Sun Jan 26 19:02:03 2014
@@ -12,6 +12,7 @@
#include "DefaultLayout.h"
#include "TargetHandler.h"
+#include "ELFReader.h"
#include "lld/ReaderWriter/ELFLinkingContext.h"
@@ -32,11 +33,6 @@ public:
llvm_unreachable("Target should provide implementation for function ");
}
- /// TargetAtomHandler
- TargetAtomHandler<ELFT> &targetAtomHandler() {
- llvm_unreachable("Target should provide implementation for function ");
- }
-
const TargetRelocationHandler<ELFT> &getRelocationHandler() const {
llvm_unreachable("Target should provide implementation for function ");
}
@@ -74,7 +70,15 @@ public:
DefaultLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS));
}
-private:
+ virtual std::unique_ptr<Reader> getObjReader(bool atomizeStrings) {
+ return std::unique_ptr<Reader>(new ELFObjectReader(atomizeStrings));
+ }
+
+ virtual std::unique_ptr<Reader> getDSOReader(bool useShlibUndefines) {
+ return std::unique_ptr<Reader>(new ELFDSOReader(useShlibUndefines));
+ }
+
+protected:
llvm::BumpPtrAllocator _alloc;
};
} // end namespace elf
Modified: lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DynamicFile.h Sun Jan 26 19:02:03 2014
@@ -22,7 +22,7 @@
namespace lld {
namespace elf {
-template <class ELFT> class DynamicFile LLVM_FINAL : public SharedLibraryFile {
+template <class ELFT> class DynamicFile : public SharedLibraryFile {
public:
static ErrorOr<std::unique_ptr<DynamicFile>>
create(std::unique_ptr<llvm::MemoryBuffer> mb, bool useShlibUndefines);
Modified: lld/trunk/lib/ReaderWriter/ELF/ELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFFile.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFFile.h Sun Jan 26 19:02:03 2014
@@ -118,12 +118,10 @@ template <class ELFT> class ELFFile : pu
public:
ELFFile(StringRef name, bool atomizeStrings = false)
- : File(name, kindObject), _ordinal(0), _doStringsMerge(atomizeStrings),
- _targetHandler(nullptr) {}
+ : File(name, kindObject), _ordinal(0), _doStringsMerge(atomizeStrings) {}
static ErrorOr<std::unique_ptr<ELFFile>>
- create(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings,
- TargetHandlerBase *handler);
+ create(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings);
virtual Reference::KindArch kindArch();
@@ -159,8 +157,6 @@ public:
return _absoluteAtoms;
}
- TargetHandler<ELFT> *targetHandler() const { return _targetHandler; }
-
Atom *findAtom(const Elf_Sym *symbol) {
return _symbolToAtomMapping.lookup(symbol);
}
@@ -195,12 +191,8 @@ protected:
StringRef sectionName,
StringRef sectionContents);
- /// Returns true if the symbol is common symbol. A common symbol represents a
- /// tentive definition in C. It has name, size and alignment constraint, but
- /// actual storage has not yet been allocated. (The linker will allocate
- /// storage for them in the later pass after coalescing tentative symbols by
- /// name.)
- virtual bool isCommonSymbol(const Elf_Sym *symbol);
+ /// Return the default reloc addend for references.
+ virtual int64_t defaultRelocAddend(const Reference &) const;
/// Returns the symbol's content size. The nextSymbol should be null if the
/// symbol is the last one in the section.
@@ -211,8 +203,113 @@ protected:
virtual void createEdge(ELFDefinedAtom<ELFT> *from, ELFDefinedAtom<ELFT> *to,
uint32_t edgeKind);
- virtual void setTargetHandler(TargetHandlerBase *handler) {
- _targetHandler = reinterpret_cast<TargetHandler<ELFT> *>(handler);
+ /// Determines if the reader needs to create atoms for the section.
+ virtual bool ignoreCreateAtomsForSection(const Elf_Shdr *shdr) {
+ return false;
+ }
+
+ /// Get the section name for a section.
+ virtual ErrorOr<StringRef> getSectionName(const Elf_Shdr *shdr) const {
+ if (!shdr)
+ return StringRef();
+ return _objFile->getSectionName(shdr);
+ }
+
+ /// Determines if the section occupy memory space.
+ virtual bool sectionOccupiesMemorySpace(const Elf_Shdr *shdr) const {
+ return (shdr->sh_type != llvm::ELF::SHT_NOBITS);
+ }
+
+ /// Return the section contents.
+ virtual ErrorOr<ArrayRef<uint8_t>>
+ getSectionContents(const Elf_Shdr *shdr) const {
+ if (!shdr || !sectionOccupiesMemorySpace(shdr))
+ return ArrayRef<uint8_t>();
+ return _objFile->getSectionContents(shdr);
+ }
+
+ /// Returns true if the symbol is a undefined symbol.
+ virtual bool isUndefinedSymbol(const Elf_Sym *sym) const {
+ return (sym->st_shndx == llvm::ELF::SHN_UNDEF);
+ }
+
+ /// Determines if the target wants to create an atom for a section that has no
+ /// symbol references.
+ virtual bool
+ handleSectionWithNoSymbols(const Elf_Shdr *shdr,
+ std::vector<Elf_Sym_Iter> &symbols) const {
+ if (shdr && shdr->sh_type == llvm::ELF::SHT_PROGBITS && symbols.empty())
+ return true;
+ return false;
+ }
+
+ /// Process the Undefined symbol and create an atom for it.
+ virtual ErrorOr<ELFUndefinedAtom<ELFT> *>
+ handleUndefinedSymbol(StringRef symName, const Elf_Sym *sym) {
+ return new (_readerStorage) ELFUndefinedAtom<ELFT>(*this, symName, sym);
+ }
+
+ /// Returns true if the symbol is a absolute symbol.
+ virtual bool isAbsoluteSymbol(const Elf_Sym *sym) const {
+ return (sym->st_shndx == llvm::ELF::SHN_ABS);
+ }
+
+ /// Process the Absolute symbol and create an atom for it.
+ virtual ErrorOr<ELFAbsoluteAtom<ELFT> *>
+ handleAbsoluteSymbol(StringRef symName, const Elf_Sym *sym, int64_t value) {
+ return new (_readerStorage)
+ ELFAbsoluteAtom<ELFT>(*this, symName, sym, value);
+ }
+
+ /// Returns true if the symbol is common symbol. A common symbol represents a
+ /// tentive definition in C. It has name, size and alignment constraint, but
+ /// actual storage has not yet been allocated. (The linker will allocate
+ /// storage for them in the later pass after coalescing tentative symbols by
+ /// name.)
+ virtual bool isCommonSymbol(const Elf_Sym *symbol) const {
+ return symbol->getType() == llvm::ELF::STT_COMMON ||
+ symbol->st_shndx == llvm::ELF::SHN_COMMON;
+ }
+
+ /// Process the common symbol and create an atom for it.
+ virtual ErrorOr<ELFCommonAtom<ELFT> *>
+ handleCommonSymbol(StringRef symName, const Elf_Sym *sym) {
+ return new (_readerStorage) ELFCommonAtom<ELFT>(*this, symName, sym);
+ }
+
+ /// Returns true if the symbol is a defined symbol.
+ virtual bool isDefinedSymbol(const Elf_Sym *sym) const {
+ return (sym->getType() == llvm::ELF::STT_NOTYPE ||
+ sym->getType() == llvm::ELF::STT_OBJECT ||
+ sym->getType() == llvm::ELF::STT_FUNC ||
+ sym->getType() == llvm::ELF::STT_GNU_IFUNC ||
+ sym->getType() == llvm::ELF::STT_SECTION ||
+ sym->getType() == llvm::ELF::STT_FILE ||
+ sym->getType() == llvm::ELF::STT_TLS);
+ }
+
+ /// Process the Defined symbol and create an atom for it.
+ virtual ErrorOr<ELFDefinedAtom<ELFT> *>
+ handleDefinedSymbol(StringRef symName, StringRef sectionName,
+ const Elf_Sym *sym, const Elf_Shdr *sectionHdr,
+ ArrayRef<uint8_t> contentData,
+ unsigned int referenceStart, unsigned int referenceEnd,
+ std::vector<ELFReference<ELFT> *> &referenceList) {
+ return new (_readerStorage) ELFDefinedAtom<ELFT>(
+ *this, symName, sectionName, sym, sectionHdr, contentData,
+ referenceStart, referenceEnd, referenceList);
+ }
+
+ /// Process the Merge string and create an atom for it.
+ virtual ErrorOr<ELFMergeAtom<ELFT> *>
+ handleMergeString(StringRef sectionName, const Elf_Shdr *sectionHdr,
+ ArrayRef<uint8_t> contentData, unsigned int offset) {
+ ELFMergeAtom<ELFT> *mergeAtom = new (_readerStorage)
+ ELFMergeAtom<ELFT>(*this, sectionName, sectionHdr, contentData, offset);
+ const MergeSectionKey mergedSectionKey(sectionHdr, offset);
+ if (_mergedSectionMap.find(mergedSectionKey) == _mergedSectionMap.end())
+ _mergedSectionMap.insert(std::make_pair(mergedSectionKey, mergeAtom));
+ return mergeAtom;
}
llvm::BumpPtrAllocator _readerStorage;
@@ -225,8 +322,7 @@ protected:
/// \brief _relocationAddendReferences and _relocationReferences contain the
/// list of relocations references. In ELF, if a section named, ".text" has
/// relocations will also have a section named ".rel.text" or ".rela.text"
- /// which will hold the entries. -- .rel or .rela is prepended to create
- /// the SHT_REL(A) section name.
+ /// which will hold the entries.
std::unordered_map<
StringRef,
range<typename llvm::object::ELFFile<ELFT>::Elf_Rela_Iter> >
@@ -254,7 +350,6 @@ protected:
/// \brief the cached options relevant while reading the ELF File
bool _doStringsMerge;
- TargetHandler<ELFT> *_targetHandler;
};
/// \brief All atoms are owned by a File. To add linker specific atoms
@@ -271,53 +366,45 @@ public:
/// \brief add a global absolute atom
virtual Atom *addAbsoluteAtom(StringRef symbolName) {
assert(!symbolName.empty() && "AbsoluteAtoms must have a name");
- Elf_Sym *symbol = new (_allocator) Elf_Sym;
+ Elf_Sym *symbol = new (this->_readerStorage) Elf_Sym;
symbol->st_name = 0;
symbol->st_value = 0;
symbol->st_shndx = llvm::ELF::SHN_ABS;
symbol->setBindingAndType(llvm::ELF::STB_GLOBAL, llvm::ELF::STT_OBJECT);
symbol->st_other = llvm::ELF::STV_DEFAULT;
symbol->st_size = 0;
- auto *newAtom =
- new (_allocator) ELFAbsoluteAtom<ELFT>(*this, symbolName, symbol, -1);
- this->_absoluteAtoms._atoms.push_back(newAtom);
- return newAtom;
+ auto newAtom = this->handleAbsoluteSymbol(symbolName, symbol, -1);
+ this->_absoluteAtoms._atoms.push_back(*newAtom);
+ return *newAtom;
}
/// \brief add an undefined atom
virtual Atom *addUndefinedAtom(StringRef symbolName) {
assert(!symbolName.empty() && "UndefinedAtoms must have a name");
- Elf_Sym *symbol = new (_allocator) Elf_Sym;
+ Elf_Sym *symbol = new (this->_readerStorage) Elf_Sym;
symbol->st_name = 0;
symbol->st_value = 0;
symbol->st_shndx = llvm::ELF::SHN_UNDEF;
symbol->st_other = llvm::ELF::STV_DEFAULT;
symbol->st_size = 0;
- auto *newAtom =
- new (_allocator) ELFUndefinedAtom<ELFT>(*this, symbolName, symbol);
- this->_undefinedAtoms._atoms.push_back(newAtom);
- return newAtom;
+ auto newAtom = this->handleUndefinedSymbol(symbolName, symbol);
+ this->_undefinedAtoms._atoms.push_back(*newAtom);
+ return *newAtom;
}
// cannot add atoms to C Runtime file
virtual void addAtom(const Atom &) {
llvm_unreachable("cannot add atoms to Runtime files");
}
-
-protected:
- llvm::BumpPtrAllocator _allocator;
};
template <class ELFT>
ErrorOr<std::unique_ptr<ELFFile<ELFT>>>
-ELFFile<ELFT>::create(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings,
- TargetHandlerBase *handler) {
+ELFFile<ELFT>::create(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings) {
error_code ec;
std::unique_ptr<ELFFile<ELFT>> file(
new ELFFile<ELFT>(mb->getBufferIdentifier(), atomizeStrings));
- file->setTargetHandler(handler);
-
file->_objFile.reset(new llvm::object::ELFFile<ELFT>(mb.release(), ec));
if (ec)
@@ -426,11 +513,11 @@ template <class ELFT> error_code ELFFile
// b) Create a separate section chunk to write mergeable atoms
std::vector<MergeString *> tokens;
for (const Elf_Shdr *msi : _mergeStringSections) {
- auto sectionName = _objFile->getSectionName(msi);
+ auto sectionName = getSectionName(msi);
if (error_code ec = sectionName.getError())
return ec;
- auto sectionContents = _objFile->getSectionContents(msi);
+ auto sectionContents = getSectionContents(msi);
if (error_code ec = sectionContents.getError())
return ec;
@@ -451,14 +538,11 @@ template <class ELFT> error_code ELFFile
for (const MergeString *tai : tokens) {
ArrayRef<uint8_t> content((const uint8_t *)tai->_string.data(),
tai->_string.size());
- ELFMergeAtom<ELFT> *mergeAtom = new (_readerStorage) ELFMergeAtom<ELFT>(
- *this, tai->_sectionName, tai->_shdr, content, tai->_offset);
- const MergeSectionKey mergedSectionKey(tai->_shdr, tai->_offset);
- if (_mergedSectionMap.find(mergedSectionKey) == _mergedSectionMap.end())
- _mergedSectionMap.insert(std::make_pair(mergedSectionKey, mergeAtom));
- mergeAtom->setOrdinal(++_ordinal);
- _definedAtoms._atoms.push_back(mergeAtom);
- _mergeAtoms.push_back(mergeAtom);
+ ErrorOr<ELFMergeAtom<ELFT> *> mergeAtom =
+ handleMergeString(tai->_sectionName, tai->_shdr, content, tai->_offset);
+ (*mergeAtom)->setOrdinal(++_ordinal);
+ _definedAtoms._atoms.push_back(*mergeAtom);
+ _mergeAtoms.push_back(*mergeAtom);
}
return error_code::success();
}
@@ -480,50 +564,41 @@ error_code ELFFile<ELFT>::createSymbolsF
if (error_code ec = symbolName.getError())
return ec;
- if (SymI->st_shndx == llvm::ELF::SHN_ABS) {
- // Create an absolute atom.
- auto *newAtom = new (_readerStorage)
- ELFAbsoluteAtom<ELFT>(*this, *symbolName, &*SymI, SymI->st_value);
-
- _absoluteAtoms._atoms.push_back(newAtom);
- _symbolToAtomMapping.insert(std::make_pair(&*SymI, newAtom));
- } else if (SymI->st_shndx == llvm::ELF::SHN_UNDEF) {
- // Create an undefined atom.
- auto *newAtom = new (_readerStorage)
- ELFUndefinedAtom<ELFT>(*this, *symbolName, &*SymI);
-
- _undefinedAtoms._atoms.push_back(newAtom);
- _symbolToAtomMapping.insert(std::make_pair(&*SymI, newAtom));
+ if (isAbsoluteSymbol(&*SymI)) {
+ ErrorOr<ELFAbsoluteAtom<ELFT> *> absAtom =
+ handleAbsoluteSymbol(*symbolName, &*SymI, SymI->st_value);
+ _absoluteAtoms._atoms.push_back(*absAtom);
+ _symbolToAtomMapping.insert(std::make_pair(&*SymI, *absAtom));
+ } else if (isUndefinedSymbol(&*SymI)) {
+ ErrorOr<ELFUndefinedAtom<ELFT> *> undefAtom =
+ handleUndefinedSymbol(*symbolName, &*SymI);
+ _undefinedAtoms._atoms.push_back(*undefAtom);
+ _symbolToAtomMapping.insert(std::make_pair(&*SymI, *undefAtom));
} else if (isCommonSymbol(&*SymI)) {
- auto *newAtom =
- new (_readerStorage) ELFCommonAtom<ELFT>(*this, *symbolName, &*SymI);
- newAtom->setOrdinal(++_ordinal);
- _definedAtoms._atoms.push_back(newAtom);
- _symbolToAtomMapping.insert(std::make_pair(&*SymI, newAtom));
+ ErrorOr<ELFCommonAtom<ELFT> *> commonAtom =
+ handleCommonSymbol(*symbolName, &*SymI);
+ (*commonAtom)->setOrdinal(++_ordinal);
+ _definedAtoms._atoms.push_back(*commonAtom);
+ _symbolToAtomMapping.insert(std::make_pair(&*SymI, *commonAtom));
+ } else if (isDefinedSymbol(&*SymI)) {
+ _sectionSymbols[section].push_back(SymI);
} else {
- assert(section && "Symbol not defined in a section!");
- // This is actually a defined symbol. Add it to its section's list of
- // symbols.
- if (SymI->getType() == llvm::ELF::STT_NOTYPE ||
- SymI->getType() == llvm::ELF::STT_OBJECT ||
- SymI->getType() == llvm::ELF::STT_FUNC ||
- SymI->getType() == llvm::ELF::STT_GNU_IFUNC ||
- SymI->getType() == llvm::ELF::STT_SECTION ||
- SymI->getType() == llvm::ELF::STT_FILE ||
- SymI->getType() == llvm::ELF::STT_TLS) {
- _sectionSymbols[section].push_back(SymI);
- } else {
- llvm::errs() << "Unable to create atom for: " << *symbolName << "\n";
- return llvm::object::object_error::parse_failed;
- }
+ llvm::errs() << "Unable to create atom for: " << *symbolName << "\n";
+ return llvm::object::object_error::parse_failed;
}
}
+
return error_code::success();
}
template <class ELFT> error_code ELFFile<ELFT>::createAtoms() {
for (auto &i : _sectionSymbols) {
const Elf_Shdr *section = i.first;
+
+ // Check if need to create atoms for this section ?
+ if ((ignoreCreateAtomsForSection(section)))
+ continue;
+
std::vector<Elf_Sym_Iter> &symbols = i.second;
// Sort symbols by position.
@@ -531,25 +606,18 @@ template <class ELFT> error_code ELFFile
[](Elf_Sym_Iter A,
Elf_Sym_Iter B) { return A->st_value < B->st_value; });
- auto sectionName =
- section ? _objFile->getSectionName(section) : StringRef();
+ ErrorOr<StringRef> sectionName = this->getSectionName(section);
if (error_code ec = sectionName.getError())
return ec;
- auto sectionContents =
- (section && section->sh_type != llvm::ELF::SHT_NOBITS)
- ? _objFile->getSectionContents(section)
- : ArrayRef<uint8_t>();
-
+ auto sectionContents = getSectionContents(section);
if (error_code ec = sectionContents.getError())
return ec;
StringRef secCont(reinterpret_cast<const char *>(sectionContents->begin()),
sectionContents->size());
- // If the section has no symbols, create a custom atom for it.
- if (section && section->sh_type == llvm::ELF::SHT_PROGBITS &&
- symbols.empty()) {
+ if (handleSectionWithNoSymbols(section, symbols)) {
ELFDefinedAtom<ELFT> *newAtom =
createSectionAtom(section, *sectionName, secCont);
_definedAtoms._atoms.push_back(newAtom);
@@ -597,11 +665,11 @@ template <class ELFT> error_code ELFFile
// resolution
if (isMergeableStringSection(section)) {
if (symbol->getBinding() == llvm::ELF::STB_GLOBAL) {
- auto definedMergeAtom = new (_readerStorage) ELFDefinedAtom<ELFT>(
- *this, symbolName, *sectionName, &**si, section, symbolData,
+ auto definedMergeAtom = handleDefinedSymbol(
+ symbolName, *sectionName, &**si, section, symbolData,
_references.size(), _references.size(), _references);
- _definedAtoms._atoms.push_back(definedMergeAtom);
- definedMergeAtom->setOrdinal(++_ordinal);
+ _definedAtoms._atoms.push_back(*definedMergeAtom);
+ (*definedMergeAtom)->setOrdinal(++_ordinal);
}
continue;
}
@@ -711,17 +779,16 @@ ELFDefinedAtom<ELFT> *ELFFile<ELFT>::cre
}
// Create the DefinedAtom and add it to the list of DefinedAtoms.
- return new (_readerStorage) ELFDefinedAtom<ELFT>(
- *this, symbolName, sectionName, symbol, section, content, referenceStart,
- _references.size(), _references);
+ return *handleDefinedSymbol(symbolName, sectionName, symbol, section, content,
+ referenceStart, _references.size(), _references);
}
-template <class ELFT> void ELFFile<ELFT>::updateReferences() {
- /// cached value of target relocation handler
- assert(_targetHandler);
- const TargetRelocationHandler<ELFT> &targetRelocationHandler =
- _targetHandler->getRelocationHandler();
+template <class ELFT>
+int64_t ELFFile<ELFT>::defaultRelocAddend(const Reference &) const {
+ return 0;
+}
+template <class ELFT> void ELFFile<ELFT>::updateReferences() {
for (auto &ri : _references) {
if (ri->kindNamespace() == lld::Reference::KindNamespace::ELF) {
const Elf_Sym *symbol = _objFile->getSymbol(ri->targetSymbolIndex());
@@ -737,8 +804,7 @@ template <class ELFT> void ELFFile<ELFT>
// If the target atom is mergeable string atom, the atom might have been
// merged with other atom having the same contents. Try to find the
// merged one if that's the case.
- int64_t relocAddend = targetRelocationHandler.relocAddend(*ri);
- uint64_t addend = ri->addend() + relocAddend;
+ uint64_t addend = ri->addend() + defaultRelocAddend(*ri);
const MergeSectionKey ms(shdr, addend);
auto msec = _mergedSectionMap.find(ms);
if (msec != _mergedSectionMap.end()) {
@@ -816,20 +882,6 @@ ELFFile<ELFT>::createSectionAtom(const E
}
template <class ELFT>
-bool ELFFile<ELFT>::isCommonSymbol(const Elf_Sym *symbol) {
- // This method handles only architecture independent stuffs, and don't know
- // whether an architecture dependent section is for common symbols or
- // not. Let the TargetHandler to make a decision if that's the case.
- if (isTargetSpecificAtom(nullptr, symbol)) {
- assert(_targetHandler);
- TargetAtomHandler<ELFT> &atomHandler = _targetHandler->targetAtomHandler();
- return atomHandler.getType(symbol) == llvm::ELF::STT_COMMON;
- }
- return symbol->getType() == llvm::ELF::STT_COMMON ||
- symbol->st_shndx == llvm::ELF::SHN_COMMON;
-}
-
-template <class ELFT>
uint64_t ELFFile<ELFT>::symbolContentSize(const Elf_Shdr *section,
const Elf_Sym *symbol,
const Elf_Sym *nextSymbol) {
Modified: lld/trunk/lib/ReaderWriter/ELF/ELFReader.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFReader.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFReader.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFReader.h Sun Jan 26 19:02:03 2014
@@ -34,16 +34,14 @@ struct ELFFileCreateELFTraits {
template <class ELFT>
static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
- bool atomizeStrings, TargetHandlerBase *handler) {
- return lld::elf::ELFFile<ELFT>::create(std::move(mb), atomizeStrings,
- handler);
+ bool atomizeStrings) {
+ return lld::elf::ELFFile<ELFT>::create(std::move(mb), atomizeStrings);
}
};
class ELFObjectReader : public Reader {
public:
- ELFObjectReader(bool atomizeStrings, TargetHandlerBase *handler)
- : _atomizeStrings(atomizeStrings), _handler(handler) {}
+ ELFObjectReader(bool atomizeStrings) : _atomizeStrings(atomizeStrings) {}
virtual bool canParse(file_magic magic, StringRef,
const MemoryBuffer &) const {
@@ -57,16 +55,15 @@ public:
1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
auto f = createELF<ELFFileCreateELFTraits>(
llvm::object::getElfArchType(&*mb), maxAlignment, std::move(mb),
- _atomizeStrings, _handler);
+ _atomizeStrings);
if (error_code ec = f.getError())
return ec;
result.push_back(std::move(*f));
return error_code::success();
}
-private:
+protected:
bool _atomizeStrings;
- TargetHandlerBase *_handler;
};
class ELFDSOReader : public Reader {
@@ -92,7 +89,7 @@ public:
return error_code::success();
}
-private:
+protected:
bool _useUndefines;
};
Added: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h?rev=200175&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFFile.h Sun Jan 26 19:02:03 2014
@@ -0,0 +1,203 @@
+//===- lib/ReaderWriter/ELF/HexagonELFFile.h
+//-------------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H
+#define LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H
+
+#include "ELFReader.h"
+#include "HexagonLinkingContext.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT> class HexagonELFFile;
+
+template <class ELFT>
+class HexagonELFDefinedAtom : public ELFDefinedAtom<ELFT> {
+ typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
+ typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
+
+public:
+ HexagonELFDefinedAtom(const HexagonELFFile<ELFT> &file, StringRef symbolName,
+ StringRef sectionName, const Elf_Sym *symbol,
+ const Elf_Shdr *section, ArrayRef<uint8_t> contentData,
+ unsigned int referenceStart, unsigned int referenceEnd,
+ std::vector<ELFReference<ELFT> *> &referenceList)
+ : ELFDefinedAtom<ELFT>(file, symbolName, sectionName, symbol, section,
+ contentData, referenceStart, referenceEnd,
+ referenceList) {}
+
+ virtual DefinedAtom::ContentType contentType() const {
+ if (this->_contentType != DefinedAtom::typeUnknown)
+ return this->_contentType;
+ else if (this->_section->sh_flags & llvm::ELF::SHF_HEX_GPREL) {
+ if (this->_section->sh_type == llvm::ELF::SHT_NOBITS)
+ return (this->_contentType = DefinedAtom::typeZeroFillFast);
+ else
+ return (this->_contentType = DefinedAtom::typeDataFast);
+ }
+ return ELFDefinedAtom<ELFT>::contentType();
+ }
+
+ virtual DefinedAtom::ContentPermissions permissions() const {
+ if (this->_section->sh_flags & llvm::ELF::SHF_HEX_GPREL)
+ return DefinedAtom::permRW_;
+ return ELFDefinedAtom<ELFT>::permissions();
+ }
+};
+
+template <class ELFT> class HexagonELFCommonAtom : public ELFCommonAtom<ELFT> {
+ typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
+ typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
+
+public:
+ HexagonELFCommonAtom(const HexagonELFFile<ELFT> &file, StringRef symbolName,
+ const Elf_Sym *symbol)
+ : ELFCommonAtom<ELFT>(file, symbolName, symbol) {}
+
+ virtual bool isSmallCommonSymbol() const {
+ switch (this->_symbol->st_shndx) {
+ // Common symbols
+ case llvm::ELF::SHN_HEXAGON_SCOMMON:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_1:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_2:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_4:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_8:
+ return true;
+ default:
+ break;
+ }
+ return false;
+ }
+
+ virtual uint64_t size() const {
+ if (isSmallCommonSymbol())
+ return this->_symbol->st_size;
+ return ELFCommonAtom<ELFT>::size();
+ }
+
+ virtual DefinedAtom::Merge merge() const {
+ if (this->_symbol->getBinding() == llvm::ELF::STB_WEAK)
+ return DefinedAtom::mergeAsWeak;
+ if (isSmallCommonSymbol())
+ return DefinedAtom::mergeAsTentative;
+ return ELFCommonAtom<ELFT>::merge();
+ }
+
+ virtual DefinedAtom::ContentType contentType() const {
+ if (isSmallCommonSymbol())
+ return DefinedAtom::typeZeroFillFast;
+ return ELFCommonAtom<ELFT>::contentType();
+ }
+
+ virtual DefinedAtom::Alignment alignment() const {
+ if (isSmallCommonSymbol())
+ return DefinedAtom::Alignment(llvm::Log2_64(this->_symbol->st_value));
+ return ELFCommonAtom<ELFT>::alignment();
+ }
+
+ virtual DefinedAtom::ContentPermissions permissions() const {
+ if (isSmallCommonSymbol())
+ return DefinedAtom::permRW_;
+ return ELFCommonAtom<ELFT>::permissions();
+ }
+};
+
+template <class ELFT> class HexagonELFFile : public ELFFile<ELFT> {
+ typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
+ typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
+
+public:
+ HexagonELFFile(StringRef name, bool atomizeStrings)
+ : ELFFile<ELFT>(name, atomizeStrings) {}
+
+ HexagonELFFile(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings,
+ error_code &ec)
+ : ELFFile<ELFT>(std::move(mb), atomizeStrings, ec) {}
+
+ static ErrorOr<std::unique_ptr<HexagonELFFile>>
+ create(std::unique_ptr<MemoryBuffer> mb, bool atomizeStrings) {
+ error_code ec;
+ std::unique_ptr<HexagonELFFile<ELFT>> file(
+ new HexagonELFFile<ELFT>(mb->getBufferIdentifier(), atomizeStrings));
+
+ file->_objFile.reset(new llvm::object::ELFFile<ELFT>(mb.release(), ec));
+
+ if (ec)
+ return ec;
+
+ // Read input sections from the input file that need to be converted to
+ // atoms
+ if ((ec = file->createAtomizableSections()))
+ return ec;
+
+ // For mergeable strings, we would need to split the section into various
+ // atoms
+ if ((ec = file->createMergeableAtoms()))
+ return ec;
+
+ // Create the necessary symbols that are part of the section that we
+ // created in createAtomizableSections function
+ if ((ec = file->createSymbolsFromAtomizableSections()))
+ return ec;
+
+ // Create the appropriate atoms from the file
+ if ((ec = file->createAtoms()))
+ return ec;
+
+ return std::move(file);
+ }
+
+ virtual bool isCommonSymbol(const Elf_Sym *symbol) const {
+ switch (symbol->st_shndx) {
+ // Common symbols
+ case llvm::ELF::SHN_HEXAGON_SCOMMON:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_1:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_2:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_4:
+ case llvm::ELF::SHN_HEXAGON_SCOMMON_8:
+ return llvm::ELF::STT_COMMON;
+
+ default:
+ break;
+ }
+ return ELFFile<ELFT>::isCommonSymbol(symbol);
+ }
+
+ /// Process the Defined symbol and create an atom for it.
+ virtual ErrorOr<ELFDefinedAtom<ELFT> *>
+ handleDefinedSymbol(StringRef symName, StringRef sectionName,
+ const Elf_Sym *sym, const Elf_Shdr *sectionHdr,
+ ArrayRef<uint8_t> contentData,
+ unsigned int referenceStart, unsigned int referenceEnd,
+ std::vector<ELFReference<ELFT> *> &referenceList) {
+ return new (this->_readerStorage) HexagonELFDefinedAtom<ELFT>(
+ *this, symName, sectionName, sym, sectionHdr, contentData,
+ referenceStart, referenceEnd, referenceList);
+ }
+
+ /// Process the Common symbol and create an atom for it.
+ virtual ErrorOr<ELFCommonAtom<ELFT> *>
+ handleCommonSymbol(StringRef symName, const Elf_Sym *sym) {
+ return new (this->_readerStorage)
+ HexagonELFCommonAtom<ELFT>(*this, symName, sym);
+ }
+};
+
+template <class ELFT> class HexagonDynamicFile : public DynamicFile<ELFT> {
+public:
+ HexagonDynamicFile(const HexagonLinkingContext &context, StringRef name)
+ : DynamicFile<ELFT>(context, name) {}
+};
+
+} // elf
+} // lld
+
+#endif // LLD_READER_WRITER_ELF_HEXAGON_ELF_FILE_H
Copied: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h (from r200173, lld/trunk/lib/ReaderWriter/ELF/ELFReader.h)
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h?p2=lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h&p1=lld/trunk/lib/ReaderWriter/ELF/ELFReader.h&r1=200173&r2=200175&rev=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFReader.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonELFReader.h Sun Jan 26 19:02:03 2014
@@ -1,4 +1,5 @@
-//===- lib/ReaderWriter/ELF/ELFReader.h -----------------------------------===//
+//===- lib/ReaderWriter/ELF/HexagonELFReader.h
+//------------------------------===//
//
// The LLVM Linker
//
@@ -7,83 +8,67 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_READER_H
-#define LLD_READER_WRITER_ELF_READER_H
+#ifndef LLD_READER_WRITER_HEXAGON_ELF_READER_H
+#define LLD_READER_WRITER_HEXAGON_ELF_READER_H
-#include "CreateELF.h"
-#include "DynamicFile.h"
-#include "ELFFile.h"
-
-#include "lld/ReaderWriter/Reader.h"
+#include "ELFReader.h"
+#include "HexagonELFFile.h"
namespace lld {
namespace elf {
-struct DynamicFileCreateELFTraits {
+struct HexagonDynamicFileCreateELFTraits {
typedef llvm::ErrorOr<std::unique_ptr<lld::SharedLibraryFile>> result_type;
template <class ELFT>
static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
bool useUndefines) {
- return lld::elf::DynamicFile<ELFT>::create(std::move(mb), useUndefines);
+ return lld::elf::HexagonDynamicFile<ELFT>::create(std::move(mb),
+ useUndefines);
}
};
-struct ELFFileCreateELFTraits {
+struct HexagonELFFileCreateELFTraits {
typedef llvm::ErrorOr<std::unique_ptr<lld::File>> result_type;
template <class ELFT>
static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
- bool atomizeStrings, TargetHandlerBase *handler) {
- return lld::elf::ELFFile<ELFT>::create(std::move(mb), atomizeStrings,
- handler);
+ bool atomizeStrings) {
+ return lld::elf::HexagonELFFile<ELFT>::create(std::move(mb),
+ atomizeStrings);
}
};
-class ELFObjectReader : public Reader {
+class HexagonELFObjectReader : public ELFObjectReader {
public:
- ELFObjectReader(bool atomizeStrings, TargetHandlerBase *handler)
- : _atomizeStrings(atomizeStrings), _handler(handler) {}
-
- virtual bool canParse(file_magic magic, StringRef,
- const MemoryBuffer &) const {
- return (magic == llvm::sys::fs::file_magic::elf_relocatable);
- }
+ HexagonELFObjectReader(bool atomizeStrings)
+ : ELFObjectReader(atomizeStrings) {}
virtual error_code
parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
std::vector<std::unique_ptr<File>> &result) const {
std::size_t maxAlignment =
1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
- auto f = createELF<ELFFileCreateELFTraits>(
+ auto f = createELF<HexagonELFFileCreateELFTraits>(
llvm::object::getElfArchType(&*mb), maxAlignment, std::move(mb),
- _atomizeStrings, _handler);
+ _atomizeStrings);
if (error_code ec = f.getError())
return ec;
result.push_back(std::move(*f));
return error_code::success();
}
-
-private:
- bool _atomizeStrings;
- TargetHandlerBase *_handler;
};
-class ELFDSOReader : public Reader {
+class HexagonELFDSOReader : public ELFDSOReader {
public:
- ELFDSOReader(bool useUndefines) : _useUndefines(useUndefines) {}
-
- virtual bool canParse(file_magic magic, StringRef,
- const MemoryBuffer &) const {
- return (magic == llvm::sys::fs::file_magic::elf_shared_object);
- }
+ HexagonELFDSOReader(bool useUndefines) : ELFDSOReader(useUndefines) {}
virtual error_code
parseFile(std::unique_ptr<MemoryBuffer> &mb, const class Registry &,
std::vector<std::unique_ptr<File>> &result) const {
std::size_t maxAlignment =
1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
- auto f = createELF<DynamicFileCreateELFTraits>(
+ auto f = createELF<HexagonDynamicFileCreateELFTraits>(
llvm::object::getElfArchType(&*mb), maxAlignment, std::move(mb),
_useUndefines);
if (error_code ec = f.getError())
@@ -91,9 +76,6 @@ public:
result.push_back(std::move(*f));
return error_code::success();
}
-
-private:
- bool _useUndefines;
};
} // namespace elf
Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.cpp Sun Jan 26 19:02:03 2014
@@ -9,6 +9,7 @@
#include "Atoms.h"
#include "HexagonLinkingContext.h"
+#include "HexagonTargetHandler.h"
#include "lld/Core/File.h"
#include "lld/Core/Pass.h"
@@ -101,3 +102,7 @@ void elf::HexagonLinkingContext::createI
initFiniFile->addFiniFunction(ai);
result.push_back(std::move(initFiniFile));
}
+
+HexagonLinkingContext::HexagonLinkingContext(llvm::Triple triple)
+ : ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
+ new HexagonTargetHandler(*this))) {}
Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonLinkingContext.h Sun Jan 26 19:02:03 2014
@@ -10,8 +10,6 @@
#ifndef LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_LINKING_CONTEXT_H
#define LLD_READER_WRITER_ELF_HEXAGON_HEXAGON_LINKING_CONTEXT_H
-#include "HexagonTargetHandler.h"
-
#include "lld/ReaderWriter/ELFLinkingContext.h"
#include "llvm/Object/ELF.h"
@@ -22,9 +20,7 @@ namespace elf {
class HexagonLinkingContext LLVM_FINAL : public ELFLinkingContext {
public:
- HexagonLinkingContext(llvm::Triple triple)
- : ELFLinkingContext(triple, std::unique_ptr<TargetHandlerBase>(
- new HexagonTargetHandler(*this))) {}
+ HexagonLinkingContext(llvm::Triple triple);
virtual void addPasses(PassManager &);
Modified: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h Sun Jan 26 19:02:03 2014
@@ -15,68 +15,13 @@
#include "HexagonRelocationHandler.h"
#include "HexagonSectionChunks.h"
#include "TargetLayout.h"
+#include "HexagonELFReader.h"
namespace lld {
namespace elf {
typedef llvm::object::ELFType<llvm::support::little, 2, false> HexagonELFType;
class HexagonLinkingContext;
-/// \brief Handle Hexagon specific Atoms
-template <class HexagonELFType>
-class HexagonTargetAtomHandler LLVM_FINAL :
- public TargetAtomHandler<HexagonELFType> {
- typedef llvm::object::Elf_Sym_Impl<HexagonELFType> Elf_Sym;
- typedef llvm::object::Elf_Shdr_Impl<HexagonELFType> Elf_Shdr;
-public:
-
- virtual DefinedAtom::ContentType
- contentType(const ELFDefinedAtom<HexagonELFType> *atom) const {
- return contentType(atom->section(), atom->symbol());
- }
-
- virtual DefinedAtom::ContentType
- contentType(const Elf_Shdr *section, const Elf_Sym *sym) const {
- switch (sym->st_shndx) {
- // Common symbols
- case llvm::ELF::SHN_HEXAGON_SCOMMON:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_1:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_2:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_4:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_8:
- return DefinedAtom::typeZeroFillFast;
-
- default:
- if (section->sh_type == llvm::ELF::SHT_NOBITS)
- return DefinedAtom::typeZeroFillFast;
- else if (section->sh_flags & llvm::ELF::SHF_HEX_GPREL)
- return DefinedAtom::typeDataFast;
- else
- llvm_unreachable("unknown symbol type");
- }
- }
-
- virtual DefinedAtom::ContentPermissions
- contentPermissions(const ELFDefinedAtom<HexagonELFType> *atom) const {
- // All of the hexagon specific symbols belong in the data segment
- return DefinedAtom::permRW_;
- }
-
- virtual int64_t getType(const Elf_Sym *sym) const {
- switch (sym->st_shndx) {
- // Common symbols
- case llvm::ELF::SHN_HEXAGON_SCOMMON:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_1:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_2:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_4:
- case llvm::ELF::SHN_HEXAGON_SCOMMON_8:
- return llvm::ELF::STT_COMMON;
-
- default:
- return sym->getType();
- }
- }
-};
-
/// \brief TargetLayout for Hexagon
template <class HexagonELFType>
class HexagonTargetLayout LLVM_FINAL : public TargetLayout<HexagonELFType> {
@@ -165,10 +110,6 @@ public:
return _targetLayout;
}
- virtual HexagonTargetAtomHandler<HexagonELFType> &targetAtomHandler() {
- return _targetAtomHandler;
- }
-
virtual const HexagonTargetRelocationHandler &getRelocationHandler() const {
return _relocationHandler;
}
@@ -216,12 +157,19 @@ public:
return _gotSymAtom->_virtualAddr;
}
+ virtual std::unique_ptr<Reader> getObjReader(bool atomizeStrings) {
+ return std::unique_ptr<Reader>(new HexagonELFObjectReader(atomizeStrings));
+ }
+
+ virtual std::unique_ptr<Reader> getDSOReader(bool useShlibUndefines) {
+ return std::unique_ptr<Reader>(new HexagonELFDSOReader(useShlibUndefines));
+ }
+
private:
static const Registry::KindStrings kindStrings[];
HexagonTargetLayout<HexagonELFType> _targetLayout;
HexagonTargetRelocationHandler _relocationHandler;
- HexagonTargetAtomHandler<HexagonELFType> _targetAtomHandler;
std::unique_ptr<HexagonRuntimeFile<HexagonELFType> > _hexagonRuntimeFile;
AtomLayout *_gotSymAtom;
};
Modified: lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCLinkingContext.h Sun Jan 26 19:02:03 2014
@@ -19,6 +19,7 @@
namespace lld {
namespace elf {
+
class PPCLinkingContext LLVM_FINAL : public ELFLinkingContext {
public:
PPCLinkingContext(llvm::Triple triple)
Modified: lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/PPC/PPCTargetHandler.h Sun Jan 26 19:02:03 2014
@@ -44,7 +44,7 @@ public:
private:
static const Registry::KindStrings kindStrings[];
-
+
PPCTargetRelocationHandler _relocationHandler;
TargetLayout<PPCELFType> _targetLayout;
};
Modified: lld/trunk/lib/ReaderWriter/ELF/Reader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Reader.cpp?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Reader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Reader.cpp Sun Jan 26 19:02:03 2014
@@ -39,16 +39,14 @@ struct ELFFileCreateELFTraits {
template <class ELFT>
static result_type create(std::unique_ptr<llvm::MemoryBuffer> mb,
- bool atomizeStrings, TargetHandlerBase *handler) {
- return lld::elf::ELFFile<ELFT>::create(std::move(mb), atomizeStrings,
- handler);
+ bool atomizeStrings) {
+ return lld::elf::ELFFile<ELFT>::create(std::move(mb), atomizeStrings);
}
};
class ELFObjectReader : public Reader {
public:
- ELFObjectReader(bool atomizeStrings, TargetHandlerBase *handler)
- : _atomizeStrings(atomizeStrings), _handler(handler) {}
+ ELFObjectReader(bool atomizeStrings) : _atomizeStrings(atomizeStrings) {}
virtual bool canParse(file_magic magic, StringRef,
const MemoryBuffer &) const {
@@ -61,9 +59,8 @@ public:
error_code ec;
std::size_t maxAlignment =
1ULL << llvm::countTrailingZeros(uintptr_t(mb->getBufferStart()));
- auto f = createELF<ELFFileCreateELFTraits>(getElfArchType(&*mb),
- maxAlignment, std::move(mb),
- _atomizeStrings, _handler);
+ auto f = createELF<ELFFileCreateELFTraits>(
+ getElfArchType(&*mb), maxAlignment, std::move(mb), _atomizeStrings);
if (error_code ec = f.getError())
return ec;
result.push_back(std::move(*f));
@@ -72,7 +69,6 @@ public:
private:
bool _atomizeStrings;
- TargetHandlerBase *_handler;
};
class ELFDSOReader : public Reader {
@@ -111,15 +107,16 @@ void Registry::addSupportELFObjects(bool
TargetHandlerBase *handler) {
// Tell registry about the ELF object file parser.
- add(std::unique_ptr<Reader>(
- new elf::ELFObjectReader(atomizeStrings, handler)));
+ add(std::move(handler->getObjReader(atomizeStrings)));
// Tell registry about the relocation name to number mapping for this arch.
handler->registerRelocationNames(*this);
}
-void Registry::addSupportELFDynamicSharedObjects(bool useShlibUndefines) {
- add(std::unique_ptr<Reader>(new elf::ELFDSOReader(useShlibUndefines)));
+void Registry::addSupportELFDynamicSharedObjects(bool useShlibUndefines,
+ TargetHandlerBase *handler) {
+ // Tell registry about the ELF dynamic shared library file parser.
+ add(handler->getDSOReader(useShlibUndefines));
}
} // end namespace lld
Modified: lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h?rev=200175&r1=200174&r2=200175&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/TargetHandler.h Sun Jan 26 19:02:03 2014
@@ -40,44 +40,12 @@ template <class ELFT> class ELFHeader;
template <class ELFT> class Section;
template <class ELFT> class TargetLayout;
-/// \brief The target registers a set of handlers for overriding target specific
-/// attributes for a DefinedAtom. The Reader uses this class to query for the
-/// type of atom and its permissions
-template <class ELFT> class TargetAtomHandler {
-public:
- typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
- typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
-
- virtual DefinedAtom::ContentType
- contentType(const ELFDefinedAtom<ELFT> *atom) const {
- return atom->contentType();
- }
-
- virtual DefinedAtom::ContentType
- contentType(const Elf_Shdr *shdr, const Elf_Sym *sym) const {
- return DefinedAtom::typeZeroFill;
- }
-
- virtual DefinedAtom::ContentPermissions
- contentPermissions(const ELFDefinedAtom<ELFT> *atom) const {
- return atom->permissions();
- }
-
- virtual int64_t getType(const Elf_Sym *sym) const {
- return llvm::ELF::STT_NOTYPE;
- }
-
- virtual ~TargetAtomHandler() {}
-};
-
template <class ELFT> class TargetRelocationHandler {
public:
virtual error_code
applyRelocation(ELFWriter &, llvm::FileOutputBuffer &,
const lld::AtomLayout &, const Reference &) const = 0;
- virtual int64_t relocAddend(const Reference &)const { return 0; }
-
virtual ~TargetRelocationHandler() {}
};
@@ -99,9 +67,6 @@ public:
/// TargetLayout
virtual TargetLayout<ELFT> &targetLayout() = 0;
- /// TargetAtomHandler
- virtual TargetAtomHandler<ELFT> &targetAtomHandler() = 0;
-
virtual const TargetRelocationHandler<ELFT> &getRelocationHandler() const = 0;
/// Create a set of Default target sections that a target might needj
@@ -127,6 +92,10 @@ public:
virtual LLD_UNIQUE_BUMP_PTR(DynamicSymbolTable<ELFT>)
createDynamicSymbolTable() = 0;
+ virtual std::unique_ptr<Reader> getObjReader(bool) = 0;
+
+ virtual std::unique_ptr<Reader> getDSOReader(bool) = 0;
+
protected:
ELFLinkingContext &_context;
};
More information about the llvm-commits
mailing list