Index: /trunk/kLdr/Makefile.kmk
===================================================================
--- /trunk/kLdr/Makefile.kmk	(revision 2953)
+++ /trunk/kLdr/Makefile.kmk	(revision 2954)
@@ -35,5 +35,5 @@
 #
 TEMPLATE_TST = Testcase template
-ifneq ($(filter win nt win32 win64,$(BUILD_TARGET)),)
+ifneq ($(filter win,$(BUILD_TARGET)),)
  TEMPLATE_TST_TOOL = VCC70
  TEMPLATE_TST_CFLAGS = -W3 -Zi -Zl -MD
@@ -41,6 +41,5 @@
  TEMPLATE_TST_ASFLAGS = -f win
  TEMPLATE_TST_DEFS = __WIN__
- TEMPLATE_SDKS.x86 = WIN32SDK W2K3DDKX86
- TEMPLATE_SDKS.amd64 = WIN64SDK W2K3DDKAMD64
+ TEMPLATE_TST_SDKS = WINPSDK W2K3DDK
 
 ## @todo this is a kBuild bug? $$(PATH_TOOL_VCC70_LIB)
@@ -112,7 +111,7 @@
 	kLdrMod.c \
 	kLdrModLX.c \
-	kLdrModPE.c \
 	kLdrModMachO.c \
-	kLdrModNative.c
+	kLdrModNative.c \
+	kLdrModPE.c
 kLdr_SOURCES.os2 = \
 	kLdr-os2.def \
Index: /trunk/kLdr/kLdr.h
===================================================================
--- /trunk/kLdr/kLdr.h	(revision 2953)
+++ /trunk/kLdr/kLdr.h	(revision 2954)
@@ -1117,6 +1117,10 @@
 /** The mach-o image format isn't supported by this kLdr build. */
 #define KLDR_ERR_MACHO_NOT_SUPPORTED    (KLDR_ERR_BASE + 7)
-/** The mach-o image format isn't supported by this kLdr build. */
-#define KLDR_ERR_AOUT_NOT_SUPPORTED     (KLDR_ERR_BASE + 8)
+/** The FAT image format isn't supported by this kLdr build or
+ * a direct open was attempt without going thru the FAT file provider.
+ * FAT images are also known as Universal Binaries. */
+#define KLDR_ERR_FAT_NOT_SUPPORTED      (KLDR_ERR_BASE + 8)
+/** The a.out image format isn't supported by this kLdr build. */
+#define KLDR_ERR_AOUT_NOT_SUPPORTED     (KLDR_ERR_BASE + 9)
 
 /** Invalid parameter to a kLdr API. */
