1/* 2 * Copyright (c) 2014 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* CoreFoundation_Prefix.h 25 Copyright (c) 2005-2013, Apple Inc. All rights reserved. 26*/ 27 28 29#define _DARWIN_UNLIMITED_SELECT 1 30 31#include <CoreFoundation/CFBase.h> 32 33 34#include <stdlib.h> 35#include <stdint.h> 36#include <string.h> 37 38#if DEPLOYMENT_TARGET_WINDOWS && defined(__cplusplus) 39extern "C" { 40#endif 41 42#define SystemIntegrityCheck(A, B) do {} while (0) 43 44 45#if INCLUDE_OBJC 46#include <objc/objc.h> 47#else 48typedef signed char BOOL; 49typedef char * id; 50typedef char * Class; 51#define YES (BOOL)1 52#define NO (BOOL)0 53#define nil NULL 54#endif 55 56#define CRSetCrashLogMessage(A) do {} while (0) 57#define CRSetCrashLogMessage2(A) do {} while (0) 58 59#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI 60#import <libkern/OSAtomic.h> 61#import <pthread.h> 62#endif 63 64/* This macro creates some helper functions which are useful in dealing with libdispatch: 65 * __ PREFIX Queue -- manages and returns a singleton serial queue 66 * 67 * Use the macro like this: 68 * DISPATCH_HELPER_FUNCTIONS(fh, NSFileHandle) 69 */ 70 71#define DISPATCH_HELPER_FUNCTIONS(PREFIX, QNAME) \ 72static dispatch_queue_t __ ## PREFIX ## Queue(void) { \ 73 static volatile dispatch_queue_t __ ## PREFIX ## dq = NULL; \ 74 if (!__ ## PREFIX ## dq) { \ 75 dispatch_queue_t dq = dispatch_queue_create(# QNAME, NULL); \ 76 void * volatile *loc = (void * volatile *)&__ ## PREFIX ## dq; \ 77 if (!OSAtomicCompareAndSwapPtrBarrier(NULL, dq, loc)) { \ 78 dispatch_release(dq); \ 79 } \ 80 } \ 81 return __ ## PREFIX ## dq; \ 82} \ 83 84 85#define LIBAUTO_STUB 1 86 87#ifndef LIBAUTO_STUB 88 89#if DEPLOYMENT_TARGET_MACOSX 90#include <auto_zone.h> 91#endif 92#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED 93#include <objc/objc-auto.h> 94#endif 95 96#endif // LIBAUTO_STUB 97 98#if DEPLOYMENT_TARGET_WINDOWS 99// Compatibility with boolean.h 100#if defined(__x86_64__) 101typedef unsigned int boolean_t; 102#else 103typedef int boolean_t; 104#endif 105#endif 106 107#if DEPLOYMENT_TARGET_LINUX 108 109#define CF_PRIVATE 110#define __strong 111#define __weak 112 113#define strtod_l(a,b,locale) strtod(a,b) 114#define strtoul_l(a,b,c,locale) strtoul(a,b,c) 115#define strtol_l(a,b,c,locale) strtol(a,b,c) 116#define strtoll_l(a,b,c,locale) strtoll(a,b,c) 117#define strncasecmp_l(a, b, c, d) strncasecmp(a, b, c) 118 119#define fprintf_l(a,locale,b,...) fprintf(a, b, __VA_ARGS__) 120 121#include <pthread.h> 122 123CF_INLINE size_t 124strlcpy(char * dst, const char * src, size_t maxlen) { 125 const size_t srclen = strlen(src); 126 if (srclen < maxlen) { 127 memcpy(dst, src, srclen+1); 128 } else if (maxlen != 0) { 129 memcpy(dst, src, maxlen-1); 130 dst[maxlen-1] = '\0'; 131 } 132 return srclen; 133} 134 135CF_INLINE size_t 136strlcat(char * dst, const char * src, size_t maxlen) { 137 const size_t srclen = strlen(src); 138 const size_t dstlen = strnlen(dst, maxlen); 139 if (dstlen == maxlen) return maxlen+srclen; 140 if (srclen < maxlen-dstlen) { 141 memcpy(dst+dstlen, src, srclen+1); 142 } else { 143 memcpy(dst+dstlen, src, maxlen-dstlen-1); 144 dst[maxlen-1] = '\0'; 145 } 146 return dstlen + srclen; 147} 148 149#define issetugid() 0 150 151// Implemented in CFPlatform.c 152bool OSAtomicCompareAndSwapPtr(void *oldp, void *newp, void *volatile *dst); 153bool OSAtomicCompareAndSwapLong(long oldl, long newl, long volatile *dst); 154bool OSAtomicCompareAndSwapPtrBarrier(void *oldp, void *newp, void *volatile *dst); 155bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue ); 156 157int32_t OSAtomicDecrement32Barrier(volatile int32_t *dst); 158int32_t OSAtomicIncrement32Barrier(volatile int32_t *dst); 159int32_t OSAtomicIncrement32(volatile int32_t *theValue); 160int32_t OSAtomicDecrement32(volatile int32_t *theValue); 161 162int32_t OSAtomicAdd32( int32_t theAmount, volatile int32_t *theValue ); 163int32_t OSAtomicAdd32Barrier( int32_t theAmount, volatile int32_t *theValue ); 164bool OSAtomicCompareAndSwap32Barrier( int32_t oldValue, int32_t newValue, volatile int32_t *theValue ); 165 166void OSMemoryBarrier(); 167 168#include <malloc.h> 169CF_INLINE size_t malloc_size(void *memblock) { 170 return malloc_usable_size(memblock); 171} 172 173// substitute for dispatch_once 174typedef pthread_once_t dispatch_once_t; 175typedef void (^dispatch_block_t)(void); 176void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block); 177 178#endif 179 180#if DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX 181#if !defined(MIN) 182#define MIN(A,B) ((A) < (B) ? (A) : (B)) 183#endif 184 185#if !defined(MAX) 186#define MAX(A,B) ((A) > (B) ? (A) : (B)) 187#endif 188 189#if !defined(ABS) 190#define ABS(A) ((A) < 0 ? (-(A)) : (A)) 191#endif 192#endif 193 194#if DEPLOYMENT_TARGET_WINDOWS 195 196#define MAXPATHLEN MAX_PATH 197#undef MAX_PATH 198#undef INVALID_HANDLE_VALUE 199 200// Defined for source compatibility 201#define ino_t _ino_t 202#define off_t _off_t 203#define mode_t uint16_t 204 205// This works because things aren't actually exported from the DLL unless they have a __declspec(dllexport) on them... so extern by itself is closest to __private_extern__ on Mac OS 206#define CF_PRIVATE extern 207 208#define __builtin_expect(P1,P2) P1 209 210// These are replacements for POSIX calls on Windows, ensuring that the UTF8 parameters are converted to UTF16 before being passed to Windows 211CF_EXPORT int _NS_stat(const char *name, struct _stat *st); 212CF_EXPORT int _NS_mkdir(const char *name); 213CF_EXPORT int _NS_rmdir(const char *name); 214CF_EXPORT int _NS_chmod(const char *name, int mode); 215CF_EXPORT int _NS_unlink(const char *name); 216CF_EXPORT char *_NS_getcwd(char *dstbuf, size_t size); // Warning: this doesn't support dstbuf as null even though 'getcwd' does 217CF_EXPORT char *_NS_getenv(const char *name); 218CF_EXPORT int _NS_rename(const char *oldName, const char *newName); 219CF_EXPORT int _NS_open(const char *name, int oflag, int pmode = 0); 220CF_EXPORT int _NS_chdir(const char *name); 221CF_EXPORT int _NS_mkstemp(char *name, int bufSize); 222CF_EXPORT int _NS_access(const char *name, int amode); 223 224#define BOOL WINDOWS_BOOL 225 226#define WIN32_LEAN_AND_MEAN 227 228#ifndef WINVER 229#define WINVER 0x0501 230#endif 231 232#ifndef _WIN32_WINNT 233#define _WIN32_WINNT 0x0501 234#endif 235 236// The order of these includes is important 237#define FD_SETSIZE 1024 238#include <winsock2.h> 239#include <windows.h> 240#include <pthread.h> 241 242#undef BOOL 243 244#ifndef HAVE_STRUCT_TIMESPEC 245#define HAVE_STRUCT_TIMESPEC 1 246struct timespec { 247 long tv_sec; 248 long tv_nsec; 249}; 250#endif /* HAVE_STRUCT_TIMESPEC */ 251 252#define __PRETTY_FUNCTION__ __FUNCTION__ 253 254#define malloc_default_zone() (void *)0 255#define malloc_zone_from_ptr(a) (void *)0 256#define malloc_zone_malloc(zone,size) malloc(size) 257#define malloc_zone_memalign(zone,align,size) malloc(size) 258#define malloc_zone_calloc(zone,count,size) calloc(count,size) 259#define bcopy(b1,b2,len) memmove(b2, b1, (size_t)(len)) 260typedef int malloc_zone_t; 261typedef int uid_t; 262typedef int gid_t; 263#define geteuid() 0 264#define getuid() 0 265#define getegid() 0 266 267#define scalbn(A, B) _scalb(A, B) 268 269#define fsync(a) _commit(a) 270#define malloc_create_zone(a,b) 123 271#define malloc_set_zone_name(zone,name) 272#define malloc_zone_realloc(zone,ptr,size) realloc(ptr,size) 273#define malloc_zone_free(zone,ptr) free(ptr) 274 275// implemented in CFInternal.h 276#define OSSpinLockLock(A) __CFSpinLock(A) 277#define OSSpinLockUnlock(A) __CFSpinUnlock(A) 278 279typedef int32_t OSSpinLock; 280 281#define OS_SPINLOCK_INIT 0 282 283#include <stdint.h> 284#include <stdbool.h> 285#include <stdio.h> 286#include <malloc.h> 287 288CF_INLINE size_t malloc_size(void *memblock) { 289 return _msize(memblock); 290} 291 292CF_INLINE uint64_t mach_absolute_time() { 293 LARGE_INTEGER count; 294 QueryPerformanceCounter(&count); 295 // mach_absolute_time is unsigned, but this function returns a signed value. 296 return (uint64_t)count.QuadPart; 297} 298 299CF_INLINE long long llabs(long long v) { 300 if (v < 0) return -v; 301 return v; 302} 303 304#define strtod_l(a,b,locale) strtod(a,b) 305#define strtoul_l(a,b,c,locale) strtoul(a,b,c) 306#define strtol_l(a,b,c,locale) strtol(a,b,c) 307#define strtoll_l(a,b,c,locale) _strtoi64(a,b,c) 308#define strncasecmp(a, b, c) _strnicmp(a, b, c) 309#define strncasecmp_l(a, b, c, d) _strnicmp(a, b, c) 310#define snprintf _snprintf 311 312#define fprintf_l(a,locale,b,...) fprintf(a, b, __VA_ARGS__) 313 314CF_INLINE size_t 315strlcpy(char * dst, const char * src, size_t maxlen) { 316 const size_t srclen = strlen(src); 317 if (srclen < maxlen) { 318 memcpy(dst, src, srclen+1); 319 } else if (maxlen != 0) { 320 memcpy(dst, src, maxlen-1); 321 dst[maxlen-1] = '\0'; 322 } 323 return srclen; 324} 325 326CF_INLINE size_t 327strlcat(char * dst, const char * src, size_t maxlen) { 328 const size_t srclen = strlen(src); 329 const size_t dstlen = strnlen(dst, maxlen); 330 if (dstlen == maxlen) return maxlen+srclen; 331 if (srclen < maxlen-dstlen) { 332 memcpy(dst+dstlen, src, srclen+1); 333 } else { 334 memcpy(dst+dstlen, src, maxlen-dstlen-1); 335 dst[maxlen-1] = '\0'; 336 } 337 return dstlen + srclen; 338} 339 340#define sleep(x) Sleep(1000*x) 341 342#define issetugid() 0 343 344// CF exports these useful atomic operation functions on Windows 345CF_EXPORT bool OSAtomicCompareAndSwapPtr(void *oldp, void *newp, void *volatile *dst); 346CF_EXPORT bool OSAtomicCompareAndSwapLong(long oldl, long newl, long volatile *dst); 347CF_EXPORT bool OSAtomicCompareAndSwapPtrBarrier(void *oldp, void *newp, void *volatile *dst); 348 349CF_EXPORT int32_t OSAtomicDecrement32Barrier(volatile int32_t *dst); 350CF_EXPORT int32_t OSAtomicIncrement32Barrier(volatile int32_t *dst); 351CF_EXPORT int32_t OSAtomicIncrement32(volatile int32_t *theValue); 352CF_EXPORT int32_t OSAtomicDecrement32(volatile int32_t *theValue); 353 354CF_EXPORT int32_t OSAtomicAdd32( int32_t theAmount, volatile int32_t *theValue ); 355CF_EXPORT int32_t OSAtomicAdd32Barrier( int32_t theAmount, volatile int32_t *theValue ); 356CF_EXPORT bool OSAtomicCompareAndSwap32Barrier( int32_t oldValue, int32_t newValue, volatile int32_t *theValue ); 357 358/* 359CF_EXPORT bool OSAtomicCompareAndSwap64( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue ); 360CF_EXPORT bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue ); 361 362CF_EXPORT int64_t OSAtomicAdd64( int64_t __theAmount, volatile int64_t *__theValue ); 363CF_EXPORT int64_t OSAtomicAdd64Barrier( int64_t __theAmount, volatile int64_t *__theValue ); 364*/ 365 366//#ifndef NTDDI_VERSION 367//#define NTDDI_VERSION NTDDI_WINXP 368//#endif 369 370#include <io.h> 371#include <fcntl.h> 372#include <errno.h> 373 374#endif 375 376#if !defined(CF_PRIVATE) 377#define CF_PRIVATE __attribute__((__visibility__("hidden"))) 378#endif 379 380#if DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_WINDOWS 381 382#include <stdarg.h> 383 384CF_INLINE int flsl( long mask ) { 385 int idx = 0; 386 while (mask != 0) mask = (unsigned long)mask >> 1, idx++; 387 return idx; 388} 389 390CF_INLINE int popcountll(long long x) { 391 int count = 0; 392 while (x) { 393 count++; 394 x &= x - 1; // reset LS1B 395 } 396 return count; 397} 398 399CF_PRIVATE int asprintf(char **ret, const char *format, ...); 400 401#endif 402 403#ifdef LIBAUTO_STUB 404 405#include <stddef.h> 406 407/* Stubs for functions in libauto. */ 408 409enum {OBJC_GENERATIONAL = (1 << 0)}; 410 411enum { 412 OBJC_RATIO_COLLECTION = (0 << 0), 413 OBJC_GENERATIONAL_COLLECTION = (1 << 0), 414 OBJC_FULL_COLLECTION = (2 << 0), 415 OBJC_EXHAUSTIVE_COLLECTION = (3 << 0), 416 OBJC_COLLECT_IF_NEEDED = (1 << 3), 417 OBJC_WAIT_UNTIL_DONE = (1 << 4), 418}; 419 420 421enum { 422 AUTO_TYPE_UNKNOWN = -1, 423 AUTO_UNSCANNED = (1 << 0), 424 AUTO_OBJECT = (1 << 1), 425 AUTO_POINTERS_ONLY = (1 << 2), 426 AUTO_MEMORY_SCANNED = !AUTO_UNSCANNED, 427 AUTO_MEMORY_UNSCANNED = AUTO_UNSCANNED, 428 AUTO_MEMORY_ALL_POINTERS = AUTO_POINTERS_ONLY, 429 AUTO_MEMORY_ALL_WEAK_POINTERS = (AUTO_UNSCANNED | AUTO_POINTERS_ONLY), 430 AUTO_OBJECT_SCANNED = AUTO_OBJECT, 431 AUTO_OBJECT_UNSCANNED = AUTO_OBJECT | AUTO_UNSCANNED, 432 AUTO_OBJECT_ALL_POINTERS = AUTO_OBJECT | AUTO_POINTERS_ONLY 433}; 434typedef unsigned long auto_memory_type_t; 435typedef struct _auto_zone_t auto_zone_t; 436typedef struct auto_weak_callback_block { 437 struct auto_weak_callback_block *next; 438 void (*callback_function)(void *arg1, void *arg2); 439 void *arg1; 440 void *arg2; 441} auto_weak_callback_block_t; 442 443CF_INLINE void *objc_memmove_collectable(void *a, const void *b, size_t c) { return memmove(a, b, c); } 444CF_INLINE void *objc_collectableZone(void) { return 0; } 445 446CF_INLINE void *auto_zone_allocate_object(void *zone, size_t size, auto_memory_type_t type, int rc, int clear) { return 0; } 447CF_INLINE const void *auto_zone_base_pointer(void *zone, const void *ptr) { return 0; } 448CF_INLINE void auto_zone_set_scan_exactly(void *zone, void *ptr) {} 449CF_INLINE void auto_zone_retain(void *zone, void *ptr) {} 450CF_INLINE unsigned int auto_zone_release(void *zone, void *ptr) { return 0; } 451CF_INLINE unsigned int auto_zone_retain_count(void *zone, const void *ptr) { return 0; } 452CF_INLINE void auto_zone_set_unscanned(void *zone, void *ptr) {} 453CF_INLINE void auto_zone_set_nofinalize(void *zone, void *ptr) {} 454CF_INLINE int auto_zone_is_finalized(void *zone, const void *ptr) { return 0; } 455CF_INLINE size_t auto_zone_size(void *zone, const void *ptr) { return 0; } 456CF_INLINE void auto_register_weak_reference(void *zone, const void *referent, void **referrer, uintptr_t *counter, void **listHead, void **listElement) {} 457CF_INLINE void auto_unregister_weak_reference(void *zone, const void *referent, void **referrer) {} 458CF_INLINE int auto_zone_is_valid_pointer(void *zone, const void *ptr) { return 0; } 459CF_INLINE BOOL objc_isAuto(id object) { return 0; } 460CF_INLINE void* auto_read_weak_reference(void *zone, void **referrer) { void *result = *referrer; return result; } 461CF_INLINE void auto_assign_weak_reference(void *zone, const void *value, const void **location, auto_weak_callback_block_t *block) { *location = (void *)value; } 462CF_INLINE auto_memory_type_t auto_zone_get_layout_type(void *zone, void *ptr) { return AUTO_UNSCANNED; } 463CF_INLINE int auto_zone_set_write_barrier(void *zone, const void *dest, const void *new_value) { return false; } 464 465CF_INLINE void objc_assertRegisteredThreadWithCollector(void) {} 466CF_INLINE void objc_registerThreadWithCollector(void) {} 467 468CF_INLINE uintptr_t _object_getExternalHash(id obj) { 469 return (uintptr_t)obj; 470} 471 472// from objc-auto.h 473 474CF_INLINE BOOL objc_atomicCompareAndSwapPtr(id predicate, id replacement, volatile id *objectLocation) 475{ return OSAtomicCompareAndSwapPtr((void *)predicate, (void *)replacement, (void * volatile *)objectLocation); } 476 477CF_INLINE BOOL objc_atomicCompareAndSwapPtrBarrier(id predicate, id replacement, volatile id *objectLocation) 478{ return OSAtomicCompareAndSwapPtrBarrier((void *)predicate, (void *)replacement, (void * volatile *)objectLocation); } 479 480CF_INLINE BOOL objc_atomicCompareAndSwapGlobal(id predicate, id replacement, volatile id *objectLocation) 481{ return OSAtomicCompareAndSwapPtr((void *)predicate, (void *)replacement, (void * volatile *)objectLocation); } 482 483CF_INLINE BOOL objc_atomicCompareAndSwapGlobalBarrier(id predicate, id replacement, volatile id *objectLocation) 484{ return OSAtomicCompareAndSwapPtrBarrier((void *)predicate, (void *)replacement, (void * volatile *)objectLocation); } 485 486CF_INLINE BOOL objc_atomicCompareAndSwapInstanceVariable(id predicate, id replacement, volatile id *objectLocation) 487{ return OSAtomicCompareAndSwapPtr((void *)predicate, (void *)replacement, (void * volatile *)objectLocation); } 488 489CF_INLINE BOOL objc_atomicCompareAndSwapInstanceVariableBarrier(id predicate, id replacement, volatile id *objectLocation) 490{ return OSAtomicCompareAndSwapPtrBarrier((void *)predicate, (void *)replacement, (void * volatile *)objectLocation); } 491 492CF_INLINE id objc_assign_strongCast(id val, id *dest) 493{ return (*dest = val); } 494 495CF_INLINE id objc_assign_global(id val, id *dest) 496{ return (*dest = val); } 497 498CF_INLINE id objc_assign_ivar(id val, id dest, ptrdiff_t offset) 499{ return (*(id*)((char *)dest+offset) = val); } 500 501//CF_INLINE void *objc_memmove_collectable(void *dst, const void *src, size_t size) { return memmove(dst, src, size); } 502 503CF_INLINE id objc_read_weak(id *location) 504{ return *location; } 505 506CF_INLINE id objc_assign_weak(id value, id *location) 507{ return (*location = value); } 508 509 510CF_INLINE void objc_finalizeOnMainThread(Class cls) { } 511CF_INLINE BOOL objc_is_finalized(void *ptr) { return NO; } 512CF_INLINE void objc_clear_stack(unsigned long options) { } 513 514CF_INLINE BOOL objc_collectingEnabled(void) { return NO; } 515CF_INLINE void objc_start_collector_thread(void) { } 516 517CF_INLINE void objc_collect(unsigned long options) { } 518 519#endif 520 521#if DEPLOYMENT_TARGET_WINDOWS && defined(__cplusplus) 522} // extern "C" 523#endif 524