#include <TargetConditionals.h>
#include "ClosureFileSystemPhysical.h"
#include "DyldSharedCache.h"
#include "MachOAnalyzer.h"
#include "RootsChecker.h"
#if DYLD_SIMULATOR_ROOTS_SUPPORT
#include "SharedCacheRuntime.h"
#endif
namespace dyld3 {
#if DYLD_SIMULATOR_ROOTS_SUPPORT
static bool imageUUIDMatchesSharedCache(const char* path, const closure::FileSystem* fileSystem,
const DyldSharedCache* cache, const closure::Image* image) {
bool uuidMatchesCache = false;
closure::FileSystemPhysical fileSystemPhysical;
if ( fileSystem == nullptr )
fileSystem = &fileSystemPhysical;
Diagnostics diag;
Platform platform = cache->platform();
const GradedArchs& archs = GradedArchs::forName(cache->archName(), true);
char realerPath[MAXPATHLEN];
dyld3::closure::LoadedFileInfo loadedFileInfo = dyld3::MachOAnalyzer::load(diag, *fileSystem, path, archs, platform, realerPath);
const dyld3::MachOAnalyzer* ma = (const dyld3::MachOAnalyzer*)loadedFileInfo.fileContent;
if ( ma != nullptr ) {
uuid_t uuid;
uuid_t image_uuid;
if ( !ma->getUuid(uuid) )
memset(&uuid, 0, sizeof(uuid_t));
if ( !image->getUuid(image_uuid) )
memset(&image_uuid, 0, sizeof(uuid_t));
uuidMatchesCache = ( memcmp(uuid, image_uuid, sizeof(uuid_t)) == 0 );
fileSystem->unloadFile(loadedFileInfo);
}
return uuidMatchesCache;
}
bool RootsChecker::uuidMatchesSharedCache(const char* path, const closure::FileSystem* fileSystem,
const DyldSharedCache* cache) {
const dyld3::closure::ImageArray* images = cache->cachedDylibsImageArray();
const closure::Image* image = nullptr;
uint32_t imageIndex;
if ( cache->hasImagePath(path, imageIndex) ) {
image = images->imageForNum(imageIndex+1);
}
return imageUUIDMatchesSharedCache(path, fileSystem, cache, image);
}
#endif
bool RootsChecker::onDiskFileIsRoot(const char* path, const DyldSharedCache* cache,
const closure::Image* image,
const closure::FileSystem* fileSystem,
uint64_t inode, uint64_t modtime) const {
uint64_t expectedINode;
uint64_t expectedMtime;
if ( image->hasFileModTimeAndInode(expectedINode, expectedMtime) ) {
if ( (expectedMtime == modtime) && (expectedINode == inode) )
return false;
return true;
}
#if DYLD_SIMULATOR_ROOTS_SUPPORT
if ( strcmp(path, "/usr/lib/system/libsystem_kernel.dylib") == 0 ) {
if ( libsystemKernelIsRoot )
return true;
if ( !fileSystemCanBeModified )
return false;
return !imageUUIDMatchesSharedCache(path, fileSystem, cache, image);
} else if ( strcmp(path, "/usr/lib/system/libsystem_platform.dylib") == 0 ) {
if ( libsystemPlatformIsRoot )
return true;
if ( !fileSystemCanBeModified )
return false;
return !imageUUIDMatchesSharedCache(path, fileSystem, cache, image);
} else if ( strcmp(path, "/usr/lib/system/libsystem_pthread.dylib") == 0 ) {
if ( libsystemPThreadIsRoot )
return true;
if ( !fileSystemCanBeModified )
return false;
return !imageUUIDMatchesSharedCache(path, fileSystem, cache, image);
}
#endif
return true;
}
}