@@ -100,12 +100,14 @@ class Image {
100
100
101
101
uint64_t HeaderAddress;
102
102
std::vector<Segment> Segments;
103
+ llvm::DenseMap<uint64_t , StringRef> DynamicRelocations;
103
104
104
105
void scanMachO (const MachOObjectFile *O) {
105
106
using namespace llvm ::MachO;
106
107
107
108
HeaderAddress = UINT64_MAX;
108
109
110
+ // Collect the segment preferred vm mappings.
109
111
for (const auto &Load : O->load_commands ()) {
110
112
if (Load.C .cmd == LC_SEGMENT_64) {
111
113
auto Seg = O->getSegment64LoadCommand (Load);
@@ -135,6 +137,23 @@ class Image {
135
137
HeaderAddress = std::min (HeaderAddress, (uint64_t )Seg.vmaddr );
136
138
}
137
139
}
140
+
141
+ // Walk through the bindings list to collect all the external references
142
+ // in the image.
143
+ llvm::Error error = llvm::Error::success ();
144
+ auto OO = const_cast <MachOObjectFile*>(O);
145
+
146
+ for (auto bind : OO->bindTable (error)) {
147
+ if (error) {
148
+ llvm::consumeError (std::move (error));
149
+ break ;
150
+ }
151
+
152
+ DynamicRelocations.insert ({bind.address (), bind.symbolName ()});
153
+ }
154
+ if (error) {
155
+ llvm::consumeError (std::move (error));
156
+ }
138
157
}
139
158
140
159
template <typename ELFT>
@@ -249,6 +268,15 @@ class Image {
249
268
}
250
269
return {};
251
270
}
271
+
272
+ RemoteAbsolutePointer
273
+ resolvePointer (uint64_t Addr, uint64_t pointerValue) const {
274
+ auto found = DynamicRelocations.find (Addr);
275
+ if (found == DynamicRelocations.end ())
276
+ return RemoteAbsolutePointer (" " , pointerValue);
277
+
278
+ return RemoteAbsolutePointer (found->second , pointerValue);
279
+ }
252
280
};
253
281
254
282
// / MemoryReader that reads from the on-disk representation of an executable
@@ -260,14 +288,31 @@ class Image {
260
288
// / the image.
261
289
class ObjectMemoryReader : public MemoryReader {
262
290
std::vector<Image> Images;
291
+
292
+ std::pair<const Image *, uint64_t >
293
+ decodeImageIndexAndAddress (uint64_t Addr) const {
294
+ unsigned index = Addr >> 48 ;
295
+ if (index >= Images.size ())
296
+ return {nullptr , 0 };
297
+
298
+ return {&Images[index], Addr & ((1ull << 48 ) - 1 )};
299
+ }
300
+
301
+ uint64_t
302
+ encodeImageIndexAndAddress (const Image *image, uint64_t imageAddr) const {
303
+ unsigned index = image - Images.data ();
304
+ return imageAddr | ((uint64_t )index << 48 );
305
+ }
263
306
264
307
StringRef getContentsAtAddress (uint64_t Addr, uint64_t Size) {
265
- auto imageIndex = Addr >> 48 ;
266
- if (imageIndex >= Images.size ())
308
+ const Image *image;
309
+ uint64_t imageAddr;
310
+ std::tie (image, imageAddr) = decodeImageIndexAndAddress (Addr);
311
+
312
+ if (!image)
267
313
return StringRef ();
268
314
269
- return Images[imageIndex]
270
- .getContentsAtAddress (Addr & 0xFFFFFFFFFFFFull , Size);
315
+ return image->getContentsAtAddress (imageAddr, Size);
271
316
}
272
317
273
318
public:
@@ -305,7 +350,8 @@ class ObjectMemoryReader : public MemoryReader {
305
350
RemoteAddress getImageStartAddress (unsigned i) const {
306
351
assert (i < Images.size ());
307
352
308
- return RemoteAddress (Images[i].getStartAddress () | ((uint64_t )i << 48 ));
353
+ return RemoteAddress (
354
+ encodeImageIndexAndAddress (&Images[i], Images[i].getStartAddress ()));
309
355
}
310
356
311
357
// TODO: We could consult the dynamic symbol tables of the images to
@@ -338,6 +384,29 @@ class ObjectMemoryReader : public MemoryReader {
338
384
Dest.append (resultBuffer.begin (), resultBuffer.begin () + i);
339
385
return true ;
340
386
}
387
+
388
+ RemoteAbsolutePointer resolvePointer (RemoteAddress Addr,
389
+ uint64_t pointerValue) override {
390
+ auto addrValue = Addr.getAddressData ();
391
+ const Image *image;
392
+ uint64_t imageAddr;
393
+ std::tie (image, imageAddr) =
394
+ decodeImageIndexAndAddress (addrValue);
395
+
396
+ if (!image)
397
+ return RemoteAbsolutePointer ();
398
+
399
+ auto resolved = image->resolvePointer (imageAddr, pointerValue);
400
+
401
+ if (resolved && resolved.isResolved ()) {
402
+ // Mix in the image index again to produce a remote address pointing into
403
+ // the same image.
404
+ return RemoteAbsolutePointer (" " , encodeImageIndexAndAddress (image,
405
+ resolved.getResolvedAddress ().getAddressData ()));
406
+ }
407
+ // If the pointer is relative to an unresolved relocation, leave it as is.
408
+ return resolved;
409
+ }
341
410
};
342
411
343
412
static int doDumpReflectionSections (ArrayRef<std::string> BinaryFilenames,
0 commit comments