Loading...
--- dyld/dyld-750.6/dyld3/ClosureFileSystemPhysical.cpp
+++ dyld/dyld-852.2/dyld3/ClosureFileSystemPhysical.cpp
@@ -23,13 +23,12 @@
#include "ClosureFileSystemPhysical.h"
+#include <TargetConditionals.h>
+
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
-#if BUILDING_UPDATE_DYLD_CACHE_BUILDER
- #include <rootless.h>
-#endif
#include <sys/errno.h>
#include <sys/mman.h>
#include <sys/stat.h>
@@ -38,6 +37,9 @@
#include <sandbox.h>
#include <sandbox/private.h>
#endif
+#include <TargetConditionals.h>
+#include "MachOFile.h"
+#include "MachOAnalyzer.h"
using dyld3::closure::FileSystemPhysical;
@@ -45,7 +47,7 @@
__block bool success = false;
// first pass: open file and ask kernel for canonical path
forEachPath(possiblePath, ^(const char* aPath, unsigned prefixLen, bool& stop) {
- int fd = ::open(aPath, O_RDONLY, 0);
+ int fd = dyld3::open(aPath, O_RDONLY, 0);
if ( fd != -1 ) {
char tempPath[MAXPATHLEN];
success = (fcntl(fd, F_GETPATH, tempPath) == 0);
@@ -110,6 +112,8 @@
}
if ( _rootPath != nullptr ) {
strlcpy(altPath, _rootPath, PATH_MAX);
+ if ( path[0] != '/' )
+ strlcat(altPath, "/", PATH_MAX);
strlcat(altPath, path, PATH_MAX);
handler(altPath, (unsigned)strlen(_rootPath), stop);
if ( stop )
@@ -144,9 +148,8 @@
// open file
__block int fd;
__block struct stat statBuf;
- __block bool sipProtected = false;
forEachPath(path, ^(const char* aPath, unsigned prefixLen, bool& stop) {
- fd = ::open(aPath, O_RDONLY, 0);
+ fd = dyld3::open(aPath, O_RDONLY, 0);
if ( fd == -1 ) {
int openErrno = errno;
if ( (openErrno == EPERM) && sandboxBlockedOpen(path) )
@@ -183,9 +186,6 @@
}
else
strcpy(realerPath, realPathWithin);
- #if BUILDING_UPDATE_DYLD_CACHE_BUILDER
- sipProtected = (rootless_check_trusted_fd(fd) == 0);
- #endif
stop = true;
}
else {
@@ -217,7 +217,7 @@
info.fileContentLen = statBuf.st_size;
info.sliceOffset = 0;
info.sliceLen = statBuf.st_size;
- info.isSipProtected = sipProtected;
+ info.isOSBinary = false;
info.inode = statBuf.st_ino;
info.mtime = statBuf.st_mtime;
info.path = path;
@@ -240,6 +240,27 @@
}
info.fileContent = wholeFile;
+ // if this is an arm64e mach-o or a fat file with an arm64e slice we need to record if it is an OS binary
+#if TARGET_OS_OSX && __arm64e__
+ const MachOAnalyzer* ma = (MachOAnalyzer*)wholeFile;
+ if ( ma->hasMachOMagic() ) {
+ if ( (ma->cputype == CPU_TYPE_ARM64) && ((ma->cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM64E) ) {
+ if ( ma->isOSBinary(fd, 0, info.fileContentLen) )
+ info.isOSBinary = true;
+ }
+ }
+ else if ( const FatFile* fat = FatFile::isFatFile(wholeFile) ) {
+ Diagnostics diag;
+ fat->forEachSlice(diag, info.fileContentLen, ^(uint32_t sliceCpuType, uint32_t sliceCpuSubType, const void* sliceStart, uint64_t sliceSize, bool& stop) {
+ if ( (sliceCpuType == CPU_TYPE_ARM64) && ((sliceCpuSubType & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM64E) ) {
+ uint64_t sliceOffset = (uint8_t*)sliceStart-(uint8_t*)wholeFile;
+ const MachOAnalyzer* sliceMA = (MachOAnalyzer*)((uint8_t*)wholeFile + sliceOffset);
+ if ( sliceMA->isOSBinary(fd, sliceOffset, sliceSize) )
+ info.isOSBinary = true;
+ }
+ });
+ }
+#endif
// Set unmap as the unload method.
info.unload = [](const LoadedFileInfo& info) {
::munmap((void*)info.fileContent, (size_t)info.fileContentLen);
@@ -257,11 +278,11 @@
void FileSystemPhysical::unloadPartialFile(LoadedFileInfo& info, uint64_t keepStartOffset, uint64_t keepLength) const {
// Unmap from 0..keepStartOffset and (keepStartOffset+keepLength)..info.fileContentLen
if (keepStartOffset)
- ::munmap((void*)info.fileContent, (size_t)keepStartOffset);
+ ::munmap((void*)info.fileContent, (size_t)trunc_page(keepStartOffset));
if ((keepStartOffset + keepLength) != info.fileContentLen) {
- // Round up to page alignment
- keepLength = (keepLength + PAGE_SIZE - 1) & (-PAGE_SIZE);
- ::munmap((void*)((char*)info.fileContent + keepStartOffset + keepLength), (size_t)(info.fileContentLen - (keepStartOffset + keepLength)));
+ uintptr_t start = round_page((uintptr_t)info.fileContent + keepStartOffset + keepLength);
+ uintptr_t end = (uintptr_t)info.fileContent + info.fileContentLen;
+ ::munmap((void*)start, end - start);
}
info.fileContent = (const void*)((char*)info.fileContent + keepStartOffset);
info.fileContentLen = keepLength;
@@ -272,7 +293,7 @@
__block bool result = false;
forEachPath(path, ^(const char* aPath, unsigned prefixLen, bool& stop) {
struct stat statBuf;
- if ( ::stat(aPath, &statBuf) == 0 ) {
+ if ( dyld3::stat(aPath, &statBuf) == 0 ) {
if (inode)
*inode = statBuf.st_ino;
if (mtime)