From 29cd838eab01ed7110f3ccb2e8c6a35c8a31dbcc Mon Sep 17 00:00:00 2001
From: Daniel Baumann <daniel.baumann@progress-linux.org>
Date: Thu, 11 Apr 2024 10:21:29 +0200
Subject: Adding upstream version 1:0.1.9998svn3589+dfsg.

Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
---
 src/lib/kStuff/kHlp/Bare/Makefile.kup      |   0
 src/lib/kStuff/kHlp/Bare/kHlpBare-gcc.c    | 223 +++++++++
 src/lib/kStuff/kHlp/Bare/kHlpBareAssert.c  | 138 ++++++
 src/lib/kStuff/kHlp/Bare/kHlpBareEnv.c     | 102 ++++
 src/lib/kStuff/kHlp/Bare/kHlpBareHeap.c    | 763 +++++++++++++++++++++++++++++
 src/lib/kStuff/kHlp/Bare/kHlpBareProcess.c |  85 ++++
 src/lib/kStuff/kHlp/Bare/kHlpBareThread.c  |  93 ++++
 src/lib/kStuff/kHlp/Bare/kHlpSys-darwin.c  | 345 +++++++++++++
 8 files changed, 1749 insertions(+)
 create mode 100644 src/lib/kStuff/kHlp/Bare/Makefile.kup
 create mode 100644 src/lib/kStuff/kHlp/Bare/kHlpBare-gcc.c
 create mode 100644 src/lib/kStuff/kHlp/Bare/kHlpBareAssert.c
 create mode 100644 src/lib/kStuff/kHlp/Bare/kHlpBareEnv.c
 create mode 100644 src/lib/kStuff/kHlp/Bare/kHlpBareHeap.c
 create mode 100644 src/lib/kStuff/kHlp/Bare/kHlpBareProcess.c
 create mode 100644 src/lib/kStuff/kHlp/Bare/kHlpBareThread.c
 create mode 100644 src/lib/kStuff/kHlp/Bare/kHlpSys-darwin.c

(limited to 'src/lib/kStuff/kHlp/Bare')