@@ -1237,9 +1241,9 @@
  * @{ */
 #define KLDR_ERR_MACHO_BASE                                 (KLDR_ERR_LX_BASE + 12)
-/** Only native endian MACH-O files are supported. */
+/** Only native endian Mach-O files are supported. */
 #define KLDR_ERR_MACHO_OTHER_ENDIAN_NOT_SUPPORTED           (KLDR_ERR_MACHO_BASE + 0)
-/** 64-bit MACH-O files aren't supported yet. */
+/** 64-bit Mach-O files aren't supported yet. */
 #define KLDR_ERR_MACHO_64BIT_NOT_SUPPORTED                  (KLDR_ERR_MACHO_BASE + 1)
-/** The MACH-O header is bad or contains new and unsupported features. */
+/** The Mach-O header is bad or contains new and unsupported features. */
 #define KLDR_ERR_MACHO_BAD_HEADER                           (KLDR_ERR_MACHO_BASE + 2)
 /** The file type isn't supported. */
@@ -1247,8 +1251,22 @@
 /** The machine (cputype / cpusubtype combination) isn't supported. */
 #define KLDR_ERR_MACHO_UNSUPPORTED_MACHINE                  (KLDR_ERR_MACHO_BASE + 4)
+/** Bad load command(s). */
+#define KLDR_ERR_MACHO_BAD_LOAD_COMMAND                     (KLDR_ERR_MACHO_BASE + 5)
+/** Encountered an unknown load command.*/
+#define KLDR_ERR_MACHO_UNKNOWN_LOAD_COMMAND                 (KLDR_ERR_MACHO_BASE + 6)
+/** Encountered a load command that's not implemented.*/
+#define KLDR_ERR_MACHO_UNSUPPORTED_LOAD_COMMAND             (KLDR_ERR_MACHO_BASE + 7)
+/** Bad section. */
+#define KLDR_ERR_MACHO_BAD_SECTION                          (KLDR_ERR_MACHO_BASE + 8)
+/** Encountered a section type that's not implemented.*/
+#define KLDR_ERR_MACHO_UNSUPPORTED_SECTION                  (KLDR_ERR_MACHO_BASE + 9)
+/** Encountered a section type that's not known to the loader. (probably invalid) */
+#define KLDR_ERR_MACHO_UNKNOWN_SECTION                      (KLDR_ERR_MACHO_BASE + 10)
+/** The sections aren't ordered by segment as expected by the loader. */
+#define KLDR_ERR_MACHO_BAD_SECTION_ORDER                    (KLDR_ERR_MACHO_BASE + 11)
 /** @} */
 
 /** End of the valid kLdr status codes. */
-#define KLDR_ERR_END                                        (KLDR_ERR_LX_BASE + 12)
+#define KLDR_ERR_END                                        (KLDR_ERR_MACHO_BASE + 12)
 
 /** @} */
Index: /trunk/kLdr/kLdrHlp.h
===================================================================
--- /trunk/kLdr/kLdrHlp.h	(revision 2953)
+++ /trunk/kLdr/kLdrHlp.h	(revision 2954)
@@ -46,19 +46,60 @@
 #define KLDR_ELEMENTS(a)            ( sizeof(a) / sizeof((a)[0]) )
 
-/** @def KLDRHLP_LE2H_U16
- * Unsigned 16-bit little-endian to host translation. */
-/** @def KLDRHLP_LE2H_U32
- * Unsigned 32-bit little-endian to host translation. */
-#if 1
-# define KLDRHLP_LE2H_U16(u16)  ((uint16_t)(u16))
-# define KLDRHLP_LE2H_U32(u32)  ((uint32_t)(u32))
-#else
-# define KLDRHLP_LE2H_U16(u16)  ( (uint16_t) (((u16) >> 8) | ((u16) << 8)) )
-# define KLDRHLP_LE2H_U32(u32)  (   ( ((u32) & UINT32_C(0xff000000)) >> 24 ) \
+
+/** @name Endian Conversion
+ * @{ */
+
+/** @def KLDRHLP_E2E_U16
+ * Convert the endian of an unsigned 16-bit value. */
+# define KLDRHLP_E2E_U16(u16)   ( (uint16_t) (((u16) >> 8) | ((u16) << 8)) )
+/** @def KLDRHLP_E2E_U32
+ * Convert the endian of an unsigned 32-bit value. */
+# define KLDRHLP_E2E_U32(u32)   (   ( ((u32) & UINT32_C(0xff000000)) >> 24 ) \
                                   | ( ((u32) & UINT32_C(0x00ff0000)) >>  8 ) \
                                   | ( ((u32) & UINT32_C(0x0000ff00)) <<  8 ) \
                                   | ( ((u32) & UINT32_C(0x000000ff)) << 24 ) \
                                 )
