Index: config/gen/platform/darwin.c
===================================================================
RCS file: /cvs/public/parrot/config/gen/platform/darwin.c,v
retrieving revision 1.14
diff -u -r1.14 darwin.c
--- config/gen/platform/darwin.c	13 Dec 2003 12:56:32 -0000	1.14
+++ config/gen/platform/darwin.c	15 Dec 2003 08:20:44 -0000
@@ -96,49 +96,10 @@
 }
 
 
-/* The dl* functions showed up in OS X 10.3. If we have them, use
-   them, otherwise roll our own */
-#if defined(PARROT_HAS_HEADER_DLFCN)
-#include <dlfcn.h>
-void *
-Parrot_dlopen(const char *filename)
-{
-    return dlopen(filename, PARROT_DLOPEN_FLAGS);
-}
-
-
-/*
-** Parrot_dlerror()
-*/
-
-const char *
-Parrot_dlerror(void)
-{
-    return dlerror();
-}
-
-
-/*
-** Parrot_dlsym()
-*/
-
-void *
-Parrot_dlsym(void *handle, const char *symbol)
-{
-    return dlsym(handle, symbol);
-}
-
-
-/*
-** Parrot_dlclose()
-*/
-
-int
-Parrot_dlclose(void *handle)
-{
-    return dlclose(handle);
-}
-#else
+/* The dl* functions showed up in OS X 10.3, but they are just a
+   wrapper around the native dyld and NSModule API, so we'll use
+   the base API directly. This gives us wider compatibility, and
+   more control over the behavior. */
 /*
 ** Parrot_dlopen()
 */
