Index: trunk/src/VBox/Runtime/common/ldr/ldrLX.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/ldr/ldrLX.cpp	(revision 74645)
+++ trunk/src/VBox/Runtime/common/ldr/ldrLX.cpp	(revision 74646)
@@ -213,17 +213,21 @@
     /* Verify the loader section. */
     offEnd = Hdr.e32_objtab + Hdr.e32_ldrsize;
-    if (Hdr.e32_objtab < sizeof(Hdr))
-        return VERR_LDRLX_BAD_LOADER_SECTION;
+    if (Hdr.e32_objtab < sizeof(Hdr) && Hdr.e32_objcnt)
+        return RTErrInfoSetF(pErrInfo, VERR_LDRLX_BAD_LOADER_SECTION,
+                             "Object table is inside the header: %#x", Hdr.e32_objtab);
     off = Hdr.e32_objtab + sizeof(struct o32_obj) * Hdr.e32_objcnt;
     if (off > offEnd)
-        return VERR_LDRLX_BAD_LOADER_SECTION;
+        return RTErrInfoSetF(pErrInfo, VERR_LDRLX_BAD_LOADER_SECTION,
+                             "Object table spans beyond the executable: e32_objcnt=%u", Hdr.e32_objcnt);
     if (    Hdr.e32_objmap
         &&  (Hdr.e32_objmap < off || Hdr.e32_objmap > offEnd))
-        return VERR_LDRLX_BAD_LOADER_SECTION;
+        return RTErrInfoSetF(pErrInfo, VERR_LDRLX_BAD_LOADER_SECTION,
+                             "Bad object page map table offset: %#x", Hdr.e32_objmap);
     if (    Hdr.e32_rsrccnt
         && (   Hdr.e32_rsrctab < off
             || Hdr.e32_rsrctab > offEnd
             || Hdr.e32_rsrctab + sizeof(struct rsrc32) * Hdr.e32_rsrccnt > offEnd))
-        return VERR_LDRLX_BAD_LOADER_SECTION;
+        return RTErrInfoSetF(pErrInfo, VERR_LDRLX_BAD_LOADER_SECTION,
+                             "Resource table is out of bounds: %#x entries at %#x", Hdr.e32_rsrccnt, Hdr.e32_rsrctab);
     if (    Hdr.e32_restab
         &&  (Hdr.e32_restab < off || Hdr.e32_restab > offEnd - 2))
@@ -510,10 +514,4 @@
     KLDRMODLX_ASSERT(!pModLX->pvMapping);
 
-    int rc = VINF_SUCCESS;
-    if (pModLX->Core.pReader)
-    {
-        rc = pModLX->Core.pReader->pfnDestroy(pModLX->Core.pReader);
-        pModLX->Core.pReader = NULL;
-    }
     if (pModLX->pbNonResNameTab)
     {
@@ -526,8 +524,5 @@
         pModLX->pbFixupSection = NULL;
     }
-    pModLX->Core.u32Magic = 0;
-    pModLX->Core.pOps = NULL;
-    RTMemFree(pModLX);
-    return rc;
+    return VINF_SUCCESS;
 }
 
Index: trunk/src/VBox/Runtime/common/ldr/ldrMachO.cpp
===================================================================
--- trunk/src/VBox/Runtime/common/ldr/ldrMachO.cpp	(revision 74645)
+++ trunk/src/VBox/Runtime/common/ldr/ldrMachO.cpp	(revision 74646)
@@ -199,5 +199,5 @@
 
     /** The image UUID, all zeros if not found. */
-    uint32_t                abImageUuid[16];
+    uint8_t                 abImageUuid[16];
 
     /** The RVA of the Global Offset Table. */
@@ -230,5 +230,5 @@
 static int  kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr, PRTLDRREADER pRdr, RTFOFF   offImage,
                                              uint32_t fOpenFlags, uint32_t *pcSegments, uint32_t *pcSections, uint32_t *pcbStringPool,
