[lld] r175904 - sort quickdata for the hexagon target
Shankar Easwaran
shankare at codeaurora.org
Fri Feb 22 10:01:08 PST 2013
Author: shankare
Date: Fri Feb 22 12:01:08 2013
New Revision: 175904
URL: http://llvm.org/viewvc/llvm-project?rev=175904&view=rev
Log:
sort quickdata for the hexagon target
Added:
lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h
lld/trunk/test/elf/Inputs/quickdata-sort-test.o.elf-hexagon (with props)
lld/trunk/test/elf/hexagon-quickdata-sort.test
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/Hexagon/HexagonTargetHandler.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=175904&r1=175903&r2=175904&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Chunk.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Chunk.h Fri Feb 22 12:01:08 2013
@@ -69,9 +69,11 @@ public:
uint64_t virtualAddr() const { return _start; }
// Does the chunk occupy memory during execution ?
uint64_t memSize() const { return _msize; }
- void setMemSize(uint64_t msize) { _msize = msize; }
+ void setMemSize(uint64_t msize) { _msize = msize; }
// Writer the chunk
virtual void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) = 0;
+ // Finalize the chunk before assigning offsets/virtual addresses
+ virtual void doPreFlight() = 0;
// Finalize the chunk before writing
virtual void finalize() = 0;
Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=175904&r1=175903&r2=175904&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h Fri Feb 22 12:01:08 2013
@@ -208,6 +208,11 @@ public:
si->finalize();
}
+ inline void doPreFlight() {
+ for (auto &si : _sections)
+ si->doPreFlight();
+ }
+
inline bool findAtomAddrByName(StringRef name, uint64_t &addr) {
for (auto sec : _sections)
if (auto section = dyn_cast<Section<ELFT> >(sec))
Modified: lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h?rev=175904&r1=175903&r2=175904&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/HeaderChunks.h Fri Feb 22 12:01:08 2013
@@ -52,7 +52,9 @@ public:
void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
- void finalize() { }
+ virtual void doPreFlight() {}
+
+ void finalize() {}
private:
Elf_Ehdr _eh;
@@ -145,11 +147,11 @@ public:
return _ph.end();
}
- void finalize() { }
+ virtual void doPreFlight() {}
- int64_t entsize() {
- return sizeof(Elf_Phdr);
- }
+ void finalize() {}
+
+ int64_t entsize() { return sizeof(Elf_Phdr); }
int64_t numHeaders() {
return _ph.size();
@@ -249,12 +251,12 @@ public:
}
void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer);
-
- void finalize() { }
-
- inline uint16_t fileSize() {
- return sizeof(Elf_Shdr) * _sectionInfo.size();
- }
+
+ virtual void doPreFlight() {}
+
+ void finalize() {}
+
+ inline uint16_t fileSize() { return sizeof(Elf_Shdr) * _sectionInfo.size(); }
inline int64_t entsize() {
return sizeof(Elf_Shdr);
Added: lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h?rev=175904&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h Fri Feb 22 12:01:08 2013
@@ -0,0 +1,76 @@
+//===- lib/ReaderWriter/ELF/Hexagon/HexagonSectionChunks.h-----------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "HexagonTargetHandler.h"
+
+namespace lld {
+namespace elf {
+typedef llvm::object::ELFType<llvm::support::little, 4, false> HexagonELFType;
+template <typename ELFT> class HexagonTargetLayout;
+class HexagonTargetInfo;
+
+/// \brief Handle Hexagon SData section
+template <class HexagonELFType>
+class SDataSection : public AtomSection<HexagonELFType> {
+public:
+ SDataSection(const HexagonTargetInfo &hti)
+ : AtomSection<HexagonELFType>(
+ hti, ".sdata", DefinedAtom::typeDataFast, 0,
+ HexagonTargetLayout<HexagonELFType>::ORDER_SDATA) {
+ this->_type = SHT_PROGBITS;
+ this->_flags = SHF_ALLOC | SHF_WRITE;
+ }
+
+ /// \brief Finalize the section contents before writing
+ virtual void doPreFlight();
+
+ /// \brief Does this section have an output segment.
+ virtual bool hasOutputSegment() { return true; }
+
+ const AtomLayout &appendAtom(const Atom *atom) {
+ const DefinedAtom *definedAtom = cast<DefinedAtom>(atom);
+ DefinedAtom::Alignment atomAlign = definedAtom->alignment();
+ uint64_t align2 = 1u << atomAlign.powerOf2;
+ this->_atoms.push_back(new (this->_alloc) AtomLayout(atom, 0, 0));
+ // Set the section alignment to the largest alignment
+ // std::max doesnot support uint64_t
+ if (this->_align2 < align2)
+ this->_align2 = align2;
+ return *(this->_atoms.back());
+ }
+
+}; // SDataSection
+
+template <class HexagonELFType>
+void SDataSection<HexagonELFType>::doPreFlight() {
+ // sort the atoms on the alignments they have been set
+ std::stable_sort(this->_atoms.begin(), this->_atoms.end(),
+ [](const AtomLayout * A, const AtomLayout * B) {
+ const DefinedAtom *definedAtomA = cast<DefinedAtom>(A->_atom);
+ const DefinedAtom *definedAtomB = cast<DefinedAtom>(B->_atom);
+ int64_t align2A = 1 << definedAtomA->alignment().powerOf2;
+ int64_t align2B = 1 << definedAtomB->alignment().powerOf2;
+ return align2A < align2B;
+ });
+
+ // Set the fileOffset, and the appropriate size of the section
+ for (auto &ai : this->_atoms) {
+ const DefinedAtom *definedAtom = cast<DefinedAtom>(ai->_atom);
+ DefinedAtom::Alignment atomAlign = definedAtom->alignment();
+ uint64_t fOffset = this->alignOffset(this->fileSize(), atomAlign);
+ uint64_t mOffset = this->alignOffset(this->memSize(), atomAlign);
+ ai->_fileOffset = fOffset;
+ this->_fsize = fOffset + definedAtom->size();
+ this->_msize = mOffset + definedAtom->size();
+ }
+} // finalize
+
+} // elf
+} // lld
+
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=175904&r1=175903&r2=175904&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h Fri Feb 22 12:01:08 2013
@@ -13,6 +13,7 @@
#include "DefaultTargetHandler.h"
#include "ExecutableAtoms.h"
#include "HexagonRelocationHandler.h"
+#include "HexagonSectionChunks.h"
#include "TargetLayout.h"
namespace lld {
@@ -75,6 +76,64 @@ public:
}
};
+/// \brief TargetLayout for Hexagon
+template <class HexagonELFType>
+class HexagonTargetLayout LLVM_FINAL : public TargetLayout<HexagonELFType> {
+
+public:
+ enum HexagonSectionOrder {
+ ORDER_SDATA = 205
+ };
+
+ HexagonTargetLayout(const HexagonTargetInfo &hti)
+ : TargetLayout<HexagonELFType>(hti), _sdataSection(nullptr) {
+ _sdataSection = new (_alloc) SDataSection<HexagonELFType>(hti);
+ }
+
+ /// \brief Return the section order for a input section
+ virtual Layout::SectionOrder getSectionOrder(
+ StringRef name, int32_t contentType, int32_t contentPermissions) {
+ if (contentType == DefinedAtom::typeDataFast)
+ return ORDER_SDATA;
+
+ return DefaultLayout<HexagonELFType>::getSectionOrder(name, contentType,
+ contentPermissions);
+ }
+
+ /// \brief This maps the input sections to the output section names
+ virtual StringRef getSectionName(StringRef name, const int32_t contentType,
+ const int32_t contentPermissions) {
+ if (contentType == DefinedAtom::typeDataFast)
+ return ".sdata";
+ return DefaultLayout<HexagonELFType>::getSectionName(name, contentType,
+ contentPermissions);
+ }
+
+ /// \brief Gets or creates a section.
+ virtual AtomSection<HexagonELFType> *
+ createSection(StringRef name, int32_t contentType,
+ DefinedAtom::ContentPermissions contentPermissions,
+ Layout::SectionOrder sectionOrder) {
+ if (contentType == DefinedAtom::typeDataFast)
+ return _sdataSection;
+ return DefaultLayout<HexagonELFType>::createSection(
+ name, contentType, contentPermissions, sectionOrder);
+ }
+
+ /// \brief get the segment type for the section thats defined by the target
+ virtual Layout::SegmentType
+ getSegmentType(Section<HexagonELFType> *section) const {
+ if (section->order() == ORDER_SDATA)
+ return PT_LOAD;
+
+ return DefaultLayout<HexagonELFType>::getSegmentType(section);
+ }
+
+private:
+ llvm::BumpPtrAllocator _alloc;
+ SDataSection<HexagonELFType> *_sdataSection;
+};
+
/// \brief TargetHandler for Hexagon
class HexagonTargetHandler LLVM_FINAL :
public DefaultTargetHandler<HexagonELFType> {
@@ -95,7 +154,7 @@ public:
private:
HexagonTargetRelocationHandler _relocationHandler;
- TargetLayout<HexagonELFType> _targetLayout;
+ HexagonTargetLayout<HexagonELFType> _targetLayout;
HexagonTargetAtomHandler<HexagonELFType> _targetAtomHandler;
};
} // end namespace elf
Modified: lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h?rev=175904&r1=175903&r2=175904&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SectionChunks.h Fri Feb 22 12:01:08 2013
@@ -39,13 +39,12 @@ public:
/// \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) {}
+ : Chunk<ELFT>(name, k, ti), _flags(0), _entSize(0), _type(0), _link(0),
+ _info(0), _segmentType(SHT_NULL) {}
+
+ /// \brief Modify the section contents before assigning virtual addresses
+ // or assigning file offsets
+ virtual void doPreFlight() {}
/// \brief Finalize the section contents before writing
virtual void finalize() {}
Modified: lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h?rev=175904&r1=175903&r2=175904&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/SegmentChunks.h Fri Feb 22 12:01:08 2013
@@ -159,8 +159,11 @@ public:
_sections.insert(_sections.begin(), c);
}
+ // Finalize the segment before assigning File Offsets / Virtual addresses
+ inline void doPreFlight() {}
+
// Finalize the segment, before we want to write to the output file
- inline void finalize() { }
+ inline void finalize() {}
// For LLVM RTTI
static inline bool classof(const Chunk<ELFT> *c) {
Modified: lld/trunk/lib/ReaderWriter/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Writer.cpp?rev=175904&r1=175903&r2=175904&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Writer.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Writer.cpp Fri Feb 22 12:01:08 2013
@@ -231,11 +231,14 @@ void ExecutableWriter<ELFT>::finalizeDef
(*endAtomIter)->_virtualAddr = (*phe)->p_vaddr + (*phe)->p_memsz;
}
-template<class ELFT>
-error_code
-ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) {
+template <class ELFT>
+error_code ExecutableWriter<ELFT>::writeFile(const File &file, StringRef path) {
buildChunks(file);
+ // Call the preFlight callbacks to modify the sections and the atoms
+ // contained in them, in anyway the targets may want
+ _layout->doPreFlight();
+
// Create the default sections like the symbol table, string table, and the
// section string table
createDefaultSections();
Added: lld/trunk/test/elf/Inputs/quickdata-sort-test.o.elf-hexagon
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/quickdata-sort-test.o.elf-hexagon?rev=175904&view=auto
==============================================================================
Binary file - no diff available.
Propchange: lld/trunk/test/elf/Inputs/quickdata-sort-test.o.elf-hexagon
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: lld/trunk/test/elf/hexagon-quickdata-sort.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/hexagon-quickdata-sort.test?rev=175904&view=auto
==============================================================================
--- lld/trunk/test/elf/hexagon-quickdata-sort.test (added)
+++ lld/trunk/test/elf/hexagon-quickdata-sort.test Fri Feb 22 12:01:08 2013
@@ -0,0 +1,12 @@
+RUN: lld-core -arch hexagon -reader ELF %p/Inputs/quickdata-sort-test.o.elf-hexagon -writer ELF -o %t1
+RUN: llvm-nm -n %t1 | FileCheck %s -check-prefix=quickdataSort
+
+quickdataSort: 00002000 D A1
+quickdataSort: 00002001 D AA1
+quickdataSort: 00002002 D B1
+quickdataSort: 00002004 D BB1
+quickdataSort: 00002008 D C1
+quickdataSort: 0000200c D CC1
+quickdataSort: 00002010 D D1
+quickdataSort: 00002018 D DD1
+
More information about the llvm-commits
mailing list