<div dir="ltr"><div class="gmail_default" style>Tests?</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Jan 4, 2013 at 1:09 PM, Michael J. Spencer <span dir="ltr"><<a href="mailto:bigcheesegs@gmail.com" target="_blank">bigcheesegs@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: mspencer<br>
Date: Fri Jan 4 15:09:21 2013<br>
New Revision: 171526<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=171526&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=171526&view=rev</a><br>
Log:<br>
[ELF] Handle misaligned ELF files properly.<br>
<br>
Modified:<br>
lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h<br>
lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp<br>
lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h?rev=171526&r1=171525&r2=171526&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h?rev=171526&r1=171525&r2=171526&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/ELF/AtomsELF.h Fri Jan 4 15:09:21 2013<br>
@@ -8,12 +8,14 @@<br>
namespace lld {<br>
/// \brief Relocation References: Defined Atoms may contain references that will<br>
/// need to be patched before the executable is written.<br>
-template <llvm::support::endianness target_endianness, bool is64Bits><br>
+template<llvm::support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
class ELFReference final : public Reference {<br>
typedef llvm::object::Elf_Rel_Impl<br>
- <target_endianness, is64Bits, false> Elf_Rel;<br>
+ <target_endianness, max_align, is64Bits, false> Elf_Rel;<br>
typedef llvm::object::Elf_Rel_Impl<br>
- <target_endianness, is64Bits, true> Elf_Rela;<br>
+ <target_endianness, max_align, is64Bits, true> Elf_Rela;<br>
public:<br>
<br>
ELFReference(const Elf_Rela *rela, uint64_t offset, const Atom *target)<br>
@@ -73,9 +75,12 @@<br>
/// \brief These atoms store symbols that are fixed to a particular address.<br>
/// This atom has no content its address will be used by the writer to fixup<br>
/// references that point to it.<br>
-template<llvm::support::endianness target_endianness, bool is64Bits><br>
+template<llvm::support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
class ELFAbsoluteAtom final : public AbsoluteAtom {<br>
- typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;<br>
+ typedef llvm::object::Elf_Sym_Impl<target_endianness, max_align, is64Bits><br>
+ Elf_Sym;<br>
<br>
public:<br>
ELFAbsoluteAtom(const File &file,<br>
@@ -118,9 +123,12 @@<br>
<br>
/// \brief ELFUndefinedAtom: These atoms store undefined symbols and are place<br>
/// holders that will be replaced by defined atoms later in the linking process.<br>
-template<llvm::support::endianness target_endianness, bool is64Bits><br>
+template<llvm::support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
class ELFUndefinedAtom final: public UndefinedAtom {<br>
- typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;<br>
+ typedef llvm::object::Elf_Sym_Impl<target_endianness, max_align, is64Bits><br>
+ Elf_Sym;<br>
<br>
public:<br>
ELFUndefinedAtom(const File &file,<br>
@@ -157,10 +165,14 @@<br>
<br>
/// \brief This atom stores defined symbols and will contain either data or<br>
/// code.<br>
-template<llvm::support::endianness target_endianness, bool is64Bits><br>
+template<llvm::support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
class ELFDefinedAtom final: public DefinedAtom {<br>
- typedef llvm::object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;<br>
- typedef llvm::object::Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;<br>
+ typedef llvm::object::Elf_Sym_Impl<target_endianness, max_align, is64Bits><br>
+ Elf_Sym;<br>
+ typedef llvm::object::Elf_Shdr_Impl<target_endianness, max_align, is64Bits><br>
+ Elf_Shdr;<br>
<br>
public:<br>
ELFDefinedAtom(const File &file,<br>
@@ -171,8 +183,8 @@<br>
llvm::ArrayRef<uint8_t> contentData,<br>
unsigned int referenceStart,<br>
unsigned int referenceEnd,<br>
- std::vector<ELFReference<br>
- <target_endianness, is64Bits> *> &referenceList)<br>
+ std::vector<ELFReference<target_endianness,<br>
+ max_align, is64Bits>*> &referenceList)<br>
<br>
: _owningFile(file)<br>
, _symbolName(symbolName)<br>
@@ -236,7 +248,6 @@<br>
}<br>
<br>
virtual ContentType contentType() const {<br>
-<br>
ContentType ret = typeUnknown;<br>
uint64_t flags = _section->sh_flags;<br>
<br>
@@ -284,7 +295,7 @@<br>
|| _symbol->st_shndx == llvm::ELF::SHN_COMMON) {<br>
return Alignment(llvm::Log2_64(_symbol->st_value));<br>
}<br>
- return Alignment(llvm::Log2_64(_section->sh_addralign),<br>
+ return Alignment(llvm::Log2_64(_section->sh_addralign),<br>
_symbol->st_value % _section->sh_addralign);<br>
}<br>
<br>
@@ -298,7 +309,7 @@<br>
<br>
virtual llvm::StringRef customSectionName() const {<br>
if ((contentType() == typeZeroFill) ||<br>
- (_symbol->st_shndx == llvm::ELF::SHN_COMMON))<br>
+ (_symbol->st_shndx == llvm::ELF::SHN_COMMON))<br>
return ".bss";<br>
return _sectionName;<br>
}<br>
@@ -337,7 +348,7 @@<br>
return permR__;<br>
<br>
default:<br>
- if (flags & llvm::ELF::SHF_WRITE)<br>
+ if (flags & llvm::ELF::SHF_WRITE)<br>
return permRW_;<br>
return permR__;<br>
}<br>
@@ -403,7 +414,8 @@<br>
uint64_t _ordinal;<br>
unsigned int _referenceStartIndex;<br>
unsigned int _referenceEndIndex;<br>
- std::vector<ELFReference<target_endianness, is64Bits> *> &_referenceList;<br>
+ std::vector<ELFReference<target_endianness, max_align, is64Bits>*> &<br>
+ _referenceList;<br>
};<br>
} // namespace lld<br>
#endif<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp?rev=171526&r1=171525&r2=171526&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp?rev=171526&r1=171525&r2=171526&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/ELF/ReaderELF.cpp Fri Jan 4 15:09:21 2013<br>
@@ -41,37 +41,33 @@<br>
#include <vector><br>
<br>
using namespace lld;<br>
-using llvm::object::Elf_Sym_Impl;<br>
using llvm::support::endianness;<br>
+using namespace llvm::object;<br>
<br>
namespace {<br>
// \brief Read a binary, find out based on the symbol table contents what kind<br>
// of symbol it is and create corresponding atoms for it<br>
-template<endianness target_endianness, bool is64Bits><br>
+template<endianness target_endianness, std::size_t max_align, bool is64Bits><br>
class FileELF: public File {<br>
- typedef llvm::object::Elf_Sym_Impl<br>
- <target_endianness, is64Bits> Elf_Sym;<br>
- typedef llvm::object::Elf_Shdr_Impl<br>
- <target_endianness, is64Bits> Elf_Shdr;<br>
- typedef llvm::object::Elf_Rel_Impl<br>
- <target_endianness, is64Bits, false> Elf_Rel;<br>
- typedef llvm::object::Elf_Rel_Impl<br>
- <target_endianness, is64Bits, true> Elf_Rela;<br>
+ typedef Elf_Sym_Impl<target_endianness, max_align, is64Bits> Elf_Sym;<br>
+ typedef Elf_Shdr_Impl<target_endianness, max_align, is64Bits> Elf_Shdr;<br>
+ typedef Elf_Rel_Impl<target_endianness, max_align, is64Bits, false> Elf_Rel;<br>
+ typedef Elf_Rel_Impl<target_endianness, max_align, is64Bits, true> Elf_Rela;<br>
<br>
public:<br>
FileELF(std::unique_ptr<llvm::MemoryBuffer> MB, llvm::error_code &EC)<br>
: File(MB->getBufferIdentifier()) {<br>
- llvm::OwningPtr<llvm::object::Binary> binaryFile;<br>
- EC = llvm::object::createBinary(MB.release(), binaryFile);<br>
+ llvm::OwningPtr<Binary> binaryFile;<br>
+ EC = createBinary(MB.release(), binaryFile);<br>
if (EC)<br>
return;<br>
<br>
// Point Obj to correct class and bitwidth ELF object<br>
- _objFile.reset(llvm::dyn_cast<llvm::object::ELFObjectFile<target_endianness,<br>
+ _objFile.reset(llvm::dyn_cast<ELFObjectFile<target_endianness, max_align,<br>
is64Bits> >(binaryFile.get()));<br>
<br>
if (!_objFile) {<br>
- EC = make_error_code(llvm::object::object_error::invalid_file_type);<br>
+ EC = make_error_code(object_error::invalid_file_type);<br>
return;<br>
}<br>
<br>
@@ -82,8 +78,8 @@<br>
// Handle: SHT_REL and SHT_RELA sections:<br>
// Increment over the sections, when REL/RELA section types are found add<br>
// the contents to the RelocationReferences map.<br>
- llvm::object::section_iterator sit(_objFile->begin_sections());<br>
- llvm::object::section_iterator sie(_objFile->end_sections());<br>
+ section_iterator sit(_objFile->begin_sections());<br>
+ section_iterator sie(_objFile->end_sections());<br>
for (; sit != sie; sit.increment(EC)) {<br>
if (EC)<br>
return;<br>
@@ -127,8 +123,8 @@<br>
<br>
// Increment over all the symbols collecting atoms and symbol names for<br>
// later use.<br>
- llvm::object::symbol_iterator it(_objFile->begin_symbols());<br>
- llvm::object::symbol_iterator ie(_objFile->end_symbols());<br>
+ symbol_iterator it(_objFile->begin_symbols());<br>
+ symbol_iterator ie(_objFile->end_symbols());<br>
<br>
for (; it != ie; it.increment(EC)) {<br>
if (EC)<br>
@@ -146,19 +142,19 @@<br>
<br>
if (symbol->st_shndx == llvm::ELF::SHN_ABS) {<br>
// Create an absolute atom.<br>
- auto *newAtom = new (_readerStorage.Allocate<br>
- <ELFAbsoluteAtom<target_endianness, is64Bits> > ())<br>
- ELFAbsoluteAtom<target_endianness, is64Bits><br>
- (*this, symbolName, symbol, symbol->st_value);<br>
+ auto *newAtom = new (_readerStorage.Allocate<<br>
+ ELFAbsoluteAtom<target_endianness, max_align, is64Bits> > ())<br>
+ ELFAbsoluteAtom<target_endianness, max_align, is64Bits>(<br>
+ *this, symbolName, symbol, symbol->st_value);<br>
<br>
_absoluteAtoms._atoms.push_back(newAtom);<br>
_symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));<br>
} else if (symbol->st_shndx == llvm::ELF::SHN_UNDEF) {<br>
// Create an undefined atom.<br>
- auto *newAtom = new (_readerStorage.Allocate<br>
- <ELFUndefinedAtom<target_endianness, is64Bits> > ())<br>
- ELFUndefinedAtom<target_endianness, is64Bits><br>
- (*this, symbolName, symbol);<br>
+ auto *newAtom = new (_readerStorage.Allocate<<br>
+ ELFUndefinedAtom<target_endianness, max_align, is64Bits> > ())<br>
+ ELFUndefinedAtom<target_endianness, max_align, is64Bits>(<br>
+ *this, symbolName, symbol);<br>
<br>
_undefinedAtoms._atoms.push_back(newAtom);<br>
_symbolToAtomMapping.insert(std::make_pair(symbol, newAtom));<br>
@@ -176,7 +172,7 @@<br>
sectionSymbols[section].push_back(symbol);<br>
} else {<br>
llvm::errs() << "Unable to create atom for: " << symbolName << "\n";<br>
- EC = llvm::object::object_error::parse_failed;<br>
+ EC = object_error::parse_failed;<br>
return;<br>
}<br>
}<br>
@@ -233,10 +229,10 @@<br>
for (auto &rai : _relocationAddendRefences[sectionName]) {<br>
if ((rai->r_offset >= (*si)->st_value) &&<br>
(rai->r_offset < (*si)->st_value+contentSize)) {<br>
- auto *ERef = new (_readerStorage.Allocate<br>
- <ELFReference<target_endianness, is64Bits> > ())<br>
- ELFReference<target_endianness, is64Bits> (<br>
- rai, rai->r_offset-(*si)->st_value, nullptr);<br>
+ auto *ERef = new (_readerStorage.Allocate<<br>
+ ELFReference<target_endianness, max_align, is64Bits> > ())<br>
+ ELFReference<target_endianness, max_align, is64Bits> (<br>
+ rai, rai->r_offset-(*si)->st_value, nullptr);<br>
<br>
_references.push_back(ERef);<br>
}<br>
@@ -246,22 +242,21 @@<br>
for (auto &ri : _relocationReferences[sectionName]) {<br>
if (((ri)->r_offset >= (*si)->st_value) &&<br>
((ri)->r_offset < (*si)->st_value+contentSize)) {<br>
- auto *ERef = new (_readerStorage.Allocate<br>
- <ELFReference<target_endianness, is64Bits> > ())<br>
- ELFReference<target_endianness, is64Bits> (<br>
- (ri), (ri)->r_offset-(*si)->st_value, nullptr);<br>
+ auto *ERef = new (_readerStorage.Allocate<<br>
+ ELFReference<target_endianness, max_align, is64Bits> > ())<br>
+ ELFReference<target_endianness, max_align, is64Bits> (<br>
+ (ri), (ri)->r_offset-(*si)->st_value, nullptr);<br>
<br>
_references.push_back(ERef);<br>
}<br>
}<br>
<br>
// Create the DefinedAtom and add it to the list of DefinedAtoms.<br>
- auto *newAtom = new (_readerStorage.Allocate<br>
- <ELFDefinedAtom<target_endianness, is64Bits> > ())<br>
- ELFDefinedAtom<target_endianness, is64Bits><br>
- (*this, symbolName, sectionName,<br>
- *si, i.first, symbolData,<br>
- referenceStart, _references.size(), _references);<br>
+ auto *newAtom = new (_readerStorage.Allocate<<br>
+ ELFDefinedAtom<target_endianness, max_align, is64Bits> > ())<br>
+ ELFDefinedAtom<target_endianness, max_align, is64Bits>(<br>
+ *this, symbolName, sectionName, *si, i.first, symbolData,<br>
+ referenceStart, _references.size(), _references);<br>
<br>
_definedAtoms._atoms.push_back(newAtom);<br>
_symbolToAtomMapping.insert(std::make_pair((*si), newAtom));<br>
@@ -301,7 +296,7 @@<br>
}<br>
<br>
private:<br>
- std::unique_ptr<llvm::object::ELFObjectFile<target_endianness, is64Bits> ><br>
+ std::unique_ptr<ELFObjectFile<target_endianness, max_align, is64Bits> ><br>
_objFile;<br>
atom_collection_vector<DefinedAtom> _definedAtoms;<br>
atom_collection_vector<UndefinedAtom> _undefinedAtoms;<br>
@@ -318,7 +313,8 @@<br>
std::map<llvm::StringRef, std::vector<const Elf_Rel *> ><br>
_relocationReferences;<br>
<br>
- std::vector<ELFReference<target_endianness, is64Bits> *> _references;<br>
+ std::vector<ELFReference<target_endianness, max_align, is64Bits> *><br>
+ _references;<br>
llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;<br>
<br>
llvm::BumpPtrAllocator _readerStorage;<br>
@@ -344,24 +340,56 @@<br>
llvm::sys::LLVMFileType fileType =<br>
llvm::sys::IdentifyFileType(mb->getBufferStart(),<br>
static_cast<unsigned>(mb->getBufferSize()));<br>
+<br>
+ std::size_t MaxAlignment =<br>
+ 1ULL << llvm::CountTrailingZeros_64(uintptr_t(mb->getBufferStart()));<br>
+<br>
switch (fileType) {<br>
case llvm::sys::ELF_Relocatable_FileType:<br>
- Ident = llvm::object::getElfArchType(&*mb);<br>
+ Ident = getElfArchType(&*mb);<br>
// Instantiate the correct FileELF template instance based on the Ident<br>
// pair. Once the File is created we push the file to the vector of files<br>
// already created during parser's life.<br>
if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second<br>
== llvm::ELF::ELFDATA2LSB) {<br>
- f.reset(new FileELF<llvm::support::little, false>(std::move(mb), ec));<br>
+ if (MaxAlignment >= 4)<br>
+ f.reset(<br>
+ new FileELF<llvm::support::little, 4, false>(std::move(mb), ec));<br>
+ else if (MaxAlignment >= 2)<br>
+ f.reset(<br>
+ new FileELF<llvm::support::little, 2, false>(std::move(mb), ec));<br>
+ else<br>
+ llvm_unreachable("Invalid alignment for ELF file!");<br>
} else if (Ident.first == llvm::ELF::ELFCLASS32 && Ident.second<br>
== llvm::ELF::ELFDATA2MSB) {<br>
- f.reset(new FileELF<llvm::support::big, false> (std::move(mb), ec));<br>
+ if (MaxAlignment >= 4)<br>
+ f.reset(<br>
+ new FileELF<llvm::support::big, 4, false>(std::move(mb), ec));<br>
+ else if (MaxAlignment >= 2)<br>
+ f.reset(<br>
+ new FileELF<llvm::support::big, 2, false>(std::move(mb), ec));<br>
+ else<br>
+ llvm_unreachable("Invalid alignment for ELF file!");<br>
} else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second<br>
== llvm::ELF::ELFDATA2MSB) {<br>
- f.reset(new FileELF<llvm::support::big, true> (std::move(mb), ec));<br>
+ if (MaxAlignment >= 8)<br>
+ f.reset(<br>
+ new FileELF<llvm::support::big, 8, true>(std::move(mb), ec));<br>
+ else if (MaxAlignment >= 2)<br>
+ f.reset(<br>
+ new FileELF<llvm::support::big, 2, true>(std::move(mb), ec));<br>
+ else<br>
+ llvm_unreachable("Invalid alignment for ELF file!");<br>
} else if (Ident.first == llvm::ELF::ELFCLASS64 && Ident.second<br>
== llvm::ELF::ELFDATA2LSB) {<br>
- f.reset(new FileELF<llvm::support::little, true> (std::move(mb), ec));<br>
+ if (MaxAlignment >= 8)<br>
+ f.reset(<br>
+ new FileELF<llvm::support::little, 8, true>(std::move(mb), ec));<br>
+ else if (MaxAlignment >= 2)<br>
+ f.reset(<br>
+ new FileELF<llvm::support::little, 2, true>(std::move(mb), ec));<br>
+ else<br>
+ llvm_unreachable("Invalid alignment for ELF file!");<br>
}<br>
if (!ec)<br>
result.push_back(std::move(f));<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp?rev=171526&r1=171525&r2=171526&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp?rev=171526&r1=171525&r2=171526&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/ELF/WriterELF.cpp Fri Jan 4 15:09:21 2013<br>
@@ -45,33 +45,36 @@<br>
using namespace llvm::object;<br>
namespace lld {<br>
namespace elf {<br>
-<br>
-template<support::endianness target_endianness, bool is64Bits><br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
class ELFExecutableWriter;<br>
<br>
/// \brief The ELFWriter class is a base class for the linker to write<br>
/// various kinds of ELF files.<br>
class ELFWriter : public Writer {<br>
- public:<br>
- ELFWriter() { }<br>
+public:<br>
+ ELFWriter() { }<br>
<br>
- public:<br>
- /// \brief builds the chunks that needs to be written to the output<br>
- /// ELF file<br>
- virtual void buildChunks(const lld::File &file) = 0;<br>
+public:<br>
+ /// \brief builds the chunks that needs to be written to the output<br>
+ /// ELF file<br>
+ virtual void buildChunks(const lld::File &file) = 0;<br>
<br>
- /// \brief Writes the chunks into the output file specified by path<br>
- virtual error_code writeFile(const lld::File &File, StringRef path) = 0;<br>
+ /// \brief Writes the chunks into the output file specified by path<br>
+ virtual error_code writeFile(const lld::File &File, StringRef path) = 0;<br>
<br>
- /// \brief Writes the chunks into the output file specified by path<br>
- virtual uint64_t addressOfAtom(const Atom *atom) = 0;<br>
+ /// \brief Writes the chunks into the output file specified by path<br>
+ virtual uint64_t addressOfAtom(const Atom *atom) = 0;<br>
<br>
- /// \brief Return the processing function to apply Relocations<br>
- virtual KindHandler *kindHandler() = 0;<br>
+ /// \brief Return the processing function to apply Relocations<br>
+ virtual KindHandler *kindHandler() = 0;<br>
};<br>
<br>
/// \brief A chunk is a contiguous region of space<br>
-template<support::endianness target_endianness, bool is64Bits><br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
class Chunk {<br>
public:<br>
<br>
@@ -83,7 +86,7 @@<br>
K_ELFSection, // Section<br>
K_ELFSectionHeader // Section header<br>
};<br>
- Chunk(StringRef name, Kind kind)<br>
+ Chunk(StringRef name, Kind kind)<br>
: _name(name)<br>
, _kind(kind)<br>
, _fsize(0)<br>
@@ -94,9 +97,9 @@<br>
, _start(0)<br>
, _fileoffset(0) {}<br>
virtual ~Chunk() {}<br>
- // Does the chunk occupy disk space<br>
+ // Does the chunk occupy disk space<br>
virtual bool occupiesNoDiskSpace() const {<br>
- return false;<br>
+ return false;<br>
}<br>
// The name of the chunk<br>
StringRef name() const { return _name; }<br>
@@ -121,8 +124,8 @@<br>
// Does the chunk occupy memory during execution ?<br>
uint64_t memSize() const { return _msize; }<br>
void setMemSize(uint64_t msize) { _msize = msize; }<br>
- // Writer the chunk<br>
- virtual void write(ELFWriter *writer,<br>
+ // Writer the chunk<br>
+ virtual void write(ELFWriter *writer,<br>
OwningPtr<FileOutputBuffer> &buffer) = 0;<br>
// Finalize the chunk before writing<br>
virtual void finalize() = 0;<br>
@@ -141,7 +144,7 @@<br>
<br>
/// \brief The ELFLayoutOptions encapsulates the options used by all Layouts<br>
/// Examples of the ELFLayoutOptions would be a script that would be used<br>
-/// to drive the layout<br>
+/// to drive the layout<br>
class ELFLayoutOptions {<br>
public:<br>
ELFLayoutOptions() { }<br>
@@ -159,10 +162,10 @@<br>
StringRef _script;<br>
};<br>
<br>
-/// \brief The ELFLayout is an abstract class for managing the final layout for<br>
+/// \brief The ELFLayout is an abstract class for managing the final layout for<br>
/// the kind of binaries(Shared Libraries / Relocatables / Executables 0<br>
-/// Each architecture (Hexagon, PowerPC, MIPS) would have a concrete<br>
-/// subclass derived from ELFLayout for generating each binary thats<br>
+/// Each architecture (Hexagon, PowerPC, MIPS) would have a concrete<br>
+/// subclass derived from ELFLayout for generating each binary thats<br>
// needed by the lld linker<br>
class ELFLayout {<br>
public:<br>
@@ -176,7 +179,7 @@<br>
(const StringRef name,<br>
int32_t contentType,<br>
int32_t contentPerm) = 0;<br>
- /// append the Atom to the layout and create appropriate sections<br>
+ /// append the Atom to the layout and create appropriate sections<br>
virtual error_code addAtom(const Atom *atom) = 0;<br>
/// find the Atom Address in the current layout<br>
virtual bool findAtomAddrByName(const StringRef name, uint64_t &addr) = 0;<br>
@@ -189,8 +192,8 @@<br>
<br>
public:<br>
ELFLayout() {}<br>
- ELFLayout(WriterOptionsELF &writerOptions,<br>
- ELFLayoutOptions &layoutOptions)<br>
+ ELFLayout(WriterOptionsELF &writerOptions,<br>
+ ELFLayoutOptions &layoutOptions)<br>
: _writerOptions(writerOptions)<br>
, _layoutOptions(layoutOptions) {}<br>
virtual ~ELFLayout() { }<br>
@@ -200,13 +203,14 @@<br>
ELFLayoutOptions _layoutOptions;<br>
};<br>
<br>
-<br>
/// \brief A section contains a set of atoms that have similiar properties<br>
/// The atoms that have similiar properties are merged to form a section<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-class Section : public Chunk<target_endianness, is64Bits> {<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+class Section : public Chunk<target_endianness, max_align, is64Bits> {<br>
public:<br>
- // The Kind of section that the object represents<br>
+ // The Kind of section that the object represents<br>
enum SectionKind {<br>
K_Default,<br>
K_SymbolTable,<br>
@@ -214,13 +218,13 @@<br>
};<br>
// Create a section object, the section is set to the default type if the<br>
// caller doesnot set it<br>
- Section(const StringRef sectionName,<br>
+ Section(const StringRef sectionName,<br>
const int32_t contentType,<br>
const int32_t contentPermissions,<br>
const int32_t order,<br>
- const SectionKind kind = K_Default)<br>
- : Chunk<target_endianness, is64Bits><br>
- (sectionName, Chunk<target_endianness, is64Bits>::K_ELFSection)<br>
+ const SectionKind kind = K_Default)<br>
+ : Chunk<target_endianness, max_align, is64Bits>(<br>
+ sectionName, Chunk<target_endianness, max_align, is64Bits>::K_ELFSection)<br>
, _contentType(contentType)<br>
, _contentPermissions(contentPermissions)<br>
, _sectionKind(kind)<br>
@@ -250,7 +254,7 @@<br>
return retOffset;<br>
}<br>
<br>
- // \brief Append an atom to a Section. The atom gets pushed into a vector<br>
+ // \brief Append an atom to a Section. The atom gets pushed into a vector<br>
// contains the atom, the atom file offset, the atom virtual address<br>
// the atom file offset is aligned appropriately as set by the Reader<br>
void appendAtom(const Atom *atom) {<br>
@@ -259,7 +263,7 @@<br>
assert(atom != nullptr && "Expecting the atom to be a DefinedAtom");<br>
DefinedAtom::Alignment atomAlign = definedAtom->alignment();<br>
uint64_t align2 = 1u << atomAlign.powerOf2;<br>
- // Align the atom to the required modulus/ align the file offset and the<br>
+ // Align the atom to the required modulus/ align the file offset and the<br>
// memory offset seperately this is required so that BSS symbols are handled<br>
// properly as the BSS symbols only occupy memory size and not file size<br>
uint64_t fOffset = alignOffset(this->fileSize(), atomAlign);<br>
@@ -286,15 +290,15 @@<br>
default:<br>
llvm_unreachable("Expecting only definedAtoms being passed here");<br>
break;<br>
- }<br>
- // Set the section alignment to the largest alignment<br>
+ }<br>
+ // Set the section alignment to the largest alignment<br>
// std::max doesnot support uint64_t<br>
- if (this->_align2 < align2)<br>
+ if (this->_align2 < align2)<br>
this->_align2 = align2;<br>
}<br>
<br>
- /// \brief Set the virtual address of each Atom in the Section. This<br>
- /// routine gets called after the linker fixes up the virtual address<br>
+ /// \brief Set the virtual address of each Atom in the Section. This<br>
+ /// routine gets called after the linker fixes up the virtual address<br>
/// of the section<br>
void assignVirtualAddress(uint64_t &addr) {<br>
for (auto &ai : _atoms) {<br>
@@ -303,15 +307,15 @@<br>
addr += this->memSize();<br>
}<br>
<br>
- /// \brief Set the file offset of each Atom in the section. This routine<br>
- /// gets called after the linker fixes up the section offset<br>
+ /// \brief Set the file offset of each Atom in the section. This routine<br>
+ /// gets called after the linker fixes up the section offset<br>
void assignOffsets(uint64_t offset) {<br>
for (auto &ai : _atoms) {<br>
ai.second.first = offset + ai.second.first;<br>
}<br>
}<br>
<br>
- /// \brief Find the Atom address given a name, this is needed to to properly<br>
+ /// \brief Find the Atom address given a name, this is needed to to properly<br>
/// apply relocation. The section class calls this to find the atom address<br>
/// to fix the relocation<br>
bool findAtomAddrByName(const StringRef name, uint64_t &addr) {<br>
@@ -329,7 +333,7 @@<br>
return _contentType == DefinedAtom::typeZeroFill;<br>
}<br>
<br>
- /// \brief The permission of the section is the most permissive permission<br>
+ /// \brief The permission of the section is the most permissive permission<br>
/// of all atoms that the section contains<br>
void setContentPermissions(int32_t perm) {<br>
_contentPermissions = std::max(perm, _contentPermissions);<br>
@@ -343,17 +347,17 @@<br>
<br>
case DefinedAtom::permR__:<br>
return llvm::ELF::SHF_ALLOC;<br>
-<br>
+<br>
case DefinedAtom::permR_X:<br>
return llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR;<br>
-<br>
+<br>
case DefinedAtom::permRW_:<br>
case DefinedAtom::permRW_L:<br>
return llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE;<br>
-<br>
+<br>
case DefinedAtom::permRWX:<br>
- return llvm::ELF::SHF_ALLOC |<br>
- llvm::ELF::SHF_WRITE |<br>
+ return llvm::ELF::SHF_ALLOC |<br>
+ llvm::ELF::SHF_WRITE |<br>
llvm::ELF::SHF_EXECINSTR;<br>
<br>
default:<br>
@@ -367,7 +371,7 @@<br>
return _contentPermissions;<br>
}<br>
<br>
- /// \brief Return the section type, the returned value is recorded in the<br>
+ /// \brief Return the section type, the returned value is recorded in the<br>
/// sh_type field of the Section Header<br>
int type() {<br>
switch (_contentType) {<br>
@@ -386,7 +390,7 @@<br>
}<br>
}<br>
<br>
- /// \brief Returns the section link field, the returned value is<br>
+ /// \brief Returns the section link field, the returned value is<br>
/// recorded in the sh_link field of the Section Header<br>
int link() const {<br>
return _link;<br>
@@ -396,15 +400,15 @@<br>
_link = link;<br>
}<br>
<br>
- /// \brief Returns the section entsize field, the returned value is<br>
+ /// \brief Returns the section entsize field, the returned value is<br>
/// recorded in the sh_entsize field of the Section Header<br>
int entsize() const {<br>
return _entSize;<br>
}<br>
<br>
- /// \brief Returns the shinfo field, the returned value is<br>
+ /// \brief Returns the shinfo field, the returned value is<br>
/// recorded in the sh_info field of the Section Header<br>
- int shinfo() const {<br>
+ int shinfo() const {<br>
return _shInfo;<br>
}<br>
<br>
@@ -437,15 +441,17 @@<br>
}<br>
<br>
/// \brief for LLVM style RTTI information<br>
- static inline bool classof(const Chunk<target_endianness, is64Bits> *c) {<br>
- return c->kind() == Chunk<target_endianness, is64Bits>::K_ELFSection;<br>
+ static inline bool classof(<br>
+ const Chunk<target_endianness, max_align, is64Bits> *c) {<br>
+ return c->kind() ==<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFSection;<br>
}<br>
<br>
/// \brief Finalize the section contents before writing<br>
void finalize() { }<br>
<br>
- /// \brief Write the section and the atom contents to the buffer<br>
- void write(ELFWriter *writer,<br>
+ /// \brief Write the section and the atom contents to the buffer<br>
+ void write(ELFWriter *writer,<br>
OwningPtr<FileOutputBuffer> &buffer) {<br>
uint8_t *chunkBuffer = buffer->getBufferStart();<br>
for (auto &ai : _atoms) {<br>
@@ -466,7 +472,7 @@<br>
assert(0 && "Found the target to be NULL");<br>
uint64_t fixupAddress = writer->addressOfAtom(ai.first) + offset;<br>
// apply the relocation<br>
- writer->kindHandler()->applyFixup(ref->kind(),<br>
+ writer->kindHandler()->applyFixup(ref->kind(),<br>
ref->addend(),<br>
&atomContent[offset],<br>
fixupAddress,<br>
@@ -476,7 +482,7 @@<br>
}<br>
<br>
/// Atom Iterators<br>
- typedef typename std::vector<std::pair<const Atom *,<br>
+ typedef typename std::vector<std::pair<const Atom *,<br>
std::pair<uint64_t, uint64_t>>>::iterator atom_iter;<br>
<br>
atom_iter atoms_begin() { return _atoms.begin(); }<br>
@@ -496,15 +502,17 @@<br>
int64_t _entSize;<br>
int64_t _shInfo;<br>
int64_t _link;<br>
-};<br>
+};<br>
<br>
-/// \brief A MergedSections represents a set of sections grouped by the same name<br>
-/// The output file that gets written by the linker has sections grouped<br>
-/// by similiar names<br>
-template<support::endianness target_endianness, bool is64Bits><br>
+/// \brief A MergedSections represents a set of sections grouped by the same<br>
+/// name. The output file that gets written by the linker has sections grouped<br>
+/// by similiar names<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
class MergedSections {<br>
public:<br>
- MergedSections(StringRef name)<br>
+ MergedSections(StringRef name)<br>
: _name(name)<br>
,_hasSegment(false)<br>
,_ordinal(0)<br>
@@ -519,17 +527,17 @@<br>
,_align2(0)<br>
,_kind(0)<br>
,_type(0) { }<br>
-<br>
+<br>
// Set the MergedSections is associated with a segment<br>
void setHasSegment() { _hasSegment = true; }<br>
<br>
- /// Sets the ordinal<br>
+ /// Sets the ordinal<br>
void setOrdinal(uint64_t ordinal) {<br>
_ordinal = ordinal;<br>
}<br>
<br>
- /// Sets the Memory size<br>
- void setMemSize(uint64_t memsz) {<br>
+ /// Sets the Memory size<br>
+ void setMemSize(uint64_t memsz) {<br>
_memSize = memsz;<br>
}<br>
<br>
@@ -538,7 +546,8 @@<br>
_size = fsiz;<br>
}<br>
<br>
- // The offset of the first section contained in the merged section is contained here<br>
+ // The offset of the first section contained in the merged section is<br>
+ // contained here<br>
void setFileOffset(uint64_t foffset) {<br>
_fileOffset = foffset;<br>
}<br>
@@ -550,12 +559,14 @@<br>
<br>
// Appends a section into the list of sections that are part of this Merged<br>
// Section<br>
- void appendSection(Chunk<target_endianness, is64Bits> *c) {<br>
- if (c->align2() > _align2)<br>
+ void appendSection(Chunk<target_endianness, max_align, is64Bits> *c) {<br>
+ if (c->align2() > _align2)<br>
_align2 = c->align2();<br>
- if (c->kind() == Chunk<target_endianness, is64Bits>::K_ELFSection) {<br>
- Section<target_endianness, is64Bits> *section;<br>
- section = llvm::dyn_cast<Section<target_endianness, is64Bits>>(c);<br>
+ if (c->kind() ==<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFSection) {<br>
+ Section<target_endianness, max_align, is64Bits> *section;<br>
+ section =<br>
+ llvm::dyn_cast<Section<target_endianness, max_align, is64Bits>>(c);<br>
_link = section->link();<br>
_shInfo = section->shinfo();<br>
_entSize = section->entsize();<br>
@@ -568,8 +579,8 @@<br>
}<br>
<br>
// Iterators<br>
- typedef typename std::vector<Chunk<target_endianness, is64Bits> *>::iterator<br>
- ChunkIter;<br>
+ typedef typename std::vector<<br>
+ Chunk<target_endianness, max_align, is64Bits> *>::iterator ChunkIter;<br>
<br>
ChunkIter begin_sections() { return _sections.begin(); }<br>
<br>
@@ -619,21 +630,23 @@<br>
uint64_t _align2;<br>
int64_t _kind;<br>
int64_t _type;<br>
- std::vector<Chunk<target_endianness, is64Bits> *> _sections;<br>
+ std::vector<Chunk<target_endianness, max_align, is64Bits> *> _sections;<br>
};<br>
<br>
-/// \brief A segment can be divided into segment slices<br>
-/// depending on how the segments can be split<br>
-template<support::endianness target_endianness, bool is64Bits><br>
+/// \brief A segment can be divided into segment slices<br>
+/// depending on how the segments can be split<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
class SegmentSlice {<br>
public:<br>
- typedef typename std::vector<Section<target_endianness, is64Bits> *>::iterator<br>
- sectionIter;<br>
+ typedef typename std::vector<<br>
+ Section<target_endianness, max_align, is64Bits> *>::iterator sectionIter;<br>
<br>
SegmentSlice() { }<br>
<br>
/// Set the segment slice so that it begins at the offset specified<br>
- /// by fileoffset and set the start of the slice to be s and the end<br>
+ /// by fileoffset and set the start of the slice to be s and the end<br>
/// of the slice to be e<br>
void set(uint64_t fileoffset, int32_t s, int e) {<br>
_startSection = s;<br>
@@ -674,8 +687,9 @@<br>
<br>
void setAlign(uint64_t align) { _align2 = align; }<br>
<br>
- static bool compare_slices(SegmentSlice<target_endianness, is64Bits> *a,<br>
- SegmentSlice<target_endianness, is64Bits> *b) {<br>
+ static bool compare_slices(<br>
+ SegmentSlice<target_endianness, max_align, is64Bits> *a,<br>
+ SegmentSlice<target_endianness, max_align, is64Bits> *b) {<br>
return (a->startSection() < b->startSection());<br>
}<br>
<br>
@@ -699,19 +713,21 @@<br>
/// \brief A segment contains a set of sections, that have similiar properties<br>
// the sections are already seperated based on different flags and properties<br>
// the segment is just a way to concatenate sections to segments<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-class Segment : public Chunk<target_endianness, is64Bits> {<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+class Segment : public Chunk<target_endianness, max_align, is64Bits> {<br>
public:<br>
- typedef typename std::vector<br>
- <SegmentSlice<target_endianness, is64Bits> *>::iterator slice_iter;<br>
- typedef typename<br>
- std::vector<Section<target_endianness, is64Bits> *>::iterator SectionIter;<br>
+ typedef typename std::vector<SegmentSlice<<br>
+ target_endianness, max_align, is64Bits> *>::iterator slice_iter;<br>
+ typedef typename std::vector<<br>
+ Section<target_endianness, max_align, is64Bits> *>::iterator SectionIter;<br>
<br>
Segment(const StringRef name,<br>
const ELFLayout::SegmentType type,<br>
const WriterOptionsELF &options)<br>
- : Chunk<target_endianness, is64Bits>(name<br>
- , Chunk<target_endianness, is64Bits>::K_ELFSegment)<br>
+ : Chunk<target_endianness, max_align, is64Bits>(name,<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFSegment)<br>
, _segmentType(type)<br>
, _flags(0)<br>
, _atomflags(0)<br>
@@ -721,7 +737,7 @@<br>
}<br>
<br>
/// append a section to a segment<br>
- void append(Section<target_endianness, is64Bits> *section) {<br>
+ void append(Section<target_endianness, max_align, is64Bits> *section) {<br>
_sections.push_back(section);<br>
if (_flags < section->flags())<br>
_flags = section->flags();<br>
@@ -738,12 +754,11 @@<br>
/// All Read Write Execute segments follow<br>
/// All Read Execute segments appear next<br>
/// All Read only segments appear first<br>
- /// All Write execute segments follow<br>
- static bool compareSegments(Segment<target_endianness, is64Bits> *sega,<br>
- Segment<target_endianness, is64Bits> *segb)<br>
- {<br>
-<br>
- if (sega->atomflags() < segb->atomflags())<br>
+ /// All Write execute segments follow<br>
+ static bool compareSegments(<br>
+ Segment<target_endianness, max_align, is64Bits> *sega,<br>
+ Segment<target_endianness, max_align, is64Bits> *segb) {<br>
+ if (sega->atomflags() < segb->atomflags())<br>
return false;<br>
return true;<br>
}<br>
@@ -756,13 +771,13 @@<br>
/// The algorithm starts off by assigning the startOffset thats passed in as<br>
/// parameter to the first section in the segment, if the difference between<br>
/// the newly computed offset is greater than a page, then we create a segment<br>
- /// slice, as it would be a waste of virtual memory just to be filled with<br>
+ /// slice, as it would be a waste of virtual memory just to be filled with<br>
/// zeroes<br>
void assignOffsets(uint64_t startOffset) {<br>
int startSection = 0;<br>
int currSection = 0;<br>
SectionIter startSectionIter, endSectionIter;<br>
- // slice align is set to the max alignment of the chunks that are<br>
+ // slice align is set to the max alignment of the chunks that are<br>
// contained in the slice<br>
uint64_t sliceAlign = 0;<br>
// Current slice size<br>
@@ -777,7 +792,8 @@<br>
for (auto si = _sections.begin(); si != _sections.end(); ++si) {<br>
if (isFirstSection) {<br>
// align the startOffset to the section alignment<br>
- uint64_t newOffset = llvm::RoundUpToAlignment(startOffset, (*si)->align2());<br>
+ uint64_t newOffset =<br>
+ llvm::RoundUpToAlignment(startOffset, (*si)->align2());<br>
curSliceFileOffset = newOffset;<br>
sliceAlign = (*si)->align2();<br>
this->setFileOffset(startOffset);<br>
@@ -786,8 +802,9 @@<br>
isFirstSection = false;<br>
} else {<br>
uint64_t curOffset = curSliceFileOffset + curSliceSize;<br>
- uint64_t newOffset = llvm::RoundUpToAlignment(curOffset, (*si)->align2());<br>
- SegmentSlice<target_endianness, is64Bits> *slice = nullptr;<br>
+ uint64_t newOffset =<br>
+ llvm::RoundUpToAlignment(curOffset, (*si)->align2());<br>
+ SegmentSlice<target_endianness, max_align, is64Bits> *slice = nullptr;<br>
// If the newOffset computed is more than a page away, lets create<br>
// a seperate segment, so that memory is not used up while running<br>
if ((newOffset - curOffset) > _options.pageSize()) {<br>
@@ -799,16 +816,17 @@<br>
}<br>
}<br>
if (!slice) {<br>
- slice = new (_segmentAllocate.Allocate<br>
- <SegmentSlice<target_endianness, is64Bits>>())<br>
- SegmentSlice<target_endianness, is64Bits>();<br>
+ slice = new (_segmentAllocate.Allocate<<br>
+ SegmentSlice<target_endianness, max_align, is64Bits>>())<br>
+ SegmentSlice<target_endianness, max_align, is64Bits>();<br>
_segmentSlices.push_back(slice);<br>
}<br>
slice->set(curSliceFileOffset, startSection, currSection);<br>
slice->setSections(startSectionIter, endSectionIter);<br>
slice->setSize(curSliceSize);<br>
slice->setAlign(sliceAlign);<br>
- uint64_t newPageOffset = llvm::RoundUpToAlignment(curOffset, _options.pageSize());<br>
+ uint64_t newPageOffset =<br>
+ llvm::RoundUpToAlignment(curOffset, _options.pageSize());<br>
newOffset = llvm::RoundUpToAlignment(newPageOffset, (*si)->align2());<br>
curSliceFileOffset = newOffset;<br>
startSectionIter = endSectionIter;<br>
@@ -827,7 +845,7 @@<br>
currSection++;<br>
endSectionIter = si;<br>
}<br>
- SegmentSlice<target_endianness, is64Bits> *slice = nullptr;<br>
+ SegmentSlice<target_endianness, max_align, is64Bits> *slice = nullptr;<br>
for (auto sei = slices_begin(); sei != slices_end(); ++sei) {<br>
// TODO: add std::find<br>
if ((*sei)->startSection() == startSection) {<br>
@@ -837,8 +855,8 @@<br>
}<br>
if (!slice) {<br>
slice = new (_segmentAllocate.Allocate<br>
- <SegmentSlice<target_endianness, is64Bits>>())<br>
- SegmentSlice<target_endianness, is64Bits>();<br>
+ <SegmentSlice<target_endianness, max_align, is64Bits>>())<br>
+ SegmentSlice<target_endianness, max_align, is64Bits>();<br>
_segmentSlices.push_back(slice);<br>
}<br>
slice->set(curSliceFileOffset, startSection, currSection);<br>
@@ -846,15 +864,15 @@<br>
slice->setSize(curSliceSize);<br>
slice->setAlign(sliceAlign);<br>
this->_fsize = curSliceFileOffset - startOffset + curSliceSize;<br>
- std::stable_sort(slices_begin(), slices_end(),<br>
- SegmentSlice<target_endianness, is64Bits>::compare_slices);<br>
+ std::stable_sort(slices_begin(), slices_end(),<br>
+ SegmentSlice<target_endianness, max_align, is64Bits>::compare_slices);<br>
}<br>
<br>
/// \brief Assign virtual addresses to the slices<br>
void assignVirtualAddress(uint64_t &addr, bool isFirstSegment) {<br>
for (auto sei = slices_begin(), see = slices_end(); sei != see; ++sei) {<br>
bool firstSlice = (sei == slices_begin());<br>
- // The first segment has distinct since it contains the<br>
+ // The first segment has distinct since it contains the<br>
// ELF header and the Program Header, if we get to the first segment<br>
// and the first slice, set it to the baseaddress<br>
// which is the segment address<br>
@@ -867,7 +885,7 @@<br>
addr = llvm::RoundUpToAlignment(addr, (*sei)->align2());<br>
}<br>
bool virtualAddressSet = false;<br>
- for (auto si = (*sei)->sections_begin(), se = (*sei)->sections_end();<br>
+ for (auto si = (*sei)->sections_begin(), se = (*sei)->sections_end();<br>
si != se; ++si) {<br>
// Align the section address<br>
addr = llvm::RoundUpToAlignment(addr, (*si)->align2());<br>
@@ -891,10 +909,10 @@<br>
return _segmentSlices.end();<br>
}<br>
<br>
- // Write the Segment<br>
+ // Write the Segment<br>
void write(ELFWriter *writer, OwningPtr<FileOutputBuffer> &buffer) {<br>
for (auto sei = slices_begin(), see = slices_end(); sei != see; ++sei) {<br>
- for (auto si = (*sei)->sections_begin(), se = (*sei)->sections_end();<br>
+ for (auto si = (*sei)->sections_begin(), se = (*sei)->sections_end();<br>
si != se; ++si) {<br>
(*si)->write(writer, buffer);<br>
}<br>
@@ -904,9 +922,11 @@<br>
// Finalize the segment, before we want to write to the output file<br>
void finalize() { }<br>
<br>
- // For LLVM RTTI<br>
- static inline bool classof(const Chunk<target_endianness, is64Bits> *c) {<br>
- return c->kind() == Chunk<target_endianness, is64Bits>::K_ELFSegment;<br>
+ // For LLVM RTTI<br>
+ static inline bool classof(<br>
+ const Chunk<target_endianness, max_align, is64Bits> *c) {<br>
+ return c->kind() ==<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFSegment;<br>
}<br>
<br>
// Getters<br>
@@ -936,8 +956,9 @@<br>
}<br>
<br>
private:<br>
- std::vector<Section<target_endianness, is64Bits> *> _sections;<br>
- std::vector<SegmentSlice<target_endianness, is64Bits> *> _segmentSlices;<br>
+ std::vector<Section<target_endianness, max_align, is64Bits> *> _sections;<br>
+ std::vector<SegmentSlice<target_endianness, max_align, is64Bits> *><br>
+ _segmentSlices;<br>
ELFLayout::SegmentType _segmentType;<br>
int64_t _flags;<br>
int64_t _atomflags;<br>
@@ -946,17 +967,18 @@<br>
};<br>
<br>
/// \brief The class represents the ELF String Table<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-class ELFStringTable : public Section<target_endianness, is64Bits> {<br>
-<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+class ELFStringTable : public Section<target_endianness, max_align, is64Bits> {<br>
public:<br>
- ELFStringTable(const char *str,<br>
- int32_t order):<br>
- Section<target_endianness, is64Bits>(str,<br>
- llvm::ELF::SHT_STRTAB,<br>
- DefinedAtom::perm___,<br>
- order,<br>
- Section<target_endianness, is64Bits>::K_StringTable) {<br>
+ ELFStringTable(const char *str, int32_t order)<br>
+ : Section<target_endianness, max_align, is64Bits>(<br>
+ str,<br>
+ llvm::ELF::SHT_STRTAB,<br>
+ DefinedAtom::perm___,<br>
+ order,<br>
+ Section<target_endianness, max_align, is64Bits>::K_StringTable) {<br>
// the string table has a NULL entry for which<br>
// add an empty string<br>
_strings.push_back("");<br>
@@ -965,12 +987,10 @@<br>
this->setOrder(order);<br>
}<br>
<br>
- static inline bool classof(ELFStringTable<target_endianness, is64Bits> *s) {<br>
- return true;<br>
- }<br>
-<br>
- static inline bool classof(const Chunk<target_endianness, is64Bits> *c) {<br>
- return c->kind() == Section<target_endianness, is64Bits>::K_StringTable;<br>
+ static inline bool classof(<br>
+ const Chunk<target_endianness, max_align, is64Bits> *c) {<br>
+ return c->kind() ==<br>
+ Section<target_endianness, max_align, is64Bits>::K_StringTable;<br>
}<br>
<br>
uint64_t addString(const StringRef symname) {<br>
@@ -980,7 +1000,7 @@<br>
return offset;<br>
}<br>
<br>
- void write(ELFWriter *writer,<br>
+ void write(ELFWriter *writer,<br>
OwningPtr<FileOutputBuffer> &buffer) {<br>
uint8_t *chunkBuffer = buffer->getBufferStart();<br>
uint8_t *dest = chunkBuffer + this->fileOffset();<br>
@@ -998,35 +1018,34 @@<br>
std::vector<StringRef> _strings;<br>
};<br>
<br>
-/// \brief The ELFSymbolTable class represents the symbol table in a ELF file<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-class ELFSymbolTable : public Section<target_endianness, is64Bits> {<br>
-<br>
+/// \brief The ELFSymbolTable class represents the symbol table in a ELF file<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+class ELFSymbolTable : public Section<target_endianness, max_align, is64Bits> {<br>
public:<br>
- typedef object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;<br>
+ typedef object::Elf_Sym_Impl<target_endianness, max_align, is64Bits> Elf_Sym;<br>
<br>
- ELFSymbolTable(const char *str,<br>
- int32_t order)<br>
- : Section<target_endianness, is64Bits>(str<br>
- , llvm::ELF::SHT_SYMTAB<br>
- , 0<br>
- , order<br>
- , Section<target_endianness, is64Bits>::K_SymbolTable) {<br>
+ ELFSymbolTable(const char *str, int32_t order)<br>
+ : Section<target_endianness, max_align, is64Bits>(<br>
+ str,<br>
+ llvm::ELF::SHT_SYMTAB,<br>
+ 0,<br>
+ order,<br>
+ Section<target_endianness, max_align, is64Bits>::K_SymbolTable) {<br>
this->setOrder(order);<br>
Elf_Sym *symbol = new (_symbolAllocate.Allocate<Elf_Sym>()) Elf_Sym;<br>
- memset ((void *)symbol,0, sizeof(Elf_Sym));<br>
+ memset((void *)symbol, 0, sizeof(Elf_Sym));<br>
_symbolTable.push_back(symbol);<br>
this->_entSize = sizeof(Elf_Sym);<br>
this->_fsize = sizeof(Elf_Sym);<br>
this->_align2 = sizeof(void *);<br>
}<br>
<br>
- static inline bool classof(ELFSymbolTable<target_endianness, is64Bits> *s) {<br>
- return true;<br>
- }<br>
-<br>
- static inline bool classof(const Chunk<target_endianness, is64Bits> *c) {<br>
- return c->kind() == Section<target_endianness, is64Bits>::K_SymbolTable;<br>
+ static inline bool classof(<br>
+ const Chunk<target_endianness, max_align, is64Bits> *c) {<br>
+ return c->kind() ==<br>
+ Section<target_endianness, max_align, is64Bits>::K_SymbolTable;<br>
}<br>
<br>
void addSymbol(const Atom *atom, int32_t sectionIndex, uint64_t addr = 0) {<br>
@@ -1056,11 +1075,12 @@<br>
default:<br>
type = ELF::STT_NOTYPE;<br>
}<br>
- if (da->scope() == DefinedAtom::scopeTranslationUnit)<br>
+ if (da->scope() == DefinedAtom::scopeTranslationUnit)<br>
binding = ELF::STB_LOCAL;<br>
else<br>
binding = ELF::STB_GLOBAL;<br>
- } else if (const AbsoluteAtom *aa = llvm::dyn_cast<const AbsoluteAtom>(atom)){<br>
+ } else if (const AbsoluteAtom *aa =<br>
+ llvm::dyn_cast<const AbsoluteAtom>(atom)){<br>
type = ELF::STT_OBJECT;<br>
symbol->st_shndx = ELF::SHN_ABS;<br>
switch (aa->scope()) {<br>
@@ -1076,7 +1096,7 @@<br>
break;<br>
}<br>
symbol->st_value = aa->value();<br>
- }<br>
+ }<br>
else {<br>
symbol->st_value = 0;<br>
type = ELF::STT_NOTYPE;<br>
@@ -1087,7 +1107,8 @@<br>
this->_fsize += sizeof(Elf_Sym);<br>
}<br>
<br>
- void setStringSection(ELFStringTable<target_endianness, is64Bits> *s) {<br>
+ void setStringSection(<br>
+ ELFStringTable<target_endianness, max_align, is64Bits> *s) {<br>
_stringSection = s;<br>
}<br>
<br>
@@ -1097,7 +1118,7 @@<br>
std::stable_sort(_symbolTable.begin(), _symbolTable.end(),<br>
[](const Elf_Sym *A, const Elf_Sym *B) {<br>
return A->getBinding() < B->getBinding();<br>
- });<br>
+ });<br>
uint16_t shInfo = 0;<br>
for (auto i : _symbolTable) {<br>
if (i->getBinding() != ELF::STB_LOCAL)<br>
@@ -1108,9 +1129,8 @@<br>
this->setLink(_stringSection->ordinal());<br>
}<br>
<br>
- void write(ELFWriter *writer,<br>
+ void write(ELFWriter *writer,<br>
OwningPtr<FileOutputBuffer> &buffer) {<br>
-<br>
uint8_t *chunkBuffer = buffer->getBufferStart();<br>
uint8_t *dest = chunkBuffer + this->fileOffset();<br>
for (auto sti : _symbolTable) {<br>
@@ -1120,7 +1140,7 @@<br>
}<br>
<br>
private:<br>
- ELFStringTable<target_endianness, is64Bits> *_stringSection;<br>
+ ELFStringTable<target_endianness, max_align, is64Bits> *_stringSection;<br>
std::vector<Elf_Sym*> _symbolTable;<br>
llvm::BumpPtrAllocator _symbolAllocate;<br>
int64_t _link;<br>
@@ -1128,14 +1148,16 @@<br>
<br>
/// \brief An ELFHeader represents the Elf[32/64]_Ehdr structure at the<br>
/// start of an ELF executable file.<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-class ELFHeader : public Chunk<target_endianness, is64Bits> {<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+class ELFHeader : public Chunk<target_endianness, max_align, is64Bits> {<br>
public:<br>
- typedef object::Elf_Ehdr_Impl<target_endianness, is64Bits> Elf_Ehdr;<br>
+ typedef Elf_Ehdr_Impl<target_endianness, max_align, is64Bits> Elf_Ehdr;<br>
<br>
ELFHeader()<br>
- : Chunk<target_endianness, is64Bits>("elfhdr"<br>
- , Chunk<target_endianness, is64Bits>::K_ELFHeader) {<br>
+ : Chunk<target_endianness, max_align, is64Bits>(<br>
+ "elfhdr", Chunk<target_endianness, max_align, is64Bits>::K_ELFHeader) {<br>
memset(_eh.e_ident, 0, llvm::ELF::EI_NIDENT);<br>
e_ident(ELF::EI_MAG0, 0x7f);<br>
e_ident(ELF::EI_MAG1, 'E');<br>
@@ -1160,13 +1182,14 @@<br>
void e_shstrndx(uint16_t shstrndx) { _eh.e_shstrndx = shstrndx; }<br>
uint64_t fileSize() { return sizeof (Elf_Ehdr); }<br>
<br>
- static inline bool classof(const Chunk<target_endianness, is64Bits> *c) {<br>
- return c->Kind() == Chunk<target_endianness, is64Bits>::K_ELFHeader;<br>
+ static inline bool classof(<br>
+ const Chunk<target_endianness, max_align, is64Bits> *c) {<br>
+ return c->Kind() ==<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFHeader;<br>
}<br>
<br>
- void write(ELFWriter *writer,<br>
+ void write(ELFWriter *writer,<br>
OwningPtr<FileOutputBuffer> &buffer) {<br>
-<br>
uint8_t *chunkBuffer = buffer->getBufferStart();<br>
uint8_t *atomContent = chunkBuffer + this->fileOffset();<br>
memcpy(atomContent, &_eh, fileSize());<br>
@@ -1180,20 +1203,23 @@<br>
<br>
/// \brief An ELFProgramHeader represents the Elf[32/64]_Phdr structure at the<br>
/// start of an ELF executable file.<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-class ELFProgramHeader : public Chunk<target_endianness, is64Bits> {<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+class ELFProgramHeader : public Chunk<target_endianness, max_align, is64Bits> {<br>
public:<br>
- typedef object::Elf_Phdr<target_endianness, is64Bits> Elf_Phdr;<br>
+ typedef Elf_Phdr<target_endianness, max_align, is64Bits> Elf_Phdr;<br>
<br>
ELFProgramHeader()<br>
- : Chunk<target_endianness, is64Bits>("elfphdr"<br>
- , Chunk<target_endianness, is64Bits>::K_ELFProgramHeader) { }<br>
+ : Chunk<target_endianness, max_align, is64Bits>(<br>
+ "elfphdr",<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFProgramHeader) { }<br>
<br>
- bool addSegment(Segment<target_endianness, is64Bits> *segment) {<br>
+ bool addSegment(Segment<target_endianness, max_align, is64Bits> *segment) {<br>
Elf_Phdr *phdr = nullptr;<br>
bool ret = false;<br>
<br>
- for (auto sei = segment->slices_begin(), see = segment->slices_end();<br>
+ for (auto sei = segment->slices_begin(), see = segment->slices_end();<br>
sei != see; ++sei) {<br>
if (_phi == _ph.end()) {<br>
phdr = new(_allocator.Allocate<Elf_Phdr>()) Elf_Phdr;<br>
@@ -1211,14 +1237,14 @@<br>
phdr->p_filesz = (*sei)->fileSize();<br>
phdr->p_memsz = (*sei)->memSize();<br>
phdr->p_flags = segment->flags();<br>
- phdr->p_align = (phdr->p_type == llvm::ELF::PT_LOAD) ?<br>
+ phdr->p_align = (phdr->p_type == llvm::ELF::PT_LOAD) ?<br>
segment->pageSize() : (*sei)->align2();<br>
}<br>
return ret;<br>
}<br>
<br>
void resetProgramHeaders() {<br>
- _phi = _ph.begin();<br>
+ _phi = _ph.begin();<br>
}<br>
<br>
void setVAddr(uint64_t addr) {<br>
@@ -1226,15 +1252,18 @@<br>
this->_fsize = this->_start - addr;<br>
}<br>
<br>
- uint64_t fileSize() { return this->_fsize + (sizeof (Elf_Phdr) * _ph.size()); }<br>
+ uint64_t fileSize() {<br>
+ return this->_fsize + (sizeof (Elf_Phdr) * _ph.size());<br>
+ }<br>
<br>
- static inline bool classof(const Chunk<target_endianness, is64Bits> *c) {<br>
- return c->Kind() == Chunk<target_endianness, is64Bits>::K_ELFProgramHeader;<br>
+ static inline bool classof(<br>
+ const Chunk<target_endianness, max_align, is64Bits> *c) {<br>
+ return c->Kind() ==<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFProgramHeader;<br>
}<br>
<br>
- void write(ELFWriter *writer,<br>
+ void write(ELFWriter *writer,<br>
OwningPtr<FileOutputBuffer> &buffer) {<br>
-<br>
uint8_t *chunkBuffer = buffer->getBufferStart();<br>
uint8_t *dest = chunkBuffer + this->fileOffset();<br>
for (auto phi : _ph) {<br>
@@ -1245,7 +1274,7 @@<br>
<br>
void finalize() { }<br>
<br>
- int64_t entsize() {<br>
+ int64_t entsize() {<br>
return sizeof(Elf_Phdr);<br>
}<br>
<br>
@@ -1262,14 +1291,17 @@<br>
<br>
/// \brief An ELFSectionHeader represents the Elf[32/64]_Shdr structure<br>
/// at the end of the file<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-class ELFSectionHeader : public Chunk<target_endianness, is64Bits> {<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+class ELFSectionHeader : public Chunk<target_endianness, max_align, is64Bits> {<br>
public:<br>
- typedef object::Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;<br>
+ typedef Elf_Shdr_Impl<target_endianness, max_align, is64Bits> Elf_Shdr;<br>
<br>
- ELFSectionHeader(int32_t order):Chunk<target_endianness, is64Bits>("shdr",<br>
- Chunk<target_endianness, is64Bits>::K_ELFSectionHeader)<br>
- {<br>
+ ELFSectionHeader(int32_t order)<br>
+ : Chunk<target_endianness, max_align, is64Bits>(<br>
+ "shdr",<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFSectionHeader) {<br>
this->_fsize = 0;<br>
this->_align2 = 8;<br>
this->setOrder(order);<br>
@@ -1280,11 +1312,12 @@<br>
this->_fsize += sizeof (Elf_Shdr);<br>
}<br>
<br>
- uint16_t fileSize() {<br>
+ uint16_t fileSize() {<br>
return sizeof(Elf_Shdr) * _sectionInfo.size();<br>
}<br>
<br>
- void appendSection(MergedSections<target_endianness, is64Bits> *section) {<br>
+ void appendSection(<br>
+ MergedSections<target_endianness, max_align, is64Bits> *section) {<br>
Elf_Shdr *shdr = new (_sectionAllocate.Allocate<Elf_Shdr>()) Elf_Shdr;<br>
shdr->sh_name = _stringSection->addString(section->name());<br>
shdr->sh_type = section->type();<br>
@@ -1299,7 +1332,7 @@<br>
_sectionInfo.push_back(shdr);<br>
}<br>
<br>
- void updateSection(Section<target_endianness, is64Bits> *section) {<br>
+ void updateSection(Section<target_endianness, max_align, is64Bits> *section) {<br>
Elf_Shdr *shdr = _sectionInfo[section->ordinal()];<br>
shdr->sh_type = section->type();<br>
shdr->sh_flags = section->flags();<br>
@@ -1312,17 +1345,19 @@<br>
shdr->sh_entsize = section->entsize();<br>
}<br>
<br>
- static inline bool classof(const Chunk<target_endianness, is64Bits> *c) {<br>
- return c->getChunkKind() == Chunk<target_endianness, is64Bits>::K_ELFSectionHeader;<br>
+ static inline bool classof(<br>
+ const Chunk<target_endianness, max_align, is64Bits> *c) {<br>
+ return c->getChunkKind() ==<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFSectionHeader;<br>
}<br>
<br>
- void setStringSection(ELFStringTable<target_endianness, is64Bits> *s) {<br>
+ void setStringSection(<br>
+ ELFStringTable<target_endianness, max_align, is64Bits> *s) {<br>
_stringSection = s;<br>
}<br>
<br>
- void write(ELFWriter *writer,<br>
+ void write(ELFWriter *writer,<br>
OwningPtr<FileOutputBuffer> &buffer) {<br>
-<br>
uint8_t *chunkBuffer = buffer->getBufferStart();<br>
uint8_t *dest = chunkBuffer + this->fileOffset();<br>
for (auto shi : _sectionInfo) {<br>
@@ -1334,7 +1369,7 @@<br>
<br>
void finalize() { }<br>
<br>
- int64_t entsize() {<br>
+ int64_t entsize() {<br>
return sizeof(Elf_Shdr);<br>
}<br>
<br>
@@ -1343,23 +1378,24 @@<br>
}<br>
<br>
private:<br>
- ELFStringTable<target_endianness, is64Bits> *_stringSection;<br>
+ ELFStringTable<target_endianness, max_align, is64Bits> *_stringSection;<br>
std::vector<Elf_Shdr*> _sectionInfo;<br>
llvm::BumpPtrAllocator _sectionAllocate;<br>
};<br>
<br>
-<br>
-/// \brief The DefaultELFLayout class is used by the Writer to arrange<br>
-/// sections and segments in the order determined by the target ELF<br>
+/// \brief The DefaultELFLayout class is used by the Writer to arrange<br>
+/// sections and segments in the order determined by the target ELF<br>
/// format. The writer creates a single instance of the DefaultELFLayout<br>
-/// class<br>
-template<support::endianness target_endianness, bool is64Bits><br>
+/// class<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
class DefaultELFLayout : public ELFLayout {<br>
public:<br>
<br>
// The order in which the sections appear in the output file<br>
- // If its determined, that the layout needs to change<br>
- // just changing the order of enumerations would essentially<br>
+ // If its determined, that the layout needs to change<br>
+ // just changing the order of enumerations would essentially<br>
// change the layout in the output file<br>
enum DefaultSectionOrder {<br>
ORDER_NOT_DEFINED = 0,<br>
@@ -1392,22 +1428,22 @@<br>
public:<br>
<br>
// The Key used for creating Sections<br>
- // The sections are created using<br>
+ // The sections are created using<br>
// SectionName, [contentType, contentPermissions]<br>
- typedef std::pair<StringRef,<br>
+ typedef std::pair<StringRef,<br>
std::pair<int32_t, int32_t>> Key;<br>
- typedef typename std::vector<Chunk<target_endianness, is64Bits> *>::iterator<br>
- ChunkIter;<br>
+ typedef typename std::vector<<br>
+ Chunk<target_endianness, max_align, is64Bits> *>::iterator ChunkIter;<br>
// The key used for Segments<br>
- // The segments are created using<br>
+ // The segments are created using<br>
// SegmentName, Segment flags<br>
typedef std::pair<StringRef, int64_t> SegmentKey;<br>
// Merged Sections contain the map of Sectionnames to a vector of sections,<br>
// that have been merged to form a single section<br>
- typedef std::map<StringRef, MergedSections<target_endianness, is64Bits> *><br>
- MergedSectionMapT;<br>
- typedef typename std::vector<br>
- <MergedSections<target_endianness, is64Bits> *>::iterator MergedSectionIter;<br>
+ typedef std::map<StringRef, MergedSections<<br>
+ target_endianness, max_align, is64Bits> *> MergedSectionMapT;<br>
+ typedef typename std::vector<MergedSections<<br>
+ target_endianness, max_align, is64Bits> *>::iterator MergedSectionIter;<br>
<br>
// HashKey for the Section<br>
class HashKey {<br>
@@ -1429,10 +1465,10 @@<br>
}<br>
};<br>
<br>
- typedef std::unordered_map<Key,<br>
- Section<target_endianness, is64Bits>*, HashKey> SectionMapT;<br>
+ typedef std::unordered_map<Key, Section<<br>
+ target_endianness, max_align, is64Bits>*, HashKey> SectionMapT;<br>
typedef std::unordered_map<SegmentKey,<br>
- Segment<target_endianness, is64Bits>*,<br>
+ Segment<target_endianness, max_align, is64Bits>*,<br>
SegmentHashKey> SegmentMapT;<br>
<br>
DefaultELFLayout(const WriterOptionsELF &options):_options(options) { }<br>
@@ -1453,19 +1489,19 @@<br>
.Default(ORDER_TEXT);<br>
<br>
case DefinedAtom::typeConstant:<br>
- return ORDER_RODATA;<br>
-<br>
+ return ORDER_RODATA;<br>
+<br>
case DefinedAtom::typeData:<br>
return ORDER_DATA;<br>
-<br>
+<br>
case DefinedAtom::typeZeroFill:<br>
return ORDER_BSS;<br>
<br>
default:<br>
// If we get passed in a section push it to OTHER<br>
- if (contentPermissions == DefinedAtom::perm___)<br>
+ if (contentPermissions == DefinedAtom::perm___)<br>
return ORDER_OTHER;<br>
-<br>
+<br>
return ORDER_NOT_DEFINED;<br>
}<br>
}<br>
@@ -1473,18 +1509,18 @@<br>
/// \brief This maps the input sections to the output section names<br>
StringRef getSectionName(const StringRef name,<br>
const int32_t contentType) {<br>
- if (contentType == DefinedAtom::typeZeroFill)<br>
+ if (contentType == DefinedAtom::typeZeroFill)<br>
return ".bss";<br>
- if (name.startswith(".text"))<br>
+ if (name.startswith(".text"))<br>
return ".text";<br>
- if (name.startswith(".rodata"))<br>
+ if (name.startswith(".rodata"))<br>
return ".rodata";<br>
return name;<br>
}<br>
<br>
/// \brief Gets the segment for a output section<br>
- virtual ELFLayout::SegmentType getSegmentType(Section<target_endianness,<br>
- is64Bits> *section) const {<br>
+ virtual ELFLayout::SegmentType getSegmentType(<br>
+ Section<target_endianness, max_align, is64Bits> *section) const {<br>
switch(section->order()) {<br>
case ORDER_INTERP:<br>
return llvm::ELF::PT_INTERP;<br>
@@ -1524,7 +1560,7 @@<br>
<br>
/// \brief Returns true/false depending on whether the section has a Output<br>
// segment or not<br>
- static bool hasOutputSegment(Section<target_endianness,<br>
+ static bool hasOutputSegment(Section<target_endianness, max_align,<br>
is64Bits> *section) {<br>
switch(section->order()) {<br>
case ORDER_INTERP:<br>
@@ -1556,19 +1592,19 @@<br>
// Adds an atom to the section<br>
virtual error_code addAtom(const Atom *atom) {<br>
const DefinedAtom *definedAtom = dyn_cast<DefinedAtom>(atom);<br>
- const StringRef sectionName =<br>
+ const StringRef sectionName =<br>
getSectionName(definedAtom->customSectionName(),<br>
definedAtom->contentType());<br>
- const lld::DefinedAtom::ContentPermissions permissions =<br>
+ const lld::DefinedAtom::ContentPermissions permissions =<br>
definedAtom->permissions();<br>
- const lld::DefinedAtom::ContentType contentType =<br>
+ const lld::DefinedAtom::ContentType contentType =<br>
definedAtom->contentType();<br>
const Key key(sectionName, std::make_pair(contentType, permissions));<br>
- const std::pair<Key, Section<target_endianness, is64Bits> *><br>
+ const std::pair<Key, Section<target_endianness, max_align, is64Bits> *><br>
currentSection(key, nullptr);<br>
- std::pair<typename SectionMapT::iterator, bool><br>
+ std::pair<typename SectionMapT::iterator, bool><br>
sectionInsert(_sectionMap.insert(currentSection));<br>
- Section<target_endianness, is64Bits> *section;<br>
+ Section<target_endianness, max_align, is64Bits> *section;<br>
// the section is already in the map<br>
if (!sectionInsert.second) {<br>
section = sectionInsert.first->second;<br>
@@ -1579,9 +1615,9 @@<br>
contentType,<br>
permissions);<br>
section = new (_allocator.Allocate<br>
- <Section<target_endianness, is64Bits>>())<br>
- Section<target_endianness, is64Bits><br>
- (sectionName, contentType,<br>
+ <Section<target_endianness, max_align, is64Bits>>())<br>
+ Section<target_endianness, max_align, is64Bits><br>
+ (sectionName, contentType,<br>
permissions, section_order);<br>
sectionInsert.first->second = section;<br>
section->setOrder(section_order);<br>
@@ -1593,12 +1629,12 @@<br>
<br>
// Merge sections with the same name into a MergedSections<br>
void mergeSimiliarSections() {<br>
- MergedSections<target_endianness, is64Bits> *mergedSection;<br>
-<br>
+ MergedSections<target_endianness, max_align, is64Bits> *mergedSection;<br>
+<br>
for (auto &si : _sections) {<br>
- const std::pair<StringRef, MergedSections<target_endianness, is64Bits> *><br>
- currentMergedSections(si->name(),<br>
- nullptr);<br>
+ const std::pair<StringRef,<br>
+ MergedSections<target_endianness, max_align, is64Bits> *><br>
+ currentMergedSections(si->name(), nullptr);<br>
std::pair<typename MergedSectionMapT::iterator, bool><br>
mergedSectionInsert<br>
(_mergedSectionMap.insert(currentMergedSections));<br>
@@ -1606,9 +1642,9 @@<br>
mergedSection = mergedSectionInsert.first->second;<br>
}<br>
else {<br>
- mergedSection = new (_allocator.Allocate<br>
- <MergedSections<target_endianness, is64Bits>>())<br>
- MergedSections<target_endianness, is64Bits>(si->name());<br>
+ mergedSection = new (_allocator.Allocate<<br>
+ MergedSections<target_endianness, max_align, is64Bits>>())<br>
+ MergedSections<target_endianness, max_align, is64Bits>(si->name());<br>
_mergedSections.push_back(mergedSection);<br>
mergedSectionInsert.first->second = mergedSection;<br>
}<br>
@@ -1619,8 +1655,8 @@<br>
void assignSectionsToSegments() {<br>
// sort the sections by their order as defined by the layout<br>
std::stable_sort(_sections.begin(), _sections.end(),<br>
- [](Chunk<target_endianness, is64Bits> *A,<br>
- Chunk<target_endianness, is64Bits> *B) {<br>
+ [](Chunk<target_endianness, max_align, is64Bits> *A,<br>
+ Chunk<target_endianness, max_align, is64Bits> *B) {<br>
return A->order() < B->order();<br>
});<br>
// Merge all sections<br>
@@ -1635,14 +1671,16 @@<br>
}<br>
++ordinal;<br>
}<br>
- Section<target_endianness, is64Bits> *section;<br>
- Segment<target_endianness, is64Bits> *segment;<br>
- for (auto msi = merged_sections_begin(), mse = merged_sections_end();<br>
+ Section<target_endianness, max_align, is64Bits> *section;<br>
+ Segment<target_endianness, max_align, is64Bits> *segment;<br>
+ for (auto msi = merged_sections_begin(), mse = merged_sections_end();<br>
msi != mse; ++msi) {<br>
- for (auto ai = (*msi)->begin_sections(), ae = (*msi)->end_sections();<br>
+ for (auto ai = (*msi)->begin_sections(), ae = (*msi)->end_sections();<br>
ai != ae; ++ai) {<br>
- if ((*ai)->kind() == Chunk<target_endianness, is64Bits>::K_ELFSection) {<br>
- section = llvm::dyn_cast<Section<target_endianness, is64Bits>>(*ai);<br>
+ if ((*ai)->kind() ==<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFSection) {<br>
+ section = llvm::dyn_cast<<br>
+ Section<target_endianness, max_align, is64Bits>>(*ai);<br>
if (!hasOutputSegment(section))<br>
continue;<br>
(*msi)->setHasSegment();<br>
@@ -1650,18 +1688,19 @@<br>
const StringRef segmentName = section->segmentKindToStr();<br>
// Use the flags of the merged Section for the segment<br>
const SegmentKey key(segmentName, (*msi)->flags());<br>
- const std::pair<SegmentKey, Segment<target_endianness, is64Bits> *><br>
- currentSegment(key, nullptr);<br>
- std::pair<typename SegmentMapT::iterator, bool><br>
+ const std::pair<SegmentKey,<br>
+ Segment<target_endianness, max_align, is64Bits> *><br>
+ currentSegment(key, nullptr);<br>
+ std::pair<typename SegmentMapT::iterator, bool><br>
segmentInsert(_segmentMap.insert(currentSegment));<br>
<br>
if (!segmentInsert.second) {<br>
segment = segmentInsert.first->second;<br>
} else {<br>
segment = new (_allocator.Allocate<br>
- <Segment<target_endianness, is64Bits>>())<br>
- Segment<target_endianness, is64Bits><br>
- (segmentName, getSegmentType(section),<br>
+ <Segment<target_endianness, max_align, is64Bits>>())<br>
+ Segment<target_endianness, max_align, is64Bits><br>
+ (segmentName, getSegmentType(section),<br>
_options);<br>
segmentInsert.first->second = segment;<br>
_segments.push_back(segment);<br>
@@ -1672,14 +1711,14 @@<br>
}<br>
}<br>
<br>
- void addSection(Chunk<target_endianness, is64Bits> *c) {<br>
+ void addSection(Chunk<target_endianness, max_align, is64Bits> *c) {<br>
_sections.push_back(c);<br>
}<br>
<br>
void assignFileOffsets() {<br>
- std::sort(_segments.begin(),<br>
- _segments.end(),<br>
- Segment<target_endianness, is64Bits>::compareSegments);<br>
+ std::sort(_segments.begin(),<br>
+ _segments.end(),<br>
+ Segment<target_endianness, max_align, is64Bits>::compareSegments);<br>
int ordinal = 0;<br>
// Compute the number of segments that might be needed, so that the<br>
// size of the program header can be computed<br>
@@ -1691,11 +1730,12 @@<br>
}<br>
}<br>
<br>
- void setELFHeader(ELFHeader<target_endianness, is64Bits> *e) {<br>
+ void setELFHeader(ELFHeader<target_endianness, max_align, is64Bits> *e) {<br>
_elfHeader = e;<br>
}<br>
<br>
- void setProgramHeader(ELFProgramHeader<target_endianness, is64Bits> *p) {<br>
+ void setProgramHeader(<br>
+ ELFProgramHeader<target_endianness, max_align, is64Bits> *p) {<br>
_programHeader = p;<br>
}<br>
<br>
@@ -1710,7 +1750,8 @@<br>
}<br>
// Add the program header<br>
if (_programHeader) {<br>
- _programHeader->setVAddr(uint64_t(virtualAddress + _elfHeader->fileSize()));<br>
+ _programHeader->setVAddr(<br>
+ uint64_t(virtualAddress + _elfHeader->fileSize()));<br>
_programHeader->setFileOffset(_elfHeader->fileSize());<br>
}<br>
bool newSegmentHeaderAdded = true;<br>
@@ -1719,7 +1760,7 @@<br>
newSegmentHeaderAdded = _programHeader->addSegment(si);<br>
numSlices += si->numSlices();<br>
}<br>
- if (!newSegmentHeaderAdded)<br>
+ if (!newSegmentHeaderAdded)<br>
break;<br>
uint64_t fileoffset = _elfHeader->fileSize() + _programHeader->fileSize();<br>
uint64_t address = virtualAddress;<br>
@@ -1735,29 +1776,32 @@<br>
(*si)->setVAddr(virtualAddress);<br>
// The first segment has the virtualAddress set to the base address as<br>
// we have added the file header and the program header dont align the<br>
- // first segment to the pagesize<br>
+ // first segment to the pagesize<br>
(*si)->assignVirtualAddress(address, (si == _segments.begin()));<br>
(*si)->setMemSize(address - virtualAddress);<br>
virtualAddress = llvm::RoundUpToAlignment(address, _options.pageSize());<br>
}<br>
_programHeader->resetProgramHeaders();<br>
}<br>
- Section<target_endianness, is64Bits> *section;<br>
+ Section<target_endianness, max_align, is64Bits> *section;<br>
// Fix the offsets of all the atoms within a section<br>
for (auto &si : _sections) {<br>
- section = llvm::dyn_cast<Section<target_endianness, is64Bits>>(si);<br>
- if (section &&<br>
- DefaultELFLayout<target_endianness, is64Bits>::hasOutputSegment(section))<br>
+ section =<br>
+ llvm::dyn_cast<Section<target_endianness, max_align, is64Bits>>(si);<br>
+ if (section &&<br>
+ DefaultELFLayout<target_endianness,<br>
+ max_align, is64Bits>::hasOutputSegment(section))<br>
section->assignOffsets(section->fileOffset());<br>
}<br>
// Set the size of the merged Sections<br>
- for (auto msi = merged_sections_begin(), mse = merged_sections_end();<br>
+ for (auto msi = merged_sections_begin(), mse = merged_sections_end();<br>
msi != mse; ++msi) {<br>
uint64_t sectionfileoffset = 0;<br>
uint64_t startFileOffset = 0;<br>
uint64_t sectionsize = 0;<br>
bool isFirstSection = true;<br>
- for (auto si = (*msi)->begin_sections(); si != (*msi)->end_sections(); ++si) {<br>
+ for (auto si = (*msi)->begin_sections(); si != (*msi)->end_sections();<br>
+ ++si) {<br>
if (isFirstSection) {<br>
startFileOffset = (*si)->fileOffset();<br>
isFirstSection = false;<br>
@@ -1770,13 +1814,13 @@<br>
(*msi)->setSize(sectionsize);<br>
}<br>
// Set the virtual addr of the merged Sections<br>
- for (auto msi = merged_sections_begin(), mse = merged_sections_end();<br>
+ for (auto msi = merged_sections_begin(), mse = merged_sections_end();<br>
msi != mse; ++msi) {<br>
uint64_t sectionstartaddr = 0;<br>
uint64_t startaddr = 0;<br>
uint64_t sectionsize = 0;<br>
bool isFirstSection = true;<br>
- for (auto si = (*msi)->begin_sections(), se = (*msi)->end_sections();<br>
+ for (auto si = (*msi)->begin_sections(), se = (*msi)->end_sections();<br>
si != se; ++si) {<br>
if (isFirstSection) {<br>
startaddr = (*si)->virtualAddr();<br>
@@ -1799,12 +1843,13 @@<br>
size = si->fileSize();<br>
}<br>
fileoffset = fileoffset + size;<br>
- Section<target_endianness, is64Bits> *section;<br>
+ Section<target_endianness, max_align, is64Bits> *section;<br>
for (auto si : _sections) {<br>
- section = llvm::dyn_cast<Section<target_endianness, is64Bits>>(si);<br>
- if (section &&<br>
- DefaultELFLayout<target_endianness, is64Bits>::hasOutputSegment<br>
- (section))<br>
+ section =<br>
+ llvm::dyn_cast<Section<target_endianness, max_align, is64Bits>>(si);<br>
+ if (section &&<br>
+ DefaultELFLayout<target_endianness,<br>
+ max_align, is64Bits>::hasOutputSegment(section))<br>
continue;<br>
fileoffset = llvm::RoundUpToAlignment(fileoffset, si->align2());<br>
si->setFileOffset(fileoffset);<br>
@@ -1820,22 +1865,24 @@<br>
}<br>
<br>
bool findAtomAddrByName(const StringRef name, uint64_t &addr) {<br>
- Section<target_endianness, is64Bits> *section;<br>
+ Section<target_endianness, max_align, is64Bits> *section;<br>
for (auto ai = _sections.begin(); ai != _sections.end(); ++ai) {<br>
- if ((*ai)->kind() == Chunk<target_endianness, is64Bits>::K_ELFSection) {<br>
- section = llvm::dyn_cast<Section<target_endianness, is64Bits>>(*ai);<br>
+ if ((*ai)->kind() ==<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFSection) {<br>
+ section =<br>
+ llvm::dyn_cast<Section<target_endianness, max_align, is64Bits>>(*ai);<br>
if (section->findAtomAddrByName(name, addr))<br>
return true;<br>
}<br>
}<br>
- return false;<br>
+ return false;<br>
}<br>
<br>
- MergedSectionIter merged_sections_begin() {<br>
+ MergedSectionIter merged_sections_begin() {<br>
return _mergedSections.begin();<br>
}<br>
<br>
- MergedSectionIter merged_sections_end() {<br>
+ MergedSectionIter merged_sections_end() {<br>
return _mergedSections.end();<br>
}<br>
<br>
@@ -1854,11 +1901,11 @@<br>
return _segments.end();<br>
}<br>
<br>
- ELFHeader<target_endianness, is64Bits> *elfHeader() {<br>
+ ELFHeader<target_endianness, max_align, is64Bits> *elfHeader() {<br>
return _elfHeader;<br>
}<br>
<br>
- ELFProgramHeader<target_endianness, is64Bits> *elfProgramHeader() {<br>
+ ELFProgramHeader<target_endianness, max_align, is64Bits> *elfProgramHeader() {<br>
return _programHeader;<br>
}<br>
<br>
@@ -1867,11 +1914,12 @@<br>
MergedSectionMapT _mergedSectionMap;<br>
SegmentMapT _segmentMap;<br>
<br>
- std::vector<Chunk<target_endianness, is64Bits> *> _sections;<br>
- std::vector<Segment<target_endianness, is64Bits> *> _segments;<br>
- std::vector<MergedSections<target_endianness, is64Bits> *> _mergedSections;<br>
- ELFHeader<target_endianness, is64Bits> *_elfHeader;<br>
- ELFProgramHeader<target_endianness, is64Bits> *_programHeader;<br>
+ std::vector<Chunk<target_endianness, max_align, is64Bits> *> _sections;<br>
+ std::vector<Segment<target_endianness, max_align, is64Bits> *> _segments;<br>
+ std::vector<MergedSections<target_endianness, max_align, is64Bits> *><br>
+ _mergedSections;<br>
+ ELFHeader<target_endianness, max_align, is64Bits> *_elfHeader;<br>
+ ELFProgramHeader<target_endianness, max_align, is64Bits> *_programHeader;<br>
llvm::BumpPtrAllocator _allocator;<br>
const WriterOptionsELF &_options;<br>
};<br>
@@ -1879,16 +1927,18 @@<br>
//===----------------------------------------------------------------------===//<br>
// ELFExecutableWriter Class<br>
//===----------------------------------------------------------------------===//<br>
-template<support::endianness target_endianness, bool is64Bits><br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
class ELFExecutableWriter : public ELFWriter {<br>
public:<br>
- typedef object::Elf_Shdr_Impl<target_endianness, is64Bits> Elf_Shdr;<br>
- typedef object::Elf_Sym_Impl<target_endianness, is64Bits> Elf_Sym;<br>
+ typedef Elf_Shdr_Impl<target_endianness, max_align, is64Bits> Elf_Shdr;<br>
+ typedef Elf_Sym_Impl<target_endianness, max_align, is64Bits> Elf_Sym;<br>
<br>
ELFExecutableWriter(const WriterOptionsELF &options);<br>
<br>
private:<br>
- // build the sections that need to be created<br>
+ // build the sections that need to be created<br>
void buildChunks(const lld::File &file);<br>
virtual error_code writeFile(const lld::File &File, StringRef path);<br>
void buildAtomToAddressMap();<br>
@@ -1897,7 +1947,7 @@<br>
void assignSectionsWithNoSegments();<br>
void addAbsoluteUndefinedSymbols(const lld::File &File);<br>
<br>
- uint64_t addressOfAtom(const Atom *atom) {<br>
+ uint64_t addressOfAtom(const Atom *atom) {<br>
return _atomToAddressMap[atom];<br>
}<br>
<br>
@@ -1911,114 +1961,140 @@<br>
std::unique_ptr<KindHandler> _referenceKindHandler;<br>
AtomToAddress _atomToAddressMap;<br>
llvm::BumpPtrAllocator _chunkAllocate;<br>
- DefaultELFLayout<target_endianness, is64Bits> *_layout;<br>
- ELFHeader<target_endianness, is64Bits> *_elfHeader;<br>
- ELFProgramHeader<target_endianness, is64Bits> *_programHeader;<br>
- ELFSymbolTable<target_endianness, is64Bits> * _symtab;<br>
- ELFStringTable<target_endianness, is64Bits> *_strtab;<br>
- ELFStringTable<target_endianness, is64Bits> *_shstrtab;<br>
- ELFSectionHeader<target_endianness, is64Bits> *_shdrtab;<br>
+ DefaultELFLayout<target_endianness, max_align, is64Bits> *_layout;<br>
+ ELFHeader<target_endianness, max_align, is64Bits> *_elfHeader;<br>
+ ELFProgramHeader<target_endianness, max_align, is64Bits> *_programHeader;<br>
+ ELFSymbolTable<target_endianness, max_align, is64Bits> * _symtab;<br>
+ ELFStringTable<target_endianness, max_align, is64Bits> *_strtab;<br>
+ ELFStringTable<target_endianness, max_align, is64Bits> *_shstrtab;<br>
+ ELFSectionHeader<target_endianness, max_align, is64Bits> *_shdrtab;<br>
};<br>
<br>
//===----------------------------------------------------------------------===//<br>
// ELFExecutableWriter<br>
//===----------------------------------------------------------------------===//<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-ELFExecutableWriter<target_endianness, is64Bits><br>
- ::ELFExecutableWriter(const WriterOptionsELF &options)<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+ELFExecutableWriter<target_endianness, max_align, is64Bits><br>
+ ::ELFExecutableWriter(const WriterOptionsELF &options)<br>
: _options(options)<br>
, _referenceKindHandler(KindHandler::makeHandler(_options.machine(),<br>
- target_endianness))<br>
-{<br>
- _layout = new DefaultELFLayout<target_endianness, is64Bits>(options);<br>
+ target_endianness)) {<br>
+ _layout =<br>
+ new DefaultELFLayout<target_endianness, max_align, is64Bits>(options);<br>
}<br>
<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-void ELFExecutableWriter<target_endianness, is64Bits><br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+void ELFExecutableWriter<target_endianness, max_align, is64Bits><br>
::buildChunks(const lld::File &file){<br>
for (const DefinedAtom *definedAtom : file.defined() ) {<br>
_layout->addAtom(definedAtom);<br>
}<br>
}<br>
<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-void ELFExecutableWriter<target_endianness, is64Bits>::buildSymbolTable () {<br>
- Section<target_endianness, is64Bits> *section;<br>
- for (auto si = _layout->sections_begin(); si != _layout->sections_end(); ++si) {<br>
- if ((*si)->kind() != Chunk<target_endianness, is64Bits>::K_ELFSection)<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+void ELFExecutableWriter<target_endianness, max_align, is64Bits><br>
+ ::buildSymbolTable () {<br>
+ Section<target_endianness, max_align, is64Bits> *section;<br>
+ for (auto si = _layout->sections_begin(); si != _layout->sections_end();<br>
+ ++si) {<br>
+ if ((*si)->kind() !=<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFSection)<br>
continue;<br>
- section = llvm::dyn_cast<Section<target_endianness, is64Bits>>(*si);<br>
+ section =<br>
+ llvm::dyn_cast<Section<target_endianness, max_align, is64Bits>>(*si);<br>
for (auto ai = section->atoms_begin(); ai != section->atoms_end(); ++ai) {<br>
_symtab->addSymbol(ai->first, section->ordinal(), ai->second.second);<br>
}<br>
}<br>
}<br>
<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-void ELFExecutableWriter<target_endianness, is64Bits>::<br>
- addAbsoluteUndefinedSymbols(const lld::File &file) {<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+void ELFExecutableWriter<target_endianness, max_align, is64Bits><br>
+ ::addAbsoluteUndefinedSymbols(const lld::File &file) {<br>
for (const UndefinedAtom *a : file.undefined()) {<br>
_symtab->addSymbol(a, ELF::SHN_UNDEF);<br>
}<br>
-<br>
+<br>
for (const AbsoluteAtom *a : file.absolute()) {<br>
_symtab->addSymbol(a, ELF::SHN_ABS);<br>
}<br>
}<br>
<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-void ELFExecutableWriter<target_endianness, is64Bits><br>
- ::buildAtomToAddressMap () {<br>
- Section<target_endianness, is64Bits> *section;<br>
- for (auto si = _layout->sections_begin();<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+void ELFExecutableWriter<target_endianness, max_align, is64Bits><br>
+ ::buildAtomToAddressMap () {<br>
+ Section<target_endianness, max_align, is64Bits> *section;<br>
+ for (auto si = _layout->sections_begin();<br>
si != _layout->sections_end(); ++si) {<br>
- if ((*si)->kind() != Chunk<target_endianness, is64Bits>::K_ELFSection)<br>
+ if ((*si)->kind() !=<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFSection)<br>
continue;<br>
- section = llvm::dyn_cast<Section<target_endianness, is64Bits>>(*si);<br>
+ section =<br>
+ llvm::dyn_cast<Section<target_endianness, max_align, is64Bits>>(*si);<br>
for (auto ai = section->atoms_begin(); ai != section->atoms_end(); ++ai) {<br>
_atomToAddressMap[ai->first] = (ai)->second.second;<br>
}<br>
}<br>
}<br>
<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-void ELFExecutableWriter<target_endianness, is64Bits><br>
- ::buildSectionHeaderTable() {<br>
- for (auto msi = _layout->merged_sections_begin();<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+void ELFExecutableWriter<target_endianness, max_align, is64Bits><br>
+ ::buildSectionHeaderTable() {<br>
+ for (auto msi = _layout->merged_sections_begin();<br>
msi != _layout->merged_sections_end(); ++msi) {<br>
- if ((*msi)->kind() != Chunk<target_endianness, is64Bits>::K_ELFSection)<br>
+ if ((*msi)->kind() !=<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFSection)<br>
continue;<br>
if ((*msi)->hasSegment())<br>
_shdrtab->appendSection(*msi);<br>
}<br>
}<br>
<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-void ELFExecutableWriter<target_endianness, is64Bits><br>
- ::assignSectionsWithNoSegments() {<br>
- Section<target_endianness, is64Bits> *section;<br>
- for (auto msi = _layout->merged_sections_begin();<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+void ELFExecutableWriter<target_endianness, max_align, is64Bits><br>
+ ::assignSectionsWithNoSegments() {<br>
+ Section<target_endianness, max_align, is64Bits> *section;<br>
+ for (auto msi = _layout->merged_sections_begin();<br>
msi != _layout->merged_sections_end(); ++msi) {<br>
- if ((*msi)->kind() != Chunk<target_endianness, is64Bits>::K_ELFSection)<br>
+ if ((*msi)->kind() !=<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFSection)<br>
continue;<br>
if (!(*msi)->hasSegment())<br>
_shdrtab->appendSection(*msi);<br>
}<br>
_layout->assignOffsetsForMiscSections();<br>
- for (auto si = _layout->sections_begin();<br>
+ for (auto si = _layout->sections_begin();<br>
si != _layout->sections_end(); ++si) {<br>
- if ((*si)->kind() != Chunk<target_endianness, is64Bits>::K_ELFSection)<br>
+ if ((*si)->kind() !=<br>
+ Chunk<target_endianness, max_align, is64Bits>::K_ELFSection)<br>
continue;<br>
- section = llvm::dyn_cast<Section<target_endianness, is64Bits>>(*si);<br>
- if (!DefaultELFLayout<target_endianness, is64Bits>::hasOutputSegment<br>
- (section))<br>
+ section =<br>
+ llvm::dyn_cast<Section<target_endianness, max_align, is64Bits>>(*si);<br>
+ if (!DefaultELFLayout<target_endianness, max_align, is64Bits><br>
+ ::hasOutputSegment(section))<br>
_shdrtab->updateSection(section);<br>
}<br>
}<br>
<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-error_code ELFExecutableWriter<target_endianness, is64Bits><br>
- ::writeFile(const lld::File &file, StringRef path) {<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+error_code ELFExecutableWriter<target_endianness, max_align, is64Bits><br>
+ ::writeFile(const lld::File &file, StringRef path) {<br>
buildChunks(file);<br>
// Create the default sections like the symbol table, string table, and the<br>
// section string table<br>
@@ -2062,7 +2138,7 @@<br>
<br>
_elfHeader->e_ident(ELF::EI_CLASS, (_options.is64Bit() ? ELF::ELFCLASS64<br>
: ELF::ELFCLASS32));<br>
- _elfHeader->e_ident(ELF::EI_DATA, (_options.endianness() == llvm::support::big)<br>
+ _elfHeader->e_ident(ELF::EI_DATA, _options.endianness() == llvm::support::big<br>
? ELF::ELFDATA2MSB : ELF::ELFDATA2LSB);<br>
_elfHeader->e_ident(ELF::EI_VERSION, 1);<br>
_elfHeader->e_ident(ELF::EI_OSABI, 0);<br>
@@ -2086,25 +2162,33 @@<br>
return buffer->commit();<br>
}<br>
<br>
-template<support::endianness target_endianness, bool is64Bits><br>
-void ELFExecutableWriter<target_endianness, is64Bits><br>
- ::createDefaultSections() {<br>
- _elfHeader = new ELFHeader<target_endianness, is64Bits>();<br>
- _programHeader = new ELFProgramHeader<target_endianness, is64Bits>();<br>
+template<support::endianness target_endianness,<br>
+ std::size_t max_align,<br>
+ bool is64Bits><br>
+void ELFExecutableWriter<target_endianness, max_align, is64Bits><br>
+ ::createDefaultSections() {<br>
+ _elfHeader =<br>
+ new ELFHeader<target_endianness, max_align, is64Bits>();<br>
+ _programHeader =<br>
+ new ELFProgramHeader<target_endianness, max_align, is64Bits>();<br>
_layout->setELFHeader(_elfHeader);<br>
_layout->setProgramHeader(_programHeader);<br>
<br>
- _symtab = new ELFSymbolTable<target_endianness, is64Bits><br>
- (".symtab",<br>
- DefaultELFLayout<target_endianness, is64Bits>::ORDER_SYMBOL_TABLE);<br>
- _strtab = new ELFStringTable<target_endianness, is64Bits><br>
- (".strtab",<br>
- DefaultELFLayout<target_endianness, is64Bits>::ORDER_STRING_TABLE);<br>
- _shstrtab = new ELFStringTable<target_endianness, is64Bits><br>
- (".shstrtab",<br>
- DefaultELFLayout<target_endianness, is64Bits>::ORDER_SECTION_STRINGS);<br>
- _shdrtab = new ELFSectionHeader<target_endianness, is64Bits><br>
- (DefaultELFLayout<target_endianness, is64Bits>::ORDER_SECTION_HEADERS);<br>
+ _symtab = new ELFSymbolTable<target_endianness, max_align, is64Bits>(<br>
+ ".symtab",<br>
+ DefaultELFLayout<target_endianness, max_align, is64Bits><br>
+ ::ORDER_SYMBOL_TABLE);<br>
+ _strtab = new ELFStringTable<target_endianness, max_align, is64Bits>(<br>
+ ".strtab",<br>
+ DefaultELFLayout<target_endianness, max_align, is64Bits><br>
+ ::ORDER_STRING_TABLE);<br>
+ _shstrtab = new ELFStringTable<target_endianness, max_align, is64Bits>(<br>
+ ".shstrtab",<br>
+ DefaultELFLayout<target_endianness, max_align, is64Bits><br>
+ ::ORDER_SECTION_STRINGS);<br>
+ _shdrtab = new ELFSectionHeader<target_endianness, max_align, is64Bits>(<br>
+ DefaultELFLayout<target_endianness, max_align, is64Bits><br>
+ ::ORDER_SECTION_HEADERS);<br>
_layout->addSection(_symtab);<br>
_layout->addSection(_strtab);<br>
_layout->addSection(_shstrtab);<br>
@@ -2112,23 +2196,21 @@<br>
_symtab->setStringSection(_strtab);<br>
_layout->addSection(_shdrtab);<br>
}<br>
-<br>
} // namespace elf<br>
<br>
Writer *createWriterELF(const WriterOptionsELF &options) {<br>
-<br>
// Set the default layout to be the static executable layout<br>
- // We would set the layout to a dynamic executable layout<br>
+ // We would set the layout to a dynamic executable layout<br>
// if we came across any shared libraries in the process<br>
-<br>
+<br>
if (!options.is64Bit() && options.endianness() == llvm::support::little)<br>
- return new lld::elf::ELFExecutableWriter<support::little, false>(options);<br>
+ return new elf::ELFExecutableWriter<support::little, 4, false>(options);<br>
else if (options.is64Bit() && options.endianness() == llvm::support::little)<br>
- return new lld::elf::ELFExecutableWriter<support::little, true>(options);<br>
+ return new elf::ELFExecutableWriter<support::little, 8, true>(options);<br>
else if (!options.is64Bit() && options.endianness() == llvm::support::big)<br>
- return new lld::elf::ELFExecutableWriter<support::big, false>(options);<br>
+ return new elf::ELFExecutableWriter<support::big, 4, false>(options);<br>
else if (options.is64Bit() && options.endianness() == llvm::support::big)<br>
- return new lld::elf::ELFExecutableWriter<support::big, true>(options);<br>
+ return new elf::ELFExecutableWriter<support::big, 8, true>(options);<br>
<br>
llvm_unreachable("Invalid Options!");<br>
}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>