objc-os.mm 34 KB

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