-#endif
+/** @def KLDRHLP_E2E_U64
+ * Convert the endian of an unsigned 64-bit value. */
+# define KLDRHLP_E2E_U64(u64)   (   ( ((u64) & UINT64_C(0xff00000000000000)) >> 56 ) \
+                                  | ( ((u64) & UINT64_C(0x00ff000000000000)) >> 40 ) \
+                                  | ( ((u64) & UINT64_C(0x0000ff0000000000)) >> 24 ) \
+                                  | ( ((u64) & UINT64_C(0x000000ff00000000)) >>  8 ) \
+                                  | ( ((u64) & UINT64_C(0x00000000ff000000)) <<  8 ) \
+                                  | ( ((u64) & UINT64_C(0x0000000000ff0000)) << 24 ) \
+                                  | ( ((u64) & UINT64_C(0x000000000000ff00)) << 40 ) \
+                                  | ( ((u64) & UINT64_C(0x00000000000000ff)) << 56 ) \
+                                )
+
+/** @def KLDRHLP_LE2H_U16
+ * Unsigned 16-bit little-endian to host endian. */
+/** @def KLDRHLP_LE2H_U32
+ * Unsigned 32-bit little-endian to host endian. */
+/** @def KLDRHLP_LE2H_U64
+ * Unsigned 64-bit little-endian to host endian. */
+/** @def KLDRHLP_BE2H_U16
+ * Unsigned 16-bit big-endian to host endian. */
+/** @def KLDRHLP_BE2H_U32
+ * Unsigned 32-bit big-endian to host endian. */
+/** @def KLDRHLP_BE2H_U64
+ * Unsigned 64-bit big-endian to host endian. */
+#if 1
+# define KLDRHLP_LE2H_U16(u16)  ((uint16_t)(u16))
+# define KLDRHLP_LE2H_U32(u32)  ((uint32_t)(u32))
+# define KLDRHLP_LE2H_U64(u64)  ((uint32_t)(u32))
+# define KLDRHLP_BE2H_U16(u16)  KLDRHLP_E2E_U16(u16)
+# define KLDRHLP_BE2H_U32(u32)  KLDRHLP_E2E_U32(u32)
+# define KLDRHLP_BE2H_U64(u64)  KLDRHLP_E2E_U64(u64)
+#else
+# define KLDRHLP_LE2H_U16(u16)  KLDRHLP_E2E_U16(u16)
+# define KLDRHLP_LE2H_U32(u32)  KLDRHLP_E2E_U32(u32)
+# define KLDRHLP_LE2H_U32(u64)  KLDRHLP_E2E_U64(u64)
+# define KLDRHLP_BE2H_U16(u16)  ((uint16_t)(u16))
+# define KLDRHLP_BE2H_U32(u32)  ((uint32_t)(u32))
+# define KLDRHLP_BE2H_U64(u64)  ((uint32_t)(u32))
+#endif
+
+/** @} */
+
 
 /*
@@ -174,10 +215,10 @@
 #  ifdef __GNUC__
 #   define kldrHlpBreakpoint() do { __asm__ __volatile__ ("int3\n\tnop"); } while (0)
-#  endif 
+#  endif
 #  ifdef _MSC_VER
 #   define kldrHlpBreakpoint() __debugbreak()
-#  endif 
-
-#endif 
+#  endif
+
+#endif
 
 #if (!defined(kLdrHlpMemChr) && !defined(kLdrHlpStrChr_needed))\
@@ -196,5 +237,5 @@
 #ifdef __cplusplus
 extern "C" {
-#endif 
+#endif
 
 int     kLdrHlpMemIComp(const void *pv1, const void *pv2, size_t cb);
@@ -230,5 +271,5 @@
 #ifdef __cplusplus
 }
-#endif 
+#endif
 
 
Index: /trunk/kLdr/kLdrInternal.h
===================================================================
--- /trunk/kLdr/kLdrInternal.h	(revision 2953)
+++ /trunk/kLdr/kLdrInternal.h	(revision 2954)
@@ -50,15 +50,27 @@
  * @{ */
 /** ELF signature ("\x7fELF"). */
-#define IMAGE_ELF_SIGNATURE KLDRHLP_LE2H_U32(0x7f | ('E' << 8) | ((uint32_t)'L' << 16) | ((uint32_t)'F' << 24))
+#define IMAGE_ELF_SIGNATURE         KLDRHLP_LE2H_U32(0x7f | ('E' << 8) | ((uint32_t)'L' << 16) | ((uint32_t)'F' << 24))
 /** PE signature ("PE\0\0"). */
-#define IMAGE_NT_SIGNATURE  KLDRHLP_LE2H_U32('P' | ('E' << 8))
+#define IMAGE_NT_SIGNATURE          KLDRHLP_LE2H_U32('P' | ('E' << 8))
 /** LX signature ("LX") */
-#define IMAGE_LX_SIGNATURE  KLDRHLP_LE2H_U16('L' | ('X' << 8))
+#define IMAGE_LX_SIGNATURE          KLDRHLP_LE2H_U16('L' | ('X' << 8))
 /** LE signature ("LE") */
-#define IMAGE_LE_SIGNATURE  KLDRHLP_LE2H_U16('L' | ('E' << 8))
+#define IMAGE_LE_SIGNATURE          KLDRHLP_LE2H_U16('L' | ('E' << 8))
 /** NE signature ("NE") */
