Index: src/rt/dylib_fixes.c
===================================================================
--- src/rt/dylib_fixes.c	(revision 0)
+++ src/rt/dylib_fixes.c	(revision 0)
@@ -0,0 +1,14 @@
+void* _Dmain __attribute__((weak));
+
+char rt_init ();
+char rt_term ();
+
+__attribute__((constructor)) static void initializer ()
+{
+    rt_init();
+}
+
+__attribute__((destructor)) static void finalizer ()
+{
+    rt_term();
+}
\ No newline at end of file
Index: src/rt/dmain2.d
===================================================================
--- src/rt/dmain2.d	(revision 283)
+++ src/rt/dmain2.d	(working copy)
@@ -177,6 +177,14 @@
 
 void _d_criticalInit()
 {
+    shared static bool hasBeenCalled;
+    
+    if (hasBeenCalled)
+    {
+        hasBeenCalled = true;
+        return;
+    }
+    
     version (Posix)
     {
         _STI_monitor_staticctor();
@@ -188,6 +196,11 @@
 
 extern (C) bool rt_init(ExceptionHandler dg = null)
 {
+    shared static bool result;
+    
+    if (result)
+        return result;
+    
     _d_criticalInit();
 
     try
@@ -198,7 +211,7 @@
             _minit();
         _moduleCtor();
         runModuleUnitTests();
-        return true;
+        return result = true;
     }
     catch (Throwable e)
     {
@@ -210,11 +223,19 @@
 
     }
     _d_criticalTerm();
-    return false;
+    return result = false;
 }
 
 void _d_criticalTerm()
 {
+    shared static bool hasBeenCalled;
+    
+    if (hasBeenCalled)
+    {
+        hasBeenCalled = true;
+        return;
+    }
+    
     version (Posix)
     {
         _STD_critical_term();
@@ -224,13 +245,18 @@
 
 extern (C) bool rt_term(ExceptionHandler dg = null)
 {
+    shared static bool result;
+    
+    if (result)
+        return result;
+    
     try
     {
         thread_joinAll();
         _d_isHalting = true;
         _moduleDtor();
         gc_term();
-        return true;
+        return result = true;
     }
     catch (Throwable e)
     {
@@ -245,7 +271,7 @@
     {
         _d_criticalTerm();
     }
-    return false;
+    return result = false;
 }
 
 /***********************************
@@ -387,17 +413,10 @@
 
     void runAll()
     {
-        gc_init();
-        initStaticDataGC();
-        version (Windows)
-            _minit();
-        _moduleCtor();
+        rt_init();
         if (runModuleUnitTests())
             tryExec(&runMain);
-        thread_joinAll();
-        _d_isHalting = true;
-        _moduleDtor();
-        gc_term();
+        rt_term();
     }
 
     tryExec(&runAll);
Index: src/rt/deh2.d
===================================================================
--- src/rt/deh2.d	(revision 283)
+++ src/rt/deh2.d	(working copy)
@@ -14,12 +14,20 @@
 
 //debug=1;
 
+version (OSX)
+    import rt.util.darwin.Image;
+
 extern (C)
 {
-    extern __gshared
+    version (OSX) {}
+    
+    else
     {
-        void* _deh_beg;
-        void* _deh_end;
+        extern __gshared
+        {
+            void* _deh_beg;
+            void* _deh_end;
+        }
     }
 
     int _d_isbaseof(ClassInfo oc, ClassInfo c);
@@ -87,26 +95,50 @@
 
 DHandlerTable *__eh_finddata(void *address)
 {
-    FuncTable *ft;
-
-//    debug printf("__eh_finddata(address = x%x)\n", address);
-//    debug printf("_deh_beg = x%x, _deh_end = x%x\n", &_deh_beg, &_deh_end);
-    for (ft = cast(FuncTable *)&_deh_beg;
-         ft < cast(FuncTable *)&_deh_end;
-         ft++)
+    version (OSX)
     {
-//      debug printf("\tfptr = x%x, fsize = x%03x, handlertable = x%x\n",
-//              ft.fptr, ft.fsize, ft.handlertable);
+        static FuncTable[] functionTables;
+        static bool hasFunctionTables;
+        
+        if (!hasFunctionTables)
+        {
+            functionTables = getSectionData!(FuncTable, "__DATA", "__deh_eh");
+            hasFunctionTables = true;
+        }
+        
+        foreach (ft ; functionTables)
+        {
+            if (ft.fptr <= address && address < cast(void *)(cast(char *)ft.fptr + ft.fsize))
+                return ft.handlertable;
+        }
+                
+        return null;
+    }
+    
+    else
+    {
+        FuncTable *ft;
 
-        if (ft.fptr <= address &&
-            address < cast(void *)(cast(char *)ft.fptr + ft.fsize))
+    //    debug printf("__eh_finddata(address = x%x)\n", address);
+    //    debug printf("_deh_beg = x%x, _deh_end = x%x\n", &_deh_beg, &_deh_end);
+        for (ft = cast(FuncTable *)&_deh_beg;
+             ft < cast(FuncTable *)&_deh_end;
+             ft++)
         {
-//          debug printf("\tfound handler table\n");
-            return ft.handlertable;
+    //      debug printf("\tfptr = x%x, fsize = x%03x, handlertable = x%x\n",
+    //              ft.fptr, ft.fsize, ft.handlertable);
+
+            if (ft.fptr <= address &&
+                address < cast(void *)(cast(char *)ft.fptr + ft.fsize))
+            {
+    //          debug printf("\tfound handler table\n");
+                return ft.handlertable;
+            }
         }
+    //    debug printf("\tnot found\n");
+        return null;
     }
-//    debug printf("\tnot found\n");
-    return null;
+
 }
 
 
Index: src/rt/util/darwin/getsect.d
===================================================================
--- src/rt/util/darwin/getsect.d	(revision 0)
+++ src/rt/util/darwin/getsect.d	(revision 0)
@@ -0,0 +1,21 @@
+/**
+ * Copyright: Copyright Digital Mars 2010.
+ * License:   <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors:   Jacob Carlborg
+ * Version: Initial created: Mar 16, 2010
+ *
+ *          Copyright Digital Mars 2010.
+ * Distributed under the Boost Software License, Version 1.0.
+ *    (See accompanying file LICENSE_1_0.txt or copy at
+ *          http://www.boost.org/LICENSE_1_0.txt)
+ */
+module rt.util.darwin.getsect;
+
+version (darwin):
+
+import rt.util.darwin.loader;
+
+extern (C):
+
+section* getsectbynamefromheader (in mach_header* mhp, in char* segname, in char* sectname);
+section_64* getsectbynamefromheader_64 (mach_header_64* mhp, in char* segname, in char* sectname);
\ No newline at end of file
Index: src/rt/util/darwin/Image.d
===================================================================
--- src/rt/util/darwin/Image.d	(revision 0)
+++ src/rt/util/darwin/Image.d	(revision 0)
@@ -0,0 +1,146 @@
+/**
+ * Copyright: Copyright Digital Mars 2010.
+ * License:   <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors:   Jacob Carlborg
+ * Version: Initial created: Feb 23, 2010
+ *
+ *          Copyright Digital Mars 2010.
+ * Distributed under the Boost Software License, Version 1.0.
+ *    (See accompanying file LICENSE_1_0.txt or copy at
+ *          http://www.boost.org/LICENSE_1_0.txt)
+ */
+module rt.util.darwin.Image;
+
+version (darwin):
+
+import rt.util.darwin.dyld;
+import rt.util.darwin.loader;
+import rt.util.darwin.getsect;
+
+struct Image
+{
+	private mach_header* header_;
+	private uint index_;
+	
+	this (uint index)
+	{
+		header_ = _dyld_get_image_header(index);
+		index_ = index;
+	}
+	
+	static uint numberOfImages ()
+	{
+		return _dyld_image_count;
+	}
+	
+	static int opApply (int delegate(ref Image) dg)
+	{
+		int result;
+		
+		for (size_t i = 0; i < numberOfImages; i++)
+		{
+			result = dg(Image(i));
+			
+			if (result)
+				break;
+		}
+		
+		return result;
+	}
+	
+	static int opApplyReverse (int delegate(ref Image) dg)
+	{
+		int result;
+		
+		for (int i = numberOfImages - 1; i >= 0; i--)
+		{
+			result = dg(Image(i));
+			
+			if (result)
+				break;
+		}
+		
+		return result;
+	}
+	
+	mach_header* header ()
+	{
+		return header_;
+	}
+	
+	mach_header_64* header64 ()
+	{
+		return cast(mach_header_64*) header_;
+	}
+	
+	CPU cpu ()
+	{
+		return CPU(header_);
+	}
+}
+
+struct CPU
+{
+	private mach_header* header;
+	
+	static CPU opCall (mach_header* header)
+	{
+		CPU cpu;
+		cpu.header = header;
+		
+		return cpu;
+	}
+	
+	bool is32bit ()
+	{		
+		return (header.magic & MH_MAGIC) != 0;
+	}
+
+	bool is64bit ()
+	{
+		return (header.magic & MH_MAGIC_64) != 0;
+	}
+}
+
+T[] getSectionData (T, string segmentName, string sectionName) ()
+{
+    T[] array;
+    
+    const c_segmentName = segmentName.ptr;
+    const c_sectionName = sectionName.ptr;    
+    
+    void* start;
+    void* end;
+    
+    foreach_reverse (image ; Image)
+    {            
+        if (image.cpu.is32bit)
+        {
+            auto header = image.header;
+            section* sect = getsectbynamefromheader(header, c_segmentName, c_sectionName);
+            
+            if (sect is null || sect.size == 0)
+                continue;
+
+            start = cast(void*) (cast(byte*) header + sect.offset);
+    	    end = cast(void*) (cast(byte*) start + sect.size);
+        }
+        
+        else
+        {
+            auto header = image.header64;
+            section_64* sect = getsectbynamefromheader_64(header, c_segmentName, c_sectionName);
+            
+            if (sect is null || sect.size == 0)
+                continue;
+
+            start = cast(void*) (cast(byte*) header + sect.offset);
+    	    end = cast(void*) (cast(byte*) start + sect.size);
+        }
+	    
+	    size_t len = cast(T*)end - cast(T*)start;
+		array ~= (cast(T*)start)[0 .. len];
+    }
+    
+    return array;
+}
\ No newline at end of file
Index: src/rt/util/darwin/loader.d
===================================================================
--- src/rt/util/darwin/loader.d	(revision 0)
+++ src/rt/util/darwin/loader.d	(revision 0)
@@ -0,0 +1,76 @@
+/**
+ * Copyright: Copyright Digital Mars 2010.
+ * License:   <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors:   Jacob Carlborg
+ * Version: Initial created: Feb 20, 2010
+ *
+ *          Copyright Digital Mars 2010.
+ * Distributed under the Boost Software License, Version 1.0.
+ *    (See accompanying file LICENSE_1_0.txt or copy at
+ *          http://www.boost.org/LICENSE_1_0.txt)
+ */
+module rt.util.darwin.loader;
+
+version (darwin):
+
+struct mach_header
+{
+	uint magic;
+	int cputype;
+	int cpusubtype;
+	uint filetype;
+	uint ncmds;
+	uint sizeofcmds;
+	uint flags;
+}
+
+struct mach_header_64
+{
+	uint magic;
+	int cputype;
+	int cpusubtype;
+	uint filetype;
+	uint ncmds;
+	uint sizeofcmds;
+	uint flags;
+	uint reserved;
+}
+
+enum : uint
+{
+	MH_MAGIC = 0xfeedface,
+	MH_CIGAM = 0xcefaedfe,
+	MH_MAGIC_64 = 0xfeedfacf,
+	MH_CIGAM_64 = 0xcffaedfe,
+}
+
+struct section
+{
+	char[16] sectname;
+	char[16] segname;
+	uint addr;
+	uint size;
+	uint offset;
+	uint align_;
+	uint reloff;
+	uint nreloc;
+	uint flags;
+	uint reserved1;
+	uint reserved2;
+}
+
+struct section_64
+{
+	char[16] sectname;
+	char[16] segname;
+	long addr;
+	long size;
+	uint offset;
+	uint align_;
+	uint reloff;
+	uint nreloc;
+	uint flags;
+	uint reserved1;
+	uint reserved2;
+	uint reserved3;
+}
\ No newline at end of file
Index: src/rt/util/darwin/dyld.d
===================================================================
--- src/rt/util/darwin/dyld.d	(revision 0)
+++ src/rt/util/darwin/dyld.d	(revision 0)
@@ -0,0 +1,22 @@
+/**
+ * Copyright: Copyright Digital Mars 2010.
+ * License:   <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
+ * Authors:   Jacob Carlborg
+ * Version: Initial created: Feb 20, 2010
+ *
+ *          Copyright Digital Mars 2010.
+ * Distributed under the Boost Software License, Version 1.0.
+ *    (See accompanying file LICENSE_1_0.txt or copy at
+ *          http://www.boost.org/LICENSE_1_0.txt)
+ */
+module rt.util.darwin.dyld;
+
+version (darwin):
+
+import rt.util.darwin.loader;
+
+extern (C):
+
+uint _dyld_image_count ();
+mach_header* _dyld_get_image_header (uint image_index);
+
Index: src/object_.d
===================================================================
--- src/object_.d	(revision 283)
+++ src/object_.d	(working copy)
@@ -27,6 +27,9 @@
     import rt.util.hash;
     import rt.util.string;
     debug(PRINTF) import core.stdc.stdio;
+    
+    version (OSX)
+        import rt.util.darwin.Image;
 
     extern (C) void onOutOfMemoryError();
     extern (C) Object _d_newclass(TypeInfo_Class ci);
@@ -1700,9 +1703,14 @@
          * and __minfo_end. The variables _minfo_beg and _minfo_end
          * are of zero size and are in the two bracketing segments,
          * respectively.
+         * 
+         * The __minfo_beg and __minfo_end sections are not put into
+         * dynamic libraries therefore we cannot use them or the
+         * _minfo_beg and _minfo_end variables. Instead we loop through
+         * all the loaded images (executables and dynamic libraries) and
+         * collect all the ModuleInfo references.
          */
-         size_t length = cast(ModuleInfo**)&_minfo_end - cast(ModuleInfo**)&_minfo_beg;
-         _moduleinfo_array = (cast(ModuleInfo**)&_minfo_beg)[0 .. length];
+         _moduleinfo_array = getSectionData!(ModuleInfo*, "__DATA", "__minfodata");
          debug printf("moduleinfo: ptr = %p, length = %d\n", _moduleinfo_array.ptr, _moduleinfo_array.length);
 
          debug foreach (m; _moduleinfo_array)
Index: posix.mak
===================================================================
--- posix.mak	(revision 283)
+++ posix.mak	(working copy)
@@ -10,7 +10,10 @@
 CFLAGS=-m32 -O
 
 OBJDIR=obj
-DRUNTIME=lib/libdruntime.a
+LIB=lib
+DRUNTIME=$(LIB)/libdruntime.a
+DRUNTIME_DYLIB=libdruntime.dylib
+DRUNTIME_DYLIB_PATH=$(LIB)/$(DRUNTIME_DYLIB)
 
 target : import $(DRUNTIME) doc
 
@@ -177,6 +180,10 @@
 	src/rt/util/hash.d \
 	src/rt/util/string.d \
 	src/rt/util/utf.d \
+	src/rt/util/darwin/dyld.d \
+	src/rt/util/darwin/getsect.d \
+	src/rt/util/darwin/Image.d \
+	src/rt/util/darwin/loader.d \
 	src/gc/gc.d \
 	src/gc/gcalloc.d \
 	src/gc/gcbits.d \
@@ -245,6 +252,11 @@
 	src/rt/util/string.d \
 	src/rt/util/utf.d \
 	\
+	src/rt/util/darwin/dyld.d \
+	src/rt/util/darwin/getsect.d \
+	src/rt/util/darwin/Image.d \
+	src/rt/util/darwin/loader.d \
+	\
 	src/rt/typeinfo/ti_AC.d \
 	src/rt/typeinfo/ti_Acdouble.d \
 	src/rt/typeinfo/ti_Acfloat.d \
@@ -307,7 +319,8 @@
 #       minit.asm is not used by dmd for Linux
 
 OBJS= $(OBJDIR)/errno_c.o $(OBJDIR)/threadasm.o $(OBJDIR)/complex.o	\
-$(OBJDIR)/critical.o $(OBJDIR)/memory_osx.o $(OBJDIR)/monitor.o
+$(OBJDIR)/critical.o $(OBJDIR)/memory_osx.o $(OBJDIR)/monitor.o \
+$(OBJDIR)/dylib_fixes.o 
 
 DOCS=\
 	$(DOCDIR)/core/bitop.html \
@@ -370,6 +383,10 @@
 $(OBJDIR)/threadasm.o : src/core/threadasm.S
 	@mkdir -p $(OBJDIR)
 	$(CC) -c $(CFLAGS) $< -o$@
+	
+$(OBJDIR)/dylib_fixes.o : src/rt/dylib_fixes.c
+	@mkdir -p $(OBJDIR)
+	$(CC) -c $(CFLAGS) $< -o$@
 
 ################### Library generation #########################
 
@@ -390,3 +407,7 @@
 
 clean:
 	rm -f $(DOCS) $(IMPORTS) $(DRUNTIME) $(OBJS)
+
+dynamic: $(OBJS) $(SRCS) win32.mak
+	$(DMD) -c -of$(OBJDIR)/libdruntime.o $(DFLAGS) $(SRCS) $(OBJS)
+	$(CC) -dynamiclib -o $(LIB)/libdruntime.dylib $(OBJDIR)/libdruntime.o -install_name @rpath/libdruntime.dylib $(OBJS) -Xlinker -headerpad_max_install_names
\ No newline at end of file
