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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
|
//===- lib/ReaderWriter/ELF/ReferenceKinds.h ------------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lld/Core/LLVM.h"
#include "lld/Core/Reference.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>
#include <memory>
#ifndef LLD_READER_WRITER_ELF_REFERENCE_KINDS_H
#define LLD_READER_WRITER_ELF_REFERENCE_KINDS_H
namespace lld {
namespace elf {
/// \brief the abstract interface to Reference::Kind values for ELF files.
///
/// Particular Kind values (e.g. 3) has a different meaning for each
/// architecture.
///
/// TODO: Needs to be updated for ELF, stubs for now.
class KindHandler {
public:
typedef Reference::Kind Kind;
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;
virtual bool isCallSite(Kind) = 0;
virtual bool isPointer(Kind) = 0;
virtual bool isLazyImmediate(Kind) = 0;
virtual bool isLazyTarget(Kind) = 0;
virtual void applyFixup(int32_t reloc, uint64_t addend,
uint8_t *location,
uint64_t fixupAddress,
uint64_t targetAddress) = 0;
protected:
KindHandler();
};
class HexagonKindHandler : public KindHandler {
public:
// Note: Reference::Kinds are a another representation of relocation types,
// using negative values to represent architecture independent reference type.
// The positive values are the same ones defined in ELF.h and that is what we
// are using.
enum Kinds {
none = llvm::ELF::R_HEX_NONE,
invalid = 255 // used to denote an error creating a Reference
};
enum RelocationError {
NoError,
Overflow
};
virtual ~HexagonKindHandler();
HexagonKindHandler();
virtual Kind stringToKind(StringRef str);
virtual StringRef kindToString(Kind);
virtual bool isCallSite(Kind);
virtual bool isPointer(Kind);
virtual bool isLazyImmediate(Kind);
virtual bool isLazyTarget(Kind);
virtual void applyFixup(int32_t reloc, uint64_t addend,
uint8_t *location,
uint64_t fixupAddress, uint64_t targetAddress);
private:
// A map is used here and in the other handlers but if performace overhead
// becomes an issue this could be implemented as an array of function
// pointers.
llvm::DenseMap<int32_t,
std::function<int (uint8_t *location, uint64_t fixupAddress,
uint64_t targetAddress, uint64_t addend)> > _fixupHandler;
};
class X86KindHandler : public KindHandler {
public:
enum Kinds {
invalid, // used to denote an error creating a Reference
none,
};
enum RelocationError {
NoError,
};
virtual ~X86KindHandler();
X86KindHandler();
virtual Kind stringToKind(StringRef str);
virtual StringRef kindToString(Kind);
virtual bool isCallSite(Kind);
virtual bool isPointer(Kind);
virtual bool isLazyImmediate(Kind);
virtual bool isLazyTarget(Kind);
virtual void applyFixup(int32_t reloc, uint64_t addend, uint8_t *location,
uint64_t fixupAddress, uint64_t targetAddress);
private:
llvm::DenseMap<int32_t,
std::function<int (uint8_t *location, uint64_t fixupAddress,
uint64_t targetAddress, uint64_t addend)> > _fixupHandler;
};
class X86_64KindHandler : public KindHandler {
public:
enum Kinds {
invalid, // used to denote an error creating a Reference
none,
};
enum RelocationError {
NoError,
};
virtual ~X86_64KindHandler();
X86_64KindHandler();
virtual Kind stringToKind(StringRef str);
virtual StringRef kindToString(Kind);
virtual bool isCallSite(Kind);
virtual bool isPointer(Kind);
virtual bool isLazyImmediate(Kind);
virtual bool isLazyTarget(Kind);
virtual void applyFixup(int32_t reloc, uint64_t addend, uint8_t *location,
uint64_t fixupAddress, uint64_t targetAddress);
private:
llvm::DenseMap<int32_t,
std::function<int (uint8_t *location, uint64_t fixupAddress,
uint64_t targetAddress, uint64_t addend)> > _fixupHandler;
};
class PPCKindHandler : public KindHandler {
public:
enum Kinds {
none = llvm::ELF::R_PPC_NONE,
invalid = 255, // used to denote an error creating a Reference
};
enum RelocationError {
NoError,
Overflow
};
virtual ~PPCKindHandler();
PPCKindHandler(llvm::support::endianness endian);
virtual Kind stringToKind(StringRef str);
virtual StringRef kindToString(Kind);
virtual bool isCallSite(Kind);
virtual bool isPointer(Kind);
virtual bool isLazyImmediate(Kind);
virtual bool isLazyTarget(Kind);
virtual void applyFixup(int32_t reloc, uint64_t addend,
uint8_t *location,
uint64_t fixupAddress, uint64_t targetAddress);
private:
llvm::DenseMap<int32_t,
std::function<int (uint8_t *location, uint64_t fixupAddress,
uint64_t targetAddress, uint64_t addend)> > _fixupHandler;
};
} // end namespace elf
} // end namespace lld
#endif
|