-                                             bool *pfCanLoad, PRTLDRADDR pLinkAddress, uint8_t *puEffFileType);
+                                             bool *pfCanLoad, PRTLDRADDR pLinkAddress, uint8_t *puEffFileType, PRTERRINFO pErrInfo);
 static int  kldrModMachOParseLoadCommands(PKLDRMODMACHO pThis, char *pbStringPool, uint32_t cbStringPool);
 
@@ -344,5 +344,6 @@
     if (RT_SUCCESS(rc))
         rc = kldrModMachOPreParseLoadCommands(pbLoadCommands, &s.Hdr32, pRdr, offImage, fOpenFlags,
-                                              &cSegments, &cSections, &cbStringPool, &fCanLoad, &LinkAddress, &uEffFileType);
+                                              &cSegments, &cSections, &cbStringPool, &fCanLoad, &LinkAddress, &uEffFileType,
+                                              pErrInfo);
     if (RT_FAILURE(rc))
     {
@@ -510,5 +511,5 @@
  * @param   fOpenFlags      RTLDR_O_XXX.
  * @param   pcSegments      Where to store the segment count.
- * @param   pcSegments      Where to store the section count.
+ * @param   pcSections      Where to store the section count.
  * @param   pcbStringPool   Where to store the string pool size.
  * @param   pfCanLoad       Where to store the can-load-image indicator.
@@ -516,9 +517,10 @@
  *                          lowest segment address).
  * @param   puEffFileType   Where to store the effective file type.
+ * @param   pErrInfo        Where to return additional error info. Optional.
  */
 static int kldrModMachOPreParseLoadCommands(uint8_t *pbLoadCommands, const mach_header_32_t *pHdr, PRTLDRREADER pRdr,
                                             RTFOFF offImage, uint32_t fOpenFlags, uint32_t *pcSegments, uint32_t *pcSections,
                                             uint32_t *pcbStringPool, bool *pfCanLoad, PRTLDRADDR pLinkAddress,
-                                            uint8_t *puEffFileType)
+                                            uint8_t *puEffFileType, PRTERRINFO pErrInfo)
 {
     union
@@ -598,5 +600,5 @@
 
                 /* Validation code shared with the 64-bit variant. */
-                #define VALIDATE_AND_ADD_SEGMENT(a_cBits) \
+#define VALIDATE_AND_ADD_SEGMENT(a_cBits) \
                 do { \
                     bool fSkipSeg = !strcmp(pSrcSeg->segname, "__DWARF")   /* Note: Not for non-object files. */ \
@@ -1005,5 +1007,6 @@
                 /** @todo valid command size. */
                 if (!(fOpenFlags & RTLDR_O_FOR_DEBUG))
-                    KLDRMODMACHO_FAILED_RETURN(VERR_LDRMACHO_UNSUPPORTED_LOAD_COMMAND);
+                    KLDRMODMACHO_FAILED_RETURN(RTErrInfoSetF(pErrInfo, VERR_LDRMACHO_UNSUPPORTED_LOAD_COMMAND,
+                                                             "cmd=%#x", u.pLoadCmd->cmd));
                 *pfCanLoad = false;
                 break;
@@ -1023,8 +1026,10 @@
             case LC_PREBIND_CKSUM:
             case LC_SYMSEG:
-                KLDRMODMACHO_FAILED_RETURN(VERR_LDRMACHO_UNSUPPORTED_LOAD_COMMAND);
+                KLDRMODMACHO_FAILED_RETURN(RTErrInfoSetF(pErrInfo, VERR_LDRMACHO_UNSUPPORTED_LOAD_COMMAND,
+                                                         "cmd=%#x", u.pLoadCmd->cmd));
 
             default:
-                KLDRMODMACHO_FAILED_RETURN(VERR_LDRMACHO_UNKNOWN_LOAD_COMMAND);
+                KLDRMODMACHO_FAILED_RETURN(RTErrInfoSetF(pErrInfo, VERR_LDRMACHO_UNKNOWN_LOAD_COMMAND,
+                                                         "cmd=%#x", u.pLoadCmd->cmd));
         }
     }
