Skip to content

Commit 1d5d9d6

Browse files
committed
Fix CFInfo on 64-bit big endian platforms.
Prior to this change 64-bit platforms treated _cfinfoa as both a 64-bit and 32-bit variable. When accessing _cfinfoa as a 32-bit variable the code makes the assumption that it is accessing the lowest (or rightmost) bits of _cfinfoa. Unfortunately on big-endian platforms it is actually accessing the high (or leftmost) bits. Fix this issue by unconditionally treating _cfinfoa as a 64-bit value when targeting a 64-bit platform.
1 parent 1080c44 commit 1d5d9d6

File tree

4 files changed

+27
-25
lines changed

4 files changed

+27
-25
lines changed

CoreFoundation/Base.subproj/CFInternal.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,11 +434,7 @@ CF_EXPORT void * __CFConstantStringClassReferencePtr;
434434
#define CONST_STRING_SECTION
435435
#endif
436436

437-
#if __BIG_ENDIAN__
438-
#define _CF_CONST_STR_CFINFOA 0x00000000C8070000
439-
#else // Little endian:
440437
#define _CF_CONST_STR_CFINFOA 0x07C8
441-
#endif // __BIG_ENDIAN__
442438

443439
#define _CF_CONST_STR_CONTENTS(cStr) {{(uintptr_t)&_CF_CONSTANT_STRING_SWIFT_CLASS, _CF_CONSTANT_OBJECT_STRONG_RC, _CF_CONST_STR_CFINFOA}, (uint8_t *)(cStr), sizeof(cStr) - 1}
444440

CoreFoundation/Base.subproj/CFRuntime.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -362,17 +362,10 @@ void _CFEnableZombies(void) {
362362
On 64 bit, also includes 32 bits more of retain count from 32-63
363363
*/
364364

365-
#if __CF_BIG_ENDIAN__
366-
#define RC_INCREMENT (1ULL)
367-
#define RC_CUSTOM_RC_BIT (0x800000ULL << 32)
368-
#define RC_DEALLOCATING_BIT (0x400000ULL << 32)
369-
#define RC_DEALLOCATED_BIT (0x200000ULL << 32)
370-
#else
371365
#define RC_INCREMENT (1ULL << 32)
372366
#define RC_CUSTOM_RC_BIT (0x800000ULL)
373367
#define RC_DEALLOCATING_BIT (0x400000ULL)
374368
#define RC_DEALLOCATED_BIT (0x200000ULL)
375-
#endif
376369

377370
#if TARGET_RT_64_BIT
378371
#define HIGH_RC_START 32

CoreFoundation/String.subproj/CFString.h

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -167,24 +167,21 @@ struct __CFConstStr {
167167
uint64_t _cfinfoa;
168168
} _base;
169169
uint8_t *_ptr;
170-
#if TARGET_RT_64_BIT && defined(__BIG_ENDIAN__)
171-
uint64_t _length;
172-
#else // 32-bit:
173170
uint32_t _length;
174-
#endif // TARGET_RT_64_BIT && defined(__BIG_ENDIAN__)
175171
};
176172

177-
#if __BIG_ENDIAN__
178173
#define CFSTR(cStr) ({ \
179-
static struct __CFConstStr str = {{(uintptr_t)&_CF_CONSTANT_STRING_SWIFT_CLASS, _CF_CONSTANT_OBJECT_STRONG_RC, 0x00000000C8070000}, (uint8_t *)(cStr), sizeof(cStr) - 1}; \
174+
static struct __CFConstStr str = { \
175+
_base: { \
176+
_cfisa: (uintptr_t)(&_CF_CONSTANT_STRING_SWIFT_CLASS), \
177+
_swift_rc: _CF_CONSTANT_OBJECT_STRONG_RC, \
178+
_cfinfoa: _CF_CONST_STR_CFINFOA \
179+
}, \
180+
_ptr: (uint8_t *)(cStr), \
181+
_length: sizeof(cStr) - 1 \
182+
}; \
180183
(CFStringRef)&str; \
181184
})
182-
#else // Little endian:
183-
#define CFSTR(cStr) ({ \
184-
static struct __CFConstStr str = {{(uintptr_t)&_CF_CONSTANT_STRING_SWIFT_CLASS, _CF_CONSTANT_OBJECT_STRONG_RC, 0x07C8}, (uint8_t *)(cStr), sizeof(cStr) - 1}; \
185-
(CFStringRef)&str; \
186-
})
187-
#endif // __BIG_ENDIAN__
188185

189186
#else
190187

Foundation/NSObjCRuntime.swift

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,17 +215,33 @@ internal func NSInvalidArgument(_ message: String, method: String = #function, f
215215

216216
internal struct _CFInfo {
217217
// This must match _CFRuntimeBase
218+
#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le)
219+
// 64-bit
220+
var info: UInt64
221+
init(typeID: CFTypeID) {
222+
// This matches what _CFRuntimeCreateInstance does to initialize the info value
223+
info = UInt64((UInt32(typeID) << 8) | 0x80)
224+
}
225+
init(typeID: CFTypeID, extra: UInt32) {
226+
info = UInt64((UInt32(typeID) << 8) | 0x80)
227+
info |= UInt64(extra) << 32
228+
}
229+
#elseif arch(arm) || arch(i386)
230+
// 32-bit
218231
var info: UInt32
219232
var pad : UInt32
220233
init(typeID: CFTypeID) {
221234
// This matches what _CFRuntimeCreateInstance does to initialize the info value
222-
info = UInt32((UInt32(typeID) << 8) | (UInt32(0x80)))
235+
info = (UInt32(typeID) << 8) | 0x80
223236
pad = 0
224237
}
225238
init(typeID: CFTypeID, extra: UInt32) {
226-
info = UInt32((UInt32(typeID) << 8) | (UInt32(0x80)))
239+
info = (UInt32(typeID) << 8) | 0x80
227240
pad = extra
228241
}
242+
#else
243+
#error("unknown architecture")
244+
#endif
229245
}
230246

231247
// MARK: Classes to strings

0 commit comments

Comments
 (0)