Loading...
--- dyld/dyld-1042.1/common/MachOFile.cpp
+++ dyld/dyld-1066.8/common/MachOFile.cpp
@@ -1870,18 +1870,19 @@
}
// <rdar://problem/57769033> dyld_cache_patchable_location only supports addend in range 0..31
+ // rdar://96164956 (dyld needs to support arbitrary addends in cache patch table)
const bool is64bit = is64();
__block bool addendTooLarge = false;
+ const uint64_t tooLargeRegularAddend = 1 << 23;
+ const uint64_t tooLargeAuthAddend = 1 << 5;
if ( this->hasChainedFixups() ) {
// with chained fixups, addends can be in the import table or embedded in a bind pointer
+ __block std::vector<uint64_t> targetAddends;
fixups.forEachChainedFixupTarget(diag, ^(int libOrdinal, const char* symbolName, uint64_t addend, bool weakImport, bool& stop) {
if ( is64bit )
addend &= 0x00FFFFFFFFFFFFFF; // ignore TBI
- if ( addend > 31 ) {
- addendTooLarge = true;
- stop = true;
- }
+ targetAddends.push_back(addend);
});
// check each pointer for embedded addend
fixups.withChainStarts(diag, ^(const dyld_chained_starts_in_image* starts) {
@@ -1889,26 +1890,60 @@
switch (segInfo->pointer_format) {
case DYLD_CHAINED_PTR_ARM64E:
case DYLD_CHAINED_PTR_ARM64E_USERLAND:
+ if ( fixupLoc->arm64e.bind.bind ) {
+ uint64_t ordinal = fixupLoc->arm64e.bind.ordinal;
+ uint64_t addend = (ordinal < targetAddends.size()) ? targetAddends[ordinal] : 0;
+ if ( fixupLoc->arm64e.bind.auth ) {
+ if ( addend >= tooLargeAuthAddend ) {
+ addendTooLarge = true;
+ stop = true;
+ }
+ } else {
+ addend += fixupLoc->arm64e.signExtendedAddend();
+ if ( addend >= tooLargeRegularAddend ) {
+ addendTooLarge = true;
+ stop = true;
+ }
+ }
+ }
+ break;
case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
- if ( fixupLoc->arm64e.bind.bind && !fixupLoc->arm64e.authBind.auth ) {
- if ( fixupLoc->arm64e.bind.addend > 31 ) {
+ if ( fixupLoc->arm64e.bind24.bind ) {
+ uint64_t ordinal = fixupLoc->arm64e.bind24.ordinal;
+ uint64_t addend = (ordinal < targetAddends.size()) ? targetAddends[ordinal] : 0;
+ if ( fixupLoc->arm64e.bind24.auth ) {
+ if ( addend >= tooLargeAuthAddend ) {
+ addendTooLarge = true;
+ stop = true;
+ }
+ } else {
+ addend += fixupLoc->arm64e.signExtendedAddend();
+ if ( addend >= tooLargeRegularAddend ) {
+ addendTooLarge = true;
+ stop = true;
+ }
+ }
+ }
+ break;
+ case DYLD_CHAINED_PTR_64:
+ case DYLD_CHAINED_PTR_64_OFFSET: {
+ if ( fixupLoc->generic64.rebase.bind ) {
+ uint64_t ordinal = fixupLoc->generic64.bind.ordinal;
+ uint64_t addend = (ordinal < targetAddends.size()) ? targetAddends[ordinal] : 0;
+ addend += fixupLoc->generic64.bind.addend;
+ if ( addend >= tooLargeRegularAddend ) {
addendTooLarge = true;
stop = true;
}
}
break;
- case DYLD_CHAINED_PTR_64:
- case DYLD_CHAINED_PTR_64_OFFSET:
- if ( fixupLoc->generic64.rebase.bind ) {
- if ( fixupLoc->generic64.bind.addend > 31 ) {
- addendTooLarge = true;
- stop = true;
- }
- }
- break;
+ }
case DYLD_CHAINED_PTR_32:
if ( fixupLoc->generic32.bind.bind ) {
- if ( fixupLoc->generic32.bind.addend > 31 ) {
+ uint64_t ordinal = fixupLoc->generic32.bind.ordinal;
+ uint64_t addend = (ordinal < targetAddends.size()) ? targetAddends[ordinal] : 0;
+ addend += fixupLoc->generic32.bind.addend;
+ if ( addend >= tooLargeRegularAddend ) {
addendTooLarge = true;
stop = true;
}
@@ -1924,7 +1959,7 @@
uint64_t addend = info.addend;
if ( is64bit )
addend &= 0x00FFFFFFFFFFFFFF; // ignore TBI
- if ( addend > 31 ) {
+ if ( addend >= tooLargeRegularAddend ) {
addendTooLarge = true;
stop = true;
}
@@ -3264,6 +3299,15 @@
}
}
+bool MachOFile::PointerMetaData::operator==(const PointerMetaData& other) const
+{
+ return (this->diversity == other.diversity)
+ && (this->high8 == other.high8)
+ && (this->authenticated == other.authenticated)
+ && (this->key == other.key)
+ && (this->usesAddrDiversity == other.usesAddrDiversity);
+}
+
#if !SUPPORT_VM_LAYOUT
bool MachOFile::getLinkeditLayout(Diagnostics& diag, mach_o::LinkeditLayout& layout) const
{