diff options
Diffstat (limited to 'lld/lib/ReaderWriter/ELF')
-rw-r--r-- | lld/lib/ReaderWriter/ELF/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/DefaultELFLayout.h | 14 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h | 18 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp | 13 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ELFWriter.h | 2 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ExecutableAtoms.h | 6 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ReaderELF.cpp | 26 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp | 21 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/ReferenceKinds.h | 9 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/WriterELF.cpp | 54 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp | 28 |
11 files changed, 85 insertions, 107 deletions
diff --git a/lld/lib/ReaderWriter/ELF/CMakeLists.txt b/lld/lib/ReaderWriter/ELF/CMakeLists.txt index aa3e54cd1ab..b12d56450c1 100644 --- a/lld/lib/ReaderWriter/ELF/CMakeLists.txt +++ b/lld/lib/ReaderWriter/ELF/CMakeLists.txt @@ -5,7 +5,6 @@ add_lld_library(lldELF ReaderELF.cpp ReferenceKinds.cpp WriterELF.cpp - WriterOptionsELF.cpp X86Reference.cpp X86_64Reference.cpp ) diff --git a/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h b/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h index ae859d8d05f..86e61ecc020 100644 --- a/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h +++ b/lld/lib/ReaderWriter/ELF/DefaultELFLayout.h @@ -10,6 +10,8 @@ #ifndef LLD_READER_WRITER_DEFAULT_ELF_LAYOUT_H_ #define LLD_READER_WRITER_DEFAULT_ELF_LAYOUT_H_ +#include "lld/Core/LinkerOptions.h" + #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Hashing.h" @@ -150,7 +152,7 @@ public: typedef typename std::vector<AbsoluteAtomPair>::iterator AbsoluteAtomIterT; - DefaultELFLayout(const WriterOptionsELF &options) : _options(options) {} + DefaultELFLayout(const ELFTargetInfo &ti) : _targetInfo(ti) {} /// \brief Return the section order for a input section virtual SectionOrder getSectionOrder @@ -250,7 +252,7 @@ private: ELFProgramHeader<ELFT> *_programHeader; std::vector<AbsoluteAtomPair> _absoluteAtoms; llvm::BumpPtrAllocator _allocator; - const WriterOptionsELF _options; + const ELFTargetInfo &_targetInfo; }; template<class ELFT> @@ -483,7 +485,7 @@ DefaultELFLayout<ELFT>::assignSectionsToSegments() { segment = segmentInsert.first->second; } else { segment = new (_allocator.Allocate<Segment<ELFT>>()) Segment<ELFT>( - segmentName, getSegmentType(section), _options); + segmentName, getSegmentType(section), _targetInfo); segmentInsert.first->second = segment; _segments.push_back(segment); } @@ -516,7 +518,7 @@ DefaultELFLayout<ELFT>::assignVirtualAddress() { if (_segments.empty()) return; - uint64_t virtualAddress = _options.baseAddress(); + uint64_t virtualAddress = _targetInfo.getLinkerOptions()._baseAddress; // HACK: This is a super dirty hack. The elf header and program header are // not part of a section, but we need them to be loaded at the base address @@ -539,7 +541,7 @@ DefaultELFLayout<ELFT>::assignVirtualAddress() { for (auto &si : _segments) { // Align the segment to a page boundary fileoffset = llvm::RoundUpToAlignment(fileoffset, - _options.pageSize()); + _targetInfo.getPageSize()); si->assignOffsets(fileoffset); fileoffset = si->fileOffset() + si->fileSize(); } @@ -552,7 +554,7 @@ DefaultELFLayout<ELFT>::assignVirtualAddress() { (*si)->assignVirtualAddress(address); (*si)->setMemSize(address - virtualAddress); virtualAddress = llvm::RoundUpToAlignment(address, - _options.pageSize()); + _targetInfo.getPageSize()); } _programHeader->resetProgramHeaders(); } diff --git a/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h b/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h index 0e329b4c6fd..177313776b9 100644 --- a/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h +++ b/lld/lib/ReaderWriter/ELF/ELFSegmentChunks.h @@ -11,7 +11,7 @@ #define LLD_READER_WRITER_ELF_SEGMENT_CHUNKS_H_ #include "lld/Core/range.h" -#include "lld/ReaderWriter/WriterELF.h" +#include "lld/ReaderWriter/Writer.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/OwningPtr.h" @@ -113,7 +113,7 @@ public: Segment(const StringRef name, const ELFLayout::SegmentType type, - const WriterOptionsELF &options); + const ELFTargetInfo &ti); /// append a section to a segment void append(Section<ELFT> *section); @@ -168,7 +168,7 @@ public: inline ELFLayout::SegmentType segmentType() { return _segmentType; } - inline int pageSize() const { return _options.pageSize(); } + inline int pageSize() const { return _targetInfo.getPageSize(); } inline int64_t atomflags() const { return _atomflags; } @@ -195,19 +195,19 @@ protected: ELFLayout::SegmentType _segmentType; int64_t _flags; int64_t _atomflags; - const WriterOptionsELF _options; + const ELFTargetInfo &_targetInfo; llvm::BumpPtrAllocator _segmentAllocate; }; template<class ELFT> Segment<ELFT>::Segment(const StringRef name, const ELFLayout::SegmentType type, - const WriterOptionsELF &options) + const ELFTargetInfo &ti) : Chunk<ELFT>(name, Chunk<ELFT>::K_ELFSegment) , _segmentType(type) , _flags(0) , _atomflags(0) - , _options(options) { + , _targetInfo(ti) { this->_align2 = 0; this->_fsize = 0; } @@ -268,7 +268,7 @@ Segment<ELFT>::assignOffsets(uint64_t startOffset) { SegmentSlice<ELFT> *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()) { + if ((newOffset - curOffset) > _targetInfo.getPageSize()) { // TODO: use std::find here for (auto s : slices()) { if (s->startSection() == startSection) { @@ -286,7 +286,7 @@ Segment<ELFT>::assignOffsets(uint64_t startOffset) { slice->setSize(curSliceSize); slice->setAlign(sliceAlign); uint64_t newPageOffset = - llvm::RoundUpToAlignment(curOffset, _options.pageSize()); + llvm::RoundUpToAlignment(curOffset, _targetInfo.getPageSize()); newOffset = llvm::RoundUpToAlignment(newPageOffset, (*si)->align2()); curSliceFileOffset = newOffset; startSectionIter = endSectionIter; @@ -332,7 +332,7 @@ void Segment<ELFT>::assignVirtualAddress(uint64_t &addr) { for (auto slice : slices()) { // Align to a page - addr = llvm::RoundUpToAlignment(addr, _options.pageSize()); + addr = llvm::RoundUpToAlignment(addr, _targetInfo.getPageSize()); // Align to the slice alignment addr = llvm::RoundUpToAlignment(addr, slice->align2()); diff --git a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp index 9a086f83cef..5c4cbfceb00 100644 --- a/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp +++ b/lld/lib/ReaderWriter/ELF/ELFTargetInfo.cpp @@ -23,6 +23,13 @@ uint16_t ELFTargetInfo::getOutputType() const { return llvm::ELF::ET_REL; case OutputKind::Shared: return llvm::ELF::ET_DYN; + case OutputKind::Core: + return llvm::ELF::ET_CORE; + case OutputKind::SharedStubs: + case OutputKind::DebugSymbols: + case OutputKind::Bundle: + case OutputKind::Preload: + break; } llvm_unreachable("Unhandled OutputKind"); } @@ -42,21 +49,21 @@ uint16_t ELFTargetInfo::getOutputMachine() const { } } -class X86ELFTargetInfo final : public ELFTargetInfo { +class X86ELFTargetInfo LLVM_FINAL : public ELFTargetInfo { public: X86ELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {} virtual uint64_t getPageSize() const { return 0x1000; } }; -class HexagonELFTargetInfo final : public ELFTargetInfo { +class HexagonELFTargetInfo LLVM_FINAL : public ELFTargetInfo { public: HexagonELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {} virtual uint64_t getPageSize() const { return 0x1000; } }; -class PPCELFTargetInfo final : public ELFTargetInfo { +class PPCELFTargetInfo LLVM_FINAL : public ELFTargetInfo { public: PPCELFTargetInfo(const LinkerOptions &lo) : ELFTargetInfo(lo) {} diff --git a/lld/lib/ReaderWriter/ELF/ELFWriter.h b/lld/lib/ReaderWriter/ELF/ELFWriter.h index 517d61c9569..20b83fd0713 100644 --- a/lld/lib/ReaderWriter/ELF/ELFWriter.h +++ b/lld/lib/ReaderWriter/ELF/ELFWriter.h @@ -12,7 +12,7 @@ #include "lld/Core/File.h" #include "lld/Core/InputFiles.h" -#include "lld/ReaderWriter/WriterELF.h" +#include "lld/ReaderWriter/Writer.h" #include "ReferenceKinds.h" namespace lld { diff --git a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h index 1820b2cbf35..f0531ac6d13 100644 --- a/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h +++ b/lld/lib/ReaderWriter/ELF/ExecutableAtoms.h @@ -15,7 +15,7 @@ #include "lld/Core/UndefinedAtom.h" #include "lld/Core/File.h" #include "lld/Core/Reference.h" -#include "lld/ReaderWriter/WriterELF.h" +#include "lld/ReaderWriter/Writer.h" #include "AtomsELF.h" namespace lld { @@ -30,9 +30,7 @@ template<class ELFT> class CRuntimeFile : public File { public: typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym; - CRuntimeFile(const WriterOptionsELF &options) - : File("C runtime") - { } + CRuntimeFile(const ELFTargetInfo &) : File("C runtime") {} /// \brief add a global absolute atom void addAbsoluteAtom(const StringRef symbolName) { diff --git a/lld/lib/ReaderWriter/ELF/ReaderELF.cpp b/lld/lib/ReaderWriter/ELF/ReaderELF.cpp index 16e53f221c6..deaf66354c4 100644 --- a/lld/lib/ReaderWriter/ELF/ReaderELF.cpp +++ b/lld/lib/ReaderWriter/ELF/ReaderELF.cpp @@ -13,10 +13,12 @@ /// //===----------------------------------------------------------------------===// -#include "lld/ReaderWriter/ReaderELF.h" -#include "lld/ReaderWriter/ReaderArchive.h" +#include "lld/ReaderWriter/Reader.h" + #include "lld/Core/File.h" #include "lld/Core/Reference.h" +#include "lld/ReaderWriter/ELFTargetInfo.h" +#include "lld/ReaderWriter/ReaderArchive.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallString.h" @@ -326,12 +328,9 @@ private: /// memory buffer for ELF class and bit width class ReaderELF : public Reader { public: - ReaderELF(const ReaderOptionsELF &, - ReaderOptionsArchive &readerOptionsArchive) - : _readerOptionsArchive(readerOptionsArchive), - _readerArchive(_readerOptionsArchive) { - _readerOptionsArchive.setReader(this); - } + ReaderELF(const TargetInfo & ti, std::function<ReaderFunc> read) + : Reader(ti), + _readerArchive(ti, read) {} error_code parseFile(std::unique_ptr<MemoryBuffer> mb, std::vector<std::unique_ptr<File>> &result) { @@ -411,18 +410,13 @@ public: } private: - ReaderOptionsArchive &_readerOptionsArchive; ReaderArchive _readerArchive; }; } // end anon namespace. namespace lld { -ReaderOptionsELF::ReaderOptionsELF() {} - -ReaderOptionsELF::~ReaderOptionsELF() {} - -Reader *createReaderELF(const ReaderOptionsELF &options, - ReaderOptionsArchive &optionsArchive) { - return new ReaderELF(options, optionsArchive); +std::unique_ptr<Reader> createReaderELF(const TargetInfo & ti, + std::function<ReaderFunc> read) { + return std::unique_ptr<Reader>(new ReaderELF(ti, std::move(read))); } } // end namespace lld diff --git a/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp b/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp index 083e843237c..769895ab843 100644 --- a/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp +++ b/lld/lib/ReaderWriter/ELF/ReferenceKinds.cpp @@ -11,29 +11,30 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Triple.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ELF.h" namespace lld { namespace elf { -KindHandler::KindHandler() { -} +KindHandler::KindHandler() {} -KindHandler::~KindHandler() { -} +KindHandler::~KindHandler() {} std::unique_ptr<KindHandler> -KindHandler::makeHandler(uint16_t arch, llvm::support::endianness endian) { +KindHandler::makeHandler(llvm::Triple::ArchType arch, bool isLittleEndian) { switch(arch) { - case llvm::ELF::EM_HEXAGON: + case llvm::Triple::hexagon: return std::unique_ptr<KindHandler>(new HexagonKindHandler()); - case llvm::ELF::EM_386: + case llvm::Triple::x86: return std::unique_ptr<KindHandler>(new X86KindHandler()); - case llvm::ELF::EM_X86_64: + case llvm::Triple::x86_64: return std::unique_ptr<KindHandler>(new X86_64KindHandler()); - case llvm::ELF::EM_PPC: - return std::unique_ptr<KindHandler>(new PPCKindHandler(endian)); + case llvm::Triple::ppc: + return std::unique_ptr<KindHandler>( + new PPCKindHandler(isLittleEndian ? llvm::support::little + : llvm::support::big)); default: llvm_unreachable("arch not supported"); } diff --git a/lld/lib/ReaderWriter/ELF/ReferenceKinds.h b/lld/lib/ReaderWriter/ELF/ReferenceKinds.h index faa4299700c..45f6cae66da 100644 --- a/lld/lib/ReaderWriter/ELF/ReferenceKinds.h +++ b/lld/lib/ReaderWriter/ELF/ReferenceKinds.h @@ -9,9 +9,12 @@ #include "lld/Core/LLVM.h" #include "lld/Core/Reference.h" -#include "lld/ReaderWriter/WriterELF.h" +#include "lld/ReaderWriter/Writer.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Support/ELF.h" +#include "llvm/Support/Endian.h" #include <functional> #include <map> @@ -32,8 +35,8 @@ class KindHandler { public: typedef Reference::Kind Kind; - static std::unique_ptr<KindHandler> makeHandler(uint16_t arch, - llvm::support::endianness endian); + static std::unique_ptr<KindHandler> makeHandler(llvm::Triple::ArchType arch, + bool isLittleEndian); virtual ~KindHandler(); virtual Kind stringToKind(StringRef str) = 0; virtual StringRef kindToString(Kind) = 0; diff --git a/lld/lib/ReaderWriter/ELF/WriterELF.cpp b/lld/lib/ReaderWriter/ELF/WriterELF.cpp index d9be025c5ca..73bb6bb6103 100644 --- a/lld/lib/ReaderWriter/ELF/WriterELF.cpp +++ b/lld/lib/ReaderWriter/ELF/WriterELF.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +#include "lld/ReaderWriter/ELFTargetInfo.h" + #include "DefaultELFLayout.h" #include "ExecutableAtoms.h" @@ -26,7 +28,7 @@ public: typedef Elf_Shdr_Impl<ELFT> Elf_Shdr; typedef Elf_Sym_Impl<ELFT> Elf_Sym; - ELFExecutableWriter(const WriterOptionsELF &options); + ELFExecutableWriter(const ELFTargetInfo &ti); private: // build the sections that need to be created @@ -49,7 +51,7 @@ private: void createDefaultSections(); - const WriterOptionsELF &_options; + const ELFTargetInfo &_targetInfo; typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress; std::unique_ptr<KindHandler> _referenceKindHandler; @@ -69,12 +71,12 @@ private: // ELFExecutableWriter //===----------------------------------------------------------------------===// template<class ELFT> -ELFExecutableWriter<ELFT>::ELFExecutableWriter(const WriterOptionsELF &options) - : _options(options) +ELFExecutableWriter<ELFT>::ELFExecutableWriter(const ELFTargetInfo &ti) + : _targetInfo(ti) , _referenceKindHandler(KindHandler::makeHandler( - _options.machine(), (endianness)ELFT::TargetEndianness)) - , _runtimeFile(options) { - _layout =new DefaultELFLayout<ELFT>(options); + ti.getTriple().getArch(), ti.isLittleEndian())) + , _runtimeFile(ti) { + _layout = new DefaultELFLayout<ELFT>(ti); } template<class ELFT> @@ -248,14 +250,14 @@ ELFExecutableWriter<ELFT>::writeFile(const lld::File &file, StringRef path) { if (ec) return ec; - _elfHeader->e_ident(ELF::EI_CLASS, (_options.is64Bit() ? ELF::ELFCLASS64 - : ELF::ELFCLASS32)); - _elfHeader->e_ident(ELF::EI_DATA, _options.endianness() == llvm::support::big - ? ELF::ELFDATA2MSB : ELF::ELFDATA2LSB); + _elfHeader->e_ident(ELF::EI_CLASS, _targetInfo.is64Bits() ? ELF::ELFCLASS64 + : ELF::ELFCLASS32); + _elfHeader->e_ident(ELF::EI_DATA, _targetInfo.isLittleEndian() + ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); _elfHeader->e_ident(ELF::EI_VERSION, 1); _elfHeader->e_ident(ELF::EI_OSABI, 0); - _elfHeader->e_type(_options.type()); - _elfHeader->e_machine(_options.machine()); + _elfHeader->e_type(_targetInfo.getOutputType()); + _elfHeader->e_machine(_targetInfo.getOutputMachine()); _elfHeader->e_version(1); _elfHeader->e_entry(0ULL); _elfHeader->e_phoff(_programHeader->fileOffset()); @@ -305,24 +307,24 @@ void ELFExecutableWriter<ELFT>::createDefaultSections() { } } // namespace elf -Writer *createWriterELF(const WriterOptionsELF &options) { +std::unique_ptr<Writer> createWriterELF(const ELFTargetInfo &TI) { using llvm::object::ELFType; // Set the default layout to be the static 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 elf::ELFExecutableWriter<ELFType<support::little, 4, false>>(options); - else if (options.is64Bit() && options.endianness() == llvm::support::little) - return - new elf::ELFExecutableWriter<ELFType<support::little, 8, true>>(options); - else if (!options.is64Bit() && options.endianness() == llvm::support::big) - return - new elf::ELFExecutableWriter<ELFType<support::big, 4, false>>(options); - else if (options.is64Bit() && options.endianness() == llvm::support::big) - return - new elf::ELFExecutableWriter<ELFType<support::big, 8, true>>(options); + if (!TI.is64Bits() && TI.isLittleEndian()) + return std::unique_ptr<Writer>(new + elf::ELFExecutableWriter<ELFType<support::little, 4, false>>(TI)); + else if (TI.is64Bits() && TI.isLittleEndian()) + return std::unique_ptr<Writer>(new + elf::ELFExecutableWriter<ELFType<support::little, 8, true>>(TI)); + else if (!TI.is64Bits() && !TI.isLittleEndian()) + return std::unique_ptr<Writer>(new + elf::ELFExecutableWriter<ELFType<support::big, 4, false>>(TI)); + else if (TI.is64Bits() && !TI.isLittleEndian()) + return std::unique_ptr<Writer>(new + elf::ELFExecutableWriter<ELFType<support::big, 8, true>>(TI)); llvm_unreachable("Invalid Options!"); } diff --git a/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp b/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp deleted file mode 100644 index 4d832aed05e..00000000000 --- a/lld/lib/ReaderWriter/ELF/WriterOptionsELF.cpp +++ /dev/null @@ -1,28 +0,0 @@ -//===- lib/ReaderWriter/ELF/WriterOptionsELF.cpp ----------------------===// -// -// The LLVM Linker -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lld/ReaderWriter/WriterELF.h" - -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/ELF.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/system_error.h" - - -namespace lld { - -StringRef WriterOptionsELF::entryPoint() const { - if (_type == llvm::ELF::ET_EXEC) - return _entryPoint; - return StringRef(); -} - -} // namespace lld |