-#define IMAGE_NE_SIGNATURE  KLDRHLP_LE2H_U16('N' | ('E' << 8))
+#define IMAGE_NE_SIGNATURE          KLDRHLP_LE2H_U16('N' | ('E' << 8))
 /** MZ signature ("MZ"). */
-#define IMAGE_DOS_SIGNATURE KLDRHLP_LE2H_U16('M' | ('Z' << 8))
+#define IMAGE_DOS_SIGNATURE         KLDRHLP_LE2H_U16('M' | ('Z' << 8))
+/** The FAT signature (universal binaries). */
+#define IMAGE_FAT_SIGNATURE         UINT32_C(0xcafebabe)
+/** The FAT signature (universal binaries), other endian. */
+#define IMAGE_FAT_SIGNATURE_OE      UINT32_C(0xbebafeca)
+/** The 32-bit Mach-O signature. */
+#define IMAGE_MACHO32_SIGNATURE     UINT32_C(0xfeedface)
+/** The 32-bit Mach-O signature, other endian. */
+#define IMAGE_MACHO32_SIGNATURE_OE  UINT32_C(0xcefaedfe)
+/** The 64-bit Mach-O signature. */
+#define IMAGE_MACHO64_SIGNATURE     UINT32_C(0xfeedfacf)
+/** The 64-bit Mach-O signature, other endian. */
+#define IMAGE_MACHO64_SIGNATURE_OE  UINT32_C(0xfefaedfe)
 /** @} */
 
@@ -424,7 +436,8 @@
 /** @name Module interpreter method tables
  * @{ */
+extern KLDRMODOPS       g_kLdrModLXOps;
+extern KLDRMODOPS       g_kLdrModMachOOps;
+extern KLDRMODOPS       g_kLdrModNativeOps;
 extern KLDRMODOPS       g_kLdrModPEOps;
-extern KLDRMODOPS       g_kLdrModLXOps;
-extern KLDRMODOPS       g_kLdrModNativeOps;
 /** @} */
 
Index: /trunk/kLdr/kLdrMod.c
===================================================================
--- /trunk/kLdr/kLdrMod.c	(revision 2953)
+++ /trunk/kLdr/kLdrMod.c	(revision 2954)
@@ -38,4 +38,5 @@
 # include "kLdrModELF32.h"
 # include "kLdrModELF64.h"
+# include "kLdrModMachO.h"
 #endif
 
@@ -184,6 +185,14 @@
     else if (u.u32 == IMAGE_NT_SIGNATURE)
         rc = g_kLdrModPEOps.pfnCreate(&g_kLdrModPEOps, pRdr, offHdr, ppMod);
+    else if (   u.u32 == IMAGE_MACHO32_SIGNATURE
+             || u.u32 == IMAGE_MACHO32_SIGNATURE_OE
+             || u.u32 == IMAGE_MACHO64_SIGNATURE
+             || u.u32 == IMAGE_MACHO64_SIGNATURE_OE)
+        rc = g_kLdrModMachOOps.pfnCreate(&g_kLdrModMachOOps, pRdr, offHdr, ppMod);
     else if (u.u32 == IMAGE_ELF_SIGNATURE)
         rc = KLDR_ERR_ELF_NOT_SUPPORTED;
+    else if (   u.u32 == IMAGE_FAT_SIGNATURE
+             || u.u32 == IMAGE_FAT_SIGNATURE_OE)
+        rc = KLDR_ERR_FAT_NOT_SUPPORTED;
     else
         rc = KLDR_ERR_UNKNOWN_FORMAT;
Index: /trunk/kLdr/kLdrModMachO.c
===================================================================
--- /trunk/kLdr/kLdrModMachO.c	(revision 2953)
+++ /trunk/kLdr/kLdrModMachO.c	(revision 2954)
@@ -33,4 +33,14 @@
 #include "kLdrInternal.h"
 #include "kLdrModMachO.h"
+
+/* quick hack for now. */
+typedef struct nlist
+{
+    uint32_t    n_strx;
+    uint8_t     n_type;
+    int8_t      n_other;
+    int16_t     n_desc;
+    uint32_t    n_value;
+} nlist_t;
 
 
@@ -75,5 +85,5 @@
 *******************************************************************************/
 /**
- * Instance data for the MACH-O MH_OBJECT module interpreter.
+ * Instance data for the Mach-O MH_OBJECT module interpreter.
  * @todo interpret the other MH_* formats.
  */
