Loading...
other-tools/dsc_extractor.cpp dyld-1340 dyld-960
--- dyld/dyld-1340/other-tools/dsc_extractor.cpp
+++ dyld/dyld-960/other-tools/dsc_extractor.cpp
@@ -22,10 +22,6 @@
  * @APPLE_LICENSE_HEADER_END@
  */
 
-#include <TargetConditionals.h>
-
-#if !TARGET_OS_EXCLAVEKIT
-
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -48,7 +44,6 @@
 
 #define NO_ULEB
 #include "Architectures.hpp"
-#include "Header.h"
 #include "MachOFileAbstraction.hpp"
 
 #include "dsc_iterator.h"
@@ -67,10 +62,6 @@
 #include <algorithm>
 #include <dispatch/dispatch.h>
 #include <optional>
-
-using mach_o::Header;
-
-asm(".linker_option \"-lCrashReporterClient\"");
 
 static int sharedCacheIsValid(const void* mapped_cache, uint64_t size) {
     // First check that the size is good.
@@ -198,15 +189,6 @@
     return 0;
 }
 
-static const char* leafName(std::string_view str)
-{
-    const char* start = strrchr(str.data(), '/');
-    if ( start != nullptr )
-        return &start[1];
-    else
-        return str.data();
-}
-
 // A MappedCache provides access to all the parts of a cache file, even those typically not mapped at runtime
 struct MappedCache {
     const DyldSharedCache*  dyldCache               = nullptr;
@@ -218,9 +200,7 @@
 static std::optional<MappedCache> mapCacheFile(const char* path,
                                                uint64_t baseCacheUnslidAddress,
                                                uint8_t* buffer,
-                                               bool isLocalSymbolsCache,
-                                               const uuid_t expectedUUID,
-                                               void (^crashReporterCallback)(const char* format, ...))
+                                               bool isLocalSymbolsCache)
 {
     struct stat statbuf;
     if ( ::stat(path, &statbuf) ) {
@@ -247,17 +227,6 @@
     if ( header->mappingCount == 0 ) {
         fprintf(stderr, "Error: No mapping in shared cache file at %s\n", path);
         return {};
-    }
-
-    if ( !uuid_is_null(expectedUUID) ) {
-        if ( memcmp(header->uuid, expectedUUID, 16) != 0 ) {
-            uuid_string_t expectedUUIDString;
-            uuid_unparse_upper(expectedUUID, expectedUUIDString);
-            uuid_string_t foundUUIDString;
-            uuid_unparse_upper(header->uuid, foundUUIDString);
-            fprintf(stderr, "Error: SubCache UUID mismatch.  Expected %s, got %s\n", expectedUUIDString, foundUUIDString);
-            return {};
-        }
     }
 
     // Use the cache code signature to see if the cache file is valid.
@@ -278,7 +247,6 @@
 
     // The local symbols cache just wants an mmap as we don't want to change offsets there
     if ( isLocalSymbolsCache ) {
-        crashReporterCallback("dyld: Mapping symbols file: %s\n", leafName(path));
         void* mapped_cache = ::mmap(nullptr, (size_t)statbuf.st_size, PROT_READ, MAP_PRIVATE, cache_fd, 0);
         if (mapped_cache == MAP_FAILED) {
             fprintf(stderr, "Error: mmap() for shared cache at %s failed, errno=%d\n", path, errno);
@@ -312,7 +280,6 @@
             fprintf(stderr, "Error: failed to allocate space to load shared cache file at %s\n", path);
             return {};
         }
-        crashReporterCallback("dyld: Allocated buffer (0x%llx..0x%llx): %s\n", (uint64_t)result, (uint64_t)result + vmSize, leafName(path));
         buffer = (uint8_t*)result;
     } else {
         subCacheBufferOffset = mappings[0].address - baseCacheUnslidAddress;
@@ -320,11 +287,7 @@
 
     for (uint32_t i=0; i < header->mappingCount; ++i) {
         uint64_t mappingAddressOffset = mappings[i].address - mappings[0].address;
-        uint64_t bufferStartAddr = (uint64_t)(buffer + mappingAddressOffset + subCacheBufferOffset);
-        crashReporterCallback("dyld: Mapping 0x%llx -> (0x%llx..0x%llx): %s\n",
-                              mappings[i].fileOffset, bufferStartAddr, bufferStartAddr + mappings[i].size, leafName(path));
-
-        void* mapped_cache = ::mmap((void*)bufferStartAddr, (size_t)mappings[i].size,
+        void* mapped_cache = ::mmap((void*)(buffer + mappingAddressOffset + subCacheBufferOffset), (size_t)mappings[i].size,
                                     PROT_READ, MAP_FIXED | MAP_PRIVATE, cache_fd, mappings[i].fileOffset);
         if (mapped_cache == MAP_FAILED) {
             fprintf(stderr, "Error: mmap() for shared cache at %s failed, errno=%d\n", path, errno);
@@ -361,23 +324,7 @@
 
 static CacheFiles mapCacheFiles(const char* path)
 {
-    __block std::string crashReporterMessage;
-    auto crashReporterCallback = ^(const char* format, ...)  __attribute__((format(printf, 1, 2))) {
-        char*   output_string;
-        va_list list;
-        va_start(list, format);
-        vasprintf(&output_string, format, list);
-        va_end(list);
-
-        crashReporterMessage += output_string;
-        free(output_string);
-
-        CRSetCrashLogMessage(crashReporterMessage.c_str());
-    };
-
-    crashReporterCallback("dyld: Starting dsc_extractor\n");
-
-    std::optional<MappedCache> mappedCache = mapCacheFile(path, 0, nullptr, false, UUID_NULL, crashReporterCallback);
+    std::optional<MappedCache> mappedCache = mapCacheFile(path, 0, nullptr, false);
     if ( !mappedCache.has_value() )
         return {};
 
@@ -385,33 +332,29 @@
     caches.push_back(mappedCache.value());
 
     const DyldSharedCache* cache = mappedCache.value().dyldCache;
-    std::string basePath = std::string(path);
-    if ( cache->header.cacheType == kDyldSharedCacheTypeUniversal )
-    {
-        std::size_t pos = basePath.find(DYLD_SHARED_CACHE_DEVELOPMENT_EXT);
-        if (pos != std::string::npos)
-            basePath = basePath.substr(0, basePath.size() - 12);
-    }
 
     // Load all subcaches, if we have them
-    if ( cache->header.mappingOffset >= offsetof(dyld_cache_header, subCacheArrayCount) ) {
+    if ( cache->header.mappingOffset >= __offsetof(dyld_cache_header, subCacheArrayCount) ) {
         if ( cache->header.subCacheArrayCount != 0 ) {
             const dyld_subcache_entry* subCacheEntries = (dyld_subcache_entry*)((uint8_t*)cache + cache->header.subCacheArrayOffset);
 
             for (uint32_t i = 0; i != cache->header.subCacheArrayCount; ++i) {
-                std::string subCachePath = std::string(path) + "." + json::unpaddedDecimal(i + 1);
-                if ( cache->header.mappingOffset > offsetof(dyld_cache_header, cacheSubType) ) {
-                    subCachePath = basePath + subCacheEntries[i].fileSuffix;
-                }
-
-                uint8_t uuid[16];
-                cache->getSubCacheUuid(i, uuid);
-
-                std::optional<MappedCache> mappedSubCache = mapCacheFile(subCachePath.c_str(), cache->unslidLoadAddress(), (uint8_t*)cache, false,
-                                                                         uuid, crashReporterCallback);
+                std::string subCachePath = std::string(path) + "." + dyld3::json::decimal(i + 1);
+                std::optional<MappedCache> mappedSubCache = mapCacheFile(subCachePath.c_str(), cache->unslidLoadAddress(), (uint8_t*)cache, false);
                 if ( !mappedSubCache.has_value() )
                     return {};
 
+                const DyldSharedCache* subCache = mappedSubCache.value().dyldCache;
+
+                if ( memcmp(subCache->header.uuid, subCacheEntries[i].uuid, 16) != 0 ) {
+                    uuid_string_t expectedUUIDString;
+                    uuid_unparse_upper(subCacheEntries[i].uuid, expectedUUIDString);
+                    uuid_string_t foundUUIDString;
+                    uuid_unparse_upper(subCache->header.uuid, foundUUIDString);
+                    fprintf(stderr, "Error: SubCache[%i] UUID mismatch.  Expected %s, got %s\n", i, expectedUUIDString, foundUUIDString);
+                    return {};
+                }
+
                 caches.push_back(mappedSubCache.value());
             }
         }
@@ -419,21 +362,27 @@
 
     // On old caches, the locals come from the same file we are extracting from
     std::string localSymbolsCachePath = path;
-    uuid_t localSymbolsUUID;
-    uuid_clear(localSymbolsUUID);
     if ( cache->hasLocalSymbolsInfoFile() ) {
         // On new caches, the locals come from a new subCache file
-        if ( endsWith(localSymbolsCachePath, DYLD_SHARED_CACHE_DEVELOPMENT_EXT) )
-            localSymbolsCachePath.resize(localSymbolsCachePath.size() - strlen(DYLD_SHARED_CACHE_DEVELOPMENT_EXT));
+        if ( endsWith(localSymbolsCachePath, ".development") )
+            localSymbolsCachePath.resize(localSymbolsCachePath.size() - strlen(".development"));
         localSymbolsCachePath += ".symbols";
-
-        uuid_copy(localSymbolsUUID, cache->header.symbolFileUUID);
-    }
-
-    std::optional<MappedCache> localSymbolsMappedCache = mapCacheFile(localSymbolsCachePath.c_str(), 0, nullptr, true,
-                                                                      localSymbolsUUID, crashReporterCallback);
-
-    CRSetCrashLogMessage("");
+    }
+
+    std::optional<MappedCache> localSymbolsMappedCache = mapCacheFile(localSymbolsCachePath.c_str(), 0, nullptr, true);
+    if ( localSymbolsMappedCache.has_value() && cache->hasLocalSymbolsInfoFile() ) {
+        // Validate the UUID of the symbols file
+        const DyldSharedCache* subCache = localSymbolsMappedCache.value().dyldCache;
+
+        if ( memcmp(subCache->header.uuid, cache->header.symbolFileUUID, 16) != 0 ) {
+            uuid_string_t expectedUUIDString;
+            uuid_unparse_upper(cache->header.symbolFileUUID, expectedUUIDString);
+            uuid_string_t foundUUIDString;
+            uuid_unparse_upper(subCache->header.uuid, foundUUIDString);
+            fprintf(stderr, "Error: Symbols subCache UUID mismatch.  Expected %s, got %s\n", expectedUUIDString, foundUUIDString);
+            return {};
+        }
+    }
 
     CacheFiles cacheFiles;
     cacheFiles.caches = std::move(caches);
@@ -445,11 +394,11 @@
 
 struct seg_info
 {
-    seg_info(std::string_view n, uint64_t o, uint64_t s)
+    seg_info(const char* n, uint64_t o, uint64_t s)
     : segName(n), offset(o), sizem(s) { }
-    std::string_view    segName;
-    uint64_t            offset;
-    uint64_t            sizem;
+    const char* segName;
+    uint64_t    offset;
+    uint64_t    sizem;
 };
 
 class CStringHash {
@@ -776,19 +725,16 @@
         const size_t newIndSymTabOffset = new_linkedit_data.size();
 
         // Copy (and adjust) indirect symbol table
-        if ( dynamicSymTab->nindirectsyms != 0 ) {
-            const uint32_t* mergedIndSymTab = (uint32_t*)(linkeditBaseAddress + dynamicSymTab->indirectsymoff);
-            new_linkedit_data.insert(new_linkedit_data.end(),
-                                     (char*)mergedIndSymTab,
-                                     (char*)(mergedIndSymTab + dynamicSymTab->nindirectsyms));
-            if ( undefSymbolShift != 0 ) {
-                uint32_t* newIndSymTab = (uint32_t*)&new_linkedit_data[newIndSymTabOffset];
-                for (uint32_t i=0; i < dynamicSymTab->nindirectsyms; ++i) {
-                    newIndSymTab[i] += undefSymbolShift;
-                }
+        const uint32_t* mergedIndSymTab = (uint32_t*)(linkeditBaseAddress + dynamicSymTab->indirectsymoff);
+        new_linkedit_data.insert(new_linkedit_data.end(),
+                                 (char*)mergedIndSymTab,
+                                 (char*)(mergedIndSymTab + dynamicSymTab->nindirectsyms));
+        if ( undefSymbolShift != 0 ) {
+            uint32_t* newIndSymTab = (uint32_t*)&new_linkedit_data[newIndSymTabOffset];
+            for (uint32_t i=0; i < dynamicSymTab->nindirectsyms; ++i) {
+                newIndSymTab[i] += undefSymbolShift;
             }
         }
-
         const uint64_t newStringPoolOffset = new_linkedit_data.size();
 
         // pointer align string pool size
@@ -855,7 +801,7 @@
 
     size_t  additionalSize  = 0;
     for(std::vector<seg_info>::const_iterator it=segments.begin(); it != segments.end(); ++it) {
-        if ( it->segName != "__LINKEDIT" )
+        if ( strcmp(it->segName, "__LINKEDIT") != 0 )
             additionalSize += it->sizem;
     }
 
@@ -866,13 +812,13 @@
     uint64_t                textOffsetInCache    = 0;
     for( std::vector<seg_info>::const_iterator it=segments.begin(); it != segments.end(); ++it) {
 
-        if( it->segName == "__TEXT" )
+        if(strcmp(it->segName, "__TEXT") == 0 )
             textOffsetInCache = it->offset;
 
         //printf("segName=%s, offset=0x%llX, size=0x%0llX\n", it->segName, it->offset, it->sizem);
         // Copy all but the __LINKEDIT.  It will be copied later during the optimizer in to a temporary buffer but it would
         // not be efficient to copy it all now for each dylib.
-        if ( it->segName == "__LINKEDIT" )
+        if (strcmp(it->segName, "__LINKEDIT") == 0 )
             continue;
         std::copy(((uint8_t*)mapped_cache)+it->offset, ((uint8_t*)mapped_cache)+it->offset+it->sizem, std::back_inserter(new_dylib_data));
     }
@@ -1048,9 +994,9 @@
         return result;
     }
 
-    mapped_cache->forEachImage(^(const Header *hdr, const char *installName) {
-        hdr->forEachSegment(^(const Header::SegmentInfo &info, bool &stop) {
-            map[installName].push_back(seg_info(info.segmentName, info.vmaddr - mapped_cache->unslidLoadAddress(), info.vmsize));
+    mapped_cache->forEachImage(^(const mach_header *mh, const char *installName) {
+        ((const dyld3::MachOAnalyzer*)mh)->forEachSegment(^(const dyld3::MachOAnalyzer::SegmentInfo &info, bool &stop) {
+            map[installName].push_back(seg_info(info.segName, info.vmAddr - mapped_cache->unslidLoadAddress(), info.vmSize));
         });
     });
 
@@ -1119,6 +1065,6 @@
 
 #endif
 
-#endif // !TARGET_OS_EXCLAVEKIT
-
-
+
+
+