Loading...
--- dyld/dyld-1284.13/libdyld/utils.cpp
+++ dyld/dyld-1122.1/libdyld/utils.cpp
@@ -37,28 +37,11 @@
#include "FileUtils.h"
#include "DyldDelegates.h"
-// mach_o
-#include "Architecture.h"
-#include "Header.h"
-#include "Image.h"
-#include "Error.h"
-#include "Version32.h"
-#include "Fixup.h"
-#include "Symbol.h"
-
using dyld3::MachOFile;
using dyld3::FatFile;
using dyld3::GradedArchs;
-
-using mach_o::Header;
-using mach_o::Image;
-using mach_o::Error;
-using mach_o::Version32;
-using mach_o::Version64;
-using mach_o::LinkedDylibAttributes;
-using mach_o::Fixup;
-using mach_o::Symbol;
-using mach_o::Platform;
+using dyld3::Platform;
+
// used by unit tests
__attribute__((visibility("hidden")))
@@ -72,23 +55,14 @@
bool macho_cpu_type_for_arch_name(const char* archName, cpu_type_t* type, cpu_subtype_t* subtype)
{
- mach_o::Architecture arch = mach_o::Architecture::byName(archName);
- if ( arch == mach_o::Architecture::invalid )
- return false;
-
- *type = arch.cpuType();
- *subtype = arch.cpuSubtype();
- return true;
+ return MachOFile::cpuTypeFromArchName(archName, type, subtype);
}
const char* macho_arch_name_for_cpu_type(cpu_type_t type, cpu_subtype_t subtype)
{
- const char* result = mach_o::Architecture(type, subtype).name();
+ const char* result = MachOFile::archName(type, subtype);
if ( strcmp(result, "unknown") == 0 )
return nullptr;
- // Strip any suffix that further specifies the exact arm64e type (.old, .kernel, etc).
- if ( std::string_view(result).starts_with("arm64e") )
- return "arm64e";
return result;
}
@@ -164,13 +138,13 @@
return result;
}
-static bool launchableOnCurrentPlatform(const Header* mh)
+static bool launchableOnCurrentPlatform(const MachOFile* mf)
{
#if TARGET_OS_OSX
// macOS is special and can launch macOS, catalyst, and iOS apps
- return ( mh->builtForPlatform(Platform::macOS) || mh->builtForPlatform(Platform::macCatalyst) || mh->builtForPlatform(Platform::iOS) );
+ return ( mf->builtForPlatform(Platform::macOS) || mf->builtForPlatform(Platform::iOSMac) || mf->builtForPlatform(Platform::iOS) );
#else
- return mh->builtForPlatform(Platform::current());
+ return mf->builtForPlatform(MachOFile::currentPlatform());
#endif
}
@@ -194,18 +168,18 @@
__block uint64_t sliceOffset = 0;
__block uint64_t sliceLen = 0;
ff->forEachSlice(diag, statbuf.st_size, ^(uint32_t sliceCpuType, uint32_t sliceCpuSubType, const void* sliceStart, uint64_t sliceSize, bool& stop) {
- if ( const Header* mh = Header::isMachO({(const uint8_t*)sliceStart, (size_t)sliceSize}) ) {
- if ( mh->isMainExecutable() ) {
- int sliceGrade = launchArchs.grade(mh->arch().cpuType(), mh->arch().cpuSubtype(), isOSBinary);
- if ( (sliceGrade > bestGrade) && launchableOnCurrentPlatform(mh) ) {
+ if ( const MachOFile* mf = MachOFile::isMachO(sliceStart) ) {
+ if ( mf->filetype == MH_EXECUTE ) {
+ int sliceGrade = launchArchs.grade(mf->cputype, mf->cpusubtype, isOSBinary);
+ if ( (sliceGrade > bestGrade) && launchableOnCurrentPlatform(mf) ) {
sliceOffset = (char*)sliceStart - (char*)mappedFile;
sliceLen = sliceSize;
bestGrade = sliceGrade;
}
}
else {
- int sliceGrade = dylibArchs.grade(mh->arch().cpuType(), mh->arch().cpuSubtype(), isOSBinary);
- if ( (sliceGrade > bestGrade) && mh->loadableIntoProcess(platform, "") ) {
+ int sliceGrade = dylibArchs.grade(mf->cputype, mf->cpusubtype, isOSBinary);
+ if ( (sliceGrade > bestGrade) && mf->loadableIntoProcess(platform, "") ) {
sliceOffset = (char*)sliceStart - (char*)mappedFile;
sliceLen = sliceSize;
bestGrade = sliceGrade;
@@ -223,16 +197,16 @@
else
result = EBADARCH;
}
- else if ( const Header* mh = Header::isMachO({(const uint8_t*)mappedFile, (size_t)statbuf.st_size}) ) {
- if ( mh->isMainExecutable() && (launchArchs.grade(mh->arch().cpuType(), mh->arch().cpuSubtype(), isOSBinary) != 0) && launchableOnCurrentPlatform(mh) ) {
+ else if ( const MachOFile* mf = MachOFile::isMachO(mappedFile) ) {
+ if ( (mf->filetype == MH_EXECUTE) && (launchArchs.grade(mf->cputype, mf->cpusubtype, isOSBinary) != 0) && launchableOnCurrentPlatform(mf) ) {
// the "best" of a main executable must pass grading and be a launchable
if ( bestSlice )
- bestSlice((const mach_header*)mh, 0, (size_t)statbuf.st_size);
- }
- else if ( (dylibArchs.grade(mh->arch().cpuType(), mh->arch().cpuSubtype(), isOSBinary) != 0) && mh->loadableIntoProcess(platform, "") ) {
+ bestSlice(mf, 0, (size_t)statbuf.st_size);
+ }
+ else if ( (dylibArchs.grade(mf->cputype, mf->cpusubtype, isOSBinary) != 0) && mf->loadableIntoProcess(platform, "") ) {
// the "best" of a dylib/bundle must pass grading and match the platform of the current process
if ( bestSlice )
- bestSlice((const mach_header*)mh, 0, (size_t)statbuf.st_size);
+ bestSlice(mf, 0, (size_t)statbuf.st_size);
}
else {
result = EBADARCH;
@@ -247,29 +221,12 @@
return result;
}
-#if __arm64e__
-static const void* stripPointer(const void* ptr)
-{
-#if __has_feature(ptrauth_calls)
- return __builtin_ptrauth_strip(ptr, ptrauth_key_asia);
-#else
- return ptr;
-#endif
-}
-#endif
int macho_best_slice_in_fd(int fd, void (^bestSlice)(const struct mach_header* slice, uint64_t sliceFileOffset, size_t sliceSize)__MACHO_NOESCAPE)
{
- bool keysOff = true;
-#if __arm64e__
- // Test if PAC is enabled
- const void* p = (const void*)&macho_best_slice;
- if ( stripPointer(p) != p )
- keysOff = false;
-#endif
- const Platform platform = Platform::current();
- const GradedArchs* launchArchs = &GradedArchs::launchCurrentOS();
- const GradedArchs* dylibArchs = &GradedArchs::forCurrentOS(keysOff, false);
+ const Platform platform = MachOFile::currentPlatform();
+ const GradedArchs* launchArchs = &GradedArchs::forCurrentOS(false, false);
+ const GradedArchs* dylibArchs = &GradedArchs::forCurrentOS(false, false);
#if TARGET_OS_SIMULATOR
const char* simArchNames = getenv("SIMULATOR_ARCHS");
if ( simArchNames == nullptr )
@@ -286,176 +243,10 @@
///
const char* _Nullable macho_dylib_install_name(const struct mach_header* _Nonnull mh) DYLD_EXCLAVEKIT_UNAVAILABLE
{
- const Header* hdr = (const Header*)mh;
- if ( hdr->hasMachOMagic() )
- return hdr->installName();
+ if ( const MachOFile* mf = MachOFile::isMachO(mh) )
+ return mf->installName();
return nullptr;
}
-static void iterateDependencies(const Image& image, void (^_Nonnull callback)(const char* _Nonnull loadPath, const char* _Nonnull attributes, bool* _Nonnull stop) )
-{
- image.header()->forEachLinkedDylib(^(const char* loadPath, LinkedDylibAttributes kind, Version32 compatVersion, Version32 curVersion,
- bool synthesizedLink, bool& stop) {
- char attrBuf[64];
- kind.toString(attrBuf);
- callback(loadPath, attrBuf, &stop);
- });
-}
-
-int macho_for_each_dependent_dylib(const struct mach_header* _Nonnull mh, size_t mappedSize,
- void (^ _Nonnull callback)(const char* _Nonnull loadPath, const char* _Nonnull attributes, bool* _Nonnull stop))
-{
- if ( mappedSize == 0 ) {
- // Image loaded by dyld
- Image image(mh);
- iterateDependencies(image, callback);
- }
- else {
- // raw mach-o file/slice in memory
- Image image(mh, mappedSize, Image::MappingKind::wholeSliceMapped);
- if ( !image.header()->hasMachOMagic() )
- return EFTYPE;
- if ( Error err = image.validate() )
- return EBADMACHO;
- iterateDependencies(image, callback);
- }
- return 0;
-}
-
-static void iterateImportedSymbols(const Image& image, void (^_Nonnull callback)(const char* _Nonnull symbolName, const char* _Nonnull libraryPath, bool weakImport, bool* _Nonnull stop) )
-{
- if ( image.hasChainedFixups() ) {
- image.chainedFixups().forEachBindTarget(^(const Fixup::BindTarget& bindTarget, bool& stop) {
- callback(bindTarget.symbolName.c_str(), image.header()->libOrdinalName(bindTarget.libOrdinal).c_str(), bindTarget.weakImport, &stop);
- });
- }
- else {
- // old opcode based fixups
- if ( image.hasBindOpcodes() ) {
- image.bindOpcodes().forEachBindTarget(^(const Fixup::BindTarget& bindTarget, bool& stop) {
- callback(bindTarget.symbolName.c_str(), image.header()->libOrdinalName(bindTarget.libOrdinal).c_str(), bindTarget.weakImport, &stop);
- }, ^(const char* symbolName) {
- });
- }
- if ( image.hasLazyBindOpcodes() ) {
- image.lazyBindOpcodes().forEachBindTarget(^(const Fixup::BindTarget& bindTarget, bool& stop) {
- callback(bindTarget.symbolName.c_str(), image.header()->libOrdinalName(bindTarget.libOrdinal).c_str(), bindTarget.weakImport, &stop);
- }, ^(const char *symbolName) {
- });
- }
- }
-}
-
-int macho_for_each_imported_symbol(const struct mach_header* _Nonnull mh, size_t mappedSize,
- void (^ _Nonnull callback)(const char* _Nonnull symbolName, const char* _Nonnull libraryPath, bool weakImport, bool* _Nonnull stop))
-{
- if ( mappedSize == 0 ) {
- // Image loaded by dyld, but sanity check
- if ( !((Header*)mh)->hasMachOMagic() )
- return EFTYPE;
- Image image(mh);
- iterateImportedSymbols(image, callback);
- }
- else {
- // raw mach-o file/slice in memory
- Image image(mh, mappedSize, Image::MappingKind::wholeSliceMapped);
- if ( !image.header()->hasMachOMagic() )
- return EFTYPE;
- if ( Error err = image.validate() )
- return EBADMACHO;
- iterateImportedSymbols(image, callback);
- }
- return 0;
-}
-
-static const char* exportSymbolAttrString(const Symbol& symbol)
-{
- uint64_t other;
- if ( symbol.isWeakDef() )
- return "weak-def";
- else if ( symbol.isThreadLocal() )
- return "thread-local";
- else if ( symbol.isDynamicResolver(other) )
- return "dynamic-resolver";
- else if ( symbol.isAbsolute(other) )
- return "absolute";
- return "";
-}
-
-static void iterateExportedSymbols(const Image& image, void (^_Nonnull callback)(const char* _Nonnull symbolName, const char* _Nonnull attributes, bool* _Nonnull stop) )
-{
- if ( image.hasExportsTrie() ) {
- image.exportsTrie().forEachExportedSymbol(^(const Symbol& symbol, bool& stop) {
- callback(symbol.name().c_str(), exportSymbolAttrString(symbol), &stop);
- });
- }
- else if ( image.hasSymbolTable() ) {
- image.symbolTable().forEachExportedSymbol(^(const Symbol& symbol, uint32_t symbolIndex, bool& stop) {
- callback(symbol.name().c_str(), exportSymbolAttrString(symbol), &stop);
- });
- }
-}
-
-int macho_for_each_exported_symbol(const struct mach_header* _Nonnull mh, size_t mappedSize,
- void (^ _Nonnull callback)(const char* _Nonnull symbolName, const char* _Nonnull attributes, bool* _Nonnull stop))
-{
- if ( mappedSize == 0 ) {
- // Image loaded by dyld, but sanity check
- if ( !((Header*)mh)->hasMachOMagic() )
- return EFTYPE;
- Image image(mh);
- iterateExportedSymbols(image, callback);
- }
- else {
- // raw mach-o file/slice in memory
- Image image(mh, mappedSize, Image::MappingKind::wholeSliceMapped);
- if ( !image.header()->hasMachOMagic() )
- return EFTYPE;
- if ( Error err = image.validate() )
- return EBADMACHO;
- iterateExportedSymbols(image, callback);
- }
- return 0;
-}
-
-
-int macho_for_each_defined_rpath(const struct mach_header* _Nonnull mh, size_t mappedSize,
- void (^ _Nonnull callback)(const char* _Nonnull rpath, bool* _Nonnull stop))
-{
- if ( mappedSize == 0 ) {
- // Image loaded by dyld
- Image image(mh);
- image.header()->forEachRPath(^(const char* _Nonnull rpath, bool& stop) {
- callback(rpath, &stop);
- });
- }
- else {
- // raw mach-o file/slice in memory
- Image image(mh, mappedSize, Image::MappingKind::wholeSliceMapped);
- if ( !image.header()->hasMachOMagic() )
- return EFTYPE;
- if ( Error err = image.validate() )
- return EBADMACHO;
- image.header()->forEachRPath(^(const char* _Nonnull rpath, bool& stop) {
- callback(rpath, &stop);
- });
- }
- return 0;
-}
-
-bool macho_source_version(const struct mach_header* _Nonnull mh, uint64_t* _Nonnull version)
-{
- Header* header = (Header*)mh;
- if ( !header->hasMachOMagic() )
- return false;
-
- Version64 v;
- if ( !header->sourceVersion(v) )
- return false;
-
- *version = v.value();
- return true;
-}
-
#endif // !TARGET_OS_EXCLAVEKIT