[Lldb-commits] [lldb] r176589 - Retrieve the dyld shared cache mapping offset from the shared cache instead of hardcoding the value.

Jason Molenda jmolenda at apple.com
Wed Mar 6 15:17:36 PST 2013


Author: jmolenda
Date: Wed Mar  6 17:17:36 2013
New Revision: 176589

URL: http://llvm.org/viewvc/llvm-project?rev=176589&view=rev
Log:
Retrieve the dyld shared cache mapping offset from the shared cache instead of hardcoding the value.
Read the version number of the dyld shared cache.
<rdar://problem/13311882> 

Modified:
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=176589&r1=176588&r2=176589&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Wed Mar  6 17:17:36 2013
@@ -1531,11 +1531,11 @@ ObjectFileMachO::ParseSymtab (bool minim
             FileSpec dsc_filespec(dsc_path, false);
 
             // We need definitions of two structures in the on-disk DSC, copy them here manually
-            struct lldb_copy_dyld_cache_header
+           struct lldb_copy_dyld_cache_header_v0
             {
-                char		magic[16];
-                uint32_t	mappingOffset;
-                uint32_t	mappingCount;
+               char        magic[16];            // e.g. "dyld_v0    i386", "dyld_v1   armv7", etc.
+               uint32_t    mappingOffset;        // file offset to first dyld_cache_mapping_info
+               uint32_t    mappingCount;         // number of dyld_cache_mapping_info entries
                 uint32_t	imagesOffset;
                 uint32_t	imagesCount;
                 uint64_t	dyldBaseAddress;
@@ -1543,9 +1543,35 @@ ObjectFileMachO::ParseSymtab (bool minim
                 uint64_t	codeSignatureSize;
                 uint64_t	slideInfoOffset;
                 uint64_t	slideInfoSize;
+               uint64_t    localSymbolsOffset;   // file offset of where local symbols are stored
+               uint64_t    localSymbolsSize;     // size of local symbols information
+           };
+           struct lldb_copy_dyld_cache_header_v1
+           {
+               char        magic[16];            // e.g. "dyld_v0    i386", "dyld_v1   armv7", etc.
+               uint32_t    mappingOffset;        // file offset to first dyld_cache_mapping_info
+               uint32_t    mappingCount;         // number of dyld_cache_mapping_info entries
+               uint32_t    imagesOffset;
+               uint32_t    imagesCount;
+               uint64_t    dyldBaseAddress;
+               uint64_t    codeSignatureOffset;
+               uint64_t    codeSignatureSize;
+               uint64_t    slideInfoOffset;
+               uint64_t    slideInfoSize;
                 uint64_t	localSymbolsOffset;
                 uint64_t	localSymbolsSize;
+               uint8_t     uuid[16];             // v1 and above, also recorded in dyld_all_image_infos v13 and later
             };
+
+           struct lldb_copy_dyld_cache_mapping_info
+           {
+               uint64_t        address;
+               uint64_t        size;
+               uint64_t        fileOffset;
+               uint32_t        maxProt;
+               uint32_t        initProt;
+           };
+
             struct lldb_copy_dyld_cache_local_symbols_info
             {
                     uint32_t        nlistOffset;
@@ -1578,19 +1604,48 @@ ObjectFileMachO::ParseSymtab (bool minim
             //
             // Save some VM space, do not map the entire cache in one shot.
 
-            if (DataBufferSP dsc_data_sp = dsc_filespec.MemoryMapFileContents(0, sizeof(struct lldb_copy_dyld_cache_header))) 
+            DataBufferSP dsc_data_sp;
+            dsc_data_sp = dsc_filespec.MemoryMapFileContents(0, sizeof(struct lldb_copy_dyld_cache_header_v1));
+
+            if (dsc_data_sp)
             {
                 DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size);
 
-                lldb::offset_t offset = offsetof (struct lldb_copy_dyld_cache_header, mappingOffset); 
+                char version_str[17];
+                int version = -1;
+                lldb::offset_t offset = 0;
+                memcpy (version_str, dsc_header_data.GetData (&offset, 16), 16);
+                version_str[16] = '\0';
+                if (strncmp (version_str, "dyld_v", 6) == 0 && isdigit (version_str[6]))
+                {
+                    int v;
+                    if (::sscanf (version_str + 6, "%d", &v) == 1)
+                    {
+                        version = v;
+                    }
+                }
+
+                offset = offsetof (struct lldb_copy_dyld_cache_header_v1, mappingOffset); 
+
                 uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
 
                 // If the mappingOffset points to a location inside the header, we've
                 // opened an old dyld shared cache, and should not proceed further.
-                if (mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header)) 
+                if ((version == 0 && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v0))
+                    || (version >= 1 && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v1)))
                 {
 
-                    offset = offsetof (struct lldb_copy_dyld_cache_header, localSymbolsOffset);
+                    DataBufferSP dsc_mapping_info_data_sp = dsc_filespec.MemoryMapFileContents(mappingOffset, sizeof (struct lldb_copy_dyld_cache_mapping_info));
+                    DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp, byte_order, addr_byte_size);
+                    offset = 0;
+
+                    // The File addresses (from the in-memory Mach-O load commands) for the shared libraries
+                    // in the shared library cache need to be adjusted by an offset to match up with the
+                    // dylibOffset identifying field in the dyld_cache_local_symbol_entry's.  This offset is
+                    // recorded in mapping_offset_value.
+                    const uint64_t mapping_offset_value = dsc_mapping_info_data.GetU64(&offset);
+
+                    offset = offsetof (struct lldb_copy_dyld_cache_header_v1, localSymbolsOffset);
                     uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
                     uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);
 
@@ -1607,14 +1662,9 @@ ObjectFileMachO::ParseSymtab (bool minim
                             struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
                             dsc_local_symbols_data.GetU32(&offset, &local_symbols_info.nlistOffset, 6);
 
-                            // The local_symbols_infos offsets are offsets into local symbols memory, NOT file offsets!
-                            // We first need to identify the local "entry" that matches the current header.
-                            // The "entry" is stored as a file offset in the dyld_shared_cache, so we need to
-                            // adjust the raw m_header value by slide and 0x30000000.
-
                             SectionSP text_section_sp(section_list->FindSectionByName(GetSegmentNameTEXT()));
 
-                            uint32_t header_file_offset = (text_section_sp->GetFileAddress() - 0x30000000);
+                            uint32_t header_file_offset = (text_section_sp->GetFileAddress() - mapping_offset_value);
 
                             offset = local_symbols_info.entriesOffset;
                             for (uint32_t entry_index = 0; entry_index < local_symbols_info.entriesCount; entry_index++)





More information about the lldb-commits mailing list