blob: f64a5099466b09feb7b98ad2db1d7e79d7be6895 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
//===- 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
namespace lld {
namespace elf {
template <typename ELFT> class MipsTargetLayout;
class MipsLinkingContext;
/// \brief Handle Mips GOT section
template <class ELFType> class MipsGOTSection : public AtomSection<ELFType> {
public:
MipsGOTSection(const MipsLinkingContext &context)
: AtomSection<ELFType>(context, ".got", DefinedAtom::typeGOT,
DefinedAtom::permRW_,
MipsTargetLayout<ELFType>::ORDER_GOT),
_globalCount(0) {
this->_flags |= SHF_MIPS_GPREL;
this->_align2 = 4;
}
/// \brief Number of local GOT entries.
std::size_t getLocalCount() const {
return this->_atoms.size() - _globalCount;
}
/// \brief Number of global GOT entries.
std::size_t getGlobalCount() const { return _globalCount; }
/// \brief Does the atom have a global GOT entry?
bool hasGlobalGOTEntry(const Atom *a) const { return _posMap.count(a); }
/// \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;
return ia == _posMap.end() && ib != _posMap.end();
}
const lld::AtomLayout &appendAtom(const Atom *atom) override {
const DefinedAtom *da = dyn_cast<DefinedAtom>(atom);
const Atom *ta = nullptr;
for (const auto &r : *da) {
if (r->kindNamespace() != lld::Reference::KindNamespace::ELF)
continue;
assert(r->kindArch() == Reference::KindArch::Mips);
if (r->kindValue() == LLD_R_MIPS_GLOBAL_GOT) {
ta = r->target();
break;
}
}
if (ta) {
_posMap[ta] = _posMap.size();
++_globalCount;
}
return AtomSection<ELFType>::appendAtom(atom);
}
private:
/// \brief Number of global GOT entries.
std::size_t _globalCount;
/// \brief Map Atoms to their GOT entry index.
llvm::DenseMap<const Atom *, std::size_t> _posMap;
};
} // elf
} // lld
#endif
|