25
25
#include " llvm/Object/ELF.h"
26
26
#include " llvm/Object/ELFObjectFile.h"
27
27
#include " llvm/Object/MachOUniversal.h"
28
+ #include " llvm/Object/RelocationResolver.h"
28
29
#include " llvm/Support/CommandLine.h"
29
30
#include " llvm/Support/Error.h"
30
31
@@ -96,7 +97,11 @@ class Image {
96
97
const ObjectFile *O;
97
98
uint64_t HeaderAddress;
98
99
std::vector<Segment> Segments;
99
- llvm::DenseMap<uint64_t , StringRef> DynamicRelocations;
100
+ struct DynamicRelocation {
101
+ StringRef Symbol;
102
+ uint64_t Offset;
103
+ };
104
+ llvm::DenseMap<uint64_t , DynamicRelocation> DynamicRelocations;
100
105
101
106
void scanMachO (const MachOObjectFile *O) {
102
107
using namespace llvm ::MachO;
@@ -144,7 +149,25 @@ class Image {
144
149
llvm::consumeError (std::move (error));
145
150
break ;
146
151
}
147
- DynamicRelocations.insert ({bind.address (), bind.symbolName ()});
152
+
153
+ // The offset from the symbol is stored at the target address.
154
+ uint64_t Offset;
155
+ auto OffsetContent = getContentsAtAddress (bind.address (),
156
+ O->getBytesInAddress ());
157
+ if (OffsetContent.empty ())
158
+ continue ;
159
+
160
+ if (O->getBytesInAddress () == 8 ) {
161
+ memcpy (&Offset, OffsetContent.data (), sizeof (Offset));
162
+ } else if (O->getBytesInAddress () == 4 ) {
163
+ uint32_t OffsetValue;
164
+ memcpy (&OffsetValue, OffsetContent.data (), sizeof (OffsetValue));
165
+ Offset = OffsetValue;
166
+ } else {
167
+ assert (false && " unexpected word size?!" );
168
+ }
169
+
170
+ DynamicRelocations.insert ({bind.address (), {bind.symbolName (), Offset}});
148
171
}
149
172
if (error) {
150
173
llvm::consumeError (std::move (error));
@@ -160,7 +183,6 @@ class Image {
160
183
auto phdrs = O->getELFFile ()->program_headers ();
161
184
if (!phdrs) {
162
185
llvm::consumeError (phdrs.takeError ());
163
- return ;
164
186
}
165
187
166
188
for (auto &ph : *phdrs) {
@@ -175,6 +197,45 @@ class Image {
175
197
Segments.push_back ({ph.p_vaddr , contents});
176
198
HeaderAddress = std::min (HeaderAddress, (uint64_t )ph.p_vaddr );
177
199
}
200
+
201
+ // Collect the dynamic relocations.
202
+ auto resolver = getRelocationResolver (*O);
203
+ auto resolverSupports = resolver.first ;
204
+ auto resolve = resolver.second ;
205
+
206
+ if (!resolverSupports || !resolve)
207
+ return ;
208
+
209
+ auto machine = O->getELFFile ()->getHeader ()->e_machine ;
210
+ auto relativeRelocType = getELFRelativeRelocationType (machine);
211
+
212
+ for (auto &S : static_cast <const ELFObjectFileBase*>(O)
213
+ ->dynamic_relocation_sections ()) {
214
+ bool isRela = O->getSection (S.getRawDataRefImpl ())->sh_type
215
+ == llvm::ELF::SHT_RELA;
216
+
217
+ for (const RelocationRef &R : S.relocations ()) {
218
+ // `getRelocationResolver` doesn't handle RELATIVE relocations, so we
219
+ // have to do that ourselves.
220
+ if (isRela && R.getType () == relativeRelocType) {
221
+ auto rela = O->getRela (R.getRawDataRefImpl ());
222
+ DynamicRelocations.insert ({R.getOffset (),
223
+ {{}, HeaderAddress + rela->r_addend }});
224
+ continue ;
225
+ }
226
+
227
+ if (!resolverSupports (R.getType ()))
228
+ continue ;
229
+ auto symbol = R.getSymbol ();
230
+ auto name = symbol->getName ();
231
+ if (!name) {
232
+ llvm::consumeError (name.takeError ());
233
+ continue ;
234
+ }
235
+ uint64_t offset = resolve (R, 0 , 0 );
236
+ DynamicRelocations.insert ({R.getOffset (), {*name, offset}});
237
+ }
238
+ }
178
239
}
179
240
180
241
void scanELF (const ELFObjectFileBase *O) {
@@ -186,6 +247,8 @@ class Image {
186
247
scanELFType (le64);
187
248
} else if (auto be64 = dyn_cast<ELFObjectFile<ELF64BE>>(O)) {
188
249
scanELFType (be64);
250
+ } else {
251
+ return ;
189
252
}
190
253
191
254
// FIXME: ReflectionContext tries to read bits of the ELF structure that
@@ -215,6 +278,8 @@ class Image {
215
278
Segments.push_back ({SectionBase, SectionContent});
216
279
}
217
280
281
+ // FIXME: We need to map the header at least, but how much of it does
282
+ // Windows typically map?
218
283
Segments.push_back ({HeaderAddress, O->getData ()});
219
284
}
220
285
@@ -272,7 +337,8 @@ class Image {
272
337
if (found == DynamicRelocations.end ())
273
338
result = RemoteAbsolutePointer (" " , pointerValue);
274
339
else
275
- result = RemoteAbsolutePointer (found->second , pointerValue);
340
+ result = RemoteAbsolutePointer (found->second .Symbol ,
341
+ found->second .Offset );
276
342
return result;
277
343
}
278
344
};
0 commit comments