@@ -1418,5 +1423,4 @@
 {
     PKLDRMODMACHO pThis = RT_FROM_MEMBER(pMod, KLDRMODMACHO, Core);
-    int rc = VINF_SUCCESS;
     KLDRMODMACHO_ASSERT(!pThis->pvMapping);
 
@@ -1432,11 +1436,4 @@
     }
 
-    if (pThis->Core.pReader)
-    {
-        rc = pThis->Core.pReader->pfnDestroy(pThis->Core.pReader);
-        pThis->Core.pReader = NULL;
-    }
-    pThis->Core.u32Magic = 0;
-    pThis->Core.pOps = NULL;
     RTMemFree(pThis->pbLoadCommands);
     pThis->pbLoadCommands = NULL;
@@ -1445,6 +1442,6 @@
     RTMemFree(pThis->pvaSymbols);
     pThis->pvaSymbols = NULL;
-    RTMemFree(pThis);
-    return rc;
+
+    return VINF_SUCCESS;
 }
 
@@ -2294,16 +2291,4 @@
 
 #endif
-
-static int kldrModMachOQueryImageUuid(PKLDRMODMACHO pThis, const void *pvBits, void *pvUuid, size_t cbUuid)
-{
-    RT_NOREF(pvBits);
-
-    memset(pvUuid, 0, cbUuid);
-    if (memcmp(pvUuid, pThis->abImageUuid, sizeof(pThis->abImageUuid)) == 0)
-        return VERR_NOT_FOUND;
-
-    memcpy(pvUuid, pThis->abImageUuid, sizeof(pThis->abImageUuid));
-    return VINF_SUCCESS;
-}
 
 
@@ -2748,4 +2733,6 @@
  * @param   pbSectBits      Pointer to the section bits.
  * @param   pFixupSect      The section being fixed up.
+ * @param   paSyms          Pointer to the symbol table.
+ * @param   cSyms           Number of symbols.
  * @param   NewBaseAddress  The new base image address.
  */
@@ -2949,4 +2936,6 @@
  * @param   pbSectBits      Pointer to the section bits.
  * @param   pFixupSect      The section being fixed up.
+ * @param   paSyms          Pointer to the symbol table.
+ * @param   cSyms           Number of symbols.
  * @param   NewBaseAddress  The new base image address.
  */
@@ -3776,8 +3765,13 @@
     {
         case RTLDRPROP_UUID:
-            rc = kldrModMachOQueryImageUuid(pThis, pvBits, (uint8_t *)pvBuf, cbBuf);
-            if (RT_FAILURE(rc))
-                return rc;
-            cbBuf = RT_MIN(cbBuf, sizeof(RTUUID));
+            Assert(cbBuf >= sizeof(pThis->abImageUuid));
+            if (!ASMMemIsZero(pThis->abImageUuid, sizeof(pThis->abImageUuid)))
+            {
+                *pcbRet = sizeof(pThis->abImageUuid);
+                memcpy(pvBuf, pThis->abImageUuid, sizeof(pThis->abImageUuid));
+                rc = VINF_SUCCESS;
+            }
+            else
+                rc = VERR_NOT_FOUND;
             break;
 
@@ -3787,10 +3781,9 @@
 
         default:
-            return VERR_NOT_FOUND;
-    }
-    if (pcbRet)
-        *pcbRet = cbBuf;
+            rc = VERR_NOT_FOUND;
+            break;
+    }
     RT_NOREF_PV(pvBits);
-    return VINF_SUCCESS;
+    return rc;
 }
 
Index: trunk/src/VBox/Runtime/testcase/tstLdr-3.cpp
===================================================================
--- trunk/src/VBox/Runtime/testcase/tstLdr-3.cpp	(revision 74645)
+++ trunk/src/VBox/Runtime/testcase/tstLdr-3.cpp	(revision 74646)
@@ -226,4 +226,14 @@
 }
 
