132 lines
4.0 KiB
C++
132 lines
4.0 KiB
C++
//===- lib/ReaderWriter/ELF/Mips/MipsSectionChunks.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_SECTION_CHUNKS_H
|
|
#define LLD_READER_WRITER_ELF_MIPS_MIPS_SECTION_CHUNKS_H
|
|
|
|
#include "MipsReginfo.h"
|
|
#include "SectionChunks.h"
|
|
|
|
namespace lld {
|
|
namespace elf {
|
|
|
|
template <typename ELFT> class MipsTargetLayout;
|
|
class MipsLinkingContext;
|
|
|
|
/// \brief Handle Mips .reginfo section
|
|
template <class ELFT> class MipsReginfoSection : public Section<ELFT> {
|
|
public:
|
|
MipsReginfoSection(const ELFLinkingContext &ctx,
|
|
MipsTargetLayout<ELFT> &targetLayout,
|
|
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;
|
|
void finalize() override;
|
|
|
|
private:
|
|
typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
|
|
|
|
Elf_Mips_RegInfo _reginfo;
|
|
MipsTargetLayout<ELFT> &_targetLayout;
|
|
};
|
|
|
|
/// \brief Handle .MIPS.options section
|
|
template <class ELFT> class MipsOptionsSection : public Section<ELFT> {
|
|
public:
|
|
MipsOptionsSection(const ELFLinkingContext &ctx,
|
|
MipsTargetLayout<ELFT> &targetLayout,
|
|
const MipsReginfo ®info);
|
|
|
|
bool hasOutputSegment() const override { return true; }
|
|
|
|
void write(ELFWriter *writer, TargetLayout<ELFT> &layout,
|
|
llvm::FileOutputBuffer &buffer) override;
|
|
void finalize() override;
|
|
|
|
private:
|
|
typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
|
|
typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
|
|
|
|
Elf_Mips_Options _header;
|
|
Elf_Mips_RegInfo _reginfo;
|
|
MipsTargetLayout<ELFT> &_targetLayout;
|
|
};
|
|
|
|
/// \brief Handle Mips GOT section
|
|
template <class ELFT> class MipsGOTSection : public AtomSection<ELFT> {
|
|
public:
|
|
MipsGOTSection(const MipsLinkingContext &ctx);
|
|
|
|
/// \brief Number of local GOT entries.
|
|
std::size_t getLocalCount() const { return _localCount; }
|
|
|
|
/// \brief Number of global GOT entries.
|
|
std::size_t getGlobalCount() const { return _posMap.size(); }
|
|
|
|
/// \brief Does the atom have a global GOT entry?
|
|
bool hasGlobalGOTEntry(const Atom *a) const {
|
|
return _posMap.count(a) || _tlsMap.count(a);
|
|
}
|
|
|
|
/// \brief Compare two atoms accordingly theirs positions in the GOT.
|
|
bool compare(const Atom *a, const Atom *b) const;
|
|
|
|
const AtomLayout *appendAtom(const Atom *atom) override;
|
|
|
|
private:
|
|
/// \brief True if the GOT contains non-local entries.
|
|
bool _hasNonLocal;
|
|
|
|
/// \brief Number of local GOT entries.
|
|
std::size_t _localCount;
|
|
|
|
/// \brief Map TLS Atoms to their GOT entry index.
|
|
llvm::DenseMap<const Atom *, std::size_t> _tlsMap;
|
|
|
|
/// \brief Map Atoms to their GOT entry index.
|
|
llvm::DenseMap<const Atom *, std::size_t> _posMap;
|
|
};
|
|
|
|
/// \brief Handle Mips PLT section
|
|
template <class ELFT> class MipsPLTSection : public AtomSection<ELFT> {
|
|
public:
|
|
MipsPLTSection(const MipsLinkingContext &ctx);
|
|
|
|
const AtomLayout *findPLTLayout(const Atom *plt) const;
|
|
|
|
const AtomLayout *appendAtom(const Atom *atom) override;
|
|
|
|
private:
|
|
/// \brief Map PLT Atoms to their layouts.
|
|
std::unordered_map<const Atom *, const AtomLayout *> _pltLayoutMap;
|
|
};
|
|
|
|
template <class ELFT> class MipsRelocationTable : public RelocationTable<ELFT> {
|
|
typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
|
|
typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
|
|
|
|
public:
|
|
MipsRelocationTable(const ELFLinkingContext &ctx, StringRef str,
|
|
int32_t order);
|
|
|
|
protected:
|
|
void writeRela(ELFWriter *writer, Elf_Rela &r, const DefinedAtom &atom,
|
|
const Reference &ref) override;
|
|
void writeRel(ELFWriter *writer, Elf_Rel &r, const DefinedAtom &atom,
|
|
const Reference &ref) override;
|
|
};
|
|
|
|
} // elf
|
|
} // lld
|
|
|
|
#endif
|