Mercurial > sdl-ios-xcode
comparison src/loadso/macosx/SDL_dlcompat.c @ 1668:4da1ee79c9af SDL-1.3
more tweaking indent options
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 29 May 2006 04:04:35 +0000 |
parents | 782fd950bd46 |
children |
comparison
equal
deleted
inserted
replaced
1667:1fddae038bc8 | 1668:4da1ee79c9af |
---|---|
106 void *dli_fbase; /* Base address of shared object */ | 106 void *dli_fbase; /* Base address of shared object */ |
107 const char *dli_sname; /* Name of nearest symbol */ | 107 const char *dli_sname; /* Name of nearest symbol */ |
108 void *dli_saddr; /* Address of nearest symbol */ | 108 void *dli_saddr; /* Address of nearest symbol */ |
109 } SDL_OSX_Dl_info; | 109 } SDL_OSX_Dl_info; |
110 | 110 |
111 static int SDL_OSX_dladdr (const void *dl_restrict, | 111 static int SDL_OSX_dladdr(const void *dl_restrict, |
112 SDL_OSX_Dl_info * dl_restrict); | 112 SDL_OSX_Dl_info * dl_restrict); |
113 #endif /* ! _POSIX_SOURCE */ | 113 #endif /* ! _POSIX_SOURCE */ |
114 #endif /* 0 */ | 114 #endif /* 0 */ |
115 | 115 |
116 static int SDL_OSX_dlclose (void *handle); | 116 static int SDL_OSX_dlclose(void *handle); |
117 static const char *SDL_OSX_dlerror (void); | 117 static const char *SDL_OSX_dlerror(void); |
118 static void *SDL_OSX_dlopen (const char *path, int mode); | 118 static void *SDL_OSX_dlopen(const char *path, int mode); |
119 static void *SDL_OSX_dlsym (void *dl_restrict handle, | 119 static void *SDL_OSX_dlsym(void *dl_restrict handle, |
120 const char *dl_restrict symbol); | 120 const char *dl_restrict symbol); |
121 | 121 |
122 #define RTLD_LAZY 0x1 | 122 #define RTLD_LAZY 0x1 |
123 #define RTLD_NOW 0x2 | 123 #define RTLD_NOW 0x2 |
124 #define RTLD_LOCAL 0x4 | 124 #define RTLD_LOCAL 0x4 |
125 #define RTLD_GLOBAL 0x8 | 125 #define RTLD_GLOBAL 0x8 |
168 /* These symbols will be looked for in dyld */ | 168 /* These symbols will be looked for in dyld */ |
169 static const struct mach_header *(*dyld_NSAddImage) (const char *, | 169 static const struct mach_header *(*dyld_NSAddImage) (const char *, |
170 unsigned long) = 0; | 170 unsigned long) = 0; |
171 static int (*dyld_NSIsSymbolNameDefinedInImage) (const struct mach_header *, | 171 static int (*dyld_NSIsSymbolNameDefinedInImage) (const struct mach_header *, |
172 const char *) = 0; | 172 const char *) = 0; |
173 static NSSymbol (*dyld_NSLookupSymbolInImage) (const struct mach_header *, | 173 static NSSymbol(*dyld_NSLookupSymbolInImage) (const struct mach_header *, |
174 const char *, unsigned long) = | 174 const char *, unsigned long) = |
175 0; | 175 0; |
176 | 176 |
177 /* Define this to make dlcompat reuse data block. This way in theory we save | 177 /* Define this to make dlcompat reuse data block. This way in theory we save |
178 * a little bit of overhead. However we then couldn't correctly catch excess | 178 * a little bit of overhead. However we then couldn't correctly catch excess |
179 * calls to SDL_OSX_dlclose(). Hence we don't use this feature | 179 * calls to SDL_OSX_dlclose(). Hence we don't use this feature |
230 /* Storage for the last error message (used by dlerror()) */ | 230 /* Storage for the last error message (used by dlerror()) */ |
231 /* static char err_str[ERR_STR_LEN]; */ | 231 /* static char err_str[ERR_STR_LEN]; */ |
232 /* static int err_filled = 0; */ | 232 /* static int err_filled = 0; */ |
233 | 233 |
234 /* Prototypes to internal functions */ | 234 /* Prototypes to internal functions */ |
235 static void debug (const char *fmt, ...); | 235 static void debug(const char *fmt, ...); |
236 static void error (const char *str, ...); | 236 static void error(const char *str, ...); |
237 static const char *safegetenv (const char *s); | 237 static const char *safegetenv(const char *s); |
238 static const char *searchList (void); | 238 static const char *searchList(void); |
239 static const char *getSearchPath (int i); | 239 static const char *getSearchPath(int i); |
240 static const char *getFullPath (int i, const char *file); | 240 static const char *getFullPath(int i, const char *file); |
241 static const struct stat *findFile (const char *file, const char **fullPath); | 241 static const struct stat *findFile(const char *file, const char **fullPath); |
242 static int isValidStatus (struct dlstatus *status); | 242 static int isValidStatus(struct dlstatus *status); |
243 static inline int isFlagSet (int mode, int flag); | 243 static inline int isFlagSet(int mode, int flag); |
244 static struct dlstatus *lookupStatus (const struct stat *sbuf); | 244 static struct dlstatus *lookupStatus(const struct stat *sbuf); |
245 static void insertStatus (struct dlstatus *dls, const struct stat *sbuf); | 245 static void insertStatus(struct dlstatus *dls, const struct stat *sbuf); |
246 static int promoteLocalToGlobal (struct dlstatus *dls); | 246 static int promoteLocalToGlobal(struct dlstatus *dls); |
247 static void *reference (struct dlstatus *dls, int mode); | 247 static void *reference(struct dlstatus *dls, int mode); |
248 static void *dlsymIntern (struct dlstatus *dls, const char *symbol, | 248 static void *dlsymIntern(struct dlstatus *dls, const char *symbol, |
249 int canSetError); | 249 int canSetError); |
250 static struct dlstatus *allocStatus (void); | 250 static struct dlstatus *allocStatus(void); |
251 static struct dlstatus *loadModule (const char *path, const struct stat *sbuf, | 251 static struct dlstatus *loadModule(const char *path, const struct stat *sbuf, |
252 int mode); | 252 int mode); |
253 static NSSymbol search_linked_libs (const struct mach_header *mh, | 253 static NSSymbol search_linked_libs(const struct mach_header *mh, |
254 const char *symbol); | 254 const char *symbol); |
255 static const char *get_lib_name (const struct mach_header *mh); | 255 static const char *get_lib_name(const struct mach_header *mh); |
256 static const struct mach_header *get_mach_header_from_NSModule (NSModule mod); | 256 static const struct mach_header *get_mach_header_from_NSModule(NSModule mod); |
257 static void dlcompat_init_func (void); | 257 static void dlcompat_init_func(void); |
258 static inline void dlcompat_init_check (void); | 258 static inline void dlcompat_init_check(void); |
259 static inline void dolock (void); | 259 static inline void dolock(void); |
260 static inline void dounlock (void); | 260 static inline void dounlock(void); |
261 static void dlerrorfree (void *data); | 261 static void dlerrorfree(void *data); |
262 static void resetdlerror (void); | 262 static void resetdlerror(void); |
263 static const struct mach_header *my_find_image (const char *name); | 263 static const struct mach_header *my_find_image(const char *name); |
264 static const struct mach_header *image_for_address (const void *address); | 264 static const struct mach_header *image_for_address(const void *address); |
265 static inline char *dyld_error_str (void); | 265 static inline char *dyld_error_str(void); |
266 | 266 |
267 #if FINK_BUILD | 267 #if FINK_BUILD |
268 /* Two Global Functions */ | 268 /* Two Global Functions */ |
269 static void *dlsym_prepend_underscore (void *handle, const char *symbol); | 269 static void *dlsym_prepend_underscore(void *handle, const char *symbol); |
270 static void *dlsym_auto_underscore (void *handle, const char *symbol); | 270 static void *dlsym_auto_underscore(void *handle, const char *symbol); |
271 | 271 |
272 /* And their _intern counterparts */ | 272 /* And their _intern counterparts */ |
273 static void *dlsym_prepend_underscore_intern (void *handle, | 273 static void *dlsym_prepend_underscore_intern(void *handle, |
274 const char *symbol); | 274 const char *symbol); |
275 static void *dlsym_auto_underscore_intern (void *handle, const char *symbol); | 275 static void *dlsym_auto_underscore_intern(void *handle, const char *symbol); |
276 #endif | 276 #endif |
277 | 277 |
278 /* Functions */ | 278 /* Functions */ |
279 | 279 |
280 static void | 280 static void |
281 debug (const char *fmt, ...) | 281 debug(const char *fmt, ...) |
282 { | 282 { |
283 #if DEBUG > 1 | 283 #if DEBUG > 1 |
284 va_list arg; | 284 va_list arg; |
285 va_start (arg, fmt); | 285 va_start(arg, fmt); |
286 fprintf (stderr, "DLDEBUG: "); | 286 fprintf(stderr, "DLDEBUG: "); |
287 vfprintf (stderr, fmt, arg); | 287 vfprintf(stderr, fmt, arg); |
288 fprintf (stderr, "\n"); | 288 fprintf(stderr, "\n"); |
289 fflush (stderr); | 289 fflush(stderr); |
290 va_end (arg); | 290 va_end(arg); |
291 #endif | 291 #endif |
292 } | 292 } |
293 | 293 |
294 static void | 294 static void |
295 error (const char *str, ...) | 295 error(const char *str, ...) |
296 { | 296 { |
297 va_list arg; | 297 va_list arg; |
298 struct dlthread *tss; | 298 struct dlthread *tss; |
299 char *err_str; | 299 char *err_str; |
300 va_start (arg, str); | 300 va_start(arg, str); |
301 tss = pthread_getspecific (dlerror_key); | 301 tss = pthread_getspecific(dlerror_key); |
302 err_str = tss->errstr; | 302 err_str = tss->errstr; |
303 SDL_strlcpy (err_str, "dlcompat: ", ERR_STR_LEN); | 303 SDL_strlcpy(err_str, "dlcompat: ", ERR_STR_LEN); |
304 vsnprintf (err_str + 10, ERR_STR_LEN - 10, str, arg); | 304 vsnprintf(err_str + 10, ERR_STR_LEN - 10, str, arg); |
305 va_end (arg); | 305 va_end(arg); |
306 debug ("ERROR: %s\n", err_str); | 306 debug("ERROR: %s\n", err_str); |
307 tss->errset = 1; | 307 tss->errset = 1; |
308 } | 308 } |
309 | 309 |
310 static void | 310 static void |
311 warning (const char *str) | 311 warning(const char *str) |
312 { | 312 { |
313 #if DEBUG > 0 | 313 #if DEBUG > 0 |
314 fprintf (stderr, "WARNING: dlcompat: %s\n", str); | 314 fprintf(stderr, "WARNING: dlcompat: %s\n", str); |
315 #endif | 315 #endif |
316 } | 316 } |
317 | 317 |
318 static const char * | 318 static const char * |
319 safegetenv (const char *s) | 319 safegetenv(const char *s) |
320 { | 320 { |
321 const char *ss = SDL_getenv (s); | 321 const char *ss = SDL_getenv(s); |
322 return ss ? ss : ""; | 322 return ss ? ss : ""; |
323 } | 323 } |
324 | 324 |
325 /* because this is only used for debugging and error reporting functions, we | 325 /* because this is only used for debugging and error reporting functions, we |
326 * don't really care about how elegant it is... it could use the load | 326 * don't really care about how elegant it is... it could use the load |
327 * commands to find the install name of the library, but... | 327 * commands to find the install name of the library, but... |
328 */ | 328 */ |
329 static const char * | 329 static const char * |
330 get_lib_name (const struct mach_header *mh) | 330 get_lib_name(const struct mach_header *mh) |
331 { | 331 { |
332 unsigned long count = _dyld_image_count (); | 332 unsigned long count = _dyld_image_count(); |
333 unsigned long i; | 333 unsigned long i; |
334 const char *val = NULL; | 334 const char *val = NULL; |
335 if (mh) { | 335 if (mh) { |
336 for (i = 0; i < count; i++) { | 336 for (i = 0; i < count; i++) { |
337 if (mh == _dyld_get_image_header (i)) { | 337 if (mh == _dyld_get_image_header(i)) { |
338 val = _dyld_get_image_name (i); | 338 val = _dyld_get_image_name(i); |
339 break; | 339 break; |
340 } | 340 } |
341 } | 341 } |
342 } | 342 } |
343 return val; | 343 return val; |
346 /* Returns the mach_header for the module bu going through all the loaded images | 346 /* Returns the mach_header for the module bu going through all the loaded images |
347 * and finding the one with the same name as the module. There really ought to be | 347 * and finding the one with the same name as the module. There really ought to be |
348 * an api for doing this, would be faster, but there isn't one right now | 348 * an api for doing this, would be faster, but there isn't one right now |
349 */ | 349 */ |
350 static const struct mach_header * | 350 static const struct mach_header * |
351 get_mach_header_from_NSModule (NSModule mod) | 351 get_mach_header_from_NSModule(NSModule mod) |
352 { | 352 { |
353 const char *mod_name = NSNameOfModule (mod); | 353 const char *mod_name = NSNameOfModule(mod); |
354 const struct mach_header *mh = NULL; | 354 const struct mach_header *mh = NULL; |
355 unsigned long count = _dyld_image_count (); | 355 unsigned long count = _dyld_image_count(); |
356 unsigned long i; | 356 unsigned long i; |
357 debug ("Module name: %s", mod_name); | 357 debug("Module name: %s", mod_name); |
358 for (i = 0; i < count; i++) { | 358 for (i = 0; i < count; i++) { |
359 if (!SDL_strcmp (mod_name, _dyld_get_image_name (i))) { | 359 if (!SDL_strcmp(mod_name, _dyld_get_image_name(i))) { |
360 mh = _dyld_get_image_header (i); | 360 mh = _dyld_get_image_header(i); |
361 break; | 361 break; |
362 } | 362 } |
363 } | 363 } |
364 return mh; | 364 return mh; |
365 } | 365 } |
372 * list of colon seperated paths, we simply concat them and the two other paths | 372 * list of colon seperated paths, we simply concat them and the two other paths |
373 * into one big string, which we then can easily parse. | 373 * into one big string, which we then can easily parse. |
374 * Splitting this string into the actual path list is done by getSearchPath() | 374 * Splitting this string into the actual path list is done by getSearchPath() |
375 */ | 375 */ |
376 static const char * | 376 static const char * |
377 searchList () | 377 searchList() |
378 { | 378 { |
379 size_t buf_size; | 379 size_t buf_size; |
380 static char *buf = NULL; | 380 static char *buf = NULL; |
381 const char *ldlp = safegetenv ("LD_LIBRARY_PATH"); | 381 const char *ldlp = safegetenv("LD_LIBRARY_PATH"); |
382 const char *dyldlp = safegetenv ("DYLD_LIBRARY_PATH"); | 382 const char *dyldlp = safegetenv("DYLD_LIBRARY_PATH"); |
383 const char *stdpath = SDL_getenv ("DYLD_FALLBACK_LIBRARY_PATH"); | 383 const char *stdpath = SDL_getenv("DYLD_FALLBACK_LIBRARY_PATH"); |
384 if (!stdpath) | 384 if (!stdpath) |
385 stdpath = "/usr/local/lib:/lib:/usr/lib"; | 385 stdpath = "/usr/local/lib:/lib:/usr/lib"; |
386 if (!buf) { | 386 if (!buf) { |
387 buf_size = | 387 buf_size = |
388 SDL_strlen (ldlp) + SDL_strlen (dyldlp) + SDL_strlen (stdpath) + | 388 SDL_strlen(ldlp) + SDL_strlen(dyldlp) + SDL_strlen(stdpath) + 4; |
389 4; | 389 buf = SDL_malloc(buf_size); |
390 buf = SDL_malloc (buf_size); | 390 SDL_snprintf(buf, buf_size, "%s%s%s%s%s%c", dyldlp, |
391 SDL_snprintf (buf, buf_size, "%s%s%s%s%s%c", dyldlp, | 391 (dyldlp[0] ? ":" : ""), ldlp, (ldlp[0] ? ":" : ""), |
392 (dyldlp[0] ? ":" : ""), ldlp, (ldlp[0] ? ":" : ""), | 392 stdpath, '\0'); |
393 stdpath, '\0'); | |
394 } | 393 } |
395 return buf; | 394 return buf; |
396 } | 395 } |
397 | 396 |
398 /* Returns the ith search path from the list as computed by searchList() */ | 397 /* Returns the ith search path from the list as computed by searchList() */ |
399 static const char * | 398 static const char * |
400 getSearchPath (int i) | 399 getSearchPath(int i) |
401 { | 400 { |
402 static const char *list = 0; | 401 static const char *list = 0; |
403 static char **path = (char **) 0; | 402 static char **path = (char **) 0; |
404 static int end = 0; | 403 static int end = 0; |
405 static int numsize = MAX_SEARCH_PATHS; | 404 static int numsize = MAX_SEARCH_PATHS; |
407 /* So we can call SDL_free() in the "destructor" we use i=-1 to return the alloc'd array */ | 406 /* So we can call SDL_free() in the "destructor" we use i=-1 to return the alloc'd array */ |
408 if (i == -1) { | 407 if (i == -1) { |
409 return (const char *) path; | 408 return (const char *) path; |
410 } | 409 } |
411 if (!path) { | 410 if (!path) { |
412 path = (char **) SDL_calloc (MAX_SEARCH_PATHS, sizeof (char **)); | 411 path = (char **) SDL_calloc(MAX_SEARCH_PATHS, sizeof(char **)); |
413 } | 412 } |
414 if (!list && !end) | 413 if (!list && !end) |
415 list = searchList (); | 414 list = searchList(); |
416 if (i >= (numsize)) { | 415 if (i >= (numsize)) { |
417 debug ("Increasing size for long PATH"); | 416 debug("Increasing size for long PATH"); |
418 tmp = | 417 tmp = |
419 (char **) SDL_calloc ((MAX_SEARCH_PATHS + numsize), | 418 (char **) SDL_calloc((MAX_SEARCH_PATHS + numsize), |
420 sizeof (char **)); | 419 sizeof(char **)); |
421 if (tmp) { | 420 if (tmp) { |
422 SDL_memcpy (tmp, path, sizeof (char **) * numsize); | 421 SDL_memcpy(tmp, path, sizeof(char **) * numsize); |
423 SDL_free (path); | 422 SDL_free(path); |
424 path = tmp; | 423 path = tmp; |
425 numsize += MAX_SEARCH_PATHS; | 424 numsize += MAX_SEARCH_PATHS; |
426 } else { | 425 } else { |
427 return 0; | 426 return 0; |
428 } | 427 } |
429 } | 428 } |
430 | 429 |
431 while (!path[i] && !end) { | 430 while (!path[i] && !end) { |
432 path[i] = strsep ((char **) &list, ":"); | 431 path[i] = strsep((char **) &list, ":"); |
433 | 432 |
434 if (path[i][0] == 0) | 433 if (path[i][0] == 0) |
435 path[i] = 0; | 434 path[i] = 0; |
436 end = (list == 0); | 435 end = (list == 0); |
437 } | 436 } |
438 return path[i]; | 437 return path[i]; |
439 } | 438 } |
440 | 439 |
441 static const char * | 440 static const char * |
442 getFullPath (int i, const char *file) | 441 getFullPath(int i, const char *file) |
443 { | 442 { |
444 static char buf[PATH_MAX]; | 443 static char buf[PATH_MAX]; |
445 const char *path = getSearchPath (i); | 444 const char *path = getSearchPath(i); |
446 if (path) { | 445 if (path) { |
447 SDL_snprintf (buf, PATH_MAX, "%s/%s", path, file); | 446 SDL_snprintf(buf, PATH_MAX, "%s/%s", path, file); |
448 } | 447 } |
449 return path ? buf : 0; | 448 return path ? buf : 0; |
450 } | 449 } |
451 | 450 |
452 /* Given a file name, try to determine the full path for that file. Starts | 451 /* Given a file name, try to determine the full path for that file. Starts |
453 * its search in the current directory, and then tries all paths in the | 452 * its search in the current directory, and then tries all paths in the |
454 * search list in the order they are specified there. | 453 * search list in the order they are specified there. |
455 */ | 454 */ |
456 static const struct stat * | 455 static const struct stat * |
457 findFile (const char *file, const char **fullPath) | 456 findFile(const char *file, const char **fullPath) |
458 { | 457 { |
459 int i = 0; | 458 int i = 0; |
460 static struct stat sbuf; | 459 static struct stat sbuf; |
461 char *fileName; | 460 char *fileName; |
462 debug ("finding file %s", file); | 461 debug("finding file %s", file); |
463 *fullPath = file; | 462 *fullPath = file; |
464 if (0 == stat (file, &sbuf)) | 463 if (0 == stat(file, &sbuf)) |
465 return &sbuf; | 464 return &sbuf; |
466 if (SDL_strchr (file, '/')) | 465 if (SDL_strchr(file, '/')) |
467 return 0; /* If the path had a / we don't look in env var places */ | 466 return 0; /* If the path had a / we don't look in env var places */ |
468 fileName = NULL; | 467 fileName = NULL; |
469 if (!fileName) | 468 if (!fileName) |
470 fileName = (char *) file; | 469 fileName = (char *) file; |
471 while ((*fullPath = getFullPath (i++, fileName))) { | 470 while ((*fullPath = getFullPath(i++, fileName))) { |
472 if (0 == stat (*fullPath, &sbuf)) | 471 if (0 == stat(*fullPath, &sbuf)) |
473 return &sbuf; | 472 return &sbuf; |
474 } | 473 } |
475 ; | 474 ; |
476 return 0; | 475 return 0; |
477 } | 476 } |
478 | 477 |
479 /* Determine whether a given dlstatus is valid or not */ | 478 /* Determine whether a given dlstatus is valid or not */ |
480 static int | 479 static int |
481 isValidStatus (struct dlstatus *status) | 480 isValidStatus(struct dlstatus *status) |
482 { | 481 { |
483 /* Walk the list to verify status is contained in it */ | 482 /* Walk the list to verify status is contained in it */ |
484 struct dlstatus *dls = stqueue; | 483 struct dlstatus *dls = stqueue; |
485 while (dls && status != dls) | 484 while (dls && status != dls) |
486 dls = dls->next; | 485 dls = dls->next; |
487 if (dls == 0) | 486 if (dls == 0) |
488 error ("invalid handle"); | 487 error("invalid handle"); |
489 else if ((dls->module == 0) || (dls->refs == 0)) | 488 else if ((dls->module == 0) || (dls->refs == 0)) |
490 error ("handle to closed library"); | 489 error("handle to closed library"); |
491 else | 490 else |
492 return TRUE; | 491 return TRUE; |
493 return FALSE; | 492 return FALSE; |
494 } | 493 } |
495 | 494 |
496 static inline int | 495 static inline int |
497 isFlagSet (int mode, int flag) | 496 isFlagSet(int mode, int flag) |
498 { | 497 { |
499 return (mode & flag) == flag; | 498 return (mode & flag) == flag; |
500 } | 499 } |
501 | 500 |
502 static struct dlstatus * | 501 static struct dlstatus * |
503 lookupStatus (const struct stat *sbuf) | 502 lookupStatus(const struct stat *sbuf) |
504 { | 503 { |
505 struct dlstatus *dls = stqueue; | 504 struct dlstatus *dls = stqueue; |
506 debug ("looking for status"); | 505 debug("looking for status"); |
507 while (dls && ( /* isFlagSet(dls->mode, RTLD_UNSHARED) */ 0 | 506 while (dls && ( /* isFlagSet(dls->mode, RTLD_UNSHARED) */ 0 |
508 || sbuf->st_dev != dls->device | 507 || sbuf->st_dev != dls->device |
509 || sbuf->st_ino != dls->inode)) | 508 || sbuf->st_ino != dls->inode)) |
510 dls = dls->next; | 509 dls = dls->next; |
511 return dls; | 510 return dls; |
512 } | 511 } |
513 | 512 |
514 static void | 513 static void |
515 insertStatus (struct dlstatus *dls, const struct stat *sbuf) | 514 insertStatus(struct dlstatus *dls, const struct stat *sbuf) |
516 { | 515 { |
517 debug ("inserting status"); | 516 debug("inserting status"); |
518 dls->inode = sbuf->st_ino; | 517 dls->inode = sbuf->st_ino; |
519 dls->device = sbuf->st_dev; | 518 dls->device = sbuf->st_dev; |
520 dls->refs = 0; | 519 dls->refs = 0; |
521 dls->mode = 0; | 520 dls->mode = 0; |
522 if ((dls->flags & DL_IN_LIST) == 0) { | 521 if ((dls->flags & DL_IN_LIST) == 0) { |
525 dls->flags |= DL_IN_LIST; | 524 dls->flags |= DL_IN_LIST; |
526 } | 525 } |
527 } | 526 } |
528 | 527 |
529 static struct dlstatus * | 528 static struct dlstatus * |
530 allocStatus () | 529 allocStatus() |
531 { | 530 { |
532 struct dlstatus *dls; | 531 struct dlstatus *dls; |
533 #ifdef REUSE_STATUS | 532 #ifdef REUSE_STATUS |
534 dls = stqueue; | 533 dls = stqueue; |
535 while (dls && dls->module) | 534 while (dls && dls->module) |
536 dls = dls->next; | 535 dls = dls->next; |
537 if (!dls) | 536 if (!dls) |
538 #endif | 537 #endif |
539 dls = SDL_calloc (sizeof (*dls), 1); | 538 dls = SDL_calloc(sizeof(*dls), 1); |
540 return dls; | 539 return dls; |
541 } | 540 } |
542 | 541 |
543 static int | 542 static int |
544 promoteLocalToGlobal (struct dlstatus *dls) | 543 promoteLocalToGlobal(struct dlstatus *dls) |
545 { | 544 { |
546 static int (*p) (NSModule module) = 0; | 545 static int (*p) (NSModule module) = 0; |
547 debug ("promoting"); | 546 debug("promoting"); |
548 if (!p) | 547 if (!p) |
549 _dyld_func_lookup ("__dyld_NSMakePrivateModulePublic", (void **) &p); | 548 _dyld_func_lookup("__dyld_NSMakePrivateModulePublic", (void **) &p); |
550 return (dls->module == MAGIC_DYLIB_MOD) || (p && p (dls->module)); | 549 return (dls->module == MAGIC_DYLIB_MOD) || (p && p(dls->module)); |
551 } | 550 } |
552 | 551 |
553 static void * | 552 static void * |
554 reference (struct dlstatus *dls, int mode) | 553 reference(struct dlstatus *dls, int mode) |
555 { | 554 { |
556 if (dls) { | 555 if (dls) { |
557 if (dls->module == MAGIC_DYLIB_MOD && isFlagSet (mode, RTLD_LOCAL)) { | 556 if (dls->module == MAGIC_DYLIB_MOD && isFlagSet(mode, RTLD_LOCAL)) { |
558 warning ("trying to open a .dylib with RTLD_LOCAL"); | 557 warning("trying to open a .dylib with RTLD_LOCAL"); |
559 error ("unable to open a .dylib with RTLD_LOCAL"); | 558 error("unable to open a .dylib with RTLD_LOCAL"); |
560 return NULL; | 559 return NULL; |
561 } | 560 } |
562 if (isFlagSet (mode, RTLD_GLOBAL) && | 561 if (isFlagSet(mode, RTLD_GLOBAL) && !isFlagSet(dls->mode, RTLD_GLOBAL) |
563 !isFlagSet (dls->mode, RTLD_GLOBAL) | 562 && !promoteLocalToGlobal(dls)) { |
564 && !promoteLocalToGlobal (dls)) { | 563 error("unable to promote local module to global"); |
565 error ("unable to promote local module to global"); | |
566 return NULL; | 564 return NULL; |
567 } | 565 } |
568 dls->mode |= mode; | 566 dls->mode |= mode; |
569 dls->refs++; | 567 dls->refs++; |
570 } else | 568 } else |
571 debug ("reference called with NULL argument"); | 569 debug("reference called with NULL argument"); |
572 | 570 |
573 return dls; | 571 return dls; |
574 } | 572 } |
575 | 573 |
576 static const struct mach_header * | 574 static const struct mach_header * |
577 my_find_image (const char *name) | 575 my_find_image(const char *name) |
578 { | 576 { |
579 const struct mach_header *mh = 0; | 577 const struct mach_header *mh = 0; |
580 const char *id = NULL; | 578 const char *id = NULL; |
581 int i = _dyld_image_count (); | 579 int i = _dyld_image_count(); |
582 int j; | 580 int j; |
583 mh = (struct mach_header *) | 581 mh = (struct mach_header *) |
584 dyld_NSAddImage (name, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED | | 582 dyld_NSAddImage(name, NSADDIMAGE_OPTION_RETURN_ONLY_IF_LOADED | |
585 NSADDIMAGE_OPTION_RETURN_ON_ERROR); | 583 NSADDIMAGE_OPTION_RETURN_ON_ERROR); |
586 if (!mh) { | 584 if (!mh) { |
587 for (j = 0; j < i; j++) { | 585 for (j = 0; j < i; j++) { |
588 id = _dyld_get_image_name (j); | 586 id = _dyld_get_image_name(j); |
589 if (!SDL_strcmp (id, name)) { | 587 if (!SDL_strcmp(id, name)) { |
590 mh = _dyld_get_image_header (j); | 588 mh = _dyld_get_image_header(j); |
591 break; | 589 break; |
592 } | 590 } |
593 } | 591 } |
594 } | 592 } |
595 return mh; | 593 return mh; |
600 * then adding the dependencies for those libraries, so we should do the same... but we don't | 598 * then adding the dependencies for those libraries, so we should do the same... but we don't |
601 * bother adding the extra dependencies, if the symbols are neither in the loaded image nor | 599 * bother adding the extra dependencies, if the symbols are neither in the loaded image nor |
602 * any of it's direct dependencies, then it probably isn't there. | 600 * any of it's direct dependencies, then it probably isn't there. |
603 */ | 601 */ |
604 static NSSymbol | 602 static NSSymbol |
605 search_linked_libs (const struct mach_header *mh, const char *symbol) | 603 search_linked_libs(const struct mach_header *mh, const char *symbol) |
606 { | 604 { |
607 unsigned int n; | 605 unsigned int n; |
608 struct load_command *lc = 0; | 606 struct load_command *lc = 0; |
609 struct mach_header *wh; | 607 struct mach_header *wh; |
610 NSSymbol nssym = 0; | 608 NSSymbol nssym = 0; |
611 if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage | 609 if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage |
612 && dyld_NSLookupSymbolInImage) { | 610 && dyld_NSLookupSymbolInImage) { |
613 lc = (struct load_command *) ((char *) mh + | 611 lc = (struct load_command *) ((char *) mh + |
614 sizeof (struct mach_header)); | 612 sizeof(struct mach_header)); |
615 for (n = 0; n < mh->ncmds; | 613 for (n = 0; n < mh->ncmds; |
616 n++, lc = (struct load_command *) ((char *) lc + lc->cmdsize)) { | 614 n++, lc = (struct load_command *) ((char *) lc + lc->cmdsize)) { |
617 if ((LC_LOAD_DYLIB == lc->cmd) | 615 if ((LC_LOAD_DYLIB == lc->cmd) |
618 || (LC_LOAD_WEAK_DYLIB == lc->cmd)) { | 616 || (LC_LOAD_WEAK_DYLIB == lc->cmd)) { |
619 if ((wh = (struct mach_header *) | 617 if ((wh = (struct mach_header *) |
620 my_find_image ((char | 618 my_find_image((char |
621 *) (((struct dylib_command *) lc)-> | 619 *) (((struct dylib_command *) lc)-> |
622 dylib.name.offset + (char *) lc)))) { | 620 dylib.name.offset + (char *) lc)))) { |
623 if (dyld_NSIsSymbolNameDefinedInImage (wh, symbol)) { | 621 if (dyld_NSIsSymbolNameDefinedInImage(wh, symbol)) { |
624 nssym = dyld_NSLookupSymbolInImage (wh, | 622 nssym = dyld_NSLookupSymbolInImage(wh, |
625 symbol, | 623 symbol, |
626 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | 624 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
627 | | 625 | |
628 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); | 626 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); |
629 break; | 627 break; |
630 } | 628 } |
631 } | 629 } |
632 } | 630 } |
633 } | 631 } |
634 if ((!nssym) && NSIsSymbolNameDefined (symbol)) { | 632 if ((!nssym) && NSIsSymbolNameDefined(symbol)) { |
635 /* I've never seen this debug message... */ | 633 /* I've never seen this debug message... */ |
636 debug ("Symbol \"%s\" is defined but was not found", symbol); | 634 debug("Symbol \"%s\" is defined but was not found", symbol); |
637 } | 635 } |
638 } | 636 } |
639 return nssym; | 637 return nssym; |
640 } | 638 } |
641 | 639 |
642 /* Up to the caller to SDL_free() returned string */ | 640 /* Up to the caller to SDL_free() returned string */ |
643 static inline char * | 641 static inline char * |
644 dyld_error_str () | 642 dyld_error_str() |
645 { | 643 { |
646 NSLinkEditErrors dylder; | 644 NSLinkEditErrors dylder; |
647 int dylderno; | 645 int dylderno; |
648 const char *dylderrstr; | 646 const char *dylderrstr; |
649 const char *dyldfile; | 647 const char *dyldfile; |
650 char *retStr = NULL; | 648 char *retStr = NULL; |
651 NSLinkEditError (&dylder, &dylderno, &dyldfile, &dylderrstr); | 649 NSLinkEditError(&dylder, &dylderno, &dyldfile, &dylderrstr); |
652 if (dylderrstr && *dylderrstr) { | 650 if (dylderrstr && *dylderrstr) { |
653 retStr = SDL_strdup (dylderrstr); | 651 retStr = SDL_strdup(dylderrstr); |
654 } | 652 } |
655 return retStr; | 653 return retStr; |
656 } | 654 } |
657 | 655 |
658 static void * | 656 static void * |
659 dlsymIntern (struct dlstatus *dls, const char *symbol, int canSetError) | 657 dlsymIntern(struct dlstatus *dls, const char *symbol, int canSetError) |
660 { | 658 { |
661 NSSymbol nssym = 0; | 659 NSSymbol nssym = 0; |
662 #ifdef __GCC__ | 660 #ifdef __GCC__ |
663 void *caller = __builtin_return_address (1); /* Be *very* careful about inlining */ | 661 void *caller = __builtin_return_address(1); /* Be *very* careful about inlining */ |
664 #else | 662 #else |
665 void *caller = NULL; | 663 void *caller = NULL; |
666 #endif | 664 #endif |
667 const struct mach_header *caller_mh = 0; | 665 const struct mach_header *caller_mh = 0; |
668 char *savedErrorStr = NULL; | 666 char *savedErrorStr = NULL; |
669 resetdlerror (); | 667 resetdlerror(); |
670 #ifndef RTLD_SELF | 668 #ifndef RTLD_SELF |
671 #define RTLD_SELF ((void *) -3) | 669 #define RTLD_SELF ((void *) -3) |
672 #endif | 670 #endif |
673 if (NULL == dls) | 671 if (NULL == dls) |
674 dls = RTLD_SELF; | 672 dls = RTLD_SELF; |
675 if ((RTLD_NEXT == dls) || (RTLD_SELF == dls)) { | 673 if ((RTLD_NEXT == dls) || (RTLD_SELF == dls)) { |
676 if (dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage | 674 if (dyld_NSIsSymbolNameDefinedInImage && dyld_NSLookupSymbolInImage |
677 && caller) { | 675 && caller) { |
678 caller_mh = image_for_address (caller); | 676 caller_mh = image_for_address(caller); |
679 if (RTLD_SELF == dls) { | 677 if (RTLD_SELF == dls) { |
680 /* FIXME: We should be using the NSModule api, if SELF is an MH_BUNDLE | 678 /* FIXME: We should be using the NSModule api, if SELF is an MH_BUNDLE |
681 * But it appears to work anyway, and looking at the code in dyld_libfuncs.c | 679 * But it appears to work anyway, and looking at the code in dyld_libfuncs.c |
682 * this is acceptable. | 680 * this is acceptable. |
683 */ | 681 */ |
684 if (dyld_NSIsSymbolNameDefinedInImage (caller_mh, symbol)) { | 682 if (dyld_NSIsSymbolNameDefinedInImage(caller_mh, symbol)) { |
685 nssym = dyld_NSLookupSymbolInImage (caller_mh, | 683 nssym = dyld_NSLookupSymbolInImage(caller_mh, |
686 symbol, | 684 symbol, |
687 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | 685 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
688 | | 686 | |
689 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); | 687 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); |
690 } | 688 } |
691 } | 689 } |
692 if (!nssym) { | 690 if (!nssym) { |
693 if (RTLD_SELF == dls) | 691 if (RTLD_SELF == dls) |
694 savedErrorStr = dyld_error_str (); | 692 savedErrorStr = dyld_error_str(); |
695 nssym = search_linked_libs (caller_mh, symbol); | 693 nssym = search_linked_libs(caller_mh, symbol); |
696 } | 694 } |
697 } else { | 695 } else { |
698 if (canSetError) | 696 if (canSetError) |
699 error ("RTLD_SELF and RTLD_NEXT are not supported"); | 697 error("RTLD_SELF and RTLD_NEXT are not supported"); |
700 return NULL; | 698 return NULL; |
701 } | 699 } |
702 } | 700 } |
703 if (!nssym) { | 701 if (!nssym) { |
704 | 702 |
705 if (RTLD_DEFAULT == dls) { | 703 if (RTLD_DEFAULT == dls) { |
706 dls = &mainStatus; | 704 dls = &mainStatus; |
707 } | 705 } |
708 if (!isValidStatus (dls)) | 706 if (!isValidStatus(dls)) |
709 return NULL; | 707 return NULL; |
710 | 708 |
711 if (dls->module != MAGIC_DYLIB_MOD) { | 709 if (dls->module != MAGIC_DYLIB_MOD) { |
712 nssym = NSLookupSymbolInModule (dls->module, symbol); | 710 nssym = NSLookupSymbolInModule(dls->module, symbol); |
713 if (!nssym && NSIsSymbolNameDefined (symbol)) { | 711 if (!nssym && NSIsSymbolNameDefined(symbol)) { |
714 debug ("Searching dependencies"); | 712 debug("Searching dependencies"); |
715 savedErrorStr = dyld_error_str (); | 713 savedErrorStr = dyld_error_str(); |
716 nssym = | 714 nssym = |
717 search_linked_libs (get_mach_header_from_NSModule | 715 search_linked_libs(get_mach_header_from_NSModule |
718 (dls->module), symbol); | 716 (dls->module), symbol); |
719 } | 717 } |
720 } else if (dls->lib && dyld_NSIsSymbolNameDefinedInImage | 718 } else if (dls->lib && dyld_NSIsSymbolNameDefinedInImage |
721 && dyld_NSLookupSymbolInImage) { | 719 && dyld_NSLookupSymbolInImage) { |
722 if (dyld_NSIsSymbolNameDefinedInImage (dls->lib, symbol)) { | 720 if (dyld_NSIsSymbolNameDefinedInImage(dls->lib, symbol)) { |
723 nssym = dyld_NSLookupSymbolInImage (dls->lib, | 721 nssym = dyld_NSLookupSymbolInImage(dls->lib, |
724 symbol, | 722 symbol, |
725 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | 723 NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
726 | | 724 | |
727 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); | 725 NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); |
728 } else if (NSIsSymbolNameDefined (symbol)) { | 726 } else if (NSIsSymbolNameDefined(symbol)) { |
729 debug ("Searching dependencies"); | 727 debug("Searching dependencies"); |
730 savedErrorStr = dyld_error_str (); | 728 savedErrorStr = dyld_error_str(); |
731 nssym = search_linked_libs (dls->lib, symbol); | 729 nssym = search_linked_libs(dls->lib, symbol); |
732 } | 730 } |
733 } else if (dls->module == MAGIC_DYLIB_MOD) { | 731 } else if (dls->module == MAGIC_DYLIB_MOD) { |
734 /* Global context, use NSLookupAndBindSymbol */ | 732 /* Global context, use NSLookupAndBindSymbol */ |
735 if (NSIsSymbolNameDefined (symbol)) { | 733 if (NSIsSymbolNameDefined(symbol)) { |
736 /* There doesn't seem to be a return on error option for this call??? | 734 /* There doesn't seem to be a return on error option for this call??? |
737 this is potentially broken, if binding fails, it will improperly | 735 this is potentially broken, if binding fails, it will improperly |
738 exit the application. */ | 736 exit the application. */ |
739 nssym = NSLookupAndBindSymbol (symbol); | 737 nssym = NSLookupAndBindSymbol(symbol); |
740 } else { | 738 } else { |
741 if (savedErrorStr) | 739 if (savedErrorStr) |
742 SDL_free (savedErrorStr); | 740 SDL_free(savedErrorStr); |
743 savedErrorStr = SDL_malloc (256); | 741 savedErrorStr = SDL_malloc(256); |
744 SDL_snprintf (savedErrorStr, 256, | 742 SDL_snprintf(savedErrorStr, 256, |
745 "Symbol \"%s\" not in global context", symbol); | 743 "Symbol \"%s\" not in global context", symbol); |
746 } | 744 } |
747 } | 745 } |
748 } | 746 } |
749 /* Error reporting */ | 747 /* Error reporting */ |
750 if (!nssym) { | 748 if (!nssym) { |
751 if (!savedErrorStr || !SDL_strlen (savedErrorStr)) { | 749 if (!savedErrorStr || !SDL_strlen(savedErrorStr)) { |
752 if (savedErrorStr) | 750 if (savedErrorStr) |
753 SDL_free (savedErrorStr); | 751 SDL_free(savedErrorStr); |
754 savedErrorStr = SDL_malloc (256); | 752 savedErrorStr = SDL_malloc(256); |
755 SDL_snprintf (savedErrorStr, 256, "Symbol \"%s\" not found", | 753 SDL_snprintf(savedErrorStr, 256, "Symbol \"%s\" not found", |
756 symbol); | 754 symbol); |
757 } | 755 } |
758 if (canSetError) { | 756 if (canSetError) { |
759 error (savedErrorStr); | 757 error(savedErrorStr); |
760 } else { | 758 } else { |
761 debug (savedErrorStr); | 759 debug(savedErrorStr); |
762 } | 760 } |
763 if (savedErrorStr) | 761 if (savedErrorStr) |
764 SDL_free (savedErrorStr); | 762 SDL_free(savedErrorStr); |
765 return NULL; | 763 return NULL; |
766 } | 764 } |
767 return NSAddressOfSymbol (nssym); | 765 return NSAddressOfSymbol(nssym); |
768 } | 766 } |
769 | 767 |
770 static struct dlstatus * | 768 static struct dlstatus * |
771 loadModule (const char *path, const struct stat *sbuf, int mode) | 769 loadModule(const char *path, const struct stat *sbuf, int mode) |
772 { | 770 { |
773 NSObjectFileImage ofi = 0; | 771 NSObjectFileImage ofi = 0; |
774 NSObjectFileImageReturnCode ofirc; | 772 NSObjectFileImageReturnCode ofirc; |
775 struct dlstatus *dls; | 773 struct dlstatus *dls; |
776 NSLinkEditErrors ler; | 774 NSLinkEditErrors ler; |
777 int lerno; | 775 int lerno; |
778 const char *errstr; | 776 const char *errstr; |
779 const char *file; | 777 const char *file; |
780 void (*init) (void); | 778 void (*init) (void); |
781 | 779 |
782 ofirc = NSCreateObjectFileImageFromFile (path, &ofi); | 780 ofirc = NSCreateObjectFileImageFromFile(path, &ofi); |
783 switch (ofirc) { | 781 switch (ofirc) { |
784 case NSObjectFileImageSuccess: | 782 case NSObjectFileImageSuccess: |
785 break; | 783 break; |
786 case NSObjectFileImageInappropriateFile: | 784 case NSObjectFileImageInappropriateFile: |
787 if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage | 785 if (dyld_NSAddImage && dyld_NSIsSymbolNameDefinedInImage |
788 && dyld_NSLookupSymbolInImage) { | 786 && dyld_NSLookupSymbolInImage) { |
789 if (isFlagSet (mode, RTLD_LOCAL)) { | 787 if (isFlagSet(mode, RTLD_LOCAL)) { |
790 warning ("trying to open a .dylib with RTLD_LOCAL"); | 788 warning("trying to open a .dylib with RTLD_LOCAL"); |
791 error ("unable to open this file with RTLD_LOCAL"); | 789 error("unable to open this file with RTLD_LOCAL"); |
792 return NULL; | 790 return NULL; |
793 } | 791 } |
794 } else { | 792 } else { |
795 error ("opening this file is unsupported on this system"); | 793 error("opening this file is unsupported on this system"); |
796 return NULL; | 794 return NULL; |
797 } | 795 } |
798 break; | 796 break; |
799 case NSObjectFileImageFailure: | 797 case NSObjectFileImageFailure: |
800 error ("object file setup failure"); | 798 error("object file setup failure"); |
801 return NULL; | 799 return NULL; |
802 case NSObjectFileImageArch: | 800 case NSObjectFileImageArch: |
803 error ("no object for this architecture"); | 801 error("no object for this architecture"); |
804 return NULL; | 802 return NULL; |
805 case NSObjectFileImageFormat: | 803 case NSObjectFileImageFormat: |
806 error ("bad object file format"); | 804 error("bad object file format"); |
807 return NULL; | 805 return NULL; |
808 case NSObjectFileImageAccess: | 806 case NSObjectFileImageAccess: |
809 error ("can't read object file"); | 807 error("can't read object file"); |
810 return NULL; | 808 return NULL; |
811 default: | 809 default: |
812 error ("unknown error from NSCreateObjectFileImageFromFile()"); | 810 error("unknown error from NSCreateObjectFileImageFromFile()"); |
813 return NULL; | 811 return NULL; |
814 } | 812 } |
815 dls = lookupStatus (sbuf); | 813 dls = lookupStatus(sbuf); |
816 if (!dls) { | 814 if (!dls) { |
817 dls = allocStatus (); | 815 dls = allocStatus(); |
818 } | 816 } |
819 if (!dls) { | 817 if (!dls) { |
820 error ("unable to allocate memory"); | 818 error("unable to allocate memory"); |
821 return NULL; | 819 return NULL; |
822 } | 820 } |
823 // dls->lib = 0; | 821 // dls->lib = 0; |
824 if (ofirc == NSObjectFileImageInappropriateFile) { | 822 if (ofirc == NSObjectFileImageInappropriateFile) { |
825 if ((dls->lib = | 823 if ((dls->lib = |
826 dyld_NSAddImage (path, NSADDIMAGE_OPTION_RETURN_ON_ERROR))) { | 824 dyld_NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR))) { |
827 debug ("Dynamic lib loaded at %ld", dls->lib); | 825 debug("Dynamic lib loaded at %ld", dls->lib); |
828 ofi = MAGIC_DYLIB_OFI; | 826 ofi = MAGIC_DYLIB_OFI; |
829 dls->module = MAGIC_DYLIB_MOD; | 827 dls->module = MAGIC_DYLIB_MOD; |
830 ofirc = NSObjectFileImageSuccess; | 828 ofirc = NSObjectFileImageSuccess; |
831 /* Although it is possible with a bit of work to modify this so it works and | 829 /* Although it is possible with a bit of work to modify this so it works and |
832 functions with RTLD_NOW, I don't deem it necessary at the moment */ | 830 functions with RTLD_NOW, I don't deem it necessary at the moment */ |
833 } | 831 } |
834 if (!(dls->module)) { | 832 if (!(dls->module)) { |
835 NSLinkEditError (&ler, &lerno, &file, &errstr); | 833 NSLinkEditError(&ler, &lerno, &file, &errstr); |
836 if (!errstr || (!SDL_strlen (errstr))) | 834 if (!errstr || (!SDL_strlen(errstr))) |
837 error ("Can't open this file type"); | 835 error("Can't open this file type"); |
838 else | 836 else |
839 error (errstr); | 837 error(errstr); |
840 if ((dls->flags & DL_IN_LIST) == 0) { | 838 if ((dls->flags & DL_IN_LIST) == 0) { |
841 SDL_free (dls); | 839 SDL_free(dls); |
842 } | 840 } |
843 return NULL; | 841 return NULL; |
844 } | 842 } |
845 } else { | 843 } else { |
846 dls->module = NSLinkModule (ofi, path, | 844 dls->module = NSLinkModule(ofi, path, |
847 NSLINKMODULE_OPTION_RETURN_ON_ERROR | | 845 NSLINKMODULE_OPTION_RETURN_ON_ERROR | |
848 NSLINKMODULE_OPTION_PRIVATE | | 846 NSLINKMODULE_OPTION_PRIVATE | |
849 (isFlagSet (mode, RTLD_NOW) ? | 847 (isFlagSet(mode, RTLD_NOW) ? |
850 NSLINKMODULE_OPTION_BINDNOW : 0)); | 848 NSLINKMODULE_OPTION_BINDNOW : 0)); |
851 NSDestroyObjectFileImage (ofi); | 849 NSDestroyObjectFileImage(ofi); |
852 if (dls->module) { | 850 if (dls->module) { |
853 dls->lib = get_mach_header_from_NSModule (dls->module); | 851 dls->lib = get_mach_header_from_NSModule(dls->module); |
854 } | 852 } |
855 } | 853 } |
856 if (!dls->module) { | 854 if (!dls->module) { |
857 NSLinkEditError (&ler, &lerno, &file, &errstr); | 855 NSLinkEditError(&ler, &lerno, &file, &errstr); |
858 if ((dls->flags & DL_IN_LIST) == 0) { | 856 if ((dls->flags & DL_IN_LIST) == 0) { |
859 SDL_free (dls); | 857 SDL_free(dls); |
860 } | 858 } |
861 error (errstr); | 859 error(errstr); |
862 return NULL; | 860 return NULL; |
863 } | 861 } |
864 | 862 |
865 insertStatus (dls, sbuf); | 863 insertStatus(dls, sbuf); |
866 dls = reference (dls, mode); | 864 dls = reference(dls, mode); |
867 if ((init = dlsymIntern (dls, "__init", 0))) { | 865 if ((init = dlsymIntern(dls, "__init", 0))) { |
868 debug ("calling _init()"); | 866 debug("calling _init()"); |
869 init (); | 867 init(); |
870 } | 868 } |
871 return dls; | 869 return dls; |
872 } | 870 } |
873 | 871 |
874 inline static void | 872 inline static void |
875 dlcompat_init_check (void) | 873 dlcompat_init_check(void) |
876 { | 874 { |
877 static pthread_mutex_t l = PTHREAD_MUTEX_INITIALIZER; | 875 static pthread_mutex_t l = PTHREAD_MUTEX_INITIALIZER; |
878 static int init_done = 0; | 876 static int init_done = 0; |
879 | 877 |
880 pthread_mutex_lock (&l); | 878 pthread_mutex_lock(&l); |
881 if (!init_done) { | 879 if (!init_done) { |
882 dlcompat_init_func (); | 880 dlcompat_init_func(); |
883 init_done = 1; | 881 init_done = 1; |
884 } | 882 } |
885 pthread_mutex_unlock (&l); | 883 pthread_mutex_unlock(&l); |
886 } | 884 } |
887 | 885 |
888 static void | 886 static void |
889 dlcompat_init_func (void) | 887 dlcompat_init_func(void) |
890 { | 888 { |
891 _dyld_func_lookup ("__dyld_NSAddImage", (void **) &dyld_NSAddImage); | 889 _dyld_func_lookup("__dyld_NSAddImage", (void **) &dyld_NSAddImage); |
892 _dyld_func_lookup ("__dyld_NSIsSymbolNameDefinedInImage", | 890 _dyld_func_lookup("__dyld_NSIsSymbolNameDefinedInImage", |
893 (void **) &dyld_NSIsSymbolNameDefinedInImage); | 891 (void **) &dyld_NSIsSymbolNameDefinedInImage); |
894 _dyld_func_lookup ("__dyld_NSLookupSymbolInImage", | 892 _dyld_func_lookup("__dyld_NSLookupSymbolInImage", |
895 (void **) &dyld_NSLookupSymbolInImage); | 893 (void **) &dyld_NSLookupSymbolInImage); |
896 if (pthread_mutex_init (&dlcompat_mutex, NULL)) | 894 if (pthread_mutex_init(&dlcompat_mutex, NULL)) |
897 exit (1); | 895 exit(1); |
898 if (pthread_key_create (&dlerror_key, &dlerrorfree)) | 896 if (pthread_key_create(&dlerror_key, &dlerrorfree)) |
899 exit (1); | 897 exit(1); |
900 } | 898 } |
901 | 899 |
902 static void | 900 static void |
903 resetdlerror () | 901 resetdlerror() |
904 { | 902 { |
905 struct dlthread *tss; | 903 struct dlthread *tss; |
906 tss = pthread_getspecific (dlerror_key); | 904 tss = pthread_getspecific(dlerror_key); |
907 tss->errset = 0; | 905 tss->errset = 0; |
908 } | 906 } |
909 | 907 |
910 static void | 908 static void |
911 dlerrorfree (void *data) | 909 dlerrorfree(void *data) |
912 { | 910 { |
913 SDL_free (data); | 911 SDL_free(data); |
914 } | 912 } |
915 | 913 |
916 /* We kind of want a recursive lock here, but meet a little trouble | 914 /* We kind of want a recursive lock here, but meet a little trouble |
917 * because they are not available pre OS X 10.2, so we fake it | 915 * because they are not available pre OS X 10.2, so we fake it |
918 * using thread specific storage to keep a lock count | 916 * using thread specific storage to keep a lock count |
919 */ | 917 */ |
920 static inline void | 918 static inline void |
921 dolock (void) | 919 dolock(void) |
922 { | 920 { |
923 int err = 0; | 921 int err = 0; |
924 struct dlthread *tss; | 922 struct dlthread *tss; |
925 dlcompat_init_check (); | 923 dlcompat_init_check(); |
926 tss = pthread_getspecific (dlerror_key); | 924 tss = pthread_getspecific(dlerror_key); |
927 if (!tss) { | 925 if (!tss) { |
928 tss = SDL_malloc (sizeof (struct dlthread)); | 926 tss = SDL_malloc(sizeof(struct dlthread)); |
929 tss->lockcnt = 0; | 927 tss->lockcnt = 0; |
930 tss->errset = 0; | 928 tss->errset = 0; |
931 if (pthread_setspecific (dlerror_key, tss)) { | 929 if (pthread_setspecific(dlerror_key, tss)) { |
932 fprintf (stderr, "dlcompat: pthread_setspecific failed\n"); | 930 fprintf(stderr, "dlcompat: pthread_setspecific failed\n"); |
933 exit (1); | 931 exit(1); |
934 } | 932 } |
935 } | 933 } |
936 if (!tss->lockcnt) | 934 if (!tss->lockcnt) |
937 err = pthread_mutex_lock (&dlcompat_mutex); | 935 err = pthread_mutex_lock(&dlcompat_mutex); |
938 tss->lockcnt = tss->lockcnt + 1; | 936 tss->lockcnt = tss->lockcnt + 1; |
939 if (err) | 937 if (err) |
940 exit (err); | 938 exit(err); |
941 } | 939 } |
942 | 940 |
943 static inline void | 941 static inline void |
944 dounlock (void) | 942 dounlock(void) |
945 { | 943 { |
946 int err = 0; | 944 int err = 0; |
947 struct dlthread *tss; | 945 struct dlthread *tss; |
948 tss = pthread_getspecific (dlerror_key); | 946 tss = pthread_getspecific(dlerror_key); |
949 tss->lockcnt = tss->lockcnt - 1; | 947 tss->lockcnt = tss->lockcnt - 1; |
950 if (!tss->lockcnt) | 948 if (!tss->lockcnt) |
951 err = pthread_mutex_unlock (&dlcompat_mutex); | 949 err = pthread_mutex_unlock(&dlcompat_mutex); |
952 if (err) | 950 if (err) |
953 exit (err); | 951 exit(err); |
954 } | 952 } |
955 | 953 |
956 static void * | 954 static void * |
957 SDL_OSX_dlopen (const char *path, int mode) | 955 SDL_OSX_dlopen(const char *path, int mode) |
958 { | 956 { |
959 const struct stat *sbuf; | 957 const struct stat *sbuf; |
960 struct dlstatus *dls; | 958 struct dlstatus *dls; |
961 const char *fullPath; | 959 const char *fullPath; |
962 | 960 |
963 dolock (); | 961 dolock(); |
964 resetdlerror (); | 962 resetdlerror(); |
965 if (!path) { | 963 if (!path) { |
966 dls = &mainStatus; | 964 dls = &mainStatus; |
967 goto dlopenok; | 965 goto dlopenok; |
968 } | 966 } |
969 if (!(sbuf = findFile (path, &fullPath))) { | 967 if (!(sbuf = findFile(path, &fullPath))) { |
970 error ("file \"%s\" not found", path); | 968 error("file \"%s\" not found", path); |
971 goto dlopenerror; | 969 goto dlopenerror; |
972 } | 970 } |
973 /* Now checks that it hasn't been closed already */ | 971 /* Now checks that it hasn't been closed already */ |
974 if ((dls = lookupStatus (sbuf)) && (dls->refs > 0)) { | 972 if ((dls = lookupStatus(sbuf)) && (dls->refs > 0)) { |
975 /* debug("status found"); */ | 973 /* debug("status found"); */ |
976 dls = reference (dls, mode); | 974 dls = reference(dls, mode); |
977 goto dlopenok; | 975 goto dlopenok; |
978 } | 976 } |
979 #ifdef RTLD_NOLOAD | 977 #ifdef RTLD_NOLOAD |
980 if (isFlagSet (mode, RTLD_NOLOAD)) { | 978 if (isFlagSet(mode, RTLD_NOLOAD)) { |
981 error ("no existing handle and RTLD_NOLOAD specified"); | 979 error("no existing handle and RTLD_NOLOAD specified"); |
982 goto dlopenerror; | 980 goto dlopenerror; |
983 } | 981 } |
984 #endif | 982 #endif |
985 if (isFlagSet (mode, RTLD_LAZY) && isFlagSet (mode, RTLD_NOW)) { | 983 if (isFlagSet(mode, RTLD_LAZY) && isFlagSet(mode, RTLD_NOW)) { |
986 error ("how can I load something both RTLD_LAZY and RTLD_NOW?"); | 984 error("how can I load something both RTLD_LAZY and RTLD_NOW?"); |
987 goto dlopenerror; | 985 goto dlopenerror; |
988 } | 986 } |
989 dls = loadModule (fullPath, sbuf, mode); | 987 dls = loadModule(fullPath, sbuf, mode); |
990 | 988 |
991 dlopenok: | 989 dlopenok: |
992 dounlock (); | 990 dounlock(); |
993 return (void *) dls; | 991 return (void *) dls; |
994 dlopenerror: | 992 dlopenerror: |
995 dounlock (); | 993 dounlock(); |
996 return NULL; | 994 return NULL; |
997 } | 995 } |
998 | 996 |
999 #if !FINK_BUILD | 997 #if !FINK_BUILD |
1000 static void * | 998 static void * |
1001 SDL_OSX_dlsym (void *dl_restrict handle, const char *dl_restrict symbol) | 999 SDL_OSX_dlsym(void *dl_restrict handle, const char *dl_restrict symbol) |
1002 { | 1000 { |
1003 int sym_len = SDL_strlen (symbol); | 1001 int sym_len = SDL_strlen(symbol); |
1004 void *value = NULL; | 1002 void *value = NULL; |
1005 char *malloc_sym = NULL; | 1003 char *malloc_sym = NULL; |
1006 dolock (); | 1004 dolock(); |
1007 malloc_sym = SDL_malloc (sym_len + 2); | 1005 malloc_sym = SDL_malloc(sym_len + 2); |
1008 if (malloc_sym) { | 1006 if (malloc_sym) { |
1009 SDL_snprintf (malloc_sym, sym_len + 2, "_%s", symbol); | 1007 SDL_snprintf(malloc_sym, sym_len + 2, "_%s", symbol); |
1010 value = dlsymIntern (handle, malloc_sym, 1); | 1008 value = dlsymIntern(handle, malloc_sym, 1); |
1011 SDL_free (malloc_sym); | 1009 SDL_free(malloc_sym); |
1012 } else { | 1010 } else { |
1013 error ("Unable to allocate memory"); | 1011 error("Unable to allocate memory"); |
1014 goto dlsymerror; | 1012 goto dlsymerror; |
1015 } | 1013 } |
1016 dounlock (); | 1014 dounlock(); |
1017 return value; | 1015 return value; |
1018 dlsymerror: | 1016 dlsymerror: |
1019 dounlock (); | 1017 dounlock(); |
1020 return NULL; | 1018 return NULL; |
1021 } | 1019 } |
1022 #endif | 1020 #endif |
1023 | 1021 |
1024 #if FINK_BUILD | 1022 #if FINK_BUILD |
1025 | 1023 |
1026 static void * | 1024 static void * |
1027 dlsym_prepend_underscore (void *handle, const char *symbol) | 1025 dlsym_prepend_underscore(void *handle, const char *symbol) |
1028 { | 1026 { |
1029 void *answer; | 1027 void *answer; |
1030 dolock (); | 1028 dolock(); |
1031 answer = dlsym_prepend_underscore_intern (handle, symbol); | 1029 answer = dlsym_prepend_underscore_intern(handle, symbol); |
1032 dounlock (); | 1030 dounlock(); |
1033 return answer; | 1031 return answer; |
1034 } | 1032 } |
1035 | 1033 |
1036 static void * | 1034 static void * |
1037 dlsym_prepend_underscore_intern (void *handle, const char *symbol) | 1035 dlsym_prepend_underscore_intern(void *handle, const char *symbol) |
1038 { | 1036 { |
1039 /* | 1037 /* |
1040 * A quick and easy way for porting packages which call dlsym(handle,"sym") | 1038 * A quick and easy way for porting packages which call dlsym(handle,"sym") |
1041 * If the porter adds -Ddlsym=dlsym_prepend_underscore to the CFLAGS then | 1039 * If the porter adds -Ddlsym=dlsym_prepend_underscore to the CFLAGS then |
1042 * this function will be called, and will add the required underscore. | 1040 * this function will be called, and will add the required underscore. |
1043 * | 1041 * |
1044 * Note that I haven't figured out yet which should be "standard", prepend | 1042 * Note that I haven't figured out yet which should be "standard", prepend |
1045 * the underscore always, or not at all. These global functions need to go away | 1043 * the underscore always, or not at all. These global functions need to go away |
1046 * for opendarwin. | 1044 * for opendarwin. |
1047 */ | 1045 */ |
1048 int sym_len = SDL_strlen (symbol); | 1046 int sym_len = SDL_strlen(symbol); |
1049 void *value = NULL; | 1047 void *value = NULL; |
1050 char *malloc_sym = NULL; | 1048 char *malloc_sym = NULL; |
1051 malloc_sym = SDL_malloc (sym_len + 2); | 1049 malloc_sym = SDL_malloc(sym_len + 2); |
1052 if (malloc_sym) { | 1050 if (malloc_sym) { |
1053 SDL_snprintf (malloc_sym, sym_len + 2, "_%s", symbol); | 1051 SDL_snprintf(malloc_sym, sym_len + 2, "_%s", symbol); |
1054 value = dlsymIntern (handle, malloc_sym, 1); | 1052 value = dlsymIntern(handle, malloc_sym, 1); |
1055 SDL_free (malloc_sym); | 1053 SDL_free(malloc_sym); |
1056 } else { | 1054 } else { |
1057 error ("Unable to allocate memory"); | 1055 error("Unable to allocate memory"); |
1058 } | 1056 } |
1059 return value; | 1057 return value; |
1060 } | 1058 } |
1061 | 1059 |
1062 static void * | 1060 static void * |
1063 dlsym_auto_underscore (void *handle, const char *symbol) | 1061 dlsym_auto_underscore(void *handle, const char *symbol) |
1064 { | 1062 { |
1065 void *answer; | 1063 void *answer; |
1066 dolock (); | 1064 dolock(); |
1067 answer = dlsym_auto_underscore_intern (handle, symbol); | 1065 answer = dlsym_auto_underscore_intern(handle, symbol); |
1068 dounlock (); | 1066 dounlock(); |
1069 return answer; | 1067 return answer; |
1070 | 1068 |
1071 } | 1069 } |
1072 static void * | 1070 static void * |
1073 dlsym_auto_underscore_intern (void *handle, const char *symbol) | 1071 dlsym_auto_underscore_intern(void *handle, const char *symbol) |
1074 { | 1072 { |
1075 struct dlstatus *dls = handle; | 1073 struct dlstatus *dls = handle; |
1076 void *addr = 0; | 1074 void *addr = 0; |
1077 addr = dlsymIntern (dls, symbol, 0); | 1075 addr = dlsymIntern(dls, symbol, 0); |
1078 if (!addr) | 1076 if (!addr) |
1079 addr = dlsym_prepend_underscore_intern (handle, symbol); | 1077 addr = dlsym_prepend_underscore_intern(handle, symbol); |
1080 return addr; | 1078 return addr; |
1081 } | 1079 } |
1082 | 1080 |
1083 | 1081 |
1084 static void * | 1082 static void * |
1085 SDL_OSX_dlsym (void *dl_restrict handle, const char *dl_restrict symbol) | 1083 SDL_OSX_dlsym(void *dl_restrict handle, const char *dl_restrict symbol) |
1086 { | 1084 { |
1087 struct dlstatus *dls = handle; | 1085 struct dlstatus *dls = handle; |
1088 void *addr = 0; | 1086 void *addr = 0; |
1089 dolock (); | 1087 dolock(); |
1090 addr = dlsymIntern (dls, symbol, 1); | 1088 addr = dlsymIntern(dls, symbol, 1); |
1091 dounlock (); | 1089 dounlock(); |
1092 return addr; | 1090 return addr; |
1093 } | 1091 } |
1094 #endif | 1092 #endif |
1095 | 1093 |
1096 static int | 1094 static int |
1097 SDL_OSX_dlclose (void *handle) | 1095 SDL_OSX_dlclose(void *handle) |
1098 { | 1096 { |
1099 struct dlstatus *dls = handle; | 1097 struct dlstatus *dls = handle; |
1100 dolock (); | 1098 dolock(); |
1101 resetdlerror (); | 1099 resetdlerror(); |
1102 if (!isValidStatus (dls)) { | 1100 if (!isValidStatus(dls)) { |
1103 goto dlcloseerror; | 1101 goto dlcloseerror; |
1104 } | 1102 } |
1105 if (dls->module == MAGIC_DYLIB_MOD) { | 1103 if (dls->module == MAGIC_DYLIB_MOD) { |
1106 const char *name; | 1104 const char *name; |
1107 if (!dls->lib) { | 1105 if (!dls->lib) { |
1108 name = "global context"; | 1106 name = "global context"; |
1109 } else { | 1107 } else { |
1110 name = get_lib_name (dls->lib); | 1108 name = get_lib_name(dls->lib); |
1111 } | 1109 } |
1112 warning ("trying to close a .dylib!"); | 1110 warning("trying to close a .dylib!"); |
1113 error ("Not closing \"%s\" - dynamic libraries cannot be closed", | 1111 error("Not closing \"%s\" - dynamic libraries cannot be closed", |
1114 name); | 1112 name); |
1115 goto dlcloseerror; | 1113 goto dlcloseerror; |
1116 } | 1114 } |
1117 if (!dls->module) { | 1115 if (!dls->module) { |
1118 error ("module already closed"); | 1116 error("module already closed"); |
1119 goto dlcloseerror; | 1117 goto dlcloseerror; |
1120 } | 1118 } |
1121 | 1119 |
1122 if (dls->refs == 1) { | 1120 if (dls->refs == 1) { |
1123 unsigned long options = 0; | 1121 unsigned long options = 0; |
1124 void (*fini) (void); | 1122 void (*fini) (void); |
1125 if ((fini = dlsymIntern (dls, "__fini", 0))) { | 1123 if ((fini = dlsymIntern(dls, "__fini", 0))) { |
1126 debug ("calling _fini()"); | 1124 debug("calling _fini()"); |
1127 fini (); | 1125 fini(); |
1128 } | 1126 } |
1129 options |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES; | 1127 options |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES; |
1130 #ifdef RTLD_NODELETE | 1128 #ifdef RTLD_NODELETE |
1131 if (isFlagSet (dls->mode, RTLD_NODELETE)) | 1129 if (isFlagSet(dls->mode, RTLD_NODELETE)) |
1132 options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED; | 1130 options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED; |
1133 #endif | 1131 #endif |
1134 if (!NSUnLinkModule (dls->module, options)) { | 1132 if (!NSUnLinkModule(dls->module, options)) { |
1135 error ("unable to unlink module"); | 1133 error("unable to unlink module"); |
1136 goto dlcloseerror; | 1134 goto dlcloseerror; |
1137 } | 1135 } |
1138 dls->refs--; | 1136 dls->refs--; |
1139 dls->module = 0; | 1137 dls->module = 0; |
1140 /* Note: the dlstatus struct dls is neither removed from the list | 1138 /* Note: the dlstatus struct dls is neither removed from the list |
1141 * nor is the memory it occupies freed. This shouldn't pose a | 1139 * nor is the memory it occupies freed. This shouldn't pose a |
1142 * problem in mostly all cases, though. | 1140 * problem in mostly all cases, though. |
1143 */ | 1141 */ |
1144 } | 1142 } |
1145 dounlock (); | 1143 dounlock(); |
1146 return 0; | 1144 return 0; |
1147 dlcloseerror: | 1145 dlcloseerror: |
1148 dounlock (); | 1146 dounlock(); |
1149 return 1; | 1147 return 1; |
1150 } | 1148 } |
1151 | 1149 |
1152 static const char * | 1150 static const char * |
1153 SDL_OSX_dlerror (void) | 1151 SDL_OSX_dlerror(void) |
1154 { | 1152 { |
1155 struct dlthread *tss; | 1153 struct dlthread *tss; |
1156 const char *err_str = NULL; | 1154 const char *err_str = NULL; |
1157 dlcompat_init_check (); | 1155 dlcompat_init_check(); |
1158 tss = pthread_getspecific (dlerror_key); | 1156 tss = pthread_getspecific(dlerror_key); |
1159 if (tss != NULL && tss->errset != 0) { | 1157 if (tss != NULL && tss->errset != 0) { |
1160 tss->errset = 0; | 1158 tss->errset = 0; |
1161 err_str = tss->errstr; | 1159 err_str = tss->errstr; |
1162 } | 1160 } |
1163 return (err_str); | 1161 return (err_str); |
1165 | 1163 |
1166 /* Given an address, return the mach_header for the image containing it | 1164 /* Given an address, return the mach_header for the image containing it |
1167 * or zero if the given address is not contained in any loaded images. | 1165 * or zero if the given address is not contained in any loaded images. |
1168 */ | 1166 */ |
1169 static const struct mach_header * | 1167 static const struct mach_header * |
1170 image_for_address (const void *address) | 1168 image_for_address(const void *address) |
1171 { | 1169 { |
1172 unsigned long i; | 1170 unsigned long i; |
1173 unsigned long j; | 1171 unsigned long j; |
1174 unsigned long count = _dyld_image_count (); | 1172 unsigned long count = _dyld_image_count(); |
1175 const struct mach_header *mh = 0; | 1173 const struct mach_header *mh = 0; |
1176 struct load_command *lc = 0; | 1174 struct load_command *lc = 0; |
1177 unsigned long addr = 0; | 1175 unsigned long addr = 0; |
1178 for (i = 0; i < count; i++) { | 1176 for (i = 0; i < count; i++) { |
1179 addr = (unsigned long) address - _dyld_get_image_vmaddr_slide (i); | 1177 addr = (unsigned long) address - _dyld_get_image_vmaddr_slide(i); |
1180 mh = _dyld_get_image_header (i); | 1178 mh = _dyld_get_image_header(i); |
1181 if (mh) { | 1179 if (mh) { |
1182 lc = (struct load_command *) ((char *) mh + | 1180 lc = (struct load_command *) ((char *) mh + |
1183 sizeof (struct mach_header)); | 1181 sizeof(struct mach_header)); |
1184 for (j = 0; j < mh->ncmds; | 1182 for (j = 0; j < mh->ncmds; |
1185 j++, lc = | 1183 j++, lc = |
1186 (struct load_command *) ((char *) lc + lc->cmdsize)) { | 1184 (struct load_command *) ((char *) lc + lc->cmdsize)) { |
1187 if (LC_SEGMENT == lc->cmd && | 1185 if (LC_SEGMENT == lc->cmd && |
1188 addr >= ((struct segment_command *) lc)->vmaddr && | 1186 addr >= ((struct segment_command *) lc)->vmaddr && |
1199 return mh; | 1197 return mh; |
1200 } | 1198 } |
1201 | 1199 |
1202 #if 0 /* unused */ | 1200 #if 0 /* unused */ |
1203 static int | 1201 static int |
1204 SDL_OSX_dladdr (const void *dl_restrict p, SDL_OSX_Dl_info * dl_restrict info) | 1202 SDL_OSX_dladdr(const void *dl_restrict p, SDL_OSX_Dl_info * dl_restrict info) |
1205 { | 1203 { |
1206 /* | 1204 /* |
1207 FIXME: USe the routine image_for_address. | 1205 FIXME: USe the routine image_for_address. |
1208 */ | 1206 */ |
1209 unsigned long i; | 1207 unsigned long i; |
1210 unsigned long j; | 1208 unsigned long j; |
1211 unsigned long count = _dyld_image_count (); | 1209 unsigned long count = _dyld_image_count(); |
1212 struct mach_header *mh = 0; | 1210 struct mach_header *mh = 0; |
1213 struct load_command *lc = 0; | 1211 struct load_command *lc = 0; |
1214 unsigned long addr = NULL; | 1212 unsigned long addr = NULL; |
1215 unsigned long table_off = (unsigned long) 0; | 1213 unsigned long table_off = (unsigned long) 0; |
1216 int found = 0; | 1214 int found = 0; |
1217 if (!info) | 1215 if (!info) |
1218 return 0; | 1216 return 0; |
1219 dolock (); | 1217 dolock(); |
1220 resetdlerror (); | 1218 resetdlerror(); |
1221 info->dli_fname = 0; | 1219 info->dli_fname = 0; |
1222 info->dli_fbase = 0; | 1220 info->dli_fbase = 0; |
1223 info->dli_sname = 0; | 1221 info->dli_sname = 0; |
1224 info->dli_saddr = 0; | 1222 info->dli_saddr = 0; |
1225 /* Some of this was swiped from code posted by Douglas Davidson <ddavidso AT apple DOT com> | 1223 /* Some of this was swiped from code posted by Douglas Davidson <ddavidso AT apple DOT com> |
1226 * to darwin-development AT lists DOT apple DOT com and slightly modified | 1224 * to darwin-development AT lists DOT apple DOT com and slightly modified |
1227 */ | 1225 */ |
1228 for (i = 0; i < count; i++) { | 1226 for (i = 0; i < count; i++) { |
1229 addr = (unsigned long) p - _dyld_get_image_vmaddr_slide (i); | 1227 addr = (unsigned long) p - _dyld_get_image_vmaddr_slide(i); |
1230 mh = _dyld_get_image_header (i); | 1228 mh = _dyld_get_image_header(i); |
1231 if (mh) { | 1229 if (mh) { |
1232 lc = (struct load_command *) ((char *) mh + | 1230 lc = (struct load_command *) ((char *) mh + |
1233 sizeof (struct mach_header)); | 1231 sizeof(struct mach_header)); |
1234 for (j = 0; j < mh->ncmds; | 1232 for (j = 0; j < mh->ncmds; |
1235 j++, lc = | 1233 j++, lc = |
1236 (struct load_command *) ((char *) lc + lc->cmdsize)) { | 1234 (struct load_command *) ((char *) lc + lc->cmdsize)) { |
1237 if (LC_SEGMENT == lc->cmd && | 1235 if (LC_SEGMENT == lc->cmd && |
1238 addr >= ((struct segment_command *) lc)->vmaddr && | 1236 addr >= ((struct segment_command *) lc)->vmaddr && |
1239 addr < | 1237 addr < |
1240 ((struct segment_command *) lc)->vmaddr + | 1238 ((struct segment_command *) lc)->vmaddr + |
1241 ((struct segment_command *) lc)->vmsize) { | 1239 ((struct segment_command *) lc)->vmsize) { |
1242 info->dli_fname = _dyld_get_image_name (i); | 1240 info->dli_fname = _dyld_get_image_name(i); |
1243 info->dli_fbase = (void *) mh; | 1241 info->dli_fbase = (void *) mh; |
1244 found = 1; | 1242 found = 1; |
1245 break; | 1243 break; |
1246 } | 1244 } |
1247 } | 1245 } |
1248 if (found) | 1246 if (found) |
1249 break; | 1247 break; |
1250 } | 1248 } |
1251 } | 1249 } |
1252 if (!found) { | 1250 if (!found) { |
1253 dounlock (); | 1251 dounlock(); |
1254 return 0; | 1252 return 0; |
1255 } | 1253 } |
1256 lc = (struct load_command *) ((char *) mh + sizeof (struct mach_header)); | 1254 lc = (struct load_command *) ((char *) mh + sizeof(struct mach_header)); |
1257 for (j = 0; j < mh->ncmds; | 1255 for (j = 0; j < mh->ncmds; |
1258 j++, lc = (struct load_command *) ((char *) lc + lc->cmdsize)) { | 1256 j++, lc = (struct load_command *) ((char *) lc + lc->cmdsize)) { |
1259 if (LC_SEGMENT == lc->cmd) { | 1257 if (LC_SEGMENT == lc->cmd) { |
1260 if (!SDL_strcmp | 1258 if (!SDL_strcmp |
1261 (((struct segment_command *) lc)->segname, "__LINKEDIT")) | 1259 (((struct segment_command *) lc)->segname, "__LINKEDIT")) |
1263 } | 1261 } |
1264 } | 1262 } |
1265 table_off = | 1263 table_off = |
1266 ((unsigned long) ((struct segment_command *) lc)->vmaddr) - | 1264 ((unsigned long) ((struct segment_command *) lc)->vmaddr) - |
1267 ((unsigned long) ((struct segment_command *) lc)->fileoff) + | 1265 ((unsigned long) ((struct segment_command *) lc)->fileoff) + |
1268 _dyld_get_image_vmaddr_slide (i); | 1266 _dyld_get_image_vmaddr_slide(i); |
1269 debug ("table off %x", table_off); | 1267 debug("table off %x", table_off); |
1270 | 1268 |
1271 lc = (struct load_command *) ((char *) mh + sizeof (struct mach_header)); | 1269 lc = (struct load_command *) ((char *) mh + sizeof(struct mach_header)); |
1272 for (j = 0; j < mh->ncmds; | 1270 for (j = 0; j < mh->ncmds; |
1273 j++, lc = (struct load_command *) ((char *) lc + lc->cmdsize)) { | 1271 j++, lc = (struct load_command *) ((char *) lc + lc->cmdsize)) { |
1274 if (LC_SYMTAB == lc->cmd) { | 1272 if (LC_SYMTAB == lc->cmd) { |
1275 | 1273 |
1276 struct nlist *symtable = | 1274 struct nlist *symtable = |
1280 struct nlist *nearest = NULL; | 1278 struct nlist *nearest = NULL; |
1281 unsigned long diff = 0xffffffff; | 1279 unsigned long diff = 0xffffffff; |
1282 unsigned long strtable = | 1280 unsigned long strtable = |
1283 (unsigned long) (((struct symtab_command *) lc)->stroff + | 1281 (unsigned long) (((struct symtab_command *) lc)->stroff + |
1284 table_off); | 1282 table_off); |
1285 debug ("symtable %x", symtable); | 1283 debug("symtable %x", symtable); |
1286 for (i = 0; i < numsyms; i++) { | 1284 for (i = 0; i < numsyms; i++) { |
1287 /* Ignore the following kinds of Symbols */ | 1285 /* Ignore the following kinds of Symbols */ |
1288 if ((!symtable->n_value) /* Undefined */ | 1286 if ((!symtable->n_value) /* Undefined */ |
1289 ||(symtable->n_type >= N_PEXT) /* Debug symbol */ | 1287 ||(symtable->n_type >= N_PEXT) /* Debug symbol */ |
1290 ||(!(symtable->n_type & N_EXT)) /* Local Symbol */ | 1288 ||(!(symtable->n_type & N_EXT)) /* Local Symbol */ |
1303 info->dli_saddr = nearest->n_value + ((void *) p - addr); | 1301 info->dli_saddr = nearest->n_value + ((void *) p - addr); |
1304 info->dli_sname = (char *) (strtable + nearest->n_un.n_strx); | 1302 info->dli_sname = (char *) (strtable + nearest->n_un.n_strx); |
1305 } | 1303 } |
1306 } | 1304 } |
1307 } | 1305 } |
1308 dounlock (); | 1306 dounlock(); |
1309 return 1; | 1307 return 1; |
1310 } | 1308 } |
1311 #endif | 1309 #endif |
1312 | 1310 |
1313 /* | 1311 /* |
1319 * have the same representation, which is true on all platforms FreeBSD | 1317 * have the same representation, which is true on all platforms FreeBSD |
1320 * runs on, but is not guaranteed by the C standard. | 1318 * runs on, but is not guaranteed by the C standard. |
1321 */ | 1319 */ |
1322 #if 0 | 1320 #if 0 |
1323 static dlfunc_t | 1321 static dlfunc_t |
1324 SDL_OSX_dlfunc (void *dl_restrict handle, const char *dl_restrict symbol) | 1322 SDL_OSX_dlfunc(void *dl_restrict handle, const char *dl_restrict symbol) |
1325 { | 1323 { |
1326 union | 1324 union |
1327 { | 1325 { |
1328 void *d; | 1326 void *d; |
1329 dlfunc_t f; | 1327 dlfunc_t f; |
1330 } rv; | 1328 } rv; |
1331 int sym_len = SDL_strlen (symbol); | 1329 int sym_len = SDL_strlen(symbol); |
1332 char *malloc_sym = NULL; | 1330 char *malloc_sym = NULL; |
1333 dolock (); | 1331 dolock(); |
1334 malloc_sym = SDL_malloc (sym_len + 2); | 1332 malloc_sym = SDL_malloc(sym_len + 2); |
1335 if (malloc_sym) { | 1333 if (malloc_sym) { |
1336 SDL_snprintf (malloc_sym, sym_len + 2, "_%s", symbol); | 1334 SDL_snprintf(malloc_sym, sym_len + 2, "_%s", symbol); |
1337 rv.d = dlsymIntern (handle, malloc_sym, 1); | 1335 rv.d = dlsymIntern(handle, malloc_sym, 1); |
1338 SDL_free (malloc_sym); | 1336 SDL_free(malloc_sym); |
1339 } else { | 1337 } else { |
1340 error ("Unable to allocate memory"); | 1338 error("Unable to allocate memory"); |
1341 goto dlfuncerror; | 1339 goto dlfuncerror; |
1342 } | 1340 } |
1343 dounlock (); | 1341 dounlock(); |
1344 return rv.f; | 1342 return rv.f; |
1345 dlfuncerror: | 1343 dlfuncerror: |
1346 dounlock (); | 1344 dounlock(); |
1347 return NULL; | 1345 return NULL; |
1348 } | 1346 } |
1349 #endif | 1347 #endif |
1350 | 1348 |
1351 | 1349 |
1357 /* System dependent library loading routines */ | 1355 /* System dependent library loading routines */ |
1358 | 1356 |
1359 #include "SDL_loadso.h" | 1357 #include "SDL_loadso.h" |
1360 | 1358 |
1361 void * | 1359 void * |
1362 SDL_LoadObject (const char *sofile) | 1360 SDL_LoadObject(const char *sofile) |
1363 { | 1361 { |
1364 void *handle = SDL_OSX_dlopen (sofile, RTLD_NOW); | 1362 void *handle = SDL_OSX_dlopen(sofile, RTLD_NOW); |
1365 const char *loaderror = SDL_OSX_dlerror (); | 1363 const char *loaderror = SDL_OSX_dlerror(); |
1366 if (handle == NULL) { | 1364 if (handle == NULL) { |
1367 SDL_SetError ("Failed loading %s: %s", sofile, loaderror); | 1365 SDL_SetError("Failed loading %s: %s", sofile, loaderror); |
1368 } | 1366 } |
1369 return (handle); | 1367 return (handle); |
1370 } | 1368 } |
1371 | 1369 |
1372 void * | 1370 void * |
1373 SDL_LoadFunction (void *handle, const char *name) | 1371 SDL_LoadFunction(void *handle, const char *name) |
1374 { | 1372 { |
1375 void *symbol = SDL_OSX_dlsym (handle, name); | 1373 void *symbol = SDL_OSX_dlsym(handle, name); |
1376 if (symbol == NULL) { | 1374 if (symbol == NULL) { |
1377 SDL_SetError ("Failed loading %s: %s", name, SDL_OSX_dlerror ()); | 1375 SDL_SetError("Failed loading %s: %s", name, SDL_OSX_dlerror()); |
1378 } | 1376 } |
1379 return (symbol); | 1377 return (symbol); |
1380 } | 1378 } |
1381 | 1379 |
1382 void | 1380 void |
1383 SDL_UnloadObject (void *handle) | 1381 SDL_UnloadObject(void *handle) |
1384 { | 1382 { |
1385 if (handle != NULL) { | 1383 if (handle != NULL) { |
1386 SDL_OSX_dlclose (handle); | 1384 SDL_OSX_dlclose(handle); |
1387 } | 1385 } |
1388 } | 1386 } |
1389 | 1387 |
1390 #endif /* SDL_LOADSO_DLCOMPAT */ | 1388 #endif /* SDL_LOADSO_DLCOMPAT */ |
1391 /* vi: set ts=4 sw=4 expandtab: */ | 1389 /* vi: set ts=4 sw=4 expandtab: */ |