+static uint32_t g_iSegNo = 0;
+static DECLCALLBACK(int) testEnumSegment1(RTLDRMOD hLdrMod, PCRTLDRSEG pSeg, void *pvUser)
+{
+    if (hLdrMod != g_hLdrMod || pvUser != NULL)
+        return VERR_INTERNAL_ERROR_3;
+    RTPrintf("Seg#%02u: %RTptr LB %RTptr %s\n", g_iSegNo++, pSeg->RVA, pSeg->cbMapped, pSeg->pszName);
+
+    return VINF_SUCCESS;
+}
+
 
 /**
@@ -239,5 +249,6 @@
 static DECLCALLBACK(int) testEnumSymbol1(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol, RTUINTPTR Value, void *pvUser)
 {
-    RT_NOREF2(hLdrMod, pvUser);
+    if (hLdrMod != g_hLdrMod || pvUser != NULL)
+        return VERR_INTERNAL_ERROR_3;
     RTPrintf("  %RTptr %s (%d)\n", Value, pszSymbol, uSymbol);
     return VINF_SUCCESS;
@@ -354,4 +365,66 @@
                 rcRet++;
             }
+
+            /*
+             * Query various properties.
+             */
+            union
+            {
+                char        szName[256];
+                uint32_t    iImpModule;
+                RTUUID      Uuid;
+            } uBuf;
+            rc = RTLdrQueryProp(g_hLdrMod, RTLDRPROP_INTERNAL_NAME, &uBuf, sizeof(uBuf));
+            if (RT_SUCCESS(rc))
+                RTPrintf("tstLdr-3: Internal name: %s\n", uBuf.szName);
+            else if (rc != VERR_NOT_FOUND && rc != VERR_NOT_SUPPORTED)
+            {
+                RTPrintf("tstLdr-3: Internal name: failed - %Rrc\n", rc);
+                rcRet++;
+            }
+
+            uint32_t cImports = 0;
+            rc = RTLdrQueryProp(g_hLdrMod, RTLDRPROP_IMPORT_COUNT, &cImports, sizeof(cImports));
+            if (RT_SUCCESS(rc))
+            {
+                RTPrintf("tstLdr-3: Import count: %u\n", cImports);
+                for (uint32_t i = 0; i < cImports; i++)
+                {
+                    uBuf.iImpModule = i;
+                    rc = RTLdrQueryProp(g_hLdrMod, RTLDRPROP_IMPORT_MODULE, &uBuf, sizeof(uBuf));
+                    if (RT_SUCCESS(rc))
+                        RTPrintf("tstLdr-3: Import module #%u: %s\n", i, uBuf.szName);
+                    else
+                    {
+                        RTPrintf("tstLdr-3: Import module #%u: failed - %Rrc\n", i, rc);
+                        rcRet++;
+                    }
+                }
+            }
+            else if (rc != VERR_NOT_FOUND && rc != VERR_NOT_SUPPORTED)
+            {
+                RTPrintf("tstLdr-3: Import count: failed - %Rrc\n", rc);
+                rcRet++;
+            }
+
+            rc = RTLdrQueryProp(g_hLdrMod, RTLDRPROP_UUID, &uBuf.Uuid, sizeof(uBuf.Uuid));
+            if (RT_SUCCESS(rc))
+                RTPrintf("tstLdr-3: UUID: %RTuuid\n", uBuf.Uuid);
+            else if (rc != VERR_NOT_FOUND && rc != VERR_NOT_SUPPORTED)
+            {
+                RTPrintf("tstLdr-3: UUID: failed - %Rrc\n", rc);
+                rcRet++;
+            }
+
+            /*
+             * Enumerate segments.
+             */
+            RTPrintf("tstLdr-3: Segments:\n");
+            rc = RTLdrEnumSegments(g_hLdrMod, testEnumSegment1, NULL);
+            if (RT_FAILURE(rc))
+            {
+                RTPrintf("tstLdr-3: Failed to enumerate symbols: %Rra\n", rc);
+                rcRet++;
+            }
         }
     }