@@ -121,5 +131,5 @@
 
 static int  kldrModMachODoCreate(PKLDRRDR pRdr, PKLDRMODMACHO *ppMod);
-static int  kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr,
+static int  kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr, PKLDRRDR pRdr,
                                              uint32_t *pcSegments, uint32_t *pcbStringPool);
 static int  kldrModMachOParseLoadCommands(PKLDRMODMACHO pModMachO, char *pbStringPool, uint32_t cbStringPool);
@@ -243,5 +253,5 @@
                      ? sizeof(mach_header_32_t) : sizeof(mach_header_64_t));
     if (!rc)
-        rc = kldrModMachOPreParseLoadCommands(pbLoadCommands, &s.Hdr32, &cSegments, &cbStringPool);
+        rc = kldrModMachOPreParseLoadCommands(pbLoadCommands, &s.Hdr32, pRdr, &cSegments, &cbStringPool);
     if (rc)
     {
@@ -375,12 +385,310 @@
  * @param   pbLoadCommands  The load commands to parse.
  * @param   pHdr            The header.
+ * @param   pRdr            The file reader.
  * @param   pcSegments      Where to store the segment count.
  * @param   pcbStringPool   Where to store the string pool size.
  */
-static int  kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr,
+static int  kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr, PKLDRRDR pRdr,
                                              uint32_t *pcSegments, uint32_t *pcbStringPool)
 {
+    union
+    {
+        uint8_t              *pb;
+        load_command_t       *pLoadCmd;
+        segment_command_32_t *pSeg32;
+        segment_command_64_t *pSeg64;
+        thread_command_t     *pThread;
+        symtab_command_t     *pSymTab;
+        uuid_command_t       *pUuid;
+    } u;
+    const uint64_t cbFile = kLdrRdrSize(pRdr);
+    uint32_t cSegments = 0;
+    uint32_t cbStringPool = 0;
+    uint32_t cLeft = pHdr->ncmds;
+    uint32_t cbLeft = pHdr->sizeofcmds;
+    uint8_t *pb = pbLoadCommands;
+    int      fConvertEndian = pHdr->magic == IMAGE_MACHO32_SIGNATURE_OE
+                           || pHdr->magic == IMAGE_MACHO64_SIGNATURE_OE;
+
     *pcSegments = 0;
     *pcbStringPool = 0;
+
+    while (cLeft-- > 0)
+    {
+        u.pb = pb;
+
+        /*
+         * Convert and validate command header.
+         */
+        if (cbLeft < sizeof(load_command_t))
+            return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+        if (fConvertEndian)
+        {
+            u.pLoadCmd->cmd = KLDRHLP_E2E_U32(u.pLoadCmd->cmd);
+            u.pLoadCmd->cmdsize = KLDRHLP_E2E_U32(u.pLoadCmd->cmdsize);
+        }
+        if (u.pLoadCmd->cmdsize > cbLeft)
+            return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+        cbLeft -= u.pLoadCmd->cmdsize;
+        pb += u.pLoadCmd->cmdsize;
+
+        /*
+         * Convert endian if needed, parse and validate the command.
+         */
+        switch (u.pLoadCmd->cmd)
+        {
+            case LC_SEGMENT_32:
+            {
+                section_32_t *pSect;
+                section_32_t *pFirstSect;
+                uint32_t cSectionsLeft;
+
+                /* convert and verify*/
+                if (u.pLoadCmd->cmdsize < sizeof(segment_command_32_t))
+                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+                if (fConvertEndian)
+                {
+                    u.pSeg32->vmaddr   = KLDRHLP_E2E_U32(u.pSeg32->vmaddr);
+                    u.pSeg32->vmsize   = KLDRHLP_E2E_U32(u.pSeg32->vmsize);
+                    u.pSeg32->fileoff  = KLDRHLP_E2E_U32(u.pSeg32->fileoff);
+                    u.pSeg32->filesize = KLDRHLP_E2E_U32(u.pSeg32->filesize);
+                    u.pSeg32->maxprot  = KLDRHLP_E2E_U32(u.pSeg32->maxprot);
+                    u.pSeg32->initprot = KLDRHLP_E2E_U32(u.pSeg32->initprot);
+                    u.pSeg32->nsects   = KLDRHLP_E2E_U32(u.pSeg32->nsects);
+                    u.pSeg32->flags    = KLDRHLP_E2E_U32(u.pSeg32->flags);
+                }
+
+                if (    u.pSeg32->filesize
+                    &&  (   u.pSeg32->fileoff > cbFile
+                         || (uint64_t)u.pSeg32->fileoff + u.pSeg32->filesize > cbFile))
+                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+                if (!u.pSeg32->filesize && u.pSeg32->fileoff)
+                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+                if (u.pSeg32->vmsize < u.pSeg32->filesize)
+                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+                if ((u.pSeg32->maxprot & u.pSeg32->initprot) != u.pSeg32->initprot)
+                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+                if (u.pSeg32->flags & ~(SG_HIGHVM | SG_FVMLIB | SG_NORELOC | SG_PROTECTED_VERSION_1))
+                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+                if (u.pSeg32->nsects * sizeof(section_32_t) > u.pLoadCmd->cmdsize - sizeof(segment_command_32_t))
+                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+
+                /* 
+                 * convert, validate and parse the sections. 
+                 */
+                cSectionsLeft = u.pSeg32->nsects;
+                pFirstSect = pSect = (section_32_t *)(u.pSeg32 + 1);
+                while (cSectionsLeft-- > 0)
+                {
+                    int fFileBits;
+
+                    if (fConvertEndian)
+                    {
+                        pSect->addr      = KLDRHLP_E2E_U32(pSect->addr);
+                        pSect->size      = KLDRHLP_E2E_U32(pSect->size);
+                        pSect->offset    = KLDRHLP_E2E_U32(pSect->offset);
+                        pSect->align     = KLDRHLP_E2E_U32(pSect->align);
+                        pSect->reloff    = KLDRHLP_E2E_U32(pSect->reloff);
+                        pSect->nreloc    = KLDRHLP_E2E_U32(pSect->nreloc);
+                        pSect->flags     = KLDRHLP_E2E_U32(pSect->flags);
+                        pSect->reserved1 = KLDRHLP_E2E_U32(pSect->reserved1);
+                        pSect->reserved2 = KLDRHLP_E2E_U32(pSect->reserved2);
+                    }
+
+                    /* validate */
+                    switch (pSect->flags & SECTION_TYPE)
+                    {
+                        case S_ZEROFILL:
+                            if (pSect->reserved1 || pSect->reserved2)
+                                return KLDR_ERR_MACHO_BAD_SECTION;
+                            fFileBits = 0;
+                            break;
+                        case S_REGULAR:
+                        case S_CSTRING_LITERALS:
+                            if (pSect->reserved1 || pSect->reserved2)
+                                return KLDR_ERR_MACHO_BAD_SECTION;
+                            fFileBits = 1;
+                            break;
+
+                        case S_LITERAL_POINTERS:
+                        case S_INTERPOSING:
+                        case S_GB_ZEROFILL:
+                        case S_NON_LAZY_SYMBOL_POINTERS:
+                        case S_LAZY_SYMBOL_POINTERS:
+                        case S_4BYTE_LITERALS:
+                        case S_8BYTE_LITERALS:
+                        case S_16BYTE_LITERALS:
+                        case S_SYMBOL_STUBS:
+                        case S_COALESCED:
+                        case S_MOD_INIT_FUNC_POINTERS:
+                        case S_MOD_TERM_FUNC_POINTERS:
+                            return KLDR_ERR_MACHO_UNSUPPORTED_SECTION;
+
+                        default:
+                            return KLDR_ERR_MACHO_UNKNOWN_SECTION;
+                    }
+                    if (pSect->flags & ~(  S_ATTR_PURE_INSTRUCTIONS | S_ATTR_NO_TOC | S_ATTR_STRIP_STATIC_SYMS
+                                         | S_ATTR_NO_DEAD_STRIP | S_ATTR_LIVE_SUPPORT | S_ATTR_SELF_MODIFYING_CODE
+                                         | S_ATTR_DEBUG | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_EXT_RELOC
+                                         | S_ATTR_LOC_RELOC | SECTION_TYPE))
+                        return KLDR_ERR_MACHO_BAD_SECTION;
+                    if (!pSect->size)
+                        return KLDR_ERR_MACHO_BAD_SECTION;
+                    if (    pSect->addr - u.pSeg32->vmaddr > u.pSeg32->vmsize
+                        ||  pSect->addr - u.pSeg32->vmaddr + pSect->size > u.pSeg32->vmsize)
+                        return KLDR_ERR_MACHO_BAD_SECTION;
+                    if (    pSect->align >= 31
+                        ||  (((1 << pSect->align) - 1) & pSect->addr)
+                        ||  (((1 << pSect->align) - 1) & u.pSeg32->vmaddr))
+                        return KLDR_ERR_MACHO_BAD_SECTION;
+                    if (    fFileBits 
+                        &&  (   pSect->offset > cbFile
+                             || (uint64_t)pSect->offset + pSect->size > cbFile))
+                        return KLDR_ERR_MACHO_BAD_SECTION;
+                    if (!fFileBits && pSect->offset)
+                        return KLDR_ERR_MACHO_BAD_SECTION;
+                    if (!pSect->nreloc && pSect->reloff)
+                        return KLDR_ERR_MACHO_BAD_SECTION;
+                    if (    pSect->nreloc 
+                        &&  (   pSect->reloff > cbFile
+                             || (uint64_t)pSect->reloff + (off_t)pSect->nreloc * sizeof(nlist_t)) > cbFile)
+                        return KLDR_ERR_MACHO_BAD_SECTION;
+
+
+                    /* count segments and strings */
+                    switch (pHdr->filetype)
+                    {
+                        case MH_OBJECT:
+                        {
+                            /* Don't load debug symbols. (test this) */
+                            if (pSect->flags & S_ATTR_DEBUG)
+                                break;
+
+                            /* a new segment? */
+                            if (    pSect == pFirstSect
+                                ||  kLdrHlpStrNComp(pSect->segname, (pSect - 1)->segname, sizeof(pSect->segname)))
+                            {
+                                /* verify that the linker/assembler has ordered sections correctly. */
+                                section_32_t *pCur = (pSect - 2);
+                                while ((uintptr_t)pCur >= (uintptr_t)pFirstSect)
+                                {
+                                    if (!kLdrHlpStrNComp(pCur->segname, pSect->segname, sizeof(pSect->segname)))
+                                        return KLDR_ERR_MACHO_BAD_SECTION_ORDER;
+                                    pCur--;
+                                }
+
+                                /* ok. count it and the string. */
+                                cSegments++;
+                                cbStringPool += kLdrHlpStrLen(pSect->segname) + 1;
+                            }
+                            break;
+                        }
+
+                        default:
+                            return KLDR_ERR_INVALID_PARAMETER;
+                    }
+
+                    /* next */
+                    pSect++;
+                }
+                break;
+            }
+
+            case LC_SEGMENT_64:
+                /* copy 32-bit code */
+                break;
+
+            case LC_SYMTAB:
+                if (fConvertEndian)
+                {
+                    u.pSymTab->symoff  = KLDRHLP_E2E_U32(u.pSymTab->symoff);
+                    u.pSymTab->nsyms   = KLDRHLP_E2E_U32(u.pSymTab->nsyms);
+                    u.pSymTab->stroff  = KLDRHLP_E2E_U32(u.pSymTab->stroff);
+                    u.pSymTab->strsize = KLDRHLP_E2E_U32(u.pSymTab->strsize);
+                }
+
+                /* verify */
+                if (    u.pSymTab->symoff >= cbFile
+                    ||  (uint64_t)u.pSymTab->symoff + u.pSymTab->nsyms * sizeof(nlist_t) > kLdrRdrSize(pRdr))
+                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+                if (    u.pSymTab->stroff >= cbFile
+                    ||  (uint64_t)u.pSymTab->stroff + u.pSymTab->strsize > cbFile)
+                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+                break;
+
+            case LC_THREAD:
+            case LC_UNIXTHREAD:
+            {
+                uint32_t *pu32 = (uint32_t *)(u.pb + sizeof(load_command_t));
+                uint32_t cItemsLeft = (u.pThread->cmdsize - sizeof(load_command_t)) / sizeof(uint32_t);
+                while (cItemsLeft)
+                {
+                    /* convert & verify header items ([0] == flavor, [1] == uint32_t count). */
+                    if (cItemsLeft < 2)
+                        return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+                    if (fConvertEndian)
+                    {
+                        pu32[0] = KLDRHLP_E2E_U32(pu32[0]);
+                        pu32[1] = KLDRHLP_E2E_U32(pu32[1]);
+                    }
+                    if (pu32[1] + 2 > cItemsLeft)
+                        return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+
+                    /* convert & verify according to flavor. */
+                    switch (pu32[0])
+                    {
+                        /** @todo */
+                        default:
+                            break;
+                    }
+
+                    /* next */
+                    cItemsLeft -= pu32[1] + 2;
+                    pu32 += pu32[1] + 2;
+                }
+                break;
+            }
+
+            case LC_UUID:
+                if (u.pUuid->cmdsize != sizeof(uuid_command_t))
+                    return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+                /** @todo Check anything here need converting? */
+                break;
+
+            case LC_LOADFVMLIB:
+            case LC_IDFVMLIB:
+            case LC_IDENT:
+            case LC_FVMFILE:
+            case LC_PREPAGE:
+            case LC_DYSYMTAB:
+            case LC_LOAD_DYLIB:
+            case LC_ID_DYLIB:
+            case LC_LOAD_DYLINKER:
+            case LC_ID_DYLINKER:
+            case LC_PREBOUND_DYLIB:
+            case LC_ROUTINES:
+            case LC_ROUTINES_64:
+            case LC_SUB_FRAMEWORK:
+            case LC_SUB_UMBRELLA:
+            case LC_SUB_CLIENT:
+            case LC_SUB_LIBRARY:
+            case LC_TWOLEVEL_HINTS:
+            case LC_PREBIND_CKSUM:
+            case LC_LOAD_WEAK_DYLIB:
+            case LC_SYMSEG:
+                return KLDR_ERR_MACHO_UNSUPPORTED_LOAD_COMMAND;
+
+            default:
+                return KLDR_ERR_MACHO_UNKNOWN_LOAD_COMMAND;
+        }
+    }
+
+    /* be strict (for now). */
+    if (cbLeft)
+        return KLDR_ERR_MACHO_BAD_LOAD_COMMAND;
+
+    *pcSegments = cSegments;
+    *pcbStringPool = cLeft;
+
     return 0;
 }
