forked from OSchip/llvm-project
add targethandler hooks from Writer and cleanup
llvm-svn: 173904
This commit is contained in:
parent
41778c3fa9
commit
a6f00fe083
|
@ -44,11 +44,9 @@ public:
|
|||
: _name(name), _kind(kind), _fsize(0), _msize(0), _align2(0), _order(0),
|
||||
_ordinal(1), _start(0), _fileoffset(0), _targetInfo(ti) {
|
||||
}
|
||||
virtual ~Chunk() {}
|
||||
virtual ~Chunk() {}
|
||||
// Does the chunk occupy disk space
|
||||
virtual bool occupiesNoDiskSpace() const {
|
||||
return false;
|
||||
}
|
||||
virtual bool occupiesNoDiskSpace() const { return false; }
|
||||
// The name of the chunk
|
||||
StringRef name() const { return _name; }
|
||||
// Kind of chunk
|
||||
|
@ -74,7 +72,7 @@ public:
|
|||
// Writer the chunk
|
||||
virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) = 0;
|
||||
// Finalize the chunk before writing
|
||||
virtual void finalize() = 0;
|
||||
virtual void finalize() = 0;
|
||||
|
||||
protected:
|
||||
StringRef _name;
|
||||
|
|
|
@ -90,7 +90,7 @@ public:
|
|||
}
|
||||
|
||||
// Data members
|
||||
const StringRef _name;
|
||||
StringRef _name;
|
||||
DefinedAtom::ContentPermissions _perm;
|
||||
};
|
||||
|
||||
|
@ -141,17 +141,22 @@ public:
|
|||
|
||||
typedef typename std::vector<AtomLayout *>::iterator AbsoluteAtomIterT;
|
||||
|
||||
DefaultLayout(const ELFTargetInfo &ti) : _targetInfo(ti) {}
|
||||
DefaultLayout(const ELFTargetInfo &ti)
|
||||
: _targetInfo(ti), _targetHandler(ti.getTargetHandler<ELFT>()) {
|
||||
}
|
||||
|
||||
/// \brief Return the section order for a input section
|
||||
virtual SectionOrder getSectionOrder
|
||||
(const StringRef name,
|
||||
int32_t contentType,
|
||||
int32_t contentPermissions);
|
||||
virtual SectionOrder getSectionOrder(StringRef name, int32_t contentType,
|
||||
int32_t contentPermissions);
|
||||
|
||||
/// \brief This maps the input sections to the output section names
|
||||
StringRef getSectionName(const StringRef name,
|
||||
const int32_t contentType);
|
||||
virtual StringRef getSectionName(StringRef name, const int32_t contentType,
|
||||
const int32_t contentPermissions);
|
||||
|
||||
/// \brief Returns the section to be created
|
||||
virtual Section<ELFT> *getSection(StringRef name, const int32_t contentType,
|
||||
const int32_t contentPermissions,
|
||||
const int32_t sectionOrder);
|
||||
|
||||
/// \brief Gets the segment for a output section
|
||||
virtual Layout::SegmentType getSegmentType(Section<ELFT> *section) const;
|
||||
|
@ -172,9 +177,9 @@ public:
|
|||
}
|
||||
|
||||
/// \brief find a absolute atom given a name
|
||||
AbsoluteAtomIterT findAbsoluteAtom(const StringRef name) {
|
||||
AbsoluteAtomIterT findAbsoluteAtom(StringRef name) {
|
||||
return std::find_if(_absoluteAtoms.begin(), _absoluteAtoms.end(),
|
||||
FindByName(name));
|
||||
FindByName(name));
|
||||
}
|
||||
|
||||
// Merge sections with the same name into a MergedSections
|
||||
|
@ -200,9 +205,9 @@ public:
|
|||
si->finalize();
|
||||
}
|
||||
|
||||
inline bool findAtomAddrByName(const StringRef name, uint64_t &addr) {
|
||||
inline bool findAtomAddrByName(StringRef name, uint64_t &addr) {
|
||||
for (auto sec : _sections)
|
||||
if (auto section = dyn_cast<Section<ELFT>>(sec))
|
||||
if (auto section = dyn_cast<Section<ELFT> >(sec))
|
||||
if (section->findAtomAddrByName(name, addr))
|
||||
return true;
|
||||
return false;
|
||||
|
@ -253,14 +258,12 @@ private:
|
|||
std::vector<AtomLayout *> _absoluteAtoms;
|
||||
llvm::BumpPtrAllocator _allocator;
|
||||
const ELFTargetInfo &_targetInfo;
|
||||
TargetHandler<ELFT> &_targetHandler;
|
||||
};
|
||||
|
||||
template<class ELFT>
|
||||
Layout::SectionOrder
|
||||
DefaultLayout<ELFT>::getSectionOrder(const StringRef name,
|
||||
int32_t contentType,
|
||||
int32_t contentPermissions)
|
||||
{
|
||||
template <class ELFT>
|
||||
Layout::SectionOrder DefaultLayout<ELFT>::getSectionOrder(
|
||||
StringRef name, int32_t contentType, int32_t contentPermissions) {
|
||||
switch (contentType) {
|
||||
case DefinedAtom::typeResolver:
|
||||
case DefinedAtom::typeCode:
|
||||
|
@ -298,10 +301,10 @@ DefaultLayout<ELFT>::getSectionOrder(const StringRef name,
|
|||
}
|
||||
|
||||
/// \brief This maps the input sections to the output section names
|
||||
template<class ELFT>
|
||||
StringRef
|
||||
DefaultLayout<ELFT>::getSectionName(const StringRef name,
|
||||
const int32_t contentType) {
|
||||
template <class ELFT>
|
||||
StringRef DefaultLayout<ELFT>::getSectionName(
|
||||
StringRef name, const int32_t contentType,
|
||||
const int32_t contentPermissions) {
|
||||
if (contentType == DefinedAtom::typeZeroFill)
|
||||
return ".bss";
|
||||
if (name.startswith(".text"))
|
||||
|
@ -312,10 +315,11 @@ DefaultLayout<ELFT>::getSectionName(const StringRef name,
|
|||
}
|
||||
|
||||
/// \brief Gets the segment for a output section
|
||||
template<class ELFT>
|
||||
Layout::SegmentType
|
||||
DefaultLayout<ELFT>::getSegmentType(Section<ELFT> *section) const {
|
||||
switch(section->order()) {
|
||||
template <class ELFT>
|
||||
Layout::SegmentType DefaultLayout<ELFT>::getSegmentType(
|
||||
Section<ELFT> *section) const {
|
||||
|
||||
switch (section->order()) {
|
||||
case ORDER_INTERP:
|
||||
return llvm::ELF::PT_INTERP;
|
||||
|
||||
|
@ -355,10 +359,12 @@ DefaultLayout<ELFT>::getSegmentType(Section<ELFT> *section) const {
|
|||
}
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
bool
|
||||
DefaultLayout<ELFT>::hasOutputSegment(Section<ELFT> *section) {
|
||||
switch(section->order()) {
|
||||
template <class ELFT>
|
||||
bool DefaultLayout<ELFT>::hasOutputSegment(Section<ELFT> *section) {
|
||||
if (section->sectionKind() == Section<ELFT>::K_Target)
|
||||
return section->hasOutputSegment();
|
||||
|
||||
switch (section->order()) {
|
||||
case ORDER_INTERP:
|
||||
case ORDER_HASH:
|
||||
case ORDER_DYNAMIC_SYMBOLS:
|
||||
|
@ -388,6 +394,14 @@ DefaultLayout<ELFT>::hasOutputSegment(Section<ELFT> *section) {
|
|||
}
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
Section<ELFT> *DefaultLayout<ELFT>::getSection(
|
||||
StringRef sectionName, int32_t contentType, int32_t permissions,
|
||||
int32_t sectionOrder) {
|
||||
return new (_allocator) Section<ELFT>(_targetInfo, sectionName, contentType,
|
||||
permissions, sectionOrder);
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
ErrorOr<const AtomLayout &> DefaultLayout<ELFT>::addAtom(const Atom *atom) {
|
||||
if (const DefinedAtom *definedAtom = dyn_cast<DefinedAtom>(atom)) {
|
||||
|
@ -396,20 +410,21 @@ ErrorOr<const AtomLayout &> DefaultLayout<ELFT>::addAtom(const Atom *atom) {
|
|||
// -noinhibit-exec.
|
||||
if (definedAtom->contentType() == DefinedAtom::typeUnknown)
|
||||
return make_error_code(llvm::errc::invalid_argument);
|
||||
const StringRef sectionName = getSectionName(
|
||||
definedAtom->customSectionName(), definedAtom->contentType());
|
||||
StringRef sectionName = definedAtom->customSectionName();
|
||||
const DefinedAtom::ContentPermissions permissions =
|
||||
definedAtom->permissions();
|
||||
const DefinedAtom::ContentType contentType =
|
||||
definedAtom->contentType();
|
||||
const DefinedAtom::ContentType contentType = definedAtom->contentType();
|
||||
|
||||
sectionName = getSectionName(sectionName, contentType, permissions);
|
||||
|
||||
const SectionKey sectionKey(sectionName, permissions);
|
||||
Section<ELFT> *section;
|
||||
|
||||
if (_sectionMap.find(sectionKey) == _sectionMap.end()) {
|
||||
SectionOrder section_order =
|
||||
getSectionOrder(sectionName, contentType, permissions);
|
||||
section = new (_allocator) Section<ELFT>(
|
||||
_targetInfo, sectionName, contentType, permissions, section_order);
|
||||
section =
|
||||
getSection(sectionName, contentType, permissions, section_order);
|
||||
section->setOrder(section_order);
|
||||
_sections.push_back(section);
|
||||
_sectionMap.insert(std::make_pair(sectionKey, section));
|
||||
|
@ -456,13 +471,13 @@ DefaultLayout<ELFT>::mergeSimiliarSections() {
|
|||
}
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
void
|
||||
DefaultLayout<ELFT>::assignSectionsToSegments() {
|
||||
template <class ELFT> void DefaultLayout<ELFT>::assignSectionsToSegments() {
|
||||
// TODO: Do we want to give a chance for the targetHandlers
|
||||
// to sort segments in an arbitrary order ?
|
||||
// sort the sections by their order as defined by the layout
|
||||
std::stable_sort(_sections.begin(), _sections.end(),
|
||||
[](Chunk<ELFT> *A, Chunk<ELFT> *B) {
|
||||
return A->order() < B->order();
|
||||
[](Chunk<ELFT> *A, Chunk<ELFT> *B) {
|
||||
return A->order() < B->order();
|
||||
});
|
||||
// Merge all sections
|
||||
mergeSimiliarSections();
|
||||
|
@ -482,11 +497,11 @@ DefaultLayout<ELFT>::assignSectionsToSegments() {
|
|||
continue;
|
||||
msi->setHasSegment();
|
||||
section->setSegment(getSegmentType(section));
|
||||
const StringRef segmentName = section->segmentKindToStr();
|
||||
StringRef segmentName = section->segmentKindToStr();
|
||||
// Use the flags of the merged Section for the segment
|
||||
const SegmentKey key(segmentName, msi->flags());
|
||||
const std::pair<SegmentKey, Segment<ELFT> *>
|
||||
currentSegment(key, nullptr);
|
||||
const std::pair<SegmentKey, Segment<ELFT> *> currentSegment(key,
|
||||
nullptr);
|
||||
std::pair<typename SegmentMapT::iterator, bool>
|
||||
segmentInsert(_segmentMap.insert(currentSegment));
|
||||
Segment<ELFT> *segment;
|
||||
|
@ -504,11 +519,10 @@ DefaultLayout<ELFT>::assignSectionsToSegments() {
|
|||
}
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
void
|
||||
DefaultLayout<ELFT>::assignFileOffsets() {
|
||||
std::sort(_segments.begin(), _segments.end(),
|
||||
Segment<ELFT>::compareSegments);
|
||||
template <class ELFT> void DefaultLayout<ELFT>::assignFileOffsets() {
|
||||
// TODO: Do we want to give a chance for the targetHandlers
|
||||
// to sort segments in an arbitrary order ?
|
||||
std::sort(_segments.begin(), _segments.end(), Segment<ELFT>::compareSegments);
|
||||
int ordinal = 0;
|
||||
// Compute the number of segments that might be needed, so that the
|
||||
// size of the program header can be computed
|
||||
|
|
|
@ -32,8 +32,8 @@ public:
|
|||
CRuntimeFile(const ELFTargetInfo &ti) : ELFFile<ELFT>(ti, "C runtime") {}
|
||||
|
||||
/// \brief add a global absolute atom
|
||||
void addAbsoluteAtom(const StringRef symbolName) {
|
||||
Elf_Sym *symbol = new(_allocator.Allocate<Elf_Sym>()) Elf_Sym;
|
||||
void addAbsoluteAtom(StringRef symbolName) {
|
||||
Elf_Sym *symbol = new (_allocator.Allocate<Elf_Sym>()) Elf_Sym;
|
||||
symbol->st_name = 0;
|
||||
symbol->st_value = 0;
|
||||
symbol->st_shndx = llvm::ELF::SHN_ABS;
|
||||
|
@ -47,7 +47,7 @@ public:
|
|||
}
|
||||
|
||||
/// \brief add an undefined atom
|
||||
void addUndefinedAtom(const StringRef symbolName) {
|
||||
void addUndefinedAtom(StringRef symbolName) {
|
||||
Elf_Sym *symbol = new (_allocator) Elf_Sym;
|
||||
symbol->st_name = 0;
|
||||
symbol->st_value = 0;
|
||||
|
|
|
@ -48,7 +48,7 @@ template <class ELFT> class ELFFile : public File {
|
|||
typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
|
||||
|
||||
public:
|
||||
ELFFile(const ELFTargetInfo &ti, const StringRef name)
|
||||
ELFFile(const ELFTargetInfo &ti, StringRef name)
|
||||
: File(name), _elfTargetInfo(ti) {
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
};
|
||||
// Create a section object, the section is set to the default type if the
|
||||
// caller doesnot set it
|
||||
Section(const ELFTargetInfo &, const StringRef sectionName,
|
||||
Section(const ELFTargetInfo &, StringRef sectionName,
|
||||
const int32_t contentType, const int32_t contentPermissions,
|
||||
const int32_t order, const SectionKind kind = K_Default);
|
||||
|
||||
|
@ -54,6 +54,18 @@ public:
|
|||
return _sectionKind;
|
||||
}
|
||||
|
||||
/// set the section Kind, this function is needed by the targetHandler
|
||||
/// to set the target section
|
||||
inline void setKind(SectionKind k) { _sectionKind = k; }
|
||||
|
||||
/// Is the section part of any segment, Target sections must override
|
||||
/// this function
|
||||
virtual bool hasOutputSegment() {
|
||||
assert((_sectionKind != K_Target) &&
|
||||
"Cannot determine if the targetSection has any output segment");
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Align the offset to the required modulus defined by the atom alignment
|
||||
uint64_t alignOffset(uint64_t offset, DefinedAtom::Alignment &atomAlign);
|
||||
|
||||
|
@ -83,7 +95,7 @@ public:
|
|||
/// \brief Find the Atom address given a name, this is needed to to properly
|
||||
/// apply relocation. The section class calls this to find the atom address
|
||||
/// to fix the relocation
|
||||
inline bool findAtomAddrByName(const StringRef name, uint64_t &addr) {
|
||||
inline bool findAtomAddrByName(StringRef name, uint64_t &addr) {
|
||||
for (auto ai : _atoms) {
|
||||
if (ai->_atom->name() == name) {
|
||||
addr = ai->_virtualAddr;
|
||||
|
@ -178,7 +190,7 @@ protected:
|
|||
// Create a section object, the section is set to the default type if the
|
||||
// caller doesnot set it
|
||||
template <class ELFT>
|
||||
Section<ELFT>::Section(const ELFTargetInfo &ti, const StringRef sectionName,
|
||||
Section<ELFT>::Section(const ELFTargetInfo &ti, StringRef sectionName,
|
||||
const int32_t contentType,
|
||||
const int32_t contentPermissions, const int32_t order,
|
||||
const SectionKind kind)
|
||||
|
@ -513,7 +525,7 @@ public:
|
|||
return c->kind() == Section<ELFT>::K_StringTable;
|
||||
}
|
||||
|
||||
uint64_t addString(const StringRef symname);
|
||||
uint64_t addString(StringRef symname);
|
||||
|
||||
void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
|
||||
|
||||
|
@ -536,9 +548,7 @@ StringTable<ELFT>::StringTable(const ELFTargetInfo &ti, const char *str,
|
|||
this->setOrder(order);
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
uint64_t
|
||||
StringTable<ELFT>::addString(const StringRef symname) {
|
||||
template <class ELFT> uint64_t StringTable<ELFT>::addString(StringRef symname) {
|
||||
_strings.push_back(symname);
|
||||
uint64_t offset = this->_fsize;
|
||||
this->_fsize += symname.size() + 1;
|
||||
|
|
|
@ -108,7 +108,7 @@ public:
|
|||
typedef typename std::vector<SegmentSlice<ELFT> *>::iterator SliceIter;
|
||||
typedef typename std::vector<Chunk<ELFT> *>::iterator SectionIter;
|
||||
|
||||
Segment(const ELFTargetInfo &ti, const StringRef name,
|
||||
Segment(const ELFTargetInfo &ti, StringRef name,
|
||||
const Layout::SegmentType type);
|
||||
|
||||
/// append a section to a segment
|
||||
|
@ -195,7 +195,7 @@ protected:
|
|||
};
|
||||
|
||||
template <class ELFT>
|
||||
Segment<ELFT>::Segment(const ELFTargetInfo &ti, const StringRef name,
|
||||
Segment<ELFT>::Segment(const ELFTargetInfo &ti, StringRef name,
|
||||
const Layout::SegmentType type)
|
||||
: Chunk<ELFT>(name, Chunk<ELFT>::K_ELFSegment, ti), _segmentType(type),
|
||||
_flags(0), _atomflags(0) {
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace lld {
|
||||
namespace elf {
|
||||
|
@ -75,30 +74,6 @@ template <class ELFT> class TargetHandler : public TargetHandlerBase {
|
|||
public:
|
||||
TargetHandler(ELFTargetInfo &targetInfo) : _targetInfo(targetInfo) {}
|
||||
|
||||
/// Register a Target, so that the target backend may choose on how to merge
|
||||
/// individual atoms within the section, this is a way to control output order
|
||||
/// of atoms that is determined by the target
|
||||
void registerTargetSection(StringRef name,
|
||||
DefinedAtom::ContentPermissions perm) {
|
||||
const TargetSectionKey targetSection(name, perm);
|
||||
if (_registeredTargetSections.find(targetSection) ==
|
||||
_registeredTargetSections.end())
|
||||
_registeredTargetSections.insert(std::make_pair(targetSection, true));
|
||||
}
|
||||
|
||||
/// Check if the section is registered given the section name and its
|
||||
/// contentType, if they are registered the target would need to
|
||||
/// create a section so that atoms insert, atom virtual address assignment
|
||||
/// could be overridden and controlled by the Target
|
||||
bool isSectionRegisteredByTarget(StringRef name,
|
||||
DefinedAtom::ContentPermissions perm) {
|
||||
const TargetSectionKey targetSection(name, perm);
|
||||
if (_registeredTargetSections.find(targetSection) ==
|
||||
_registeredTargetSections.end())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// If the target overrides ELF header information, this API would
|
||||
/// return true, so that the target can set all fields specific to
|
||||
/// that target
|
||||
|
@ -131,37 +106,8 @@ public:
|
|||
/// symbols over to small data, this would also be used
|
||||
virtual void allocateCommons() = 0;
|
||||
|
||||
private:
|
||||
struct TargetSectionKey {
|
||||
TargetSectionKey(StringRef name, DefinedAtom::ContentPermissions perm)
|
||||
: _name(name), _perm(perm) {
|
||||
}
|
||||
|
||||
// Data members
|
||||
const StringRef _name;
|
||||
DefinedAtom::ContentPermissions _perm;
|
||||
};
|
||||
|
||||
struct TargetSectionKeyHash {
|
||||
int64_t operator()(const TargetSectionKey &k) const {
|
||||
return llvm::hash_combine(k._name, k._perm);
|
||||
}
|
||||
};
|
||||
|
||||
struct TargetSectionKeyEq {
|
||||
bool operator()(const TargetSectionKey &lhs,
|
||||
const TargetSectionKey &rhs) const {
|
||||
return ((lhs._name == rhs._name) && (lhs._perm == rhs._perm));
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::unordered_map<TargetSectionKey, bool, TargetSectionKeyHash,
|
||||
TargetSectionKeyEq> RegisteredTargetSectionMapT;
|
||||
typedef typename RegisteredTargetSectionMapT::iterator RegisteredTargetSectionMapIterT;
|
||||
|
||||
protected:
|
||||
const ELFTargetInfo &_targetInfo;
|
||||
RegisteredTargetSectionMapT _registeredTargetSections;
|
||||
};
|
||||
} // end namespace elf
|
||||
} // end namespace lld
|
||||
|
|
|
@ -21,42 +21,8 @@ namespace elf {
|
|||
/// be changed in the final layout
|
||||
template <class ELFT> class TargetLayout : public DefaultLayout<ELFT> {
|
||||
public:
|
||||
TargetLayout(ELFTargetInfo &targetInfo)
|
||||
: DefaultELFLayout<ELFT>(targetInfo) {
|
||||
}
|
||||
|
||||
/// isTargetSection provides a way to determine if the section that
|
||||
/// we are processing has been registered by the target and the target
|
||||
/// wants to handle them.
|
||||
/// For example: the Writer may be processing a section but the target
|
||||
/// might want to override the functionality on how atoms are inserted
|
||||
/// into the section. Such sections are set the K_TargetSection flag in
|
||||
/// the SectionKind after they are created
|
||||
virtual bool isTargetSection(const StringRef name, const int32_t contentType,
|
||||
const int32_t contentPermissions) = 0;
|
||||
|
||||
/// The target may want to override the sectionName to a different
|
||||
/// section Name in the output
|
||||
virtual StringRef sectionName(const StringRef name, const int32_t contentType,
|
||||
const int32_t contentPermissions) = 0;
|
||||
|
||||
/// The target may want to override the section order that has been
|
||||
/// set by the DefaultLayout
|
||||
virtual Layout::SectionOrder getSectionOrder(
|
||||
const StringRef name, int32_t contentType,
|
||||
int32_t contentPermissions) = 0;
|
||||
|
||||
/// The target can set the segment type for a Section
|
||||
virtual Layout::SegmentType segmentType(Section<ELFT> *section) const = 0;
|
||||
|
||||
/// Returns true/false depending on whether the section has a Output
|
||||
// segment or not
|
||||
bool hasOutputSegment(Section<ELFT> *section) = 0;
|
||||
|
||||
/// Returns the target Section for a section name and content Type
|
||||
Section<ELFT> *getSection(const StringRef name,
|
||||
DefinedAtom::ContentPermissions permissions) = 0;
|
||||
|
||||
TargetLayout(const ELFTargetInfo &targetInfo)
|
||||
: DefaultLayout<ELFT>(targetInfo) {}
|
||||
};
|
||||
} // end namespace elf
|
||||
} // end namespace lld
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "lld/ReaderWriter/Writer.h"
|
||||
|
||||
#include "DefaultLayout.h"
|
||||
#include "TargetLayout.h"
|
||||
#include "ExecutableAtoms.h"
|
||||
|
||||
#include "lld/ReaderWriter/ELFTargetInfo.h"
|
||||
|
@ -54,8 +55,9 @@ private:
|
|||
void createDefaultSections();
|
||||
|
||||
const ELFTargetInfo &_targetInfo;
|
||||
TargetHandler<ELFT> &_targetHandler;
|
||||
|
||||
typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
|
||||
typedef llvm::DenseMap<const Atom *, uint64_t> AtomToAddress;
|
||||
std::unique_ptr<KindHandler> _referenceKindHandler;
|
||||
AtomToAddress _atomToAddressMap;
|
||||
llvm::BumpPtrAllocator _chunkAllocate;
|
||||
|
@ -72,17 +74,17 @@ private:
|
|||
//===----------------------------------------------------------------------===//
|
||||
// ExecutableWriter
|
||||
//===----------------------------------------------------------------------===//
|
||||
template<class ELFT>
|
||||
template <class ELFT>
|
||||
ExecutableWriter<ELFT>::ExecutableWriter(const ELFTargetInfo &ti)
|
||||
: _targetInfo(ti)
|
||||
, _referenceKindHandler(KindHandler::makeHandler(
|
||||
ti.getTriple().getArch(), ti.isLittleEndian()))
|
||||
, _runtimeFile(ti) {
|
||||
_layout = new DefaultLayout<ELFT>(ti);
|
||||
: _targetInfo(ti), _targetHandler(ti.getTargetHandler<ELFT>()),
|
||||
_referenceKindHandler(KindHandler::makeHandler(ti.getTriple().getArch(),
|
||||
ti.isLittleEndian())),
|
||||
_runtimeFile(ti) {
|
||||
_layout = new TargetLayout<ELFT>(_targetInfo);
|
||||
}
|
||||
|
||||
template<class ELFT>
|
||||
void ExecutableWriter<ELFT>::buildChunks(const File &file){
|
||||
template <class ELFT>
|
||||
void ExecutableWriter<ELFT>::buildChunks(const File &file) {
|
||||
for (const DefinedAtom *definedAtom : file.defined() ) {
|
||||
_layout->addAtom(definedAtom);
|
||||
}
|
||||
|
@ -163,10 +165,12 @@ void ExecutableWriter<ELFT>::addDefaultAtoms() {
|
|||
}
|
||||
|
||||
/// \brief Hook in lld to add CRuntime file
|
||||
template<class ELFT>
|
||||
template <class ELFT>
|
||||
void ExecutableWriter<ELFT>::addFiles(InputFiles &inputFiles) {
|
||||
addDefaultAtoms();
|
||||
inputFiles.prependFile(_runtimeFile);
|
||||
// Give a chance for the target to add atoms
|
||||
_targetHandler.addFiles(inputFiles);
|
||||
}
|
||||
|
||||
/// Finalize the value of all the absolute symbols that we
|
||||
|
@ -260,16 +264,21 @@ ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) {
|
|||
if (ec)
|
||||
return ec;
|
||||
|
||||
_Header->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64
|
||||
: ELF::ELFCLASS32);
|
||||
_Header->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian()
|
||||
? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
|
||||
_Header->e_ident(ELF::EI_VERSION, 1);
|
||||
_Header->e_ident(ELF::EI_OSABI, 0);
|
||||
_Header->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64 :
|
||||
ELF::ELFCLASS32);
|
||||
_Header->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian() ?
|
||||
ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
|
||||
_Header->e_type(_targetInfo.getOutputType());
|
||||
_Header->e_machine(_targetInfo.getOutputMachine());
|
||||
_Header->e_version(1);
|
||||
_Header->e_entry(0ULL);
|
||||
|
||||
if (!_targetHandler.doesOverrideHeader()) {
|
||||
_Header->e_ident(ELF::EI_VERSION, 1);
|
||||
_Header->e_ident(ELF::EI_OSABI, 0);
|
||||
_Header->e_version(1);
|
||||
} else {
|
||||
// override the contents of the ELF Header
|
||||
_targetHandler.setHeaderInfo(_Header);
|
||||
}
|
||||
_Header->e_phoff(_programHeader->fileOffset());
|
||||
_Header->e_shoff(_shdrtab->fileOffset());
|
||||
_Header->e_phentsize(_programHeader->entsize());
|
||||
|
@ -314,6 +323,9 @@ void ExecutableWriter<ELFT>::createDefaultSections() {
|
|||
_shdrtab->setStringSection(_shstrtab);
|
||||
_symtab->setStringSection(_strtab);
|
||||
_layout->addSection(_shdrtab);
|
||||
|
||||
// give a chance for the target to add sections
|
||||
_targetHandler.createDefaultSections();
|
||||
}
|
||||
} // namespace elf
|
||||
|
||||
|
|
Loading…
Reference in New Issue