@@ -45,6 +45,7 @@ struct MemoryMappedSegmentData {
4545 const char *current_load_cmd_addr;
4646 u32 lc_type;
4747 uptr base_virt_addr;
48+ uptr addr_mask;
4849};
4950
5051template <typename Section>
@@ -53,58 +54,12 @@ static void NextSectionLoad(LoadedModule *module, MemoryMappedSegmentData *data,
5354 const Section *sc = (const Section *)data->current_load_cmd_addr ;
5455 data->current_load_cmd_addr += sizeof (Section);
5556
56- uptr sec_start = sc->addr + data->base_virt_addr ;
57+ uptr sec_start = ( sc->addr & data-> addr_mask ) + data->base_virt_addr ;
5758 uptr sec_end = sec_start + sc->size ;
5859 module ->addAddressRange (sec_start, sec_end, /* executable=*/ false , isWritable,
5960 sc->sectname );
6061}
6162
62- static bool VerifyMemoryMapping (MemoryMappingLayout* mapping) {
63- InternalMmapVector<LoadedModule> modules;
64- modules.reserve (128 ); // matches DumpProcessMap
65- mapping->DumpListOfModules (&modules);
66-
67- InternalMmapVector<LoadedModule::AddressRange> segments;
68- for (uptr i = 0 ; i < modules.size (); ++i) {
69- for (auto & range : modules[i].ranges ()) {
70- segments.push_back (range);
71- }
72- }
73-
74- // Verify that none of the segments overlap:
75- // 1. Sort the segments by the start address
76- // 2. Check that every segment starts after the previous one ends.
77- Sort (segments.data (), segments.size (),
78- [](LoadedModule::AddressRange& a, LoadedModule::AddressRange& b) {
79- return a.beg < b.beg ;
80- });
81-
82- // To avoid spam, we only print the report message once-per-process.
83- static bool invalid_module_map_reported = false ;
84- bool well_formed = true ;
85-
86- for (size_t i = 1 ; i < segments.size (); i++) {
87- uptr cur_start = segments[i].beg ;
88- uptr prev_end = segments[i - 1 ].end ;
89- if (cur_start < prev_end) {
90- well_formed = false ;
91- VReport (2 , " Overlapping mappings: %s start = %p, %s end = %p\n " ,
92- segments[i].name , (void *)cur_start, segments[i - 1 ].name ,
93- (void *)prev_end);
94- if (!invalid_module_map_reported) {
95- Report (
96- " WARN: Invalid dyld module map detected. This is most likely a bug "
97- " in the sanitizer.\n " );
98- Report (" WARN: Backtraces may be unreliable.\n " );
99- invalid_module_map_reported = true ;
100- }
101- }
102- }
103-
104- mapping->Reset ();
105- return well_formed;
106- }
107-
10863void MemoryMappedSegment::AddAddressRanges (LoadedModule *module ) {
10964 // Don't iterate over sections when the caller hasn't set up the
11065 // data pointer, when there are no sections, or when the segment
@@ -130,7 +85,6 @@ void MemoryMappedSegment::AddAddressRanges(LoadedModule *module) {
13085
13186MemoryMappingLayout::MemoryMappingLayout (bool cache_enabled) {
13287 Reset ();
133- VerifyMemoryMapping (this );
13488}
13589
13690MemoryMappingLayout::~MemoryMappingLayout () {
@@ -236,7 +190,6 @@ typedef struct dyld_shared_cache_dylib_text_info
236190
237191extern bool _dyld_get_shared_cache_uuid (uuid_t uuid);
238192extern const void *_dyld_get_shared_cache_range (size_t *length);
239- extern intptr_t _dyld_get_image_slide (const struct mach_header * mh);
240193extern int dyld_shared_cache_iterate_text (
241194 const uuid_t cacheUuid,
242195 void (^callback)(const dyld_shared_cache_dylib_text_info *info));
@@ -305,21 +258,23 @@ static bool NextSegmentLoad(MemoryMappedSegment *segment,
305258 layout_data->current_load_cmd_count --;
306259 if (((const load_command *)lc)->cmd == kLCSegment ) {
307260 const SegmentCommand* sc = (const SegmentCommand *)lc;
308- if ( strncmp (sc-> segname , " __LINKEDIT " , sizeof ( " __LINKEDIT " )) == 0 ) {
309- // The LINKEDIT sections are for internal linker use, and may alias
310- // with the LINKEDIT section for other modules. (If we included them,
311- // our memory map would contain overlappping sections.)
312- return false ;
313- }
314-
315- uptr base_virt_addr;
316- if (layout_data-> current_image == kDyldImageIdx )
317- base_virt_addr = (uptr) _dyld_get_image_slide ( get_dyld_hdr ()) ;
318- else
261+ uptr base_virt_addr, addr_mask;
262+ if (layout_data-> current_image == kDyldImageIdx ) {
263+ base_virt_addr = (uptr) get_dyld_hdr ();
264+ // vmaddr is masked with 0xfffff because on macOS versions < 10.12,
265+ // it contains an absolute address rather than an offset for dyld.
266+ // To make matters even more complicated, this absolute address
267+ // isn't actually the absolute segment address, but the offset portion
268+ // of the address is accurate when combined with the dyld base address,
269+ // and the mask will give just this offset.
270+ addr_mask = 0xfffff ;
271+ } else {
319272 base_virt_addr =
320273 (uptr)_dyld_get_image_vmaddr_slide (layout_data->current_image );
274+ addr_mask = ~0 ;
275+ }
321276
322- segment->start = sc->vmaddr + base_virt_addr;
277+ segment->start = ( sc->vmaddr & addr_mask) + base_virt_addr;
323278 segment->end = segment->start + sc->vmsize ;
324279 // Most callers don't need section information, so only fill this struct
325280 // when required.
@@ -329,6 +284,7 @@ static bool NextSegmentLoad(MemoryMappedSegment *segment,
329284 (const char *)lc + sizeof (SegmentCommand);
330285 seg_data->lc_type = kLCSegment ;
331286 seg_data->base_virt_addr = base_virt_addr;
287+ seg_data->addr_mask = addr_mask;
332288 internal_strncpy (seg_data->name , sc->segname ,
333289 ARRAY_SIZE (seg_data->name ));
334290 }
0 commit comments