@@ -148,37 +109,76 @@
 {
     int dyld_result;
     NSObjectFileImage ofile;
-    NSModule handle = NULL;
 
+    /* try bundle-style loading first */
     dyld_result = NSCreateObjectFileImageFromFile(filename, &ofile);
-    if (NSObjectFileImageSuccess != dyld_result) {
-        switch(dyld_result) {
-        case NSObjectFileImageFailure:
-            fprintf(stderr, "open result was Failure (%i)\n", dyld_result);
-            break;
-        case NSObjectFileImageInappropriateFile:
-            fprintf(stderr, "open result was InappropriateFile (%i)\n", dyld_result);
-            break;
-        case NSObjectFileImageArch:
-            fprintf(stderr, "open result was Arch (%i)\n", dyld_result);
-            break;
-        case NSObjectFileImageFormat:
-            fprintf(stderr, "open result was Format (%i)\n", dyld_result);
-            break;
-        case NSObjectFileImageAccess:
-            fprintf(stderr, "open result was Access (%i)\n", dyld_result);
-            break;
-        default:
-            fprintf(stderr, "open result was unknown (%i)\n", dyld_result);
-            break;
-        }
-        exit(1);
+
+    if (NSObjectFileImageSuccess == dyld_result)
+    {
+        NSModule module = NSLinkModule(ofile, filename, 
+                              NSLINKMODULE_OPTION_RETURN_ON_ERROR 
+                              | NSLINKMODULE_OPTION_PRIVATE);
+    
+        NSDestroyObjectFileImage(ofile);
+
+        return module; /* NSModule is typedef'd to void*  */
     }
-    handle = NSLinkModule(ofile, filename, TRUE);
-    NSDestroyObjectFileImage(ofile);
+    else
+    { /* bundle-style loading didn't work; try dylib-style before giving up */
+        const struct mach_header *header = 
+                NSAddImage( filename, 
+                            NSADDIMAGE_OPTION_RETURN_ON_ERROR 
+                            | NSADDIMAGE_OPTION_WITH_SEARCHING);
+
+        if (header)
+        {
+            union {
+                const void * __c_ptr;
+                void * __ptr;
+            } __ptr_u;
+#define const_cast(b) (__ptr_u.__c_ptr = (b), __ptr_u.__ptr)
 
-    return handle;
+            return const_cast(header);
+        }
+        else
+        { /* that didn't work either; go ahead and report the orignal error */
 
+            switch(dyld_result) {
+            case NSObjectFileImageFailure:
+                fprintf(stderr, 
+                        "open result was Failure (%i) for filename [%s]\n", 
+                        dyld_result, filename);
+                break;
+            case NSObjectFileImageInappropriateFile:
+                fprintf(stderr, 
+                        "open result was InappropriateFile (%i) for filename [%s]\n",
+                        dyld_result, filename);
+                break;
+            case NSObjectFileImageArch:
+                fprintf(stderr, 
+                        "open result was Arch (%i) for filename [%s]\n",
+                        dyld_result, filename);
+                break;
+            case NSObjectFileImageFormat:
+                fprintf(stderr, 
+                        "open result was Format (%i) for filename [%s]\n",
+                        dyld_result, filename);
+                break;
+            case NSObjectFileImageAccess:
+                fprintf(stderr, 
+                        "open result was Access (%i) for filename [%s]\n",
+                        dyld_result, filename);
+                break;
+            default:
+                fprintf(stderr, 
+                        "open result was unknown (%i) for filename [%s]\n",
+                        dyld_result, filename);
+                break;
+            }
+
+            return NULL;
+        }
+    }
 }
 
 
@@ -200,15 +200,46 @@
 void *
 Parrot_dlsym(void *handle, const char *symbol)
 {
-    void *addr;
+    NSSymbol found_symbol = NULL;
+    char *fixed_name = malloc(strlen(symbol) + 2);
 
-    if (NSIsSymbolNameDefined(symbol))
-        addr = NSAddressOfSymbol(NSLookupAndBindSymbol(symbol));
+    /* Need to prepend underscore to symbol name to match the C convention 
+       for symbol naming. */
+    strcpy(fixed_name, "_");
+    strcat(fixed_name, symbol);
+
+    if (!handle) /* must be looking up global symbol */
+    {
+        if (NSIsSymbolNameDefined(fixed_name))
+        {
+            found_symbol = NSLookupAndBindSymbol(fixed_name);
+        }
+    }
+    else if (    ((struct mach_header *)handle)->magic == MH_MAGIC 
+              || ((struct mach_header *)handle)->magic == MH_CIGAM )
+    {
+        if (NSIsSymbolNameDefinedInImage(handle, fixed_name))
+        {
+            found_symbol = NSLookupSymbolInImage(handle, fixed_name, 
+                    NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR 
+                    | NSLOOKUPSYMBOLINIMAGE_OPTION_BIND);
+        }
+    }
     else
-        addr = NULL;
+    {
+        found_symbol = NSLookupSymbolInModule(handle, fixed_name);
+    }
 
-    return addr;
+    free(fixed_name);
 
+    if (!symbol)
+    {
+        return NULL;
+    }
+    else
+    {
+        return NSAddressOfSymbol(found_symbol);
+    }
 }
 
 
@@ -219,10 +250,22 @@
 int
 Parrot_dlclose(void *handle)
 {
-    return 0;
+    if ( handle && !( ((struct mach_header *)handle)->magic == MH_MAGIC 
+                   || ((struct mach_header *)handle)->magic == MH_CIGAM ) )
+    {
+        unsigned long options = NSUNLINKMODULE_OPTION_NONE;
+#ifdef __ppc__
+        options = NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
+#endif
+
+        return (int)NSUnLinkModule(handle, options);
+    }
+    else
+    {
+        return 0;
+    }
 }
 
-#endif
 
 /*
  * itimer stuff
Index: config/init/hints/darwin.pl
===================================================================
RCS file: /cvs/public/parrot/config/init/hints/darwin.pl,v
retrieving revision 1.9
diff -u -r1.9 darwin.pl
--- config/init/hints/darwin.pl	11 Dec 2003 16:38:43 -0000	1.9
+++ config/init/hints/darwin.pl	15 Dec 2003 08:20:44 -0000
@@ -19,4 +19,5 @@
   ldflags => $ldflags,
   ccwarn => "-Wno-shadow",
   libs => $libs,
+  so => '.dylib',
 );
