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
|
//===- 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 "llvm/ADT/DenseMap.h"
#include "lld/Core/LLVM.h"
#include "lld/Core/Reference.h"
#include "lld/ReaderWriter/WriterELF.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 {
///
/// The KindHandler class is 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(uint16_t arch,
llvm::support::endianness endian);
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);
// 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.
private:
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 PPCKindHandler : 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_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;
};
} // namespace elf
} // namespace lld
#endif // LLD_READER_WRITER_ELF_REFERENCE_KINDS_H_
|