[llvm-commits] [lld] r171526 - in /lld/trunk/lib/ReaderWriter/ELF: AtomsELF.h ReaderELF.cpp WriterELF.cpp
Michael Spencer
bigcheesegs at gmail.com
Fri Jan 4 14:26:25 PST 2013
On Fri, Jan 4, 2013 at 1:24 PM, Chandler Carruth <chandlerc at google.com> wrote:
> Tests?
This is already tested by the archive tests. They only failed under
-fsanitize=undefined. They no longer fail with this patch.
- Michael Spencer
>
>
> 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->
>
> ...
>
> [Message clipped]
More information about the llvm-commits
mailing list