@@ -1723,5 +2031,5 @@
 /** @copydoc kLdrModRelocateBits */
 static int kldrModMachORelocateBits(PKLDRMOD pMod, void *pvBits, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress,
-                                 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
+                                    PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser)
 {
     PKLDRMODMACHO pModMachO = (PKLDRMODMACHO)pMod->pvData;
@@ -1740,9 +2048,9 @@
 
 /**
- * The PE module interpreter method table.
+ * The Mach-O module interpreter method table.
  */
-KLDRMODOPS g_kLdrModPEOps =
-{
-    "PE",
+KLDRMODOPS g_kLdrModMachOOps =
+{
+    "Mach-O",
     NULL,
     kldrModMachOCreate,
Index: /trunk/kLdr/kLdrModMachO.h
===================================================================
--- /trunk/kLdr/kLdrModMachO.h	(revision 2953)
+++ /trunk/kLdr/kLdrModMachO.h	(revision 2954)
@@ -283,5 +283,5 @@
 {
     uint32_t        cmd;            /**< The load command id. */
-    uint32_t        cmdsize;        /**< The size of the command (including this header?). */
+    uint32_t        cmdsize;        /**< The size of the command (including this header). */
 } load_command_t;
 
@@ -308,5 +308,5 @@
 #define LC_ID_DYLIB         UINT32_C(0x0d)  /**< Dynamically linked share library ident. See dylib_command. */
 #define LC_LOAD_DYLINKER    UINT32_C(0x0e)  /**< Load a dynamical link editor. See dylinker_command. */
-#define LC_ID_DYLINKER      UINt32_C(0x0f)  /**< Dynamic link editor ident. See dylinker_command. */
+#define LC_ID_DYLINKER      UINT32_C(0x0f)  /**< Dynamic link editor ident. See dylinker_command. */
 #define LC_PREBOUND_DYLIB   UINT32_C(0x10)  /**< Prebound modules for dynamically linking of a shared lib. See prebound_dylib_command. */
 #define LC_ROUTINES         UINT32_C(0x11)  /**< Image routines. See routines_command_32. */
