Loading...
--- dyld/dyld-1286.10/cache-builder/dyld_app_cache_util.cpp
+++ dyld/dyld-940/cache-builder/dyld_app_cache_util.cpp
@@ -32,30 +32,26 @@
#include <variant>
#include <CoreFoundation/CFBundle.h>
-#include <CoreFoundation/CFNumber.h>
#include <CoreFoundation/CFPropertyList.h>
#include <CoreFoundation/CFStream.h>
#include "kernel_collection_builder.h"
#include "ClosureFileSystemPhysical.h"
#include "FileUtils.h"
-#include "Header.h"
#include "JSONWriter.h"
#include "MachOAppCache.h"
-using namespace json;
+using namespace dyld3::json;
using dyld3::closure::FileSystemPhysical;
using dyld3::closure::LoadedFileInfo;
using dyld3::GradedArchs;
using dyld3::MachOAnalyzer;
using dyld3::MachOAppCache;
-using json::Node;
-
-using mach_o::Header;
-using mach_o::Platform;
-
-__attribute__((__noreturn__))
+using dyld3::Platform;
+using dyld3::json::Node;
+
+__attribute__((noreturn))
static void exit_usage(const char* missingOption = nullptr) {
if ( missingOption != nullptr ) {
fprintf(stderr, "Missing option '%s'\n", missingOption);
@@ -70,7 +66,6 @@
fprintf(stderr, " -kmod print the kmod_info of an existing app cache\n");
fprintf(stderr, " -uuid print the UUID of an existing app cache\n");
fprintf(stderr, " -fips print the FIPS section of an existing app cache\n");
- fprintf(stderr, " -function-starts print the function starts of an app cache\n");
fprintf(stderr, "\n");
fprintf(stderr, "Usage: dyld_app_cache_util -validate file-path -arch arch -platform platform\n");
@@ -117,10 +112,8 @@
bool printFixups = false;
bool printSymbols = false;
bool printUUID = false;
- bool printPrelinkInfo = false;
bool printKModInfo = false;
bool printFIPS = false;
- bool printFunctionStarts = false;
};
struct ValidateOptions {
@@ -221,20 +214,12 @@
exitOrGetState<DumpOptions>(options, arg).printUUID = true;
continue;
}
- if (strcmp(arg, "-prelink-info") == 0) {
- exitOrGetState<DumpOptions>(options, arg).printPrelinkInfo = true;
- continue;
- }
if (strcmp(arg, "-kmod") == 0) {
exitOrGetState<DumpOptions>(options, arg).printKModInfo = true;
continue;
}
if (strcmp(arg, "-fips") == 0) {
exitOrGetState<DumpOptions>(options, arg).printFIPS = true;
- continue;
- }
- if (strcmp(arg, "-function-starts") == 0) {
- exitOrGetState<DumpOptions>(options, arg).printFunctionStarts = true;
continue;
}
@@ -286,7 +271,7 @@
exitOrGetState<CreateKernelCollectionOptions>(options, arg).volumeRoot = argv[++i];
continue;
}
- if ( (strcmp(arg, "-bundle-id") == 0) || (strcmp(arg, "-b") == 0) ) {
+ if (strcmp(arg, "-bundle-id") == 0) {
exitOrGetState<CreateKernelCollectionOptions>(options, arg).bundleIDs.push_back(argv[++i]);
continue;
}
@@ -328,6 +313,32 @@
return true;
}
+static Platform stringToPlatform(const std::string& str) {
+ if (str == "unknown")
+ return Platform::unknown;
+ if (str == "macOS")
+ return Platform::macOS;
+ if (str == "iOS")
+ return Platform::iOS;
+ if (str == "tvOS")
+ return Platform::tvOS;
+ if (str == "watchOS")
+ return Platform::watchOS;
+ if (str == "bridgeOS")
+ return Platform::bridgeOS;
+ if (str == "iOSMac")
+ return Platform::iOSMac;
+ if (str == "UIKitForMac")
+ return Platform::iOSMac;
+ if (str == "iOS_simulator")
+ return Platform::iOS_simulator;
+ if (str == "tvOS_simulator")
+ return Platform::tvOS_simulator;
+ if (str == "watchOS_simulator")
+ return Platform::watchOS_simulator;
+ return Platform::unknown;
+}
+
static int dumpAppCache(const DumpOptions& options) {
// Verify any required options
if (gOpts.archs.size() != 1)
@@ -345,12 +356,15 @@
}
const GradedArchs& archs = GradedArchs::forName(gOpts.archs[0]);
- Platform platform = Platform();
+ Platform platform = Platform::unknown;
+ bool isKernelCollection = false;
// HACK: Pass a real option for building a kernel app cache
- if (strcmp(gOpts.platform, "kernel") != 0) {
- platform = Platform::byName(gOpts.platform);
- if ( platform.empty() ) {
+ if (!strcmp(gOpts.platform, "kernel")) {
+ isKernelCollection = true;
+ } else {
+ platform = stringToPlatform(gOpts.platform);
+ if (platform == Platform::unknown) {
fprintf(stderr, "Could not create app cache because: unknown platform '%s'\n", gOpts.platform);
return 1;
}
@@ -376,13 +390,13 @@
// Add the segments for the app cache
__block Node appCacheSegmentsNode;
__block bool hasError = false;
- ((const Header*)appCacheMA)->forEachSegment(^(const Header::SegmentInfo &info, bool &stopSegment) {
+ appCacheMA->forEachSegment(^(const dyld3::MachOFile::SegmentInfo &info, bool &stopSegment) {
Node segmentNode;
- segmentNode.map["name"] = makeNode(info.segmentName.data());
- segmentNode.map["vmAddr"] = makeNode(hex(info.vmaddr));
- segmentNode.map["vmSize"] = makeNode(hex(info.vmsize));
- segmentNode.map["vmEnd"] = makeNode(hex(info.vmaddr + info.vmsize));
- switch (info.initProt) {
+ segmentNode.map["name"] = makeNode(info.segName);
+ segmentNode.map["vmAddr"] = makeNode(hex(info.vmAddr));
+ segmentNode.map["vmSize"] = makeNode(hex(info.vmSize));
+ segmentNode.map["vmEnd"] = makeNode(hex(info.vmAddr + info.vmSize));
+ switch (info.protections) {
case VM_PROT_READ:
segmentNode.map["permissions"] = makeNode("r--");
break;
@@ -402,21 +416,21 @@
segmentNode.map["permissions"] = makeNode("rwx");
break;
default:
- fprintf(stderr, "Unknown permissions on segment '%.*s'\n", (int)info.segmentName.size(), info.segmentName.data());
+ fprintf(stderr, "Unknown permissions on segment '%s'\n", info.segName);
hasError = true;
stopSegment = true;
}
__block Node sectionsNode;
- ((const Header*)appCacheMA)->forEachSection(^(const Header::SectionInfo §Info, bool &stopSection) {
- if ( sectInfo.segmentName != info.segmentName )
+ appCacheMA->forEachSection(^(const dyld3::MachOAnalyzer::SectionInfo §Info, bool malformedSectionRange, bool &stopSection) {
+ if ( strncmp(sectInfo.segInfo.segName, info.segName, 16) != 0 )
return;
Node sectionNode;
- sectionNode.map["name"] = makeNode(std::string(sectInfo.sectionName));
- sectionNode.map["vmAddr"] = makeNode(hex(sectInfo.address));
- sectionNode.map["vmSize"] = makeNode(hex(sectInfo.size));
- sectionNode.map["vmEnd"] = makeNode(hex(sectInfo.address + sectInfo.size));
+ sectionNode.map["name"] = makeNode(sectInfo.sectName);
+ sectionNode.map["vmAddr"] = makeNode(hex(sectInfo.sectAddr));
+ sectionNode.map["vmSize"] = makeNode(hex(sectInfo.sectSize));
+ sectionNode.map["vmEnd"] = makeNode(hex(sectInfo.sectAddr + sectInfo.sectSize));
sectionsNode.array.push_back(sectionNode);
});
@@ -444,14 +458,14 @@
__block Node dylibsNode;
appCacheMA->forEachDylib(diag, ^(const MachOAnalyzer *ma, const char *name, bool &stop) {
__block Node segmentsNode;
- ((const Header*)ma)->forEachSegment(^(const Header::SegmentInfo &info, bool &stopSegment) {
+ ma->forEachSegment(^(const dyld3::MachOFile::SegmentInfo &info, bool &stopSegment) {
Node segmentNode;
- segmentNode.map["name"] = makeNode(info.segmentName.data());
- segmentNode.map["vmAddr"] = makeNode(hex(info.vmaddr));
- segmentNode.map["vmSize"] = makeNode(hex(info.vmsize));
- segmentNode.map["vmEnd"] = makeNode(hex(info.vmaddr + info.vmsize));
-
- switch (info.initProt) {
+ segmentNode.map["name"] = makeNode(info.segName);
+ segmentNode.map["vmAddr"] = makeNode(hex(info.vmAddr));
+ segmentNode.map["vmSize"] = makeNode(hex(info.vmSize));
+ segmentNode.map["vmEnd"] = makeNode(hex(info.vmAddr + info.vmSize));
+
+ switch (info.protections) {
case VM_PROT_READ:
segmentNode.map["permissions"] = makeNode("r--");
break;
@@ -468,21 +482,21 @@
segmentNode.map["permissions"] = makeNode("r-x");
break;
default:
- fprintf(stderr, "Unknown permissions on segment '%.*s'\n", (int)info.segmentName.size(), info.segmentName.data());
+ fprintf(stderr, "Unknown permissions on segment '%s'\n", info.segName);
hasError = true;
stop = true;
}
__block Node sectionsNode;
- ((const Header*)ma)->forEachSection(^(const Header::SectionInfo §Info, bool &stopSection) {
- if ( sectInfo.segmentName != info.segmentName )
+ ma->forEachSection(^(const dyld3::MachOAnalyzer::SectionInfo §Info, bool malformedSectionRange, bool &stopSection) {
+ if ( strncmp(sectInfo.segInfo.segName, info.segName, 16) != 0 )
return;
Node sectionNode;
- sectionNode.map["name"] = makeNode(std::string(sectInfo.sectionName));
- sectionNode.map["vmAddr"] = makeNode(hex(sectInfo.address));
- sectionNode.map["vmSize"] = makeNode(hex(sectInfo.size));
- sectionNode.map["vmEnd"] = makeNode(hex(sectInfo.address + sectInfo.size));
+ sectionNode.map["name"] = makeNode(sectInfo.sectName);
+ sectionNode.map["vmAddr"] = makeNode(hex(sectInfo.sectAddr));
+ sectionNode.map["vmSize"] = makeNode(hex(sectInfo.sectSize));
+ sectionNode.map["vmEnd"] = makeNode(hex(sectInfo.sectAddr + sectInfo.sectSize));
sectionsNode.array.push_back(sectionNode);
});
@@ -517,8 +531,8 @@
uint64_t entryOffset;
bool usesCRT;
Node entryPointNode;
- if ( ((const Header*)appCacheMA)->getEntry(entryOffset, usesCRT) ) {
- entryPointNode.value = hex(((const Header*)appCacheMA)->preferredLoadAddress() + entryOffset);
+ if ( appCacheMA->getEntry(entryOffset, usesCRT) ) {
+ entryPointNode.value = hex(appCacheMA->preferredLoadAddress() + entryOffset);
}
topNode.map["entrypoint"] = entryPointNode;
@@ -530,11 +544,11 @@
__block Node topNode;
__block uint64_t baseAddress = ~0ULL;
- ((const Header*)appCacheMA)->forEachSegment(^(const Header::SegmentInfo& info, bool& stop) {
- baseAddress = std::min(baseAddress, info.vmaddr);
+ appCacheMA->forEachSegment(^(const dyld3::MachOAnalyzer::SegmentInfo& info, bool& stop) {
+ baseAddress = std::min(baseAddress, info.vmAddr);
});
uint64_t cacheBaseAddress = baseAddress;
- uint64_t textSegVMAddr = ((const Header*)appCacheMA)->preferredLoadAddress();
+ uint64_t textSegVMAddr = appCacheMA->preferredLoadAddress();
auto getFixupsNode = [cacheBaseAddress, textSegVMAddr](const dyld3::MachOAnalyzer* ma) {
__block Node fixupsNode;
@@ -563,7 +577,7 @@
case DYLD_CHAINED_PTR_X86_64_KERNEL_CACHE: {
uint64_t targetVMOffset = fixupLoc->kernel64.target;
uint64_t targetVMAddr = targetVMOffset + cacheBaseAddress;
- std::string level = "kc(" + unpaddedDecimal(fixupLoc->kernel64.cacheLevel) + ")";
+ std::string level = "kc(" + decimal(fixupLoc->kernel64.cacheLevel) + ")";
std::string fixup = level + " + " + hex(targetVMAddr);
if (fixupLoc->kernel64.isAuth) {
fixup += " auth(";
@@ -571,7 +585,7 @@
fixup += " ";
fixup += fixupLoc->kernel64.addrDiv ? "addr" : "!addr";
fixup += " ";
- fixup += unpaddedDecimal(fixupLoc->kernel64.diversity);
+ fixup += decimal(fixupLoc->kernel64.diversity);
fixup += ")";
}
fixupsNode.map[hex(vmOffset)] = makeNode(fixup);
@@ -586,10 +600,10 @@
diag.assertNoError();
ma->forEachRebase(diag, ^(const char *opcodeName, const dyld3::MachOAnalyzer::LinkEditInfo &leInfo,
- const Header::SegmentInfo *segments,
+ const dyld3::MachOAnalyzer::SegmentInfo *segments,
bool segIndexSet, uint32_t pointerSize, uint8_t segmentIndex,
uint64_t segmentOffset, dyld3::MachOAnalyzer::Rebase kind, bool &stop) {
- uint64_t rebaseVmAddr = segments[segmentIndex].vmaddr + segmentOffset;
+ uint64_t rebaseVmAddr = segments[segmentIndex].vmAddr + segmentOffset;
uint64_t runtimeOffset = rebaseVmAddr - textSegVMAddr;
const uint8_t* fixupLoc = (const uint8_t*)ma + runtimeOffset;
@@ -689,7 +703,7 @@
// add uuid
Node appUUIDNode;
uuid_t appUUID = {};
- if ( ((Header*)appCacheMA)->getUuid(appUUID) ) {
+ if ( appCacheMA->getUuid(appUUID) ) {
uuid_string_t uuidString;
uuid_unparse_upper(appUUID, uuidString);
appUUIDNode.value = uuidString;
@@ -743,56 +757,6 @@
printJSON(topNode, 0, std::cout);
}
- if (options.printPrelinkInfo) {
- __block Node topNode;
-
- const uint8_t* prelinkInfoBuffer = nullptr;
- uint64_t prelinkInfoBufferSize = 0;
- prelinkInfoBuffer = (const uint8_t*)appCacheMA->findSectionContent("__PRELINK_INFO", "__info", prelinkInfoBufferSize);
- if ( prelinkInfoBuffer != nullptr ) {
- CFReadStreamRef readStreamRef = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, prelinkInfoBuffer, prelinkInfoBufferSize, kCFAllocatorNull);
- if ( !CFReadStreamOpen(readStreamRef) ) {
- fprintf(stderr, "Could not open plist stream\n");
- exit(1);
- }
- CFErrorRef errorRef = nullptr;
- CFPropertyListRef plistRef = CFPropertyListCreateWithStream(kCFAllocatorDefault, readStreamRef, prelinkInfoBufferSize, kCFPropertyListImmutable, nullptr, &errorRef);
- if ( errorRef != nullptr ) {
- CFStringRef stringRef = CFErrorCopyFailureReason(errorRef);
- fprintf(stderr, "Could not read plist because: %s\n", CFStringGetCStringPtr(stringRef, kCFStringEncodingASCII));
- CFRelease(stringRef);
- exit(1);
- }
- assert(CFGetTypeID(plistRef) == CFDictionaryGetTypeID());
- CFArrayRef kextPrelinkInfosRef = (CFArrayRef)CFDictionaryGetValue((CFDictionaryRef)plistRef, CFSTR("_PrelinkInfoDictionary"));
- if ( kextPrelinkInfosRef != nullptr ) {
- assert(CFGetTypeID(kextPrelinkInfosRef) == CFArrayGetTypeID());
-
- CFIndex count = CFArrayGetCount(kextPrelinkInfosRef);
- for ( CFIndex index = 0; index != count; ++index ) {
- CFDictionaryRef kextInfoRef = (CFDictionaryRef)CFArrayGetValueAtIndex(kextPrelinkInfosRef, index);
- assert(CFGetTypeID(kextInfoRef) == CFDictionaryGetTypeID());
-
- CFStringRef bundleIDRef = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)kextInfoRef, CFSTR("CFBundleIdentifier"));
- CFNumberRef executableSizeRef = (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)kextInfoRef, CFSTR("_PrelinkExecutableSize"));
-
- const char* bundleName = CFStringGetCStringPtr(bundleIDRef, kCFStringEncodingASCII);
- uint64_t execSize = 0;
- CFNumberGetValue(executableSizeRef, CFNumberGetType(executableSizeRef), &execSize);
-
- Node kextNode;
- kextNode.map["bundle-id"] = json::makeNode(bundleName);
- kextNode.map["executable-size"] = json::hex(execSize);
- topNode.array.push_back(std::move(kextNode));
- }
- }
- CFRelease(plistRef);
- CFRelease(readStreamRef);
- }
-
- printJSON(topNode, 0, std::cout);
- }
-
if (options.printKModInfo) {
__block Node topNode;
@@ -815,7 +779,7 @@
ma->forEachLocalSymbol(diag, ^(const char* aSymbolName, uint64_t n_value, uint8_t n_type,
uint8_t n_sect, uint16_t n_desc, bool& stopSymbols) {
if ( strcmp(aSymbolName, "_kmod_info") == 0 ) {
- kmodInfoVMOffset = n_value - ((const Header*)ma)->preferredLoadAddress();
+ kmodInfoVMOffset = n_value - ma->preferredLoadAddress();
found = true;
stopSymbols = true;
}
@@ -825,7 +789,7 @@
if ( found ) {
dyld3::MachOAppCache::KModInfo64_v1* kmodInfo = (dyld3::MachOAppCache::KModInfo64_v1*)((uint8_t*)ma + kmodInfoVMOffset);
Node kmodInfoNode;
- kmodInfoNode.map["info-version"] = makeNode(unpaddedDecimal(kmodInfo->info_version));
+ kmodInfoNode.map["info-version"] = makeNode(decimal(kmodInfo->info_version));
kmodInfoNode.map["name"] = makeNode((const char*)&kmodInfo->name[0]);
kmodInfoNode.map["version"] = makeNode((const char*)&kmodInfo->version[0]);
kmodInfoNode.map["address"] = makeNode(hex(kmodInfo->address));
@@ -880,37 +844,6 @@
printJSON(topNode, 0, std::cout);
}
- if (options.printFunctionStarts) {
- __block Node topNode;
-
- auto getStartsNode = [](const dyld3::MachOAnalyzer* ma) {
- __block Node functionStartsNode;
-
- uint64_t loadAddress = ((const Header*)ma)->preferredLoadAddress();
- ma->forEachFunctionStart(^(uint64_t runtimeOffset) {
- Node functionStart = makeNode(hex(loadAddress + runtimeOffset));
- functionStartsNode.array.push_back(functionStart);
- });
-
- return functionStartsNode;
- };
-
- topNode.map["function-starts"] = getStartsNode(appCacheMA);
-
- __block Node dylibsNode;
- appCacheMA->forEachDylib(diag, ^(const MachOAnalyzer *ma, const char *name, bool &stop) {
- Node dylibNode;
- dylibNode.map["name"] = makeNode(name);
- dylibNode.map["function-starts"] = getStartsNode(ma);
-
- dylibsNode.array.push_back(dylibNode);
- });
-
- topNode.map["dylibs"] = dylibsNode;
-
- printJSON(topNode, 0, std::cout);
- }
-
return 0;
}
@@ -924,7 +857,7 @@
exit_usage();
const GradedArchs& archs = GradedArchs::forName(gOpts.archs[0]);
- Platform platform = Platform();
+ Platform platform = Platform::unknown;
// HACK: Pass a real option for building a kernel app cache
if (strcmp(gOpts.platform, "kernel")) {
@@ -1014,7 +947,7 @@
createKernelCollectionForArch(const CreateKernelCollectionOptions& options, const char* arch,
Diagnostics& diag) {
const GradedArchs& archs = GradedArchs::forName(arch);
- Platform platform = Platform();
+ Platform platform = Platform::unknown;
KernelCollectionBuilder* kcb = nullptr;
@@ -1034,14 +967,12 @@
}
LoadedFileInfo info;
char realerPath[MAXPATHLEN];
- void (^fileErrorLog)(const char *format, ...) __printflike(1, 2)
- = ^(const char *format, ...) __printflike(1, 2) {
+ bool loadedFile = fileSystem.loadFile(kernelCollectionPath, info, realerPath, ^(const char *format, ...) {
va_list list;
va_start(list, format);
- diag.error(format, va_list_wrap(list));
+ diag.error(format, list);
va_end(list);
- };
- bool loadedFile = fileSystem.loadFile(kernelCollectionPath, info, realerPath, fileErrorLog);
+ });
if ( !loadedFile )
return false;
CFStringRef pathStringRef = CFStringCreateWithCString(kCFAllocatorDefault, kernelCollectionPath, kCFStringEncodingASCII);
@@ -1066,14 +997,12 @@
}
LoadedFileInfo info;
char realerPath[MAXPATHLEN];
- void (^fileErrorLog)(const char *format, ...) __printflike(1, 2)
- = ^(const char *format, ...) __printflike(1, 2) {
+ bool loadedFile = fileSystem.loadFile(options.kernelPath, info, realerPath, ^(const char *format, ...) {
va_list list;
va_start(list, format);
- diag.error(format, va_list_wrap(list));
+ diag.error(format, list);
va_end(list);
- };
- bool loadedFile = fileSystem.loadFile(options.kernelPath, info, realerPath, fileErrorLog);
+ });
if ( !loadedFile )
return {};
CFStringRef pathStringRef = CFStringCreateWithCString(kCFAllocatorDefault, options.kernelPath, kCFStringEncodingASCII);
@@ -1424,14 +1353,13 @@
bool isCodeless = bundleData.executablePath.empty();
if ( !isCodeless ) {
char realerPath[MAXPATHLEN];
- void (^fileErrorLog)(const char *format, ...) __printflike(1, 2)
- = ^(const char *format, ...) __printflike(1, 2) {
+ bool loadedFile = fileSystem.loadFile(bundleData.executablePath.c_str(), info, realerPath,
+ ^(const char *format, ...) {
va_list list;
va_start(list, format);
- diag.error(format, va_list_wrap(list));
+ diag.error(format, list);
va_end(list);
- };
- bool loadedFile = fileSystem.loadFile(bundleData.executablePath.c_str(), info, realerPath, fileErrorLog);
+ });
if ( !loadedFile )
return {};
}