[lld] r175207 - [ELF][Writer] Refactor Section to not have atoms. Move atoms into AtomSection.
Michael J. Spencer
bigcheesegs at gmail.com
Thu Feb 14 12:24:39 PST 2013
Author: mspencer
Date: Thu Feb 14 14:24:38 2013
New Revision: 175207
URL: http://llvm.org/viewvc/llvm-project?rev=175207&view=rev
Log:
[ELF][Writer] Refactor Section to not have atoms. Move atoms into AtomSection.
The purpose of this change is to simplify creating non-atom sections.
Previously _contentType, _sectionKind and _order were used for multiple
purposes and collided in places. This moves all of the Atom specific logic down
into AtomSection and makes Section just have raw Elf_Shdr flags.
Modified:
lld/trunk/lib/ReaderWriter/ELF/Chunk.h
lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h
lld/trunk/lib/ReaderWriter/ELF/Layout.h
lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
lld/trunk/lib/ReaderWriter/ELF/Writer.cpp
Modified: lld/trunk/lib/ReaderWriter/ELF/Chunk.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Chunk.h?rev=175207&r1=175206&r2=175207&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Chunk.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Chunk.h Thu Feb 14 14:24:38 2013
@@ -38,6 +38,7 @@ public:
K_ProgramHeader, // Program Header
K_ELFSegment, // Segment
K_ELFSection, // Section
+ K_AtomSection, //< A section containing atoms.
K_SectionHeader // Section header
};
Chunk(StringRef name, Kind kind, const ELFTargetInfo &ti)
@@ -80,7 +81,7 @@ protected:
uint64_t _fsize;
uint64_t _msize;
uint64_t _align2;
- uint32_t _order;
+ uint32_t _order;
uint64_t _ordinal;
uint64_t _start;
uint64_t _fileoffset;
Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=175207&r1=175206&r2=175207&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h Thu Feb 14 14:24:38 2013
@@ -129,7 +129,7 @@ public:
}
};
- typedef std::unordered_map<SectionKey, Section<ELFT> *, SectionKeyHash,
+ typedef std::unordered_map<SectionKey, AtomSection<ELFT> *, SectionKeyHash,
SectionKeyEq> SectionMapT;
typedef std::unordered_map<SegmentKey, Segment<ELFT> *,
SegmentHashKey> SegmentMapT;
@@ -155,10 +155,10 @@ public:
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 or creates a section.
+ AtomSection<ELFT> *getSection(
+ StringRef name, int32_t contentType,
+ DefinedAtom::ContentPermissions contentPermissions);
/// \brief Gets the segment for a output section
virtual Layout::SegmentType getSegmentType(Section<ELFT> *section) const;
@@ -254,6 +254,13 @@ public:
return 0;
}
+protected:
+ /// \brief Allocate a new section.
+ virtual AtomSection<ELFT> *createSection(
+ StringRef name, int32_t contentType,
+ DefinedAtom::ContentPermissions contentPermissions,
+ SectionOrder sectionOrder);
+
private:
SectionMapT _sectionMap;
MergedSectionMapT _mergedSectionMap;
@@ -381,9 +388,6 @@ Layout::SegmentType DefaultLayout<ELFT>:
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:
@@ -410,18 +414,35 @@ bool DefaultLayout<ELFT>::hasOutputSegme
case ORDER_FINI_ARRAY:
case ORDER_BSS:
return true;
-
default:
- return false;
+ return section->hasOutputSegment();
}
}
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);
+AtomSection<ELFT> *DefaultLayout<ELFT>::createSection(
+ StringRef sectionName, int32_t contentType,
+ DefinedAtom::ContentPermissions permissions, SectionOrder sectionOrder) {
+ return new (_allocator) AtomSection<ELFT>(
+ _targetInfo, sectionName, contentType, permissions, sectionOrder);
+}
+
+template <class ELFT>
+AtomSection<ELFT> *DefaultLayout<ELFT>::getSection(
+ StringRef sectionName, int32_t contentType,
+ DefinedAtom::ContentPermissions permissions) {
+ const SectionKey sectionKey(sectionName, permissions);
+ auto sec = _sectionMap.find(sectionKey);
+ if (sec != _sectionMap.end())
+ return sec->second;
+ SectionOrder sectionOrder =
+ getSectionOrder(sectionName, contentType, permissions);
+ AtomSection<ELFT> *newSec =
+ createSection(sectionName, contentType, permissions, sectionOrder);
+ newSec->setOrder(sectionOrder);
+ _sections.push_back(newSec);
+ _sectionMap.insert(std::make_pair(sectionKey, newSec));
+ return newSec;
}
template <class ELFT>
@@ -438,21 +459,8 @@ ErrorOr<const AtomLayout &> DefaultLayou
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 =
- getSection(sectionName, contentType, permissions, section_order);
- section->setOrder(section_order);
- _sections.push_back(section);
- _sectionMap.insert(std::make_pair(sectionKey, section));
- } else {
- section = _sectionMap[sectionKey];
- }
+ AtomSection<ELFT> *section =
+ getSection(sectionName, contentType, permissions);
// Add runtime relocations to the .rela section.
for (const auto &reloc : *definedAtom)
if (_targetInfo.isRuntimeRelocation(*definedAtom, *reloc))
Modified: lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h?rev=175207&r1=175206&r2=175207&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h Thu Feb 14 14:24:38 2013
@@ -302,15 +302,15 @@ template<class ELFT>
void
SectionHeader<ELFT>::updateSection(Section<ELFT> *section) {
Elf_Shdr *shdr = _sectionInfo[section->ordinal()];
- shdr->sh_type = section->type();
- shdr->sh_flags = section->flags();
+ shdr->sh_type = section->getType();
+ shdr->sh_flags = section->getFlags();
shdr->sh_offset = section->fileOffset();
shdr->sh_addr = section->virtualAddr();
shdr->sh_size = section->fileSize();
- shdr->sh_link = section->link();
- shdr->sh_info = section->shinfo();
+ shdr->sh_link = section->getLink();
+ shdr->sh_info = section->getInfo();
shdr->sh_addralign = section->align2();
- shdr->sh_entsize = section->entsize();
+ shdr->sh_entsize = section->getEntSize();
}
template <class ELFT>
Modified: lld/trunk/lib/ReaderWriter/ELF/Layout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Layout.h?rev=175207&r1=175206&r2=175207&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Layout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Layout.h Thu Feb 14 14:24:38 2013
@@ -46,17 +46,14 @@ public:
public:
/// Return the order the section would appear in the output file
- virtual SectionOrder getSectionOrder
- (const StringRef name,
- int32_t contentType,
- int32_t contentPerm) = 0;
+ virtual SectionOrder getSectionOrder(StringRef name, int32_t contentType,
+ int32_t contentPerm) = 0;
/// \brief Append the Atom to the layout and create appropriate sections.
/// \returns A reference to the atom layout or an error. The atom layout will
/// be updated as linking progresses.
virtual ErrorOr<const AtomLayout &> addAtom(const Atom *atom) = 0;
/// find the Atom Address in the current layout
- virtual bool findAtomAddrByName(const StringRef name,
- uint64_t &addr) = 0;
+ virtual bool findAtomAddrByName(StringRef name, uint64_t &addr) = 0;
/// associates a section to a segment
virtual void assignSectionsToSegments() = 0;
/// associates a virtual address to the segment, section, and the atom
Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=175207&r1=175206&r2=175207&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Thu Feb 14 14:24:38 2013
@@ -31,42 +31,122 @@
namespace lld {
namespace elf {
+using namespace llvm::ELF;
-/// \brief A section contains a set of atoms that have similiar properties
-/// The atoms that have similiar properties are merged to form a section
-template<class ELFT>
-class Section : public Chunk<ELFT> {
+/// \brief An ELF section.
+template <class ELFT> class Section : public Chunk<ELFT> {
public:
- // The Kind of section that the object represents
- enum SectionKind {
- K_Default,
- K_Target, // The section is handed over to the target
- K_SymbolTable,
- K_StringTable,
- };
- // Create a section object, the section is set to the default type if the
- // caller doesnot set it
- Section(const ELFTargetInfo &, StringRef sectionName,
- const int32_t contentType, const int32_t contentPermissions,
- const int32_t order, const SectionKind kind = K_Default);
-
- /// return the section kind
- inline SectionKind sectionKind() const {
- 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; }
+ /// \param type the ELF SHT_* type of the section.
+ Section(const ELFTargetInfo &ti, StringRef name,
+ typename Chunk<ELFT>::Kind k = Chunk<ELFT>::K_ELFSection)
+ : Chunk<ELFT>(name, k, ti),
+ _flags(0),
+ _entSize(0),
+ _type(0),
+ _link(0),
+ _info(0),
+ _segmentType(SHT_NULL) {}
+
+ /// \brief Finalize the section contents before writing
+ virtual void finalize() {}
- /// Is the section part of any segment, Target sections must override
- /// this function
+ /// \brief Does this section have an output segment.
virtual bool hasOutputSegment() {
- assert((_sectionKind != K_Target) &&
- "Cannot determine if the targetSection has any output segment");
return false;
}
+ /// \brief Assign file offsets starting at offset.
+ virtual void assignOffsets(uint64_t offset) {}
+
+ /// \brief Assign virtual addresses starting at addr. Addr is modified to be
+ /// the next available virtual address.
+ virtual void assignVirtualAddress(uint64_t &addr) {}
+
+ uint64_t getFlags() const { return _flags; }
+ uint64_t getEntSize() const { return _entSize; }
+ uint32_t getType() const { return _type; }
+ uint32_t getLink() const { return _link; }
+ uint32_t getInfo() const { return _info; }
+ Layout::SegmentType getSegmentType() const { return _segmentType; }
+
+ /// \brief convert the segment type to a String for diagnostics and printing
+ /// purposes
+ StringRef segmentKindToStr() const;
+
+ // TODO: Move this down to AtomSection.
+ virtual bool findAtomAddrByName(StringRef name, uint64_t &addr) {
+ return false;
+ }
+
+ /// \brief Records the segmentType, that this section belongs to
+ void setSegment(const Layout::SegmentType segmentType) {
+ this->_segmentType = segmentType;
+ }
+
+ static bool classof(const Chunk<ELFT> *c) {
+ return c->kind() == Chunk<ELFT>::K_ELFSection ||
+ c->kind() == Chunk<ELFT>::K_AtomSection;
+ }
+
+protected:
+ /// \brief ELF SHF_* flags.
+ uint64_t _flags;
+ /// \brief The size of each entity.
+ uint64_t _entSize;
+ /// \brief ELF SHT_* type.
+ uint32_t _type;
+ /// \brief sh_link field.
+ uint32_t _link;
+ /// \brief the sh_info field.
+ uint32_t _info;
+ /// \brief the output ELF segment type of this section.
+ Layout::SegmentType _segmentType;
+};
+
+/// \brief A section containing atoms.
+template <class ELFT> class AtomSection : public Section<ELFT> {
+public:
+ AtomSection(const ELFTargetInfo &ti, StringRef name, int32_t contentType,
+ int32_t permissions, int32_t order)
+ : Section<ELFT>(ti, name, Chunk<ELFT>::K_AtomSection),
+ _contentType(contentType), _contentPermissions(permissions) {
+ this->setOrder(order);
+ switch (contentType) {
+ case DefinedAtom::typeCode:
+ case DefinedAtom::typeData:
+ case DefinedAtom::typeConstant:
+ case DefinedAtom::typeGOT:
+ case DefinedAtom::typeStub:
+ case DefinedAtom::typeResolver:
+ case DefinedAtom::typeTLVInitialData:
+ this->_type = SHT_PROGBITS;
+ break;
+ case DefinedAtom::typeZeroFill:
+ case DefinedAtom::typeTLVInitialZeroFill:
+ this->_type = SHT_NOBITS;
+ break;
+ }
+
+ switch (permissions) {
+ case DefinedAtom::permR__:
+ this->_flags = SHF_ALLOC;
+ break;
+ case DefinedAtom::permR_X:
+ this->_flags = SHF_ALLOC | SHF_EXECINSTR;
+ break;
+ case DefinedAtom::permRW_:
+ case DefinedAtom::permRW_L:
+ this->_flags = SHF_ALLOC | SHF_WRITE;
+ if (_contentType == DefinedAtom::typeTLVInitialData ||
+ _contentType == DefinedAtom::typeTLVInitialZeroFill)
+ this->_flags |= SHF_TLS;
+ break;
+ case DefinedAtom::permRWX:
+ this->_flags = SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR;
+ break;
+ }
+ }
+
/// Align the offset to the required modulus defined by the atom alignment
uint64_t alignOffset(uint64_t offset, DefinedAtom::Alignment &atomAlign);
@@ -78,7 +158,7 @@ public:
/// \brief Set the virtual address of each Atom in the Section. This
/// routine gets called after the linker fixes up the virtual address
/// of the section
- inline void assignVirtualAddress(uint64_t &addr) {
+ virtual void assignVirtualAddress(uint64_t &addr) {
for (auto &ai : _atoms) {
ai->_virtualAddr = addr + ai->_fileOffset;
}
@@ -86,7 +166,7 @@ public:
/// \brief Set the file offset of each Atom in the section. This routine
/// gets called after the linker fixes up the section offset
- inline void assignOffsets(uint64_t offset) {
+ virtual void assignOffsets(uint64_t offset) {
for (auto &ai : _atoms) {
ai->_fileOffset = offset + ai->_fileOffset;
}
@@ -95,7 +175,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(StringRef name, uint64_t &addr) {
+ virtual bool findAtomAddrByName(StringRef name, uint64_t &addr) {
for (auto ai : _atoms) {
if (ai->_atom->name() == name) {
addr = ai->_virtualAddr;
@@ -106,104 +186,43 @@ public:
}
/// \brief Does the Atom occupy any disk space
- inline bool occupiesNoDiskSpace() const {
+ bool occupiesNoDiskSpace() const {
return _contentType == DefinedAtom::typeZeroFill;
}
/// \brief The permission of the section is the most permissive permission
/// of all atoms that the section contains
- inline void setContentPermissions(int32_t perm) {
+ void setContentPermissions(int32_t perm) {
_contentPermissions = std::max(perm, _contentPermissions);
}
- /// \brief Get the section flags, defined by the permissions of the section
- int64_t flags();
-
- /// \brief Return the section type, the returned value is recorded in the
- /// sh_type field of the Section Header
- int type();
-
- /// \brief convert the segment type to a String for diagnostics
- /// and printing purposes
- StringRef segmentKindToStr() const;
-
/// \brief Return the raw flags, we need this to sort segments
inline int64_t atomflags() const {
return _contentPermissions;
}
- /// \brief Returns the section link field, the returned value is
- /// recorded in the sh_link field of the Section Header
- inline int link() const {
- return _link;
- }
-
- inline void setLink(int32_t link) {
- _link = link;
- }
-
- /// \brief Returns the section entsize field, the returned value is
- /// recorded in the sh_entsize field of the Section Header
- inline int entsize() const {
- return _entSize;
- }
-
- /// \brief Returns the shinfo field, the returned value is
- /// recorded in the sh_info field of the Section Header
- inline int shinfo() const {
- return _shInfo;
- }
-
- /// \brief Records the segmentType, that this section belongs to
- inline void setSegment(const Layout::SegmentType segmentType) {
- _segmentType = segmentType;
- }
-
- /// \brief for LLVM style RTTI information
- static inline bool classof(const Chunk<ELFT> *c) {
- return c->kind() == Chunk<ELFT>::K_ELFSection;
- }
-
- /// \brief Finalize the section contents before writing
- inline void finalize() { }
-
- /// \brief Write the section and the atom contents to the buffer
- void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
-
/// Atom Iterators
typedef typename std::vector<AtomLayout *>::iterator atom_iter;
range<atom_iter> atoms() { return _atoms; }
+ virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+
+ static bool classof(const Chunk<ELFT> *c) {
+ return c->kind() == Chunk<ELFT>::K_AtomSection;
+ }
+
protected:
+ llvm::BumpPtrAllocator _alloc;
int32_t _contentType;
int32_t _contentPermissions;
- SectionKind _sectionKind;
std::vector<AtomLayout *> _atoms;
- Layout::SegmentType _segmentType;
- int64_t _entSize;
- int64_t _shInfo;
- int64_t _link;
- llvm::BumpPtrAllocator _alloc;
};
-// 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, StringRef sectionName,
- const int32_t contentType,
- const int32_t contentPermissions, const int32_t order,
- const SectionKind kind)
- : Chunk<ELFT>(sectionName, Chunk<ELFT>::K_ELFSection, ti),
- _contentType(contentType), _contentPermissions(contentPermissions),
- _sectionKind(kind), _entSize(0), _shInfo(0), _link(0) {
- this->setOrder(order);
-}
-
/// Align the offset to the required modulus defined by the atom alignment
-template<class ELFT>
-uint64_t
-Section<ELFT>::alignOffset(uint64_t offset, DefinedAtom::Alignment &atomAlign) {
+template <class ELFT>
+uint64_t AtomSection<ELFT>::alignOffset(uint64_t offset,
+ DefinedAtom::Alignment &atomAlign) {
uint64_t requiredModulus = atomAlign.modulus;
uint64_t align2 = 1u << atomAlign.powerOf2;
uint64_t currentModulus = (offset % align2);
@@ -221,7 +240,7 @@ Section<ELFT>::alignOffset(uint64_t offs
// contains the atom, the atom file offset, the atom virtual address
// the atom file offset is aligned appropriately as set by the Reader
template <class ELFT>
-const AtomLayout &Section<ELFT>::appendAtom(const Atom *atom) {
+const AtomLayout &AtomSection<ELFT>::appendAtom(const Atom *atom) {
Atom::Definition atomType = atom->definition();
const DefinedAtom *definedAtom = cast<DefinedAtom>(atom);
@@ -235,9 +254,9 @@ const AtomLayout &Section<ELFT>::appendA
switch (atomType) {
case Atom::definitionRegular:
switch(definedAtom->contentType()) {
- case DefinedAtom::typeCode:
- case DefinedAtom::typeData:
- case DefinedAtom::typeConstant:
+ case DefinedAtom::typeCode:
+ case DefinedAtom::typeData:
+ case DefinedAtom::typeConstant:
case DefinedAtom::typeGOT:
case DefinedAtom::typeStub:
case DefinedAtom::typeResolver:
@@ -250,7 +269,7 @@ const AtomLayout &Section<ELFT>::appendA
<< "Adding atom: " << atom->name() << "@"
<< fOffset << "\n");
break;
- case DefinedAtom::typeZeroFill:
+ case DefinedAtom::typeZeroFill:
case DefinedAtom::typeTLVInitialZeroFill:
_atoms.push_back(new (_alloc) AtomLayout(atom, mOffset, 0));
this->_msize = mOffset + definedAtom->size();
@@ -272,73 +291,9 @@ const AtomLayout &Section<ELFT>::appendA
return *_atoms.back();
}
-/// \brief Get the section flags, defined by the permissions of the section
-template<class ELFT>
-int64_t
-Section<ELFT>::flags() {
- switch (_contentPermissions) {
- case DefinedAtom::perm___:
- return 0;
-
- case DefinedAtom::permR__:
- return llvm::ELF::SHF_ALLOC;
-
- case DefinedAtom::permR_X:
- return llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR;
-
- case DefinedAtom::permRW_:
- case DefinedAtom::permRW_L:
- if (_contentType == DefinedAtom::typeTLVInitialData ||
- _contentType == DefinedAtom::typeTLVInitialZeroFill)
- return llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE | llvm::ELF::SHF_TLS;
- return llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE;
-
- case DefinedAtom::permRWX:
- return llvm::ELF::SHF_ALLOC |
- llvm::ELF::SHF_WRITE |
- llvm::ELF::SHF_EXECINSTR;
-
- default:
- break;
- }
- return llvm::ELF::SHF_ALLOC;
-}
-
-/// \brief Return the section type, the returned value is recorded in the
-/// sh_type field of the Section Header
-
-template<class ELFT>
-int
-Section<ELFT>::type() {
- if (_sectionKind == K_SymbolTable)
- return llvm::ELF::SHT_SYMTAB;
-
- switch (_contentType) {
- case DefinedAtom::typeCode:
- case DefinedAtom::typeData:
- case DefinedAtom::typeConstant:
- case DefinedAtom::typeGOT:
- case DefinedAtom::typeStub:
- case DefinedAtom::typeResolver:
- case DefinedAtom::typeTLVInitialData:
- return llvm::ELF::SHT_PROGBITS;
-
- case DefinedAtom::typeZeroFill:
- case DefinedAtom::typeTLVInitialZeroFill:
- return llvm::ELF::SHT_NOBITS;
-
- // Case to handle section types
- // Symtab, String Table ...
- default:
- return _contentType;
- }
-}
-
/// \brief convert the segment type to a String for diagnostics
/// and printing purposes
-template<class ELFT>
-StringRef
-Section<ELFT>::segmentKindToStr() const {
+template <class ELFT> StringRef Section<ELFT>::segmentKindToStr() const {
switch(_segmentType) {
case llvm::ELF::PT_INTERP:
return "INTERP";
@@ -361,7 +316,8 @@ Section<ELFT>::segmentKindToStr() const
/// \brief Write the section and the atom contents to the buffer
template <class ELFT>
-void Section<ELFT>::write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+void AtomSection<ELFT>::write(ELFWriter *writer,
+ llvm::FileOutputBuffer &buffer) {
uint8_t *chunkBuffer = buffer.getBufferStart();
for (auto &ai : _atoms) {
DEBUG_WITH_TYPE("Section",
@@ -464,7 +420,7 @@ private:
StringRef _name;
bool _hasSegment;
uint64_t _ordinal;
- int64_t _flags;
+ uint64_t _flags;
uint64_t _size;
uint64_t _memSize;
uint64_t _fileOffset;
@@ -503,12 +459,12 @@ MergedSections<ELFT>::appendSection(Chun
if (c->align2() > _align2)
_align2 = c->align2();
if (const auto section = dyn_cast<Section<ELFT>>(c)) {
- _link = section->link();
- _shInfo = section->shinfo();
- _entSize = section->entsize();
- _type = section->type();
- if (_flags < section->flags())
- _flags = section->flags();
+ _link = section->getLink();
+ _shInfo = section->getInfo();
+ _entSize = section->getEntSize();
+ _type = section->getType();
+ if (_flags < section->getFlags())
+ _flags = section->getFlags();
}
_kind = c->kind();
_sections.push_back(c);
@@ -520,15 +476,9 @@ class StringTable : public Section<ELFT>
public:
StringTable(const ELFTargetInfo &, const char *str, int32_t order);
- static inline bool classof(const Chunk<ELFT> *c) {
- return c->kind() == Section<ELFT>::K_StringTable;
- }
-
uint64_t addString(StringRef symname);
- void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
-
- inline void finalize() { }
+ virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
private:
std::vector<StringRef> _strings;
@@ -552,14 +502,14 @@ private:
template <class ELFT>
StringTable<ELFT>::StringTable(const ELFTargetInfo &ti, const char *str,
int32_t order)
- : Section<ELFT>(ti, str, llvm::ELF::SHT_STRTAB, DefinedAtom::perm___, order,
- Section<ELFT>::K_StringTable) {
+ : Section<ELFT>(ti, str) {
// the string table has a NULL entry for which
// add an empty string
_strings.push_back("");
this->_fsize = 1;
this->_align2 = 1;
this->setOrder(order);
+ this->_type = SHT_STRTAB;
}
template <class ELFT> uint64_t StringTable<ELFT>::addString(StringRef symname) {
@@ -600,31 +550,23 @@ public:
void addSymbol(const Atom *atom, int32_t sectionIndex, uint64_t addr = 0);
- void finalize();
+ virtual void finalize();
- void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
+ virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
- static inline bool classof(const Chunk<ELFT> *c) {
- return c->kind() == Section<ELFT>::K_SymbolTable;
- }
-
- inline void setStringSection(StringTable<ELFT> *s) {
- _stringSection = s;
- }
+ void setStringSection(StringTable<ELFT> *s) { _stringSection = s; }
private:
StringTable<ELFT> *_stringSection;
std::vector<Elf_Sym*> _symbolTable;
llvm::BumpPtrAllocator _symbolAllocate;
- int64_t _link;
};
/// ELF Symbol Table
template <class ELFT>
SymbolTable<ELFT>::SymbolTable(const ELFTargetInfo &ti, const char *str,
- int32_t order)
- : Section<ELFT>(ti, str, llvm::ELF::SHT_SYMTAB, 0, order,
- Section<ELFT>::K_SymbolTable) {
+ int32_t order)
+ : Section<ELFT>(ti, str) {
this->setOrder(order);
Elf_Sym *symbol = new (_symbolAllocate.Allocate<Elf_Sym>()) Elf_Sym;
memset((void *)symbol, 0, sizeof(Elf_Sym));
@@ -632,13 +574,12 @@ SymbolTable<ELFT>::SymbolTable(const ELF
this->_entSize = sizeof(Elf_Sym);
this->_fsize = sizeof(Elf_Sym);
this->_align2 = sizeof(void *);
+ this->_type = SHT_SYMTAB;
}
-template<class ELFT>
-void
-SymbolTable<ELFT>::addSymbol(const Atom *atom,
- int32_t sectionIndex,
- uint64_t addr) {
+template <class ELFT>
+void SymbolTable<ELFT>::addSymbol(const Atom *atom, int32_t sectionIndex,
+ uint64_t addr) {
Elf_Sym *symbol = new(_symbolAllocate.Allocate<Elf_Sym>()) Elf_Sym;
unsigned char binding = 0, type = 0;
symbol->st_name = _stringSection->addString(atom->name());
@@ -707,9 +648,7 @@ SymbolTable<ELFT>::addSymbol(const Atom
this->_fsize += sizeof(Elf_Sym);
}
-template<class ELFT>
-void
-SymbolTable<ELFT>::finalize() {
+template <class ELFT> void SymbolTable<ELFT>::finalize() {
// sh_info should be one greater than last symbol with STB_LOCAL binding
// we sort the symbol table to keep all local symbols at the beginning
std::stable_sort(_symbolTable.begin(), _symbolTable.end(),
@@ -722,13 +661,13 @@ SymbolTable<ELFT>::finalize() {
break;
shInfo++;
}
- this->_shInfo = shInfo;
- this->setLink(_stringSection->ordinal());
+ this->_info = shInfo;
+ this->_link = _stringSection->ordinal();
}
template <class ELFT>
void SymbolTable<ELFT>::write(ELFWriter *writer,
- llvm::FileOutputBuffer &buffer) {
+ llvm::FileOutputBuffer &buffer) {
uint8_t *chunkBuffer = buffer.getBufferStart();
uint8_t *dest = chunkBuffer + this->fileOffset();
for (auto sti : _symbolTable) {
@@ -742,11 +681,12 @@ public:
typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
RelocationTable(const ELFTargetInfo &ti, StringRef str, int32_t order)
- : Section<ELFT>(ti, str, llvm::ELF::SHT_RELA, DefinedAtom::permR__, order,
- Section<ELFT>::K_Default) {
+ : Section<ELFT>(ti, str) {
this->setOrder(order);
this->_entSize = sizeof(Elf_Rela);
this->_align2 = llvm::alignOf<Elf_Rela>();
+ this->_type = SHT_RELA;
+ this->_flags = SHF_ALLOC;
}
void addRelocation(const DefinedAtom &da, const Reference &r) {
@@ -755,7 +695,7 @@ public:
this->_msize = this->_fsize;
}
- void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
+ virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) {
uint8_t *chunkBuffer = buffer.getBufferStart();
uint8_t *dest = chunkBuffer + this->fileOffset();
for (const auto &rel : _relocs) {
Modified: lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h?rev=175207&r1=175206&r2=175207&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h Thu Feb 14 14:24:38 2013
@@ -224,7 +224,7 @@ protected:
std::vector<Chunk<ELFT> *> _sections;
std::vector<SegmentSlice<ELFT> *> _segmentSlices;
Layout::SegmentType _segmentType;
- int64_t _flags;
+ uint64_t _flags;
int64_t _atomflags;
llvm::BumpPtrAllocator _segmentAllocate;
};
@@ -238,21 +238,36 @@ Segment<ELFT>::Segment(const ELFTargetIn
this->_fsize = 0;
}
-template<class ELFT>
-void
-Segment<ELFT>::append(Section<ELFT> *section) {
+// This function actually is used, but not in all instantiations of Segment.
+LLVM_ATTRIBUTE_UNUSED
+static DefinedAtom::ContentPermissions toAtomPerms(uint64_t flags) {
+ switch (flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR)) {
+ case SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR:
+ return DefinedAtom::permRWX;
+ case SHF_ALLOC | SHF_EXECINSTR:
+ return DefinedAtom::permR_X;
+ case SHF_ALLOC:
+ return DefinedAtom::permR__;
+ case SHF_ALLOC | SHF_WRITE:
+ return DefinedAtom::permRW_;
+ default:
+ return DefinedAtom::permUnknown;
+ }
+}
+
+template <class ELFT> void Segment<ELFT>::append(Section<ELFT> *section) {
_sections.push_back(section);
- if (_flags < section->flags())
- _flags = section->flags();
- if (_atomflags < section->atomflags())
- _atomflags = section->atomflags();
+ if (_flags < section->getFlags())
+ _flags = section->getFlags();
+ if (_atomflags < toAtomPerms(_flags))
+ _atomflags = toAtomPerms(_flags);
if (this->_align2 < section->align2())
this->_align2 = section->align2();
}
template <class ELFT>
bool Segment<ELFT>::compareSegments(Segment<ELFT> *sega, Segment<ELFT> *segb) {
- return (sega->atomflags() < segb->atomflags());
+ return sega->atomflags() < segb->atomflags();
}
template <class ELFT> void Segment<ELFT>::assignOffsets(uint64_t startOffset) {
Modified: lld/trunk/lib/ReaderWriter/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Writer.cpp?rev=175207&r1=175206&r2=175207&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Writer.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Writer.cpp Thu Feb 14 14:24:38 2013
@@ -92,7 +92,7 @@ void ExecutableWriter<ELFT>::buildChunks
template<class ELFT>
void ExecutableWriter<ELFT>::buildSymbolTable () {
for (auto sec : _layout->sections())
- if (auto section = dyn_cast<Section<ELFT>>(sec))
+ if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
for (const auto &atom : section->atoms())
_symtab->addSymbol(atom->_atom, section->ordinal(), atom->_virtualAddr);
}
@@ -111,7 +111,7 @@ ExecutableWriter<ELFT>::addAbsoluteUndef
template<class ELFT>
void ExecutableWriter<ELFT>::buildAtomToAddressMap () {
for (auto sec : _layout->sections())
- if (auto section = dyn_cast<Section<ELFT>>(sec))
+ if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
for (const auto &atom : section->atoms())
_atomToAddressMap[atom->_atom] = atom->_virtualAddr;
// build the atomToAddressMap that contains absolute symbols too
@@ -122,7 +122,8 @@ void ExecutableWriter<ELFT>::buildAtomTo
template<class ELFT>
void ExecutableWriter<ELFT>::buildSectionHeaderTable() {
for (auto mergedSec : _layout->mergedSections()) {
- if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
+ if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection &&
+ mergedSec->kind() != Chunk<ELFT>::K_AtomSection)
continue;
if (mergedSec->hasSegment())
_shdrtab->appendSection(mergedSec);
@@ -132,7 +133,8 @@ void ExecutableWriter<ELFT>::buildSectio
template<class ELFT>
void ExecutableWriter<ELFT>::assignSectionsWithNoSegments() {
for (auto mergedSec : _layout->mergedSections()) {
- if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection)
+ if (mergedSec->kind() != Chunk<ELFT>::K_ELFSection &&
+ mergedSec->kind() != Chunk<ELFT>::K_AtomSection)
continue;
if (!mergedSec->hasSegment())
_shdrtab->appendSection(mergedSec);
More information about the llvm-commits
mailing list