diff --git a/src/lib/kStuff/kHlp/Bare/Makefile.kup b/src/lib/kStuff/kHlp/Bare/Makefile.kup
new file mode 100644
index 0000000..e69de29
diff --git a/src/lib/kStuff/kHlp/Bare/kHlpBare-gcc.c b/src/lib/kStuff/kHlp/Bare/kHlpBare-gcc.c
new file mode 100644
index 0000000..889e48f
--- /dev/null
+++ b/src/lib/kStuff/kHlp/Bare/kHlpBare-gcc.c
@@ -0,0 +1,223 @@
+/* $Id: kHlpBare-gcc.c 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpBare - The Dynamic Loader, Helper Functions for GCC.
+ */
+
+/*
+ * Copyright (c) 2006-2007 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <k/kLdr.h>
+#include "kHlp.h"
+
+
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
+
+
+void *memchr(const void *pv, int ch, KSIZE cb)
+{
+    const char *pb = pv;
+    while (cb-- > 0)
+    {
+        if (*pb == ch)
+            return (void *)pb;
+        pb++;
+    }
+    return 0;
+}
+
+
+int memcmp(const void *pv1, const void *pv2, KSIZE cb)
+{
+    /*
+     * Pointer size pointer size.
+     */
+    if (    cb > 16
+        &&  !((KUPTR)pv1 & (sizeof(void *) - 1))
+        &&  !((KUPTR)pv2 & (sizeof(void *) - 1)) )
+    {
+        const KUPTR *pu1 = pv1;
+        const KUPTR *pu2 = pv2;
+        while (cb >= sizeof(KUPTR))
+        {
+            const KUPTR u1 = *pu1++;
+            const KUPTR u2 = *pu2++;
+            if (u1 != u2)
+                return u1 > u2 ? 1 : -1;
+            cb -= sizeof(KUPTR);
+        }
+        if (!cb)
+            return 0;
+        pv1 = (const void *)pu1;
+        pv2 = (const void *)pu2;
+    }
+
+    /*
+     * Byte by byte.
+     */
+    if (cb)
+    {
+        const unsigned char *pb1 = pv1;
+        const unsigned char *pb2 = pv2;
+        while (cb-- > 0)
+        {
+            const unsigned char b1 = *pb1++;
+            const unsigned char b2 = *pb2++;
+            if (b1 != b2)
+                return b1 > b2 ? 1 : -1;
+        }
+    }
+    return 0;
+}
+
+
+void *memcpy(void *pv1, const void *pv2, KSIZE cb)
+{
+    void *pv1Start = pv1;
+
+    /*
+     * Pointer size pointer size.
+     */
+    if (    cb > 16
+        &&  !((KUPTR)pv1 & (sizeof(void *) - 1))
+        &&  !((KUPTR)pv2 & (sizeof(void *) - 1)) )
+    {
+        KUPTR       *pu1 = pv1;
+        const KUPTR *pu2 = pv2;
+        while (cb >= sizeof(KUPTR))
+        {
+            cb -= sizeof(KUPTR);
+            *pu1++ = *pu2++;
+        }
+        if (!cb)
+            return 0;
+        pv1 = (void *)pu1;
+        pv2 = (const void *)pu2;
+    }
+
+    /*
+     * byte by byte
+     */
+    if (cb)
+    {
+        unsigned char       *pb1 = pv1;
+        const unsigned char *pb2 = pv2;
+        while (cb-- > 0)
+            *pb1++ = *pb2++;
+    }
+
+    return pv1Start;
+}
+
+void *memset(void *pv, int ch, KSIZE cb)
+{
+    void *pvStart = pv;
+
+    /*
+     * Pointer size pointer size.
+     */
+    if (    cb > 16
+        &&  !((KUPTR)pv & (sizeof(void *) - 1)))
+    {
+        KUPTR  *pu = pv;
+        KUPTR   u = ch | (ch << 8);
+        u |= u << 16;
+#if K_ARCH_BITS >= 64
+        u |= u << 32;
+#endif
+#if K_ARCH_BITS >= 128
+        u |= u << 64;
+#endif
+
+        while (cb >= sizeof(KUPTR))
+        {
+            cb -= sizeof(KUPTR);
+            *pu++ = u;
+        }
+    }
+
+    /*
+     * Byte by byte
+     */
+    if (cb)
+    {
+        unsigned char *pb = pv;
+        while (cb-- > 0)
+            *pb++ = ch;
+    }
+    return pvStart;
+}
+
+
+int strcmp(const char *psz1, const char *psz2)
+{
+    for (;;)
+    {
+        const char ch1 = *psz1++;
+        const char ch2 = *psz2++;
+        if (ch1 != ch2)
+            return (int)ch1 - (int)ch2;
+        if (!ch1)
+            return 0;
+    }
+}
+
+
+int strncmp(const char *psz1, const char *psz2, KSIZE cch)
+{
+    while (cch-- > 0)
+    {
+        const char ch1 = *psz1++;
+        const char ch2 = *psz2++;
+        if (ch1 != ch2)
+            return (int)ch1 - (int)ch2;
+        if (!ch1)
+            break;
+    }
+    return 0;
+}
+
+char *strchr(const char *psz, int ch)
+{
+    for (;;)
+    {
+        const char chCur = *psz;
+        if (chCur == ch)
+            return (char *)psz;
+        if (!chCur)
+            return 0;
+        psz++;
+    }
+}
+
+KSIZE strlen(const char *psz)
+{
+    const char *pszStart = psz;
+    while (*psz)
+        psz++;
+    return psz - pszStart;
+}
+
diff --git a/src/lib/kStuff/kHlp/Bare/kHlpBareAssert.c b/src/lib/kStuff/kHlp/Bare/kHlpBareAssert.c
new file mode 100644
index 0000000..138e73e
--- /dev/null
+++ b/src/lib/kStuff/kHlp/Bare/kHlpBareAssert.c
@@ -0,0 +1,138 @@
+/* $Id: kHlpBareAssert.c 82 2016-08-22 21:01:51Z bird $ */
+/** @file
+ * kHlpBare - Assert Backend.
+ */
+
+/*
+ * Copyright (c) 2006-2007 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <k/kHlpAssert.h>
+#include <k/kHlpString.h>
+
+#if K_OS == K_OS_DARWIN \
+ || K_OS == K_OS_FREEBSD \
+ || K_OS == K_OS_LINUX \
+ || K_OS == K_OS_NETBSD \
+ || K_OS == K_OS_OPENBSD \
+ || K_OS == K_OS_SOLARIS
+# include <k/kHlpSys.h>
+
+#elif K_OS == K_OS_OS2
+# define INCL_BASE
+# define INCL_ERRORS
+# include <os2.h>
+
+#elif  K_OS == K_OS_WINDOWS
+# include <Windows.h>
+
+#else
+# error "port me"
+#endif
+
+
+/**
+ * Writes a assert string with unix lineendings.
+ *
+ * @param   pszMsg  The string.
+ */
+static void kHlpAssertWrite(const char *pszMsg)
+{
+#if K_OS == K_OS_DARWIN \
+ || K_OS == K_OS_FREEBSD \
+ || K_OS == K_OS_LINUX \
+ || K_OS == K_OS_NETBSD \
+ || K_OS == K_OS_OPENBSD \
+ || K_OS == K_OS_SOLARIS
+    KSIZE cchMsg = kHlpStrLen(pszMsg);
+    kHlpSys_write(2 /* stderr */, pszMsg, cchMsg);
+
+#elif K_OS == K_OS_OS2 ||  K_OS == K_OS_WINDOWS
+    /*
+     * Line by line.
+     */
+    ULONG       cbWritten;
+    const char *pszNl = kHlpStrChr(pszMsg, '\n');
+    while (pszNl)
+    {
+        cbWritten = pszNl - pszMsg;
+
+# if K_OS == K_OS_OS2
+        if (cbWritten)
+            DosWrite((HFILE)2, pszMsg, cbWritten, &cbWritten);
+        DosWrite((HFILE)2, "\r\n", 2, &cbWritten);
+# else /* K_OS == K_OS_WINDOWS */
+        if (cbWritten)
+            WriteFile((HANDLE)STD_ERROR_HANDLE, pszMsg, cbWritten, &cbWritten, NULL);
+        WriteFile((HANDLE)STD_ERROR_HANDLE, "\r\n", 2, &cbWritten, NULL);
+# endif
+
+        /* next */
+        pszMsg = pszNl + 1;
+        pszNl = kHlpStrChr(pszMsg, '\n');
+    }
+
+    /*
+     * Remaining incomplete line.
+     */
+    if (*pszMsg)
+    {
+        cbWritten = kHlpStrLen(pszMsg);
+# if K_OS == K_OS_OS2
+        DosWrite((HFILE)2, pszMsg, cbWritten, &cbWritten);
+# else /* K_OS == K_OS_WINDOWS */
+        WriteFile((HANDLE)STD_ERROR_HANDLE, pszMsg, cbWritten, &cbWritten, NULL);
+# endif
+    }
+
+#else
+# error "port me"
+#endif
+}
+
+
+KHLP_DECL(void) kHlpAssertMsg1(const char *pszExpr, const char *pszFile, unsigned iLine, const char *pszFunction)
+{
+    char szLine[16];
+
+    kHlpAssertWrite("\n!!!kLdr Assertion Failed!!!\nExpression: ");
+    kHlpAssertWrite(pszExpr);
+    kHlpAssertWrite("\nAt: ");
+    kHlpAssertWrite(pszFile);
+    kHlpAssertWrite("(");
+    kHlpAssertWrite(kHlpInt2Ascii(szLine, sizeof(szLine), iLine, 10));
+    kHlpAssertWrite(") ");
+    kHlpAssertWrite(pszFunction);
+    kHlpAssertWrite("\n");
+}
+
+
+KHLP_DECL(void) kHlpAssertMsg2(const char *pszFormat, ...)
+{
+    kHlpAssertWrite(pszFormat);
+}
+
diff --git a/src/lib/kStuff/kHlp/Bare/kHlpBareEnv.c b/src/lib/kStuff/kHlp/Bare/kHlpBareEnv.c
new file mode 100644
index 0000000..353c19e
--- /dev/null
+++ b/src/lib/kStuff/kHlp/Bare/kHlpBareEnv.c
@@ -0,0 +1,102 @@
+/* $Id: kHlpBareEnv.c 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpBare - Environment Manipulation.
+ */
+
+/*
+ * Copyright (c) 2006-2007 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <k/kHlpEnv.h>
+#include <k/kHlpString.h>
+#include <k/kErrors.h>
+
+#if K_OS == K_OS_DARWIN
+
+#elif K_OS == K_OS_LINUX
+
+#elif K_OS == K_OS_OS2
+# define INCL_BASE
+# define INCL_ERRORS
+# include <os2.h>
+
+#elif  K_OS == K_OS_WINDOWS
+# include <Windows.h>
+
+#else
+# error "port me"
+#endif
+
+
+KHLP_DECL(int) kHlpGetEnv(const char *pszVar, char *pszVal, KSIZE cchVal)
+{
+#if K_OS == K_OS_DARWIN
+    /** @todo need to figure out where the stuff is or how it's inherited on darwin ... */
+    return KERR_ENVVAR_NOT_FOUND;
+
+#elif K_OS == K_OS_LINUX
+    /** @todo either read /proc/self/environ or figure out where in the memory the initial environment is... */
+    return KERR_ENVVAR_NOT_FOUND;
+
+#elif K_OS == K_OS_OS2
+    PSZ pszValue = NULL;
+    int rc;
+
+    *pszVal = '\0';
+    rc = DosScanEnv((PCSZ)pszVar, &pszValue);
+    if (!rc)
+    {
+        KSIZE  cch = kHlpStrLen((const char *)pszValue);
+        if (cchVal > cch)
+            kHlpMemCopy(pszVal, pszValue, cch + 1);
+        else
+            rc = KERR_BUFFER_OVERFLOW;
+    }
+    else
+        rc = KERR_ENVVAR_NOT_FOUND;
+    return rc;
+
+#elif K_OS == K_OS_WINDOWS
+    DWORD cch;
+
+    SetLastError(0);
+    cch = GetEnvironmentVariable(pszVar, pszVal, cchVal);
+    if (cch > 0 && cch < cchVal)
+        return 0;
+
+    *pszVal = '\0';
+    if (cch >= cchVal)
+        return KERR_BUFFER_OVERFLOW;
+    if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
+        return KERR_ENVVAR_NOT_FOUND;
+    return GetLastError();
+
+#else
+# error "Port me"
+#endif
+}
+
diff --git a/src/lib/kStuff/kHlp/Bare/kHlpBareHeap.c b/src/lib/kStuff/kHlp/Bare/kHlpBareHeap.c
new file mode 100644
index 0000000..d5e44b4
--- /dev/null
+++ b/src/lib/kStuff/kHlp/Bare/kHlpBareHeap.c
@@ -0,0 +1,763 @@
+/* $Id: kHlpBareHeap.c 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpBare - Heap.
+ */
+
+/*
+ * Copyright (c) 2006-2007 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define KHLPHEAP_STRICT
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <k/kHlpAlloc.h>
+#include <k/kHlpString.h>
+#include <k/kHlpAssert.h>
+
+#if K_OS == K_OS_OS2
+# define INCL_BASE
+# define INCL_ERRORS
+# include <os2.h>
+
+#elif  K_OS == K_OS_WINDOWS
+# include <Windows.h>
+
+#else
+# include <k/kHlpAlloc.h>
+#endif
+
+
+/*******************************************************************************
+*   Structures and Typedefs                                                    *
+*******************************************************************************/
+/**
+ * A heap block.
+ */
+typedef struct KHLPHEAPBLOCK
+{
+    /** Next block in the global list. */
+    struct KHLPHEAPBLOCK   *pNext;
+    /** Previous block in the global list. */
+    struct KHLPHEAPBLOCK   *pPrev;
+    /** The size of this block including this header. */
+    KSIZE                   cb;
+    /** The flags. */
+    KSIZE                   fFlags;
+} KHLPHEAPBLOCK, *PKHLPHEAPBLOCK;
+
+/** Indicates whether the block is free (set) or allocated (clear). */
+#define KHLPHEAPBLOCK_FLAG_FREE     ((KSIZE)1)
+/** Valid flag mask. */
+#define KHLPHEAPBLOCK_FLAG_MASK     ((KSIZE)1)
+
+/** Checks if the block is freed. */
+#define KHLPHEAPBLOCK_IS_FREE(pB)       ( (pB)->fFlags & KHLPHEAPBLOCK_FLAG_FREE )
+/** Check if the block is allocated. */
+#define KHLPHEAPBLOCK_IS_ALLOCATED(pB)  !KHLPHEAPBLOCK_IS_FREE(pB)
+/** Checks if the two blocks are adjacent.
+ * Assumes pB1 < pB2. */
+#define KHLPHEAPBLOCK_IS_ADJACENT(pB1, pB2) \
+    ( ((KUPTR)(pB1) + (pB1)->cb) == (KUPTR)(pB2) )
+
+/** The block alignment. */
+#define KHLPHEAPBLOCK_ALIGNMENT     sizeof(KHLPHEAPBLOCK)
+
+/** @def KHLPHEAP_ASSERT
+ * Heap assertion. */
+/** @def KHLPHEAP_ASSERT_BLOCK
+ * Assert that a heap block is valid. */
+/** @def KHLPHEAP_ASSERT_FREE
+ * Assert that a heap free block is valid. */
+#ifdef KHLPHEAP_STRICT
+# define KHLPHEAP_ASSERT(expr)      kHlpAssert(expr)
+
+# define KHLPHEAP_ASSERT_BLOCK(pHeap, pBlock) \
+    do { \
+        KHLPHEAP_ASSERT(!((pBlock)->fFlags & ~KHLPHEAPBLOCK_FLAG_MASK)); \
+        KHLPHEAP_ASSERT(!((pBlock)->cb & (KHLPHEAPBLOCK_ALIGNMENT - 1))); \
+        KHLPHEAP_ASSERT((KUPTR)(pBlock)->pPrev < (KUPTR)(pBlock)); \
+        KHLPHEAP_ASSERT((KUPTR)(pBlock)->pNext > (KUPTR)(pBlock) || !(pBlock)->pNext); \
+    } while (0)
+
+# define KHLPHEAP_ASSERT_FREE(pHeap, pFree) \
+    do { \
+        KHLPHEAP_ASSERT_BLOCK(pHeap, &(pFree)->Core); \
+        KHLPHEAP_ASSERT((KUPTR)(pFree)->pPrev < (KUPTR)(pFree)); \
+        KHLPHEAP_ASSERT((KUPTR)(pFree)->pNext > (KUPTR)(pFree) || !(pFree)->pNext); \
+    } while (0)
+
+#else
+# define KHLPHEAP_ASSERT(expr)          do { } while (0)
+# define KHLPHEAP_ASSERT_BLOCK(pH, pB)  do { } while (0)
+# define KHLPHEAP_ASSERT_FREE(pH, pF)   do { } while (0)
+#endif
+
+
+/**
+ * A free heap block.
+ */
+typedef struct KHLPHEAPFREE
+{
+    /** The core bit which we have in common with used blocks. */
+    KHLPHEAPBLOCK           Core;
+    /** The next free block. */
+    struct KHLPHEAPFREE    *pNext;
+    /** The previous free block. */
+    struct KHLPHEAPFREE    *pPrev;
+} KHLPHEAPFREE, *PKHLPHEAPFREE;
+
+
+/**
+ * A heap segment.
+ */
+typedef struct KHLPHEAPSEG
+{
+    /** The base address of the segment. */
+    void                   *pvBase;
+    /** The length of the segment (in bytes). */
+    KSIZE                   cb;
+} KHLPHEAPSEG, *PKHLPHEAPSEG;
+
+/**
+ * Bundle of heap segments.
+ */
+typedef struct KHLPHEAPSEGS
+{
+    /** Pointer to the next segment bundle. */
+    struct KHLPHEAPSEGS    *pNext;
+    /** The number of segments used. */
+    KU32                    cSegs;
+    /** Array of chunks. */
+    KHLPHEAPSEG             aSegs[64];
+} KHLPHEAPSEGS, *PKHLPHEAPSEGS;
+
+
+/**
+ * Heap anchor block.
+ */
+typedef struct KHLPHEAPANCHOR
+{
+    /** Head of the block list. */
+    PKHLPHEAPBLOCK          pHead;
+    /** Tail of the block list. */
+    PKHLPHEAPBLOCK          pTail;
+    /** Head of the free list. */
+    PKHLPHEAPFREE           pFreeHead;
+    /** Head segment bundle.
+     * The order of this list is important, but a bit peculiar.
+     * Logically, SegsHead::pNext is the tail pointer. */
+    KHLPHEAPSEGS            SegsHead;
+} KHLPHEAPANCHOR, *PKHLPHEAPANCHOR;
+
+
+
+/*******************************************************************************
+*   Global Variables                                                           *
+*******************************************************************************/
+/** The heap anchor block. */
+static KHLPHEAPANCHOR       g_Heap;
+
+
+/*******************************************************************************
+*   Internal Functions                                                         *
+*******************************************************************************/
+static int      khlpHeapInit(PKHLPHEAPANCHOR pHeap);
+static void     khlpHeapDelete(PKHLPHEAPANCHOR pHeap);
+static void *   khlpHeapAlloc(PKHLPHEAPANCHOR pHeap, KSIZE cb);
+static void     khlpHeapFree(PKHLPHEAPANCHOR pHeap, void *pv);
+static KSIZE    khlpHeapBlockSize(PKHLPHEAPANCHOR pHeap, void *pv);
+static void     khlpHeapDonate(PKHLPHEAPANCHOR pHeap, void *pv, KSIZE cb);
+static int      khlpHeapSegAlloc(PKHLPHEAPSEG pSeg, KSIZE cb);
+static void     khlpHeapSegFree(PKHLPHEAPSEG pSeg);
+
+
+/**
+ * Initializes the kLdr heap.
+ *
+ * @returns 0 on success, non-zero OS specific status code on failure.
+ */
+KHLP_DECL(int) kHlpHeapInit(void)
+{
+    return khlpHeapInit(&g_Heap);
+}
+
+
+/**
+ * Terminates the kLdr heap.
+ */
+KHLP_DECL(void) kHlpHeapTerm(void)
+{
+    khlpHeapDelete(&g_Heap);
+}
+
+
+KHLP_DECL(void *) kHlpAlloc(KSIZE cb)
+{
+    return khlpHeapAlloc(&g_Heap, cb);
+}
+
+
+KHLP_DECL(void *) kHlpAllocZ(KSIZE cb)
+{
+    void *pv = khlpHeapAlloc(&g_Heap, cb);
+    if (pv)
+        kHlpMemSet(pv, 0, cb);
+    return pv;
+}
+
+
+KHLP_DECL(void *) kHlpDup(const void *pv, KSIZE cb)
+{
+    void *pvNew = khlpHeapAlloc(&g_Heap, cb);
+    if (pvNew)
+        kHlpMemCopy(pvNew, pv, cb);
+    return pvNew;
+}
+
+
+KHLP_DECL(char *) kHlpStrDup(const char *psz)
+{
+    return (char *)kHlpDup(psz, kHlpStrLen(psz) + 1);
+}
+
+
+KHLP_DECL(void *) kHlpRealloc(void *pv, KSIZE cb)
+{
+    void *pvNew;
+    if (!cb)
+    {
+        kHlpFree(pv);
+        pvNew = NULL;
+    }
+    else if (!pv)
+        pvNew = khlpHeapAlloc(&g_Heap, cb);
+    else
+    {
+        KSIZE cbToCopy = khlpHeapBlockSize(&g_Heap, pv);
+        pvNew = khlpHeapAlloc(&g_Heap, cb);
+        if (pvNew)
+        {
+            kHlpMemCopy(pvNew, pv, cb);
+            kHlpFree(pv);
+        }
+    }
+    return pvNew;
+}
+
+
+KHLP_DECL(void) kHlpFree(void *pv)
+{
+    khlpHeapFree(&g_Heap, pv);
+}
+
+
+/**
+ * Donates memory to the heap.
+ *
+ * @param   pv      The address of the memory.
+ * @param   cb      The amount of memory.
+ */
+KHLP_DECL(void) kHlpHeapDonate(void *pv, KSIZE cb)
+{
+    khlpHeapDonate(&g_Heap, pv, cb);
+}
+
+
+
+/**
+ * Initializes the heap anchor.
+ *
+ * @returns 0 on success, non-zero on failure.
+ * @param   pHeap   The heap anchor to be initialized.
+ */
+static int khlpHeapInit(PKHLPHEAPANCHOR pHeap)
+{
+    pHeap->pHead = NULL;
+    pHeap->pTail = NULL;
+    pHeap->pFreeHead = NULL;
+    pHeap->SegsHead.pNext = NULL;
+    pHeap->SegsHead.cSegs = 0;
+    return 0;
+}
+
+
+/**
+ * Deletes a heap.
+ * This will free all resources (memory) associated with the heap.
+ *
+ * @param   pHeap   The heap to be deleted.
+ */
+static void khlpHeapDelete(PKHLPHEAPANCHOR pHeap)
+{
+    /*
+     * Free the segments, LIFO order.
+     * The head element is the last to be free, while the
+     * head.pNext is really the tail pointer - neat or what?
+     */
+    while (     pHeap->SegsHead.cSegs
+           ||   pHeap->SegsHead.pNext)
+    {
+        /* find the tail. */
+        KU32            iSeg;
+        PKHLPHEAPSEGS   pSegs = pHeap->SegsHead.pNext;
+        if (!pSegs)
+            pSegs = &pHeap->SegsHead;
+        else
+        {
+            pHeap->SegsHead.pNext = pSegs->pNext;
+            pSegs->pNext = NULL;
+        }
+
+        /* free the segments */
+        iSeg = pSegs->cSegs;
+        while (iSeg-- > 0)
+            khlpHeapSegFree(&pSegs->aSegs[iSeg]);
+        pSegs->cSegs = 0;
+    }
+
+    /* Zap the anchor. */
+    pHeap->pHead = NULL;
+    pHeap->pTail = NULL;
+    pHeap->pFreeHead = NULL;
+    pHeap->SegsHead.pNext = NULL;
+    pHeap->SegsHead.cSegs = 0;
+}
+
+
+/**
+ * Internal heap block allocator.
+ */
+static void *   kldrHeapAllocSub(PKHLPHEAPANCHOR pHeap, KSIZE cb)
+{
+    /*
+     * Find a fitting free block.
+     */
+    const KSIZE     cbReq = K_ALIGN_Z(cb + sizeof(KHLPHEAPBLOCK), KHLPHEAPBLOCK_ALIGNMENT);
+    PKHLPHEAPFREE   pCur = pHeap->pFreeHead;
+    while (pCur)
+    {
+        if (pCur->Core.cb >= cbReq)
+        {
+            if (pCur->Core.cb != cbReq)
+            {
+                /* check and see if there is a better match close by. */
+                PKHLPHEAPFREE pCur2 = pCur->pNext;
+                unsigned i = 16;
+                while (i-- > 0 && pCur2)
+                {
+                    if (pCur2->Core.cb >= cbReq)
+                    {
+                        if (pCur2->Core.cb == cbReq)
+                        {
+                            pCur = pCur2;
+                            break;
+                        }
+                        if (pCur2->Core.cb < pCur->Core.cb)
+                            pCur = pCur2;
+                    }
+
+                    /* next */
+                    KHLPHEAP_ASSERT_FREE(pHeap, pCur2);
+                    pCur2 = pCur2->pNext;
+                }
+            }
+            break;
+        }
+
+        /* next */
+        KHLPHEAP_ASSERT_FREE(pHeap, pCur);
+        pCur = pCur->pNext;
+    }
+    if (!pCur)
+        return NULL;
+    KHLPHEAP_ASSERT_FREE(pHeap, pCur);
+
+    /*
+     * Do we need to split out a block?
+     */
+    if (pCur->Core.cb - cbReq >= KHLPHEAPBLOCK_ALIGNMENT * 2)
+    {
+        PKHLPHEAPBLOCK pNew;
+
+        pCur->Core.cb -= cbReq;
+
+        pNew = (PKHLPHEAPBLOCK)((KUPTR)pCur + pCur->Core.cb);
+        pNew->fFlags = 0;
+        pNew->cb = cbReq;
+        pNew->pNext = pCur->Core.pNext;
+        if (pNew->pNext)
+            pNew->pNext->pPrev = pNew;
+        else
+            pHeap->pTail = pNew;
+        pNew->pPrev = &pCur->Core;
+        pCur->Core.pNext = pNew;
+
+        KHLPHEAP_ASSERT_FREE(pHeap, pCur);
+        KHLPHEAP_ASSERT_BLOCK(pHeap, pNew);
+        return pNew + 1;
+    }
+
+    /*
+     * No, just unlink it from the free list and return.
+     */
+    if (pCur->pNext)
+        pCur->pNext->pPrev = pCur->pPrev;
+    if (pCur->pPrev)
+        pCur->pPrev->pNext = pCur->pNext;
+    else
+        pHeap->pFreeHead = pCur->pNext;
+    pCur->Core.fFlags &= ~KHLPHEAPBLOCK_FLAG_FREE;
+
+    KHLPHEAP_ASSERT_BLOCK(pHeap, &pCur->Core);
+    return &pCur->Core + 1;
+}
+
+
+/**
+ * Allocate a heap block.
+ *
+ * @returns Pointer to the allocated heap block on success. On failure NULL is returned.
+ * @param   pHeap   The heap.
+ * @param   cb      The requested heap block size.
+ */
+static void *   khlpHeapAlloc(PKHLPHEAPANCHOR pHeap, KSIZE cb)
+{
+    void *pv;
+
+    /* adjust the requested block size. */
+    cb = K_ALIGN_Z(cb, KHLPHEAPBLOCK_ALIGNMENT);
+    if (!cb)
+        cb = KHLPHEAPBLOCK_ALIGNMENT;
+
+    /* try allocate the block. */
+    pv = kldrHeapAllocSub(pHeap, cb);
+    if (!pv)
+    {
+        /*
+         * Failed, add another segment and try again.
+         */
+        KHLPHEAPSEG Seg;
+        if (khlpHeapSegAlloc(&Seg, cb + sizeof(KHLPHEAPSEGS) + sizeof(KHLPHEAPBLOCK) * 16))
+            return NULL;
+
+        /* donate before insterting the segment, this makes sure we got heap to expand the segment list. */
+        khlpHeapDonate(pHeap, Seg.pvBase, Seg.cb);
+
+        /* insert the segment. */
+        if (pHeap->SegsHead.cSegs < sizeof(pHeap->SegsHead.aSegs) / sizeof(pHeap->SegsHead.aSegs[0]))
+            pHeap->SegsHead.aSegs[pHeap->SegsHead.cSegs++] = Seg;
+        else if (   pHeap->SegsHead.pNext
+                 && pHeap->SegsHead.pNext->cSegs < sizeof(pHeap->SegsHead.aSegs) / sizeof(pHeap->SegsHead.aSegs[0]))
+            pHeap->SegsHead.pNext->aSegs[pHeap->SegsHead.pNext->cSegs++] = Seg;
+        else
+        {
+            PKHLPHEAPSEGS pSegs = (PKHLPHEAPSEGS)kldrHeapAllocSub(pHeap, sizeof(*pSegs));
+            KHLPHEAP_ASSERT(pSegs);
+            pSegs->pNext = pHeap->SegsHead.pNext;
+            pHeap->SegsHead.pNext = pSegs;
+            pSegs->aSegs[0] = Seg;
+            pSegs->cSegs = 1;
+        }
+
+        /* retry (should succeed) */
+        pv = kldrHeapAllocSub(pHeap, cb);
+        KHLPHEAP_ASSERT(pv);
+    }
+
+    return pv;
+}
+
+
+/**
+ * Frees a heap block.
+ *
+ * @param   pHeap   The heap.
+ * @param   pv      The pointer returned by khlpHeapAlloc().
+ */
+static void     khlpHeapFree(PKHLPHEAPANCHOR pHeap, void *pv)
+{
+    PKHLPHEAPFREE pFree, pLeft, pRight;
+
+    /* ignore NULL pointers. */
+    if (!pv)
+        return;
+
+    pFree = (PKHLPHEAPFREE)((PKHLPHEAPBLOCK)pv - 1);
+    KHLPHEAP_ASSERT_BLOCK(pHeap, &pFree->Core);
+    KHLPHEAP_ASSERT(KHLPHEAPBLOCK_IS_ALLOCATED(&pFree->Core));
+
+    /*
+     * Merge or link with left node?
+     */
+    pLeft = (PKHLPHEAPFREE)pFree->Core.pPrev;
+    if (    pLeft
+        &&  KHLPHEAPBLOCK_IS_FREE(&pLeft->Core)
+        &&  KHLPHEAPBLOCK_IS_ADJACENT(&pLeft->Core, &pFree->Core)
+       )
+    {
+        /* merge left */
+        pLeft->Core.pNext = pFree->Core.pNext;
+        if (pFree->Core.pNext)
+            pFree->Core.pNext->pPrev = &pLeft->Core;
+        else
+            pHeap->pTail = &pLeft->Core;
+
+        pLeft->Core.cb += pFree->Core.cb;
+        pFree->Core.fFlags = ~0;
+        pFree = pLeft;
+    }
+    else
+    {
+        /* link left */
+        while (pLeft && !KHLPHEAPBLOCK_IS_FREE(&pLeft->Core))
+            pLeft = (PKHLPHEAPFREE)pLeft->Core.pPrev;
+        if (pLeft)
+        {
+            pFree->pPrev = pLeft;
+            pFree->pNext = pLeft->pNext;
+            if (pLeft->pNext)
+                pLeft->pNext->pPrev = pFree;
+            pLeft->pNext  = pFree;
+        }
+        else
+        {
+            pFree->pPrev = NULL;
+            pFree->pNext = pHeap->pFreeHead;
+            if (pHeap->pFreeHead)
+                pHeap->pFreeHead->pPrev = pFree;
+            pHeap->pFreeHead = pFree;
+        }
+        pFree->Core.fFlags |= KHLPHEAPBLOCK_FLAG_FREE;
+    }
+    KHLPHEAP_ASSERT_FREE(pHeap, pFree);
+
+    /*
+     * Merge right?
+     */
+    pRight = (PKHLPHEAPFREE)pFree->Core.pNext;
+    if (    pRight
+        &&  KHLPHEAPBLOCK_IS_FREE(&pRight->Core)
+        &&  KHLPHEAPBLOCK_IS_ADJACENT(&pFree->Core, pRight)
+       )
+    {
+        /* unlink pRight from the global list. */
+        pFree->Core.pNext = pRight->Core.pNext;
+        if (pRight->Core.pNext)
+            pRight->Core.pNext->pPrev = &pFree->Core;
+        else
+            pHeap->pTail = &pFree->Core;
+
+        /* unlink pRight from the free list. */
+        pFree->pNext = pRight->pNext;
+        if (pRight->pNext)
+            pRight->pNext->pPrev = pFree;
+
+        /* update size and invalidate pRight. */
+        pFree->Core.cb += pRight->Core.cb;
+        pRight->Core.fFlags = ~0;
+    }
+}
+
+
+/**
+ * Calcs the size of a heap block.
+ *
+ * @returns The block size (in bytes).
+ * @param   pHeap       The heap.
+ * @param   pv          Pointer to an in-use heap block.
+ */
+static KSIZE khlpHeapBlockSize(PKHLPHEAPANCHOR pHeap, void *pv)
+{
+    PKHLPHEAPBLOCK pBlock  = (PKHLPHEAPBLOCK)pv - 1;
+    KHLPHEAP_ASSERT_BLOCK(pHeap, pBlock);
+    KHLPHEAP_ASSERT(KHLPHEAPBLOCK_IS_ALLOCATED(pBlock));
+    return (KU8 *)pBlock->pNext - (KU8 *)pv;
+}
+
+
+/**
+ * Donates memory to the heap.
+ *
+ * The donated memory is returned to the donator when the heap is deleted.
+ *
+ * @param pHeap The heap
+ * @param pv    The pointer to the donated memory.
+ * @param cb    Size of the donated memory.
+ */
+static void     khlpHeapDonate(PKHLPHEAPANCHOR pHeap, void *pv, KSIZE cb)
+{
+    PKHLPHEAPBLOCK pBlock;
+
+    /*
+     * Don't bother with small donations.
+     */
+    if (cb < KHLPHEAPBLOCK_ALIGNMENT * 4)
+        return;
+
+    /*
+     * Align the donation on a heap block boundrary.
+     */
+    if ((KUPTR)pv & (KHLPHEAPBLOCK_ALIGNMENT - 1))
+    {
+        cb -= (KUPTR)pv & 31;
+        pv = K_ALIGN_P(pv, KHLPHEAPBLOCK_ALIGNMENT);
+    }
+    cb &= ~(KSIZE)(KHLPHEAPBLOCK_ALIGNMENT - 1);
+
+    /*
+     * Create an allocated block, link it and free it.
+     */
+    pBlock = (PKHLPHEAPBLOCK)pv;
+    pBlock->pNext = NULL;
+    pBlock->pPrev = NULL;
+    pBlock->cb = cb;
+    pBlock->fFlags = 0;
+
+    /* insert */
+    if ((KUPTR)pBlock < (KUPTR)pHeap->pHead)
+    {
+        /* head */
+        pBlock->pNext = pHeap->pHead;
+        pHeap->pHead->pPrev = pBlock;
+        pHeap->pHead = pBlock;
+    }
+    else if ((KUPTR)pBlock > (KUPTR)pHeap->pTail)
+    {
+        if (pHeap->pTail)
+        {
+            /* tail */
+            pBlock->pPrev = pHeap->pTail;
+            pHeap->pTail->pNext = pBlock;
+            pHeap->pTail = pBlock;
+        }
+        else
+        {
+            /* first */
+            pHeap->pHead = pBlock;
+            pHeap->pTail = pBlock;
+        }
+    }
+    else
+    {
+        /* in list (unlikely) */
+        PKHLPHEAPBLOCK pPrev = pHeap->pHead;
+        PKHLPHEAPBLOCK pCur = pPrev->pNext;
+        for (;;)
+        {
+            KHLPHEAP_ASSERT_BLOCK(pHeap, pCur);
+            if ((KUPTR)pCur > (KUPTR)pBlock)
+                break;
+            pPrev = pCur;
+            pCur = pCur->pNext;
+        }
+
+        pBlock->pNext = pCur;
+        pBlock->pPrev = pPrev;
+        pPrev->pNext = pBlock;
+        pCur->pPrev = pBlock;
+    }
+    KHLPHEAP_ASSERT_BLOCK(pHeap, pBlock);
+
+    /* free it */
+    khlpHeapFree(pHeap, pBlock + 1);
+}
+
+
+
+/**
+ * Allocates a new segment.
+ *
+ * @returns 0 on success, non-zero OS status code on failure.
+ * @param   pSeg    Where to put the info about the allocated segment.
+ * @param   cbMin   The minimum segment size.
+ */
+static int khlpHeapSegAlloc(PKHLPHEAPSEG pSeg, KSIZE cbMin)
+{
+#if K_OS == K_OS_OS2
+    APIRET rc;
+
+    pSeg->cb = (cbMin + 0xffff) & ~(KSIZE)0xffff;
+    pSeg->pvBase = NULL;
+    rc = DosAllocMem(&pSeg->pvBase, pSeg->cb, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_ANY);
+    if (rc == ERROR_INVALID_PARAMETER)
+        rc = DosAllocMem(&pSeg->pvBase, pSeg->cb, PAG_COMMIT | PAG_READ | PAG_WRITE);
+    if (rc)
+    {
+        pSeg->pvBase = NULL;
+        pSeg->cb = 0;
+        return rc;
+    }
+
+#elif  K_OS == K_OS_WINDOWS
+    pSeg->cb = (cbMin + 0xffff) & ~(KSIZE)0xffff;
+    pSeg->pvBase = VirtualAlloc(NULL, pSeg->cb, MEM_COMMIT, PAGE_READWRITE);
+    if (!pSeg->pvBase)
+    {
+        pSeg->cb = 0;
+        return GetLastError();
+    }
+
+#else
+    int rc;
+
+    pSeg->cb = (cbMin + 0xffff) & ~(KSIZE)0xffff;
+    pSeg->pvBase = NULL;
+    rc = kHlpPageAlloc(&pSeg->pvBase, pSeg->cb, KPROT_READWRITE, K_FALSE);
+    if (rc)
+    {
+        pSeg->pvBase = NULL;
+        pSeg->cb = 0;
+        return rc;
+    }
+
+#endif
+
+    return 0;
+}
+
+
+/**
+ * Frees a segment.
+ *
+ * @param   pSeg    The segment to be freed.
+ */
+static void khlpHeapSegFree(PKHLPHEAPSEG pSeg)
+{
+#if K_OS == K_OS_OS2
+    APIRET rc = DosFreeMem(pSeg->pvBase);
+    KHLPHEAP_ASSERT(!rc); (void)rc;
+
+#elif  K_OS == K_OS_WINDOWS
+    BOOL fRc = VirtualFree(pSeg->pvBase, 0 /*pSeg->cb*/, MEM_RELEASE);
+    KHLPHEAP_ASSERT(fRc); (void)fRc;
+
+#else
+    int rc = kHlpPageFree(pSeg->pvBase, pSeg->cb);
+    KHLPHEAP_ASSERT(!rc); (void)rc;
+
+#endif
+}
+
diff --git a/src/lib/kStuff/kHlp/Bare/kHlpBareProcess.c b/src/lib/kStuff/kHlp/Bare/kHlpBareProcess.c
new file mode 100644
index 0000000..f7db3ff
--- /dev/null
+++ b/src/lib/kStuff/kHlp/Bare/kHlpBareProcess.c
@@ -0,0 +1,85 @@
+/* $Id: kHlpBareProcess.c 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpBare - Process Management
+ */
+
+/*
+ * Copyright (c) 2006-2007 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <k/kHlpProcess.h>
+#include <k/kHlpAssert.h>
+
+#if K_OS == K_OS_DARWIN \
+ || K_OS == K_OS_FREEBSD \
+ || K_OS == K_OS_LINUX \
+ || K_OS == K_OS_NETBSD \
+ || K_OS == K_OS_OPENBSD \
+ || K_OS == K_OS_SOLARIS
+# include <k/kHlpSys.h>
+
+#elif K_OS == K_OS_OS2
+# define INCL_BASE
+# define INCL_ERRORS
+# include <os2.h>
+#elif  K_OS == K_OS_WINDOWS
+# include <Windows.h>
+#else
+# error "port me"
+#endif
+
+
+/**
+ * Terminate the process.
+ *
+ * @param   rc      The exit status.
+ */
+void    kHlpExit(int rc)
+{
+    for (;;)
+    {
+#if K_OS == K_OS_DARWIN \
+ || K_OS == K_OS_FREEBSD \
+ || K_OS == K_OS_LINUX \
+ || K_OS == K_OS_NETBSD \
+ || K_OS == K_OS_OPENBSD \
+ || K_OS == K_OS_SOLARIS
+        kHlpSys_exit(rc);
+
+#elif K_OS == K_OS_OS2
+        DosExit(EXIT_PROCESS, rc);
+
+#elif  K_OS == K_OS_WINDOWS
+        TerminateProcess(GetCurrentProcess(), rc);
+
+#else
+# error "Port me"
+#endif
+        kHlpAssert(!"Impossible");
+    }
+}
+
diff --git a/src/lib/kStuff/kHlp/Bare/kHlpBareThread.c b/src/lib/kStuff/kHlp/Bare/kHlpBareThread.c
new file mode 100644
index 0000000..b484676
--- /dev/null
+++ b/src/lib/kStuff/kHlp/Bare/kHlpBareThread.c
@@ -0,0 +1,93 @@
+/* $Id: kHlpBareThread.c 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpBare - Thread Manipulation.
+ */
+
+/*
+ * Copyright (c) 2006-2007 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*******************************************************************************
+*   Header Files                                                               *
+*******************************************************************************/
+#include <k/kHlpThread.h>
+
+#if K_OS == K_OS_DARWIN
+# include <mach/mach_time.h>
+
+#elif K_OS == K_OS_LINUX
+# include <k/kHlpSys.h>
+
+#elif K_OS == K_OS_OS2
+# define INCL_BASE
+# define INCL_ERRORS
+# include <os2.h>
+#elif  K_OS == K_OS_WINDOWS
+# include <Windows.h>
+#else
+# error "port me"
+#endif
+
+
+/**
+ * Sleep for a number of milliseconds.
+ * @param   cMillies    Number of milliseconds to sleep.
+ */
+void kHlpSleep(unsigned cMillies)
+{
+#if K_OS == K_OS_DARWIN
+    static struct mach_timebase_info   s_Info;
+    static KBOOL                s_fNanoseconds = K_UNKNOWN;
+    KU64 uNow = mach_absolute_time();
+    KU64 uDeadline;
+    KU64 uPeriod;
+
+    if (s_fNanoseconds == K_UNKNOWN)
+    {
+        if (mach_timebase_info(&s_Info))
+            s_fNanoseconds = K_TRUE; /* the easy way out */
+        else if (s_Info.denom == s_Info.numer)
+            s_fNanoseconds = K_TRUE;
+        else
+            s_fNanoseconds = K_FALSE;
+    }
+
+    uPeriod = (KU64)cMillies * 1000 * 1000;
+    if (!s_fNanoseconds)
+        uPeriod = (double)uPeriod * s_Info.denom / s_Info.numer; /* Use double to avoid 32-bit trouble. */
+    uDeadline = uNow + uPeriod;
+    mach_wait_until(uDeadline);
+
+#elif K_OS == K_OS_LINUX
+    /** @todo find the right syscall... */
+
+#elif K_OS == K_OS_OS2
+    DosSleep(cMillies);
+#elif  K_OS == K_OS_WINDOWS
+    Sleep(cMillies);
+#else
+    usleep(cMillies * 1000);
+#endif
+}
+
diff --git a/src/lib/kStuff/kHlp/Bare/kHlpSys-darwin.c b/src/lib/kStuff/kHlp/Bare/kHlpSys-darwin.c
new file mode 100644
index 0000000..b4153f2
--- /dev/null
+++ b/src/lib/kStuff/kHlp/Bare/kHlpSys-darwin.c
@@ -0,0 +1,345 @@
+/* $Id: kHlpSys-darwin.c 29 2009-07-01 20:30:29Z bird $ */
+/** @file
+ * kHlpBare -
+ */
+
+/*
+ * Copyright (c) 2006-2007 Knut St. Osmundsen <bird-kStuff-spamix@anduin.net>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <k/kHlpSys.h>
+#include <unistd.h>
+#include <errno.h>
+#include <dlfcn.h>
+#include <sys/mman.h>
+#include <mach/mach_time.h>
+
+
+#define USE_DARWIN_SYSCALLS
+
+#if K_ARCH == K_ARCH_X86_32
+# define DARWIN_SYSCALL(name, code) \
+    asm("\
+    .text                                   \n\
+    .globl _" #name "                       \n\
+    _" #name ":                             \n\
+        mov     $ " #code ", %eax           \n\
+        call    1f                          \n\
+    1:                                      \n\
+        pop     %edx                        \n\
+        mov     %esp, %ecx                  \n\
+        sysenter                            \n\
+        jnae    2f                          \n\
+        ret                                 \n\
+    2:                                      \n\
+        neg     %eax                        \n\
+        ret                                 \n\
+    ")
+
+# define DARWIN_SYSCALL_RET64(name, code) \
+    asm("\
+    .text                                   \n\
+    .globl _" #name "                       \n\
+    _" #name ":                             \n\
+        mov     $ " #code ", %eax           \n\
+        int     $0x80                       \n\
+        jnae    2f                          \n\
+        ret                                 \n\
+    2:                                      \n\
+        neg     %eax                        \n\
+        mov     $0xffffffff, %edx           \n\
+        ret                                 \n\
+    ")
+
+# define DARWIN_SYSCALL_NOERR(name, code) \
+    asm("\
+    .text                                   \n\
+    .globl _" #name "                       \n\
+    _" #name ":                             \n\
+        mov     $ " #code ", %eax           \n\
+        call    1f                          \n\
+    1:                                      \n\
+        pop     %edx                        \n\
+        mov     %esp, %ecx                  \n\
+        sysenter                            \n\
+        ret                                 \n\
+    ")
+
+#elif K_ARCH == K_ARCH_AMD64
+# define DARWIN_SYSCALL(name, code) \
+    asm("\
+    .text                                   \n\
+    .globl _" #name "                       \n\
+    _" #name ":                             \n\
+        mov     $ " #code ", %eax           \n\
+        mov     %rcx, %r10                  \n\
+        sysenter                            \n\
+        jnae    2f                          \n\
+        ret                                 \n\
+    2:                                      \n\
+        neg     %eax                        \n\
+        movsx   %eax, %rax                  \n\
+        ret                                 \n\
+    ")
+
+# define DARWIN_SYSCALL_RET64(name, code) DARWIN_SYSCALL_RET(name, code)
+
+# define DARWIN_SYSCALL_NOERR(name, code) \
+    asm("\
+    .text                                   \n\
+    .globl _" #name "                       \n\
+    _" #name ":                             \n\
+        mov     $ " #code ", %eax           \n\
+        mov     %rcx, %r10                  \n\
+        sysenter                            \n\
+        ret                                 \n\
+    ")
+
+
+#else
+# error later...
+#endif
+
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_readlink, 0x000c003a);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_readlink, 0x0200003a);
+#else
+KSSIZE      kHlpSys_readlink(const char *pszPath, char *pszBuf, KSIZE cbBuf)
+{
+    KSSIZE cbRet = readlink(pszPath, pszBuf, cbBuf);
+    return cbRet >= 0 ? cbRet : -errno;
+}
+#endif
+
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_open, 0x000c0005);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_open, 0x02000005);
+#else
+int         kHlpSys_open(const char *filename, int flags, int mode)
+{
+    int fd = open(filename, flags, mode);
+    return fd >= 0 ? fd : -errno;
+}
+#endif
+
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_close, 0x000c0006);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_close, 0x02000006);
+#else
+int         kHlpSys_close(int fd)
+{
+   if (!close(fd))
+       return 0;
+   return -errno;
+}
+#endif
+
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL_RET64(kHlpSys_lseek, 0x000000c7);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL_RET64(kHlpSys_lseek, 0x020000c7);
+#else
+KFOFF       kHlpSys_lseek(int fd, int whench, KFOFF off)
+{
+    KFOFF offRet = lseek(fd, whench, off);
+    return offRet >= 0 ? offRet : -errno;
+}
+#endif
+
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_read, 0x000c0003);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_read, 0x02000003);
+#else
+KSSIZE      kHlpSys_read(int fd, void *pvBuf, KSIZE cbBuf)
+{
+    KSSIZE cbRead = read(fd, pvBuf, cbBuf);
+    return cbRead >= 0 ? cbRead : -errno;
+}
+#endif
+
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_write, 0x000c0004);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_write, 0x02000004);
+#else
+KSSIZE      kHlpSys_write(int fd, const void *pvBuf, KSIZE cbBuf)
+{
+    KSSIZE cbWritten = write(fd, pvBuf, cbBuf);
+    return cbWritten >= 0 ? cbWritten : -errno;
+}
+#endif
+
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_mmap, 0x020000c5);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_mmap, 0x020000c5);
+#else
+void       *kHlpSys_mmap(void *addr, KSIZE len, int prot, int flags, int fd, KI64 off)
+{
+    void *pv = mmap(addr, len, prot, flags, fd, off);
+    return pv != (void *)-1
+        ? pv
+        : errno < 256 ? (void *)(long)errno : (void *)(long)ENOMEM;
+}
+#endif
+
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_mprotect, 0x000c004a);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_mprotect, 0x0200004a);
+#else
+int         kHlpSys_mprotect(void *addr, KSIZE len, int prot)
+{
+    if (!mprotect(addr, len, prot))
+        return 0;
+    return -errno;
+}
+#endif
+
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_munmap, 0x00080049);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_munmap, 0x02000049);
+#else
+int         kHlpSys_munmap(void *addr, KSIZE len)
+{
+    if (!munmap(addr, len))
+        return 0;
+    return -errno;
+}
+#endif
+
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_exit, 0x00040001);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(kHlpSys_exit, 0x02000001);
+#else
+void        kHlpSys_exit(int rc)
+{
+    _Exit(rc);
+}
+#endif
+
+
+/*
+ * Some other stuff we'll be needing - Move to an appropriate place?
+ */
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL_NOERR(mach_task_self, 0xffffffe4);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL_NOERR(mach_task_self, 0xffffffe4);
+#endif
+
+//#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+//DARWIN_SYSCALL(semaphore_create, 0x00040001);
+//#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+//DARWIN_SYSCALL(semaphore_create, 0x02000001);
+//#endif
+#ifdef USE_DARWIN_SYSCALLS
+kern_return_t semaphore_create(task_t t, semaphore_t *ps, int p, int v)
+{
+    return 0;
+}
+#endif
+
+//#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+//DARWIN_SYSCALL(semaphore_destroy, 0x00040001);
+//#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+//DARWIN_SYSCALL(semaphore_destroy, 0x02000001);
+//#endif
+#ifdef USE_DARWIN_SYSCALLS
+kern_return_t semaphore_destroy(task_t t, semaphore_t s)
+{
+    return 0;
+}
+#endif
+
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(semaphore_wait, 0xffffffdc);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(semaphore_wait, 0xffffffdc);
+#endif
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(semaphore_signal, 0xffffffdf);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(semaphore_signal, 0xffffffdf);
+#endif
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(mach_wait_until, 0xffffffa6);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(mach_wait_until, 0xffffffa6);
+#endif
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(mach_timebase_info, 0xffffffa7);
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+DARWIN_SYSCALL(mach_timebase_info, 0xffffffa7);
+#endif
+
+#if K_ARCH == K_ARCH_X86_32 && defined(USE_DARWIN_SYSCALLS)
+asm("\n\
+.text                           \n\
+.globl _mach_absolute_time      \n\
+_mach_absolute_time:            \n\
+    mov     $0xffff1700, %edx   \n\
+    jmp     *%edx\n"); /* common page stuff. */
+#elif K_ARCH == K_ARCH_AMD64 && defined(USE_DARWIN_SYSCALLS)
+#endif
+
+
+void *dlopen(const char *pszModule, int fFlags)
+{
+    return NULL;
+}
+
+
+int dlclose(void *pvMod)
+{
+
+}
+
+
+void *dlsym(void *pvMod, const char *pszSymbol)
+{
+    return NULL;
+}
+
-- 
cgit v1.2.3