[lld] r238310 - [Mips] Move member function definitions to cpp files
Simon Atanasyan
simon at atanasyan.com
Wed May 27 04:56:15 PDT 2015
Author: atanasyan
Date: Wed May 27 06:56:15 2015
New Revision: 238310
URL: http://llvm.org/viewvc/llvm-project?rev=238310&view=rev
Log:
[Mips] Move member function definitions to cpp files
No functional changes.
Added:
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp
- copied, changed from r238304, lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp
Removed:
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler64EL.cpp
Modified:
lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt?rev=238310&r1=238309&r2=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/CMakeLists.txt Wed May 27 06:56:15 2015
@@ -1,11 +1,14 @@
add_llvm_library(lldMipsELFTarget
MipsCtorsOrderPass.cpp
+ MipsELFFile.cpp
MipsELFFlagsMerger.cpp
+ MipsELFWriters.cpp
MipsLinkingContext.cpp
MipsRelocationHandler.cpp
MipsRelocationPass.cpp
- MipsTargetHandler32EL.cpp
- MipsTargetHandler64EL.cpp
+ MipsSectionChunks.cpp
+ MipsTargetHandler.cpp
+ MipsTargetLayout.cpp
LINK_LIBS
lldELF
lldReaderWriter
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h?rev=238309&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h (removed)
@@ -1,117 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsDynamicLibraryWriter.h ---------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_DYNAMIC_LIBRARY_WRITER_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_DYNAMIC_LIBRARY_WRITER_H
-
-#include "DynamicLibraryWriter.h"
-#include "MipsDynamicTable.h"
-#include "MipsELFWriters.h"
-#include "MipsLinkingContext.h"
-#include "MipsSectionChunks.h"
-
-namespace lld {
-namespace elf {
-
-template <typename ELFT> class MipsSymbolTable;
-template <typename ELFT> class MipsDynamicSymbolTable;
-template <typename ELFT> class MipsTargetLayout;
-
-template <class ELFT>
-class MipsDynamicLibraryWriter : public DynamicLibraryWriter<ELFT> {
-public:
- MipsDynamicLibraryWriter(MipsLinkingContext &ctx,
- MipsTargetLayout<ELFT> &layout);
-
-protected:
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-
- void finalizeDefaultAtomValues() override;
- void createDefaultSections() override;
-
- std::error_code setELFHeader() override {
- DynamicLibraryWriter<ELFT>::setELFHeader();
- _writeHelper.setELFHeader(*this->_elfHeader);
- return std::error_code();
- }
-
- unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable() override;
- unique_bump_ptr<DynamicTable<ELFT>> createDynamicTable() override;
- unique_bump_ptr<DynamicSymbolTable<ELFT>> createDynamicSymbolTable() override;
-
-private:
- MipsELFWriter<ELFT> _writeHelper;
- MipsTargetLayout<ELFT> &_targetLayout;
- unique_bump_ptr<Section<ELFT>> _reginfo;
-};
-
-template <class ELFT>
-MipsDynamicLibraryWriter<ELFT>::MipsDynamicLibraryWriter(
- MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout)
- : DynamicLibraryWriter<ELFT>(ctx, layout), _writeHelper(ctx, layout),
- _targetLayout(layout) {}
-
-template <class ELFT>
-void MipsDynamicLibraryWriter<ELFT>::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- DynamicLibraryWriter<ELFT>::createImplicitFiles(result);
- result.push_back(_writeHelper.createRuntimeFile());
-}
-
-template <class ELFT>
-void MipsDynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
- // Finalize the atom values that are part of the parent.
- DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues();
- _writeHelper.finalizeMipsRuntimeAtomValues();
-}
-
-template <class ELFT>
-void MipsDynamicLibraryWriter<ELFT>::createDefaultSections() {
- DynamicLibraryWriter<ELFT>::createDefaultSections();
- const auto &ctx = static_cast<const MipsLinkingContext &>(this->_ctx);
- const auto &mask = ctx.getMergedReginfoMask();
- if (!mask.hasValue())
- return;
- if (ELFT::Is64Bits)
- _reginfo = unique_bump_ptr<Section<ELFT>>(
- new (this->_alloc) MipsOptionsSection<ELFT>(ctx, _targetLayout, *mask));
- else
- _reginfo = unique_bump_ptr<Section<ELFT>>(
- new (this->_alloc) MipsReginfoSection<ELFT>(ctx, _targetLayout, *mask));
- this->_layout.addSection(_reginfo.get());
-}
-
-template <class ELFT>
-unique_bump_ptr<SymbolTable<ELFT>>
- MipsDynamicLibraryWriter<ELFT>::createSymbolTable() {
- return unique_bump_ptr<SymbolTable<ELFT>>(
- new (this->_alloc) MipsSymbolTable<ELFT>(this->_ctx));
-}
-
-/// \brief create dynamic table
-template <class ELFT>
-unique_bump_ptr<DynamicTable<ELFT>>
- MipsDynamicLibraryWriter<ELFT>::createDynamicTable() {
- return unique_bump_ptr<DynamicTable<ELFT>>(
- new (this->_alloc) MipsDynamicTable<ELFT>(this->_ctx, _targetLayout));
-}
-
-/// \brief create dynamic symbol table
-template <class ELFT>
-unique_bump_ptr<DynamicSymbolTable<ELFT>>
- MipsDynamicLibraryWriter<ELFT>::createDynamicSymbolTable() {
- return unique_bump_ptr<DynamicSymbolTable<ELFT>>(
- new (this->_alloc)
- MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout));
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif
Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp?rev=238310&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.cpp Wed May 27 06:56:15 2015
@@ -0,0 +1,284 @@
+//===- lib/ReaderWriter/ELF/MipsELFFile.cpp -------------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MipsELFFile.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT>
+MipsELFDefinedAtom<ELFT>::MipsELFDefinedAtom(
+ const MipsELFFile<ELFT> &file, StringRef symbolName, StringRef sectionName,
+ const Elf_Sym *symbol, const Elf_Shdr *section,
+ ArrayRef<uint8_t> contentData, unsigned int referenceStart,
+ unsigned int referenceEnd, std::vector<ELFReference<ELFT> *> &referenceList)
+ : ELFDefinedAtom<ELFT>(file, symbolName, sectionName, symbol, section,
+ contentData, referenceStart, referenceEnd,
+ referenceList) {}
+
+template <class ELFT>
+const MipsELFFile<ELFT> &MipsELFDefinedAtom<ELFT>::file() const {
+ return static_cast<const MipsELFFile<ELFT> &>(this->_owningFile);
+}
+
+template <class ELFT>
+DefinedAtom::CodeModel MipsELFDefinedAtom<ELFT>::codeModel() const {
+ switch (this->_symbol->st_other & llvm::ELF::STO_MIPS_MIPS16) {
+ case llvm::ELF::STO_MIPS_MIPS16:
+ return DefinedAtom::codeMips16;
+ case llvm::ELF::STO_MIPS_PIC:
+ return DefinedAtom::codeMipsPIC;
+ case llvm::ELF::STO_MIPS_MICROMIPS:
+ return DefinedAtom::codeMipsMicro;
+ case llvm::ELF::STO_MIPS_MICROMIPS | llvm::ELF::STO_MIPS_PIC:
+ return DefinedAtom::codeMipsMicroPIC;
+ default:
+ return DefinedAtom::codeNA;
+ }
+}
+
+template class MipsELFDefinedAtom<ELF32LE>;
+template class MipsELFDefinedAtom<ELF64LE>;
+
+template <class ELFT> static bool isMips64EL() {
+ return ELFT::Is64Bits && ELFT::TargetEndianness == llvm::support::little;
+}
+
+template <class ELFT, bool isRela>
+static uint32_t
+extractTag(const llvm::object::Elf_Rel_Impl<ELFT, isRela> &rel) {
+ return (rel.getType(isMips64EL<ELFT>()) & 0xffffff00) >> 8;
+}
+
+template <class ELFT>
+MipsELFReference<ELFT>::MipsELFReference(uint64_t symValue, const Elf_Rela &rel)
+ : ELFReference<ELFT>(&rel, rel.r_offset - symValue,
+ Reference::KindArch::Mips,
+ rel.getType(isMips64EL<ELFT>()) & 0xff,
+ rel.getSymbol(isMips64EL<ELFT>())),
+ _tag(extractTag(rel)) {}
+
+template <class ELFT>
+MipsELFReference<ELFT>::MipsELFReference(uint64_t symValue, const Elf_Rel &rel)
+ : ELFReference<ELFT>(rel.r_offset - symValue, Reference::KindArch::Mips,
+ rel.getType(isMips64EL<ELFT>()) & 0xff,
+ rel.getSymbol(isMips64EL<ELFT>())),
+ _tag(extractTag(rel)) {}
+
+template class MipsELFReference<ELF32LE>;
+template class MipsELFReference<ELF64LE>;
+
+template <class ELFT>
+MipsELFFile<ELFT>::MipsELFFile(std::unique_ptr<MemoryBuffer> mb,
+ ELFLinkingContext &ctx)
+ : ELFFile<ELFT>(std::move(mb), ctx) {}
+
+template <class ELFT> bool MipsELFFile<ELFT>::isPIC() const {
+ return this->_objFile->getHeader()->e_flags & llvm::ELF::EF_MIPS_PIC;
+}
+
+template <class ELFT> std::error_code MipsELFFile<ELFT>::doParse() {
+ if (std::error_code ec = ELFFile<ELFT>::doParse())
+ return ec;
+ // Retrieve some auxiliary data like GP value, TLS section address etc
+ // from the object file.
+ return readAuxData();
+}
+
+template <class ELFT>
+ELFDefinedAtom<ELFT> *MipsELFFile<ELFT>::createDefinedAtom(
+ StringRef symName, StringRef sectionName, const Elf_Sym *sym,
+ const Elf_Shdr *sectionHdr, ArrayRef<uint8_t> contentData,
+ unsigned int referenceStart, unsigned int referenceEnd,
+ std::vector<ELFReference<ELFT> *> &referenceList) {
+ return new (this->_readerStorage) MipsELFDefinedAtom<ELFT>(
+ *this, symName, sectionName, sym, sectionHdr, contentData, referenceStart,
+ referenceEnd, referenceList);
+}
+
+template <class ELFT>
+const typename MipsELFFile<ELFT>::Elf_Shdr *
+MipsELFFile<ELFT>::findSectionByType(uint64_t type) const {
+ for (const Elf_Shdr §ion : this->_objFile->sections())
+ if (section.sh_type == type)
+ return §ion;
+ return nullptr;
+}
+
+template <class ELFT>
+const typename MipsELFFile<ELFT>::Elf_Shdr *
+MipsELFFile<ELFT>::findSectionByFlags(uint64_t flags) const {
+ for (const Elf_Shdr §ion : this->_objFile->sections())
+ if (section.sh_flags & flags)
+ return §ion;
+ return nullptr;
+}
+
+template <class ELFT>
+ErrorOr<const typename MipsELFFile<ELFT>::Elf_Mips_RegInfo *>
+MipsELFFile<ELFT>::findRegInfoSec() const {
+ using namespace llvm::ELF;
+ if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_OPTIONS)) {
+ auto contents = this->getSectionContents(sec);
+ if (std::error_code ec = contents.getError())
+ return ec;
+
+ ArrayRef<uint8_t> raw = contents.get();
+ while (!raw.empty()) {
+ if (raw.size() < sizeof(Elf_Mips_Options))
+ return make_dynamic_error_code(
+ StringRef("Invalid size of MIPS_OPTIONS section"));
+
+ const auto *opt = reinterpret_cast<const Elf_Mips_Options *>(raw.data());
+ if (opt->kind == ODK_REGINFO)
+ return &opt->getRegInfo();
+ raw = raw.slice(opt->size);
+ }
+ } else if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_REGINFO)) {
+ auto contents = this->getSectionContents(sec);
+ if (std::error_code ec = contents.getError())
+ return ec;
+
+ ArrayRef<uint8_t> raw = contents.get();
+ if (raw.size() != sizeof(Elf_Mips_RegInfo))
+ return make_dynamic_error_code(
+ StringRef("Invalid size of MIPS_REGINFO section"));
+
+ return reinterpret_cast<const Elf_Mips_RegInfo *>(raw.data());
+ }
+ return nullptr;
+}
+
+template <class ELFT> std::error_code MipsELFFile<ELFT>::readAuxData() {
+ using namespace llvm::ELF;
+ if (const Elf_Shdr *sec = findSectionByFlags(SHF_TLS)) {
+ _tpOff = sec->sh_addr + TP_OFFSET;
+ _dtpOff = sec->sh_addr + DTP_OFFSET;
+ }
+
+ auto &ctx = static_cast<MipsLinkingContext &>(this->_ctx);
+
+ ErrorOr<const Elf_Mips_RegInfo *> regInfoSec = findRegInfoSec();
+ if (auto ec = regInfoSec.getError())
+ return ec;
+ if (const Elf_Mips_RegInfo *regInfo = regInfoSec.get()) {
+ ctx.mergeReginfoMask(*regInfo);
+ _gp0 = regInfo->ri_gp_value;
+ }
+
+ const Elf_Ehdr *hdr = this->_objFile->getHeader();
+ if (std::error_code ec = ctx.mergeElfFlags(hdr->e_flags))
+ return ec;
+
+ return std::error_code();
+}
+
+template <class ELFT>
+void MipsELFFile<ELFT>::createRelocationReferences(const Elf_Sym *symbol,
+ ArrayRef<uint8_t> content,
+ range<Elf_Rela_Iter> rels) {
+ const auto value = this->getSymbolValue(symbol);
+ for (const auto &rel : rels) {
+ if (rel.r_offset < value || value + content.size() <= rel.r_offset)
+ continue;
+ auto r = new (this->_readerStorage) MipsELFReference<ELFT>(value, rel);
+ this->addReferenceToSymbol(r, symbol);
+ this->_references.push_back(r);
+ }
+}
+
+template <class ELFT>
+void MipsELFFile<ELFT>::createRelocationReferences(const Elf_Sym *symbol,
+ ArrayRef<uint8_t> symContent,
+ ArrayRef<uint8_t> secContent,
+ range<Elf_Rel_Iter> rels) {
+ const auto value = this->getSymbolValue(symbol);
+ for (Elf_Rel_Iter rit = rels.begin(), eit = rels.end(); rit != eit; ++rit) {
+ if (rit->r_offset < value || value + symContent.size() <= rit->r_offset)
+ continue;
+
+ auto r = new (this->_readerStorage) MipsELFReference<ELFT>(value, *rit);
+ this->addReferenceToSymbol(r, symbol);
+ this->_references.push_back(r);
+
+ auto addend = readAddend(*rit, secContent);
+ auto pairRelType = getPairRelocation(*rit);
+ if (pairRelType != llvm::ELF::R_MIPS_NONE) {
+ addend <<= 16;
+ auto mit = findMatchingRelocation(pairRelType, rit, eit);
+ if (mit != eit)
+ addend += int16_t(readAddend(*mit, secContent));
+ else
+ // FIXME (simon): Show detailed warning.
+ llvm::errs() << "lld warning: cannot matching LO16 relocation\n";
+ }
+ this->_references.back()->setAddend(addend);
+ }
+}
+
+template <class ELFT>
+static uint8_t
+getPrimaryType(const llvm::object::Elf_Rel_Impl<ELFT, false> &rel) {
+ return rel.getType(isMips64EL<ELFT>()) & 0xff;
+}
+
+template <class ELFT>
+Reference::Addend
+MipsELFFile<ELFT>::readAddend(const Elf_Rel &ri,
+ const ArrayRef<uint8_t> content) const {
+ return readMipsRelocAddend(getPrimaryType(ri), content.data() + ri.r_offset);
+}
+
+template <class ELFT>
+uint32_t MipsELFFile<ELFT>::getPairRelocation(const Elf_Rel &rel) const {
+ switch (getPrimaryType(rel)) {
+ case llvm::ELF::R_MIPS_HI16:
+ return llvm::ELF::R_MIPS_LO16;
+ case llvm::ELF::R_MIPS_PCHI16:
+ return llvm::ELF::R_MIPS_PCLO16;
+ case llvm::ELF::R_MIPS_GOT16:
+ if (isLocalBinding(rel))
+ return llvm::ELF::R_MIPS_LO16;
+ break;
+ case llvm::ELF::R_MICROMIPS_HI16:
+ return llvm::ELF::R_MICROMIPS_LO16;
+ case llvm::ELF::R_MICROMIPS_GOT16:
+ if (isLocalBinding(rel))
+ return llvm::ELF::R_MICROMIPS_LO16;
+ break;
+ default:
+ // Nothing to do.
+ break;
+ }
+ return llvm::ELF::R_MIPS_NONE;
+}
+
+template <class ELFT>
+typename MipsELFFile<ELFT>::Elf_Rel_Iter
+MipsELFFile<ELFT>::findMatchingRelocation(uint32_t pairRelType,
+ Elf_Rel_Iter rit,
+ Elf_Rel_Iter eit) const {
+ return std::find_if(rit, eit, [&](const Elf_Rel &rel) {
+ return getPrimaryType(rel) == pairRelType &&
+ rel.getSymbol(isMips64EL<ELFT>()) ==
+ rit->getSymbol(isMips64EL<ELFT>());
+ });
+}
+
+template <class ELFT>
+bool MipsELFFile<ELFT>::isLocalBinding(const Elf_Rel &rel) const {
+ return this->_objFile->getSymbol(rel.getSymbol(isMips64EL<ELFT>()))
+ ->getBinding() == llvm::ELF::STB_LOCAL;
+}
+
+template class MipsELFFile<ELF32LE>;
+template class MipsELFFile<ELF64LE>;
+
+} // elf
+} // lld
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h?rev=238310&r1=238309&r2=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFFile.h Wed May 27 06:56:15 2015
@@ -30,70 +30,32 @@ public:
StringRef sectionName, const Elf_Sym *symbol,
const Elf_Shdr *section, ArrayRef<uint8_t> contentData,
unsigned int referenceStart, unsigned int referenceEnd,
- std::vector<ELFReference<ELFT> *> &referenceList)
- : ELFDefinedAtom<ELFT>(file, symbolName, sectionName, symbol, section,
- contentData, referenceStart, referenceEnd,
- referenceList) {}
-
- const MipsELFFile<ELFT>& file() const override {
- return static_cast<const MipsELFFile<ELFT> &>(this->_owningFile);
- }
-
- DefinedAtom::CodeModel codeModel() const override {
- switch (this->_symbol->st_other & llvm::ELF::STO_MIPS_MIPS16) {
- case llvm::ELF::STO_MIPS_MIPS16:
- return DefinedAtom::codeMips16;
- case llvm::ELF::STO_MIPS_PIC:
- return DefinedAtom::codeMipsPIC;
- case llvm::ELF::STO_MIPS_MICROMIPS:
- return DefinedAtom::codeMipsMicro;
- case llvm::ELF::STO_MIPS_MICROMIPS | llvm::ELF::STO_MIPS_PIC:
- return DefinedAtom::codeMipsMicroPIC;
- default:
- return DefinedAtom::codeNA;
- }
- }
+ std::vector<ELFReference<ELFT> *> &referenceList);
+
+ const MipsELFFile<ELFT>& file() const override;
+ DefinedAtom::CodeModel codeModel() const override;
};
template <class ELFT> class MipsELFReference : public ELFReference<ELFT> {
typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
- static const bool _isMips64EL =
- ELFT::Is64Bits && ELFT::TargetEndianness == llvm::support::little;
-
public:
- MipsELFReference(uint64_t symValue, const Elf_Rela &rel)
- : ELFReference<ELFT>(
- &rel, rel.r_offset - symValue, Reference::KindArch::Mips,
- rel.getType(_isMips64EL) & 0xff, rel.getSymbol(_isMips64EL)),
- _tag(extractTag(rel)) {}
-
- MipsELFReference(uint64_t symValue, const Elf_Rel &rel)
- : ELFReference<ELFT>(rel.r_offset - symValue, Reference::KindArch::Mips,
- rel.getType(_isMips64EL) & 0xff,
- rel.getSymbol(_isMips64EL)),
- _tag(extractTag(rel)) {}
+ MipsELFReference(uint64_t symValue, const Elf_Rela &rel);
+ MipsELFReference(uint64_t symValue, const Elf_Rel &rel);
uint32_t tag() const override { return _tag; }
void setTag(uint32_t tag) { _tag = tag; }
private:
uint32_t _tag;
-
- template <class R> static uint32_t extractTag(const R &rel) {
- return (rel.getType(_isMips64EL) & 0xffffff00) >> 8;
- }
};
template <class ELFT> class MipsELFFile : public ELFFile<ELFT> {
public:
- MipsELFFile(std::unique_ptr<MemoryBuffer> mb, ELFLinkingContext &ctx)
- : ELFFile<ELFT>(std::move(mb), ctx) {}
+ MipsELFFile(std::unique_ptr<MemoryBuffer> mb, ELFLinkingContext &ctx);
- bool isPIC() const {
- return this->_objFile->getHeader()->e_flags & llvm::ELF::EF_MIPS_PIC;
- }
+ bool isPIC() const;
/// \brief gp register value stored in the .reginfo section.
int64_t getGP0() const { return _gp0; }
@@ -103,13 +65,7 @@ public:
uint64_t getDTPOffset() const { return _dtpOff; }
protected:
- std::error_code doParse() override {
- if (std::error_code ec = ELFFile<ELFT>::doParse())
- return ec;
- // Retrieve some auxiliary data like GP value, TLS section address etc
- // from the object file.
- return readAuxData();
- }
+ std::error_code doParse() override;
private:
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
@@ -120,9 +76,6 @@ private:
enum { TP_OFFSET = 0x7000, DTP_OFFSET = 0x8000 };
- static const bool _isMips64EL =
- ELFT::Is64Bits && ELFT::TargetEndianness == llvm::support::little;
-
int64_t _gp0 = 0;
uint64_t _tpOff = 0;
uint64_t _dtpOff = 0;
@@ -132,173 +85,36 @@ private:
const Elf_Sym *sym, const Elf_Shdr *sectionHdr,
ArrayRef<uint8_t> contentData, unsigned int referenceStart,
unsigned int referenceEnd,
- std::vector<ELFReference<ELFT> *> &referenceList) override {
- return new (this->_readerStorage) MipsELFDefinedAtom<ELFT>(
- *this, symName, sectionName, sym, sectionHdr, contentData,
- referenceStart, referenceEnd, referenceList);
- }
-
- const Elf_Shdr *findSectionByType(uint64_t type) const {
- for (const Elf_Shdr §ion : this->_objFile->sections())
- if (section.sh_type == type)
- return §ion;
- return nullptr;
- }
-
- const Elf_Shdr *findSectionByFlags(uint64_t flags) const {
- for (const Elf_Shdr §ion : this->_objFile->sections())
- if (section.sh_flags & flags)
- return §ion;
- return nullptr;
- }
-
- typedef typename llvm::object::ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
- typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
- typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
-
- ErrorOr<const Elf_Mips_RegInfo *> findRegInfoSec() const {
- using namespace llvm::ELF;
- if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_OPTIONS)) {
- auto contents = this->getSectionContents(sec);
- if (std::error_code ec = contents.getError())
- return ec;
-
- ArrayRef<uint8_t> raw = contents.get();
- while (!raw.empty()) {
- if (raw.size() < sizeof(Elf_Mips_Options))
- return make_dynamic_error_code(
- StringRef("Invalid size of MIPS_OPTIONS section"));
-
- const auto *opt =
- reinterpret_cast<const Elf_Mips_Options *>(raw.data());
- if (opt->kind == ODK_REGINFO)
- return &opt->getRegInfo();
- raw = raw.slice(opt->size);
- }
- } else if (const Elf_Shdr *sec = findSectionByType(SHT_MIPS_REGINFO)) {
- auto contents = this->getSectionContents(sec);
- if (std::error_code ec = contents.getError())
- return ec;
-
- ArrayRef<uint8_t> raw = contents.get();
- if (raw.size() != sizeof(Elf_Mips_RegInfo))
- return make_dynamic_error_code(
- StringRef("Invalid size of MIPS_REGINFO section"));
-
- return reinterpret_cast<const Elf_Mips_RegInfo *>(raw.data());
- }
- return nullptr;
- }
-
- std::error_code readAuxData() {
- using namespace llvm::ELF;
- if (const Elf_Shdr *sec = findSectionByFlags(SHF_TLS)) {
- _tpOff = sec->sh_addr + TP_OFFSET;
- _dtpOff = sec->sh_addr + DTP_OFFSET;
- }
-
- auto &ctx = static_cast<MipsLinkingContext &>(this->_ctx);
-
- ErrorOr<const Elf_Mips_RegInfo *> regInfoSec = findRegInfoSec();
- if (auto ec = regInfoSec.getError())
- return ec;
- if (const Elf_Mips_RegInfo *regInfo = regInfoSec.get()) {
- ctx.mergeReginfoMask(*regInfo);
- _gp0 = regInfo->ri_gp_value;
- }
-
- const Elf_Ehdr *hdr = this->_objFile->getHeader();
- if (std::error_code ec = ctx.mergeElfFlags(hdr->e_flags))
- return ec;
-
- return std::error_code();
- }
+ std::vector<ELFReference<ELFT> *> &referenceList) override;
void createRelocationReferences(const Elf_Sym *symbol,
ArrayRef<uint8_t> content,
- range<Elf_Rela_Iter> rels) override {
- const auto value = this->getSymbolValue(symbol);
- for (const auto &rel : rels) {
- if (rel.r_offset < value || value + content.size() <= rel.r_offset)
- continue;
- auto r = new (this->_readerStorage) MipsELFReference<ELFT>(value, rel);
- this->addReferenceToSymbol(r, symbol);
- this->_references.push_back(r);
- }
- }
-
+ range<Elf_Rela_Iter> rels) override;
void createRelocationReferences(const Elf_Sym *symbol,
ArrayRef<uint8_t> symContent,
ArrayRef<uint8_t> secContent,
- range<Elf_Rel_Iter> rels) override {
- const auto value = this->getSymbolValue(symbol);
- for (Elf_Rel_Iter rit = rels.begin(), eit = rels.end(); rit != eit; ++rit) {
- if (rit->r_offset < value || value + symContent.size() <= rit->r_offset)
- continue;
-
- auto r = new (this->_readerStorage) MipsELFReference<ELFT>(value, *rit);
- this->addReferenceToSymbol(r, symbol);
- this->_references.push_back(r);
-
- auto addend = readAddend(*rit, secContent);
- auto pairRelType = getPairRelocation(*rit);
- if (pairRelType != llvm::ELF::R_MIPS_NONE) {
- addend <<= 16;
- auto mit = findMatchingRelocation(pairRelType, rit, eit);
- if (mit != eit)
- addend += int16_t(readAddend(*mit, secContent));
- else
- // FIXME (simon): Show detailed warning.
- llvm::errs() << "lld warning: cannot matching LO16 relocation\n";
- }
- this->_references.back()->setAddend(addend);
- }
- }
+ range<Elf_Rel_Iter> rels) override;
+
+ const Elf_Shdr *findSectionByType(uint64_t type) const;
+ const Elf_Shdr *findSectionByFlags(uint64_t flags) const;
+
+ typedef typename llvm::object::ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
+ typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
+ typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
+
+ ErrorOr<const Elf_Mips_RegInfo *> findRegInfoSec() const;
+
+ std::error_code readAuxData();
Reference::Addend readAddend(const Elf_Rel &ri,
- const ArrayRef<uint8_t> content) const {
- return readMipsRelocAddend(getPrimaryType(ri),
- content.data() + ri.r_offset);
- }
-
- uint32_t getPairRelocation(const Elf_Rel &rel) const {
- switch (getPrimaryType(rel)) {
- case llvm::ELF::R_MIPS_HI16:
- return llvm::ELF::R_MIPS_LO16;
- case llvm::ELF::R_MIPS_PCHI16:
- return llvm::ELF::R_MIPS_PCLO16;
- case llvm::ELF::R_MIPS_GOT16:
- if (isLocalBinding(rel))
- return llvm::ELF::R_MIPS_LO16;
- break;
- case llvm::ELF::R_MICROMIPS_HI16:
- return llvm::ELF::R_MICROMIPS_LO16;
- case llvm::ELF::R_MICROMIPS_GOT16:
- if (isLocalBinding(rel))
- return llvm::ELF::R_MICROMIPS_LO16;
- break;
- default:
- // Nothing to do.
- break;
- }
- return llvm::ELF::R_MIPS_NONE;
- }
+ const ArrayRef<uint8_t> content) const;
+
+ uint32_t getPairRelocation(const Elf_Rel &rel) const;
Elf_Rel_Iter findMatchingRelocation(uint32_t pairRelType, Elf_Rel_Iter rit,
- Elf_Rel_Iter eit) const {
- return std::find_if(rit, eit, [&](const Elf_Rel &rel) {
- return getPrimaryType(rel) == pairRelType &&
- rel.getSymbol(_isMips64EL) == rit->getSymbol(_isMips64EL);
- });
- }
-
- static uint8_t getPrimaryType(const Elf_Rel &rel) {
- return rel.getType(_isMips64EL) & 0xff;
- }
- bool isLocalBinding(const Elf_Rel &rel) const {
- return this->_objFile->getSymbol(rel.getSymbol(_isMips64EL))
- ->getBinding() == llvm::ELF::STB_LOCAL;
- }
+ Elf_Rel_Iter eit) const;
+
+ bool isLocalBinding(const Elf_Rel &rel) const;
};
} // elf
Copied: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp (from r238304, lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h)
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp?p2=lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp&p1=lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h&r1=238304&r2=238310&rev=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp Wed May 27 06:56:15 2015
@@ -1,4 +1,4 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h -------------------===//
+//===- lib/ReaderWriter/ELF/Mips/MipsELFWriters.cpp -----------------------===//
//
// The LLVM Linker
//
@@ -6,43 +6,141 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_EXECUTABLE_WRITER_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_EXECUTABLE_WRITER_H
-#include "ExecutableWriter.h"
#include "MipsDynamicTable.h"
#include "MipsELFWriters.h"
#include "MipsLinkingContext.h"
+#include "MipsTargetHandler.h"
+#include "MipsTargetLayout.h"
+
+namespace {
+class MipsDynamicAtom : public lld::elf::DynamicAtom {
+public:
+ MipsDynamicAtom(const lld::File &f) : DynamicAtom(f) {}
+
+ ContentPermissions permissions() const override { return permR__; }
+};
+}
namespace lld {
namespace elf {
-template <typename ELFT> class MipsTargetLayout;
+template <class ELFT>
+MipsELFWriter<ELFT>::MipsELFWriter(MipsLinkingContext &ctx,
+ MipsTargetLayout<ELFT> &targetLayout)
+ : _ctx(ctx), _targetLayout(targetLayout) {}
template <class ELFT>
-class MipsExecutableWriter : public ExecutableWriter<ELFT> {
-public:
- MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout);
+void MipsELFWriter<ELFT>::setELFHeader(ELFHeader<ELFT> &elfHeader) {
+ elfHeader.e_version(1);
+ elfHeader.e_ident(llvm::ELF::EI_VERSION, llvm::ELF::EV_CURRENT);
+ elfHeader.e_ident(llvm::ELF::EI_OSABI, llvm::ELF::ELFOSABI_NONE);
+ if (_targetLayout.findOutputSection(".got.plt"))
+ elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 1);
+ else
+ elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 0);
-protected:
- void buildDynamicSymbolTable(const File &file) override;
+ elfHeader.e_flags(_ctx.getMergedELFFlags());
+}
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
+template <class ELFT>
+void MipsELFWriter<ELFT>::finalizeMipsRuntimeAtomValues() {
+ if (!_ctx.isDynamic())
+ return;
- void finalizeDefaultAtomValues() override;
- void createDefaultSections() override;
- std::error_code setELFHeader() override;
-
- unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable() override;
- unique_bump_ptr<DynamicTable<ELFT>> createDynamicTable() override;
- unique_bump_ptr<DynamicSymbolTable<ELFT>> createDynamicSymbolTable() override;
-
-private:
- MipsELFWriter<ELFT> _writeHelper;
- MipsTargetLayout<ELFT> &_targetLayout;
- unique_bump_ptr<Section<ELFT>> _reginfo;
-};
+ auto gotSection = _targetLayout.findOutputSection(".got");
+ auto got = gotSection ? gotSection->virtualAddr() : 0;
+ auto gp = gotSection ? got + _targetLayout.getGPOffset() : 0;
+
+ setAtomValue("_gp", gp);
+ setAtomValue("_gp_disp", gp);
+ setAtomValue("__gnu_local_gp", gp);
+}
+
+template <class ELFT>
+std::unique_ptr<RuntimeFile<ELFT>> MipsELFWriter<ELFT>::createRuntimeFile() {
+ auto file = llvm::make_unique<RuntimeFile<ELFT>>(_ctx, "Mips runtime file");
+ if (_ctx.isDynamic()) {
+ file->addAbsoluteAtom("_gp");
+ file->addAbsoluteAtom("_gp_disp");
+ file->addAbsoluteAtom("__gnu_local_gp");
+ file->addAtom(*new (file->allocator()) MipsDynamicAtom(*file));
+ }
+ return file;
+}
+
+template <class ELFT>
+void MipsELFWriter<ELFT>::setAtomValue(StringRef name, uint64_t value) {
+ AtomLayout *atom = _targetLayout.findAbsoluteAtom(name);
+ assert(atom);
+ atom->_virtualAddr = value;
+}
+
+template <class ELFT>
+MipsDynamicLibraryWriter<ELFT>::MipsDynamicLibraryWriter(
+ MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout)
+ : DynamicLibraryWriter<ELFT>(ctx, layout), _writeHelper(ctx, layout),
+ _targetLayout(layout) {}
+
+template <class ELFT>
+void MipsDynamicLibraryWriter<ELFT>::createImplicitFiles(
+ std::vector<std::unique_ptr<File>> &result) {
+ DynamicLibraryWriter<ELFT>::createImplicitFiles(result);
+ result.push_back(_writeHelper.createRuntimeFile());
+}
+
+template <class ELFT>
+void MipsDynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues() {
+ DynamicLibraryWriter<ELFT>::finalizeDefaultAtomValues();
+ _writeHelper.finalizeMipsRuntimeAtomValues();
+}
+
+template <class ELFT>
+void MipsDynamicLibraryWriter<ELFT>::createDefaultSections() {
+ DynamicLibraryWriter<ELFT>::createDefaultSections();
+ const auto &ctx = static_cast<const MipsLinkingContext &>(this->_ctx);
+ const auto &mask = ctx.getMergedReginfoMask();
+ if (!mask.hasValue())
+ return;
+ if (ELFT::Is64Bits)
+ _reginfo = unique_bump_ptr<Section<ELFT>>(
+ new (this->_alloc) MipsOptionsSection<ELFT>(ctx, _targetLayout, *mask));
+ else
+ _reginfo = unique_bump_ptr<Section<ELFT>>(
+ new (this->_alloc) MipsReginfoSection<ELFT>(ctx, _targetLayout, *mask));
+ this->_layout.addSection(_reginfo.get());
+}
+
+template <class ELFT>
+std::error_code MipsDynamicLibraryWriter<ELFT>::setELFHeader() {
+ DynamicLibraryWriter<ELFT>::setELFHeader();
+ _writeHelper.setELFHeader(*this->_elfHeader);
+ return std::error_code();
+}
+
+template <class ELFT>
+unique_bump_ptr<SymbolTable<ELFT>>
+MipsDynamicLibraryWriter<ELFT>::createSymbolTable() {
+ return unique_bump_ptr<SymbolTable<ELFT>>(
+ new (this->_alloc) MipsSymbolTable<ELFT>(this->_ctx));
+}
+
+template <class ELFT>
+unique_bump_ptr<DynamicTable<ELFT>>
+MipsDynamicLibraryWriter<ELFT>::createDynamicTable() {
+ return unique_bump_ptr<DynamicTable<ELFT>>(
+ new (this->_alloc) MipsDynamicTable<ELFT>(this->_ctx, _targetLayout));
+}
+
+template <class ELFT>
+unique_bump_ptr<DynamicSymbolTable<ELFT>>
+MipsDynamicLibraryWriter<ELFT>::createDynamicSymbolTable() {
+ return unique_bump_ptr<DynamicSymbolTable<ELFT>>(new (
+ this->_alloc) MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout));
+}
+
+template class MipsDynamicLibraryWriter<ELF32LE>;
+template class MipsDynamicLibraryWriter<ELF64LE>;
template <class ELFT>
MipsExecutableWriter<ELFT>::MipsExecutableWriter(MipsLinkingContext &ctx,
@@ -140,7 +238,7 @@ template <class ELFT> void MipsExecutabl
template <class ELFT>
unique_bump_ptr<SymbolTable<ELFT>>
- MipsExecutableWriter<ELFT>::createSymbolTable() {
+MipsExecutableWriter<ELFT>::createSymbolTable() {
return unique_bump_ptr<SymbolTable<ELFT>>(
new (this->_alloc) MipsSymbolTable<ELFT>(this->_ctx));
}
@@ -148,7 +246,7 @@ unique_bump_ptr<SymbolTable<ELFT>>
/// \brief create dynamic table
template <class ELFT>
unique_bump_ptr<DynamicTable<ELFT>>
- MipsExecutableWriter<ELFT>::createDynamicTable() {
+MipsExecutableWriter<ELFT>::createDynamicTable() {
return unique_bump_ptr<DynamicTable<ELFT>>(
new (this->_alloc) MipsDynamicTable<ELFT>(this->_ctx, _targetLayout));
}
@@ -156,13 +254,13 @@ unique_bump_ptr<DynamicTable<ELFT>>
/// \brief create dynamic symbol table
template <class ELFT>
unique_bump_ptr<DynamicSymbolTable<ELFT>>
- MipsExecutableWriter<ELFT>::createDynamicSymbolTable() {
- return unique_bump_ptr<DynamicSymbolTable<ELFT>>(
- new (this->_alloc)
- MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout));
+MipsExecutableWriter<ELFT>::createDynamicSymbolTable() {
+ return unique_bump_ptr<DynamicSymbolTable<ELFT>>(new (
+ this->_alloc) MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout));
}
-} // namespace elf
-} // namespace lld
+template class MipsExecutableWriter<ELF32LE>;
+template class MipsExecutableWriter<ELF64LE>;
-#endif
+} // elf
+} // lld
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h?rev=238310&r1=238309&r2=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsELFWriters.h Wed May 27 06:56:15 2015
@@ -9,6 +9,8 @@
#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_WRITERS_H
#define LLD_READER_WRITER_ELF_MIPS_MIPS_ELF_WRITERS_H
+#include "DynamicLibraryWriter.h"
+#include "ExecutableWriter.h"
#include "MipsLinkingContext.h"
namespace lld {
@@ -16,63 +18,71 @@ namespace elf {
template <class ELFT> class MipsTargetLayout;
-class MipsDynamicAtom : public DynamicAtom {
+template <typename ELFT> class MipsELFWriter {
public:
- MipsDynamicAtom(const File &f) : DynamicAtom(f) {}
+ MipsELFWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout);
+
+ void setELFHeader(ELFHeader<ELFT> &elfHeader);
+
+ void finalizeMipsRuntimeAtomValues();
- ContentPermissions permissions() const override { return permR__; }
+ std::unique_ptr<RuntimeFile<ELFT>> createRuntimeFile();
+
+private:
+ MipsLinkingContext &_ctx;
+ MipsTargetLayout<ELFT> &_targetLayout;
+
+ void setAtomValue(StringRef name, uint64_t value);
};
-template <typename ELFT> class MipsELFWriter {
+template <class ELFT>
+class MipsDynamicLibraryWriter : public DynamicLibraryWriter<ELFT> {
public:
- MipsELFWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout)
- : _ctx(ctx), _targetLayout(targetLayout) {}
+ MipsDynamicLibraryWriter(MipsLinkingContext &ctx,
+ MipsTargetLayout<ELFT> &layout);
+
+protected:
+ // Add any runtime files and their atoms to the output
+ void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
+
+ void finalizeDefaultAtomValues() override;
+ void createDefaultSections() override;
- void setELFHeader(ELFHeader<ELFT> &elfHeader) {
- elfHeader.e_version(1);
- elfHeader.e_ident(llvm::ELF::EI_VERSION, llvm::ELF::EV_CURRENT);
- elfHeader.e_ident(llvm::ELF::EI_OSABI, llvm::ELF::ELFOSABI_NONE);
- if (_targetLayout.findOutputSection(".got.plt"))
- elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 1);
- else
- elfHeader.e_ident(llvm::ELF::EI_ABIVERSION, 0);
-
- elfHeader.e_flags(_ctx.getMergedELFFlags());
- }
-
- void finalizeMipsRuntimeAtomValues() {
- if (!_ctx.isDynamic())
- return;
-
- auto gotSection = _targetLayout.findOutputSection(".got");
- auto got = gotSection ? gotSection->virtualAddr() : 0;
- auto gp = gotSection ? got + _targetLayout.getGPOffset() : 0;
-
- setAtomValue("_gp", gp);
- setAtomValue("_gp_disp", gp);
- setAtomValue("__gnu_local_gp", gp);
- }
-
- std::unique_ptr<RuntimeFile<ELFT>> createRuntimeFile() {
- auto file = llvm::make_unique<RuntimeFile<ELFT>>(_ctx, "Mips runtime file");
- if (_ctx.isDynamic()) {
- file->addAbsoluteAtom("_gp");
- file->addAbsoluteAtom("_gp_disp");
- file->addAbsoluteAtom("__gnu_local_gp");
- file->addAtom(*new (file->allocator()) MipsDynamicAtom(*file));
- }
- return file;
- }
+ std::error_code setELFHeader() override;
+
+ unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable() override;
+ unique_bump_ptr<DynamicTable<ELFT>> createDynamicTable() override;
+ unique_bump_ptr<DynamicSymbolTable<ELFT>> createDynamicSymbolTable() override;
private:
- MipsLinkingContext &_ctx;
+ MipsELFWriter<ELFT> _writeHelper;
MipsTargetLayout<ELFT> &_targetLayout;
+ unique_bump_ptr<Section<ELFT>> _reginfo;
+};
+
+template <class ELFT>
+class MipsExecutableWriter : public ExecutableWriter<ELFT> {
+public:
+ MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout);
+
+protected:
+ void buildDynamicSymbolTable(const File &file) override;
- void setAtomValue(StringRef name, uint64_t value) {
- AtomLayout *atom = _targetLayout.findAbsoluteAtom(name);
- assert(atom);
- atom->_virtualAddr = value;
- }
+ // Add any runtime files and their atoms to the output
+ void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
+
+ void finalizeDefaultAtomValues() override;
+ void createDefaultSections() override;
+ std::error_code setELFHeader() override;
+
+ unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable() override;
+ unique_bump_ptr<DynamicTable<ELFT>> createDynamicTable() override;
+ unique_bump_ptr<DynamicSymbolTable<ELFT>> createDynamicSymbolTable() override;
+
+private:
+ MipsELFWriter<ELFT> _writeHelper;
+ MipsTargetLayout<ELFT> &_targetLayout;
+ unique_bump_ptr<Section<ELFT>> _reginfo;
};
} // elf
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h?rev=238309&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h (removed)
@@ -1,168 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsExecutableWriter.h -------------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_EXECUTABLE_WRITER_H
-#define LLD_READER_WRITER_ELF_MIPS_MIPS_EXECUTABLE_WRITER_H
-
-#include "ExecutableWriter.h"
-#include "MipsDynamicTable.h"
-#include "MipsELFWriters.h"
-#include "MipsLinkingContext.h"
-
-namespace lld {
-namespace elf {
-
-template <typename ELFT> class MipsTargetLayout;
-
-template <class ELFT>
-class MipsExecutableWriter : public ExecutableWriter<ELFT> {
-public:
- MipsExecutableWriter(MipsLinkingContext &ctx, MipsTargetLayout<ELFT> &layout);
-
-protected:
- void buildDynamicSymbolTable(const File &file) override;
-
- // Add any runtime files and their atoms to the output
- void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
-
- void finalizeDefaultAtomValues() override;
- void createDefaultSections() override;
- std::error_code setELFHeader() override;
-
- unique_bump_ptr<SymbolTable<ELFT>> createSymbolTable() override;
- unique_bump_ptr<DynamicTable<ELFT>> createDynamicTable() override;
- unique_bump_ptr<DynamicSymbolTable<ELFT>> createDynamicSymbolTable() override;
-
-private:
- MipsELFWriter<ELFT> _writeHelper;
- MipsTargetLayout<ELFT> &_targetLayout;
- unique_bump_ptr<Section<ELFT>> _reginfo;
-};
-
-template <class ELFT>
-MipsExecutableWriter<ELFT>::MipsExecutableWriter(MipsLinkingContext &ctx,
- MipsTargetLayout<ELFT> &layout)
- : ExecutableWriter<ELFT>(ctx, layout), _writeHelper(ctx, layout),
- _targetLayout(layout) {}
-
-template <class ELFT>
-std::error_code MipsExecutableWriter<ELFT>::setELFHeader() {
- std::error_code ec = ExecutableWriter<ELFT>::setELFHeader();
- if (ec)
- return ec;
-
- StringRef entryName = this->_ctx.entrySymbolName();
- if (const AtomLayout *al = this->_layout.findAtomLayoutByName(entryName)) {
- const auto *ea = cast<DefinedAtom>(al->_atom);
- if (ea->codeModel() == DefinedAtom::codeMipsMicro ||
- ea->codeModel() == DefinedAtom::codeMipsMicroPIC)
- // Adjust entry symbol value if this symbol is microMIPS encoded.
- this->_elfHeader->e_entry(al->_virtualAddr | 1);
- }
-
- _writeHelper.setELFHeader(*this->_elfHeader);
- return std::error_code();
-}
-
-template <class ELFT>
-void MipsExecutableWriter<ELFT>::buildDynamicSymbolTable(const File &file) {
- // MIPS ABI requires to add to dynsym even undefined symbols
- // if they have a corresponding entries in a global part of GOT.
- for (auto sec : this->_layout.sections())
- if (auto section = dyn_cast<AtomSection<ELFT>>(sec))
- for (const auto &atom : section->atoms()) {
- if (_targetLayout.getGOTSection().hasGlobalGOTEntry(atom->_atom)) {
- this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
- atom->_virtualAddr, atom);
- continue;
- }
-
- const DefinedAtom *da = dyn_cast<const DefinedAtom>(atom->_atom);
- if (!da)
- continue;
-
- if (da->dynamicExport() != DefinedAtom::dynamicExportAlways &&
- !this->_ctx.isDynamicallyExportedSymbol(da->name()) &&
- !(this->_ctx.shouldExportDynamic() &&
- da->scope() == Atom::Scope::scopeGlobal))
- continue;
-
- this->_dynamicSymbolTable->addSymbol(atom->_atom, section->ordinal(),
- atom->_virtualAddr, atom);
- }
-
- for (const UndefinedAtom *a : file.undefined())
- // FIXME (simon): Consider to move this check to the
- // MipsELFUndefinedAtom class method. That allows to
- // handle more complex coditions in the future.
- if (_targetLayout.getGOTSection().hasGlobalGOTEntry(a))
- this->_dynamicSymbolTable->addSymbol(a, ELF::SHN_UNDEF);
-
- // Skip our immediate parent class method
- // ExecutableWriter<ELFT>::buildDynamicSymbolTable because we replaced it
- // with our own version. Call OutputELFWriter directly.
- OutputELFWriter<ELFT>::buildDynamicSymbolTable(file);
-}
-
-template <class ELFT>
-void MipsExecutableWriter<ELFT>::createImplicitFiles(
- std::vector<std::unique_ptr<File>> &result) {
- ExecutableWriter<ELFT>::createImplicitFiles(result);
- result.push_back(_writeHelper.createRuntimeFile());
-}
-
-template <class ELFT>
-void MipsExecutableWriter<ELFT>::finalizeDefaultAtomValues() {
- // Finalize the atom values that are part of the parent.
- ExecutableWriter<ELFT>::finalizeDefaultAtomValues();
- _writeHelper.finalizeMipsRuntimeAtomValues();
-}
-
-template <class ELFT> void MipsExecutableWriter<ELFT>::createDefaultSections() {
- ExecutableWriter<ELFT>::createDefaultSections();
- const auto &ctx = static_cast<const MipsLinkingContext &>(this->_ctx);
- const auto &mask = ctx.getMergedReginfoMask();
- if (!mask.hasValue())
- return;
- if (ELFT::Is64Bits)
- _reginfo = unique_bump_ptr<Section<ELFT>>(
- new (this->_alloc) MipsOptionsSection<ELFT>(ctx, _targetLayout, *mask));
- else
- _reginfo = unique_bump_ptr<Section<ELFT>>(
- new (this->_alloc) MipsReginfoSection<ELFT>(ctx, _targetLayout, *mask));
- this->_layout.addSection(_reginfo.get());
-}
-
-template <class ELFT>
-unique_bump_ptr<SymbolTable<ELFT>>
- MipsExecutableWriter<ELFT>::createSymbolTable() {
- return unique_bump_ptr<SymbolTable<ELFT>>(
- new (this->_alloc) MipsSymbolTable<ELFT>(this->_ctx));
-}
-
-/// \brief create dynamic table
-template <class ELFT>
-unique_bump_ptr<DynamicTable<ELFT>>
- MipsExecutableWriter<ELFT>::createDynamicTable() {
- return unique_bump_ptr<DynamicTable<ELFT>>(
- new (this->_alloc) MipsDynamicTable<ELFT>(this->_ctx, _targetLayout));
-}
-
-/// \brief create dynamic symbol table
-template <class ELFT>
-unique_bump_ptr<DynamicSymbolTable<ELFT>>
- MipsExecutableWriter<ELFT>::createDynamicSymbolTable() {
- return unique_bump_ptr<DynamicSymbolTable<ELFT>>(
- new (this->_alloc)
- MipsDynamicSymbolTable<ELFT>(this->_ctx, _targetLayout));
-}
-
-} // namespace elf
-} // namespace lld
-
-#endif
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp?rev=238310&r1=238309&r2=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsLinkingContext.cpp Wed May 27 06:56:15 2015
@@ -28,9 +28,9 @@ static std::unique_ptr<TargetHandler> cr
MipsLinkingContext &ctx) {
switch (triple.getArch()) {
case llvm::Triple::mipsel:
- return createMips32ELTargetHandler(ctx);
+ return llvm::make_unique<MipsTargetHandler<ELF32LE>>(ctx);
case llvm::Triple::mips64el:
- return createMips64ELTargetHandler(ctx);
+ return llvm::make_unique<MipsTargetHandler<ELF64LE>>(ctx);
default:
llvm_unreachable("Unhandled arch");
}
Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp?rev=238310&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp Wed May 27 06:56:15 2015
@@ -0,0 +1,235 @@
+//===- lib/ReaderWriter/ELF/Mips/MipsSectionChunks.cpp --------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MipsLinkingContext.h"
+#include "MipsSectionChunks.h"
+#include "MipsTargetLayout.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT>
+MipsReginfoSection<ELFT>::MipsReginfoSection(
+ const ELFLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout,
+ const MipsReginfo ®info)
+ : Section<ELFT>(ctx, ".reginfo", "MipsReginfo"),
+ _targetLayout(targetLayout) {
+ this->setOrder(MipsTargetLayout<ELFT>::ORDER_MIPS_REGINFO);
+ this->_entSize = sizeof(Elf_Mips_RegInfo);
+ this->_fsize = sizeof(Elf_Mips_RegInfo);
+ this->_msize = sizeof(Elf_Mips_RegInfo);
+ this->_alignment = 4;
+ this->_type = SHT_MIPS_REGINFO;
+ this->_flags = SHF_ALLOC;
+
+ std::memset(&_reginfo, 0, sizeof(_reginfo));
+ _reginfo.ri_gprmask = reginfo._gpRegMask;
+ _reginfo.ri_cprmask[0] = reginfo._cpRegMask[0];
+ _reginfo.ri_cprmask[1] = reginfo._cpRegMask[1];
+ _reginfo.ri_cprmask[2] = reginfo._cpRegMask[2];
+ _reginfo.ri_cprmask[3] = reginfo._cpRegMask[3];
+}
+
+template <class ELFT>
+void MipsReginfoSection<ELFT>::write(ELFWriter *writer,
+ TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer) {
+ uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
+ std::memcpy(dest, &_reginfo, this->_fsize);
+}
+
+template <class ELFT> void MipsReginfoSection<ELFT>::finalize() {
+ _reginfo.ri_gp_value = _targetLayout.getGPAddr();
+
+ if (this->_outputSection)
+ this->_outputSection->setType(this->_type);
+}
+
+template class MipsReginfoSection<ELF32LE>;
+template class MipsReginfoSection<ELF64LE>;
+
+template <class ELFT>
+MipsOptionsSection<ELFT>::MipsOptionsSection(
+ const ELFLinkingContext &ctx, MipsTargetLayout<ELFT> &targetLayout,
+ const MipsReginfo ®info)
+ : Section<ELFT>(ctx, ".MIPS.options", "MipsOptions"),
+ _targetLayout(targetLayout) {
+ this->setOrder(MipsTargetLayout<ELFT>::ORDER_MIPS_OPTIONS);
+ this->_entSize = 1;
+ this->_alignment = 8;
+ this->_fsize = llvm::RoundUpToAlignment(
+ sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo), this->_alignment);
+ this->_msize = this->_fsize;
+ this->_type = SHT_MIPS_OPTIONS;
+ this->_flags = SHF_ALLOC | SHF_MIPS_NOSTRIP;
+
+ _header.kind = ODK_REGINFO;
+ _header.size = this->_fsize;
+ _header.section = 0;
+ _header.info = 0;
+
+ std::memset(&_reginfo, 0, sizeof(_reginfo));
+ _reginfo.ri_gprmask = reginfo._gpRegMask;
+ _reginfo.ri_cprmask[0] = reginfo._cpRegMask[0];
+ _reginfo.ri_cprmask[1] = reginfo._cpRegMask[1];
+ _reginfo.ri_cprmask[2] = reginfo._cpRegMask[2];
+ _reginfo.ri_cprmask[3] = reginfo._cpRegMask[3];
+}
+
+template <class ELFT>
+void MipsOptionsSection<ELFT>::write(ELFWriter *writer,
+ TargetLayout<ELFT> &layout,
+ llvm::FileOutputBuffer &buffer) {
+ uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
+ std::memset(dest, 0, this->_fsize);
+ std::memcpy(dest, &_header, sizeof(_header));
+ std::memcpy(dest + sizeof(_header), &_reginfo, sizeof(_reginfo));
+}
+
+template <class ELFT> void MipsOptionsSection<ELFT>::finalize() {
+ _reginfo.ri_gp_value = _targetLayout.getGPAddr();
+
+ if (this->_outputSection)
+ this->_outputSection->setType(this->_type);
+}
+
+template class MipsOptionsSection<ELF32LE>;
+template class MipsOptionsSection<ELF64LE>;
+
+template <class ELFT>
+MipsGOTSection<ELFT>::MipsGOTSection(const MipsLinkingContext &ctx)
+ : AtomSection<ELFT>(ctx, ".got", DefinedAtom::typeGOT, DefinedAtom::permRW_,
+ MipsTargetLayout<ELFT>::ORDER_GOT),
+ _hasNonLocal(false), _localCount(0) {
+ this->_flags |= SHF_MIPS_GPREL;
+ this->_alignment = 4;
+}
+
+template <class ELFT>
+bool MipsGOTSection<ELFT>::compare(const Atom *a, const Atom *b) const {
+ auto ia = _posMap.find(a);
+ auto ib = _posMap.find(b);
+
+ if (ia != _posMap.end() && ib != _posMap.end())
+ return ia->second < ib->second;
+
+ return ia == _posMap.end() && ib != _posMap.end();
+}
+
+template <class ELFT>
+const AtomLayout *MipsGOTSection<ELFT>::appendAtom(const Atom *atom) {
+ const DefinedAtom *da = dyn_cast<DefinedAtom>(atom);
+
+ if (atom->name() == "_GLOBAL_OFFSET_TABLE_")
+ return AtomSection<ELFT>::appendAtom(atom);
+
+ for (const auto &r : *da) {
+ if (r->kindNamespace() != Reference::KindNamespace::ELF)
+ continue;
+ assert(r->kindArch() == Reference::KindArch::Mips);
+ switch (r->kindValue()) {
+ case LLD_R_MIPS_GLOBAL_GOT:
+ _hasNonLocal = true;
+ _posMap[r->target()] = _posMap.size();
+ return AtomSection<ELFT>::appendAtom(atom);
+ case R_MIPS_TLS_TPREL32:
+ case R_MIPS_TLS_DTPREL32:
+ case R_MIPS_TLS_TPREL64:
+ case R_MIPS_TLS_DTPREL64:
+ _hasNonLocal = true;
+ _tlsMap[r->target()] = _tlsMap.size();
+ return AtomSection<ELFT>::appendAtom(atom);
+ case R_MIPS_TLS_DTPMOD32:
+ case R_MIPS_TLS_DTPMOD64:
+ _hasNonLocal = true;
+ break;
+ }
+ }
+
+ if (!_hasNonLocal)
+ ++_localCount;
+
+ return AtomSection<ELFT>::appendAtom(atom);
+}
+
+template class MipsGOTSection<ELF32LE>;
+template class MipsGOTSection<ELF64LE>;
+
+template <class ELFT>
+MipsPLTSection<ELFT>::MipsPLTSection(const MipsLinkingContext &ctx)
+ : AtomSection<ELFT>(ctx, ".plt", DefinedAtom::typeGOT, DefinedAtom::permR_X,
+ MipsTargetLayout<ELFT>::ORDER_PLT) {}
+
+template <class ELFT>
+const AtomLayout *MipsPLTSection<ELFT>::findPLTLayout(const Atom *plt) const {
+ auto it = _pltLayoutMap.find(plt);
+ return it != _pltLayoutMap.end() ? it->second : nullptr;
+}
+
+template <class ELFT>
+const AtomLayout *MipsPLTSection<ELFT>::appendAtom(const Atom *atom) {
+ const auto *layout = AtomSection<ELFT>::appendAtom(atom);
+
+ const DefinedAtom *da = cast<DefinedAtom>(atom);
+
+ for (const auto &r : *da) {
+ if (r->kindNamespace() != Reference::KindNamespace::ELF)
+ continue;
+ assert(r->kindArch() == Reference::KindArch::Mips);
+ if (r->kindValue() == LLD_R_MIPS_STO_PLT) {
+ _pltLayoutMap[r->target()] = layout;
+ break;
+ }
+ }
+
+ return layout;
+}
+
+template class MipsPLTSection<ELF32LE>;
+template class MipsPLTSection<ELF64LE>;
+
+template <class ELFT> static bool isMips64EL() {
+ return ELFT::Is64Bits && ELFT::TargetEndianness == llvm::support::little;
+}
+
+template <class ELFT>
+MipsRelocationTable<ELFT>::MipsRelocationTable(const ELFLinkingContext &ctx,
+ StringRef str, int32_t order)
+ : RelocationTable<ELFT>(ctx, str, order) {}
+
+template <class ELFT>
+void MipsRelocationTable<ELFT>::writeRela(ELFWriter *writer, Elf_Rela &r,
+ const DefinedAtom &atom,
+ const Reference &ref) {
+ uint32_t rType = ref.kindValue() | (ref.tag() << 8);
+ r.setSymbolAndType(this->getSymbolIndex(ref.target()), rType,
+ isMips64EL<ELFT>());
+ r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
+ // The addend is used only by relative relocations
+ if (this->_ctx.isRelativeReloc(ref))
+ r.r_addend = writer->addressOfAtom(ref.target()) + ref.addend();
+ else
+ r.r_addend = 0;
+}
+
+template <class ELFT>
+void MipsRelocationTable<ELFT>::writeRel(ELFWriter *writer, Elf_Rel &r,
+ const DefinedAtom &atom,
+ const Reference &ref) {
+ uint32_t rType = ref.kindValue() | (ref.tag() << 8);
+ r.setSymbolAndType(this->getSymbolIndex(ref.target()), rType,
+ isMips64EL<ELFT>());
+ r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
+}
+
+template class MipsRelocationTable<ELF32LE>;
+template class MipsRelocationTable<ELF64LE>;
+
+} // elf
+} // lld
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h?rev=238310&r1=238309&r2=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsSectionChunks.h Wed May 27 06:56:15 2015
@@ -23,41 +23,14 @@ template <class ELFT> class MipsReginfoS
public:
MipsReginfoSection(const ELFLinkingContext &ctx,
MipsTargetLayout<ELFT> &targetLayout,
- const MipsReginfo ®info)
- : Section<ELFT>(ctx, ".reginfo", "MipsReginfo"),
- _targetLayout(targetLayout) {
- this->setOrder(MipsTargetLayout<ELFT>::ORDER_MIPS_REGINFO);
- this->_entSize = sizeof(Elf_Mips_RegInfo);
- this->_fsize = sizeof(Elf_Mips_RegInfo);
- this->_msize = sizeof(Elf_Mips_RegInfo);
- this->_alignment = 4;
- this->_type = SHT_MIPS_REGINFO;
- this->_flags = SHF_ALLOC;
-
- std::memset(&_reginfo, 0, sizeof(_reginfo));
- _reginfo.ri_gprmask = reginfo._gpRegMask;
- _reginfo.ri_cprmask[0] = reginfo._cpRegMask[0];
- _reginfo.ri_cprmask[1] = reginfo._cpRegMask[1];
- _reginfo.ri_cprmask[2] = reginfo._cpRegMask[2];
- _reginfo.ri_cprmask[3] = reginfo._cpRegMask[3];
- }
+ const MipsReginfo ®info);
StringRef segmentKindToStr() const override { return "REGINFO"; }
-
bool hasOutputSegment() const override { return true; }
void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override {
- uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
- std::memcpy(dest, &_reginfo, this->_fsize);
- }
-
- void finalize() override {
- _reginfo.ri_gp_value = _targetLayout.getGPAddr();
-
- if (this->_outputSection)
- this->_outputSection->setType(this->_type);
- }
+ llvm::FileOutputBuffer &buffer) override;
+ void finalize() override;
private:
typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
@@ -69,51 +42,15 @@ private:
/// \brief Handle .MIPS.options section
template <class ELFT> class MipsOptionsSection : public Section<ELFT> {
public:
- typedef typename std::vector<MipsReginfo>::const_iterator mask_const_iterator;
-
MipsOptionsSection(const ELFLinkingContext &ctx,
MipsTargetLayout<ELFT> &targetLayout,
- const MipsReginfo ®info)
- : Section<ELFT>(ctx, ".MIPS.options", "MipsOptions"),
- _targetLayout(targetLayout) {
- this->setOrder(MipsTargetLayout<ELFT>::ORDER_MIPS_OPTIONS);
- this->_entSize = 1;
- this->_alignment = 8;
- this->_fsize = llvm::RoundUpToAlignment(
- sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo), this->_alignment);
- this->_msize = this->_fsize;
- this->_type = SHT_MIPS_OPTIONS;
- this->_flags = SHF_ALLOC | SHF_MIPS_NOSTRIP;
-
- _header.kind = ODK_REGINFO;
- _header.size = this->_fsize;
- _header.section = 0;
- _header.info = 0;
-
- std::memset(&_reginfo, 0, sizeof(_reginfo));
- _reginfo.ri_gprmask = reginfo._gpRegMask;
- _reginfo.ri_cprmask[0] = reginfo._cpRegMask[0];
- _reginfo.ri_cprmask[1] = reginfo._cpRegMask[1];
- _reginfo.ri_cprmask[2] = reginfo._cpRegMask[2];
- _reginfo.ri_cprmask[3] = reginfo._cpRegMask[3];
- }
+ const MipsReginfo ®info);
bool hasOutputSegment() const override { return true; }
void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
- llvm::FileOutputBuffer &buffer) override {
- uint8_t *dest = buffer.getBufferStart() + this->fileOffset();
- std::memset(dest, 0, this->_fsize);
- std::memcpy(dest, &_header, sizeof(_header));
- std::memcpy(dest + sizeof(_header), &_reginfo, sizeof(_reginfo));
- }
-
- void finalize() override {
- _reginfo.ri_gp_value = _targetLayout.getGPAddr();
-
- if (this->_outputSection)
- this->_outputSection->setType(this->_type);
- }
+ llvm::FileOutputBuffer &buffer) override;
+ void finalize() override;
private:
typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
@@ -127,14 +64,7 @@ private:
/// \brief Handle Mips GOT section
template <class ELFT> class MipsGOTSection : public AtomSection<ELFT> {
public:
- MipsGOTSection(const MipsLinkingContext &ctx)
- : AtomSection<ELFT>(ctx, ".got", DefinedAtom::typeGOT,
- DefinedAtom::permRW_,
- MipsTargetLayout<ELFT>::ORDER_GOT),
- _hasNonLocal(false), _localCount(0) {
- this->_flags |= SHF_MIPS_GPREL;
- this->_alignment = 4;
- }
+ MipsGOTSection(const MipsLinkingContext &ctx);
/// \brief Number of local GOT entries.
std::size_t getLocalCount() const { return _localCount; }
@@ -148,50 +78,9 @@ public:
}
/// \brief Compare two atoms accordingly theirs positions in the GOT.
- bool compare(const Atom *a, const Atom *b) const {
- auto ia = _posMap.find(a);
- auto ib = _posMap.find(b);
-
- if (ia != _posMap.end() && ib != _posMap.end())
- return ia->second < ib->second;
+ bool compare(const Atom *a, const Atom *b) const;
- return ia == _posMap.end() && ib != _posMap.end();
- }
-
- const AtomLayout *appendAtom(const Atom *atom) override {
- const DefinedAtom *da = dyn_cast<DefinedAtom>(atom);
-
- if (atom->name() == "_GLOBAL_OFFSET_TABLE_")
- return AtomSection<ELFT>::appendAtom(atom);
-
- for (const auto &r : *da) {
- if (r->kindNamespace() != Reference::KindNamespace::ELF)
- continue;
- assert(r->kindArch() == Reference::KindArch::Mips);
- switch (r->kindValue()) {
- case LLD_R_MIPS_GLOBAL_GOT:
- _hasNonLocal = true;
- _posMap[r->target()] = _posMap.size();
- return AtomSection<ELFT>::appendAtom(atom);
- case R_MIPS_TLS_TPREL32:
- case R_MIPS_TLS_DTPREL32:
- case R_MIPS_TLS_TPREL64:
- case R_MIPS_TLS_DTPREL64:
- _hasNonLocal = true;
- _tlsMap[r->target()] = _tlsMap.size();
- return AtomSection<ELFT>::appendAtom(atom);
- case R_MIPS_TLS_DTPMOD32:
- case R_MIPS_TLS_DTPMOD64:
- _hasNonLocal = true;
- break;
- }
- }
-
- if (!_hasNonLocal)
- ++_localCount;
-
- return AtomSection<ELFT>::appendAtom(atom);
- }
+ const AtomLayout *appendAtom(const Atom *atom) override;
private:
/// \brief True if the GOT contains non-local entries.
@@ -210,33 +99,11 @@ private:
/// \brief Handle Mips PLT section
template <class ELFT> class MipsPLTSection : public AtomSection<ELFT> {
public:
- MipsPLTSection(const MipsLinkingContext &ctx)
- : AtomSection<ELFT>(ctx, ".plt", DefinedAtom::typeGOT,
- DefinedAtom::permR_X,
- MipsTargetLayout<ELFT>::ORDER_PLT) {}
-
- const AtomLayout *findPLTLayout(const Atom *plt) const {
- auto it = _pltLayoutMap.find(plt);
- return it != _pltLayoutMap.end() ? it->second : nullptr;
- }
+ MipsPLTSection(const MipsLinkingContext &ctx);
- const AtomLayout *appendAtom(const Atom *atom) override {
- const auto *layout = AtomSection<ELFT>::appendAtom(atom);
+ const AtomLayout *findPLTLayout(const Atom *plt) const;
- const DefinedAtom *da = cast<DefinedAtom>(atom);
-
- for (const auto &r : *da) {
- if (r->kindNamespace() != Reference::KindNamespace::ELF)
- continue;
- assert(r->kindArch() == Reference::KindArch::Mips);
- if (r->kindValue() == LLD_R_MIPS_STO_PLT) {
- _pltLayoutMap[r->target()] = layout;
- break;
- }
- }
-
- return layout;
- }
+ const AtomLayout *appendAtom(const Atom *atom) override;
private:
/// \brief Map PLT Atoms to their layouts.
@@ -247,33 +114,15 @@ template <class ELFT> class MipsRelocati
typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
- static const bool _isMips64EL =
- ELFT::Is64Bits && ELFT::TargetEndianness == llvm::support::little;
-
public:
MipsRelocationTable(const ELFLinkingContext &ctx, StringRef str,
- int32_t order)
- : RelocationTable<ELFT>(ctx, str, order) {}
+ int32_t order);
protected:
void writeRela(ELFWriter *writer, Elf_Rela &r, const DefinedAtom &atom,
- const Reference &ref) override {
- uint32_t rType = ref.kindValue() | (ref.tag() << 8);
- r.setSymbolAndType(this->getSymbolIndex(ref.target()), rType, _isMips64EL);
- r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
- // The addend is used only by relative relocations
- if (this->_ctx.isRelativeReloc(ref))
- r.r_addend = writer->addressOfAtom(ref.target()) + ref.addend();
- else
- r.r_addend = 0;
- }
-
+ const Reference &ref) override;
void writeRel(ELFWriter *writer, Elf_Rel &r, const DefinedAtom &atom,
- const Reference &ref) override {
- uint32_t rType = ref.kindValue() | (ref.tag() << 8);
- r.setSymbolAndType(this->getSymbolIndex(ref.target()), rType, _isMips64EL);
- r.r_offset = writer->addressOfAtom(&atom) + ref.offsetInAtom();
- }
+ const Reference &ref) override;
};
} // elf
Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp?rev=238310&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.cpp Wed May 27 06:56:15 2015
@@ -0,0 +1,155 @@
+//===- lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp ----------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ELFReader.h"
+#include "MipsELFFile.h"
+#include "MipsELFWriters.h"
+#include "MipsTargetHandler.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT>
+MipsTargetHandler<ELFT>::MipsTargetHandler(MipsLinkingContext &ctx)
+ : _ctx(ctx), _targetLayout(new MipsTargetLayout<ELFT>(ctx)),
+ _relocationHandler(
+ createMipsRelocationHandler<ELFT>(ctx, *_targetLayout)) {}
+
+template <class ELFT>
+std::unique_ptr<Reader> MipsTargetHandler<ELFT>::getObjReader() {
+ return llvm::make_unique<ELFReader<MipsELFFile<ELFT>>>(_ctx);
+}
+
+template <class ELFT>
+std::unique_ptr<Reader> MipsTargetHandler<ELFT>::getDSOReader() {
+ return llvm::make_unique<ELFReader<DynamicFile<ELFT>>>(_ctx);
+}
+
+template <class ELFT>
+const TargetRelocationHandler &
+MipsTargetHandler<ELFT>::getRelocationHandler() const {
+ return *_relocationHandler;
+}
+
+template <class ELFT>
+std::unique_ptr<Writer> MipsTargetHandler<ELFT>::getWriter() {
+ switch (_ctx.getOutputELFType()) {
+ case llvm::ELF::ET_EXEC:
+ return llvm::make_unique<MipsExecutableWriter<ELFT>>(_ctx, *_targetLayout);
+ case llvm::ELF::ET_DYN:
+ return llvm::make_unique<MipsDynamicLibraryWriter<ELFT>>(_ctx,
+ *_targetLayout);
+ case llvm::ELF::ET_REL:
+ llvm_unreachable("TODO: support -r mode");
+ default:
+ llvm_unreachable("unsupported output type");
+ }
+}
+
+template class MipsTargetHandler<ELF32LE>;
+template class MipsTargetHandler<ELF64LE>;
+
+template <class ELFT>
+MipsSymbolTable<ELFT>::MipsSymbolTable(const ELFLinkingContext &ctx)
+ : SymbolTable<ELFT>(ctx, ".symtab",
+ TargetLayout<ELFT>::ORDER_SYMBOL_TABLE) {}
+
+template <class ELFT>
+void MipsSymbolTable<ELFT>::addDefinedAtom(Elf_Sym &sym, const DefinedAtom *da,
+ int64_t addr) {
+ SymbolTable<ELFT>::addDefinedAtom(sym, da, addr);
+
+ switch (da->codeModel()) {
+ case DefinedAtom::codeMipsMicro:
+ sym.st_other |= llvm::ELF::STO_MIPS_MICROMIPS;
+ break;
+ case DefinedAtom::codeMipsMicroPIC:
+ sym.st_other |= llvm::ELF::STO_MIPS_MICROMIPS | llvm::ELF::STO_MIPS_PIC;
+ break;
+ default:
+ break;
+ }
+}
+
+template <class ELFT> void MipsSymbolTable<ELFT>::finalize(bool sort) {
+ SymbolTable<ELFT>::finalize(sort);
+
+ for (auto &ste : this->_symbolTable) {
+ if (!ste._atom)
+ continue;
+ if (const auto *da = dyn_cast<DefinedAtom>(ste._atom)) {
+ if (da->codeModel() == DefinedAtom::codeMipsMicro ||
+ da->codeModel() == DefinedAtom::codeMipsMicroPIC) {
+ // Adjust dynamic microMIPS symbol value. That allows a dynamic
+ // linker to recognize and handle this symbol correctly.
+ ste._symbol.st_value = ste._symbol.st_value | 1;
+ }
+ }
+ }
+}
+
+template class MipsSymbolTable<ELF32LE>;
+template class MipsSymbolTable<ELF64LE>;
+
+template <class ELFT>
+MipsDynamicSymbolTable<ELFT>::MipsDynamicSymbolTable(
+ const ELFLinkingContext &ctx, MipsTargetLayout<ELFT> &layout)
+ : DynamicSymbolTable<ELFT>(ctx, layout, ".dynsym",
+ TargetLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS),
+ _targetLayout(layout) {}
+
+template <class ELFT> void MipsDynamicSymbolTable<ELFT>::sortSymbols() {
+ typedef typename DynamicSymbolTable<ELFT>::SymbolEntry SymbolEntry;
+ std::stable_sort(this->_symbolTable.begin(), this->_symbolTable.end(),
+ [this](const SymbolEntry &A, const SymbolEntry &B) {
+ if (A._symbol.getBinding() != STB_GLOBAL &&
+ B._symbol.getBinding() != STB_GLOBAL)
+ return A._symbol.getBinding() < B._symbol.getBinding();
+
+ return _targetLayout.getGOTSection().compare(A._atom,
+ B._atom);
+ });
+}
+
+template <class ELFT> void MipsDynamicSymbolTable<ELFT>::finalize() {
+ DynamicSymbolTable<ELFT>::finalize();
+
+ const auto &pltSection = _targetLayout.getPLTSection();
+
+ for (auto &ste : this->_symbolTable) {
+ const Atom *a = ste._atom;
+ if (!a)
+ continue;
+ if (auto *layout = pltSection.findPLTLayout(a)) {
+ a = layout->_atom;
+ // Under some conditions a dynamic symbol table record should hold
+ // a symbol value of the corresponding PLT entry. For details look
+ // at the PLT entry creation code in the class MipsRelocationPass.
+ // Let's update atomLayout fields for such symbols.
+ assert(!ste._atomLayout);
+ ste._symbol.st_value = layout->_virtualAddr;
+ ste._symbol.st_other |= ELF::STO_MIPS_PLT;
+ }
+
+ if (const auto *da = dyn_cast<DefinedAtom>(a)) {
+ if (da->codeModel() == DefinedAtom::codeMipsMicro ||
+ da->codeModel() == DefinedAtom::codeMipsMicroPIC) {
+ // Adjust dynamic microMIPS symbol value. That allows a dynamic
+ // linker to recognize and handle this symbol correctly.
+ ste._symbol.st_value = ste._symbol.st_value | 1;
+ }
+ }
+ }
+}
+
+template class MipsDynamicSymbolTable<ELF32LE>;
+template class MipsDynamicSymbolTable<ELF64LE>;
+
+}
+}
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h?rev=238310&r1=238309&r2=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler.h Wed May 27 06:56:15 2015
@@ -9,10 +9,6 @@
#ifndef LLD_READER_WRITER_ELF_MIPS_MIPS_TARGET_HANDLER_H
#define LLD_READER_WRITER_ELF_MIPS_MIPS_TARGET_HANDLER_H
-#include "ELFReader.h"
-#include "MipsDynamicLibraryWriter.h"
-#include "MipsELFFile.h"
-#include "MipsExecutableWriter.h"
#include "MipsLinkingContext.h"
#include "MipsTargetLayout.h"
#include "TargetHandler.h"
@@ -23,37 +19,12 @@ namespace elf {
/// \brief TargetHandler for Mips
template <class ELFT> class MipsTargetHandler final : public TargetHandler {
public:
- MipsTargetHandler(MipsLinkingContext &ctx)
- : _ctx(ctx), _targetLayout(new MipsTargetLayout<ELFT>(ctx)),
- _relocationHandler(
- createMipsRelocationHandler<ELFT>(ctx, *_targetLayout)) {}
-
- std::unique_ptr<Reader> getObjReader() override {
- return llvm::make_unique<ELFReader<MipsELFFile<ELFT>>>(_ctx);
- }
-
- std::unique_ptr<Reader> getDSOReader() override {
- return llvm::make_unique<ELFReader<DynamicFile<ELFT>>>(_ctx);
- }
-
- const TargetRelocationHandler &getRelocationHandler() const override {
- return *_relocationHandler;
- }
-
- std::unique_ptr<Writer> getWriter() override {
- switch (_ctx.getOutputELFType()) {
- case llvm::ELF::ET_EXEC:
- return llvm::make_unique<MipsExecutableWriter<ELFT>>(
- _ctx, *_targetLayout);
- case llvm::ELF::ET_DYN:
- return llvm::make_unique<MipsDynamicLibraryWriter<ELFT>>(
- _ctx, *_targetLayout);
- case llvm::ELF::ET_REL:
- llvm_unreachable("TODO: support -r mode");
- default:
- llvm_unreachable("unsupported output type");
- }
- }
+ MipsTargetHandler(MipsLinkingContext &ctx);
+
+ std::unique_ptr<Reader> getObjReader() override;
+ std::unique_ptr<Reader> getDSOReader() override;
+ const TargetRelocationHandler &getRelocationHandler() const override;
+ std::unique_ptr<Writer> getWriter() override;
private:
MipsLinkingContext &_ctx;
@@ -65,105 +36,26 @@ template <class ELFT> class MipsSymbolTa
public:
typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
- MipsSymbolTable(const ELFLinkingContext &ctx)
- : SymbolTable<ELFT>(ctx, ".symtab",
- TargetLayout<ELFT>::ORDER_SYMBOL_TABLE) {}
+ MipsSymbolTable(const ELFLinkingContext &ctx);
void addDefinedAtom(Elf_Sym &sym, const DefinedAtom *da,
- int64_t addr) override {
- SymbolTable<ELFT>::addDefinedAtom(sym, da, addr);
-
- switch (da->codeModel()) {
- case DefinedAtom::codeMipsMicro:
- sym.st_other |= llvm::ELF::STO_MIPS_MICROMIPS;
- break;
- case DefinedAtom::codeMipsMicroPIC:
- sym.st_other |= llvm::ELF::STO_MIPS_MICROMIPS | llvm::ELF::STO_MIPS_PIC;
- break;
- default:
- break;
- }
- }
-
- void finalize(bool sort) override {
- SymbolTable<ELFT>::finalize(sort);
-
- for (auto &ste : this->_symbolTable) {
- if (!ste._atom)
- continue;
- if (const auto *da = dyn_cast<DefinedAtom>(ste._atom)) {
- if (da->codeModel() == DefinedAtom::codeMipsMicro ||
- da->codeModel() == DefinedAtom::codeMipsMicroPIC) {
- // Adjust dynamic microMIPS symbol value. That allows a dynamic
- // linker to recognize and handle this symbol correctly.
- ste._symbol.st_value = ste._symbol.st_value | 1;
- }
- }
- }
- }
+ int64_t addr) override;
+ void finalize(bool sort) override;
};
template <class ELFT>
class MipsDynamicSymbolTable : public DynamicSymbolTable<ELFT> {
public:
MipsDynamicSymbolTable(const ELFLinkingContext &ctx,
- MipsTargetLayout<ELFT> &layout)
- : DynamicSymbolTable<ELFT>(ctx, layout, ".dynsym",
- TargetLayout<ELFT>::ORDER_DYNAMIC_SYMBOLS),
- _targetLayout(layout) {}
-
- void sortSymbols() override {
- typedef typename DynamicSymbolTable<ELFT>::SymbolEntry SymbolEntry;
- std::stable_sort(this->_symbolTable.begin(), this->_symbolTable.end(),
- [this](const SymbolEntry &A, const SymbolEntry &B) {
- if (A._symbol.getBinding() != STB_GLOBAL &&
- B._symbol.getBinding() != STB_GLOBAL)
- return A._symbol.getBinding() < B._symbol.getBinding();
-
- return _targetLayout.getGOTSection().compare(A._atom, B._atom);
- });
- }
-
- void finalize() override {
- DynamicSymbolTable<ELFT>::finalize();
-
- const auto &pltSection = _targetLayout.getPLTSection();
-
- for (auto &ste : this->_symbolTable) {
- const Atom *a = ste._atom;
- if (!a)
- continue;
- if (auto *layout = pltSection.findPLTLayout(a)) {
- a = layout->_atom;
- // Under some conditions a dynamic symbol table record should hold
- // a symbol value of the corresponding PLT entry. For details look
- // at the PLT entry creation code in the class MipsRelocationPass.
- // Let's update atomLayout fields for such symbols.
- assert(!ste._atomLayout);
- ste._symbol.st_value = layout->_virtualAddr;
- ste._symbol.st_other |= ELF::STO_MIPS_PLT;
- }
-
- if (const auto *da = dyn_cast<DefinedAtom>(a)) {
- if (da->codeModel() == DefinedAtom::codeMipsMicro ||
- da->codeModel() == DefinedAtom::codeMipsMicroPIC) {
- // Adjust dynamic microMIPS symbol value. That allows a dynamic
- // linker to recognize and handle this symbol correctly.
- ste._symbol.st_value = ste._symbol.st_value | 1;
- }
- }
- }
- }
+ MipsTargetLayout<ELFT> &layout);
+
+ void sortSymbols() override;
+ void finalize() override;
private:
MipsTargetLayout<ELFT> &_targetLayout;
};
-std::unique_ptr<TargetHandler>
-createMips32ELTargetHandler(MipsLinkingContext &ctx);
-std::unique_ptr<TargetHandler>
-createMips64ELTargetHandler(MipsLinkingContext &ctx);
-
} // end namespace elf
} // end namespace lld
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp?rev=238309&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp (removed)
@@ -1,18 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsTargetHandler32EL.cpp ----------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MipsTargetHandler.h"
-
-using namespace lld;
-using namespace lld::elf;
-
-std::unique_ptr<TargetHandler>
-lld::elf::createMips32ELTargetHandler(MipsLinkingContext &ctx) {
- return llvm::make_unique<MipsTargetHandler<ELF32LE>>(ctx);
-}
Removed: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler64EL.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler64EL.cpp?rev=238309&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler64EL.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetHandler64EL.cpp (removed)
@@ -1,18 +0,0 @@
-//===- lib/ReaderWriter/ELF/Mips/MipsTargetHandler64EL.cpp ----------------===//
-//
-// The LLVM Linker
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MipsTargetHandler.h"
-
-using namespace lld;
-using namespace lld::elf;
-
-std::unique_ptr<TargetHandler>
-lld::elf::createMips64ELTargetHandler(MipsLinkingContext &ctx) {
- return llvm::make_unique<MipsTargetHandler<ELF64LE>>(ctx);
-}
Added: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp?rev=238310&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp (added)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp Wed May 27 06:56:15 2015
@@ -0,0 +1,83 @@
+//===- lib/ReaderWriter/ELF/Mips/MipsTargetLayout.cpp ---------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MipsLinkingContext.h"
+#include "MipsTargetLayout.h"
+
+namespace lld {
+namespace elf {
+
+template <class ELFT>
+MipsTargetLayout<ELFT>::MipsTargetLayout(MipsLinkingContext &ctx)
+ : TargetLayout<ELFT>(ctx),
+ _gotSection(new (this->_allocator) MipsGOTSection<ELFT>(ctx)),
+ _pltSection(new (this->_allocator) MipsPLTSection<ELFT>(ctx)) {}
+
+template <class ELFT>
+AtomSection<ELFT> *MipsTargetLayout<ELFT>::createSection(
+ StringRef name, int32_t type, DefinedAtom::ContentPermissions permissions,
+ typename TargetLayout<ELFT>::SectionOrder order) {
+ if (type == DefinedAtom::typeGOT && name == ".got")
+ return _gotSection;
+ if (type == DefinedAtom::typeStub && name == ".plt")
+ return _pltSection;
+ return TargetLayout<ELFT>::createSection(name, type, permissions, order);
+}
+
+template <class ELFT>
+typename TargetLayout<ELFT>::SegmentType
+MipsTargetLayout<ELFT>::getSegmentType(Section<ELFT> *section) const {
+ switch (section->order()) {
+ case ORDER_MIPS_REGINFO:
+ return llvm::ELF::PT_MIPS_REGINFO;
+ case ORDER_MIPS_OPTIONS:
+ return llvm::ELF::PT_LOAD;
+ default:
+ return TargetLayout<ELFT>::getSegmentType(section);
+ }
+}
+
+template <class ELFT> uint64_t MipsTargetLayout<ELFT>::getGPAddr() {
+ std::call_once(_gpOnce, [this]() {
+ if (AtomLayout *a = this->findAbsoluteAtom("_gp"))
+ _gpAddr = a->_virtualAddr;
+ });
+ return _gpAddr;
+}
+
+template <class ELFT>
+typename TargetLayout<ELFT>::SectionOrder
+MipsTargetLayout<ELFT>::getSectionOrder(StringRef name, int32_t contentType,
+ int32_t contentPermissions) {
+ if ((contentType == DefinedAtom::typeStub) && (name.startswith(".text")))
+ return TargetLayout<ELFT>::ORDER_TEXT;
+
+ return TargetLayout<ELFT>::getSectionOrder(name, contentType,
+ contentPermissions);
+}
+
+template <class ELFT>
+unique_bump_ptr<RelocationTable<ELFT>>
+MipsTargetLayout<ELFT>::createRelocationTable(StringRef name, int32_t order) {
+ return unique_bump_ptr<RelocationTable<ELFT>>(new (
+ this->_allocator) MipsRelocationTable<ELFT>(this->_ctx, name, order));
+}
+
+template <class ELFT>
+uint64_t MipsTargetLayout<ELFT>::getLookupSectionFlags(
+ const OutputSection<ELFT> *os) const {
+ uint64_t flags = TargetLayout<ELFT>::getLookupSectionFlags(os);
+ return flags & ~llvm::ELF::SHF_MIPS_NOSTRIP;
+}
+
+template class MipsTargetLayout<ELF32LE>;
+template class MipsTargetLayout<ELF64LE>;
+
+} // end namespace elf
+} // end namespace lld
Modified: lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h?rev=238310&r1=238309&r2=238310&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/Mips/MipsTargetLayout.h Wed May 27 06:56:15 2015
@@ -25,10 +25,7 @@ public:
ORDER_MIPS_OPTIONS
};
- MipsTargetLayout(MipsLinkingContext &ctx)
- : TargetLayout<ELFT>(ctx),
- _gotSection(new (this->_allocator) MipsGOTSection<ELFT>(ctx)),
- _pltSection(new (this->_allocator) MipsPLTSection<ELFT>(ctx)) {}
+ MipsTargetLayout(MipsLinkingContext &ctx);
const MipsGOTSection<ELFT> &getGOTSection() const { return *_gotSection; }
const MipsPLTSection<ELFT> &getPLTSection() const { return *_pltSection; }
@@ -36,60 +33,26 @@ public:
AtomSection<ELFT> *
createSection(StringRef name, int32_t type,
DefinedAtom::ContentPermissions permissions,
- typename TargetLayout<ELFT>::SectionOrder order) override {
- if (type == DefinedAtom::typeGOT && name == ".got")
- return _gotSection;
- if (type == DefinedAtom::typeStub && name == ".plt")
- return _pltSection;
- return TargetLayout<ELFT>::createSection(name, type, permissions, order);
- }
+ typename TargetLayout<ELFT>::SectionOrder order) override;
typename TargetLayout<ELFT>::SegmentType
- getSegmentType(Section<ELFT> *section) const override {
- switch (section->order()) {
- case ORDER_MIPS_REGINFO:
- return llvm::ELF::PT_MIPS_REGINFO;
- case ORDER_MIPS_OPTIONS:
- return llvm::ELF::PT_LOAD;
- default:
- return TargetLayout<ELFT>::getSegmentType(section);
- }
- }
+ getSegmentType(Section<ELFT> *section) const override;
/// \brief GP offset relative to .got section.
uint64_t getGPOffset() const { return 0x7FF0; }
/// \brief Get '_gp' symbol address.
- uint64_t getGPAddr() {
- std::call_once(_gpOnce, [this]() {
- if (AtomLayout *a = this->findAbsoluteAtom("_gp"))
- _gpAddr = a->_virtualAddr;
- });
- return _gpAddr;
- }
+ uint64_t getGPAddr();
/// \brief Return the section order for a input section
typename TargetLayout<ELFT>::SectionOrder
getSectionOrder(StringRef name, int32_t contentType,
- int32_t contentPermissions) override {
- if ((contentType == DefinedAtom::typeStub) && (name.startswith(".text")))
- return TargetLayout<ELFT>::ORDER_TEXT;
-
- return TargetLayout<ELFT>::getSectionOrder(name, contentType,
- contentPermissions);
- }
+ int32_t contentPermissions) override;
protected:
unique_bump_ptr<RelocationTable<ELFT>>
- createRelocationTable(StringRef name, int32_t order) override {
- return unique_bump_ptr<RelocationTable<ELFT>>(new (
- this->_allocator) MipsRelocationTable<ELFT>(this->_ctx, name, order));
- }
-
- uint64_t getLookupSectionFlags(const OutputSection<ELFT> *os) const override {
- uint64_t flags = TargetLayout<ELFT>::getLookupSectionFlags(os);
- return flags & ~llvm::ELF::SHF_MIPS_NOSTRIP;
- }
+ createRelocationTable(StringRef name, int32_t order) override;
+ uint64_t getLookupSectionFlags(const OutputSection<ELFT> *os) const override;
private:
MipsGOTSection<ELFT> *_gotSection;
More information about the llvm-commits
mailing list