]> git.saurik.com Git - apple/dyld.git/blame - src/dyldAPIs.cpp
dyld-360.22.tar.gz
[apple/dyld.git] / src / dyldAPIs.cpp
CommitLineData
0959b6d4
A
1/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
39a8cd10 3 * Copyright (c) 2004-2009 Apple Inc. All rights reserved.
0959b6d4
A
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25//
26// This file implements that API's in <mach-o/dyld.h>
27//
28//
29
bac542e6 30#define __STDC_LIMIT_MACROS
0959b6d4 31#include <stddef.h>
bac542e6 32#include <stdint.h>
0959b6d4 33#include <string.h>
bac542e6
A
34#include <sys/param.h>
35#include <sys/mount.h>
39a8cd10 36#include <Availability.h>
bac542e6
A
37
38
39#include <vector>
40#include <map>
41#include <algorithm>
42
0959b6d4
A
43#include <mach/mach.h>
44#include <sys/time.h>
a3afc008 45#include <sys/sysctl.h>
39a8cd10 46#include <mach/mach_traps.h> // for task_self_trap()
0959b6d4 47
0959b6d4 48
bac542e6 49#include "mach-o/dyld_images.h"
0959b6d4
A
50#include "mach-o/dyld.h"
51#include "mach-o/dyld_priv.h"
0959b6d4
A
52
53#include "ImageLoader.h"
54#include "dyld.h"
bac542e6
A
55#include "dyldLibSystemInterface.h"
56
57#undef _POSIX_C_SOURCE
58#include "dlfcn.h"
59
412ebb8e
A
60// from dyldExceptions.c
61extern "C" void __Unwind_SjLj_SetThreadKey(pthread_key_t key);
62
63// from dyld_gdb.cpp
64extern void addImagesToAllImages(uint32_t infoCount, const dyld_image_info info[]);
bac542e6 65
39a8cd10
A
66// deprecated APIs are still availble on Mac OS X, but not on iPhone OS
67#if __IPHONE_OS_VERSION_MIN_REQUIRED
68 #define DEPRECATED_APIS_SUPPORTED 0
69#else
70 #define DEPRECATED_APIS_SUPPORTED 1
bac542e6 71#endif
0959b6d4 72
19894a12 73static bool sDynamicInterposing = false;
39a8cd10
A
74
75#if DEPRECATED_APIS_SUPPORTED
0959b6d4
A
76static char sLastErrorFilePath[1024];
77static NSLinkEditErrors sLastErrorFileCode;
78static int sLastErrorNo;
39a8cd10 79#endif
0959b6d4
A
80
81// In 10.3.x and earlier all the NSObjectFileImage API's were implemeneted in libSystem.dylib
82// Beginning in 10.4 the NSObjectFileImage API's are implemented in dyld and libSystem just forwards
83// This conditional keeps support for old libSystem's which needed some help implementing the API's
832b6fce 84#define OLD_LIBSYSTEM_SUPPORT (__i386__)
0959b6d4
A
85
86// The following functions have no prototype in any header. They are special cases
87// where _dyld_func_lookup() is used directly.
39a8cd10
A
88static void _dyld_make_delayed_module_initializer_calls();
89static void registerThreadHelpers(const dyld::LibSystemHelpers*);
90#if DEPRECATED_APIS_SUPPORTED
0959b6d4 91static void _dyld_install_handlers(void* undefined, void* multiple, void* linkEdit);
bac542e6 92#if OLD_LIBSYSTEM_SUPPORT
0959b6d4 93static NSModule _dyld_link_module(NSObjectFileImage object_addr, size_t object_size, const char* moduleName, uint32_t options);
bac542e6 94#endif
0959b6d4 95static void _dyld_register_binding_handler(void * (*)(const char *, const char *, void *), ImageLoader::BindingOptions);
0959b6d4
A
96static bool NSMakePrivateModulePublic(NSModule module);
97static void _dyld_call_module_initializers_for_dylib(const struct mach_header* mh_dylib_header);
0959b6d4
A
98
99// The following functions are dyld API's, but since dyld links with a static copy of libc.a
100// the public name cannot be used.
101static void client_dyld_lookup_and_bind(const char* symbolName, void** address, NSModule* module);
102static bool client_NSIsSymbolNameDefined(const char* symbolName);
39a8cd10 103#endif // DEPRECATED_APIS_SUPPORTED
19894a12 104#if SUPPORT_ZERO_COST_EXCEPTIONS
39a8cd10 105static bool client_dyld_find_unwind_sections(void* addr, dyld_unwind_sections* info);
412ebb8e 106#endif
0959b6d4
A
107
108static void unimplemented()
109{
110 dyld::halt("unimplemented dyld function\n");
111}
112
113struct dyld_func {
114 const char* name;
115 void* implementation;
116};
117
118static struct dyld_func dyld_funcs[] = {
bac542e6
A
119 {"__dyld_register_func_for_add_image", (void*)_dyld_register_func_for_add_image },
120 {"__dyld_register_func_for_remove_image", (void*)_dyld_register_func_for_remove_image },
bac542e6
A
121 {"__dyld_dladdr", (void*)dladdr },
122 {"__dyld_dlclose", (void*)dlclose },
123 {"__dyld_dlerror", (void*)dlerror },
124 {"__dyld_dlopen", (void*)dlopen },
125 {"__dyld_dlsym", (void*)dlsym },
126 {"__dyld_dlopen_preflight", (void*)dlopen_preflight },
bac542e6
A
127 {"__dyld_image_count", (void*)_dyld_image_count },
128 {"__dyld_get_image_header", (void*)_dyld_get_image_header },
129 {"__dyld_get_image_vmaddr_slide", (void*)_dyld_get_image_vmaddr_slide },
130 {"__dyld_get_image_name", (void*)_dyld_get_image_name },
39a8cd10 131 {"__dyld_get_image_slide", (void*)_dyld_get_image_slide },
bac542e6 132 {"__dyld__NSGetExecutablePath", (void*)_NSGetExecutablePath },
39a8cd10
A
133
134 // SPIs
135 {"__dyld_dyld_register_image_state_change_handler", (void*)dyld_register_image_state_change_handler },
136 {"__dyld_register_thread_helpers", (void*)registerThreadHelpers },
137 {"__dyld_fork_child", (void*)_dyld_fork_child },
39a8cd10
A
138 {"__dyld_make_delayed_module_initializer_calls", (void*)_dyld_make_delayed_module_initializer_calls },
139 {"__dyld_get_all_image_infos", (void*)_dyld_get_all_image_infos },
19894a12 140#if SUPPORT_ZERO_COST_EXCEPTIONS
39a8cd10
A
141 {"__dyld_find_unwind_sections", (void*)client_dyld_find_unwind_sections },
142#endif
19894a12 143#if __i386__ || __x86_64__ || __arm__ || __arm64__
39a8cd10
A
144 {"__dyld_fast_stub_entry", (void*)dyld::fastBindLazySymbol },
145#endif
146 {"__dyld_image_path_containing_address", (void*)dyld_image_path_containing_address },
412ebb8e 147 {"__dyld_shared_cache_some_image_overridden", (void*)dyld_shared_cache_some_image_overridden },
2fd3f4e8 148 {"__dyld_process_is_restricted", (void*)dyld::processIsRestricted },
19894a12 149 {"__dyld_dynamic_interpose", (void*)dyld_dynamic_interpose },
df9d6cf7
A
150#if DYLD_SHARED_CACHE_SUPPORT
151 {"__dyld_shared_cache_file_path", (void*)dyld::getStandardSharedCacheFilePath },
152#endif
153 {"__dyld_get_image_header_containing_address", (void*)dyld_image_header_containing_address },
39a8cd10
A
154
155 // deprecated
156#if DEPRECATED_APIS_SUPPORTED
0959b6d4
A
157 {"__dyld_lookup_and_bind", (void*)client_dyld_lookup_and_bind },
158 {"__dyld_lookup_and_bind_with_hint", (void*)_dyld_lookup_and_bind_with_hint },
0959b6d4
A
159 {"__dyld_lookup_and_bind_fully", (void*)_dyld_lookup_and_bind_fully },
160 {"__dyld_install_handlers", (void*)_dyld_install_handlers },
161 {"__dyld_link_edit_error", (void*)NSLinkEditError },
0959b6d4 162 {"__dyld_unlink_module", (void*)NSUnLinkModule },
0959b6d4
A
163 {"__dyld_bind_objc_module", (void*)_dyld_bind_objc_module },
164 {"__dyld_bind_fully_image_containing_address", (void*)_dyld_bind_fully_image_containing_address },
165 {"__dyld_image_containing_address", (void*)_dyld_image_containing_address },
bac542e6 166 {"__dyld_register_binding_handler", (void*)_dyld_register_binding_handler },
0959b6d4
A
167 {"__dyld_NSNameOfSymbol", (void*)NSNameOfSymbol },
168 {"__dyld_NSAddressOfSymbol", (void*)NSAddressOfSymbol },
169 {"__dyld_NSModuleForSymbol", (void*)NSModuleForSymbol },
170 {"__dyld_NSLookupAndBindSymbol", (void*)NSLookupAndBindSymbol },
171 {"__dyld_NSLookupAndBindSymbolWithHint", (void*)NSLookupAndBindSymbolWithHint },
172 {"__dyld_NSLookupSymbolInModule", (void*)NSLookupSymbolInModule},
173 {"__dyld_NSLookupSymbolInImage", (void*)NSLookupSymbolInImage},
174 {"__dyld_NSMakePrivateModulePublic", (void*)NSMakePrivateModulePublic},
175 {"__dyld_NSIsSymbolNameDefined", (void*)client_NSIsSymbolNameDefined},
176 {"__dyld_NSIsSymbolNameDefinedWithHint", (void*)NSIsSymbolNameDefinedWithHint },
177 {"__dyld_NSIsSymbolNameDefinedInImage", (void*)NSIsSymbolNameDefinedInImage},
178 {"__dyld_NSNameOfModule", (void*)NSNameOfModule },
179 {"__dyld_NSLibraryNameForModule", (void*)NSLibraryNameForModule },
180 {"__dyld_NSAddLibrary", (void*)NSAddLibrary },
181 {"__dyld_NSAddLibraryWithSearching", (void*)NSAddLibraryWithSearching },
182 {"__dyld_NSAddImage", (void*)NSAddImage },
0959b6d4
A
183 {"__dyld_launched_prebound", (void*)_dyld_launched_prebound },
184 {"__dyld_all_twolevel_modules_prebound", (void*)_dyld_all_twolevel_modules_prebound },
185 {"__dyld_call_module_initializers_for_dylib", (void*)_dyld_call_module_initializers_for_dylib },
0959b6d4
A
186 {"__dyld_NSCreateObjectFileImageFromFile", (void*)NSCreateObjectFileImageFromFile },
187 {"__dyld_NSCreateObjectFileImageFromMemory", (void*)NSCreateObjectFileImageFromMemory },
0959b6d4
A
188 {"__dyld_NSDestroyObjectFileImage", (void*)NSDestroyObjectFileImage },
189 {"__dyld_NSLinkModule", (void*)NSLinkModule },
190 {"__dyld_NSHasModInitObjectFileImage", (void*)NSHasModInitObjectFileImage },
191 {"__dyld_NSSymbolDefinitionCountInObjectFileImage", (void*)NSSymbolDefinitionCountInObjectFileImage },
192 {"__dyld_NSSymbolDefinitionNameInObjectFileImage", (void*)NSSymbolDefinitionNameInObjectFileImage },
193 {"__dyld_NSIsSymbolDefinedInObjectFileImage", (void*)NSIsSymbolDefinedInObjectFileImage },
194 {"__dyld_NSSymbolReferenceNameInObjectFileImage", (void*)NSSymbolReferenceNameInObjectFileImage },
195 {"__dyld_NSSymbolReferenceCountInObjectFileImage", (void*)NSSymbolReferenceCountInObjectFileImage },
196 {"__dyld_NSGetSectionDataInObjectFileImage", (void*)NSGetSectionDataInObjectFileImage },
bac542e6
A
197#if OLD_LIBSYSTEM_SUPPORT
198 {"__dyld_link_module", (void*)_dyld_link_module },
199#endif
39a8cd10
A
200#endif //DEPRECATED_APIS_SUPPORTED
201
0959b6d4
A
202 {NULL, 0}
203};
204
205
206
39a8cd10
A
207#if DEPRECATED_APIS_SUPPORTED
208
209static void dyldAPIhalt(const char* apiName, const char* errorMsg)
210{
211 dyld::log("dyld: %s() error\n", apiName);
212 dyld::halt(errorMsg);
213}
214
0959b6d4
A
215// dyld's abstract type NSSymbol is implemented as const ImageLoader::Symbol*
216inline NSSymbol SymbolToNSSymbol(const ImageLoader::Symbol* sym)
217{
218 return (NSSymbol)sym;
219}
220inline const ImageLoader::Symbol* NSSymbolToSymbol(NSSymbol sym)
221{
222 return (const ImageLoader::Symbol*)sym;
223}
224
225// dyld's abstract type NSModule is implemented as ImageLoader*
bac542e6 226inline NSModule ImageLoaderToNSModule(const ImageLoader* image)
0959b6d4
A
227{
228 return (NSModule)image;
229}
230inline ImageLoader* NSModuleToImageLoader(NSModule module)
231{
232 ImageLoader* image = (ImageLoader*)module;
233 if ( dyld::validImage(image) )
234 return image;
235 return NULL;
236}
237
238// actual definition for opaque type
239struct __NSObjectFileImage
240{
241 ImageLoader* image;
242 const void* imageBaseAddress; // not used with OFI created from files
243 size_t imageLength; // not used with OFI created from files
244};
2fd3f4e8
A
245
246
247VECTOR_NEVER_DESTRUCTED(NSObjectFileImage);
0959b6d4
A
248static std::vector<NSObjectFileImage> sObjectFileImages;
249
250
251
252//
253// __NSObjectFileImage are deleted in NSDestroyObjectFileImage()
254// The contained image is delete in one of two places:
255// NSUnLinkModule deletes the image if there is no __NSObjectFileImage with a reference to it
256// NSDestroyObjectFileImage deletes the image if image is not in list of valid images
257//
258
259
0959b6d4
A
260
261static void setLastError(NSLinkEditErrors code, int errnum, const char* file, const char* message)
262{
263 dyld::setErrorMessage(message);
264 strncpy(sLastErrorFilePath, file, 1024);
265 sLastErrorFilePath[1023] = '\0';
266 sLastErrorFileCode = code;
267 sLastErrorNo = errnum;
268}
269
39a8cd10 270#endif // DEPRECATED_APIS_SUPPORTED
0959b6d4
A
271
272/*
273 *_dyld_NSGetExecutablePath is the dyld side of _NSGetExecutablePath which
274 * copies the path of the executable into the buffer and returns 0 if the path
275 * was successfully copied in the provided buffer. If the buffer is not large
276 * enough, -1 is returned and the expected buffer size is copied in *bufsize.
277 * Note that _NSGetExecutablePath will return "a path" to the executable not a
278 * "real path" to the executable. That is the path may be a symbolic link and
279 * not the real file. And with deep directories the total bufsize needed could
280 * be more than MAXPATHLEN.
281 */
282int _NSGetExecutablePath(char* buf, uint32_t *bufsize)
283{
284 if ( dyld::gLogAPIs )
bac542e6 285 dyld::log("%s(...)\n", __func__);
0959b6d4
A
286 const char* exePath = dyld::getExecutablePath();
287 if(*bufsize < strlen(exePath) + 1){
19894a12 288 *bufsize = (uint32_t)(strlen(exePath) + 1);
0959b6d4
A
289 return -1;
290 }
291 strcpy(buf, exePath);
292 return 0;
293}
294
39a8cd10
A
295uint32_t _dyld_image_count(void)
296{
297 if ( dyld::gLogAPIs )
298 dyld::log("%s()\n", __func__);
299 return dyld::getImageCount();
300}
301
302const struct mach_header* _dyld_get_image_header(uint32_t image_index)
303{
304 if ( dyld::gLogAPIs )
305 dyld::log("%s(%u)\n", __func__, image_index);
306 ImageLoader* image = dyld::getIndexedImage(image_index);
307 if ( image != NULL )
308 return (struct mach_header*)image->machHeader();
309 else
310 return NULL;
311}
312
313intptr_t _dyld_get_image_vmaddr_slide(uint32_t image_index)
314{
315 if ( dyld::gLogAPIs )
316 dyld::log("%s(%u)\n", __func__, image_index);
317 ImageLoader* image = dyld::getIndexedImage(image_index);
318 if ( image != NULL )
319 return image->getSlide();
320 else
321 return 0;
322}
323
324intptr_t _dyld_get_image_slide(const struct mach_header* mh)
325{
326 if ( dyld::gLogAPIs )
327 dyld::log("%s(%p)\n", __func__, mh);
328 ImageLoader* image = dyld::findImageByMachHeader(mh);
329 if ( image != NULL )
330 return image->getSlide();
331 else
332 return 0;
333}
334
335
336const char* _dyld_get_image_name(uint32_t image_index)
337{
338 if ( dyld::gLogAPIs )
339 dyld::log("%s(%u)\n", __func__, image_index);
340 ImageLoader* image = dyld::getIndexedImage(image_index);
341 if ( image != NULL )
832b6fce 342 return image->getRealPath();
39a8cd10
A
343 else
344 return NULL;
345}
346
df9d6cf7 347const struct mach_header * dyld_image_header_containing_address(const void* address)
39a8cd10
A
348{
349 if ( dyld::gLogAPIs )
350 dyld::log("%s(%p)\n", __func__, address);
351 ImageLoader* image = dyld::findImageContainingAddress(address);
352 if ( image != NULL )
353 return image->machHeader();
354 return NULL;
355}
356
357
358void _dyld_register_func_for_add_image(void (*func)(const struct mach_header *mh, intptr_t vmaddr_slide))
359{
360 if ( dyld::gLogAPIs )
361 dyld::log("%s(%p)\n", __func__, (void *)func);
362 dyld::registerAddCallback(func);
363}
364
365void _dyld_register_func_for_remove_image(void (*func)(const struct mach_header *mh, intptr_t vmaddr_slide))
366{
367 if ( dyld::gLogAPIs )
368 dyld::log("%s(%p)\n", __func__, (void *)func);
369 dyld::registerRemoveCallback(func);
370}
371
372
373
374// called by crt before main() by programs linked with 10.4 or earlier crt1.o
375static void _dyld_make_delayed_module_initializer_calls()
376{
377 if ( dyld::gLogAPIs )
378 dyld::log("%s()\n", __func__);
379
380#if SUPPORT_OLD_CRT_INITIALIZATION
381 if ( dyld::gRunInitializersOldWay )
382 dyld::initializeMainExecutable();
383#endif
384}
385
386
387
388#if DEPRECATED_APIS_SUPPORTED
0959b6d4
A
389
390//
391// _dyld_call_module_initializers_for_dylib() is the dyld side of
392// __initialize_Cplusplus() which is in dylib1.o.
393// It is intended to only be called inside -init rouintes.
394// -init routines are called before module initializers (what C++
395// initializers use). Calling __initialize_Cplusplus() in a -init
396// routine causes the module initializers for an image to be called
397// which then allows C++ to be used inside a -init routine
398//
399static void _dyld_call_module_initializers_for_dylib(const struct mach_header* mh_dylib_header)
400{
401 if ( dyld::gLogAPIs )
bac542e6 402 dyld::log("__initialize_Cplusplus()\n");
0959b6d4
A
403
404 // for now, do nothing...
405}
406
407
408void _dyld_lookup_and_bind_fully(const char* symbolName, void** address, NSModule* module)
409{
410 if ( dyld::gLogAPIs )
bac542e6 411 dyld::log("%s(\"%s\", %p, %p)\n", __func__, symbolName, address, module);
0959b6d4
A
412 ImageLoader* image;
413 const ImageLoader::Symbol* sym;
414 dyld::clearErrorMessage();
bac542e6 415 if ( dyld::flatFindExportedSymbol(symbolName, &sym, (const ImageLoader**)&image) ) {
0959b6d4 416 try {
bac542e6 417 image->bindAllLazyPointers(dyld::gLinkContext, true);
0959b6d4 418 if ( address != NULL)
bac542e6 419 *address = (void*)image->getExportedSymbolAddress(sym, dyld::gLinkContext);
0959b6d4
A
420 if ( module != NULL)
421 *module = ImageLoaderToNSModule(image);
422 }
423 catch (const char* msg) {
424 dyldAPIhalt(__func__, msg);
425 }
426 }
427 else {
428 // on failure to find symbol return NULLs
429 if ( address != NULL)
430 *address = NULL;
431 if ( module != NULL)
432 *module = NULL;
433 }
434}
435
436// Note: This cannot have public name because dyld is built with a static copy of libc.a
437// which calls dyld_lookup_and_bind() and expects to find dyld's symbols not host process
438static void client_dyld_lookup_and_bind(const char* symbolName, void** address, NSModule* module)
439{
440 if ( dyld::gLogAPIs )
bac542e6
A
441 dyld::log("_dyld_lookup_and_bind(\"%s\", %p, %p)\n", symbolName, address, module);
442 const ImageLoader* image;
0959b6d4
A
443 const ImageLoader::Symbol* sym;
444 if ( dyld::flatFindExportedSymbol(symbolName, &sym, &image) ) {
445 if ( address != NULL)
bac542e6 446 *address = (void*)image->getExportedSymbolAddress(sym, dyld::gLinkContext);
0959b6d4
A
447 if ( module != NULL)
448 *module = ImageLoaderToNSModule(image);
449 }
450 else {
451 // on failure to find symbol return NULLs
452 if ( address != NULL)
453 *address = NULL;
454 if ( module != NULL)
455 *module = NULL;
456 }
457}
458
459void _dyld_lookup_and_bind_with_hint(const char* symbolName, const char* library_name_hint, void** address, NSModule* module)
460{
461 if ( dyld::gLogAPIs )
bac542e6
A
462 dyld::log("%s(\"%s\", \"%s\", %p, %p)\n", __func__, symbolName, library_name_hint, address, module);
463 const ImageLoader* image;
0959b6d4
A
464 const ImageLoader::Symbol* sym;
465 // Look for library whose path contains the hint. If that fails search everywhere
466 if ( dyld::flatFindExportedSymbolWithHint(symbolName, library_name_hint, &sym, &image)
467 || dyld::flatFindExportedSymbol(symbolName, &sym, &image) ) {
468 if ( address != NULL)
bac542e6 469 *address = (void*)image->getExportedSymbolAddress(sym, dyld::gLinkContext);
0959b6d4
A
470 if ( module != NULL)
471 *module = ImageLoaderToNSModule(image);
472 }
473 else {
474 // on failure to find symbol return NULLs
475 if ( address != NULL)
476 *address = NULL;
477 if ( module != NULL)
478 *module = NULL;
479 }
480}
481
482
483NSSymbol NSLookupAndBindSymbol(const char *symbolName)
484{
485 if ( dyld::gLogAPIs )
bac542e6
A
486 dyld::log("%s(\"%s\")\n", __func__, symbolName);
487 const ImageLoader* image;
0959b6d4
A
488 const ImageLoader::Symbol* sym;
489 if ( dyld::flatFindExportedSymbol(symbolName, &sym, &image) ) {
490 return SymbolToNSSymbol(sym);
491 }
492 // return NULL on failure
493 return NULL;
494}
495
496NSSymbol NSLookupAndBindSymbolWithHint(const char* symbolName, const char* libraryNameHint)
497{
498 if ( dyld::gLogAPIs )
bac542e6
A
499 dyld::log("%s(\"%s\", \"%s\")\n", __func__, symbolName, libraryNameHint);
500 const ImageLoader* image;
0959b6d4
A
501 const ImageLoader::Symbol* sym;
502 bool found = dyld::flatFindExportedSymbolWithHint(symbolName, libraryNameHint, &sym, &image);
503 if ( ! found ) {
504 // hint failed, do slow search of all images
505 found = dyld::flatFindExportedSymbol(symbolName, &sym, &image);
506 }
507 if ( found )
508 return SymbolToNSSymbol(sym);
509
510 // return NULL on failure and log
511 if ( dyld::gLogAPIs )
bac542e6 512 dyld::log("%s(\"%s\", \"%s\") => NULL \n", __func__, symbolName, libraryNameHint);
0959b6d4
A
513 return NULL;
514}
515
0959b6d4 516
0959b6d4
A
517
518
519static __attribute__((noinline))
8bc9f0af 520const struct mach_header* addImage(void* callerAddress, const char* path, bool search, bool dontLoad, bool matchInstallName, bool abortOnError)
0959b6d4
A
521{
522 ImageLoader* image = NULL;
bac542e6 523 std::vector<const char*> rpathsFromCallerImage;
0959b6d4
A
524 try {
525 dyld::clearErrorMessage();
0959b6d4 526 ImageLoader* callerImage = dyld::findImageContainingAddress(callerAddress);
bac542e6
A
527 // like dlopen, use rpath from caller image and from main executable
528 if ( callerImage != NULL )
529 callerImage->getRPaths(dyld::gLinkContext, rpathsFromCallerImage);
530 ImageLoader::RPathChain callersRPaths(NULL, &rpathsFromCallerImage);
531 if ( callerImage != dyld::mainExecutable() ) {
532 dyld::mainExecutable()->getRPaths(dyld::gLinkContext, rpathsFromCallerImage);
533 }
0959b6d4
A
534 dyld::LoadContext context;
535 context.useSearchPaths = search;
39a8cd10 536 context.useFallbackPaths = search;
0959b6d4 537 context.useLdLibraryPath = false;
bac542e6 538 context.implicitRPath = false;
0959b6d4
A
539 context.matchByInstallName = matchInstallName;
540 context.dontLoad = dontLoad;
541 context.mustBeBundle = false;
542 context.mustBeDylib = true;
39a8cd10 543 context.canBePIE = false;
0959b6d4 544 context.origin = callerImage != NULL ? callerImage->getPath() : NULL; // caller's image's path
bac542e6 545 context.rpath = &callersRPaths; // rpaths from caller and main executable
0959b6d4
A
546
547 image = load(path, context);
548 if ( image != NULL ) {
549 if ( context.matchByInstallName )
550 image->setMatchInstallPath(true);
2fd3f4e8 551 dyld::link(image, false, false, callersRPaths);
bac542e6
A
552 dyld::runInitializers(image);
553 // images added with NSAddImage() can never be unloaded
554 image->setNeverUnload();
0959b6d4
A
555 }
556 }
557 catch (const char* msg) {
bac542e6 558 dyld::garbageCollectImages();
0959b6d4
A
559 if ( abortOnError) {
560 char pathMsg[strlen(msg)+strlen(path)+4];
561 strcpy(pathMsg, msg);
562 strcat(pathMsg, " ");
563 strcat(pathMsg, path);
564 dyldAPIhalt("NSAddImage", pathMsg);
565 }
566 // not halting, so set error state for NSLinkEditError to find
567 setLastError(NSLinkEditOtherError, 0, path, msg);
2028a915 568 free((void*)msg); // our free() will do nothing if msg is a string literal
bac542e6 569 image = NULL;
0959b6d4 570 }
bac542e6
A
571 // free rpaths (getRPaths() malloc'ed each string)
572 for(std::vector<const char*>::iterator it=rpathsFromCallerImage.begin(); it != rpathsFromCallerImage.end(); ++it) {
573 const char* str = *it;
574 free((void*)str);
575 }
576 if ( image == NULL )
577 return NULL;
578 else
579 return image->machHeader();
0959b6d4
A
580}
581
bac542e6 582
0959b6d4
A
583const struct mach_header* NSAddImage(const char* path, uint32_t options)
584{
585 if ( dyld::gLogAPIs )
bac542e6 586 dyld::log("%s(\"%s\", 0x%08X)\n", __func__, path, options);
0959b6d4
A
587 const bool dontLoad = ( (options & NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED) != 0 );
588 const bool search = ( (options & NSADDIMAGE_OPTION_WITH_SEARCHING) != 0 );
589 const bool matchInstallName = ( (options & NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME) != 0 );
832b6fce 590 const bool abortOnError = ( (options & (NSADDIMAGE_OPTION_RETURN_ON_ERROR|NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED)) == 0 );
8bc9f0af
A
591 void* callerAddress = __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
592 return addImage(callerAddress, path, search, dontLoad, matchInstallName, abortOnError);
0959b6d4
A
593}
594
595bool NSAddLibrary(const char* path)
596{
597 if ( dyld::gLogAPIs )
bac542e6 598 dyld::log("%s(\"%s\")\n", __func__, path);
8bc9f0af
A
599 void* callerAddress = __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
600 return (addImage(callerAddress, path, false, false, false, false) != NULL);
0959b6d4
A
601}
602
603bool NSAddLibraryWithSearching(const char* path)
604{
605 if ( dyld::gLogAPIs )
bac542e6 606 dyld::log("%s(\"%s\")\n", __func__, path);
8bc9f0af
A
607 void* callerAddress = __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
608 return (addImage(callerAddress, path, true, false, false, false) != NULL);
0959b6d4
A
609}
610
611
612
613//#define NSADDIMAGE_OPTION_NONE 0x0
614//#define NSADDIMAGE_OPTION_RETURN_ON_ERROR 0x1
615//#define NSADDIMAGE_OPTION_MATCH_FILENAME_BY_INSTALLNAME 0x8
616
617bool NSIsSymbolNameDefinedInImage(const struct mach_header* mh, const char* symbolName)
618{
619 if ( dyld::gLogAPIs )
bac542e6 620 dyld::log("%s(%p, \"%s\")\n", __func__, (void *)mh, symbolName);
0959b6d4
A
621 ImageLoader* image = dyld::findImageByMachHeader(mh);
622 if ( image != NULL ) {
39a8cd10 623 if ( image->findExportedSymbol(symbolName, true, NULL) != NULL)
0959b6d4
A
624 return true;
625 }
626 return false;
627}
628
39a8cd10 629
0959b6d4
A
630NSSymbol NSLookupSymbolInImage(const struct mach_header* mh, const char* symbolName, uint32_t options)
631{
632 if ( dyld::gLogAPIs )
bac542e6 633 dyld::log("%s(%p, \"%s\", 0x%08X)\n", __func__, mh, symbolName, options);
0959b6d4
A
634 const ImageLoader::Symbol* symbol = NULL;
635 dyld::clearErrorMessage();
636 ImageLoader* image = dyld::findImageByMachHeader(mh);
637 if ( image != NULL ) {
638 try {
639 if ( options & NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_FULLY ) {
bac542e6 640 image->bindAllLazyPointers(dyld::gLinkContext, true);
0959b6d4
A
641 }
642 else if ( options & NSLOOKUPSYMBOLINIMAGE_OPTION_BIND_NOW ) {
bac542e6 643 image->bindAllLazyPointers(dyld::gLinkContext, false);
0959b6d4
A
644 }
645 }
646 catch (const char* msg) {
647 if ( (options & NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR) == 0 ) {
648 dyldAPIhalt(__func__, msg);
649 }
650 }
39a8cd10 651 symbol = image->findExportedSymbol(symbolName, true, NULL);
0959b6d4
A
652 }
653 if ( dyld::gLogAPIs && (symbol == NULL) )
bac542e6 654 dyld::log("%s(%p, \"%s\", 0x%08X) ==> NULL\n", __func__, mh, symbolName, options);
0959b6d4
A
655 return SymbolToNSSymbol(symbol);
656}
657
658
659// Note: This cannot have public name because dyld is built with a static copy of libc.a
660// which calls NSIsSymbolNameDefined() and expects to find dyld's symbols not host process
661static bool client_NSIsSymbolNameDefined(const char* symbolName)
662{
663 if ( dyld::gLogAPIs )
bac542e6
A
664 dyld::log("NSIsSymbolNameDefined(\"%s\")\n", symbolName);
665 const ImageLoader* image;
0959b6d4
A
666 const ImageLoader::Symbol* sym;
667 return dyld::flatFindExportedSymbol(symbolName, &sym, &image);
668}
669
670bool NSIsSymbolNameDefinedWithHint(const char* symbolName, const char* libraryNameHint)
671{
672 if ( dyld::gLogAPIs )
bac542e6
A
673 dyld::log("%s(\"%s\", \"%s\")\n", __func__, symbolName, libraryNameHint);
674 const ImageLoader* image;
0959b6d4
A
675 const ImageLoader::Symbol* sym;
676 bool found = dyld::flatFindExportedSymbolWithHint(symbolName, libraryNameHint, &sym, &image);
677 if ( ! found ) {
678 // hint failed, do slow search of all images
679 found = dyld::flatFindExportedSymbol(symbolName, &sym, &image);
680 }
681 if ( !found && dyld::gLogAPIs )
bac542e6 682 dyld::log("%s(\"%s\", \"%s\") => false \n", __func__, symbolName, libraryNameHint);
0959b6d4
A
683 return found;
684}
685
686const char* NSNameOfSymbol(NSSymbol symbol)
687{
688 if ( dyld::gLogAPIs )
bac542e6 689 dyld::log("%s(%p)\n", __func__, (void *)symbol);
0959b6d4 690 const char* result = NULL;
39a8cd10 691 ImageLoader* image = dyld::findImageContainingSymbol(symbol);
0959b6d4
A
692 if ( image != NULL )
693 result = image->getExportedSymbolName(NSSymbolToSymbol(symbol));
694 return result;
695}
696
697void* NSAddressOfSymbol(NSSymbol symbol)
698{
699 if ( dyld::gLogAPIs )
bac542e6 700 dyld::log("%s(%p)\n", __func__, (void *)symbol);
39a8cd10
A
701 if ( symbol == NULL )
702 return NULL;
0959b6d4 703 void* result = NULL;
39a8cd10 704 ImageLoader* image = dyld::findImageContainingSymbol(symbol);
0959b6d4 705 if ( image != NULL )
bac542e6 706 result = (void*)image->getExportedSymbolAddress(NSSymbolToSymbol(symbol), dyld::gLinkContext);
0959b6d4
A
707 return result;
708}
709
710NSModule NSModuleForSymbol(NSSymbol symbol)
711{
712 if ( dyld::gLogAPIs )
bac542e6 713 dyld::log("%s(%p)\n", __func__, (void *)symbol);
0959b6d4 714 NSModule result = NULL;
39a8cd10 715 ImageLoader* image = dyld::findImageContainingSymbol(symbol);
0959b6d4
A
716 if ( image != NULL )
717 result = ImageLoaderToNSModule(image);
718 return result;
719}
720
721
0959b6d4
A
722
723
724bool _dyld_all_twolevel_modules_prebound(void)
725{
726 if ( dyld::gLogAPIs )
bac542e6 727 dyld::log("%s()\n", __func__);
39a8cd10 728 return FALSE;
0959b6d4
A
729}
730
731void _dyld_bind_objc_module(const void *objc_module)
732{
733 if ( dyld::gLogAPIs )
bac542e6 734 dyld::log("%s(%p)\n", __func__, objc_module);
0959b6d4
A
735 // do nothing, with new dyld everything already bound
736}
737
738
739bool _dyld_bind_fully_image_containing_address(const void* address)
740{
741 if ( dyld::gLogAPIs )
bac542e6 742 dyld::log("%s(%p)\n", __func__, address);
0959b6d4
A
743 dyld::clearErrorMessage();
744 ImageLoader* image = dyld::findImageContainingAddress(address);
745 if ( image != NULL ) {
746 try {
bac542e6 747 image->bindAllLazyPointers(dyld::gLinkContext, true);
0959b6d4
A
748 return true;
749 }
750 catch (const char* msg) {
751 dyldAPIhalt(__func__, msg);
752 }
753 }
754 return false;
755}
756
757bool _dyld_image_containing_address(const void* address)
758{
759 if ( dyld::gLogAPIs )
bac542e6 760 dyld::log("%s(%p)\n", __func__, address);
0959b6d4
A
761 ImageLoader *imageLoader = dyld::findImageContainingAddress(address);
762 return (NULL != imageLoader);
763}
764
765static NSObjectFileImage createObjectImageFile(ImageLoader* image, const void* address = NULL, size_t len=0)
766{
767 NSObjectFileImage result = new __NSObjectFileImage();
768 result->image = image;
769 result->imageBaseAddress = address;
770 result->imageLength = len;
771 sObjectFileImages.push_back(result);
772 return result;
773}
774
775NSObjectFileImageReturnCode NSCreateObjectFileImageFromFile(const char* pathName, NSObjectFileImage *objectFileImage)
776{
777 if ( dyld::gLogAPIs )
bac542e6 778 dyld::log("%s(\"%s\", ...)\n", __func__, pathName);
0959b6d4
A
779 try {
780 void* callerAddress = __builtin_return_address(1); // note layers: 1: real client, 0: libSystem glue
781 ImageLoader* callerImage = dyld::findImageContainingAddress(callerAddress);
782
783 dyld::LoadContext context;
784 context.useSearchPaths = false;
39a8cd10 785 context.useFallbackPaths = false;
0959b6d4 786 context.useLdLibraryPath = false;
bac542e6 787 context.implicitRPath = false;
0959b6d4
A
788 context.matchByInstallName = false;
789 context.dontLoad = false;
790 context.mustBeBundle = true;
791 context.mustBeDylib = false;
39a8cd10 792 context.canBePIE = false;
0959b6d4
A
793 context.origin = callerImage != NULL ? callerImage->getPath() : NULL; // caller's image's path
794 context.rpath = NULL; // support not yet implemented
795
796 ImageLoader* image = dyld::load(pathName, context);
797 // Note: We DO NOT link the image! NSLinkModule will do that
798 if ( image != NULL ) {
799 if ( !image->isBundle() ) {
800 // the image must have been already loaded (since context.mustBeBundle will prevent it from being loaded)
801 return NSObjectFileImageInappropriateFile;
802 }
803 *objectFileImage = createObjectImageFile(image);
804 return NSObjectFileImageSuccess;
805 }
806 }
807 catch (const char* msg) {
bac542e6
A
808 //dyld::log("dyld: NSCreateObjectFileImageFromFile() error: %s\n", msg);
809 dyld::garbageCollectImages();
810 free((void*)msg);
0959b6d4
A
811 return NSObjectFileImageInappropriateFile;
812 }
813 return NSObjectFileImageFailure;
814}
815
816
817NSObjectFileImageReturnCode NSCreateObjectFileImageFromMemory(const void* address, size_t size, NSObjectFileImage *objectFileImage)
818{
819 if ( dyld::gLogAPIs )
bac542e6 820 dyld::log("%s(%p, %lu, %p)\n", __func__, address, size, objectFileImage);
0959b6d4
A
821
822 try {
823 ImageLoader* image = dyld::loadFromMemory((const uint8_t*)address, size, NULL);
824 if ( ! image->isBundle() ) {
825 // this API can only be used with bundles...
bac542e6 826 dyld::garbageCollectImages();
0959b6d4
A
827 return NSObjectFileImageInappropriateFile;
828 }
829 // Note: We DO NOT link the image! NSLinkModule will do that
830 if ( image != NULL ) {
831 *objectFileImage = createObjectImageFile(image, address, size);
832 return NSObjectFileImageSuccess;
833 }
834 }
835 catch (const char* msg) {
bac542e6
A
836 free((void*)msg);
837 dyld::garbageCollectImages();
838 //dyld::log("dyld: NSCreateObjectFileImageFromMemory() error: %s\n", msg);
0959b6d4
A
839 }
840 return NSObjectFileImageFailure;
841}
842
843static bool validOFI(NSObjectFileImage objectFileImage)
844{
845 const int ofiCount = sObjectFileImages.size();
846 for (int i=0; i < ofiCount; ++i) {
847 if ( sObjectFileImages[i] == objectFileImage )
848 return true;
849 }
850 return false;
851}
852
853bool NSDestroyObjectFileImage(NSObjectFileImage objectFileImage)
854{
855 if ( dyld::gLogAPIs )
bac542e6 856 dyld::log("%s(%p)\n", __func__, objectFileImage);
0959b6d4
A
857
858 if ( validOFI(objectFileImage) ) {
bac542e6
A
859 // a failure during NSLinkModule will delete the image
860 if ( objectFileImage->image != NULL ) {
861 // if the image has never been linked or has been unlinked, the image is not in the list of valid images
862 // and we should delete it
863 bool linkedImage = dyld::validImage(objectFileImage->image);
864 if ( ! linkedImage ) {
39a8cd10 865 ImageLoader::deleteImage(objectFileImage->image);
bac542e6
A
866 objectFileImage->image = NULL;
867 }
868 }
0959b6d4
A
869
870 // remove from list of ofi's
871 for (std::vector<NSObjectFileImage>::iterator it=sObjectFileImages.begin(); it != sObjectFileImages.end(); it++) {
872 if ( *it == objectFileImage ) {
873 sObjectFileImages.erase(it);
874 break;
875 }
876 }
877
878 // if object was created from a memory, release that memory
879 // NOTE: this is the way dyld has always done this. NSCreateObjectFileImageFromMemory() hands over ownership of the memory to dyld
880 if ( objectFileImage->imageBaseAddress != NULL ) {
39a8cd10
A
881 bool freed = false;
882 if ( (dyld::gLibSystemHelpers != NULL) && (dyld::gLibSystemHelpers->version >= 6) ) {
883 size_t sz = (*dyld::gLibSystemHelpers->malloc_size)(objectFileImage->imageBaseAddress);
884 if ( sz != 0 ) {
885 (*dyld::gLibSystemHelpers->free)((void*)(objectFileImage->imageBaseAddress));
886 freed = true;
887 }
888 }
889 if ( ! freed )
890 vm_deallocate(mach_task_self(), (vm_address_t)objectFileImage->imageBaseAddress, objectFileImage->imageLength);
0959b6d4
A
891 }
892
893 // free ofi object
894 delete objectFileImage;
895
896 return true;
897 }
898 return false;
899}
900
901bool NSHasModInitObjectFileImage(NSObjectFileImage objectFileImage)
902{
903 if ( dyld::gLogAPIs )
bac542e6 904 dyld::log("%s(%p)\n", __func__, objectFileImage);
0959b6d4
A
905 return objectFileImage->image->needsInitialization();
906}
907
908uint32_t NSSymbolDefinitionCountInObjectFileImage(NSObjectFileImage objectFileImage)
909{
910 if ( dyld::gLogAPIs )
bac542e6 911 dyld::log("%s(%p)\n", __func__, objectFileImage);
0959b6d4
A
912 return objectFileImage->image->getExportedSymbolCount();
913}
914
915const char* NSSymbolDefinitionNameInObjectFileImage(NSObjectFileImage objectFileImage, uint32_t ordinal)
916{
917 if ( dyld::gLogAPIs )
bac542e6 918 dyld::log("%s(%p,%d)\n", __func__, objectFileImage, ordinal);
0959b6d4
A
919 const ImageLoader::Symbol* sym = objectFileImage->image->getIndexedExportedSymbol(ordinal);
920 return objectFileImage->image->getExportedSymbolName(sym);
921}
922
923uint32_t NSSymbolReferenceCountInObjectFileImage(NSObjectFileImage objectFileImage)
924{
925 if ( dyld::gLogAPIs )
bac542e6 926 dyld::log("%s(%p)\n", __func__, objectFileImage);
0959b6d4
A
927 return objectFileImage->image->getImportedSymbolCount();
928}
929
930const char * NSSymbolReferenceNameInObjectFileImage(NSObjectFileImage objectFileImage, uint32_t ordinal,
931 bool* tentative_definition)
932{
933 if ( dyld::gLogAPIs )
bac542e6 934 dyld::log("%s(%p,%d)\n", __func__, objectFileImage, ordinal);
0959b6d4
A
935 const ImageLoader::Symbol* sym = objectFileImage->image->getIndexedImportedSymbol(ordinal);
936 if ( tentative_definition != NULL ) {
39a8cd10 937 ImageLoader::ReferenceFlags flags = objectFileImage->image->getImportedSymbolInfo(sym);
0959b6d4
A
938 if ( (flags & ImageLoader::kTentativeDefinition) != 0 )
939 *tentative_definition = true;
940 else
941 *tentative_definition = false;
942 }
943 return objectFileImage->image->getImportedSymbolName(sym);
944}
945
946void* NSGetSectionDataInObjectFileImage(NSObjectFileImage objectFileImage,
947 const char* segmentName, const char* sectionName, unsigned long* size)
948{
949 if ( dyld::gLogAPIs )
bac542e6 950 dyld::log("%s(%p,%s, %s)\n", __func__, objectFileImage, segmentName, sectionName);
0959b6d4
A
951
952 void* start;
953 size_t length;
954 if ( objectFileImage->image->getSectionContent(segmentName, sectionName, &start, &length) ) {
955 if ( size != NULL )
956 *size = length;
957 return start;
958 }
959 return NULL;
960}
961
962
963
964bool NSIsSymbolDefinedInObjectFileImage(NSObjectFileImage objectFileImage, const char* symbolName)
965{
966 if ( dyld::gLogAPIs )
bac542e6 967 dyld::log("%s(%p,%s)\n", __func__, objectFileImage, symbolName);
39a8cd10 968 const ImageLoader::Symbol* sym = objectFileImage->image->findExportedSymbol(symbolName, true, NULL);
0959b6d4
A
969 return ( sym != NULL );
970}
971
0959b6d4
A
972
973
974NSModule NSLinkModule(NSObjectFileImage objectFileImage, const char* moduleName, uint32_t options)
975{
976 if ( dyld::gLogAPIs )
bac542e6 977 dyld::log("%s(%p, \"%s\", 0x%08X)\n", __func__, objectFileImage, moduleName, options);
0959b6d4
A
978
979 dyld::clearErrorMessage();
980 try {
2fd3f4e8
A
981 if ( (options & NSLINKMODULE_OPTION_CAN_UNLOAD) != 0 )
982 objectFileImage->image->setCanUnload();
983
0959b6d4
A
984 // NSLinkModule allows a bundle to be link multpile times
985 // each link causes the bundle to be copied to a new address
986 if ( objectFileImage->image->isLinked() ) {
987 // already linked, so clone a new one and link it
0959b6d4
A
988 objectFileImage->image = dyld::cloneImage(objectFileImage->image);
989 }
412ebb8e 990
39a8cd10 991 // for memory based images, set moduleName as the name anyone calling _dyld_get_image_name() will see
412ebb8e 992 if ( objectFileImage->image->getPath() == NULL ) {
39a8cd10 993 objectFileImage->image->setPath(moduleName);
412ebb8e
A
994 // <rdar://problem/8812589> dyld has NULL paths in image info array
995 dyld_image_info info;
996 info.imageLoadAddress = objectFileImage->image->machHeader();
997 info.imageFilePath = moduleName;
998 info.imageFileModDate = 0;
999 addImagesToAllImages(1, &info);
1000 }
0959b6d4
A
1001
1002 // support private bundles
1003 if ( (options & NSLINKMODULE_OPTION_PRIVATE) != 0 )
1004 objectFileImage->image->setHideExports();
1005
1006 // set up linking options
bac542e6 1007 bool forceLazysBound = ( (options & NSLINKMODULE_OPTION_BINDNOW) != 0 );
0959b6d4
A
1008
1009 // load libraries, rebase, bind, to make this image usable
2fd3f4e8 1010 dyld::link(objectFileImage->image, forceLazysBound, false, ImageLoader::RPathChain(NULL,NULL));
0959b6d4 1011
39a8cd10
A
1012 // bump reference count to keep this bundle from being garbage collected
1013 objectFileImage->image->incrementDlopenReferenceCount();
1014
bac542e6
A
1015 // run initializers unless magic flag says not to
1016 if ( (options & NSLINKMODULE_OPTION_DONT_CALL_MOD_INIT_ROUTINES) == 0 )
1017 dyld::runInitializers(objectFileImage->image);
1018
0959b6d4
A
1019 return ImageLoaderToNSModule(objectFileImage->image);
1020 }
1021 catch (const char* msg) {
bac542e6 1022 dyld::garbageCollectImages();
0959b6d4
A
1023 if ( (options & NSLINKMODULE_OPTION_RETURN_ON_ERROR) == 0 )
1024 dyldAPIhalt(__func__, msg);
1025 // not halting, so set error state for NSLinkEditError to find
0959b6d4 1026 setLastError(NSLinkEditOtherError, 0, moduleName, msg);
bac542e6
A
1027 // dyld::link() deleted the image so lose our reference
1028 objectFileImage->image = NULL;
1029 free((void*)msg);
0959b6d4
A
1030 return NULL;
1031 }
1032}
1033
bac542e6 1034
0959b6d4
A
1035#if OLD_LIBSYSTEM_SUPPORT
1036// This is for compatibility with old libSystems (libdyld.a) which process ObjectFileImages outside dyld
1037static NSModule _dyld_link_module(NSObjectFileImage object_addr, size_t object_size, const char* moduleName, uint32_t options)
1038{
1039 if ( dyld::gLogAPIs )
bac542e6 1040 dyld::log("%s(%p, \"%s\", 0x%08X)\n", "NSLinkModule", object_addr, moduleName, options); // note name/args translation
0959b6d4
A
1041 ImageLoader* image = NULL;
1042 dyld::clearErrorMessage();
1043 try {
39a8cd10 1044 const char* imageName = moduleName;
0959b6d4
A
1045 image = dyld::loadFromMemory((const uint8_t*)object_addr, object_size, imageName);
1046
0959b6d4
A
1047 if ( image != NULL ) {
1048 // support private bundles
1049 if ( (options & NSLINKMODULE_OPTION_PRIVATE) != 0 )
1050 image->setHideExports();
1051
1052 // set up linking options
bac542e6 1053 bool forceLazysBound = ( (options & NSLINKMODULE_OPTION_BINDNOW) != 0 );
0959b6d4
A
1054
1055 // load libraries, rebase, bind, to make this image usable
2fd3f4e8 1056 dyld::link(image, forceLazysBound, false, ImageLoader::RPathChain(NULL,NULL));
bac542e6
A
1057
1058 // run initializers unless magic flag says not to
1059 if ( (options & NSLINKMODULE_OPTION_DONT_CALL_MOD_INIT_ROUTINES) == 0 )
1060 dyld::runInitializers(image);
0959b6d4
A
1061 }
1062 }
1063 catch (const char* msg) {
1064 if ( (options & NSLINKMODULE_OPTION_RETURN_ON_ERROR) == 0 )
1065 dyldAPIhalt("NSLinkModule", msg);
1066 // not halting, so set error state for NSLinkEditError to find
1067 setLastError(NSLinkEditOtherError, 0, moduleName, msg);
1068 // if image was created for this bundle, destroy it
1069 if ( image != NULL ) {
1070 dyld::removeImage(image);
39a8cd10 1071 ImageLoader::deleteImage(image);
0959b6d4
A
1072 }
1073 image = NULL;
bac542e6 1074 free((void*)msg);
0959b6d4
A
1075 }
1076 return ImageLoaderToNSModule(image);
1077}
1078#endif
1079
1080NSSymbol NSLookupSymbolInModule(NSModule module, const char* symbolName)
1081{
1082 if ( dyld::gLogAPIs )
bac542e6 1083 dyld::log("%s(%p, \"%s\")\n", __func__, (void *)module, symbolName);
0959b6d4
A
1084 ImageLoader* image = NSModuleToImageLoader(module);
1085 if ( image == NULL )
1086 return NULL;
39a8cd10 1087 return SymbolToNSSymbol(image->findExportedSymbol(symbolName, false, NULL));
0959b6d4
A
1088}
1089
1090const char* NSNameOfModule(NSModule module)
1091{
1092 if ( dyld::gLogAPIs )
bac542e6 1093 dyld::log("%s(%p)\n", __func__, module);
0959b6d4
A
1094 ImageLoader* image = NSModuleToImageLoader(module);
1095 if ( image == NULL )
1096 return NULL;
1097 return image->getPath();
1098}
1099
1100const char* NSLibraryNameForModule(NSModule module)
1101{
1102 if ( dyld::gLogAPIs )
bac542e6 1103 dyld::log("%s(%p)\n", __func__, module);
0959b6d4
A
1104 ImageLoader* image = NSModuleToImageLoader(module);
1105 if ( image == NULL )
1106 return NULL;
1107 return image->getPath();
1108}
1109
1110bool NSUnLinkModule(NSModule module, uint32_t options)
1111{
1112 if ( dyld::gLogAPIs )
bac542e6 1113 dyld::log("%s(%p, 0x%08X)\n", __func__, module, options);
0959b6d4
A
1114 if ( module == NULL )
1115 return false;
1116 ImageLoader* image = NSModuleToImageLoader(module);
1117 if ( image == NULL )
1118 return false;
19894a12
A
1119 dyld::runImageStaticTerminators(image);
1120 if ( (dyld::gLibSystemHelpers != NULL) && (dyld::gLibSystemHelpers->version >= 13) ) {
df9d6cf7 1121 __cxa_range_t ranges[image->segmentCount()];
19894a12
A
1122 int rangeCount = 0;
1123 for (unsigned int j=0; j < image->segmentCount(); ++j) {
1124 if ( !image->segExecutable(j) )
1125 continue;
1126 ranges[rangeCount].addr = (const void*)image->segActualLoadAddress(j);
1127 ranges[rangeCount].length = image->segSize(j);
1128 ++rangeCount;
1129 }
1130 (*dyld::gLibSystemHelpers->cxa_finalize_ranges)(ranges, rangeCount);
1131 }
0959b6d4
A
1132 dyld::removeImage(image);
1133
1134 if ( (options & NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED) != 0 )
1135 image->setLeaveMapped();
1136
1137 // TODO: NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES
1138
1139 // Only delete image if there is no ofi referencing it
1140 // That means the ofi was destroyed after linking, so no one is left to delete this image
1141 const int ofiCount = sObjectFileImages.size();
1142 bool found = false;
1143 for (int i=0; i < ofiCount; ++i) {
1144 NSObjectFileImage ofi = sObjectFileImages[i];
1145 if ( ofi->image == image )
1146 found = true;
1147 }
1148 if ( !found )
39a8cd10 1149 ImageLoader::deleteImage(image);
0959b6d4
A
1150
1151 return true;
1152}
1153
1154// internal name and parameters do not match public name and parameters...
1155static void _dyld_install_handlers(void* undefined, void* multiple, void* linkEdit)
1156{
1157 if ( dyld::gLogAPIs )
bac542e6 1158 dyld::log("NSLinkEditErrorHandlers()\n");
0959b6d4
A
1159
1160 dyld::registerUndefinedHandler((dyld::UndefinedHandler)undefined);
1161 // no support for multiple or linkedit handlers
1162}
1163
0959b6d4 1164
0959b6d4
A
1165
1166
1167void NSLinkEditError(NSLinkEditErrors* c, int* errorNumber, const char** fileName, const char** errorString)
1168{
1169 // FIXME FIXME
1170 *c = sLastErrorFileCode;
1171 *errorNumber = sLastErrorNo;
1172 *fileName = sLastErrorFilePath;
1173 *errorString = dyld::getErrorMessage();
1174}
1175
39a8cd10
A
1176
1177
0959b6d4
A
1178static void _dyld_register_binding_handler(void * (*bindingHandler)(const char *, const char *, void *), ImageLoader::BindingOptions bindingOptions)
1179{
1180 if ( dyld::gLogAPIs )
bac542e6 1181 dyld::log("%s()\n", __func__);
0959b6d4
A
1182 dyld::gLinkContext.bindingHandler = bindingHandler;
1183 dyld::gLinkContext.bindingOptions = bindingOptions;
1184}
1185
39a8cd10
A
1186#endif //DEPRECATED_APIS_SUPPORTED
1187
0959b6d4
A
1188
1189// Call by fork() in libSystem after the kernel trap is done on the child side
412ebb8e 1190void _dyld_fork_child()
0959b6d4
A
1191{
1192 if ( dyld::gLogAPIs )
bac542e6 1193 dyld::log("%s()\n", __func__);
0959b6d4
A
1194 // The implementation of fork() in libSystem knows to reset the variable mach_task_self_
1195 // in libSystem for the child of a fork. But dyld is built with a static copy
1196 // of libc.a and has its own copy of mach_task_self_ which we reset here.
1197 //
1198 // In mach_init.h mach_task_self() is #defined to mach_task_self_ and
1199 // in mach_init() mach_task_self_ is initialized to task_self_trap().
1200 //
1201 extern mach_port_t mach_task_self_;
1202 mach_task_self_ = task_self_trap();
39a8cd10
A
1203
1204 // If dyld is sending load/unload notices to CoreSymbolication, the shared memory
1205 // page is not copied on fork. <rdar://problem/6797342>
1206 // NULL the CoreSymbolication shared memory pointer to prevent a crash.
2fd3f4e8 1207 dyld::gProcessInfo->coreSymbolicationShmPage = NULL;
39a8cd10 1208 // for safety, make sure child starts with clean systemOrderFlag
2fd3f4e8 1209 dyld::gProcessInfo->systemOrderFlag = 0;
0959b6d4
A
1210}
1211
0959b6d4 1212
39a8cd10 1213#if DEPRECATED_APIS_SUPPORTED
0959b6d4
A
1214// returns true if prebinding was used in main executable
1215bool _dyld_launched_prebound()
1216{
1217 if ( dyld::gLogAPIs )
bac542e6 1218 dyld::log("%s()\n", __func__);
0959b6d4
A
1219
1220