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