objc-os.mm 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
  1. /*
  2. * Copyright (c) 2007 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. * objc-os.m
  25. * OS portability layer.
  26. **********************************************************************/
  27. #include "objc-private.h"
  28. #include "objc-loadmethod.h"
  29. #if TARGET_OS_WIN32
  30. #include "objc-runtime-old.h"
  31. #include "objcrt.h"
  32. const fork_unsafe_lock_t fork_unsafe_lock;
  33. int monitor_init(monitor_t *c)
  34. {
  35. // fixme error checking
  36. HANDLE mutex = CreateMutex(NULL, TRUE, NULL);
  37. while (!c->mutex) {
  38. // fixme memory barrier here?
  39. if (0 == InterlockedCompareExchangePointer(&c->mutex, mutex, 0)) {
  40. // we win - finish construction
  41. c->waiters = CreateSemaphore(NULL, 0, 0x7fffffff, NULL);
  42. c->waitersDone = CreateEvent(NULL, FALSE, FALSE, NULL);
  43. InitializeCriticalSection(&c->waitCountLock);
  44. c->waitCount = 0;
  45. c->didBroadcast = 0;
  46. ReleaseMutex(c->mutex);
  47. return 0;
  48. }
  49. }
  50. // someone else allocated the mutex and constructed the monitor
  51. ReleaseMutex(mutex);
  52. CloseHandle(mutex);
  53. return 0;
  54. }
  55. void mutex_init(mutex_t *m)
  56. {
  57. while (!m->lock) {
  58. CRITICAL_SECTION *newlock = malloc(sizeof(CRITICAL_SECTION));
  59. InitializeCriticalSection(newlock);
  60. // fixme memory barrier here?
  61. if (0 == InterlockedCompareExchangePointer(&m->lock, newlock, 0)) {
  62. return;
  63. }
  64. // someone else installed their lock first
  65. DeleteCriticalSection(newlock);
  66. free(newlock);
  67. }
  68. }
  69. void recursive_mutex_init(recursive_mutex_t *m)
  70. {
  71. // fixme error checking
  72. HANDLE newmutex = CreateMutex(NULL, FALSE, NULL);
  73. while (!m->mutex) {
  74. // fixme memory barrier here?
  75. if (0 == InterlockedCompareExchangePointer(&m->mutex, newmutex, 0)) {
  76. // we win
  77. return;
  78. }
  79. }
  80. // someone else installed their lock first
  81. CloseHandle(newmutex);
  82. }
  83. WINBOOL APIENTRY DllMain( HMODULE hModule,
  84. DWORD ul_reason_for_call,
  85. LPVOID lpReserved
  86. )
  87. {
  88. switch (ul_reason_for_call) {
  89. case DLL_PROCESS_ATTACH:
  90. environ_init();
  91. tls_init();
  92. lock_init();
  93. sel_init(3500); // old selector heuristic
  94. exception_init();
  95. break;
  96. case DLL_THREAD_ATTACH:
  97. break;
  98. case DLL_THREAD_DETACH:
  99. case DLL_PROCESS_DETACH:
  100. break;
  101. }
  102. return TRUE;
  103. }
  104. OBJC_EXPORT void *_objc_init_image(HMODULE image, const objc_sections *sects)
  105. {
  106. header_info *hi = malloc(sizeof(header_info));
  107. size_t count, i;
  108. hi->mhdr = (const headerType *)image;
  109. hi->info = sects->iiStart;
  110. hi->allClassesRealized = NO;
  111. hi->modules = sects->modStart ? (Module *)((void **)sects->modStart+1) : 0;
  112. hi->moduleCount = (Module *)sects->modEnd - hi->modules;
  113. hi->protocols = sects->protoStart ? (struct old_protocol **)((void **)sects->protoStart+1) : 0;
  114. hi->protocolCount = (struct old_protocol **)sects->protoEnd - hi->protocols;
  115. hi->imageinfo = NULL;
  116. hi->imageinfoBytes = 0;
  117. // hi->imageinfo = sects->iiStart ? (uint8_t *)((void **)sects->iiStart+1) : 0;;
  118. // hi->imageinfoBytes = (uint8_t *)sects->iiEnd - hi->imageinfo;
  119. hi->selrefs = sects->selrefsStart ? (SEL *)((void **)sects->selrefsStart+1) : 0;
  120. hi->selrefCount = (SEL *)sects->selrefsEnd - hi->selrefs;
  121. hi->clsrefs = sects->clsrefsStart ? (Class *)((void **)sects->clsrefsStart+1) : 0;
  122. hi->clsrefCount = (Class *)sects->clsrefsEnd - hi->clsrefs;
  123. count = 0;
  124. for (i = 0; i < hi->moduleCount; i++) {
  125. if (hi->modules[i]) count++;
  126. }
  127. hi->mod_count = 0;
  128. hi->mod_ptr = 0;
  129. if (count > 0) {
  130. hi->mod_ptr = malloc(count * sizeof(struct objc_module));
  131. for (i = 0; i < hi->moduleCount; i++) {
  132. if (hi->modules[i]) memcpy(&hi->mod_ptr[hi->mod_count++], hi->modules[i], sizeof(struct objc_module));
  133. }
  134. }
  135. hi->moduleName = malloc(MAX_PATH * sizeof(TCHAR));
  136. GetModuleFileName((HMODULE)(hi->mhdr), hi->moduleName, MAX_PATH * sizeof(TCHAR));
  137. appendHeader(hi);
  138. if (PrintImages) {
  139. _objc_inform("IMAGES: loading image for %s%s%s%s\n",
  140. hi->fname,
  141. headerIsBundle(hi) ? " (bundle)" : "",
  142. hi->info->isReplacement() ? " (replacement)":"",
  143. hi->info->hasCategoryClassProperties() ? " (has class properties)":"");
  144. }
  145. // Count classes. Size various table based on the total.
  146. int total = 0;
  147. int unoptimizedTotal = 0;
  148. {
  149. if (_getObjc2ClassList(hi, &count)) {
  150. total += (int)count;
  151. if (!hi->getInSharedCache()) unoptimizedTotal += count;
  152. }
  153. }
  154. _read_images(&hi, 1, total, unoptimizedTotal);
  155. return hi;
  156. }
  157. OBJC_EXPORT void _objc_load_image(HMODULE image, header_info *hinfo)
  158. {
  159. prepare_load_methods(hinfo);
  160. call_load_methods();
  161. }
  162. OBJC_EXPORT void _objc_unload_image(HMODULE image, header_info *hinfo)
  163. {
  164. _objc_fatal("image unload not supported");
  165. }
  166. // TARGET_OS_WIN32
  167. #elif TARGET_OS_MAC
  168. #include "objc-file-old.h"
  169. #include "objc-file.h"
  170. /***********************************************************************
  171. * libobjc must never run static destructors.
  172. * Cover libc's __cxa_atexit with our own definition that runs nothing.
  173. * rdar://21734598 ER: Compiler option to suppress C++ static destructors
  174. **********************************************************************/
  175. extern "C" int __cxa_atexit();
  176. extern "C" int __cxa_atexit() { return 0; }
  177. /***********************************************************************
  178. * bad_magic.
  179. * Return YES if the header has invalid Mach-o magic.
  180. **********************************************************************/
  181. bool bad_magic(const headerType *mhdr)
  182. {
  183. return (mhdr->magic != MH_MAGIC && mhdr->magic != MH_MAGIC_64 &&
  184. mhdr->magic != MH_CIGAM && mhdr->magic != MH_CIGAM_64);
  185. }
  186. static header_info * addHeader(const headerType *mhdr, const char *path, int &totalClasses, int &unoptimizedTotalClasses)
  187. {
  188. header_info *hi;
  189. if (bad_magic(mhdr)) return NULL;
  190. bool inSharedCache = false;
  191. // Look for hinfo from the dyld shared cache.
  192. hi = preoptimizedHinfoForHeader(mhdr);
  193. if (hi) {
  194. // Found an hinfo in the dyld shared cache.
  195. // Weed out duplicates.
  196. if (hi->isLoaded()) {
  197. return NULL;
  198. }
  199. inSharedCache = true;
  200. // Initialize fields not set by the shared cache
  201. // hi->next is set by appendHeader
  202. hi->setLoaded(true);
  203. if (PrintPreopt) {
  204. _objc_inform("PREOPTIMIZATION: honoring preoptimized header info at %p for %s", hi, hi->fname());
  205. }
  206. #if !__OBJC2__
  207. _objc_fatal("shouldn't be here");
  208. #endif
  209. #if DEBUG
  210. // Verify image_info
  211. size_t info_size = 0;
  212. const objc_image_info *image_info = _getObjcImageInfo(mhdr,&info_size);
  213. assert(image_info == hi->info());
  214. #endif
  215. }
  216. else
  217. {
  218. // Didn't find an hinfo in the dyld shared cache.
  219. // Weed out duplicates
  220. for (hi = FirstHeader; hi; hi = hi->getNext()) {
  221. if (mhdr == hi->mhdr()) return NULL;
  222. }
  223. // Locate the __OBJC segment
  224. size_t info_size = 0;
  225. unsigned long seg_size;
  226. const objc_image_info *image_info = _getObjcImageInfo(mhdr,&info_size);
  227. const uint8_t *objc_segment = getsegmentdata(mhdr,SEG_OBJC,&seg_size);
  228. if (!objc_segment && !image_info) return NULL;
  229. // Allocate a header_info entry.
  230. // Note we also allocate space for a single header_info_rw in the
  231. // rw_data[] inside header_info.
  232. hi = (header_info *)calloc(sizeof(header_info) + sizeof(header_info_rw), 1);
  233. // Set up the new header_info entry.
  234. hi->setmhdr(mhdr);
  235. #if !__OBJC2__
  236. // mhdr must already be set
  237. hi->mod_count = 0;
  238. hi->mod_ptr = _getObjcModules(hi, &hi->mod_count);
  239. #endif
  240. // Install a placeholder image_info if absent to simplify code elsewhere
  241. static const objc_image_info emptyInfo = {0, 0};
  242. hi->setinfo(image_info ?: &emptyInfo);
  243. hi->setLoaded(true);
  244. hi->setAllClassesRealized(NO);
  245. }
  246. #if __OBJC2__
  247. {
  248. size_t count = 0;
  249. if (_getObjc2ClassList(hi, &count)) {
  250. totalClasses += (int)count;
  251. if (!inSharedCache) unoptimizedTotalClasses += count;
  252. }
  253. }
  254. #endif
  255. appendHeader(hi);
  256. return hi;
  257. }
  258. /***********************************************************************
  259. * linksToLibrary
  260. * Returns true if the image links directly to a dylib whose install name
  261. * is exactly the given name.
  262. **********************************************************************/
  263. bool
  264. linksToLibrary(const header_info *hi, const char *name)
  265. {
  266. const struct dylib_command *cmd;
  267. unsigned long i;
  268. cmd = (const struct dylib_command *) (hi->mhdr() + 1);
  269. for (i = 0; i < hi->mhdr()->ncmds; i++) {
  270. if (cmd->cmd == LC_LOAD_DYLIB || cmd->cmd == LC_LOAD_UPWARD_DYLIB ||
  271. cmd->cmd == LC_LOAD_WEAK_DYLIB || cmd->cmd == LC_REEXPORT_DYLIB)
  272. {
  273. const char *dylib = cmd->dylib.name.offset + (const char *)cmd;
  274. if (0 == strcmp(dylib, name)) return true;
  275. }
  276. cmd = (const struct dylib_command *)((char *)cmd + cmd->cmdsize);
  277. }
  278. return false;
  279. }
  280. #if SUPPORT_GC_COMPAT
  281. /***********************************************************************
  282. * shouldRejectGCApp
  283. * Return YES if the executable requires GC.
  284. **********************************************************************/
  285. static bool shouldRejectGCApp(const header_info *hi)
  286. {
  287. assert(hi->mhdr()->filetype == MH_EXECUTE);
  288. if (!hi->info()->supportsGC()) {
  289. // App does not use GC. Don't reject it.
  290. return NO;
  291. }
  292. // Exception: Trivial AppleScriptObjC apps can run without GC.
  293. // 1. executable defines no classes
  294. // 2. executable references NSBundle only
  295. // 3. executable links to AppleScriptObjC.framework
  296. // Note that objc_appRequiresGC() also knows about this.
  297. size_t classcount = 0;
  298. size_t refcount = 0;
  299. #if __OBJC2__
  300. _getObjc2ClassList(hi, &classcount);
  301. _getObjc2ClassRefs(hi, &refcount);
  302. #else
  303. if (hi->mod_count == 0 || (hi->mod_count == 1 && !hi->mod_ptr[0].symtab)) classcount = 0;
  304. else classcount = 1;
  305. _getObjcClassRefs(hi, &refcount);
  306. #endif
  307. if (classcount == 0 && refcount == 1 &&
  308. linksToLibrary(hi, "/System/Library/Frameworks"
  309. "/AppleScriptObjC.framework/Versions/A"
  310. "/AppleScriptObjC"))
  311. {
  312. // It's AppleScriptObjC. Don't reject it.
  313. return NO;
  314. }
  315. else {
  316. // GC and not trivial AppleScriptObjC. Reject it.
  317. return YES;
  318. }
  319. }
  320. /***********************************************************************
  321. * rejectGCImage
  322. * Halt if an image requires GC.
  323. * Testing of the main executable should use rejectGCApp() instead.
  324. **********************************************************************/
  325. static bool shouldRejectGCImage(const headerType *mhdr)
  326. {
  327. assert(mhdr->filetype != MH_EXECUTE);
  328. objc_image_info *image_info;
  329. size_t size;
  330. #if !__OBJC2__
  331. unsigned long seg_size;
  332. // 32-bit: __OBJC seg but no image_info means no GC support
  333. if (!getsegmentdata(mhdr, "__OBJC", &seg_size)) {
  334. // Not objc, therefore not GC. Don't reject it.
  335. return NO;
  336. }
  337. image_info = _getObjcImageInfo(mhdr, &size);
  338. if (!image_info) {
  339. // No image_info, therefore not GC. Don't reject it.
  340. return NO;
  341. }
  342. #else
  343. // 64-bit: no image_info means no objc at all
  344. image_info = _getObjcImageInfo(mhdr, &size);
  345. if (!image_info) {
  346. // Not objc, therefore not GC. Don't reject it.
  347. return NO;
  348. }
  349. #endif
  350. return image_info->requiresGC();
  351. }
  352. // SUPPORT_GC_COMPAT
  353. #endif
  354. /***********************************************************************
  355. * map_images_nolock
  356. * Process the given images which are being mapped in by dyld.
  357. * All class registration and fixups are performed (or deferred pending
  358. * discovery of missing superclasses etc), and +load methods are called.
  359. *
  360. * info[] is in bottom-up order i.e. libobjc will be earlier in the
  361. * array than any library that links to libobjc.
  362. *
  363. * Locking: loadMethodLock(old) or runtimeLock(new) acquired by map_images.
  364. **********************************************************************/
  365. #if __OBJC2__
  366. #include "objc-file.h"
  367. #else
  368. #include "objc-file-old.h"
  369. #endif
  370. void
  371. map_images_nolock(unsigned mhCount, const char * const mhPaths[],
  372. const struct mach_header * const mhdrs[])
  373. {
  374. static bool firstTime = YES;
  375. header_info *hList[mhCount];
  376. uint32_t hCount;
  377. size_t selrefCount = 0;
  378. // Perform first-time initialization if necessary.
  379. // This function is called before ordinary library initializers.
  380. // fixme defer initialization until an objc-using image is found?
  381. if (firstTime) {
  382. preopt_init();
  383. }
  384. if (PrintImages) {
  385. _objc_inform("IMAGES: processing %u newly-mapped images...\n", mhCount);
  386. }
  387. // Find all images with Objective-C metadata.
  388. hCount = 0;
  389. // Count classes. Size various table based on the total.
  390. int totalClasses = 0;
  391. int unoptimizedTotalClasses = 0;
  392. {
  393. uint32_t i = mhCount;
  394. while (i--) {
  395. const headerType *mhdr = (const headerType *)mhdrs[i];
  396. auto hi = addHeader(mhdr, mhPaths[i], totalClasses, unoptimizedTotalClasses);
  397. if (!hi) {
  398. // no objc data in this entry
  399. continue;
  400. }
  401. if (mhdr->filetype == MH_EXECUTE) {
  402. // Size some data structures based on main executable's size
  403. #if __OBJC2__
  404. size_t count;
  405. _getObjc2SelectorRefs(hi, &count);
  406. selrefCount += count;
  407. _getObjc2MessageRefs(hi, &count);
  408. selrefCount += count;
  409. #else
  410. _getObjcSelectorRefs(hi, &selrefCount);
  411. #endif
  412. #if SUPPORT_GC_COMPAT
  413. // Halt if this is a GC app.
  414. if (shouldRejectGCApp(hi)) {
  415. _objc_fatal_with_reason
  416. (OBJC_EXIT_REASON_GC_NOT_SUPPORTED,
  417. OS_REASON_FLAG_CONSISTENT_FAILURE,
  418. "Objective-C garbage collection "
  419. "is no longer supported.");
  420. }
  421. #endif
  422. }
  423. hList[hCount++] = hi;
  424. if (PrintImages) {
  425. _objc_inform("IMAGES: loading image for %s%s%s%s%s\n",
  426. hi->fname(),
  427. mhdr->filetype == MH_BUNDLE ? " (bundle)" : "",
  428. hi->info()->isReplacement() ? " (replacement)" : "",
  429. hi->info()->hasCategoryClassProperties() ? " (has class properties)" : "",
  430. hi->info()->optimizedByDyld()?" (preoptimized)":"");
  431. }
  432. }
  433. }
  434. // Perform one-time runtime initialization that must be deferred until
  435. // the executable itself is found. This needs to be done before
  436. // further initialization.
  437. // (The executable may not be present in this infoList if the
  438. // executable does not contain Objective-C code but Objective-C
  439. // is dynamically loaded later.
  440. if (firstTime) {
  441. sel_init(selrefCount);
  442. arr_init();
  443. #if SUPPORT_GC_COMPAT
  444. // Reject any GC images linked to the main executable.
  445. // We already rejected the app itself above.
  446. // Images loaded after launch will be rejected by dyld.
  447. for (uint32_t i = 0; i < hCount; i++) {
  448. auto hi = hList[i];
  449. auto mh = hi->mhdr();
  450. if (mh->filetype != MH_EXECUTE && shouldRejectGCImage(mh)) {
  451. _objc_fatal_with_reason
  452. (OBJC_EXIT_REASON_GC_NOT_SUPPORTED,
  453. OS_REASON_FLAG_CONSISTENT_FAILURE,
  454. "%s requires Objective-C garbage collection "
  455. "which is no longer supported.", hi->fname());
  456. }
  457. }
  458. #endif
  459. #if TARGET_OS_OSX
  460. // Disable +initialize fork safety if the app is too old (< 10.13).
  461. // Disable +initialize fork safety if the app has a
  462. // __DATA,__objc_fork_ok section.
  463. if (dyld_get_program_sdk_version() < DYLD_MACOSX_VERSION_10_13) {
  464. DisableInitializeForkSafety = true;
  465. if (PrintInitializing) {
  466. _objc_inform("INITIALIZE: disabling +initialize fork "
  467. "safety enforcement because the app is "
  468. "too old (SDK version " SDK_FORMAT ")",
  469. FORMAT_SDK(dyld_get_program_sdk_version()));
  470. }
  471. }
  472. for (uint32_t i = 0; i < hCount; i++) {
  473. auto hi = hList[i];
  474. auto mh = hi->mhdr();
  475. if (mh->filetype != MH_EXECUTE) continue;
  476. unsigned long size;
  477. if (getsectiondata(hi->mhdr(), "__DATA", "__objc_fork_ok", &size)) {
  478. DisableInitializeForkSafety = true;
  479. if (PrintInitializing) {
  480. _objc_inform("INITIALIZE: disabling +initialize fork "
  481. "safety enforcement because the app has "
  482. "a __DATA,__objc_fork_ok section");
  483. }
  484. }
  485. break; // assume only one MH_EXECUTE image
  486. }
  487. #endif
  488. }
  489. if (hCount > 0) {
  490. _read_images(hList, hCount, totalClasses, unoptimizedTotalClasses);
  491. }
  492. firstTime = NO;
  493. }
  494. /***********************************************************************
  495. * unmap_image_nolock
  496. * Process the given image which is about to be unmapped by dyld.
  497. * mh is mach_header instead of headerType because that's what
  498. * dyld_priv.h says even for 64-bit.
  499. *
  500. * Locking: loadMethodLock(both) and runtimeLock(new) acquired by unmap_image.
  501. **********************************************************************/
  502. void
  503. unmap_image_nolock(const struct mach_header *mh)
  504. {
  505. if (PrintImages) {
  506. _objc_inform("IMAGES: processing 1 newly-unmapped image...\n");
  507. }
  508. header_info *hi;
  509. // Find the runtime's header_info struct for the image
  510. for (hi = FirstHeader; hi != NULL; hi = hi->getNext()) {
  511. if (hi->mhdr() == (const headerType *)mh) {
  512. break;
  513. }
  514. }
  515. if (!hi) return;
  516. if (PrintImages) {
  517. _objc_inform("IMAGES: unloading image for %s%s%s\n",
  518. hi->fname(),
  519. hi->mhdr()->filetype == MH_BUNDLE ? " (bundle)" : "",
  520. hi->info()->isReplacement() ? " (replacement)" : "");
  521. }
  522. _unload_image(hi);
  523. // Remove header_info from header list
  524. removeHeader(hi);
  525. free(hi);
  526. }
  527. /***********************************************************************
  528. * static_init
  529. * Run C++ static constructor functions.
  530. * libc calls _objc_init() before dyld would call our static constructors,
  531. * so we have to do it ourselves.
  532. **********************************************************************/
  533. static void static_init()
  534. {
  535. size_t count;
  536. auto inits = getLibobjcInitializers(&_mh_dylib_header, &count);
  537. for (size_t i = 0; i < count; i++) {
  538. inits[i]();
  539. }
  540. }
  541. /***********************************************************************
  542. * _objc_atfork_prepare
  543. * _objc_atfork_parent
  544. * _objc_atfork_child
  545. * Allow ObjC to be used between fork() and exec().
  546. * libc requires this because it has fork-safe functions that use os_objects.
  547. *
  548. * _objc_atfork_prepare() acquires all locks.
  549. * _objc_atfork_parent() releases the locks again.
  550. * _objc_atfork_child() forcibly resets the locks.
  551. **********************************************************************/
  552. // Declare lock ordering.
  553. #if LOCKDEBUG
  554. __attribute__((constructor))
  555. static void defineLockOrder()
  556. {
  557. // Every lock precedes crashlog_lock
  558. // on the assumption that fatal errors could be anywhere.
  559. lockdebug_lock_precedes_lock(&loadMethodLock, &crashlog_lock);
  560. lockdebug_lock_precedes_lock(&classInitLock, &crashlog_lock);
  561. #if __OBJC2__
  562. lockdebug_lock_precedes_lock(&runtimeLock, &crashlog_lock);
  563. lockdebug_lock_precedes_lock(&DemangleCacheLock, &crashlog_lock);
  564. #else
  565. lockdebug_lock_precedes_lock(&classLock, &crashlog_lock);
  566. lockdebug_lock_precedes_lock(&methodListLock, &crashlog_lock);
  567. lockdebug_lock_precedes_lock(&NXUniqueStringLock, &crashlog_lock);
  568. lockdebug_lock_precedes_lock(&impLock, &crashlog_lock);
  569. #endif
  570. lockdebug_lock_precedes_lock(&selLock, &crashlog_lock);
  571. lockdebug_lock_precedes_lock(&cacheUpdateLock, &crashlog_lock);
  572. lockdebug_lock_precedes_lock(&objcMsgLogLock, &crashlog_lock);
  573. lockdebug_lock_precedes_lock(&AltHandlerDebugLock, &crashlog_lock);
  574. lockdebug_lock_precedes_lock(&AssociationsManagerLock, &crashlog_lock);
  575. SideTableLocksPrecedeLock(&crashlog_lock);
  576. PropertyLocks.precedeLock(&crashlog_lock);
  577. StructLocks.precedeLock(&crashlog_lock);
  578. CppObjectLocks.precedeLock(&crashlog_lock);
  579. // loadMethodLock precedes everything
  580. // because it is held while +load methods run
  581. lockdebug_lock_precedes_lock(&loadMethodLock, &classInitLock);
  582. #if __OBJC2__
  583. lockdebug_lock_precedes_lock(&loadMethodLock, &runtimeLock);
  584. lockdebug_lock_precedes_lock(&loadMethodLock, &DemangleCacheLock);
  585. #else
  586. lockdebug_lock_precedes_lock(&loadMethodLock, &methodListLock);
  587. lockdebug_lock_precedes_lock(&loadMethodLock, &classLock);
  588. lockdebug_lock_precedes_lock(&loadMethodLock, &NXUniqueStringLock);
  589. lockdebug_lock_precedes_lock(&loadMethodLock, &impLock);
  590. #endif
  591. lockdebug_lock_precedes_lock(&loadMethodLock, &selLock);
  592. lockdebug_lock_precedes_lock(&loadMethodLock, &cacheUpdateLock);
  593. lockdebug_lock_precedes_lock(&loadMethodLock, &objcMsgLogLock);
  594. lockdebug_lock_precedes_lock(&loadMethodLock, &AltHandlerDebugLock);
  595. lockdebug_lock_precedes_lock(&loadMethodLock, &AssociationsManagerLock);
  596. SideTableLocksSucceedLock(&loadMethodLock);
  597. PropertyLocks.succeedLock(&loadMethodLock);
  598. StructLocks.succeedLock(&loadMethodLock);
  599. CppObjectLocks.succeedLock(&loadMethodLock);
  600. // PropertyLocks and CppObjectLocks and AssociationManagerLock
  601. // precede everything because they are held while objc_retain()
  602. // or C++ copy are called.
  603. // (StructLocks do not precede everything because it calls memmove only.)
  604. auto PropertyAndCppObjectAndAssocLocksPrecedeLock = [&](const void *lock) {
  605. PropertyLocks.precedeLock(lock);
  606. CppObjectLocks.precedeLock(lock);
  607. lockdebug_lock_precedes_lock(&AssociationsManagerLock, lock);
  608. };
  609. #if __OBJC2__
  610. PropertyAndCppObjectAndAssocLocksPrecedeLock(&runtimeLock);
  611. PropertyAndCppObjectAndAssocLocksPrecedeLock(&DemangleCacheLock);
  612. #else
  613. PropertyAndCppObjectAndAssocLocksPrecedeLock(&methodListLock);
  614. PropertyAndCppObjectAndAssocLocksPrecedeLock(&classLock);
  615. PropertyAndCppObjectAndAssocLocksPrecedeLock(&NXUniqueStringLock);
  616. PropertyAndCppObjectAndAssocLocksPrecedeLock(&impLock);
  617. #endif
  618. PropertyAndCppObjectAndAssocLocksPrecedeLock(&classInitLock);
  619. PropertyAndCppObjectAndAssocLocksPrecedeLock(&selLock);
  620. PropertyAndCppObjectAndAssocLocksPrecedeLock(&cacheUpdateLock);
  621. PropertyAndCppObjectAndAssocLocksPrecedeLock(&objcMsgLogLock);
  622. PropertyAndCppObjectAndAssocLocksPrecedeLock(&AltHandlerDebugLock);
  623. SideTableLocksSucceedLocks(PropertyLocks);
  624. SideTableLocksSucceedLocks(CppObjectLocks);
  625. SideTableLocksSucceedLock(&AssociationsManagerLock);
  626. PropertyLocks.precedeLock(&AssociationsManagerLock);
  627. CppObjectLocks.precedeLock(&AssociationsManagerLock);
  628. #if __OBJC2__
  629. lockdebug_lock_precedes_lock(&classInitLock, &runtimeLock);
  630. #endif
  631. #if __OBJC2__
  632. // Runtime operations may occur inside SideTable locks
  633. // (such as storeWeak calling getMethodImplementation)
  634. SideTableLocksPrecedeLock(&runtimeLock);
  635. SideTableLocksPrecedeLock(&classInitLock);
  636. // Some operations may occur inside runtimeLock.
  637. lockdebug_lock_precedes_lock(&runtimeLock, &selLock);
  638. lockdebug_lock_precedes_lock(&runtimeLock, &cacheUpdateLock);
  639. lockdebug_lock_precedes_lock(&runtimeLock, &DemangleCacheLock);
  640. #else
  641. // Runtime operations may occur inside SideTable locks
  642. // (such as storeWeak calling getMethodImplementation)
  643. SideTableLocksPrecedeLock(&methodListLock);
  644. SideTableLocksPrecedeLock(&classInitLock);
  645. // Method lookup and fixup.
  646. lockdebug_lock_precedes_lock(&methodListLock, &classLock);
  647. lockdebug_lock_precedes_lock(&methodListLock, &selLock);
  648. lockdebug_lock_precedes_lock(&methodListLock, &cacheUpdateLock);
  649. lockdebug_lock_precedes_lock(&methodListLock, &impLock);
  650. lockdebug_lock_precedes_lock(&classLock, &selLock);
  651. lockdebug_lock_precedes_lock(&classLock, &cacheUpdateLock);
  652. #endif
  653. // Striped locks use address order internally.
  654. SideTableDefineLockOrder();
  655. PropertyLocks.defineLockOrder();
  656. StructLocks.defineLockOrder();
  657. CppObjectLocks.defineLockOrder();
  658. }
  659. // LOCKDEBUG
  660. #endif
  661. static bool ForkIsMultithreaded;
  662. void _objc_atfork_prepare()
  663. {
  664. // Save threaded-ness for the child's use.
  665. ForkIsMultithreaded = pthread_is_threaded_np();
  666. lockdebug_assert_no_locks_locked();
  667. lockdebug_setInForkPrepare(true);
  668. loadMethodLock.lock();
  669. PropertyLocks.lockAll();
  670. CppObjectLocks.lockAll();
  671. AssociationsManagerLock.lock();
  672. SideTableLockAll();
  673. classInitLock.enter();
  674. #if __OBJC2__
  675. runtimeLock.lock();
  676. DemangleCacheLock.lock();
  677. #else
  678. methodListLock.lock();
  679. classLock.lock();
  680. NXUniqueStringLock.lock();
  681. impLock.lock();
  682. #endif
  683. selLock.lock();
  684. cacheUpdateLock.lock();
  685. objcMsgLogLock.lock();
  686. AltHandlerDebugLock.lock();
  687. StructLocks.lockAll();
  688. crashlog_lock.lock();
  689. lockdebug_assert_all_locks_locked();
  690. lockdebug_setInForkPrepare(false);
  691. }
  692. void _objc_atfork_parent()
  693. {
  694. lockdebug_assert_all_locks_locked();
  695. CppObjectLocks.unlockAll();
  696. StructLocks.unlockAll();
  697. PropertyLocks.unlockAll();
  698. AssociationsManagerLock.unlock();
  699. AltHandlerDebugLock.unlock();
  700. objcMsgLogLock.unlock();
  701. crashlog_lock.unlock();
  702. loadMethodLock.unlock();
  703. cacheUpdateLock.unlock();
  704. selLock.unlock();
  705. SideTableUnlockAll();
  706. #if __OBJC2__
  707. DemangleCacheLock.unlock();
  708. runtimeLock.unlock();
  709. #else
  710. impLock.unlock();
  711. NXUniqueStringLock.unlock();
  712. methodListLock.unlock();
  713. classLock.unlock();
  714. #endif
  715. classInitLock.leave();
  716. lockdebug_assert_no_locks_locked();
  717. }
  718. void _objc_atfork_child()
  719. {
  720. // Turn on +initialize fork safety enforcement if applicable.
  721. if (ForkIsMultithreaded && !DisableInitializeForkSafety) {
  722. MultithreadedForkChild = true;
  723. }
  724. lockdebug_assert_all_locks_locked();
  725. CppObjectLocks.forceResetAll();
  726. StructLocks.forceResetAll();
  727. PropertyLocks.forceResetAll();
  728. AssociationsManagerLock.forceReset();
  729. AltHandlerDebugLock.forceReset();
  730. objcMsgLogLock.forceReset();
  731. crashlog_lock.forceReset();
  732. loadMethodLock.forceReset();
  733. cacheUpdateLock.forceReset();
  734. selLock.forceReset();
  735. SideTableForceResetAll();
  736. #if __OBJC2__
  737. DemangleCacheLock.forceReset();
  738. runtimeLock.forceReset();
  739. #else
  740. impLock.forceReset();
  741. NXUniqueStringLock.forceReset();
  742. methodListLock.forceReset();
  743. classLock.forceReset();
  744. #endif
  745. classInitLock.forceReset();
  746. lockdebug_assert_no_locks_locked();
  747. }
  748. /***********************************************************************
  749. * _objc_init
  750. * Bootstrap initialization. Registers our image notifier with dyld.
  751. * Called by libSystem BEFORE library initialization time
  752. **********************************************************************/
  753. void _objc_init(void)
  754. {
  755. static bool initialized = false;
  756. if (initialized) return;
  757. initialized = true;
  758. // fixme defer initialization until an objc-using image is found?
  759. environ_init();
  760. tls_init();
  761. static_init();
  762. lock_init();
  763. exception_init();
  764. _dyld_objc_notify_register(&map_images, load_images, unmap_image);
  765. }
  766. /***********************************************************************
  767. * _headerForAddress.
  768. * addr can be a class or a category
  769. **********************************************************************/
  770. static const header_info *_headerForAddress(void *addr)
  771. {
  772. #if __OBJC2__
  773. const char *segnames[] = { "__DATA", "__DATA_CONST", "__DATA_DIRTY" };
  774. #else
  775. const char *segnames[] = { "__OBJC" };
  776. #endif
  777. header_info *hi;
  778. for (hi = FirstHeader; hi != NULL; hi = hi->getNext()) {
  779. for (size_t i = 0; i < sizeof(segnames)/sizeof(segnames[0]); i++) {
  780. unsigned long seg_size;
  781. uint8_t *seg = getsegmentdata(hi->mhdr(), segnames[i], &seg_size);
  782. if (!seg) continue;
  783. // Is the class in this header?
  784. if ((uint8_t *)addr >= seg && (uint8_t *)addr < seg + seg_size) {
  785. return hi;
  786. }
  787. }
  788. }
  789. // Not found
  790. return 0;
  791. }
  792. /***********************************************************************
  793. * _headerForClass
  794. * Return the image header containing this class, or NULL.
  795. * Returns NULL on runtime-constructed classes, and the NSCF classes.
  796. **********************************************************************/
  797. const header_info *_headerForClass(Class cls)
  798. {
  799. return _headerForAddress(cls);
  800. }
  801. /**********************************************************************
  802. * secure_open
  803. * Securely open a file from a world-writable directory (like /tmp)
  804. * If the file does not exist, it will be atomically created with mode 0600
  805. * If the file exists, it must be, and remain after opening:
  806. * 1. a regular file (in particular, not a symlink)
  807. * 2. owned by euid
  808. * 3. permissions 0600
  809. * 4. link count == 1
  810. * Returns a file descriptor or -1. Errno may or may not be set on error.
  811. **********************************************************************/
  812. int secure_open(const char *filename, int flags, uid_t euid)
  813. {
  814. struct stat fs, ls;
  815. int fd = -1;
  816. bool truncate = NO;
  817. bool create = NO;
  818. if (flags & O_TRUNC) {
  819. // Don't truncate the file until after it is open and verified.
  820. truncate = YES;
  821. flags &= ~O_TRUNC;
  822. }
  823. if (flags & O_CREAT) {
  824. // Don't create except when we're ready for it
  825. create = YES;
  826. flags &= ~O_CREAT;
  827. flags &= ~O_EXCL;
  828. }
  829. if (lstat(filename, &ls) < 0) {
  830. if (errno == ENOENT && create) {
  831. // No such file - create it
  832. fd = open(filename, flags | O_CREAT | O_EXCL, 0600);
  833. if (fd >= 0) {
  834. // File was created successfully.
  835. // New file does not need to be truncated.
  836. return fd;
  837. } else {
  838. // File creation failed.
  839. return -1;
  840. }
  841. } else {
  842. // lstat failed, or user doesn't want to create the file
  843. return -1;
  844. }
  845. } else {
  846. // lstat succeeded - verify attributes and open
  847. if (S_ISREG(ls.st_mode) && // regular file?
  848. ls.st_nlink == 1 && // link count == 1?
  849. ls.st_uid == euid && // owned by euid?
  850. (ls.st_mode & ALLPERMS) == (S_IRUSR | S_IWUSR)) // mode 0600?
  851. {
  852. // Attributes look ok - open it and check attributes again
  853. fd = open(filename, flags, 0000);
  854. if (fd >= 0) {
  855. // File is open - double-check attributes
  856. if (0 == fstat(fd, &fs) &&
  857. fs.st_nlink == ls.st_nlink && // link count == 1?
  858. fs.st_uid == ls.st_uid && // owned by euid?
  859. fs.st_mode == ls.st_mode && // regular file, 0600?
  860. fs.st_ino == ls.st_ino && // same inode as before?
  861. fs.st_dev == ls.st_dev) // same device as before?
  862. {
  863. // File is open and OK
  864. if (truncate) ftruncate(fd, 0);
  865. return fd;
  866. } else {
  867. // Opened file looks funny - close it
  868. close(fd);
  869. return -1;
  870. }
  871. } else {
  872. // File didn't open
  873. return -1;
  874. }
  875. } else {
  876. // Unopened file looks funny - don't open it
  877. return -1;
  878. }
  879. }
  880. }
  881. #if TARGET_OS_IPHONE
  882. const char *__crashreporter_info__ = NULL;
  883. const char *CRSetCrashLogMessage(const char *msg)
  884. {
  885. __crashreporter_info__ = msg;
  886. return msg;
  887. }
  888. const char *CRGetCrashLogMessage(void)
  889. {
  890. return __crashreporter_info__;
  891. }
  892. #endif
  893. // TARGET_OS_MAC
  894. #else
  895. #error unknown OS
  896. #endif