@@ -232,17 +232,6 @@ class Image {
232
232
fputs (" unsupported image format\n " , stderr);
233
233
abort ();
234
234
}
235
-
236
- // ObjectMemoryReader uses the most significant 16 bits of the address to
237
- // index multiple images, so if an object maps stuff out of that range
238
- // we won't be able to read it. 2**48 of virtual address space ought to be
239
- // enough for anyone, but warn if we blow that limit.
240
- for (auto Segment : Segments) {
241
- if (Segment.Addr >= 0xFFFFFFFFFFFFull ) {
242
- fputs (" warning: segment mapped at address above 2**48\n " , stderr);
243
- continue ;
244
- }
245
- }
246
235
}
247
236
248
237
unsigned getBytesInAddress () const {
@@ -252,6 +241,14 @@ class Image {
252
241
uint64_t getStartAddress () const {
253
242
return HeaderAddress;
254
243
}
244
+
245
+ uint64_t getEndAddress () const {
246
+ uint64_t max = 0 ;
247
+ for (auto &Segment : Segments) {
248
+ max = std::max (max, Segment.Addr + Segment.Contents .size ());
249
+ }
250
+ return max;
251
+ }
255
252
256
253
StringRef getContentsAtAddress (uint64_t Addr, uint64_t Size) const {
257
254
for (auto &Segment : Segments) {
@@ -288,21 +285,27 @@ class Image {
288
285
// / and the low 48 bits correspond to the preferred virtual address mapping of
289
286
// / the image.
290
287
class ObjectMemoryReader : public MemoryReader {
291
- std::vector<Image> Images;
288
+ struct ImageEntry {
289
+ Image TheImage;
290
+ uint64_t Slide;
291
+ };
292
+ std::vector<ImageEntry> Images;
292
293
293
294
std::pair<const Image *, uint64_t >
294
295
decodeImageIndexAndAddress (uint64_t Addr) const {
295
- unsigned index = Addr >> 48 ;
296
- if (index >= Images.size ())
297
- return {nullptr , 0 };
298
-
299
- return {&Images[index], Addr & ((1ull << 48 ) - 1 )};
296
+ for (auto &Image : Images) {
297
+ if (Image.TheImage .getStartAddress () + Image.Slide <= Addr
298
+ && Addr < Image.TheImage .getEndAddress () + Image.Slide ) {
299
+ return {&Image.TheImage , Addr - Image.Slide };
300
+ }
301
+ }
302
+ return {nullptr , 0 };
300
303
}
301
304
302
305
uint64_t
303
306
encodeImageIndexAndAddress (const Image *image, uint64_t imageAddr) const {
304
- unsigned index = image - Images. data () ;
305
- return imageAddr | (( uint64_t )index << 48 ) ;
307
+ auto entry = ( const ImageEntry*)image ;
308
+ return imageAddr + entry-> Slide ;
306
309
}
307
310
308
311
StringRef getContentsAtAddress (uint64_t Addr, uint64_t Size) {
@@ -323,11 +326,6 @@ class ObjectMemoryReader : public MemoryReader {
323
326
fputs (" no object files provided\n " , stderr);
324
327
abort ();
325
328
}
326
- // We use a 16-bit index for images, so can't take more than 64K at once.
327
- if (ObjectFiles.size () > 0x10000 ) {
328
- fputs (" can't dump more than 65,536 images at once\n " , stderr);
329
- abort ();
330
- }
331
329
unsigned WordSize = 0 ;
332
330
for (const ObjectFile *O : ObjectFiles) {
333
331
// All the object files we look at should share a word size.
@@ -337,15 +335,32 @@ class ObjectMemoryReader : public MemoryReader {
337
335
fputs (" object files must all be for the same architecture\n " , stderr);
338
336
abort ();
339
337
}
340
- Images.emplace_back (O);
338
+ Images.push_back ({Image (O), 0 });
339
+ }
340
+
341
+ // If there is more than one image loaded, try to fit them into one address
342
+ // space.
343
+ if (Images.size () > 1 ) {
344
+ uint64_t NextAddrSpace = 0 ;
345
+ for (auto &Image : Images) {
346
+ Image.Slide = NextAddrSpace - Image.TheImage .getStartAddress ();
347
+ NextAddrSpace +=
348
+ Image.TheImage .getEndAddress () - Image.TheImage .getStartAddress ();
349
+ NextAddrSpace = (NextAddrSpace + 16383 ) & ~16383 ;
350
+ }
351
+
352
+ if (WordSize < 8 && NextAddrSpace > 0xFFFFFFFFu ) {
353
+ fputs (" object files did not fit in address space" , stderr);
354
+ abort ();
355
+ }
341
356
}
342
357
}
343
358
344
- ArrayRef<Image > getImages () const { return Images; }
359
+ ArrayRef<ImageEntry > getImages () const { return Images; }
345
360
346
361
bool queryDataLayout (DataLayoutQueryType type, void *inBuffer,
347
362
void *outBuffer) override {
348
- auto wordSize = Images.front ().getBytesInAddress ();
363
+ auto wordSize = Images.front ().TheImage . getBytesInAddress ();
349
364
switch (type) {
350
365
case DLQ_GetPointerSize: {
351
366
auto result = static_cast <uint8_t *>(outBuffer);
@@ -366,7 +381,8 @@ class ObjectMemoryReader : public MemoryReader {
366
381
assert (i < Images.size ());
367
382
368
383
return RemoteAddress (
369
- encodeImageIndexAndAddress (&Images[i], Images[i].getStartAddress ()));
384
+ encodeImageIndexAndAddress (&Images[i].TheImage ,
385
+ Images[i].TheImage .getStartAddress ()));
370
386
}
371
387
372
388
// TODO: We could consult the dynamic symbol tables of the images to
0 commit comments